Type Definition Data Structures

Here are presented data structures that describe types in Turbo Pascal. All types belong to one of base Turbo Pascal types: Untyped, Array, Record, Object, File, Text, Function/Procedure, Set, Pointer, String, Extended, Real, Integer, Boolean, Char, Enumeration.
Type TBaseType = (btUntyped, btArray, btRecord, btObject, btFile, btText, btFunctionProcedure, btSet,
                  btPointer, btString, btExtended, btReal, btInteger, btBoolean, btChar, btEnumeration);
Integer types have additional flags that determine integer properties.
     TIntegerType = (itSigned, itUnsigned, it16Bit, it32Bit, it32Bytes);

     TIntegerTypeSet = Set of TIntegerType;
Each Turbo Pascal compiler data record that needs to specify a type uses a type definition record with two offsets. One offset defines unit where the type is defined. It specifies the offset in current main symbol table where the name of the unit is stored. The other offset specifies offset in main symbol table of target unit where type identifier is stored. All indentifiers in the symbol table are followed by some data which defines their properties. This way a complete reference to the type definition data is provided.
     PUnitOffsets = ^TUnitOffsets;
     TUnitOffsets = Record
                      Case Byte of     { UnitIdentifierDataOffset }
                        0: (TypeOffset, UnitIdentifierData: Word);
                        1: (Offset, Segment: Word);
                        2: (UnitAndTypeOffset: LongInt);
                        3: (PreviousPointerToTypeDefinitionOffset, TemporarySymbolTableRecordOffset: Word);
                        4: (TypedConstantOffset, TypedConstantsBlockRecordOffset: Word);
This procedure creates pointer to type definition record from type definition offsets.
Function PointerFromOffsets (Var UnitTypeOffsets: TUnitOffsets): Pointer;
  PointerFromOffsets := Ptr (
    PUnitIdentifierData (Ptr (Seg (UnitTypeOffsets), UnitTypeOffsets.UnitIdentifierData))^.UnitSegment,
All base types share the same basic fields, however, every base type uses some additional data fields.
Type PTypeDefinition = ^TTypeDefinition;
     TTypeDefinition = Object
                         BaseType: TBaseType;
                         DataType: TIntegerTypeSet;
                         Size: Word;
                         TypeIdentifierOffset: Word;
                         W06_: Word;  { NextMemberOffset }

     PArrayTypeDefinition = ^TArrayTypeDefinition;                    { btArray }
     TArrayTypeDefinition = Object (TTypeDefinition)
                              ElementTypeOffset: TUnitOffsets;
                              IndexTypeOffset:   TUnitOffsets;
                              Function  IsZeroBasedCharacterArray: Boolean;
                              Function  IsCharacterArrayCompatibleWithString (Var Len: Byte): Boolean;

     PRecordTypeDefinition = ^TRecordTypeDefinition;                  { btRecord }
     TRecordTypeDefinition = Object (TTypeDefinition)
                               FieldsListOffset: Word;
                               W0A:              Word;

     PObjectTypeDefinition = ^TObjectTypeDefinition;                  { btObject }
     TObjectTypeDefinition = Object (TRecordTypeDefinition)
                               AncestorTypeOffset                 : TUnitOffsets;
                               VMT_Size                           : Word;
                               VMT_TypedConstantsBlockRecordOffset: Word;
                               OffsetOf_VMT_Offset: Word;
                               W16: Word;
                               W18: Word;
                               W1A: Word;
                               W1C: Word;
                               W1E: Word;
                               W20: Word;
                               W22: Word;
                               W24: Word;

     PFileTypeDefinition = ^TFileTypeDefinition;                      { btFile }
     TFileTypeDefinition = Object (TTypeDefinition)
                             BaseFileTypeOffset: TUnitOffsets;

     PProcedureTypeDefinition = ^TProcedureTypeDefinition;            { btProcedure }
     TProcedureTypeDefinition = Object (TTypeDefinition)
                                  ResultTypeOffset:   TUnitOffsets;
                                  NumberOfParameters: Word;

     PSetTypeDefinition = ^TSetTypeDefinition;                        { btSet }
     TSetTypeDefinition = Object (TTypeDefinition)
                            BaseSetTypeOffset: TUnitOffsets;
                            Function  GetSetSizeAndLowestElementDataOffset (Var DataOffset: Byte): Byte;

     PPointerTypeDefinition = ^TPointerTypeDefinition;                { btPointer }
     TPointerTypeDefinition = Object (TTypeDefinition)
                                PointerBaseTypeOffset: TUnitOffsets;

     PStringTypeDefinition = PArrayTypeDefinition;                    { btString }
     TStringTypeDefinition = TArrayTypeDefinition;

     POrdinalTypeDefinition = ^TOrdinalTypeDefinition;                { btInteger, btBoolean, btChar, btEnumeration }
     TOrdinalTypeDefinition = Object (TTypeDefinition)
                                LowerLimit:  LongInt;
                                UpperLimit:  LongInt;
                                OrdinalType: TUnitOffsets;
This procedure creates type definition record in the main symbol table and sets its data.
Function CreateTypeDefinition (Size, TypeSize: Word; IType: TIntegerTypeSet; BType: TBaseType): Pointer;
Var TypeDef: PTypeDefinition;
  TypeDef := IncreaseSymbolTable (stMain, Size);
  CreateTypeDefinition := TypeDef;
  With TypeDef^ do
      BaseType := BType;
      DataType := IType;
      Size := TypeSize;
      TypeIdentifierOffset := 0;
      W06_ := 0;
© 2017 Turbo Pascal | Privacy Policy