Processing Statements
Processing statements is more simpler than processing expressions. Consequently, majority of the code is generated by expressions and not by statements themselves. Statements in Turbo Pascal are organized into an object that contains methods for each Pascal statement and statement intermediate code – offset to the intermediate code subrutine for each statement.
Type PStatement = ^TStatement;
TStatement = Object
StatementCode: Word;
Function ProcessStatement: Boolean;
Procedure ProcessStatementsBetweenTokens (StartToken, EndToken: TToken);
Procedure Process_ASM_END_Block;
Procedure ProcessAssignmentStatementOrProcedureCall;
Procedure Process_INLINE_Statement;
Procedure ProcessSystemProcedure;
Procedure Process_IF_Statement;
Procedure Process_WHILE_Statement;
Procedure Process_REPEAT_Statement;
Procedure Process_FOR_Statement;
Procedure Process_CASE_Statement;
Procedure Process_WITH_Statement;
Procedure Process_GOTO_Statement;
Procedure ProcessLabelIdentifierStatement;
Procedure ProcessPortStatement;
Private
Procedure AddIntermediateCodeSubroutine (Var IntermediateCodeOffsets: TIntermediateCodeOffsets);
end;
Before processing a Pascal statement Turbo Pascal check stack (this subroutine also writes compilation progress), checks for numeric labels (for GoTo
statements), checks if identifier is declared (assignment and procedure call statements), marks source line number and processes statement according to the current token:
- Block of statements between tokens begin – end
- Assignment statement or procedure call
- System procedure
- IF statement
- WHILE statement
- REPEAT statement
- FOR statement
- CASE statement
- WITH statement
- GOTO statement
- ASM statement
- INLINE statement
- PORT statement
- Label identifier
Function TStatement.ProcessStatement: Boolean;
Var LineNumberBeforeStatement: Word;
Saved_StatementMaxStackFrameOffset: Word;
begin
CheckStack;
ProcessStatement := False;
StatementCode := 0;
StatementCompilerSwitches := ModuleCompilerSwitches;
CheckForNumericLabel;
CheckForDeclaredIdentifier;
Case Token of
Token_VariableIdentifier, Token_ProcedureIdentifier, Token_SystemProcedure, Token_BEGIN, Token_IF, Token_WHILE,
Token_REPEAT, Token_FOR, Token_CASE, Token_WITH, Token_GOTO, Token_LabelIdentifier, Token_ASM, Token_LeftParenthesis,
Token_INLINE, Token_SystemFunctionOrProcedure, Token_TypeIdentifier, Token_STRING, Token_FILE, Token_INHERITED,
Token_SystemFunction, Token_At, Token_Mem,
Token_Port: LineNumberBeforeStatement := GetCurrentProgramBlockSourceLineNumber;
else Exit;
end;
Saved_StatementMaxStackFrameOffset := StatementMaxStackFrameOffset;
Case Token of
Token_VariableIdentifier,
Token_ProcedureIdentifier: ProcessAssignmentStatementOrProcedureCall;
Token_SystemProcedure: ProcessSystemProcedure;
Token_BEGIN: ProcessStatementsBetweenTokens (Token_BEGIN, Token_END);
Token_IF: Process_IF_Statement;
Token_WHILE: Process_WHILE_Statement;
Token_REPEAT: Process_REPEAT_Statement;
Token_FOR: Process_FOR_Statement;
Token_CASE: Process_CASE_Statement;
Token_WITH: Process_WITH_Statement;
Token_GOTO: Process_GOTO_Statement;
Token_LabelIdentifier: ProcessLabelIdentifierStatement;
Token_ASM: Process_ASM_END_Block;
Token_LeftParenthesis: ProcessAssignmentStatementOrProcedureCall;
Token_INLINE: Process_INLINE_Statement;
Token_SystemFunctionOrProcedure: ProcessSystemProcedure;
Token_TypeIdentifier,
Token_STRING,
Token_FILE,
Token_INHERITED,
Token_SystemFunction,
Token_At,
Token_Mem: ProcessAssignmentStatementOrProcedureCall;
Token_Port: ProcessPortStatement;
end;
ProcessStatement := True;
StatementMaxStackFrameOffset := Saved_StatementMaxStackFrameOffset;
If LineNumberBeforeStatement <> 0 then
begin
MarkSourceLineNumber (LineNumberBeforeStatement);
StoreCode_icGoSub (StatementCode);
StatementCode := EndSubroutine;
end;
end;