public override void Visit(BinOpExpression expression) { expression.Left.AcceptVisitor(this); var type1 = ResultType; expression.Right.AcceptVisitor(this); var type2 = ResultType; if (expression.Operation == BinOps.Add || expression.Operation == BinOps.Div || expression.Operation == BinOps.Mul || expression.Operation == BinOps.Sub) { if (type1 == typeof(int)) { if (type2 == typeof(long)) { throw new InvalidProgramException("Operation types are invalid"); } ResultType = typeof(int); } else if (type1 == typeof(long)) { if (type2 == typeof(int)) { throw new InvalidProgramException("Operation types are invalid"); } ResultType = typeof(long); } } }
private static Expression ProcessExpression(Expression exp) { if (exp is BinOpExpression) { var binOp = (BinOpExpression)exp; if (binOp.Operation == BinOps.Mul && binOp.Right is LiteralExpression) { // Decompose multiplication into shifts, e.g. x * 3 => x << 1 + x uint literal = ((LiteralExpression)binOp.Right).Value; if (literal == 0) { return((LiteralExpression)0); } if (literal == 1) { return(binOp.Left); } uint bits = NumberOfSetBits(literal); if (bits <= 2) { var sum = new List <Expression>(); int n = 0; while (literal != 0) { if ((literal & 1) != 0) { if (n == 0) { sum.Add(binOp.Left); } else { sum.Add(binOp.Left << n); } } literal >>= 1; n++; } BinOpExpression x = sum.OfType <BinOpExpression>().First(); foreach (Expression i in sum.Except(new[] { x })) { x += i; } return(x); } } else { binOp.Left = ProcessExpression(binOp.Left); binOp.Right = ProcessExpression(binOp.Right); } } else if (exp is ArrayIndexExpression) { ((ArrayIndexExpression)exp).Array = ProcessExpression(((ArrayIndexExpression)exp).Array); } else if (exp is UnaryOpExpression) { ((UnaryOpExpression)exp).Value = ProcessExpression(((UnaryOpExpression)exp).Value); } return(exp); }
private static Expression GenerateInverse(Expression exp, Expression var, Dictionary <Expression, bool> hasVar) { var result = var; while (!(exp is VariableExpression)) { Debug.Assert(hasVar[exp]); if (exp is UnaryOpExpression) { var unaryOp = (UnaryOpExpression)exp; result = new UnaryOpExpression { Operation = unaryOp.Operation, Value = result }; exp = unaryOp.Value; } else if (exp is BinOpExpression) { var binOp = (BinOpExpression)exp; var leftHasVar = hasVar[binOp.Left]; var varExp = leftHasVar ? binOp.Left : binOp.Right; var constExp = leftHasVar ? binOp.Right : binOp.Left; if (binOp.Operation == BinOps.Add) { result = new BinOpExpression { Operation = BinOps.Sub, Left = result, Right = constExp }; } else if (binOp.Operation == BinOps.Sub) { if (leftHasVar) { result = new BinOpExpression { Operation = BinOps.Add, Left = result, Right = constExp } } ; else { result = new BinOpExpression { Operation = BinOps.Sub, Left = constExp, Right = result } }; } else if (binOp.Operation == BinOps.Mul) { Debug.Assert(constExp is LiteralExpression); var val = ((LiteralExpression)constExp).Value; val = MathsUtils.modInv(val); result = new BinOpExpression { Operation = BinOps.Mul, Left = result, Right = (LiteralExpression)val }; } else if (binOp.Operation == BinOps.Xor) { result = new BinOpExpression { Operation = BinOps.Xor, Left = result, Right = constExp }; } exp = varExp; } } return(result); }
public abstract void Visit(BinOpExpression expression);
public override void Visit(BinOpExpression expression) { throw new NotImplementedException(); }