Press enter to see results or esc to cancel.

System Function SizeOf

This procedure processes system function SizeOf.

Procedure Func_SizeOf; Far;
Var ArgumentTypeDefPtr: PTypeDefinition;

  Procedure SetValueToTypeDefinitionSize;
  begin
    With Expression^ do
      begin
        IntermediateCodeOffset := 0;
        Location := elConstant;
        UsedRegisters := [];
        Expression^.CheckOrdinalOverflowAndStore (ArgumentTypeDefPtr^.Size, False);
        ExpectTokenAndGetNext (Token_RightParenthesis);
        TypeDefPtr := Ptr (SystemUnitSegment, LongInt_TypeOffset);
      end;
  end;

begin
  ExpectTokenAndGetNext (Token_LeftParenthesis);
  If IsTypeIdentifier (ArgumentTypeDefPtr) then
    begin
      SetValueToTypeDefinitionSize;
      Exit;
    end;
  If OpenArrayOrOpenString (ArgumentTypeDefPtr) then
    begin
      ArgumentTypeDefPtr := PointerFromOffsets (PArrayTypeDefinition (ArgumentTypeDefPtr)^.ElementTypeOffset);
      Expression^.PositionToOpenParameterHighestIndex;
      Expression^.LoadExpressionToRegisters (urAX);
      GenerateInstruction_Byte ($40);  { INC   AX };
      Expression^.IntegerMultiplicationWithConstant (0, ArgumentTypeDefPtr^.Size);
      Expression^.EndIntermediateCodeSubroutine;
      ExpectTokenAndGetNext (Token_RightParenthesis);
      Expression^.TypeDefPtr := Ptr (SystemUnitSegment, LongInt_TypeOffset);
      Exit;
    end;
  If ArgumentTypeDefPtr^.BaseType <> btObject then
    begin
      SetValueToTypeDefinitionSize;
      Exit;
    end;
  If PObjectTypeDefinition (ArgumentTypeDefPtr)^.VMT_Size = 0 then
    begin
      SetValueToTypeDefinitionSize;
      Exit;
    end;
  Inc (Expression^.Value.Word, PObjectTypeDefinition (ArgumentTypeDefPtr)^.OffsetOf_VMT_Offset);
  Expression^.Calculate;
  Expression^.GenerateInstructionWithExpressionInMemOrReg ($8B, $38);  { MOV   DI, [BX + SI] }
  GenerateInstruction_TwoBytes ($8B, $05);                             { MOV   AX, [DI]      }
  ES_DI_PointerDestroyed;
  With Expression^ do
    begin
      Expression^.EndIntermediateCodeSubroutine;
      Location := elRegister;
      DataType := [itUnsigned, it16Bit];
      UsedRegisters := [urAX];
      LocationData.Register := rAX;
    end;
  ExpectTokenAndGetNext (Token_RightParenthesis);
  Expression^.TypeDefPtr := Ptr (SystemUnitSegment, LongInt_TypeOffset);
end;

This function returns identifier type and True if next identifier is type identifier or False if identifier is variable.

Function IsTypeIdentifier (Var TypeDefPtr: PTypeDefinition): Boolean;
begin
  CheckForDeclaredIdentifier;
  IsTypeIdentifier := True;
  Case Token of
    Token_TypeIdentifier,
    Token_STRING,
    Token_FILE: TypeDefPtr := ExpectTypeIdentifier;
    else begin
           Expression^.ExpectVariableReferenceExceptProcedureOrFunction;
           TypeDefPtr := Expression^.TypeDefPtr;
           IsTypeIdentifier := False;
         end;
  end;
end;

This function returns True if array or string has size 0.

Function OpenArrayOrOpenString (TypeDef: PTypeDefinition): Boolean;
begin
  OpenArrayOrOpenString := False;
  Case TypeDef^.BaseType of
    btArray,
    btString: OpenArrayOrOpenString := TypeDef^.Size = 0;
  end;
end;