Press enter to see results or esc to cancel.

String Operations

Constant strings are added in the temporary buffer, while all non-constant string operations are performed in stack frame.

  Procedure ConstantStringOperations;
  Var BoolResult: LongBool;
      LeftString, RightString: PString;
      CommonLength, NewStringOffset: Word;
  begin
    LeftString  := Ptr (DSeg, LeftExpression.Value.Word);
    RightString := Ptr (DSeg, RightExpression.Value.Word);
    Case Operation of
      Calc_Add: begin
                  If (Ofs (LeftString^) + Length (LeftString^) + 1 = Ofs (RightString^)) and
                     (Ofs (RightString^) + Length (RightString^) + 1 = TempBufferFreePositionOffset) then
                       TempBufferFreePositionOffset := Ofs (LeftString^);
                  CommonLength := Length (LeftString^) + Length (RightString^);
                  If CommonLength > $FF then CommonLength := $FF;
                  NewStringOffset := GetTempBufferOffset (CommonLength + 1);
                  PString (Ptr (DSeg, NewStringOffset))^ := LeftString^ + RightString^;
                  LeftExpression.Value.Word := NewStringOffset;
                end;
      else begin
             Case Operation of
               Calc_IsEqual:          BoolResult := LeftString^  = RightString^;
               Calc_IsNotEqual:       BoolResult := LeftString^ <> RightString^;
               Calc_IsGreater:        BoolResult := LeftString^  > RightString^;
               Calc_IsLower:          BoolResult := LeftString^  > RightString^;
               Calc_IsGreaterOrEqual: BoolResult := LeftString^ >= RightString^;
               Calc_IsLowerOrEqual:   BoolResult := LeftString^ <= RightString^;
             end;
             SetLeftExpressionToConstantBooleanValue (BoolResult);
           end;
    end;
  end;

  Procedure GenerateCodeForStringOperations;
  Label NoEmptyString;
  begin
    Case Operation of
      Calc_ADD: begin
                  LeftExpression.CopyStringToStackFrame ($0100);
                  RightExpression.StoreStringConstantToCodeBlock;
                  ConvertToPointerAndPushBothExpressions (LeftExpression, RightExpression);
                  CalculateBothExpressions (LeftExpression, RightExpression);
                  GenerateInstruction_CALL_FAR (SysProc_SConcat);
                  With LeftExpression do
                    begin
                      LeftExpression.EndIntermediateCodeSubroutine;
                      UsedRegisters := [urBX, urDX, urCX, urAX];
                    end;
                end;
      else begin
             If (RightExpression.Location <> elConstant) or (PString (Ptr (DSeg, RightExpression.Value.Word))^ <> '') then
               begin
                 If (LeftExpression.Location <> elConstant) then GoTo NoEmptyString;
                 ExchangeLeftAndRightExpression;
                 If PString (Ptr (DSeg, RightExpression.Value.Word))^ <> '' then GoTo NoEmptyString;
               end;
             LeftExpression.PositionToStringLength;
             With RightExpression do
               begin
                 DataType := [];
                 Value.LongInt := 0;
               end;
             GenerateCodeForIntegerComparisons;
             LeftExpression.EndIntermediateCodeSubroutine;
             Exit;
 NoEmptyString:

             LeftExpression.StoreStringConstantToCodeBlock;
             RightExpression.StoreStringConstantToCodeBlock;
             ConvertToPointerAndPushBothExpressions (LeftExpression, RightExpression);
             CalculateBothExpressions (LeftExpression, RightExpression);
             GenerateInstruction_CALL_FAR (SysProc_SCompare);
             With LeftExpression do
               begin
                 LeftExpression.EndIntermediateCodeSubroutine;
                 UsedRegisters := [urBX, urDX, urCX, urAX];
               end;
             LeftExpression.SetExpressionToBooleanJump (UnsignedConditionalJumpOpCode [Operation]);
           end;
    end;
  end;