public object Execute(FiMClass reportClass, bool global = false) { if (reportClass.GetVariable(this.Name) != null) { throw new FiMException("Variable " + this.Name + " already exists"); } KirinValue value = new KirinValue(this.RawValue, reportClass, this.ExpectedType); if (value.Value == null) { value.Value = FiMHelper.GetDefaultValue(this.ExpectedType); } else { if (value.Type != this.ExpectedType) { throw new FiMException("Expected " + this.ExpectedType.AsNamedString() + ", got " + value.Type.AsNamedString()); } } value.Constant = Constant; FiMVariable var = new FiMVariable(this.Name, value); reportClass.Variables.Push(var, global); return(null); }
public override object Execute(FiMClass reportClass, params object[] args) { int localVariables = 0; reportClass.Variables.PushFunctionStack(); if (this.Arguments?.Count() > 0) { for (int i = 0; i < this.Arguments.Count(); i++) { if (reportClass.Variables.Has(this.Arguments[i].Name)) { throw new FiMException("Variable name " + this.Arguments[i].Name + " already exists"); } if (i < args.Length) { if (FiMHelper.AsVariableType(args[i]) != this.Arguments[i].Type) { throw new FiMException("Expected " + this.Arguments[i].Type.AsNamedString() + ", got " + FiMHelper.AsVariableType(args[i]).AsNamedString()); } reportClass.Variables.Push(new FiMVariable(this.Arguments[i].Name, new KirinValue(args[i]))); } else { reportClass.Variables.Push( new FiMVariable( this.Arguments[i].Name, new KirinValue(FiMHelper.GetDefaultValue(this.Arguments[i].Type)) ) ); } localVariables++; } } var result = Statement.Execute(reportClass); reportClass.Variables.PopFunctionStack(); if (result != null && this.Returns == null) { throw new FiMException("Non-value returning function returned value"); } if (result != null && this.Returns != null && this.Returns != KirinVariableType.UNKNOWN) { if (FiMHelper.AsVariableType(result) != this.Returns) { throw new FiMException("Expected " + ((KirinVariableType)this.Returns).AsNamedString() + ", got " + FiMHelper.AsVariableType(result).AsNamedString()); } return(result); } return(null); }
public override object Execute(FiMClass reportClass, params object[] args) { object[] sanitizedArgs = null; if (this.Arguments?.Count > 0) { sanitizedArgs = new object[this.Arguments.Count]; for (int i = 0; i < this.Arguments.Count; i++) { if (i < args.Length) { if (this.Arguments[i] == KirinVariableType.EXPERIMENTAL_DYNAMIC_ARRAY) { if (!FiMHelper.IsTypeArray(args[i])) { throw new FiMException("Expected an array, got " + FiMHelper.AsVariableType(args[i]).AsNamedString()); } } else if (FiMHelper.AsVariableType(args[i]) != this.Arguments[i]) { throw new FiMException("Expected " + this.Arguments[i].AsNamedString() + ", got " + FiMHelper.AsVariableType(args[i]).AsNamedString()); } sanitizedArgs[i] = args[i]; } else { sanitizedArgs[i] = FiMHelper.GetDefaultValue(this.Arguments[i]); } } } object result; try { result = this.Function.DynamicInvoke(sanitizedArgs); } catch (Exception ex) { throw new Exception("An error has occured while running a custom method\n\n" + ex.ToString()); } if (result != null && this.Returns == null) { throw new FiMException("Non-value returning function returned value"); } if (result != null && this.Returns != null && this.Returns != KirinVariableType.UNKNOWN) { if (FiMHelper.AsVariableType(result) != this.Returns) { throw new FiMException("Expected " + ((KirinVariableType)this.Returns).AsNamedString() + ", got " + FiMHelper.AsVariableType(result).AsNamedString()); } return(result); } return(null); }
public KirinValue Load() { if (this.Raw == null) { if (FiMHelper.IsTypeArray(this.Type)) { this._Value = FiMHelper.GetDefaultValue(this.Type); } else { if (this.ForcedType == null) { throw new FiMException("Value is null"); } this._Value = FiMHelper.GetDefaultValue((KirinVariableType)this.ForcedType); } } else { string raw = this.Raw; var eType = FiMHelper.DeclarationType.Determine(" " + raw, out string eKeyword, false); if (eType != KirinVariableType.UNKNOWN) { raw = raw.Substring(eKeyword.Length); this.ForceType(eType); } if (this.ForcedType != null) { eType = (KirinVariableType)this.ForcedType; } object value; if (KirinLiteral.TryParse(raw, out object lResult)) { value = lResult; } else { value = KirinValue.Evaluate(Class, raw, out var returnedType, ForcedType); this.ForceType(returnedType); } if (eType != KirinVariableType.UNKNOWN && FiMHelper.AsVariableType(value) != eType) { throw new FiMException("Expected " + eType.AsNamedString() + ", got " + FiMHelper.AsVariableType(value)); } this._Value = value; } return(this); }
/// <summary> /// Evaluates raw FiM++ string into a value /// </summary> public static object Evaluate( FiMClass reportClass, string evaluatable, out KirinVariableType returnedType, KirinVariableType?expectedType = null ) { returnedType = KirinVariableType.UNKNOWN; // Nothing if (evaluatable == "nothing" && expectedType != null) { returnedType = (KirinVariableType)expectedType; return(FiMHelper.GetDefaultValue(returnedType)); } // Calling an existing variable if (reportClass.GetVariable(evaluatable) != null) { var variable = reportClass.GetVariable(evaluatable); returnedType = variable.Type; return(variable.Value); } // Calling an existing method if (reportClass.GetParagraphLazy(evaluatable) != null) { KirinValue[] args = null; string pName = evaluatable; if (pName.Contains(KirinFunctionCall.FunctionParam)) { int pIndex = pName.IndexOf(KirinFunctionCall.FunctionParam); pName = pName.Substring(0, pIndex); args = KirinFunctionCall.ParseCallArguments( evaluatable.Substring(pName.Length + KirinFunctionCall.FunctionParam.Length), reportClass ).ToArray(); } var paragraph = reportClass.GetParagraph(pName); if (paragraph == null) { throw new FiMException("Paragraph " + pName + " not found"); } if (paragraph.ReturnType == KirinVariableType.UNKNOWN) { throw new FiMException("Paragraph returns nothing"); } returnedType = paragraph.ReturnType; return(paragraph.Execute(args)); } // Array if (expectedType != null && FiMHelper.IsTypeArray((KirinVariableType)expectedType)) { System.Collections.IDictionary dict = null; var args = KirinFunctionCall.ParseCallArguments(evaluatable, reportClass); if (!FiMHelper.IsTypeOfArray(args[0].Type, (KirinArrayType)expectedType)) { throw new FiMException("Invalid list value type"); } if (!args.All(a => a.Type == args[0].Type)) { throw new FiMException("Unidentical list value type"); } int i = 1; if (expectedType == KirinVariableType.STRING_ARRAY) { dict = new Dictionary <int, string>(); args.ForEach(kv => dict.Add(i++, Convert.ToString(kv.Value))); } else if (expectedType == KirinVariableType.NUMBER_ARRAY) { dict = new Dictionary <int, double>(); args.ForEach(kv => dict.Add(i++, Convert.ToDouble(kv.Value))); } else if (expectedType == KirinVariableType.BOOL_ARRAY) { dict = new Dictionary <int, bool>(); args.ForEach(kv => dict.Add(i++, Convert.ToBoolean(kv.Value))); } returnedType = (KirinVariableType)expectedType; return(dict); } // Array index if (FiMHelper.ArrayIndex.IsArrayIndex(evaluatable, reportClass)) { var match = FiMHelper.ArrayIndex.GetArrayIndex(evaluatable, reportClass); var varIndex = new KirinValue(match.RawIndex, reportClass); if (varIndex.Type != KirinVariableType.NUMBER) { throw new FiMException("Invalid index value"); } int index = Convert.ToInt32(varIndex.Value); string strVar = match.RawVariable; if (!reportClass.Variables.Has(strVar)) { throw new FiMException("Variable " + strVar + " does not exist"); } var variable = reportClass.Variables.Get(strVar); if (!FiMHelper.IsTypeArray(variable.Type) && variable.Type != KirinVariableType.STRING) { throw new FiMException("Cannot index a non-array variable"); } if (variable.Type == KirinVariableType.STRING) { returnedType = KirinVariableType.CHAR; return(Convert.ToString(variable.Value)[index - 1]); } var dict = variable.Value as System.Collections.IDictionary; if (variable.Type == KirinVariableType.STRING_ARRAY) { returnedType = KirinVariableType.STRING; return(Convert.ToString(dict[index])); } if (variable.Type == KirinVariableType.BOOL_ARRAY) { returnedType = KirinVariableType.BOOL; return(Convert.ToBoolean(dict[index])); } if (variable.Type == KirinVariableType.NUMBER_ARRAY) { returnedType = KirinVariableType.NUMBER; return(Convert.ToDouble(dict[index])); } } // Arithmetic if (KirinArithmetic.IsArithmetic(evaluatable, out var arithmeticResult)) { var arithmetic = new KirinArithmetic(arithmeticResult); var value = arithmetic.GetValue(reportClass); returnedType = FiMHelper.AsVariableType(value.GetType()); return(value); } // Conditional if (KirinConditional.IsConditional(evaluatable, out var conditionalResult)) { var conditional = new KirinConditional(conditionalResult); returnedType = KirinVariableType.BOOL; return(conditional.GetValue(reportClass)); } throw new FiMException("Cannot evaluate " + evaluatable); }