Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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;
 }
Beispiel #5
0
        /// <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);
        }
Beispiel #6
0
        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;
        }
Beispiel #7
0
        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));
        }
Beispiel #8
0
        /// <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;
        }
Beispiel #9
0
 public abstract object Evaluate(object[] parameters, ParseTreeEvaluator tree);
Beispiel #10
0
        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);
        }
Beispiel #11
0
 public override object Evaluate(object[] parameters, ParseTreeEvaluator tree)
 {
     tree.Context.PushScope(null);
     object result = FunctionDelegate(parameters);
     tree.Context.PopScope();
     return result;
 }
Beispiel #12
0
 public abstract object Evaluate(object[] parameters, ParseTreeEvaluator tree);