Ejemplo n.º 1
0
        public async override Task VisitAsync(BinaryExpression expression)
        {
            // simulate Lazy<Func<>> behavior for late evaluation
            object leftValue           = null;
            Func <Task <object> > left = async() =>
            {
                if (leftValue == null)
                {
                    await expression.LeftExpression.AcceptAsync(this);

                    leftValue = Result;
                }
                return(leftValue);
            };

            // simulate Lazy<Func<>> behavior for late evaluation
            object rightValue           = null;
            Func <Task <object> > right = async() =>
            {
                if (rightValue == null)
                {
                    await expression.RightExpression.AcceptAsync(this);

                    rightValue = Result;
                }
                return(rightValue);
            };

            switch (expression.Type)
            {
            case BinaryExpressionType.And:
                Result = Convert.ToBoolean(await left()) && Convert.ToBoolean(await right());
                break;

            case BinaryExpressionType.Or:
                Result = Convert.ToBoolean(await left()) || Convert.ToBoolean(await right());
                break;

            case BinaryExpressionType.Div:
                //Actually doesn't need checked here, since if one is real,
                // checked does nothing, and if they are int the result will only be same or smaller
                // (since anything between 1 and 0 is not int and 0 is an exception anyway
                Result = IsReal(await left()) || IsReal(await right())
                                 ? Numbers.Divide(await left(), await right(), _options)
                                 : Numbers.Divide(Convert.ToDouble(await left()), await right(), _options);
                break;

            case BinaryExpressionType.Equal:
                // Use the type of the left operand to make the comparison
                Result = CompareUsingMostPreciseType(await left(), await right()) == 0;
                break;

            case BinaryExpressionType.Greater:
                // Use the type of the left operand to make the comparison
                Result = CompareUsingMostPreciseType(await left(), await right()) > 0;
                break;

            case BinaryExpressionType.GreaterOrEqual:
                // Use the type of the left operand to make the comparison
                Result = CompareUsingMostPreciseType(await left(), await right()) >= 0;
                break;

            case BinaryExpressionType.Lesser:
                // Use the type of the left operand to make the comparison
                Result = CompareUsingMostPreciseType(await left(), await right()) < 0;
                break;

            case BinaryExpressionType.LesserOrEqual:
                // Use the type of the left operand to make the comparison
                Result = CompareUsingMostPreciseType(await left(), await right()) <= 0;
                break;

            case BinaryExpressionType.Minus:
                Result = Checked ? Numbers.SoustractChecked(await left(), await right(), _options) : Numbers.Soustract(await left(), await right(), _options);
                break;


            case BinaryExpressionType.Modulo:
                Result = Numbers.Modulo(await left(), await right());
                break;

            case BinaryExpressionType.NotEqual:
                // Use the type of the left operand to make the comparison
                Result = CompareUsingMostPreciseType(await left(), await right()) != 0;
                break;

            case BinaryExpressionType.Plus:
                if (await left() is string)
                {
                    Result = String.Concat(await left(), await right());
                }
                else
                {
                    Result = Checked ? Numbers.AddChecked(await left(), await right(), _options) : Numbers.Add(await left(), await right(), _options);
                }

                break;

            case BinaryExpressionType.Times:
                Result = Checked ? Numbers.MultiplyChecked(await left(), await right(), _options) : Numbers.Multiply(await left(), await right(), _options);
                break;

            case BinaryExpressionType.BitwiseAnd:
                Result = Convert.ToUInt16(await left()) & Convert.ToUInt16(await right());
                break;


            case BinaryExpressionType.BitwiseOr:
                Result = Convert.ToUInt16(await left()) | Convert.ToUInt16(await right());
                break;


            case BinaryExpressionType.BitwiseXOr:
                Result = Convert.ToUInt16(await left()) ^ Convert.ToUInt16(await right());
                break;


            case BinaryExpressionType.LeftShift:
                Result = Convert.ToUInt16(await left()) << Convert.ToUInt16(await right());
                break;


            case BinaryExpressionType.RightShift:
                Result = Convert.ToUInt16(await left()) >> Convert.ToUInt16(await right());
                break;
            }
        }