public static CoalesceTrue ( Expression left, Expression right, MethodInfo isTrue, ParameterExpression &temp ) : Expression | ||
left | Expression | |
right | Expression | |
isTrue | MethodInfo | |
temp | ParameterExpression | |
return | Expression |
// This is a compound comparison operator like: a < b < c. // That's represented as binary operators, but it's not the same as (a<b) < c, so we do special transformations. // We need to: // - return true iff (a<b) && (b<c), but ensure that b is only evaluated once. // - ensure evaluation order is correct (a,b,c) // - don't evaluate c if a<b is false. private MSAst.Expression FinishCompare(MSAst.Expression left) { Debug.Assert(_right is BinaryExpression); BinaryExpression bright = (BinaryExpression)_right; // Transform the left child of my right child (the next node in sequence) MSAst.Expression rleft = bright.Left; // Store it in the temp MSAst.ParameterExpression temp = Ast.Parameter(typeof(object), "chained_comparison"); // Create binary operation: left <_op> (temp = rleft) MSAst.Expression comparison = MakeBinaryOperation( _op, left, Ast.Assign(temp, AstUtils.Convert(rleft, temp.Type)), Span ); MSAst.Expression rright; // Transform rright, comparing to temp if (IsComparison(bright._right)) { rright = bright.FinishCompare(temp); } else { MSAst.Expression transformedRight = bright.Right; rright = MakeBinaryOperation( bright.Operator, temp, transformedRight, bright.Span ); } // return (left (op) (temp = rleft)) and (rright) MSAst.ParameterExpression tmp; MSAst.Expression res = AstUtils.CoalesceTrue( comparison, rright, AstMethods.IsTrue, out tmp ); return(Ast.Block( new[] { temp, tmp }, res )); }
internal static MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen, MSA.Expression /*!*/ left, MSA.Expression /*!*/ right) { MSA.ParameterExpression temp; MSA.Expression result = AstUtils.CoalesceTrue( AstUtils.Box(left), AstUtils.Box(right), Methods.IsTrue, out temp ); gen.CurrentScope.AddHidden(temp); return(result); }