Ejemplo n.º 1
0
        // Builds the tree by pushing or popping on a stack
        // depending on which Node we are looking at
        private void BuildTree(Queue <string> output)
        {
            Stack <Node> nodes = new Stack <Node>();
            Decimal      num;

            // For every string on the output queue
            foreach (string s in output)
            {
                // Check if it is a number
                if (s.All(c => Char.IsDigit(c)) || Decimal.TryParse(s, out num))
                {
                    // Create new value node
                    nodes.Push(new ValNode(Convert.ToDouble(s)));
                }
                // Check if it is a variable
                else if (Char.IsLetter(s[0]))
                {
                    // Create new variable node
                    nodes.Push(new VarNode(s));
                }
                else
                {
                    // Create new operator node, and give it the last 2 things
                    // as it's children
                    OpNode temp = new OpNode(Convert.ToChar(s));
                    temp.rightChild = nodes.Pop();
                    temp.leftChild  = nodes.Pop();
                    nodes.Push(temp);
                }
            }
            // Pop the top of the stack and set it to root
            root = nodes.Pop();
        }
Ejemplo n.º 2
0
 static private void PerformOperation(OpNode operation, double val, ref double result) // Performs the operation contained in the opnode
 {
     if (operation.Value == "+")                                                       // Addition
     {
         result += val;
     }
     else if (operation.Value == "-") // Subtraction
     {
         result -= val;
     }
     else if (operation.Value == "*") // Multiplication
     {
         result *= val;
     }
     else // Division
     {
         if (val != 0) // ensures no dividing by zero
         {
             result /= val;
         }
         else // otherwise result will not change
         {
             throw new DivideByZeroException();
         }
     }
 }
Ejemplo n.º 3
0
        private double evalNode(Node node)
        {
            OpNode    op_node  = node as OpNode;
            ValueNode val_node = node as ValueNode;
            VarNode   var_node = node as VarNode;

            if (null != op_node)
            {
                switch (op_node.m_op)
                {
                case '+': return(evalNode(op_node.m_left) + evalNode(op_node.m_right));

                case '-': return(evalNode(op_node.m_left) - evalNode(op_node.m_right));

                case '*': return(evalNode(op_node.m_left) * evalNode(op_node.m_right));

                case '/': return(evalNode(op_node.m_left) / evalNode(op_node.m_right));

                case '^': return(Math.Pow(evalNode(op_node.m_left), evalNode(op_node.m_right)));
                }
            }

            if (null != val_node)//if node is a value node, return it's value
            {
                return(val_node.m_value);
            }

            if (null != var_node)               //if node is a variable, look up key in dictionary and return corresponding value
            {
                return(m_dict[var_node.m_var]); //will crash if variable isn't defined, so don't allows eval function to be called unless all variables are define. SEE allVarsDefined() function
            }

            return(0);//I don't know the how this code could get here, but the compiler wants something here
        }
Ejemplo n.º 4
0
        Node ConstructTree(string expression)
        {
            double value;

            for (int i = expression.Length - 1; i >= 0; i--)
            {
                switch (expression[i])
                {
                case '+':
                case '-':
                case '*':
                case '/':
                    OpNode newNode = new OpNode(expression[i]);
                    if (root == null)
                    {
                        root = newNode;
                    }
                    newNode.left  = ConstructTree(expression.Substring(0, i));
                    newNode.right = ConstructTree(expression.Substring(i + 1));
                    return(newNode);
                }
            }
            if (Double.TryParse(expression, out value))
            {
                return(new ValNode(value));
            }
            else
            {
                return(new VarNode(expression));
            }
        }
Ejemplo n.º 5
0
 public OperationTraceCollector()
 {
     _root = new OpNode {
         Id = Guid.NewGuid()
     };
     _currentNode = _root;
 }
Ejemplo n.º 6
0
        bool allVarsDefinedNode(Node node)
        {
            OpNode o = node as OpNode;

            if (o != null)//node is an OpNode
            {
                return(allVarsDefinedNode(o.m_left) && allVarsDefinedNode(o.m_right));
            }

            ValueNode value = node as ValueNode;

            if (value != null)//node is a ValueNode
            {
                return(true);
            }

            VarNode var = node as VarNode;

            if (var != null)                       //node is a VarNode
            {
                if (m_dict.ContainsKey(var.m_var)) //if key exists
                {
                    return(true);
                }
                else//if key is not in dictionary
                {
                    return(false);
                }
            }

            return(false);//Don't know how code would get here
        }
