コード例 #1
0
        protected object Visit(BinaryExpression expression)
        {
            switch (expression.NodeType)
            {
            case ExpressionType.OrElse:
            {
                var left = this.Visit(expression.Left);

                if ((bool)left)
                {
                    return(true);
                }

                return((bool)this.Visit(expression.Right));
            }

            case ExpressionType.AndAlso:
            {
                var left = this.Visit(expression.Left);

                if (!(bool)left)
                {
                    return(false);
                }

                return((bool)this.Visit(expression.Right));
            }

            case ExpressionType.Or:
            {
                var left  = (long)Convert.ChangeType(this.Visit(expression.Left), typeof(long));
                var right = (long)Convert.ChangeType(this.Visit(expression.Right), typeof(long));

                return(Convert.ChangeType(left | right, expression.Type));
            }

            case ExpressionType.And:
            {
                var left  = (long)Convert.ChangeType(this.Visit(expression.Left), typeof(long));
                var right = (long)Convert.ChangeType(this.Visit(expression.Right), typeof(long));

                return(Convert.ChangeType(left & right, expression.Type));
            }

            case ExpressionType.ExclusiveOr:
            {
                var left  = (long)Convert.ChangeType(this.Visit(expression.Left), typeof(long));
                var right = (long)Convert.ChangeType(this.Visit(expression.Right), typeof(long));

                return(Convert.ChangeType(left ^ right, expression.Type));
            }

            case ExpressionType.Equal:
            case ExpressionType.NotEqual:
            {
                if (expression.Type == typeof(bool))
                {
                    var left = this.Visit(expression.Left);

                    if (left == InterpretFailed)
                    {
                        return(InterpretFailed);
                    }

                    var right = this.Visit(expression.Right);

                    if (right == InterpretFailed)
                    {
                        return(InterpretFailed);
                    }

                    if (left == right)
                    {
                        return(expression.NodeType == ExpressionType.Equal);
                    }

                    if (left is short && right is short)
                    {
                        return(((short)left == (short)right) && expression.NodeType == ExpressionType.Equal);
                    }
                    else if (left is int && right is int)
                    {
                        return((int)left == (int)right && expression.NodeType == ExpressionType.Equal);
                    }
                    else if (left is long && right is long)
                    {
                        return((long)left == (long)right && expression.NodeType == ExpressionType.Equal);
                    }
                    else if (left is string && right is string)
                    {
                        return((string)left == (string)right && expression.NodeType == ExpressionType.Equal);
                    }
                    else if (expression.Left.Type == typeof(object) && expression.Right.Type == typeof(object))
                    {
                        return(EqualityComparer <object> .Default.Equals(left, right));
                    }

                    return(InterpretFailed);
                }
                return(InterpretFailed);
            }

            case ExpressionType.Add:
            case ExpressionType.Subtract:
            case ExpressionType.Multiply:
            case ExpressionType.Divide:
            {
                var left = this.Visit(expression.Left);

                if (left == InterpretFailed)
                {
                    return(InterpretFailed);
                }

                var right = this.Visit(expression.Right);

                if (right == InterpretFailed)
                {
                    return(InterpretFailed);
                }

                Type type = null;

                if (expression.Left.Type == typeof(string) || expression.Right.Type == typeof(string))
                {
                    type = typeof(string);

                    left  = Convert.ChangeType(left, typeof(string));
                    right = Convert.ChangeType(right, typeof(string));
                }
                else if (expression.Left.Type == typeof(decimal) || expression.Right.Type == typeof(decimal))
                {
                    type = typeof(decimal);

                    left  = Convert.ChangeType(left, typeof(decimal));
                    right = Convert.ChangeType(right, typeof(decimal));
                }
                else if (expression.Left.Type == typeof(double) || expression.Right.Type == typeof(double))
                {
                    type = typeof(double);

                    left  = Convert.ChangeType(left, typeof(double));
                    right = Convert.ChangeType(right, typeof(double));
                }
                else if (expression.Left.Type == typeof(float) || expression.Right.Type == typeof(float))
                {
                    type = typeof(float);

                    left  = Convert.ChangeType(left, typeof(float));
                    right = Convert.ChangeType(right, typeof(float));
                }
                else if (expression.Left.Type == typeof(long) || expression.Right.Type == typeof(long))
                {
                    type = typeof(long);

                    left  = Convert.ChangeType(left, typeof(long));
                    right = Convert.ChangeType(right, typeof(long));
                }
                else if (expression.Left.Type == typeof(uint) || expression.Right.Type == typeof(uint))
                {
                    if (expression.Left.Type == typeof(uint) && expression.Right.Type == typeof(uint))
                    {
                        type = typeof(uint);

                        left  = Convert.ChangeType(left, typeof(uint));
                        right = Convert.ChangeType(right, typeof(uint));
                    }
                    else
                    {
                        type = typeof(long);

                        left  = Convert.ChangeType(left, typeof(long));
                        right = Convert.ChangeType(right, typeof(long));
                    }
                }
                else if (expression.Left.Type == typeof(int) || expression.Right.Type == typeof(int))
                {
                    type = typeof(int);

                    left  = Convert.ChangeType(left, typeof(int));
                    right = Convert.ChangeType(right, typeof(int));
                }
                else if (expression.Left.Type == typeof(ushort) || expression.Right.Type == typeof(ushort))
                {
                    if (expression.Left.Type == typeof(ushort) && expression.Right.Type == typeof(ushort))
                    {
                        type = typeof(ushort);

                        left  = Convert.ChangeType(left, typeof(ushort));
                        right = Convert.ChangeType(right, typeof(ushort));
                    }
                    else
                    {
                        type = typeof(int);

                        left  = Convert.ChangeType(left, typeof(int));
                        right = Convert.ChangeType(right, typeof(int));
                    }
                }
                else if (expression.Left.Type == typeof(short) || expression.Right.Type == typeof(short))
                {
                    type = typeof(short);

                    left  = Convert.ChangeType(left, typeof(short));
                    right = Convert.ChangeType(right, typeof(short));
                }
                else if (expression.Left.Type == typeof(byte) || expression.Right.Type == typeof(byte))
                {
                    type = typeof(byte);

                    left  = Convert.ChangeType(left, typeof(byte));
                    right = Convert.ChangeType(right, typeof(byte));
                }
                else if (expression.Left.Type == typeof(sbyte) || expression.Right.Type == typeof(sbyte))
                {
                    type = typeof(int);

                    left  = Convert.ChangeType(left, typeof(int));
                    right = Convert.ChangeType(right, typeof(int));
                }
                else if (expression.Left.Type == typeof(byte) || expression.Right.Type == typeof(byte))
                {
                    type = typeof(int);

                    left  = Convert.ChangeType(left, typeof(int));
                    right = Convert.ChangeType(right, typeof(int));
                }

                if (type == null)
                {
                    return(InterpretFailed);
                }

                Func <object, object, object> func = null;

                switch (expression.NodeType)
                {
                case ExpressionType.Add:
                    func = BinaryOperations.GetAddFunc(type);
                    break;

                case ExpressionType.Subtract:
                    func = BinaryOperations.GetSubtractFunc(type);
                    break;

                case ExpressionType.Multiply:
                    func = BinaryOperations.GetMultiplyFunc(type);
                    break;

                case ExpressionType.Divide:
                    func = BinaryOperations.GetDivideFunc(type);
                    break;
                }

                if (func != null)
                {
                    return(func(left, right));
                }

                return(InterpretFailed);
            }

            default:
                return(InterpretFailed);
            }
        }