protected override object EvalExpression(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 EvalExpression 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; 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); }
protected override object EvalStart(ParseTree tree, params object[] paramlist) { return(this.GetValue(tree, TokenType.Expression, 0)); }
protected virtual object EvalStringLiteral(ParseTree tree, params object[] paramlist) { throw new NotImplementedException(); }
protected virtual object EvalVariable(ParseTree tree, params object[] paramlist) { throw new NotImplementedException(); }
protected virtual object EvalAssignmentExpression(ParseTree tree, params object[] paramlist) { throw new NotImplementedException(); }
protected virtual object EvalMultiplicativeExpression(ParseTree tree, params object[] paramlist) { throw new NotImplementedException(); }
protected virtual object EvalStart(ParseTree tree, params object[] paramlist) { return("Could not interpret input; no semantics implemented."); }
/// <summary> /// this implements the evaluation functionality, cannot be used directly /// </summary> /// <param name="tree">the parsetree itself</param> /// <param name="paramlist">optional input parameters</param> /// <returns>a partial result of the evaluation</returns> internal object Eval(ParseTree tree, params object[] paramlist) { object Value = null; switch (Token.Type) { case TokenType.Start: Value = EvalStart(tree, paramlist); break; case TokenType.Function: Value = EvalFunction(tree, paramlist); break; case TokenType.PrimaryExpression: Value = EvalPrimaryExpression(tree, paramlist); break; case TokenType.ParenthesizedExpression: Value = EvalParenthesizedExpression(tree, paramlist); break; case TokenType.UnaryExpression: Value = EvalUnaryExpression(tree, paramlist); break; case TokenType.PowerExpression: Value = EvalPowerExpression(tree, paramlist); break; case TokenType.MultiplicativeExpression: Value = EvalMultiplicativeExpression(tree, paramlist); break; case TokenType.AdditiveExpression: Value = EvalAdditiveExpression(tree, paramlist); break; case TokenType.ConcatEpression: Value = EvalConcatEpression(tree, paramlist); break; case TokenType.RelationalExpression: Value = EvalRelationalExpression(tree, paramlist); break; case TokenType.EqualityExpression: Value = EvalEqualityExpression(tree, paramlist); break; case TokenType.ConditionalAndExpression: Value = EvalConditionalAndExpression(tree, paramlist); break; case TokenType.ConditionalOrExpression: Value = EvalConditionalOrExpression(tree, paramlist); break; case TokenType.AssignmentExpression: Value = EvalAssignmentExpression(tree, paramlist); break; case TokenType.Expression: Value = EvalExpression(tree, paramlist); break; case TokenType.Params: Value = EvalParams(tree, paramlist); break; case TokenType.Literal: Value = EvalLiteral(tree, paramlist); break; case TokenType.IntegerLiteral: Value = EvalIntegerLiteral(tree, paramlist); break; case TokenType.RealLiteral: Value = EvalRealLiteral(tree, paramlist); break; case TokenType.StringLiteral: Value = EvalStringLiteral(tree, paramlist); break; case TokenType.Variable: Value = EvalVariable(tree, paramlist); break; default: Value = Token.Text; break; } return(Value); }
protected object GetValue(ParseTree tree, TokenType type, int index) { return(GetValue(tree, type, ref index)); }