Press enter to see results or esc to cancel.

Processing Type Declarations

This procedure processes type declarations – identifiers that denote types. Object types have their own processing.

Procedure ProcessTypeDeclarations;
Var TypeIdentifier: PIdentifier;
    TypeIdentifierData: PTypeIdentifierData;
    CurrentType: PTypeDefinition;

  Function ProcessTypeDeclaration: PTypeDefinition;
  begin
    Case Token of
      Token_Object: ProcessTypeDeclaration := ProcessObjectTypeDeclaration (TypeIdentifier);
      else          ProcessTypeDeclaration := ProcessNonObjectTypeDeclaration;
    end;
  end;

begin
  GetNextToken;
  LastPointerToTypeDefinitionOffset := 0;
  Repeat
    TypeIdentifier := ExpectAndStoreIdentifier (SizeOf (TTypeIdentifierData), Pointer (TypeIdentifierData));
    ExpectTokenAndGetNext (Token_Equal);
    CheckFor_OBJECT_PROCEDURE_FUNCTION_Type (TypeIdentifier, TypeIdentifierData^.UnitTypeOffsets);
    CurrentType := ProcessTypeDeclaration;
    If (Seg (CurrentType^) = MainSymbolTable.Segment) and (CurrentType^.TypeIdentifierOffset = 0) then
      CurrentType^.TypeIdentifierOffset := Ofs (TypeIdentifier^);
    GetTypeAndUnitIdentifierOffsets (CurrentType, TypeIdentifierData^.UnitTypeOffsets);
    TypeIdentifier^.Token := Token_TypeIdentifier;
    ExpectTokenAndGetNext (TOKEN_Semicolon);
  until Token <> TOKEN_Identifier;
  ResolvePointerToTypeDefinitions;
end;

Pascal allows to declare inside type definition statement pointers to types that will be declared later. This is useful in Object and Record types which may include pointers to themselves. Such pointer types are first stored into temporary table for later processing. This procedure resolves pointers to forward type declarations.

Procedure ResolvePointerToTypeDefinitions;
Var TempToken: TToken;
    BaseTypeIdDataPtr: PTypeIdentifierData;
    DataOfs: Word;
    PointerTypeDefinition: PPointerTypeDefinition;
begin
  While LastPointerToTypeDefinitionOffset <> 0 do
    begin
      PointerTypeDefinition := Ptr (MainSymbolTable.Segment, LastPointerToTypeDefinitionOffset);
      CopyStringFromTemporaryBlockToCurrentIdentifier (
        PointerTypeDefinition^.PointerBaseTypeOffset.TemporarySymbolTableRecordOffset);
      If not FindCurrentIdentifier (TempToken, DataOfs, Pointer (BaseTypeIdDataPtr)) then
        CurrentIdentifierError (UndefinedTypeInPointerDefinition);
      If TempToken <> Token_TypeIdentifier then CurrentIdentifierError (UndefinedTypeInPointerDefinition);
      LastPointerToTypeDefinitionOffset := PointerTypeDefinition^.PointerBaseTypeOffset.PreviousPointerToTypeDefinitionOffset;
      GetTypeAndUnitIdentifierOffsets (PointerFromOffsets (BaseTypeIdDataPtr^.UnitTypeOffsets),
                                       PointerTypeDefinition^.PointerBaseTypeOffset);
    end;
end;

Procedure CheckFor_OBJECT_PROCEDURE_FUNCTION_Type (TypeId: PIdentifier; Var UnitTypeOffsets: TUnitOffsets);
begin
  Case Token of
    Token_OBJECT,
    Token_PROCEDURE,
    Token_FUNCTION: begin
                      TypeId^.Token := Token_OBJECT_PROCEDURE_FUNCTION_TypeIdentifier;
                      GetTypeAndUnitIdentifierOffsets (SymbolTable [stMain].Ptr, UnitTypeOffsets);
                    end;
  end;
end;