2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
5 * Author: Ceriel J.H. Jacobs
8 /* S T A T E M E N T S */
10 /* $Id: statement.g,v 1.34 1997/02/21 17:10:16 ceriel Exp $ */
24 static int loopcount = 0; /* Count nested loops */
25 extern t_node *EmptyStatement;
28 statement(register t_node **pnd;)
31 extern int return_occurred;
34 * This part is not in the reference grammar. The reference grammar
35 * states : assignment | ProcedureCall | ...
36 * but this gives LL(1) conflicts
39 [ { nd = dot2node(Stat, *pnd, NULLNODE);
41 nd->nd_lineno = (*pnd)->nd_lineno;
43 ActualParameters(&(nd->nd_RIGHT))?
47 { error("':=' expected instead of '='");
51 { nd = dot2node(Stat, *pnd, NULLNODE); }
52 expression(&(nd->nd_RIGHT))
63 WHILE { *pnd = nd = dot2leaf(Stat); }
64 expression(&(nd->nd_LEFT))
66 StatementSequence(&(nd->nd_RIGHT))
69 REPEAT { *pnd = nd = dot2leaf(Stat); }
70 StatementSequence(&(nd->nd_LEFT))
72 expression(&(nd->nd_RIGHT))
75 LOOP { *pnd = nd = dot2leaf(Stat); }
76 StatementSequence(&((*pnd)->nd_RIGHT))
82 WITH { *pnd = nd = dot2leaf(Stat); }
83 designator(&(nd->nd_LEFT))
85 StatementSequence(&(nd->nd_RIGHT))
89 { if (!loopcount) error("EXIT not in a LOOP");
90 *pnd = dot2leaf(Stat);
94 { return_occurred = 1; }
96 /* empty */ { *pnd = EmptyStatement; }
100 * The next two rules in-line in "Statement", because of an LL(1) conflict
103 designator BECOMES expression
107 designator ActualParameters?
111 StatementSequence(register t_node **pnd;)
114 register t_node *nd1;
120 { if (nd != EmptyStatement) {
121 nd1 = dot2node(Link, *pnd, nd);
124 pnd = &(nd1->nd_RIGHT);
130 IfStatement(t_node **pnd;)
134 IF { nd = dot2leaf(Stat);
137 expression(&(nd->nd_LEFT))
138 THEN { nd->nd_RIGHT = dot2leaf(Link);
141 StatementSequence(&(nd->nd_LEFT))
143 ELSIF { nd->nd_RIGHT = dot2leaf(Stat);
147 expression(&(nd->nd_LEFT))
148 THEN { nd->nd_RIGHT = dot2leaf(Link);
151 StatementSequence(&(nd->nd_LEFT))
155 StatementSequence(&(nd->nd_RIGHT))
161 CaseStatement(t_node **pnd;)
166 CASE { *pnd = nd = dot2leaf(Stat); }
167 expression(&(nd->nd_LEFT))
169 case(&(nd->nd_RIGHT), &tp)
170 { nd = nd->nd_RIGHT; }
173 case(&(nd->nd_RIGHT), &tp)
174 { nd = nd->nd_RIGHT; }
176 [ ELSE StatementSequence(&(nd->nd_RIGHT))
182 case(t_node **pnd; t_type **ptp;) :
183 [ CaseLabelList(ptp, pnd)
184 ':' { *pnd = dot2node(Link, *pnd, NULLNODE); }
185 StatementSequence(&((*pnd)->nd_RIGHT))
188 { *pnd = dot2node(Link, *pnd, NULLNODE);
189 (*pnd)->nd_symb = '|';
193 /* inline in statement; lack of space
194 WhileStatement(t_node **pnd;)
198 WHILE { *pnd = nd = dot2leaf(Stat); }
199 expression(&(nd->nd_LEFT))
201 StatementSequence(&(nd->nd_RIGHT))
205 RepeatStatement(t_node **pnd;)
209 REPEAT { *pnd = nd = dot2leaf(Stat); }
210 StatementSequence(&(nd->nd_LEFT))
212 expression(&(nd->nd_RIGHT))
216 ForStatement(t_node **pnd;)
218 register t_node *nd, *nd1;
220 FOR { *pnd = nd = dot2leaf(Stat); }
221 IDENT { nd1 = dot2leaf(Name); }
222 BECOMES { nd->nd_LEFT = dot2node(Stat, nd1, dot2leaf(Link));
223 nd1 = nd->nd_LEFT->nd_RIGHT;
226 expression(&(nd1->nd_LEFT))
228 expression(&(nd1->nd_RIGHT))
229 { nd->nd_RIGHT = nd1 = dot2leaf(Link);
234 ConstExpression(&(nd1->nd_LEFT))
235 { if (!(nd1->nd_LEFT->nd_type->tp_fund & T_INTORCARD)) {
236 error("illegal type in BY clause");
240 { nd1->nd_LEFT = dot2leaf(Value);
241 nd1->nd_LEFT->nd_INT = 1;
245 StatementSequence(&(nd1->nd_RIGHT))
249 /* inline in Statement; lack of space
250 LoopStatement(t_node **pnd;):
251 LOOP { *pnd = dot2leaf(Stat); }
252 StatementSequence(&((*pnd)->nd_RIGHT))
256 WithStatement(t_node **pnd;)
260 WITH { *pnd = nd = dot2leaf(Stat); }
261 designator(&(nd->nd_LEFT))
263 StatementSequence(&(nd->nd_RIGHT))
268 ReturnStatement(t_node **pnd;)
270 register t_def *df = CurrentScope->sc_definedby;
271 register t_type *tp = df->df_type ? ResultType(df->df_type) : 0;
275 RETURN { *pnd = nd = dot2leaf(Stat); }
277 expression(&(nd->nd_RIGHT))
278 { if (scopeclosed(CurrentScope)) {
279 error("a module body cannot return a value");
282 error("procedure \"%s\" is not a function, so cannot return a value", df->df_idf->id_text);
287 error("function procedure \"%s\" must return a value", df->df_idf->id_text);