Press enter to see results or esc to cancel.

Boolean Operations

Boolean operations are similar to integer operations. Constant Boolean operations are performed with boolean expressions converted to boolean bytes (0 or 1) and using procedures for integer calculation.

  Procedure ConstantBooleanOperations;
  begin
    LeftExpression.ConvertToBooleanByte;
    RightExpression.ConvertToBooleanByte;
    ConstantIntegerOperations;
  end;

Generating code for Boolean expression is no different from code for integer expressions with the exception of short-circuit evaluations. Boolean operations AND and OR can be decided after only one operant is calculated. If the first operand in boolean operation OR evaluates to True then there is no need to evaluate the second one. Similarly, if the first operand in boolean operation AND evaluates to False then there is no need to evaluate the second one. This procedure takes care for this. Short-circuit evaluation is a great example of the elegance of Turbo Pascal and boolean expressions using jump lists.

  Procedure GenerateCodeForBooleanOperations;
  Var LastJumpToTrue, LastJumpToFalse, TempWord: PWord;
      JumpIfTrueOpCode: Byte;
  begin
    If (FullBooleanEval in StatementCompilerSwitches) or not (Operation in [Calc_AND, Calc_OR]) then
      begin
        LeftExpression.ConvertToBooleanByte;
        RightExpression.ConvertToBooleanByte;
        GenerateCodeForIntegerOperations;
        Exit;
      end;
    LeftExpression.ConvertExpressionToBooleanJump;
    RightExpression.ConvertExpressionToBooleanJump;
    LeftExpression.Calculate;
    LastJumpToTrue := @LeftExpression.Value.LastJumpToTrue;
    LastJumpToFalse := @LeftExpression.Value.LastJumpToFalse;
    JumpIfTrueOpCode := LeftExpression.LocationData.JumpIfTrueOpCode;
    If Operation <> Calc_OR then
      begin
        JumpIfTrueOpCode := JumpIfTrueOpCode xor $01;
        TempWord := LastJumpToTrue;
        LastJumpToTrue := LastJumpToFalse;
        LastJumpToFalse := TempWord;
      end;
    GenerateCodeForNearJump (LastJumpToTrue^, JumpIfTrueOpCode);
    GenerateLabelAndSetJumpsToIt (LastJumpToFalse^);
    RightExpression.Calculate;
    LeftExpression.EndIntermediateCodeSubroutine;
    With LeftExpression do UsedRegisters := UsedRegisters + RightExpression.UsedRegisters;
    JoinJumpsOfBothExpressions (LeftExpression.Value.LastJumpToTrue, RightExpression.Value.LastJumpToTrue);
    JoinJumpsOfBothExpressions (LeftExpression.Value.LastJumpToFalse, RightExpression.Value.LastJumpToFalse);
    LeftExpression.LocationData.JumpIfTrueOpCode := RightExpression.LocationData.JumpIfTrueOpCode;
  end;