示例#1
0
        T Fold <T>(ArithmeticBinaryExpression n) where T : struct
        {
            var vleft  = n.left.Value.Val <T>();
            var vright = n.right.Value.Val <T>();

            switch (n.op)
            {
            case ArithmeticBinaryOp.ADD: return(Operator.Add(vleft, vright));

            case ArithmeticBinaryOp.SUB: return(Operator.Subtract(vleft, vright));

            case ArithmeticBinaryOp.MUL: return(Operator.Multiply(vleft, vright));

            case ArithmeticBinaryOp.QUOT: return(Operator.Add(vleft, vright));

            case ArithmeticBinaryOp.DIV: return(Operator.Divide(vleft, vright));

            case ArithmeticBinaryOp.MOD: return(Operator.DivideInt32(vleft, n.right.Value.Val <int>()));

            // TODO
            //	case ArithmeticBinaryOp.SHL: return Operator
            //	case ArithmeticBinaryOp.SHR: return Operator
            default:        throw new SemanticException("Constant folding of operator not yet supported");
            }
        }
示例#2
0
 public override bool Visit(ArithmeticBinaryExpression node)
 {
     Visit((BinaryExpression)node);
     TraverseSetParent(node, node.left);
     TraverseSetParent(node, node.right);
     return(true);
 }
示例#3
0
        public override bool Visit(ArithmeticBinaryExpression node)
        {
            Visit(node.left);
            Visit(node.right);

            if (node.left.Value == null || node.right == null)
            {
                return(false);
            }

            if (node.Type is IntegerType)
            {
                node.Value = new IntegralValue(Fold <long>(node));
            }
            if (node.Type is CharType)
            {
                node.Value = new IntegralValue(Fold <char>(node));
            }
            if (node.Type is BoolType)
            {
                node.Value = new IntegralValue(Fold <bool>(node));
            }
            else if (node.Type is RealType)
            {
                node.Value = new RealValue(Fold <double>(node));
            }

            // TODO strings

            return(true);
        }
示例#4
0
        public void ExecuteForCommand()
        {
            ICommand        setX     = new SetVariableCommand("x", new ConstantExpression(0));
            ICommand        setY     = new SetVariableCommand("y", new ConstantExpression(0));
            List <ICommand> commands = new List <ICommand>();

            commands.Add(setX);
            commands.Add(setY);
            ICommand initialCommand = new CompositeCommand(commands);

            IExpression condition = new CompareExpression(ComparisonOperator.Less, new VariableExpression("x"), new ConstantExpression(6));

            IExpression addXtoY = new ArithmeticBinaryExpression(ArithmeticOperator.Add, new VariableExpression("y"), new VariableExpression("x"));
            ICommand    addToY  = new SetVariableCommand("y", addXtoY);

            ICommand endCommand = new SetVariableCommand("x", new ArithmeticBinaryExpression(ArithmeticOperator.Add, new VariableExpression("x"), new ConstantExpression(1)));

            ForCommand forcmd = new ForCommand(initialCommand, condition, endCommand, addToY);

            BindingEnvironment environment = new BindingEnvironment();

            environment.SetValue("y", null);

            forcmd.Execute(environment);

            Assert.AreEqual(15, environment.GetValue("y"));
        }
示例#5
0
        public void ExecuteWhileCommand()
        {
            IExpression     incrementX = new ArithmeticBinaryExpression(ArithmeticOperator.Add, new ConstantExpression(1), new VariableExpression("x"));
            IExpression     decrementY = new ArithmeticBinaryExpression(ArithmeticOperator.Subtract, new VariableExpression("y"), new ConstantExpression(1));
            ICommand        setX       = new SetVariableCommand("x", incrementX);
            ICommand        setY       = new SetVariableCommand("y", decrementY);
            List <ICommand> commands   = new List <ICommand>();

            commands.Add(setX);
            commands.Add(setY);
            ICommand    command = new CompositeCommand(commands);
            IExpression yexpr   = new VariableExpression("y");

            WhileCommand whilecmd = new WhileCommand(yexpr, command);

            BindingEnvironment environment = new BindingEnvironment();

            environment.SetValue("x", 0);
            environment.SetValue("y", 5);

            whilecmd.Execute(environment);

            Assert.AreEqual(0, environment.GetValue("y"));
            Assert.AreEqual(5, environment.GetValue("x"));
        }
示例#6
0
 public void Visit(ArithmeticBinaryExpression expr)
 {
     this.writer.Write("(");
     expr.LeftExpression.Accept(this);
     this.writer.Write(string.Format(" {0} ", operators[expr.Operation]));
     expr.RightExpression.Accept(this);
     this.writer.Write(")");
 }
