/// <summary> /// the list of parameters must correspond the the required set of Arguments /// </summary> /// <param name="parameters"></param> /// <returns></returns> public override object Evaluate(object[] parameters, ParseTreeEvaluator tree) { // create a new scope for the arguments Variables pars = Arguments.Clone(); // now push a copy of the function arguments on the stack tree.Context.PushScope(pars); // assign the parameters to the current function scope variables int i = 0; foreach (string key in pars.Keys) { pars[key] = parameters[i++]; } // execute the function here object result = Node.Evaluate(tree, null); // clean up the stack tree.Context.PopScope(); return(result); }
protected override object EvaluateVariable(ParseTree tree, params object[] paramlist) { ParseTreeEvaluator root = tree as ParseTreeEvaluator; if (root == null) { tree.Errors.Add(new ParseError("Invalid parser used", 1040, this)); return(null); } if (root.Context == null) { tree.Errors.Add(new ParseError("No context defined", 1041, this)); return(null); } string key = this.nodes[0].Token.Text.ToLowerInvariant(); // first check if the variable was declared in scope of a function if (root.Context.CurrentScope != null && root.Context.CurrentScope.ContainsKey(key)) { return(root.Context.CurrentScope[key]); } // if not in scope of a function // next check if the variable was declared as a global variable if (root.Context.Globals != null && root.Context.Globals.ContainsKey(key)) { return(root.Context.Globals[key]); } //variable not found tree.Errors.Add(new ParseError("Variable not defined: " + key, 1039, this)); return(null); }
public override object Evaluate(object[] parameters, ParseTreeEvaluator tree) { tree.Context.PushScope(null); object result = FunctionDelegate(parameters); tree.Context.PopScope(); return(result); }
/// <summary> /// required to override this function from base otherwise the parsetree will consist of incorrect types of nodes /// </summary> /// <param name="token"></param> /// <param name="text"></param> /// <returns></returns> public override ParseNode CreateNode(Token token, string text) { ParseTreeEvaluator node = new ParseTreeEvaluator(); node.Token = token; node.text = text; node.Parent = this; return node; }
/// <summary> /// required to override this function from base otherwise the parsetree will consist of incorrect types of nodes /// </summary> /// <param name="token"></param> /// <param name="text"></param> /// <returns></returns> public override ParseNode CreateNode(Token token, string text) { ParseTreeEvaluator node = new ParseTreeEvaluator(); node.Token = token; node.text = text; node.Parent = this; return(node); }
public Expression(string exp) { expression = exp; Scanner scanner = new Scanner(); Parser parser = new Parser(scanner); tree = new ParseTreeEvaluator(Context.Default); tree = parser.Parse(expression, tree) as ParseTreeEvaluator; }
protected override object EvaluateFunction(ParseTree tree, params object[] paramlist) { ParseNode funcNode = this.nodes[0]; ParseNode paramNode = this.nodes[2]; ParseTreeEvaluator root = tree as ParseTreeEvaluator; if (root == null) { tree.Errors.Add(new ParseError("Invalid parser used", 1040, this)); return(null); } if (root.Context == null) { tree.Errors.Add(new ParseError("No context defined", 1041, this)); return(null); } if (root.Context.CurrentStackSize > 50) { tree.Errors.Add(new ParseError("Stack overflow: " + funcNode.Token.Text + "()", 1046, this)); return(null); } string key = funcNode.Token.Text.ToLowerInvariant(); if (!root.Context.Functions.ContainsKey(key)) { tree.Errors.Add(new ParseError("Fuction not defined: " + funcNode.Token.Text + "()", 1042, this)); return(null); } // retrieves the function from declared functions Function func = root.Context.Functions[key]; // evaluate the function parameters object[] parameters = new object[0]; if (paramNode.Token.Type == TokenType.Params) { parameters = (paramNode.Evaluate(tree, paramlist) as List <object>).ToArray(); } if (parameters.Length < func.MinParameters) { tree.Errors.Add(new ParseError("At least " + func.MinParameters.ToString() + " parameter(s) expected", 1043, this)); return(null); // illegal number of parameters } else if (parameters.Length > func.MaxParameters) { tree.Errors.Add(new ParseError("No more than " + func.MaxParameters.ToString() + " parameter(s) expected", 1044, this)); return(null); // illegal number of parameters } return(func.Evaluate(parameters, root)); }
/// <summary> /// the list of parameters must correspond the the required set of Arguments /// </summary> /// <param name="parameters"></param> /// <returns></returns> public override object Evaluate(object[] parameters, ParseTreeEvaluator tree) { // create a new scope for the arguments Variables pars = Arguments.Clone(); // now push a copy of the function arguments on the stack tree.Context.PushScope(pars); // assign the parameters to the current function scope variables int i = 0; foreach (string key in pars.Keys) pars[key] = parameters[i++]; // execute the function here object result = Node.Evaluate(tree, null); // clean up the stack tree.Context.PopScope(); return result; }
public abstract object Evaluate(object[] parameters, ParseTreeEvaluator tree);
protected override object EvaluateExpression(ParseTree tree, params object[] paramlist) { // if only left hand side available, this is not an assignment, simple evaluate expression if (nodes.Count == 1) { return(this.GetValue(tree, TokenType.AssignmentExpression, 0)); // return the result } if (nodes.Count != 3) { tree.Errors.Add(new ParseError("Illegal EvaluateExpression format", 1092, this)); return(null); } // ok, this is an assignment so declare the function or variable // assignment only allowed to function or to a variable ParseNode v = GetFunctionOrVariable(nodes[0]); if (v == null) { tree.Errors.Add(new ParseError("Can only assign to function or variable", 1020, this)); return(null); } ParseTreeEvaluator root = tree as ParseTreeEvaluator; if (root == null) { tree.Errors.Add(new ParseError("Invalid parser used", 1040, this)); return(null); } if (root.Context == null) { tree.Errors.Add(new ParseError("No context defined", 1041, this)); return(null); } if (v.Token.Type == TokenType.VARIABLE) { // simply overwrite any previous defnition string key = v.Token.Text.ToLowerInvariant(); root.Context.Globals[key] = this.GetValue(tree, TokenType.AssignmentExpression, 1); return(null); } else if (v.Token.Type == TokenType.Function) { string key = v.Nodes[0].Token.Text; // function lookup is case insensitive if (root.Context.Functions.ContainsKey(key.ToLower())) { if (!(root.Context.Functions[key.ToLower()] is DynamicFunction)) { tree.Errors.Add(new ParseError("Built in functions cannot be overwritten", 1050, this)); return(null); } } // lets determine the input variables. // functions must be of te form f(x;y;z) = x+y*z; // check the function parameters to be of type Variable, error otherwise Variables vars = new Variables(); ParseNode paramsNode = v.Nodes[2]; if (paramsNode.Token.Type == TokenType.Params) { // function has parameters, so check if they are all variable declarations for (int i = 0; i < paramsNode.Nodes.Count; i += 2) { ParseNode varNode = GetFunctionOrVariable(paramsNode.Nodes[i]); if (varNode == null || varNode.Token.Type != TokenType.VARIABLE) { tree.Errors.Add(new ParseError("Function declaration may only contain variables", 1051, this)); return(null); } // simply declare the variable, no need to evaluate the value of it at this point. // evaluation will be done when the function is executed // note, variables are Case Sensitive (!) vars.Add(varNode.Token.Text, null); } } // we have all the info we need to know to declare the dynamicly defined function // pass on nodes[2] which is the Right Hand Side (RHS) of the assignment // nodes[2] will be evaluated at runtime when the function is executed. DynamicFunction dynf = new DynamicFunction(key, nodes[2], vars, vars.Count, vars.Count); root.Context.Functions[key.ToLower()] = dynf; return(null); } // in an assignment, dont return any result (basically void) return(null); }
public override object Evaluate(object[] parameters, ParseTreeEvaluator tree) { tree.Context.PushScope(null); object result = FunctionDelegate(parameters); tree.Context.PopScope(); return result; }