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; } }