1987-04-29 10:22:07 +00:00
|
|
|
/*
|
|
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
|
|
*
|
|
|
|
* Author: Ceriel J.H. Jacobs
|
|
|
|
*/
|
|
|
|
|
1986-03-26 15:11:02 +00:00
|
|
|
/* S T A T E M E N T S */
|
|
|
|
|
1987-04-29 10:22:07 +00:00
|
|
|
/* $Header$ */
|
|
|
|
|
1986-03-20 14:52:03 +00:00
|
|
|
{
|
1986-06-26 09:39:36 +00:00
|
|
|
#include <assert.h>
|
1986-04-06 17:42:56 +00:00
|
|
|
#include <em_arith.h>
|
1986-04-17 09:28:09 +00:00
|
|
|
#include <em_label.h>
|
1986-04-28 18:06:58 +00:00
|
|
|
|
1986-04-22 22:36:16 +00:00
|
|
|
#include "idf.h"
|
1986-04-06 17:42:56 +00:00
|
|
|
#include "LLlex.h"
|
1986-04-22 22:36:16 +00:00
|
|
|
#include "scope.h"
|
|
|
|
#include "def.h"
|
1986-04-17 09:28:09 +00:00
|
|
|
#include "type.h"
|
1986-04-06 17:42:56 +00:00
|
|
|
#include "node.h"
|
1986-04-15 17:51:53 +00:00
|
|
|
|
|
|
|
static int loopcount = 0; /* Count nested loops */
|
1987-09-23 16:39:43 +00:00
|
|
|
extern t_node *EmptyStatement;
|
1986-03-20 14:52:03 +00:00
|
|
|
}
|
|
|
|
|
1987-09-23 16:39:43 +00:00
|
|
|
statement(register t_node **pnd;)
|
1986-04-06 17:42:56 +00:00
|
|
|
{
|
1987-09-23 16:39:43 +00:00
|
|
|
register t_node *nd;
|
1986-10-06 20:36:30 +00:00
|
|
|
extern int return_occurred;
|
1986-04-06 17:42:56 +00:00
|
|
|
} :
|
1986-03-20 14:52:03 +00:00
|
|
|
/*
|
|
|
|
* This part is not in the reference grammar. The reference grammar
|
|
|
|
* states : assignment | ProcedureCall | ...
|
|
|
|
* but this gives LL(1) conflicts
|
|
|
|
*/
|
1986-04-17 09:28:09 +00:00
|
|
|
designator(pnd)
|
1987-09-23 16:39:43 +00:00
|
|
|
[ { nd = dot2node(Stat, *pnd, NULLNODE);
|
1986-04-17 09:28:09 +00:00
|
|
|
nd->nd_symb = '(';
|
1990-09-14 14:37:24 +00:00
|
|
|
nd->nd_lineno = (*pnd)->nd_lineno;
|
1986-04-09 18:14:49 +00:00
|
|
|
}
|
1986-04-17 09:28:09 +00:00
|
|
|
ActualParameters(&(nd->nd_right))?
|
1986-03-20 14:52:03 +00:00
|
|
|
|
|
1986-11-28 11:59:08 +00:00
|
|
|
[ BECOMES
|
|
|
|
| '=' { error("':=' expected instead of '='");
|
|
|
|
DOT = BECOMES;
|
|
|
|
}
|
|
|
|
]
|
1987-08-10 21:43:47 +00:00
|
|
|
{ nd = dot2node(Stat, *pnd, NULLNODE); }
|
1986-04-17 09:28:09 +00:00
|
|
|
expression(&(nd->nd_right))
|
1986-03-20 14:52:03 +00:00
|
|
|
]
|
1986-04-17 09:28:09 +00:00
|
|
|
{ *pnd = nd; }
|
1986-03-20 14:52:03 +00:00
|
|
|
/*
|
|
|
|
* end of changed part
|
|
|
|
*/
|
|
|
|
|
|
1986-04-15 17:51:53 +00:00
|
|
|
IfStatement(pnd)
|
1986-03-20 14:52:03 +00:00
|
|
|
|
|
1986-04-15 17:51:53 +00:00
|
|
|
CaseStatement(pnd)
|
1986-03-20 14:52:03 +00:00
|
|
|
|
|
1987-08-10 21:43:47 +00:00
|
|
|
WHILE { *pnd = nd = dot2leaf(Stat); }
|
1987-08-03 18:20:55 +00:00
|
|
|
expression(&(nd->nd_left))
|
|
|
|
DO
|
|
|
|
StatementSequence(&(nd->nd_right))
|
|
|
|
END
|
1986-03-20 14:52:03 +00:00
|
|
|
|
|
1987-08-10 21:43:47 +00:00
|
|
|
REPEAT { *pnd = nd = dot2leaf(Stat); }
|
1987-08-03 18:20:55 +00:00
|
|
|
StatementSequence(&(nd->nd_left))
|
|
|
|
UNTIL
|
|
|
|
expression(&(nd->nd_right))
|
1986-03-20 14:52:03 +00:00
|
|
|
|
|
1986-04-15 17:51:53 +00:00
|
|
|
{ loopcount++; }
|
1987-08-10 21:43:47 +00:00
|
|
|
LOOP { *pnd = nd = dot2leaf(Stat); }
|
1987-08-03 18:20:55 +00:00
|
|
|
StatementSequence(&((*pnd)->nd_right))
|
|
|
|
END
|
1986-04-15 17:51:53 +00:00
|
|
|
{ loopcount--; }
|
1986-03-20 14:52:03 +00:00
|
|
|
|
|
1986-04-15 17:51:53 +00:00
|
|
|
ForStatement(pnd)
|
1986-03-20 14:52:03 +00:00
|
|
|
|
|
1986-04-15 17:51:53 +00:00
|
|
|
WithStatement(pnd)
|
1986-03-20 14:52:03 +00:00
|
|
|
|
|
|
|
|
EXIT
|
1986-05-30 18:48:00 +00:00
|
|
|
{ if (!loopcount) error("EXIT not in a LOOP");
|
1987-08-10 21:43:47 +00:00
|
|
|
*pnd = dot2leaf(Stat);
|
1986-04-15 17:51:53 +00:00
|
|
|
}
|
1986-03-20 14:52:03 +00:00
|
|
|
|
|
1986-05-30 18:48:00 +00:00
|
|
|
ReturnStatement(pnd)
|
1986-10-06 20:36:30 +00:00
|
|
|
{ return_occurred = 1; }
|
1986-06-04 09:01:48 +00:00
|
|
|
|
|
1987-08-10 21:43:47 +00:00
|
|
|
/* empty */ { *pnd = EmptyStatement; }
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The next two rules in-line in "Statement", because of an LL(1) conflict
|
|
|
|
|
|
|
|
assignment:
|
|
|
|
designator BECOMES expression
|
|
|
|
;
|
|
|
|
|
|
|
|
ProcedureCall:
|
|
|
|
designator ActualParameters?
|
|
|
|
;
|
|
|
|
*/
|
|
|
|
|
1987-09-23 16:39:43 +00:00
|
|
|
StatementSequence(register t_node **pnd;)
|
1986-06-04 09:01:48 +00:00
|
|
|
{
|
1987-09-23 16:39:43 +00:00
|
|
|
t_node *nd;
|
|
|
|
register t_node *nd1;
|
1986-06-04 09:01:48 +00:00
|
|
|
} :
|
1986-04-15 17:51:53 +00:00
|
|
|
statement(pnd)
|
1986-09-25 19:39:06 +00:00
|
|
|
[ %persistent
|
1987-08-11 10:50:30 +00:00
|
|
|
';'
|
|
|
|
statement(&nd)
|
1988-11-28 12:54:38 +00:00
|
|
|
{ if (nd != EmptyStatement) {
|
|
|
|
nd1 = dot2node(Link, *pnd, nd);
|
|
|
|
*pnd = nd1;
|
|
|
|
nd1->nd_symb = ';';
|
|
|
|
pnd = &(nd1->nd_right);
|
|
|
|
}
|
1986-04-15 17:51:53 +00:00
|
|
|
}
|
|
|
|
]*
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
1987-09-23 16:39:43 +00:00
|
|
|
IfStatement(t_node **pnd;)
|
1986-04-06 17:42:56 +00:00
|
|
|
{
|
1987-09-23 16:39:43 +00:00
|
|
|
register t_node *nd;
|
1986-04-06 17:42:56 +00:00
|
|
|
} :
|
1987-08-10 21:43:47 +00:00
|
|
|
IF { nd = dot2leaf(Stat);
|
1986-04-15 17:51:53 +00:00
|
|
|
*pnd = nd;
|
|
|
|
}
|
|
|
|
expression(&(nd->nd_left))
|
1987-08-10 21:43:47 +00:00
|
|
|
THEN { nd->nd_right = dot2leaf(Link);
|
1986-06-04 09:01:48 +00:00
|
|
|
nd = nd->nd_right;
|
1986-04-15 17:51:53 +00:00
|
|
|
}
|
|
|
|
StatementSequence(&(nd->nd_left))
|
|
|
|
[
|
1987-08-10 21:43:47 +00:00
|
|
|
ELSIF { nd->nd_right = dot2leaf(Stat);
|
1986-04-15 17:51:53 +00:00
|
|
|
nd = nd->nd_right;
|
|
|
|
nd->nd_symb = IF;
|
|
|
|
}
|
|
|
|
expression(&(nd->nd_left))
|
1987-08-10 21:43:47 +00:00
|
|
|
THEN { nd->nd_right = dot2leaf(Link);
|
1986-04-15 17:51:53 +00:00
|
|
|
nd = nd->nd_right;
|
|
|
|
}
|
|
|
|
StatementSequence(&(nd->nd_left))
|
|
|
|
]*
|
|
|
|
[
|
|
|
|
ELSE
|
|
|
|
StatementSequence(&(nd->nd_right))
|
1988-02-10 14:06:34 +00:00
|
|
|
|
|
|
|
|
]
|
1986-03-20 14:52:03 +00:00
|
|
|
END
|
|
|
|
;
|
|
|
|
|
1987-09-23 16:39:43 +00:00
|
|
|
CaseStatement(t_node **pnd;)
|
1986-04-06 17:42:56 +00:00
|
|
|
{
|
1987-09-23 16:39:43 +00:00
|
|
|
register t_node *nd;
|
|
|
|
t_type *tp = 0;
|
1986-04-06 17:42:56 +00:00
|
|
|
} :
|
1987-08-10 21:43:47 +00:00
|
|
|
CASE { *pnd = nd = dot2leaf(Stat); }
|
1986-04-15 17:51:53 +00:00
|
|
|
expression(&(nd->nd_left))
|
|
|
|
OF
|
|
|
|
case(&(nd->nd_right), &tp)
|
|
|
|
{ nd = nd->nd_right; }
|
|
|
|
[
|
|
|
|
'|'
|
|
|
|
case(&(nd->nd_right), &tp)
|
|
|
|
{ nd = nd->nd_right; }
|
|
|
|
]*
|
1987-04-29 10:22:07 +00:00
|
|
|
[ ELSE StatementSequence(&(nd->nd_right))
|
1988-02-10 14:06:34 +00:00
|
|
|
|
|
|
|
|
]
|
1986-03-20 14:52:03 +00:00
|
|
|
END
|
|
|
|
;
|
|
|
|
|
1987-09-23 16:39:43 +00:00
|
|
|
case(t_node **pnd; t_type **ptp;) :
|
1986-04-17 09:28:09 +00:00
|
|
|
[ CaseLabelList(ptp, pnd)
|
1987-08-10 21:43:47 +00:00
|
|
|
':' { *pnd = dot2node(Link, *pnd, NULLNODE); }
|
1986-04-15 17:51:53 +00:00
|
|
|
StatementSequence(&((*pnd)->nd_right))
|
1988-02-10 14:06:34 +00:00
|
|
|
|
|
|
|
|
]
|
1987-08-10 21:43:47 +00:00
|
|
|
{ *pnd = dot2node(Link, *pnd, NULLNODE);
|
1986-04-15 17:51:53 +00:00
|
|
|
(*pnd)->nd_symb = '|';
|
|
|
|
}
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
1987-08-03 18:20:55 +00:00
|
|
|
/* inline in statement; lack of space
|
1987-09-23 16:39:43 +00:00
|
|
|
WhileStatement(t_node **pnd;)
|
1986-04-06 17:42:56 +00:00
|
|
|
{
|
1987-09-23 16:39:43 +00:00
|
|
|
register t_node *nd;
|
1986-04-06 17:42:56 +00:00
|
|
|
}:
|
1987-08-10 21:43:47 +00:00
|
|
|
WHILE { *pnd = nd = dot2leaf(Stat); }
|
1986-04-15 17:51:53 +00:00
|
|
|
expression(&(nd->nd_left))
|
|
|
|
DO
|
|
|
|
StatementSequence(&(nd->nd_right))
|
|
|
|
END
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
1987-09-23 16:39:43 +00:00
|
|
|
RepeatStatement(t_node **pnd;)
|
1986-04-06 17:42:56 +00:00
|
|
|
{
|
1987-09-23 16:39:43 +00:00
|
|
|
register t_node *nd;
|
1986-04-06 17:42:56 +00:00
|
|
|
}:
|
1987-08-10 21:43:47 +00:00
|
|
|
REPEAT { *pnd = nd = dot2leaf(Stat); }
|
1986-04-15 17:51:53 +00:00
|
|
|
StatementSequence(&(nd->nd_left))
|
|
|
|
UNTIL
|
|
|
|
expression(&(nd->nd_right))
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
1987-08-03 18:20:55 +00:00
|
|
|
*/
|
1986-03-20 14:52:03 +00:00
|
|
|
|
1987-09-23 16:39:43 +00:00
|
|
|
ForStatement(t_node **pnd;)
|
1986-04-06 17:42:56 +00:00
|
|
|
{
|
1987-09-23 16:39:43 +00:00
|
|
|
register t_node *nd, *nd1;
|
|
|
|
t_node *dummy;
|
1986-04-06 17:42:56 +00:00
|
|
|
}:
|
1987-08-10 21:43:47 +00:00
|
|
|
FOR { *pnd = nd = dot2leaf(Stat); }
|
1986-06-04 09:01:48 +00:00
|
|
|
IDENT { nd->nd_IDF = dot.TOK_IDF; }
|
1987-08-10 21:43:47 +00:00
|
|
|
BECOMES { nd->nd_left = nd1 = dot2leaf(Stat); }
|
1986-10-06 20:36:30 +00:00
|
|
|
expression(&(nd1->nd_left))
|
1986-05-30 18:48:00 +00:00
|
|
|
TO
|
1986-10-06 20:36:30 +00:00
|
|
|
expression(&(nd1->nd_right))
|
1986-04-15 17:51:53 +00:00
|
|
|
[
|
1986-05-30 18:48:00 +00:00
|
|
|
BY
|
|
|
|
ConstExpression(&dummy)
|
1986-07-08 14:59:02 +00:00
|
|
|
{ if (!(dummy->nd_type->tp_fund & T_INTORCARD)) {
|
1986-05-30 18:48:00 +00:00
|
|
|
error("illegal type in BY clause");
|
|
|
|
}
|
1986-10-06 20:36:30 +00:00
|
|
|
nd1->nd_INT = dummy->nd_INT;
|
1986-05-30 18:48:00 +00:00
|
|
|
FreeNode(dummy);
|
1986-04-15 17:51:53 +00:00
|
|
|
}
|
|
|
|
|
|
1986-10-06 20:36:30 +00:00
|
|
|
{ nd1->nd_INT = 1; }
|
1986-04-15 17:51:53 +00:00
|
|
|
]
|
|
|
|
DO
|
1986-10-06 20:36:30 +00:00
|
|
|
StatementSequence(&(nd->nd_right))
|
1986-04-15 17:51:53 +00:00
|
|
|
END
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
1987-08-03 18:20:55 +00:00
|
|
|
/* inline in Statement; lack of space
|
1987-09-23 16:39:43 +00:00
|
|
|
LoopStatement(t_node **pnd;):
|
1987-08-10 21:43:47 +00:00
|
|
|
LOOP { *pnd = dot2leaf(Stat); }
|
1986-04-15 17:51:53 +00:00
|
|
|
StatementSequence(&((*pnd)->nd_right))
|
|
|
|
END
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
1987-08-03 18:20:55 +00:00
|
|
|
*/
|
1986-03-20 14:52:03 +00:00
|
|
|
|
1987-09-23 16:39:43 +00:00
|
|
|
WithStatement(t_node **pnd;)
|
1986-04-06 17:42:56 +00:00
|
|
|
{
|
1987-09-23 16:39:43 +00:00
|
|
|
register t_node *nd;
|
1986-04-06 17:42:56 +00:00
|
|
|
}:
|
1987-08-10 21:43:47 +00:00
|
|
|
WITH { *pnd = nd = dot2leaf(Stat); }
|
1986-04-15 17:51:53 +00:00
|
|
|
designator(&(nd->nd_left))
|
|
|
|
DO
|
|
|
|
StatementSequence(&(nd->nd_right))
|
|
|
|
END
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
1986-05-30 18:48:00 +00:00
|
|
|
|
1987-09-23 16:39:43 +00:00
|
|
|
ReturnStatement(t_node **pnd;)
|
1986-05-30 18:48:00 +00:00
|
|
|
{
|
1987-09-23 16:39:43 +00:00
|
|
|
register t_def *df = CurrentScope->sc_definedby;
|
1990-11-22 09:49:37 +00:00
|
|
|
register t_type *tp = df->df_type ? ResultType(df->df_type) : 0;
|
1987-09-23 16:39:43 +00:00
|
|
|
register t_node *nd;
|
1986-05-30 18:48:00 +00:00
|
|
|
} :
|
|
|
|
|
1987-08-10 21:43:47 +00:00
|
|
|
RETURN { *pnd = nd = dot2leaf(Stat); }
|
1986-05-30 18:48:00 +00:00
|
|
|
[
|
|
|
|
expression(&(nd->nd_right))
|
|
|
|
{ if (scopeclosed(CurrentScope)) {
|
1988-11-28 12:54:38 +00:00
|
|
|
error("a module body cannot return a value");
|
1986-05-30 18:48:00 +00:00
|
|
|
}
|
1990-11-22 09:49:37 +00:00
|
|
|
else if (! tp) {
|
1988-11-28 12:54:38 +00:00
|
|
|
error("procedure \"%s\" is not a function, so cannot return a value", df->df_idf->id_text);
|
1986-05-30 18:48:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
1990-11-22 09:49:37 +00:00
|
|
|
{ if (tp) {
|
1988-11-28 12:54:38 +00:00
|
|
|
error("function procedure \"%s\" must return a value", df->df_idf->id_text);
|
1986-05-30 18:48:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
;
|