Press enter to see results or esc to cancel.

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 the main symbol table of the 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);
                    end;

This procedure creates pointer to type definition record from type definition offsets.

Function PointerFromOffsets (Var UnitTypeOffsets: TUnitOffsets): Pointer;
begin
  PointerFromOffsets := Ptr (
    PUnitIdentifierData (Ptr (Seg (UnitTypeOffsets), UnitTypeOffsets.UnitIdentifierData))^.UnitSegment,
    UnitTypeOffsets.TypeOffset);
end;

All base types share the same basic fields, however, every base type uses some additional data fields.

ype PTypeDefinition = ^TTypeDefinition;
     TTypeDefinition = Object
                         BaseType: TBaseType;
                         DataType: TIntegerTypeSet;
                         Size: Word;
                         TypeIdentifierOffset: Word;
                         W06_: Word;  { NextMemberOffset }
                       end;

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

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

     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;
                             end;

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

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

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

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

     PStringTypeDefinition = PArrayTypeDefinition;                    { btString }
     TStringTypeDefinition = TArrayTypeDefinition;

     POrdinalTypeDefinition = ^TOrdinalTypeDefinition;                { btInteger, btBoolean, btChar, btEnumeration }
     TOrdinalTypeDefinition = Object (TTypeDefinition)
                                LowerLimit:  LongInt;
                                UpperLimit:  LongInt;
                                OrdinalType: TUnitOffsets;
                              end;

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;
begin
  TypeDef := IncreaseSymbolTable (stMain, Size);
  CreateTypeDefinition := TypeDef;
  With TypeDef^ do
    begin
      BaseType := BType;
      DataType := IType;
      Size := TypeSize;
      TypeIdentifierOffset := 0;
      W06_ := 0;
    end;
end;