Implement C99 scope rules for selection and iteration statements.

Under these rules, if, switch, for, while, and do statements each have their own block scopes separate from the enclosing scope, and their substatements also have their own block scopes.

This patch always applies the C99 scope rules, but a flag can be changed to disable them or make them conditional on a configuration setting.
This commit is contained in:
Stephen Heumann 2018-03-24 18:01:28 -05:00
parent 14adcd6a80
commit d6502c0719

View File

@ -82,6 +82,7 @@ implementation
const const
maxBitField = 32; {max # of bits in a bit field} maxBitField = 32; {max # of bits in a bit field}
allowMixedDeclarations = true; allowMixedDeclarations = true;
c99Scope = true;
type type
@ -569,6 +570,8 @@ var
stPtr^.doLab := lab; stPtr^.doLab := lab;
stPtr^.breakLab := 0; stPtr^.breakLab := 0;
stPtr^.continueLab := 0; stPtr^.continueLab := 0;
if c99Scope then PushTable;
if c99Scope then PushTable;
Statement; {process the first loop body statement} Statement; {process the first loop body statement}
end; {DoStatement} end; {DoStatement}
@ -598,6 +601,7 @@ var
stPtr^.continueLab := continueLab; stPtr^.continueLab := continueLab;
stPtr^.breakLab := breakLab; stPtr^.breakLab := breakLab;
if c99Scope then PushTable;
Match(lparench,13); {evaluate the start condition} Match(lparench,13); {evaluate the start condition}
if token.kind <> semicolonch then begin if token.kind <> semicolonch then begin
Expression(normalExpression, [semicolonch]); Expression(normalExpression, [semicolonch]);
@ -639,6 +643,7 @@ var
stPtr^.e3List := tl; {save the list} stPtr^.e3List := tl; {save the list}
Match(rparench,12); {get the closing for loop paren} Match(rparench,12); {get the closing for loop paren}
if c99Scope then PushTable;
Statement; {process the first loop body statement} Statement; {process the first loop body statement}
end; {ForStatement} end; {ForStatement}
@ -654,6 +659,7 @@ var
begin {IfStatement} begin {IfStatement}
NextToken; {skip the 'if' token} NextToken; {skip the 'if' token}
if c99Scope then PushTable;
Match(lparench, 13); {evaluate the condition} Match(lparench, 13); {evaluate the condition}
Expression(normalExpression, [rparench]); Expression(normalExpression, [rparench]);
Match(rparench, 12); Match(rparench, 12);
@ -667,6 +673,7 @@ var
statementList := stPtr; statementList := stPtr;
stPtr^.kind := ifSt; stPtr^.kind := ifSt;
stPtr^.ifLab := lab; stPtr^.ifLab := lab;
if c99Scope then PushTable;
Statement; {process the 'true' statement} Statement; {process the 'true' statement}
end; {IfStatement} end; {IfStatement}
@ -767,6 +774,7 @@ var
stPtr^.breakLab := stPtr^.switchExit; stPtr^.breakLab := stPtr^.switchExit;
stPtr^.switchList := nil; stPtr^.switchList := nil;
stPtr^.switchDefault := 0; stPtr^.switchDefault := 0;
if c99Scope then PushTable;
Match(lparench, 13); {evaluate the condition} Match(lparench, 13); {evaluate the condition}
Expression(normalExpression,[rparench]); Expression(normalExpression,[rparench]);
Match(rparench, 12); Match(rparench, 12);
@ -802,6 +810,7 @@ var
Error(71); Error(71);
end; {case} end; {case}
Gen1(pc_ujp, stPtr^.switchLab); {branch to the xjp instruction} Gen1(pc_ujp, stPtr^.switchLab); {branch to the xjp instruction}
if c99Scope then PushTable;
Statement; {process the loop body statement} Statement; {process the loop body statement}
end; {SwitchStatement} end; {SwitchStatement}
@ -828,11 +837,13 @@ var
stPtr^.breakLab := endl; stPtr^.breakLab := endl;
stPtr^.continueLab := top; stPtr^.continueLab := top;
Gen1(dc_lab, top); {define the top label} Gen1(dc_lab, top); {define the top label}
if c99Scope then PushTable;
Match(lparench, 13); {evaluate the condition} Match(lparench, 13); {evaluate the condition}
Expression(normalExpression, [rparench]); Expression(normalExpression, [rparench]);
Match(rparench, 12); Match(rparench, 12);
CompareToZero(pc_neq); {evaluate the condition} CompareToZero(pc_neq); {evaluate the condition}
Gen1(pc_fjp, endl); Gen1(pc_fjp, endl);
if c99Scope then PushTable;
Statement; {process the first loop body statement} Statement; {process the first loop body statement}
end; {WhileStatement} end; {WhileStatement}
@ -897,6 +908,7 @@ var
stPtr: statementPtr; {work pointer} stPtr: statementPtr; {work pointer}
begin {EndDoStatement} begin {EndDoStatement}
if c99Scope then PopTable;
stPtr := statementList; {get the statement record} stPtr := statementList; {get the statement record}
if token.kind = whilesy then begin {if a while clause exists, process it} if token.kind = whilesy then begin {if a while clause exists, process it}
NextToken; {skip the 'while' token} NextToken; {skip the 'while' token}
@ -915,6 +927,7 @@ if stPtr^.breakLab <> 0 then {create the break label}
Gen1(dc_lab, stPtr^.breakLab); Gen1(dc_lab, stPtr^.breakLab);
statementList := stPtr^.next; {pop the statement record} statementList := stPtr^.next; {pop the statement record}
dispose(stPtr); dispose(stPtr);
if c99Scope then PopTable;
end; {EndDoStatement} end; {EndDoStatement}
@ -927,6 +940,7 @@ var
stPtr: statementPtr; {work pointer} stPtr: statementPtr; {work pointer}
begin {EndIfStatement} begin {EndIfStatement}
if c99Scope then PopTable;
stPtr := statementList; {get the label to branch to} stPtr := statementList; {get the label to branch to}
lab1 := stPtr^.ifLab; lab1 := stPtr^.ifLab;
statementList := stPtr^.next; {pop the statement record} statementList := stPtr^.next; {pop the statement record}
@ -942,10 +956,13 @@ if token.kind = elsesy then begin {if an else clause exists, process it}
statementList := stPtr; statementList := stPtr;
stPtr^.kind := elseSt; stPtr^.kind := elseSt;
stPtr^.elseLab := lab2; stPtr^.elseLab := lab2;
if c99Scope then PushTable;
Statement; {evaluate the else clause} Statement; {evaluate the else clause}
end {if} end {if}
else else begin
Gen1(dc_lab, lab1); {create label for if to branch to} Gen1(dc_lab, lab1); {create label for if to branch to}
if c99Scope then PopTable;
end; {else}
end; {EndIfStatement} end; {EndIfStatement}
@ -957,10 +974,12 @@ var
stPtr: statementPtr; {work pointer} stPtr: statementPtr; {work pointer}
begin {EndElseStatement} begin {EndElseStatement}
if c99Scope then PopTable;
stPtr := statementList; {create the label to branch to} stPtr := statementList; {create the label to branch to}
Gen1(dc_lab, stPtr^.elseLab); Gen1(dc_lab, stPtr^.elseLab);
statementList := stPtr^.next; {pop the statement record} statementList := stPtr^.next; {pop the statement record}
dispose(stPtr); dispose(stPtr);
if c99Scope then PopTable;
end; {EndElseStatement} end; {EndElseStatement}
@ -975,6 +994,7 @@ var
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions} lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
begin {EndForStatement} begin {EndForStatement}
if c99Scope then PopTable;
stPtr := statementList; stPtr := statementList;
Gen1(dc_lab, stPtr^.continueLab); {define the continue label} Gen1(dc_lab, stPtr^.continueLab); {define the continue label}
@ -1003,6 +1023,7 @@ Gen1(pc_ujp, stPtr^.forLoop); {loop to the test}
Gen1(dc_lab, stPtr^.breakLab); {create the exit label} Gen1(dc_lab, stPtr^.breakLab); {create the exit label}
statementList := stPtr^.next; {pop the statement record} statementList := stPtr^.next; {pop the statement record}
dispose(stPtr); dispose(stPtr);
if c99Scope then PopTable;
end; {EndForStatement} end; {EndForStatement}
@ -1026,6 +1047,7 @@ var
swPtr,swPtr2: switchPtr; {switch label table list} swPtr,swPtr2: switchPtr; {switch label table list}
begin {EndSwitchStatement} begin {EndSwitchStatement}
if c99Scope then PopTable;
stPtr := statementList; {get the statement record} stPtr := statementList; {get the statement record}
exitLab := stPtr^.switchExit; {get the exit label} exitLab := stPtr^.switchExit; {get the exit label}
isLong := stPtr^.isLong; {get the long flag} isLong := stPtr^.isLong; {get the long flag}
@ -1095,6 +1117,7 @@ else begin
FreeTemp(stPtr^.ln, stPtr^.size); {release temp variable} FreeTemp(stPtr^.ln, stPtr^.size); {release temp variable}
statementList := stPtr^.next; {pop the statement record} statementList := stPtr^.next; {pop the statement record}
dispose(stPtr); dispose(stPtr);
if c99Scope then PopTable;
end; {EndSwitchStatement} end; {EndSwitchStatement}
@ -1106,11 +1129,13 @@ var
stPtr: statementPtr; {work pointer} stPtr: statementPtr; {work pointer}
begin {EndWhileStatement} begin {EndWhileStatement}
if c99Scope then PopTable;
stPtr := statementList; {loop to the test} stPtr := statementList; {loop to the test}
Gen1(pc_ujp, stPtr^.whileTop); Gen1(pc_ujp, stPtr^.whileTop);
Gen1(dc_lab, stPtr^.whileEnd); {create the exit label} Gen1(dc_lab, stPtr^.whileEnd); {create the exit label}
statementList := stPtr^.next; {pop the statement record} statementList := stPtr^.next; {pop the statement record}
dispose(stPtr); dispose(stPtr);
if c99Scope then PopTable;
end; {EndWhileStatement} end; {EndWhileStatement}
{-- Type declarations ------------------------------------------} {-- Type declarations ------------------------------------------}