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;