Press enter to see results or esc to cancel.

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;