Processing Constant Declarations

Turbo Pascal constants can be of two types: ordinary constants which are only stored to the symbol table and typed constants which are also embedded into the program. Therefore typed constant values are stored into separate symbol table.
Procedure ProcessConstantDeclarations;
Var TypePtr: PTypeDefinition;
    Variable: PVariableIdentifierData;
    Constant: PConstantIdentifierData absolute Variable;
    ConstantIdentifier: PIdentifier;
    Expression: TExpression;
    DataPtr, AddData: Pointer;
    Size: Word;
    UnitTypeOffsets: TUnitOffsets;

  Procedure GetTypedConstantInitialValue;
  Var VarData: Pointer;
      Size: Word;
  begin
    Size := TypePtr^.Size;
    VarData := IncreaseSymbolTable (stTypedConstants, Size);
    CurrentTypedConstantValueOffset := Ofs (VarData^);
    FillChar (VarData^, Size, 0);
    TypedConstantsOffsetBeforeConstantValueProcessing := Ofs (VarData^) + Size;
    ProcessTypedConstant (TypePtr);
    TypedConstantsOffsetBeforeConstantValueProcessing := LastTypedConstantsSize;
  end;

begin
  GetNextToken;
  Repeat
    ConstantIdentifier := ExpectAndStoreIdentifier (0, AddData);
    If CheckAndGetNextToken (Token_Colon) then
      begin                                                                               { Typed constant }
        Variable := IncreaseSymbolTable (stMain, SizeOf (TVariableIdentifierData));
        TokenForEqual := Token_EqualAsSeparator;
        TypePtr := GetVariableType;
        TokenForEqual := Token_Equal;
        If (WordAlignment in ModuleCompilerSwitches) and (TypePtr^.Size <> 1) then WordAlignAddressForTypedConstants;
        ForceCreationOfTypedConstantsBlockRecord := True;
        VariableData_Flags := TypedConstant;
        RecordTypeDefinitionOffset.TypedConstantOffset :=
          SymbolTable [stTypedConstants].NextRecordOffset - LastTypedConstantsSize;
        RecordTypeDefinitionOffset.TypedConstantsBlockRecordOffset := SymbolTable [stTypedConstantsBlocks].NextRecordOffset;
        ExpectTokenAndGetNext (Token_EqualAsSeparator);
        GetTypedConstantInitialValue;
        ConstantIdentifier^.Token := Token_VariableIdentifier;
        With Variable^ do
          begin
            Flags := VariableData_Flags;
            W1.Ofs := RecordTypeDefinitionOffset.TypedConstantOffset;
            W1.Seg := RecordTypeDefinitionOffset.TypedConstantsBlockRecordOffset;
            W5 := VariableData_NextMemberOffset;
            UnitTypeOffsets := CurrentVarUnitTypeOffsets;
          end;
      end else
        begin
          ExpectTokenAndGetNext (Token_Equal);
          Expression.ExpectConstantExpression;
          ConstantIdentifier^.Token := Token_ConstantIdentifier;
          DataPtr := @Expression.Value;
          TypePtr := Expression.TypeDefPtr;
          Size := 4;
          If TypePtr^.BaseType < btInteger then
            Case TypePtr^.BaseType of
              btPointer: Size := 4;
              btExtended: Size := 10;
              else begin
                    DataPtr := Ptr (DSeg, Expression.Value.Word);
                    If TypePtr^.BaseType = btSet then Size := 32
                      else Size := Byte (DataPtr^) + 1;
                 end;
            end;
          GetTypeAndUnitIdentifierOffsets (TypePtr, UnitTypeOffsets);
          Constant := IncreaseSymbolTable (stMain, SizeOf (TUnitOffsets) + Size);
          Constant^.UnitTypeOffsets := UnitTypeOffsets;
          Move (DataPtr^, Constant^.Value, Size);
        end;
    ExpectTokenAndGetNext (TOKEN_Semicolon);
  until Token <> Token_Identifier;
  CreateTypedConstantsBlockRecord;
end;
For each Const declaration Turbo Pascal creates a record in symbol table for typed constants (if they are declared).
Procedure CreateTypedConstantsBlockRecord;
begin
  WordAlignAddressForTypedConstants;
  If (SymbolTable [stTypedConstants].UsedSize <> LastTypedConstantsSize) or ForceCreationOfTypedConstantsBlockRecord then
    begin
      ForceCreationOfTypedConstantsBlockRecord := False;
      With PTypedConstantsBlockRecord (IncreaseSymbolTable (stTypedConstantsBlocks, SizeOf (TTypedConstantsBlockRecord)))^ do
        begin
          Offset := 0;
          ConstantsSize := SymbolTable [stTypedConstants].UsedSize - LastTypedConstantsSize;
          ReferencesSize := SymbolTable [stTypedConstantsReferences].UsedSize - LastTypedConstantsReferencesSize;
          tcrW6 := CurrentRecordOrObjectTypeDefinitionOffset;
        end;
      LastTypedConstantsSize := SymbolTable [stTypedConstants].UsedSize;
      TypedConstantsOffsetBeforeConstantValueProcessing := SymbolTable [stTypedConstants].NextRecordOffset;
      LastTypedConstantsReferencesSize := SymbolTable [stTypedConstantsReferences].UsedSize;
    end;
end;
 
 
 
© 2017 Turbo Pascal | Privacy Policy