示例#7
0
        public void DecompileCompositeCommand()
        {
            IExpression expression = new ArithmeticBinaryExpression(ArithmeticOperation.Add, new ConstantExpression(1), new ConstantExpression(2));
            ICommand    command1   = new SetCommand("a", expression);
            ICommand    command2   = new SetCommand("b", expression);
            ICommand    command    = new CompositeCommand(new ICommand[] { command1, command2 });

            Assert.AreEqual("{\r\na = (1 + 2);\r\nb = (1 + 2);\r\n}\r\n", this.Decompile(command));
        }
示例#8
0
        public void CreateBinaryExpression()
        {
            IExpression      leftExpression  = new ConstantExpression(1);
            IExpression      rightExpression = new ConstantExpression(2);
            BinaryExpression expression      = new ArithmeticBinaryExpression(ArithmeticOperator.Add, leftExpression, rightExpression);

            Assert.IsTrue(expression.LeftExpression == leftExpression);
            Assert.IsTrue(expression.RightExpression == rightExpression);
        }
示例#9
0
        public void ParseSimpleSum()
        {
            Parser parser = new Parser("1+2");
            var    result = parser.ParseExpression();

            Assert.IsNull(parser.ParseExpression());

            Assert.IsNotNull(result);
            Assert.IsInstanceOfType(result, typeof(ArithmeticBinaryExpression));

            ArithmeticBinaryExpression expression = (ArithmeticBinaryExpression)result;

            Assert.IsInstanceOfType(expression.LeftExpression, typeof(ConstantExpression));
            Assert.IsInstanceOfType(expression.RightExpression, typeof(ConstantExpression));
        }
示例#10
0
        public void ParseSimpleBinaryExpressionWithParenthesis()
        {
            IExpression expression = ParseExpression("((a) + (2))");

            Assert.IsNotNull(expression);
            Assert.IsInstanceOfType(expression, typeof(ArithmeticBinaryExpression));

            ArithmeticBinaryExpression operation = (ArithmeticBinaryExpression)expression;

            Assert.AreEqual(ArithmeticOperator.Add, operation.Operation);
            Assert.IsNotNull(operation.LeftExpression);
            Assert.IsInstanceOfType(operation.LeftExpression, typeof(LocalVariableExpression));
            Assert.IsNotNull(operation.RightExpression);
            Assert.IsInstanceOfType(operation.RightExpression, typeof(ConstantExpression));
        }
示例#11
0
        public void ParseTwoBinaryExpression()
        {
            IExpression expression = ParseExpression("a + 2 - 3");

            Assert.IsNotNull(expression);
            Assert.IsInstanceOfType(expression, typeof(ArithmeticBinaryExpression));

            ArithmeticBinaryExpression operation = (ArithmeticBinaryExpression)expression;

            Assert.AreEqual(ArithmeticOperator.Subtract, operation.Operation);
            Assert.IsNotNull(operation.LeftExpression);
            Assert.IsInstanceOfType(operation.LeftExpression, typeof(ArithmeticBinaryExpression));
            Assert.IsNotNull(operation.RightExpression);
            Assert.IsInstanceOfType(operation.RightExpression, typeof(ConstantExpression));
        }
示例#12
0
        public void ParseSimpleSum()
        {
            Parser parser = new Parser("1+2");
            var    result = parser.ParseExpression();

            Assert.IsNull(parser.ParseExpression());

            Assert.IsNotNull(result);
            Assert.That(result is ArithmeticBinaryExpression);

            ArithmeticBinaryExpression expression = (ArithmeticBinaryExpression)result;

            Assert.That(expression.LeftExpression is ConstantExpression);
            Assert.That(expression.RightExpression is ConstantExpression);
        }
示例#13
0
        public void ParseModExpression()
        {
            IExpression expression = ParseExpression("a % 2");

            Assert.IsNotNull(expression);
            Assert.IsInstanceOfType(expression, typeof(ArithmeticBinaryExpression));

            ArithmeticBinaryExpression operation = (ArithmeticBinaryExpression)expression;

            Assert.AreEqual(ArithmeticOperator.Modulo, operation.Operation);
            Assert.IsNotNull(operation.LeftExpression);
            Assert.IsInstanceOfType(operation.LeftExpression, typeof(VariableExpression));
            Assert.IsNotNull(operation.RightExpression);
            Assert.IsInstanceOfType(operation.RightExpression, typeof(ConstantExpression));
        }
