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;