/// <summary> /// return value; /// </summary> /// <returns></returns> public override Expr Parse() { var token = _tokenIt.NextToken; var exp = new FunctionExpr(); _parser.SetupContext(exp, token); var name = "anon_" + token.Line + "_" + token.LineCharPos; _tokenIt.Advance(); _tokenIt.Expect(Tokens.LeftParenthesis); var argnames = _parser.ParseNames(); exp.Meta.Init(name, argnames); _tokenIt.Expect(Tokens.RightParenthesis); ParseBlock(exp); var lambdaExp = new LambdaExpr(); lambdaExp.Expr = exp; return lambdaExp; }
/// <summary> /// Call a function by passing in all the values. /// </summary> /// <param name="ctx">The context of the runtime</param> /// <param name="functionName">The name of the function to call.</param> /// <param name="paramListExpressions">List of parameters as expressions to evaluate first to actual values</param> /// <param name="paramVals">List to store the resolved paramter expressions. ( these will be resolved if paramListExpressions is supplied and resolveParams is true. If /// resolveParams is false, the list is assumed to have the values for the paramters to the function.</param> /// <param name="resolveParams">Whether or not to resolve the list of parameter expression objects</param> /// <returns></returns> public static object CallFunctionInScript(Context ctx, FunctionExpr function, string functionName, List<Expr> paramListExpressions, List<object> paramVals, bool resolveParams) { // 1. Determine if any parameters provided. var hasParams = paramListExpressions != null && paramListExpressions.Count > 0; // 2. Resolve parameters if necessary if (resolveParams && function != null && (function.HasArguments || hasParams)) ParamHelper.ResolveParametersForScriptFunction(function.Meta, paramListExpressions, paramVals); // 3. Assign the argument values to the function and evaluate. function.ArgumentValues = paramVals; function.Evaluate(); object result = null; if (function.HasReturnValue) result = function.ReturnValue; else result = LObjects.Null; return result; }
public object VisitFunction(FunctionExpr expr) { return null; }
/// <summary> /// Call a fluent script function from c#. /// </summary> /// <param name="context">The context of the call.</param> /// <param name="expr">The lambda function</param> /// <param name="convertApplicableTypes">Whether or not to convert applicable c# types to fluentscript types, eg. ints and longs to double, List(object) to LArrayType and Dictionary(string, object) to LMapType</param> /// <param name="args"></param> public static object CallFunctionViaCSharpUsingLambda(Context context, FunctionExpr expr, bool convertApplicableTypes, params object[] args) { var argsList = args.ToList<object>(); if (convertApplicableTypes) LangTypeHelper.ConvertToLangTypeValues(argsList); var execution = new Execution(); execution.Ctx = context; if (EvalHelper.Ctx == null) EvalHelper.Ctx = context; var result = FunctionHelper.CallFunctionInScript(context, expr, expr.Meta.Name, null, argsList, false, execution); return result; }
/// <summary> /// Registers a custom function callback. /// </summary> /// <param name="pattern"></param> /// <param name="stmt">The function</param> public void Register(string pattern, FunctionExpr stmt) { _functions[pattern] = stmt; _lcaseToFormaNameMap[pattern.ToLower()] = pattern; }
private void PushParametersInScope(FunctionExpr expr) { // 1. Validate : any arguments. if (expr.ArgumentValues == null || expr.ArgumentValues.Count == 0) return; if (expr.Meta.Arguments == null || expr.Meta.Arguments.Count == 0) return; // 2. Check if there is an parameter named "arguments" var hasParameterNamedArguments = false; if (expr.Meta.Arguments != null && expr.Meta.Arguments.Count > 0) if (expr.Meta.ArgumentsLookup.ContainsKey("arguments")) hasParameterNamedArguments = true; // 3. Get the symbolscope of the inside of the function and see if any statements. ISymbols symscope = null; var hasStatements = expr.Statements != null && expr.Statements.Count > 0; if (hasStatements) symscope = expr.Statements[0].SymScope; // 3. Add function arguments to scope for (var ndx = 0; ndx < expr.Meta.Arguments.Count; ndx++) { var val = expr.ArgumentValues[ndx] as LObject; var arg = expr.Meta.Arguments[ndx]; // 4. Clone primitive datatypes. if (val.Type.IsPrimitiveType()) { var copied = val.Clone(); expr.ArgumentValues[ndx] = copied; } // 5. Now, set the memory value of the parameter. this.Ctx.Memory.SetValue(arg.Name, val); // 6. Finally, update the symbol type if (hasStatements) { var sym = symscope.GetSymbol(arg.Name); if (sym != null && val.Type.TypeVal == TypeConstants.Function && sym.Category != SymbolCategory.Func) { SymbolHelper.ResetSymbolAsFunction(symscope, arg.Name, val); } } } // Finally add the arguments. // NOTE: Any extra arguments will be part of the implicit "arguments" array. if (!hasParameterNamedArguments) { var argArray = new LArray(expr.ArgumentValues); expr.Ctx.Memory.SetValue("arguments", argArray); } }
private void InitializeFunctionCall(FunctionExpr expr) { // Keep track of total times this function was executed. // Keep tract of total times this function caused an error if (expr.ExecutionCount == long.MaxValue) expr.ExecutionCount = 0; else expr.ExecutionCount++; if (expr.ErrorCount == long.MaxValue) expr.ErrorCount = 0; expr.ContinueRunning = true; expr.ReturnValue = null; expr.HasReturnValue = false; PushParametersInScope(expr); }
public object VisitFunction(FunctionExpr expr) { InitializeFunctionCall(expr); try { if (expr.Statements == null || expr.Statements.Count == 0) return LObjects.Null; foreach (var statement in expr.Statements) { statement.Evaluate(this); if (!expr.ContinueRunning) break; } } catch (Exception ex) { expr.ErrorCount++; throw ex; } return LObjects.Null; }
public Expr OnParseLambda() { var tokenIt = this._parser.TokenIt; var initiatorToken = tokenIt.NextToken; // <codeLambda> // Check for lambda or function declare. var next = tokenIt.Peek(); if (next.Token != Tokens.LeftParenthesis) { return OnParseFunctionDeclare(); } // This a lambda. var expr = new LambdaExpr(); var funcExp = new FunctionExpr(); expr.Expr = funcExp; expr.Expr.Meta = new FunctionMetaData(); this._parser.SetupContext(funcExp, initiatorToken); var name = "anon_" + initiatorToken.Line + "_" + initiatorToken.LineCharPos; tokenIt.Advance(); tokenIt.Expect(Tokens.LeftParenthesis); var argnames = _parser.ParseNames(); funcExp.Meta.Init(name, argnames); tokenIt.Expect(Tokens.RightParenthesis); this.OnParseLambdaBlock(funcExp); // </codeLambda> this._parser.SetupContext(expr, initiatorToken); return expr; }