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;