Пример #1
0
        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);
                }
            }
        }
Пример #2
0
        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);
        }
Пример #4
0
 public abstract void Visit(BinOpExpression expression);
Пример #5
0
 public override void Visit(BinOpExpression expression)
 {
     throw new NotImplementedException();
 }