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