INLINE Statement

This procedure processes Inline statement  and generates intermediate code for inline records.  Inline records are storend into the main symbol table but are removed after the intermediate code has been generated. 
Procedure TStatement.Process_INLINE_Statement;
Var Saved_MainSymbolTableNextRecordOffset: Word;
    InlineCodeSize: Word;
begin
  GetNextToken;
  Saved_MainSymbolTableNextRecordOffset := SymbolTable [stMain].NextRecordOffset;
  GenerateIntermediateCodeForInlineRecords (Process_INLINE (InlineCodeSize), InlineCodeSize);
  SymbolTable [stMain].NextRecordOffset := Saved_MainSymbolTableNextRecordOffset;
  StatementCode := EndSubroutine;
end;
This procedure processes Inline records (variables, procedures, functions and integer values) and stores them into the main symbol table.
Function Process_INLINE (Var InlineCodeSize: Word): PInlineRecord;
Label StoreInlineRecord;
Var Saved_MainSymbolTableNextRecordOffset: Word;
    CurrentInlineIdentifierData: PVariableIdentifierData;
    InlineRecord: TInlineRecord;
    FunctionType: PTypeDefinition;
    PlusMinusToken: TToken;
    TempPtr: Pointer;
    RecSize: Byte;
begin
  Saved_MainSymbolTableNextRecordOffset := SymbolTable [stMain].NextRecordOffset;
  Process_INLINE := SymbolTable [stMain].Ptr;
  TokenForSlash := Token_INLINE_Separator;
  ExpectTokenAndGetNext (Token_LeftParenthesis);
  Repeat
    If CheckAndGetNextToken (Token_Greater) then InlineRecord.RecordType := irWord else
      If CheckAndGetNextToken (Token_Lower) then InlineRecord.RecordType := irByte else InlineRecord.RecordType := irDefault;
    CheckForDeclaredIdentifier;
    Case Token of
      Token_VariableIdentifier,
      Token_ProcedureIdentifier:
        begin
          Case Token of
            Token_VariableIdentifier: begin
                                        CurrentInlineIdentifierData := CurrentIdentifierDataPtr;
                                        While vfAbsoluteVar in CurrentInlineIdentifierData^.Flags do
                                          CurrentInlineIdentifierData := PVariableIdentifierData (
                                            PointerFromOffsets (CurrentInlineIdentifierData^.AbsoluteVarDataOffsets));
                                        With CurrentInlineIdentifierData^ do
                                          begin
                                            If Field in Flags then Error (INLINE_Error);
                                            If vf1 in Flags then InlineRecord.W1 := W1.Ofs else
                                              begin
                                                If InlineRecord.RecordType = irByte then Error (INLINE_Error);
                                                Case vf0 in Flags of
                                                  True: InlineRecord.RecordType := irVarAbsoluteAddress;
                                                  else InlineRecord.RecordType  := irVar;
                                                end;
                                                InlineRecord.W3 := W1.Seg;
                                                InlineRecord.W5 :=
                                                  UnitIdentifierDataOffset (Seg (CurrentInlineIdentifierData^));
                                                InlineRecord.W1 := W1.Ofs;
                                              end;
                                          end;
                                      end;
            Token_ProcedureIdentifier: If not FunctionAsResult (FunctionType, InlineRecord.W1) then
                                         begin
                                           InlineRecord.W1 := ExpectIntegerConstant;
                                           Goto StoreInlineRecord;
                                         end;
          end;
          If InlineRecord.RecordType = irDefault then InlineRecord.RecordType := irWord;
          GetNextToken;
          PlusMinusToken := Token;
          If CheckPlusMinusAndGetNextToken then
            Case PlusMinusToken of
              Token_Minus: Dec (InlineRecord.W1, ExpectIntegerConstant);
              else         Inc (InlineRecord.W1, ExpectIntegerConstant);
            end;
        end;
      else InlineRecord.W1 := ExpectIntegerConstant;
    end;

StoreInlineRecord:

    If InlineRecord.RecordType = irDefault then
      Case InlineRecord.WordRec.ByteH of
        0: InlineRecord.RecordType := irByte;
        else InlineRecord.RecordType := irWord;
      end;
    Case InlineRecord.RecordType of
      irByte: RecSize := 2;
      irWord: RecSize := 3;
      else RecSize := 7;
    end;
    TempPtr := IncreaseSymbolTable (stMain, RecSize);
    Move (InlineRecord, TempPtr^, RecSize);
  until not CheckAndGetNextToken (Token_INLINE_Separator);
  TokenForSlash := Token_Slash;
  ExpectTokenAndGetNext (Token_RightParenthesis);
  InlineCodeSize := SymbolTable [stMain].NextRecordOffset - Saved_MainSymbolTableNextRecordOffset;
end;
This procedure generates intermediate code from Inline records.
Procedure GenerateIntermediateCodeForInlineRecords (InlineRecord: PInlineRecord; Len: Word);
Type TWord = Word;
Var InlineRecordOfs: Word absolute InlineRecord;
    EndOffset: Word;
begin
  EndOffset := InlineRecordOfs + Len;
  While InlineRecordOfs < EndOffset do
    Case InlineRecord^.RecorDType of
      irByte: begin
                GenerateInstruction_Byte (InlineRecord^.Byte);
                Inc (InlineRecordOfs, 2);
              end;
      irWord: begin
                GenerateInstruction_Word (InlineRecord^.Word);
                Inc (InlineRecordOfs, 3);
              end;
      irVar: begin
             With InlineRecord^ do
               GenerateReference (TWord (Ptr (Seg (InlineRecord^), W5)^), W3, W1, [rfDataSegment, rfOffset]);
             Inc (InlineRecordOfs, 7);
           end;
      else begin
             With InlineRecord^ do GenerateReference (TWord (Ptr (Seg (InlineRecord^), W5)^), W3, W1,
                                                    [rfDataSegment, rfConstant, rfOffset]);
             Inc (InlineRecordOfs, 7);                           { Absolute address }
           end;
    end;
  ES_DI_PointerDestroyed;
end;
 
 
 
© 2017 Turbo Pascal | Privacy Policy