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"); } }
public override bool Visit(ArithmeticBinaryExpression node) { Visit((BinaryExpression)node); TraverseSetParent(node, node.left); TraverseSetParent(node, node.right); return(true); }
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); }
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")); }
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")); }
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(")"); }
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)); }
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); }
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)); }
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)); }
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)); }
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); }
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)); }
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")); }
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")); }
// 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); } }
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); }
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); }
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); }
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)); }
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)); }
public void AddTwoIntegers() { IExpression expression = new ArithmeticBinaryExpression(ArithmeticOperation.Add, new ConstantExpression(1), new ConstantExpression(2)); Assert.AreEqual(3, expression.Evaluate(null)); }
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); }
public void SubtractTwoIntegers() { IExpression expression = new ArithmeticBinaryExpression(ArithmeticOperation.Substract, new ConstantExpression(1), new ConstantExpression(2)); Assert.AreEqual(-1, expression.Evaluate(null)); }
public void DivideTwoIntegers() { IExpression expression = new ArithmeticBinaryExpression(ArithmeticOperation.Divide, new ConstantExpression(3), new ConstantExpression(2)); Assert.AreEqual(3 / 2, expression.Evaluate(null)); }
public void MultiplyTwoIntegers() { IExpression expression = new ArithmeticBinaryExpression(ArithmeticOperation.Multiply, new ConstantExpression(3), new ConstantExpression(2)); Assert.AreEqual(6, expression.Evaluate(null)); }