Ejemplo n.º 7
0
        // Build tree function. Takes in expression and separates operators from values and variables
        private void BuildTree(string exp)
        {
            // Use Regex Split to go through expression string and tokenize the string into substrings
            // Each substring that gets split is put into a List<string>
            // Each substring is made sure to be not empty
            // Regex Expression: ([+-/*\(\)])   :   Any operator or parentheses
            // Any variable or number will be separated by operators or parentheses.
            // So this makes sense to use the operators to do the splitting
            List <string> tokens = new List <string>();

            tokens = Regex.Split(exp, @"([+-/*\(\)])").Where(s => s != String.Empty).ToList <string>();
            // op       [+\\-/*()\\^]
            // digit    [\\d]+
            // variable [a-zA-Z]+;


            // Adds all the variables to a list to be used for our dictionary of dependencies
            foreach (string s in tokens)
            {
                if (Char.IsUpper(s[0]))
                {
                    varsForDeps.Add(s);
                }
            }

            // Convert from infix notation to reverse polish
            tokens = ToPolish(tokens);
            // Using a stack structure to create our tree
            // Operands are pushed onto the stack
            // Operators pop the necessary operands off the stack and set those as its children
            // This operator node then gets pushed onto the stack
            Stack <Node> stack = new Stack <Node>();

            foreach (string s in tokens)
            {
                // Creates variable node. Sets default value to zero
                if (Char.IsLetter(s, 0))
                {
                    stack.Push(new VarNode(s));
                    if (!(vars.ContainsKey(s)))
                    {
                        SetVar(s, 0);
                    }
                }
                else if (Char.IsDigit(s, 0))
                {
                    stack.Push(new ValNode(Convert.ToDouble(s)));
                }
                else
                {
                    OpNode temp = new OpNode(s[0]);
                    temp.rightChild = stack.Pop();
                    temp.leftChild  = stack.Pop();
                    stack.Push(temp);
                }
            }
            root = stack.Pop();
        }
Ejemplo n.º 8
0
        internal void StartOperation(Guid id, string name, string title, string message, string methodName, long startTicks)
        {
            var node = new OpNode {
                Id = id, Name = name, Title = title, Message = message, MethodName = methodName, StartTicks = startTicks
            };

            node.Parent = _currentNode;
            node.Parent.Children.Add(node);
            _currentNode = node;
        }
Ejemplo n.º 9
0
        internal void EndOperation(string message, bool successful, Guid id, long finishTicks, decimal secondsElapsed)
        {
            var node = _currentNode;

            node.Message     = message;
            node.Successful  = successful;
            node.FinishTicks = finishTicks;
            node.Duration    = secondsElapsed;
            _currentNode     = node.Parent;
        }
Ejemplo n.º 10
0
        public void WhenEvalIsCalledOnAnUnitializedOpNode_ShouldThrowInvalidOperationException()
        {
            // Arrange
            OpNode testOpNode = new OpNode();

            // Act
            testOpNode.Eval();

            // Assert is handled by the ExpectedException attribute on the test method.
        }
Ejemplo n.º 11
0
        //Calculates an Expression Tree given it's root node
        private double Evaluate(Node n)
        {
            if (n == null)
            {
                return(-1);
            }

            ConstNode constTest = n as ConstNode;

            if (constTest != null)
            {
                return(constTest.get_val());
            }

            VarNode varTest = n as VarNode;

            if (varTest != null)
            {
                try
                {
                    return(vDict[n.get_name()]);
                }
                catch (Exception c)
                {
                    Console.WriteLine("Key Not Found, Undefined Behavior");
                }
            }

            OpNode opTest = n as OpNode;

            if (opTest != null)
            {
                if (opTest.get_name() == "+")
                {
                    return(Evaluate(opTest.Left) + Evaluate(opTest.Right));
                }

                else if (opTest.get_name() == "-")
                {
                    return(Evaluate(opTest.Left) - Evaluate(opTest.Right));
                }

                else if (opTest.get_name() == "*")
                {
                    return(Evaluate(opTest.Left) * Evaluate(opTest.Right));
                }

                else if (opTest.get_name() == "/")
                {
                    return(Evaluate(opTest.Left) / Evaluate(opTest.Right));
                }
            }

            return(0.0); //default return value
        }
