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-27 17:37:41 +00:00
|
|
|
/* E X P R E S S I O N S */
|
|
|
|
|
1994-06-24 14:02:31 +00:00
|
|
|
/* $Id$ */
|
1987-04-29 10:22:07 +00:00
|
|
|
|
1986-03-20 14:52:03 +00:00
|
|
|
{
|
2019-03-01 17:39:25 +00:00
|
|
|
#include "parameters.h"
|
1986-05-01 19:06:53 +00:00
|
|
|
#include "debug.h"
|
1986-03-27 17:37:41 +00:00
|
|
|
|
2019-03-01 17:39:25 +00:00
|
|
|
#include "alloc.h"
|
|
|
|
#include "em_arith.h"
|
|
|
|
#include "em_label.h"
|
1986-04-09 18:14:49 +00:00
|
|
|
#include <assert.h>
|
1986-05-01 19:06:53 +00:00
|
|
|
|
1986-03-27 17:37:41 +00:00
|
|
|
#include "LLlex.h"
|
|
|
|
#include "idf.h"
|
|
|
|
#include "def.h"
|
1986-04-06 17:42:56 +00:00
|
|
|
#include "node.h"
|
1986-04-07 17:40:38 +00:00
|
|
|
#include "type.h"
|
2019-03-01 17:39:25 +00:00
|
|
|
#include "error.h"
|
1986-06-17 12:04:05 +00:00
|
|
|
#include "chk_expr.h"
|
1986-11-05 14:33:00 +00:00
|
|
|
#include "warning.h"
|
|
|
|
|
|
|
|
extern char options[];
|
1986-03-20 14:52:03 +00:00
|
|
|
}
|
|
|
|
|
1987-06-18 15:46:08 +00:00
|
|
|
/* inline, we need room for pdp/11
|
2019-05-10 17:09:03 +00:00
|
|
|
number(struct node **p;) :
|
1986-04-06 17:42:56 +00:00
|
|
|
[
|
1986-05-28 18:36:51 +00:00
|
|
|
%default
|
1986-06-17 12:04:05 +00:00
|
|
|
INTEGER
|
1986-03-20 14:52:03 +00:00
|
|
|
|
|
1986-06-17 12:04:05 +00:00
|
|
|
REAL
|
1987-08-10 21:43:47 +00:00
|
|
|
] { *p = dot2leaf(Value);
|
1986-06-17 12:04:05 +00:00
|
|
|
(*p)->nd_type = toktype;
|
1986-04-07 17:40:38 +00:00
|
|
|
}
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
1987-06-18 15:46:08 +00:00
|
|
|
*/
|
1986-03-20 14:52:03 +00:00
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
qualident(struct node **p;)
|
1986-03-27 17:37:41 +00:00
|
|
|
{
|
|
|
|
} :
|
1987-08-10 21:43:47 +00:00
|
|
|
IDENT { *p = dot2leaf(Name); }
|
1986-03-27 17:37:41 +00:00
|
|
|
[
|
1986-11-17 11:41:28 +00:00
|
|
|
selector(p)
|
1986-03-27 17:37:41 +00:00
|
|
|
]*
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
selector(register struct node **pnd;)
|
|
|
|
{ struct node *nd;
|
1991-03-12 16:52:00 +00:00
|
|
|
} :
|
|
|
|
'.' { nd = dot2leaf(Select); nd->nd_NEXT = *pnd; *pnd = nd; }
|
1986-05-30 18:48:00 +00:00
|
|
|
IDENT { (*pnd)->nd_IDF = dot.TOK_IDF; }
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
ExpList(struct node **pnd;)
|
1986-04-06 17:42:56 +00:00
|
|
|
{
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct node *nd;
|
1986-04-06 17:42:56 +00:00
|
|
|
} :
|
1987-08-10 21:43:47 +00:00
|
|
|
expression(pnd) { *pnd = nd = dot2node(Link,*pnd,NULLNODE);
|
1986-11-26 16:40:45 +00:00
|
|
|
nd->nd_symb = ',';
|
1986-04-10 01:08:49 +00:00
|
|
|
}
|
1986-04-06 17:42:56 +00:00
|
|
|
[
|
1991-03-12 16:52:00 +00:00
|
|
|
',' { nd->nd_RIGHT = dot2leaf(Link);
|
|
|
|
nd = nd->nd_RIGHT;
|
1986-04-06 17:42:56 +00:00
|
|
|
}
|
1991-03-12 16:52:00 +00:00
|
|
|
expression(&(nd->nd_LEFT))
|
1986-04-06 17:42:56 +00:00
|
|
|
]*
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
ConstExpression(register struct node **pnd;)
|
1986-11-26 16:40:45 +00:00
|
|
|
{
|
|
|
|
}:
|
1986-04-06 17:42:56 +00:00
|
|
|
expression(pnd)
|
1986-03-20 14:52:03 +00:00
|
|
|
/*
|
|
|
|
* Changed rule in new Modula-2.
|
|
|
|
* Check that the expression is a constant expression and evaluate!
|
|
|
|
*/
|
1991-03-12 16:52:00 +00:00
|
|
|
{
|
1987-05-27 10:16:03 +00:00
|
|
|
DO_DEBUG(options['C'], print("CONSTANT EXPRESSION\n"));
|
1991-03-12 16:52:00 +00:00
|
|
|
DO_DEBUG(options['C'], PrNode(*pnd, 0));
|
1986-11-26 16:40:45 +00:00
|
|
|
|
1991-03-12 16:52:00 +00:00
|
|
|
if (ChkExpression(pnd) &&
|
|
|
|
(*pnd)->nd_class != Set &&
|
|
|
|
(*pnd)->nd_class != Value &&
|
|
|
|
! (options['l'] && (*pnd)->nd_class == Def && IsProc((*pnd)))) {
|
1986-11-05 14:33:00 +00:00
|
|
|
error("constant expression expected");
|
1986-04-10 01:08:49 +00:00
|
|
|
}
|
1986-11-26 16:40:45 +00:00
|
|
|
|
1987-05-27 10:16:03 +00:00
|
|
|
DO_DEBUG(options['C'], print("RESULTS IN\n"));
|
1991-03-12 16:52:00 +00:00
|
|
|
DO_DEBUG(options['C'], PrNode(*pnd, 0));
|
1986-04-07 17:40:38 +00:00
|
|
|
}
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
expression(register struct node **pnd;)
|
1986-04-06 17:42:56 +00:00
|
|
|
{
|
|
|
|
} :
|
1986-04-07 17:40:38 +00:00
|
|
|
SimpleExpression(pnd)
|
1986-04-06 17:42:56 +00:00
|
|
|
[
|
|
|
|
/* relation */
|
1986-05-28 18:36:51 +00:00
|
|
|
[ '=' | '#' | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN ]
|
1987-08-10 21:43:47 +00:00
|
|
|
{ *pnd = dot2node(Oper, *pnd, NULLNODE); }
|
1991-03-12 16:52:00 +00:00
|
|
|
SimpleExpression(&((*pnd)->nd_RIGHT))
|
1988-02-10 14:06:34 +00:00
|
|
|
|
|
|
|
|
]
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
1986-04-06 17:42:56 +00:00
|
|
|
/* Inline in expression
|
1986-03-20 14:52:03 +00:00
|
|
|
relation:
|
1986-05-28 18:36:51 +00:00
|
|
|
'=' | '#' | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
1986-04-06 17:42:56 +00:00
|
|
|
*/
|
1986-03-20 14:52:03 +00:00
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
SimpleExpression(register struct node **pnd;)
|
1986-04-06 17:42:56 +00:00
|
|
|
{
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct node *nd = 0;
|
1986-04-06 17:42:56 +00:00
|
|
|
} :
|
1986-04-07 17:40:38 +00:00
|
|
|
[
|
|
|
|
[ '+' | '-' ]
|
1987-08-10 21:43:47 +00:00
|
|
|
{ nd = dot2leaf(Uoper);
|
1986-11-26 16:40:45 +00:00
|
|
|
/* priority of unary operator ??? */
|
1986-04-07 17:40:38 +00:00
|
|
|
}
|
1988-02-10 14:06:34 +00:00
|
|
|
|
|
|
|
|
]
|
1986-04-07 17:40:38 +00:00
|
|
|
term(pnd)
|
1987-06-18 15:46:08 +00:00
|
|
|
{ if (nd) {
|
1991-03-12 16:52:00 +00:00
|
|
|
nd->nd_RIGHT = *pnd;
|
1987-06-18 15:46:08 +00:00
|
|
|
*pnd = nd;
|
|
|
|
}
|
|
|
|
nd = *pnd;
|
|
|
|
}
|
1986-04-06 17:42:56 +00:00
|
|
|
[
|
|
|
|
/* AddOperator */
|
|
|
|
[ '+' | '-' | OR ]
|
1987-08-10 21:43:47 +00:00
|
|
|
{ nd = dot2node(Oper, nd, NULLNODE); }
|
1991-03-12 16:52:00 +00:00
|
|
|
term(&(nd->nd_RIGHT))
|
1986-04-06 17:42:56 +00:00
|
|
|
]*
|
1987-06-18 15:46:08 +00:00
|
|
|
{ *pnd = nd; }
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
1986-04-06 17:42:56 +00:00
|
|
|
/* Inline in "SimpleExpression"
|
1986-03-20 14:52:03 +00:00
|
|
|
AddOperator:
|
|
|
|
'+' | '-' | OR
|
|
|
|
;
|
1986-04-06 17:42:56 +00:00
|
|
|
*/
|
1986-03-20 14:52:03 +00:00
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
term(struct node **pnd;)
|
1986-04-06 17:42:56 +00:00
|
|
|
{
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct node *nd;
|
1986-04-06 17:42:56 +00:00
|
|
|
}:
|
1987-07-30 13:37:39 +00:00
|
|
|
factor(pnd) { nd = *pnd; }
|
1986-04-06 17:42:56 +00:00
|
|
|
[
|
|
|
|
/* MulOperator */
|
1987-07-30 13:37:39 +00:00
|
|
|
[ '*' | '/' | DIV | MOD | AND ]
|
1987-08-10 21:43:47 +00:00
|
|
|
{ nd = dot2node(Oper, nd, NULLNODE); }
|
1991-03-12 16:52:00 +00:00
|
|
|
factor(&(nd->nd_RIGHT))
|
1986-04-06 17:42:56 +00:00
|
|
|
]*
|
1987-07-30 13:37:39 +00:00
|
|
|
{ *pnd = nd; }
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
1986-04-06 17:42:56 +00:00
|
|
|
/* inline in "term"
|
1986-03-20 14:52:03 +00:00
|
|
|
MulOperator:
|
1987-07-30 13:37:39 +00:00
|
|
|
'*' | '/' | DIV | MOD | AND
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
1986-04-06 17:42:56 +00:00
|
|
|
*/
|
1986-03-20 14:52:03 +00:00
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
factor(register struct node **p;)
|
1986-03-27 17:37:41 +00:00
|
|
|
{
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct node *nd;
|
|
|
|
struct node *nd1;
|
1986-03-27 17:37:41 +00:00
|
|
|
} :
|
1986-11-17 11:41:28 +00:00
|
|
|
qualident(p)
|
1986-03-20 14:52:03 +00:00
|
|
|
[
|
1988-02-10 14:06:34 +00:00
|
|
|
designator_tail(p)
|
1986-04-06 17:42:56 +00:00
|
|
|
[
|
1987-08-10 21:43:47 +00:00
|
|
|
{ *p = dot2node(Call, *p, NULLNODE); }
|
1991-03-12 16:52:00 +00:00
|
|
|
ActualParameters(&((*p)->nd_RIGHT))
|
1988-02-10 14:06:34 +00:00
|
|
|
|
|
|
|
|
]
|
1986-04-07 17:40:38 +00:00
|
|
|
|
|
1988-07-05 19:06:40 +00:00
|
|
|
bare_set(&nd1)
|
1991-03-12 16:52:00 +00:00
|
|
|
{ nd = nd1; nd->nd_LEFT = *p; *p = nd; }
|
1986-03-20 14:52:03 +00:00
|
|
|
]
|
|
|
|
|
|
1986-04-06 17:42:56 +00:00
|
|
|
bare_set(p)
|
1986-03-20 14:52:03 +00:00
|
|
|
| %default
|
1987-06-18 15:46:08 +00:00
|
|
|
[
|
|
|
|
%default
|
|
|
|
INTEGER
|
|
|
|
|
|
|
|
|
REAL
|
|
|
|
|
|
|
|
|
STRING
|
1987-08-10 21:43:47 +00:00
|
|
|
] { *p = dot2leaf(Value);
|
1987-06-18 15:46:08 +00:00
|
|
|
(*p)->nd_type = toktype;
|
|
|
|
}
|
1986-03-20 14:52:03 +00:00
|
|
|
|
|
1987-08-10 21:43:47 +00:00
|
|
|
'(' { nd = dot2leaf(Uoper); }
|
1987-06-18 15:46:08 +00:00
|
|
|
expression(p)
|
|
|
|
{ /* In some cases we must leave the '(' as an unary
|
|
|
|
operator, because otherwise we cannot see that the
|
|
|
|
factor was not a designator
|
|
|
|
*/
|
|
|
|
register int class = (*p)->nd_class;
|
|
|
|
|
|
|
|
if (class == Arrsel ||
|
|
|
|
class == Arrow ||
|
|
|
|
class == Name ||
|
1991-03-12 16:52:00 +00:00
|
|
|
class == Select) {
|
|
|
|
nd->nd_RIGHT = *p;
|
1987-06-18 15:46:08 +00:00
|
|
|
*p = nd;
|
|
|
|
}
|
1987-09-23 16:39:43 +00:00
|
|
|
else FreeNode(nd);
|
1986-04-28 18:06:58 +00:00
|
|
|
}
|
1987-06-18 15:46:08 +00:00
|
|
|
')'
|
1986-03-20 14:52:03 +00:00
|
|
|
|
|
1987-08-10 21:43:47 +00:00
|
|
|
NOT { *p = dot2leaf(Uoper); }
|
1991-03-12 16:52:00 +00:00
|
|
|
factor(&((*p)->nd_RIGHT))
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
bare_set(struct node **pnd;)
|
1986-04-06 17:42:56 +00:00
|
|
|
{
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct node *nd;
|
1986-04-06 17:42:56 +00:00
|
|
|
} :
|
1991-03-12 16:52:00 +00:00
|
|
|
'{' { DOT = SET;
|
1987-08-10 21:43:47 +00:00
|
|
|
*pnd = nd = dot2leaf(Xset);
|
1986-04-07 17:40:38 +00:00
|
|
|
nd->nd_type = bitset_type;
|
1986-04-06 17:42:56 +00:00
|
|
|
}
|
|
|
|
[
|
|
|
|
element(nd)
|
1991-03-12 16:52:00 +00:00
|
|
|
[ { nd = nd->nd_RIGHT; }
|
1986-04-07 17:40:38 +00:00
|
|
|
',' element(nd)
|
1986-04-06 17:42:56 +00:00
|
|
|
]*
|
1988-02-10 14:06:34 +00:00
|
|
|
|
|
|
|
|
]
|
1986-04-06 17:42:56 +00:00
|
|
|
'}'
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
ActualParameters(struct node **pnd;):
|
1986-04-06 17:42:56 +00:00
|
|
|
'(' ExpList(pnd)? ')'
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
element(register struct node *nd;) :
|
1991-03-12 16:52:00 +00:00
|
|
|
expression(&(nd->nd_RIGHT))
|
1986-04-06 17:42:56 +00:00
|
|
|
[
|
1986-04-07 17:40:38 +00:00
|
|
|
UPTO
|
1991-03-12 16:52:00 +00:00
|
|
|
{ nd->nd_RIGHT = dot2node(Link, nd->nd_RIGHT, NULLNODE);}
|
|
|
|
expression(&(nd->nd_RIGHT->nd_RIGHT))
|
1988-02-10 14:06:34 +00:00
|
|
|
|
|
|
|
|
]
|
1991-03-12 16:52:00 +00:00
|
|
|
{ nd->nd_RIGHT = dot2node(Link, nd->nd_RIGHT, NULLNODE);
|
|
|
|
nd->nd_RIGHT->nd_symb = ',';
|
1986-04-07 17:40:38 +00:00
|
|
|
}
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
designator(struct node **pnd;)
|
1986-10-06 20:36:30 +00:00
|
|
|
:
|
1986-11-17 11:41:28 +00:00
|
|
|
qualident(pnd)
|
1988-02-10 14:06:34 +00:00
|
|
|
designator_tail(pnd)
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
designator_tail(register struct node **pnd;):
|
1986-04-06 17:42:56 +00:00
|
|
|
visible_designator_tail(pnd)
|
1986-11-05 14:33:00 +00:00
|
|
|
[ %persistent
|
|
|
|
%default
|
1986-04-09 18:14:49 +00:00
|
|
|
selector(pnd)
|
1986-03-27 17:37:41 +00:00
|
|
|
|
|
1986-04-06 17:42:56 +00:00
|
|
|
visible_designator_tail(pnd)
|
1986-03-27 17:37:41 +00:00
|
|
|
]*
|
1988-02-10 14:06:34 +00:00
|
|
|
|
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|
|
|
|
|
2019-05-10 17:09:03 +00:00
|
|
|
visible_designator_tail(struct node **pnd;)
|
1987-06-18 15:46:08 +00:00
|
|
|
{
|
2019-05-10 17:09:03 +00:00
|
|
|
register struct node *nd = *pnd;
|
1987-06-18 15:46:08 +00:00
|
|
|
}:
|
1987-08-10 21:43:47 +00:00
|
|
|
'[' { nd = dot2node(Arrsel, nd, NULLNODE); }
|
1991-03-12 16:52:00 +00:00
|
|
|
expression(&(nd->nd_RIGHT))
|
1986-04-09 18:14:49 +00:00
|
|
|
[
|
|
|
|
','
|
1987-08-10 21:43:47 +00:00
|
|
|
{ nd = dot2node(Arrsel, nd, NULLNODE);
|
1986-04-09 18:14:49 +00:00
|
|
|
}
|
1991-03-12 16:52:00 +00:00
|
|
|
expression(&(nd->nd_RIGHT))
|
1986-04-09 18:14:49 +00:00
|
|
|
]*
|
1986-04-06 17:42:56 +00:00
|
|
|
']'
|
1987-06-18 15:46:08 +00:00
|
|
|
{ *pnd = nd; }
|
1988-07-05 19:06:40 +00:00
|
|
|
|
|
|
|
|
'^' { *pnd = dot2node(Arrow, NULLNODE, nd); }
|
1986-03-20 14:52:03 +00:00
|
|
|
;
|