Processing Typecast or Method Call
This procedure processes type identifiers in expression. If a period follows an object type then this is a method call. If left parenthesis follows then this is a typecast.
Procedure TExpression.ProcessValueTypecastOrMethodCall;
Var NewType: PTypeDefinition;
OldDataType: TBaseType;
OldSize: Word;
begin
NewType := ExpectTypeIdentifier;
If NewType^.BaseType = btObject then If CheckAndGetNextToken (Token_Period) then
begin
IntermediateCodeOffset := 0;
UsedRegisters := [];
FindAndProcessMethodCall (NewType, [pfMethod], [mcStatic], MethodIdentifierExpected);
Exit;
end;
ExpectTokenAndGetNext (Token_LeftParenthesis);
If (NewType^.BaseType >= btInteger) or (NewType^.BaseType = btPointer) then
begin
CalculateExpression;
If ExtendedSyntax in ModuleCompilerSwitches then CheckForStringConversionToPChar (@NewType);
end else ExpectVariableReferenceExceptProcedureOrFunction;
ExpectTokenAndGetNext (Token_RightParenthesis);
OldDataType := TypeDefPtr^.BaseType;
OldSize := TypeDefPtr^.Size;
TypeDefPtr := NewType;
If Location = elMemory then
If (OldDataType = btUntyped) or (OldSize = NewType^.Size) then
begin
DataType := NewType^.DataType;
Exit;
end;
If (OldDataType < btInteger) and (OldDataType <> btPointer) then Error (InvalidTypeCast);
If (NewType^.BaseType < btInteger) and (NewType^.BaseType <> btPointer) then Error (InvalidTypeCast);
ExtendInteger (NewType^.DataType);
end;
This procedure finds method in object’s domain and sets expression data.
Procedure TExpression.FindAndProcessMethodCall (TempPtr: Pointer; Flags: TProcedureFlagsSet; IntType: TIntegerTypeSet; CompilerError: TCompilerError);
Var IdentifierDataPtr: PProcedureIdentifierData;
IdentifierPtr: Word;
FoundToken: TToken;
begin
If Token <> Token_Identifier then Error (CompilerError);
If not IsCurrentIdentifierDeclaredAsMemberInRecordOrObject (TempPtr, PVariableIdentifierData (IdentifierDataPtr), FoundToken, IdentifierPtr) then Error (CompilerError);
If FoundToken <> Token_ProcedureIdentifier then Error (CompilerError);
If IdentifierDataPtr^.Flags * Flags = [] then Error (CompilerError);
TypeDefPtr := @IdentifierDataPtr^.ProcedureTypeDefinition;
Location := elProcedure;
DataType := IntType;
Value.W16 := Ofs (CurrentRecordTypeDef^);
Value.W18 := Seg (CurrentRecordTypeDef^);
GetNextToken;
end;
This procedure expects type identifier and returns pointer to type definition record.
Function ExpectTypeIdentifier: PTypeDefinition;
begin
Case Token of
Token_STRING: ExpectTypeIdentifier := Ptr (SystemUnitSegment, String_TypeOffset);
Token_FILE: ExpectTypeIdentifier := Ptr (SystemUnitSegment, File_TypeOffset);
else begin
CheckForDeclaredIdentifier;
If Token <> Token_TypeIdentifier then Error (TypeIdentifierExpected);
ExpectTypeIdentifier := ProcessTypeIdentifier;
Exit;
end;
end;
GetNextToken;
end;