Press enter to see results or esc to cancel.

Processing Unary Sign Operators

This procedure processes unary plus or minus before a factor. Plus is skipped while minus changes the sign if expression is integer, extended or real.

  Procedure ProcessUnaryMinus_Plus;
  Var LastToken: TToken;
      Overflow: Boolean;
      TempInteger: LongInt;
      TempIntegerTypeSet: TIntegerTypeSet;
  begin
    LastToken := Token;
    CheckPlusMinusAndGetNextToken;
    ProcessFactor;
    If LastToken <> Token_Minus then Exit;
    Case TypeDefPtr^.BaseType of
      btInteger: begin
              If Location = elConstant then
                begin
                  Overflow := False;
                  TempInteger := 0 - Value.LongInt;
                  Asm
                    JNO   @1
                    INC   Overflow
                @1:
                  end;
                  CheckOrdinalOverflowAndStore (TempInteger, Overflow);
                  Exit;
                end;
              SetLowestCommonIntegerType ([itSigned, it16Bit], DataType, TempIntegerTypeSet);
              ExtendInteger (TempIntegerTypeSet);
              Calculate;
              LoadExpressionToRegisters (urAX);
              If not (it32Bit in DataType) then GenerateInstruction_TwoBytes ($F7, $D8) { NEG   AX  }
                else GenerateCode_NEG_LongInt;
              GenerateOverflowCheckingCode (Self);
              EndIntermediateCodeSubroutine;
            end;
      btExtended: begin
                    If Location <> elConstant then
                      begin
                        ConvertRealToExtended;
                        LoadExpressionToFPU;
                        Calculate;
                        ModifyAndSroreFPUInstructionForFixup ($E0D9);         { FCHS }
                        EndIntermediateCodeSubroutine;
                      end else Value.Extended := - Value.Extended;
                  end;
      btReal: begin
              If Instructions80x87 in StatementCompilerSwitches then
                begin
                  ConvertRealToExtended;
                  LoadExpressionToFPU;
                  Calculate;
                  ModifyAndSroreFPUInstructionForFixup ($E0D9);         { FCHS }
                  EndIntermediateCodeSubroutine;
                  Exit;
                end;
              Calculate;
              LoadRealExpressionToRegisterSet (rAX_BX_DX);
              GenerateInstruction_TwoBytes ($08, $C0);              { OR     AL, AL }
              GenerateInstruction_TwoBytes ($74, $03);              { JE     $ + 5  }
              GenerateInstruction_TwoBytes ($80, $F6);              { XOR    DH, 80 }
              GenerateInstruction_Byte ($80);
              EndIntermediateCodeSubroutine;
            end;
      else Error (OperandTypesDoNotMatchOperator);
    end;
  end;