1 /* S T A T E M E N T S */
20 int slevel = 0; /* nesting level of statements */
24 /* ISO section 6.8.3.2, p. 128 */
26 BEGIN StatementSequence END
29 /* ISO section 6.8.3.1, p. 128 */
35 { chk_labels(slevel + 1); }
38 /* ISO section 6.8.1, p. 126 */
47 { if( nd ) DefLabel(nd, slevel); }
50 C_lin((arith) dot.tk_lineno);
55 if (ms_lineno != dot.tk_lineno) {
56 C_ms_std((char *) 0, N_SLINE, (int) dot.tk_lineno);
57 ms_lineno = dot.tk_lineno;
70 /* ISO section 6.8.2.1, p. 126 */
73 struct node *pnd, *expp;
76 /* This is a changed rule, because the grammar as specified in the
77 * reference is not LL(1), and this gives conflicts.
78 * Note : the grammar states : AssignmentStatement |
79 * ProcedureStatement | ...
80 * In order to add assertions, there is an extra entry, which gives
81 * a conflict. This conflict is then resolved using an %if clause.
87 /* Evidently this is the beginning of the changed part
89 %if( !options['s'] && !strcmp(dot.TOK_IDF->id_text, "assert") )
90 IDENT { line = LineNumber; }
92 { AssertStat(expp, line);
96 IDENT { pnd = MkLeaf(Name, &dot); }
99 /* At this point the IDENT can be a FunctionIdentifier in
100 * which case the VariableAccessTail must be empty.
102 VariableAccessTail(&pnd)
107 '=' { error("':=' expected instead of '='"); }
110 { AssignStat(pnd, expp); }
112 { pnd = MkNode(Call, pnd, NULLNODE, &dot); }
113 ActualParameterList(&(pnd->nd_right))?
125 /* end of changed part
131 struct node *nd = NULLNODE;
133 /* This is a new rule because the grammar specified by the standard
134 * is not exactly LL(1) (see SimpleStatement).
137 READ ReadParameterList(&nd) { ChkRead(nd); }
139 READLN ReadParameterList(&nd)? { ChkReadln(nd); }
141 WRITE WriteParameterList(&nd) { ChkWrite(nd); }
143 WRITELN WriteParameterList(&nd)? { ChkWriteln(nd); }
152 /* ISO section 6.8.3.1, p. 128 */
163 /* ISO section 6.8.2.4, p. 127 */
169 { if( nd ) TstLabel(nd, slevel); }
172 /* ISO section 6.8.3.3, p. 128 */
173 ConditionalStatement:
180 /* ISO section 6.8.3.6, p. 129 */
189 /* ISO section 6.8.3.10, p. 132 */
192 struct scopelist *Save = CurrVis;
196 RecordVariableList(&nd)
198 Statement { EndWith(Save, nd);
199 chk_labels(slevel + 1);
203 RecordVariableList(register struct node **pnd;)
208 { *pnd = nd = MkNode(Link, nd, NULLNODE, &dot);
212 ',' { nd->nd_right = MkLeaf(Link, &dot);
215 RecordVariable(&(nd->nd_left))
219 RecordVariable(register struct node **pnd;):
224 /* ISO section 6.8.3.4, p. 128 */
228 label l1 = ++text_label;
229 label l2 = ++text_label;
232 BooleanExpression(&nd)
237 CodeExpr(nd, &ds, l1);
241 Statement { chk_labels(slevel + 1); }
242 [ %prefer /* closest matching */
249 chk_labels(slevel + 1);
257 /* ISO section 6.8.3.5, p. 128 */
260 struct node *casend, *nd;
263 /* This is a changed rule, because the grammar as specified in the
264 * reference states that a semicolon is optional before END,
265 * and this is not LL(1).
267 CASE { casend = nd = MkLeaf(Link, &dot);
268 casend->nd_lab = ++text_label;
269 exit_label = ++text_label;
271 Expression(&(nd->nd_left))
272 { CaseExpr(casend); }
274 CaseListElement(&(nd->nd_right), exit_label)
275 { nd = nd->nd_right; }
276 CaseListElementTail(&(nd->nd_right), exit_label)
278 { CaseEnd(casend, exit_label); }
281 CaseListElementTail(register struct node **pnd; label exit_label;):
282 /* This is a new rule, all because of a silly semicolon
291 CaseListElement(pnd, exit_label)
292 CaseListElementTail(&((*pnd)->nd_right), exit_label)
296 CaseListElement(register struct node **pnd; label exit_label;):
297 CaseConstantList(pnd)
299 { *pnd = MkNode(Link, *pnd, NULLNODE, &dot);
300 (*pnd)->nd_lab = ++text_label;
301 C_df_ilb(text_label);
303 Statement { C_bra(exit_label);
304 chk_labels(slevel + 1);
308 /* ISO section 6.8.3.7, p. 129 */
312 label repeatlb = ++text_label;
315 { C_df_ilb(repeatlb); }
318 BooleanExpression(&nd)
323 CodeExpr(nd, &ds, repeatlb);
328 /* ISO section 6.8.3.8, p. 129 */
332 label whilelb = ++text_label;
333 label exitlb = ++text_label;
337 { C_df_ilb(whilelb); }
338 BooleanExpression(&nd)
343 CodeExpr(nd, &ds, exitlb);
350 chk_labels(slevel + 1);
354 /* ISO section 6.8.3.9, p. 130 */
357 register struct node *nd;
359 label l1 = ++text_label;
360 label l2 = ++text_label;
361 arith tmp2 = (arith) 0;
364 /* ControlVariable must be an EntireVariable */
365 IDENT { nd = MkLeaf(Name, &dot); }
367 Expression(&(nd->nd_left))
371 DOWNTO { stepsize = -1; }
373 Expression(&(nd->nd_right))
375 if( !err_occurred ) {
376 CodePExpr(nd->nd_left);
378 tmp2 = CodeInitFor(nd->nd_right, 2);
379 CodeFor(nd, stepsize, l1, l2);
384 { if( !err_occurred )
385 CodeEndFor(nd, stepsize, l1, l2, tmp2);
387 chk_labels(slevel + 1);
389 if( tmp2 ) FreeInt(tmp2);
393 /* SPECIALSPECIALSPECIALSPECIALSPECIALSPECIALSPECIALSPECIALSPECIALSPECIAL */
394 /* ISO section 6.9, p. 132-136 */
395 ReadParameterList(register struct node **pnd;)
397 register struct node *nd;
399 /* This is a changed rule, because the grammar as specified in the
400 * reference is not LL(1), and this gives conflicts.
403 VariableAccess(pnd) /* possibly a FileVariable */
405 MkNode(Link, *pnd, NULLNODE, &dot);
409 ',' { nd->nd_right = MkLeaf(Link, &dot);
412 VariableAccess(&(nd->nd_left))
417 WriteParameterList(register struct node **pnd;)
419 register struct node *nd;
421 /* This is a changed rule, because the grammar as specified in the
422 * reference is not LL(1), and this gives conflicts.
425 /* Only the first WriteParameter can be a FileVariable !!
429 MkNode(Link, *pnd, NULLNODE, &dot);
433 ',' { nd->nd_right = MkLeaf(Link, &dot);
436 WriteParameter(&(nd->nd_left))
441 WriteParameter(register struct node **pnd;)
443 register struct node *nd;
446 { if( !ChkExpression(*pnd) )
447 (*pnd)->nd_type = error_type;
450 MkNode(Link, *pnd, NULLNODE, &dot);
454 /* Here the first Expression can't be a FileVariable
456 ':' { nd->nd_right = MkLeaf(Link, &dot);
459 Expression(&(nd->nd_left))
460 { if( !ChkExpression(nd->nd_left) )
461 nd->nd_left->nd_type = error_type;
462 MarkUsed(nd->nd_left);
465 ':' { nd->nd_right = MkLeaf(Link, &dot);
468 Expression(&(nd->nd_left))
469 { if( !ChkExpression(nd->nd_left) )
470 nd->nd_left->nd_type = error_type;
471 MarkUsed(nd->nd_left);