Press enter to see results or esc to cancel.

System Procedures Inc and Dec

This function processes system procedures Inc and Dec.

Function Proc_Inc_Dec: Word; Far;
Var VarExpression, ValueExpression: TExpression;
    ElementSize: Word;

  Procedure GenerateCodeFor_Inc_Dec;
  begin
    Case ValueExpression.Location of
      elConstant: With VarExpression do
                    begin
                      Calculate;
                      If not (it32Bit in DataType) and (ValueExpression.Value.LongInt = 1) then
                        VarExpression.GenerateInstruction_8_16_bit ($FE,
                                                                                                   ProcParameter and $08) else
                          begin
                            GenerateArithmeticInstructionWithImmediateValue (ValueExpression.Value.Word, ProcParameter);
                            If it32Bit in DataType then
                              begin
                                Inc (VarExpression.Value.Offset, 2);
                                GenerateArithmeticInstructionWithImmediateValue (ValueExpression.Value.W12,
                                                                             ProcParameter and $08 or $10);
                                Dec (VarExpression.Value.Offset, 2);
                              end;
                          end;
                      EndIntermediateCodeSubroutine;
                    end;
      else begin
             ValueExpression.Calculate;
             ValueExpression.Save (VarExpression.UsedRegisters);
             VarExpression.Calculate;
             ValueExpression.PopToRegisters ([]);
             VarExpression.GenerateInstruction_8_16_bit (ProcParameter,
                                                                 ValueExpression.LocationData.Register shl 3);
             If it32Bit in VarExpression.DataType then
               begin
                 Inc (VarExpression.Value.Offset, 2);
                 VarExpression.GenerateInstruction_8_16_bit (ProcParameter and $08 or $10,
                                                                                              $10);
                 Dec (VarExpression.Value.Offset, 2);
               end;
             VarExpression.EndIntermediateCodeSubroutine;
           end;
    end;
  end;

begin
  ExpectTokenAndGetNext (Token_LeftParenthesis);
  VarExpression.ExpectAssignableVariableReferenceExceptProcedureOrFunction;
  ElementSize := 1;
  Case VarExpression.TypeDefPtr^.BaseType of
    btPointer: begin
                 ElementSize := PTypeDefinition (PointerFromOffsets (
                                  PPointerTypeDefinition (VarExpression.TypeDefPtr)^.PointerBaseTypeOffset))^.Size;
                 If ElementSize = 0 then Error (OrdinalVariableExpected);
                 VarExpression.DataType := itWord;
               end;
    btInteger,
    btBoolean,
    btChar,
    btEnumeration:
    else Error (OrdinalVariableExpected);
  end;
  If CheckAndGetNextToken (Token_Comma) then
    begin
      ValueExpression.ExpectIntegerExpression;
      ValueExpression.LoadPointerToMemoryTo_DX_AX;
      ValueExpression.ExtendInteger (VarExpression.DataType);
      If ElementSize <> 1 then
        With ValueExpression do
          Case Location of
            elConstant: Value.Word := Value.Word * ElementSize;
            else begin
                   Calculate;
                   ValueExpression.IntegerMultiplicationWithConstant (rAX, ElementSize);
                   EndIntermediateCodeSubroutine;
                 end;
          end;
    end else With ValueExpression do
               begin
                 IntermediateCodeOffset := 0;
                 Location := elConstant;
                 Value.LongInt := ElementSize;
               end;
  ExpectTokenAndGetNext (Token_RightParenthesis);
  GenerateCodeFor_Inc_Dec;
  VarExpression.CheckRange (VarExpression.TypeDefPtr);
  Proc_Inc_Dec := VarExpression.IntermediateCodeOffset;
end;