示例#14
0
        public void ExecuteForEachCommand()
        {
            IExpression addToX = new ArithmeticBinaryExpression(ArithmeticOperator.Add, new VariableExpression("b"), new VariableExpression("a"));
            ICommand    setX   = new SetVariableCommand("a", addToX);
            IExpression values = new ConstantExpression(new int [] { 1, 2, 3 });

            ForEachCommand foreachcmd = new ForEachCommand("b", values, setX);

            Context context = new Context();

            context.SetValue("a", 0);

            foreachcmd.Execute(context);

            Assert.AreEqual(6, context.GetValue("a"));
        }
示例#15
0
        public void ExecuteForEachCommand()
        {
            IExpression addToX = new ArithmeticBinaryExpression(ArithmeticOperator.Add, new VariableExpression("y"), new VariableExpression("x"));
            ICommand    setX   = new SetVariableCommand("x", addToX);
            IExpression values = new ConstantExpression(new int [] { 1, 2, 3 });

            ForEachCommand foreachcmd = new ForEachCommand("y", values, setX);

            BindingEnvironment environment = new BindingEnvironment();

            environment.SetValue("x", 0);

            foreachcmd.Execute(environment);

            Assert.AreEqual(6, environment.GetValue("x"));
        }
示例#16
0
        // Currently only working with ints
        public override Value Visit(ArithmeticBinaryExpression node)
        {
            Visit((BinaryExpression)node);
            Value l = traverse(node.left);
            Value r = traverse(node.right);

            if (l.IsNull || r.IsNull)
            {
                return(Value.Null);
            }

            switch (node.op)
            {
            case ArithmeticBinaryOp.ADD:
                return(builder.BuildAdd(l, r));

            case ArithmeticBinaryOp.SUB:
                return(builder.BuildSub(l, r));

            case ArithmeticBinaryOp.MUL:
                return(builder.BuildMul(l, r));

            case ArithmeticBinaryOp.DIV:
                return(builder.BuildUDiv(l, r));

            case ArithmeticBinaryOp.QUOT:
                return(builder.BuildMul(l, r));

            case ArithmeticBinaryOp.MOD:
                return(builder.BuildURem(l, r));

            case ArithmeticBinaryOp.SHR:
                return(builder.BuildLShr(l, r));

            case ArithmeticBinaryOp.SHL:
                return(builder.BuildShl(l, r));

            default:                            // never happens
                Error("Invalid arithmetic binary operator: " + node.op, node);
                return(Value.Null);
            }
        }