Ejemplo n.º 12
0
    Node ExprAdd()
    {
        Node left = ExprMul();

        while (!End() && GetChar() == '+')
        {
            char op    = NextChar();
            Node right = ExprMul();
            left = new OpNode(op, left, right);
        }
        return(left);
    }
Ejemplo n.º 13
0
        public void EvalMultiplyTest()
        {
            // Arrange
            double  testLeftValue  = 11.3214;
            double  testRightValue = 3485;
            ExpNode testLeftNode   = new ValNode(testLeftValue);
            ExpNode testRightNode  = new ValNode(testRightValue);

            OpNode testOpNode = new OpNode(ref testLeftNode, ref testRightNode, '*');

            // Act and Assert
            Assert.AreEqual((testLeftValue * testRightValue), testOpNode.Eval());
        }
Ejemplo n.º 14
0
        public override bool Amend(out Node node)
        {
            if (!base.Amend(out var group))
            {
                node = group;
                return(false);
            }

            //Magnitude of the grouped simplification
            node = new OpNode(Operation.Transform);
            node.Usurp(new FunctionNode(TransformName));
            node.Append(group);

            return(true);
        }
Ejemplo n.º 15
0
        // Compile tree
        Node Compile(string exp)
        {
            exp = RemoveOuterParens(exp);

            // get last op index
            int index = getOpIndex(exp);

            // if no op
            if (index == -1)
            {
                return(MakeSimple(exp));
            }
            // create op node
            OpNode mroot = new OpNode(exp[index]);

            mroot.pRight = Compile(exp.Substring(index + 1));
            mroot.pLeft  = Compile(exp.Substring(0, index));
            return(mroot);
        }
Ejemplo n.º 16
0
        Node processMultiTokenStream(string[] tokens)
        {
            // diveide and conquer: take first toplevel operator and recurse left
            // and right of it. sadly this cannot take operator precedence into account,
            // so the user will have to use brackets for this.

            //i.e. a term like 4 * 5 + 7 will become:
            //          Mul
            //      4     Add
            //           5   7
            // resulting in 4 being multiplied with 12 instead of 5.
            int i = GetLowestPrecendeOperatorIndex(tokens);

            // No top level operator found? We might have to deal with a call to
            // an inbuilt function, e.g. Sqrt(a + 10)
            if (i == -1)
            {
                if (tokens[0] == "{" && tokens[tokens.Length - 1] == "}")
                {
                    // this is probably a plain list.
                    var listEntries = parseParamlist(tokens.Skip(1).Take(tokens.Length - 2));
                    return(new ListNode(listEntries));
                }

                if (tokens[0] == "(" && tokens[tokens.Length - 1] == ")")
                {
                    return(parseTokenStream(tokens.Skip(1).Take(tokens.Length - 2).ToArray()));
                }

                return(CreateFuncCallNode(tokens));
            }

            // slice array.:
            var    left  = parseTokenStream(tokens.Take(i).ToArray());
            var    right = parseTokenStream(tokens.Skip(i + 1).ToArray());
            OpNode n     = CreateOpNode(tokens[i]);

            n.Left  = left;
            n.Right = right;
            return(n);
        }
Ejemplo n.º 17
0
        //description: traverse through the tree to return a hashet of the variable names
        //parameter: root node and hashset
        //return:
        public void GetVarsHelper(Node n, HashSet <string> vars)
        {
            if (n == null)
            {
                return;
            }

            if (n is VarNode)                //if variable node add variable name to hashset
            {
                VarNode var = n as VarNode;

                vars.Add(var.Name);
            }

            else if (n is OpNode)           //if operator node recurse into left and right node
            {
                OpNode op = n as OpNode;

                GetVarsHelper(op.Left, vars);
                GetVarsHelper(op.Right, vars);
            }
        }
Ejemplo n.º 18
0
 public OperationTraceCollector()
 {
     _root = new OpNode { Id = Guid.NewGuid() };
     _currentNode = _root;
 }
Ejemplo n.º 19
0
 internal void StartOperation(Guid id, string name, string title, string message, string methodName, long startTicks)
 {
     var node = new OpNode { Id = id, Name = name, Title = title, Message = message, MethodName = methodName, StartTicks = startTicks };
     node.Parent = _currentNode;
     node.Parent.Children.Add(node);
     _currentNode = node;
 }
