/// <summary> /// Test two conditions, and conditionally branch vs. fall through: /// either branch to target or fall through to subsequent code; /// conditions are and'ed together: both together constitute "true". /// Another way of thinking of this is condition conjunction (both). /// </summary> /// <param name="left"> /// Initial/left test condition. /// </param> /// <param name="right"> /// Initial/right test condition -- possibly short-circuted. /// </param> /// <param name="target"> /// Conditional branch target (or else fall thru). /// </param> /// <param name="reverse"> /// false --> normal case, fall through on both true, otherwise on false: branch to target /// true --> reversed case, fall through at least one false, otherwise on true: branch to target /// </param> public void EvalBoth(AbstractSyntaxTree left, AbstractSyntaxTree right, BranchTargetLabel target, bool reverse) { // NB: "Both" means evaluating left/first and right/second operands in the normal way. // Each operand is evaluated to branch around the then-part or loop-body on condition false, // and fall thru into the then-part or loop-body on condition true (both sub conditions being true). left.GenerateCodeForConditionalBranchWithPrettyPrint(this, target, reverse); right.GenerateCodeForConditionalBranchWithPrettyPrint(this, target, reverse); }
/// <summary> /// Test two conditions, and conditionally branch vs. fall through: /// either branch to target or fall through to subsequent code; /// conditions are or'ed together: either one constitutes "true". /// Another way of thinking of this is condition disjunction (i.e. either). /// </summary> /// <param name="left"> /// Initial/left test condition. /// </param> /// <param name="right"> /// Initial/right test condition -- possibly short-circuted. /// </param> /// <param name="target"> /// Conditional branch target (or else fall thru). /// </param> /// <param name="reverse"> /// false --> normal case, fall through to following code on at least one true, otherwise on false: branch to target /// true --> reversed case, fall through both false, otherwise on true: branch to target /// </param> public void EvalEither(AbstractSyntaxTree left, AbstractSyntaxTree right, BranchTargetLabel target, bool reverse) { // NB: "Either" means evaluating left/first operand, and on true, taking branch around the right/second operand // and into the fall thru code of the then-part or loop-body! // This requires use of an intermediate label, and a reversal of the evaluation condition, but only for the left/first operand. // The second operand is evaluated as per normal, take brach around the then-part or loop-body on condition false. var around = CreateLabel(); left.GenerateCodeForConditionalBranchWithPrettyPrint(this, around, !reverse); right.GenerateCodeForConditionalBranchWithPrettyPrint(this, target, reverse); PlaceLabelHere(around); }