示例#17
0
        private IExpression ParseBinaryExpressionSecondLevel()
        {
            IExpression expression = this.ParseUnaryExpression();

            if (expression == null)
            {
                return(null);
            }

            while (this.TryParse(TokenType.Operator, "*", "/", @"\"))
            {
                Token              oper  = this.lexer.NextToken();
                IExpression        right = this.ParseUnaryExpression();
                ArithmeticOperator op    = oper.Value == "*" ? ArithmeticOperator.Multiply : (oper.Value == "/" ? ArithmeticOperator.Divide : ArithmeticOperator.IntegerDivide);

                expression = new ArithmeticBinaryExpression(op, expression, right);
            }

            return(expression);
        }
示例#18
0
        private IExpression ParseBinaryExpressionFirstLevel()
        {
            IExpression expression = this.ParseBinaryExpressionSecondLevel();

            if (expression == null)
            {
                return(null);
            }

            while (this.TryParse(TokenType.Operator, "+", "-"))
            {
                Token              oper  = this.lexer.NextToken();
                IExpression        right = this.ParseBinaryExpressionSecondLevel();
                ArithmeticOperator op    = oper.Value == "+" ? ArithmeticOperator.Add : ArithmeticOperator.Subtract;

                expression = new ArithmeticBinaryExpression(op, expression, right);
            }

            return(expression);
        }
示例#19
0
        private IExpression ParseBinaryExpressionSecondLevel()
        {
            IExpression expression = this.ParseUnaryExpression();

            if (expression == null)
            {
                return(null);
            }

            while (this.TryParse(TokenType.Operator, "*", "/", @"\", "%"))
            {
                Token              oper  = this.lexer.NextToken();
                IExpression        right = this.ParseUnaryExpression();
                ArithmeticOperator op;

                if (oper.Value == "*")
                {
                    op = ArithmeticOperator.Multiply;
                }
                else if (oper.Value == "/")
                {
                    op = ArithmeticOperator.Divide;
                }
                else if (oper.Value == "\\")
                {
                    op = ArithmeticOperator.IntegerDivide;
                }
                else if (oper.Value == "%")
                {
                    op = ArithmeticOperator.Modulo;
                }
                else
                {
                    throw new ParserException(string.Format("Invalid operator '{0}'", oper.Value));
                }

                expression = new ArithmeticBinaryExpression(op, expression, right);
            }

            return(expression);
        }
示例#20
0
        public void ParseTwoBinaryExpressionDifferentLevels()
        {
            IExpression expression = ParseExpression("a + 2 * 3");

            Assert.IsNotNull(expression);
            Assert.IsInstanceOfType(expression, typeof(ArithmeticBinaryExpression));

            ArithmeticBinaryExpression arithmeticExpression = (ArithmeticBinaryExpression)expression;

            Assert.AreEqual(ArithmeticOperator.Add, arithmeticExpression.Operation);
            Assert.IsNotNull(arithmeticExpression.LeftExpression);
            Assert.IsInstanceOfType(arithmeticExpression.LeftExpression, typeof(VariableExpression));
            Assert.IsNotNull(arithmeticExpression.RightExpression);
            Assert.IsInstanceOfType(arithmeticExpression.RightExpression, typeof(ArithmeticBinaryExpression));

            ArithmeticBinaryExpression rigthExpression = (ArithmeticBinaryExpression)arithmeticExpression.RightExpression;

            Assert.AreEqual(ArithmeticOperator.Multiply, rigthExpression.Operation);
            Assert.IsInstanceOfType(rigthExpression.LeftExpression, typeof(ConstantExpression));
            Assert.IsInstanceOfType(rigthExpression.RightExpression, typeof(ConstantExpression));
        }
示例#21
0
        private static object EvaluateArithmeticBinaryOperator(ArithmeticOperator operation, object left, object right)
        {
            IExpression expression = new ArithmeticBinaryExpression(operation, new ConstantExpression(left), new ConstantExpression(right));

            return(expression.Evaluate(null));
        }
示例#22
0
        public void AddTwoIntegers()
        {
            IExpression expression = new ArithmeticBinaryExpression(ArithmeticOperation.Add, new ConstantExpression(1), new ConstantExpression(2));

            Assert.AreEqual(3, expression.Evaluate(null));
        }
示例#23
0
        private IExpression ParseStringInterpolation(string text)
        {
            IList <IExpression> expressions = new List <IExpression>();

            while (true)
            {
                int pos = text.IndexOf('$');

                if (pos < 0)
                {
                    if (!string.IsNullOrEmpty(text))
                    {
                        IExpression textexpr = new ConstantExpression(text);
                        expressions.Add(textexpr);
                    }

                    break;
                }

                if (pos == text.Length - 1)
                {
                    throw new ParserException("Unexpected End of String");
                }

                string left = text.Substring(0, pos);

                if (!string.IsNullOrEmpty(left))
                {
                    expressions.Add(new ConstantExpression(left));
                }

                if (text[pos + 1] == '{')
                {
                    int pos2 = text.IndexOf('}', pos + 1);

                    if (pos2 < 0)
                    {
                        throw new ParserException("Unexpected End of String");
                    }

                    string subtext = text.Substring(pos + 2, pos2 - pos - 2);
                    text = text.Substring(pos2 + 1);

                    Parser parser = new Parser(subtext);

                    IExpression newexpr = parser.ParseExpression();

                    if (parser.ParseExpression() != null)
                    {
                        throw new ParserException("Bad String Interpolation");
                    }

                    expressions.Add(newexpr);
                }
                else if (char.IsLetter(text[pos + 1]))
                {
                    Parser      parser  = new Parser(text.Substring(pos + 1));
                    string      name    = parser.ParseName();
                    IExpression varexpr = new VariableExpression(name);
                    expressions.Add(varexpr);
                    text = text.Substring(pos + name.Length + 1);
                }
                else
                {
                    throw new ParserException("Bad String Interpolation");
                }
            }

            if (expressions.Count == 1)
            {
                return(expressions[0]);
            }

            IExpression expression = expressions[0];

            foreach (var expr in expressions.Skip(1))
            {
                expression = new ArithmeticBinaryExpression(ArithmeticOperator.Add, expression, expr);
            }

            return(expression);
        }
示例#24
0
        public void SubtractTwoIntegers()
        {
            IExpression expression = new ArithmeticBinaryExpression(ArithmeticOperation.Substract, new ConstantExpression(1), new ConstantExpression(2));

            Assert.AreEqual(-1, expression.Evaluate(null));
        }
示例#25
0
        public void DivideTwoIntegers()
        {
            IExpression expression = new ArithmeticBinaryExpression(ArithmeticOperation.Divide, new ConstantExpression(3), new ConstantExpression(2));

            Assert.AreEqual(3 / 2, expression.Evaluate(null));
        }
示例#26
0
        public void MultiplyTwoIntegers()
        {
            IExpression expression = new ArithmeticBinaryExpression(ArithmeticOperation.Multiply, new ConstantExpression(3), new ConstantExpression(2));

            Assert.AreEqual(6, expression.Evaluate(null));
        }