Ejemplo n.º 20
0
 internal void EndOperation(string message, bool successful, Guid id, long finishTicks, decimal secondsElapsed)
 {
     var node = _currentNode;
     node.Message = message;
     node.Successful = successful;
     node.FinishTicks = finishTicks;
     node.Duration = secondsElapsed;
     _currentNode = node.Parent;
 }
Ejemplo n.º 21
0
 static private void PerformOperation(OpNode operation, double val, ref double result) // Performs the operation contained in the opnode
 {
     if (operation.Value == "+") // Addition
         result += val;
     else if (operation.Value == "-") // Subtraction
         result -= val;
     else if (operation.Value == "*") // Multiplication
         result *= val;
     else // Division
     {
         if (val != 0) // ensures no dividing by zero
             result /= val;
         else // otherwise result will not change
             throw new DivideByZeroException();
     }
 }
Ejemplo n.º 22
0
        void walkAST(object ast_node, List <string> varstack, byte varstack_callindex)
        {
            Type t = ast_node.GetType();

            if (NumericMap.ContainsKey(t))
            {
                this.bytecodes.Add(NumericMap[t]);

                Dictionary <Type, NumericCovert> ConvertMap = new Dictionary <Type, NumericCovert>
                {
                    { typeof(sbyte), () => BitConverter.GetBytes((sbyte)ast_node) },
                    { typeof(byte), () => BitConverter.GetBytes((byte)ast_node) },
                    { typeof(short), () => BitConverter.GetBytes((short)ast_node) },
                    { typeof(ushort), () => BitConverter.GetBytes((ushort)ast_node) },
                    { typeof(int), () => BitConverter.GetBytes((int)ast_node) },
                    { typeof(uint), () => BitConverter.GetBytes((uint)ast_node) },
                    { typeof(long), () => BitConverter.GetBytes((long)ast_node) },
                    { typeof(float), () => BitConverter.GetBytes((float)ast_node) },
                    { typeof(double), () => BitConverter.GetBytes((double)ast_node) }
                };

                foreach (byte item in ConvertMap[t]())
                {
                    this.bytecodes.Add(item);
                }
            }
            else if (t == typeof(string) || t == typeof(char))
            {
                string node = ast_node.ToString();

                this.bytecodes.Add((byte)Opdata.iot);

                if (this.textstack_map.ContainsKey(node))
                {
                    this.walkAST(this.textstack_map[node], null, 0);
                }
                else
                {
                    foreach (byte item in Encoding.Unicode.GetBytes(node))
                    {
                        this.textstack_bytes.Add(item);
                    }

                    this.textstack_bytes.Add(Definition.EOT);
                    this.textstack_bytes.Add(0);

                    this.textstack_map[node] = this.textstack_index;

                    this.walkAST(this.textstack_index, null, 0);

                    this.textstack_index += 1;
                }
            }
            else if (t == typeof(OpNode))
            {
                OpNode node = (OpNode)ast_node;

                if (node.opcode == (byte)Opexplicit.scope)
                {
                    // node.arguments[0] is the variable name
                    // node.arguments[1] is the content
                    if (node.arguments.Count >= 2)
                    {
                        varstack.Add(node.arguments[0].ToString());

                        this.walkAST(node.arguments[1], varstack, varstack_callindex);

                        this.bytecodes.Add(node.opcode);
                    }

                    foreach (object item in node.body)
                    {
                        this.walkAST(item, varstack, varstack_callindex);
                    }

                    if (node.arguments.Count >= 2)
                    {
                        varstack.RemoveAt(varstack.Count - 1);
                        this.bytecodes.Add((byte)Opimplicit.sweep);
                    }
                }
                else if (node.opcode == (byte)Opexplicit.get)
                {
                    string name      = node.body[0].ToString();
                    bool   not_found = true;

                    for (int l = varstack.Count; l-- != 0;)
                    {
                        if (name == varstack[l])
                        {
                            if (l < varstack_callindex)
                            {
                                this.bytecodes.Add(node.opcode);
                                this.bytecodes.Add((byte)l);
                            }
                            else
                            {
                                this.bytecodes.Add((byte)Opimplicit.localfget);
                                this.bytecodes.Add((byte)(l - varstack_callindex));
                            }

                            not_found = false;
                            break;
                        }
                    }

                    if (not_found)
                    {
                        throw new Exception("no variable " + name + " in scope");
                    }
                }
                else if (node.opcode == (byte)Opexplicit.func)
                {
                    this.bytecodes.Add(node.opcode);

                    // ======= set the length of function body ========
                    this.bytecodes.Add(0);
                    this.bytecodes.Add(0);
                    this.bytecodes.Add(0);
                    this.bytecodes.Add(0);

                    // ======= push variables to var stack ========
                    int bytecodes_len = this.bytecodes.Count;

                    this.bytecodes.Add((byte)node.arguments.Count);

                    varstack_callindex = (byte)varstack.Count;

                    foreach (object item in node.arguments)
                    {
                        varstack.Add(item.ToString());
                    }

                    // ========= walk through function body ==========
                    foreach (object item in node.body)
                    {
                        this.walkAST(item, varstack, varstack_callindex);
                    }

                    // ========= jump back to origin pc =============
                    this.bytecodes.Add((byte)Opimplicit.sweepn);
                    this.bytecodes.Add((byte)Opimplicit.jump);

                    // ========= clean up ===========
                    int args_len = node.arguments.Count;
                    while (args_len != 0)
                    {
                        args_len -= 1;
                        varstack.RemoveAt(varstack.Count - 1);
                    }

                    // ========= set function body length ============
                    byte[] offset_bytes = BitConverter.GetBytes((uint)(this.bytecodes.Count - bytecodes_len));
                    this.bytecodes[bytecodes_len - 4] = offset_bytes[0];
                    this.bytecodes[bytecodes_len - 3] = offset_bytes[1];
                    this.bytecodes[bytecodes_len - 2] = offset_bytes[2];
                    this.bytecodes[bytecodes_len - 1] = offset_bytes[3];
                }
                else if (node.opcode == (byte)Opexplicit.ifElse)
                {
                    // push condition on stack
                    this.walkAST(node.body[0], varstack, varstack_callindex);

                    this.bytecodes.Add(node.opcode);

                    // else branch addresss
                    int else_val_address = this.bytecodes.Count;
                    this.bytecodes.Add(0);
                    this.bytecodes.Add(0);
                    this.bytecodes.Add(0);
                    this.bytecodes.Add(0);

                    // body of branch true
                    this.walkAST(node.body[1], varstack, varstack_callindex);

                    // exit address
                    this.bytecodes.Add((byte)Opdata.uint32);

                    int exit_val_address = this.bytecodes.Count;
                    this.bytecodes.Add(0);
                    this.bytecodes.Add(0);
                    this.bytecodes.Add(0);
                    this.bytecodes.Add(0);

                    this.bytecodes.Add((byte)Opimplicit.jumpoffset);

                    byte[] offset_bytes = BitConverter.GetBytes((uint)(this.bytecodes.Count - else_val_address));
                    this.bytecodes[else_val_address + 0] = offset_bytes[0];
                    this.bytecodes[else_val_address + 1] = offset_bytes[1];
                    this.bytecodes[else_val_address + 2] = offset_bytes[2];
                    this.bytecodes[else_val_address + 3] = offset_bytes[3];

                    // body of branch false
                    this.walkAST(node.body[2], varstack, varstack_callindex);

                    byte[] exit_address_bytes = BitConverter.GetBytes((uint)(this.bytecodes.Count - (exit_val_address + 5)));
                    this.bytecodes[exit_val_address + 0] = exit_address_bytes[0];
                    this.bytecodes[exit_val_address + 1] = exit_address_bytes[1];
                    this.bytecodes[exit_val_address + 2] = exit_address_bytes[2];
                    this.bytecodes[exit_val_address + 3] = exit_address_bytes[3];
                }
                else
                {
                    foreach (object item in node.body)
                    {
                        this.walkAST(item, varstack, varstack_callindex);
                    }

                    this.bytecodes.Add(node.opcode);

                    if (Enum.IsDefined(typeof(Opexplicit), node.opcode) && !Definition.OpWithTwoArgs.Contains((Opexplicit)node.opcode))
                    {
                        this.bytecodes.Add((byte)node.body.Count);
                    }
                }
            }
        }