258 lines
4.5 KiB
Plaintext
258 lines
4.5 KiB
Plaintext
/* E X P R E S S I O N S */
|
|
|
|
{
|
|
#include "debug.h"
|
|
|
|
#include <alloc.h>
|
|
#include <em_arith.h>
|
|
#include <em_label.h>
|
|
#include <assert.h>
|
|
|
|
#include "LLlex.h"
|
|
#include "idf.h"
|
|
#include "def.h"
|
|
#include "node.h"
|
|
#include "const.h"
|
|
#include "type.h"
|
|
#include "chk_expr.h"
|
|
}
|
|
|
|
number(struct node **p;) :
|
|
[
|
|
%default
|
|
INTEGER
|
|
|
|
|
REAL
|
|
] { *p = MkLeaf(Value, &dot);
|
|
(*p)->nd_type = toktype;
|
|
}
|
|
;
|
|
|
|
qualident(int types;
|
|
struct def **pdf;
|
|
char *str;
|
|
struct node **p;
|
|
)
|
|
{
|
|
struct node *nd;
|
|
} :
|
|
IDENT { nd = MkLeaf(Name, &dot); }
|
|
[
|
|
selector(&nd)
|
|
]*
|
|
{ if (types && ChkDesignator(nd)) {
|
|
if (nd->nd_class != Def) {
|
|
node_error(nd, "%s expected", str);
|
|
}
|
|
else {
|
|
register struct def *df = nd->nd_def;
|
|
|
|
if ( !((types|D_ERROR) & df->df_kind)) {
|
|
if (df->df_kind == D_FORWARD) {
|
|
node_error(nd,"%s \"%s\" not declared", str, df->df_idf->id_text);
|
|
}
|
|
else {
|
|
node_error(nd,"identifier \"%s\" is not a %s", df->df_idf->id_text, str);
|
|
}
|
|
}
|
|
if (pdf) *pdf = df;
|
|
}
|
|
}
|
|
if (!p) FreeNode(nd);
|
|
else *p = nd;
|
|
}
|
|
;
|
|
|
|
selector(struct node **pnd;):
|
|
'.' { *pnd = MkNode(Link,*pnd,NULLNODE,&dot); }
|
|
IDENT { (*pnd)->nd_IDF = dot.TOK_IDF; }
|
|
;
|
|
|
|
ExpList(struct node **pnd;)
|
|
{
|
|
register struct node *nd;
|
|
} :
|
|
expression(pnd) { *pnd = nd = MkNode(Link,*pnd,NULLNODE,&dot);
|
|
(*pnd)->nd_symb = ',';
|
|
}
|
|
[
|
|
',' { nd->nd_right = MkLeaf(Link, &dot);
|
|
nd = nd->nd_right;
|
|
}
|
|
expression(&(nd->nd_left))
|
|
]*
|
|
;
|
|
|
|
ConstExpression(struct node **pnd;):
|
|
expression(pnd)
|
|
/*
|
|
* Changed rule in new Modula-2.
|
|
* Check that the expression is a constant expression and evaluate!
|
|
*/
|
|
{ DO_DEBUG(options['X'], print("CONSTANT EXPRESSION\n"));
|
|
DO_DEBUG(options['X'], PrNode(*pnd, 0));
|
|
if (ChkExpression(*pnd) &&
|
|
((*pnd)->nd_class != Set && (*pnd)->nd_class != Value)) {
|
|
error("Constant expression expected");
|
|
}
|
|
DO_DEBUG(options['X'], print("RESULTS IN\n"));
|
|
DO_DEBUG(options['X'], PrNode(*pnd, 0));
|
|
}
|
|
;
|
|
|
|
expression(struct node **pnd;)
|
|
{
|
|
} :
|
|
SimpleExpression(pnd)
|
|
[
|
|
/* relation */
|
|
[ '=' | '#' | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN ]
|
|
{ *pnd = MkNode(Oper, *pnd, NULLNODE, &dot); }
|
|
SimpleExpression(&((*pnd)->nd_right))
|
|
]?
|
|
;
|
|
|
|
/* Inline in expression
|
|
relation:
|
|
'=' | '#' | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN
|
|
;
|
|
*/
|
|
|
|
SimpleExpression(struct node **pnd;)
|
|
{
|
|
} :
|
|
[
|
|
[ '+' | '-' ]
|
|
{ *pnd = MkLeaf(Uoper, &dot);
|
|
pnd = &((*pnd)->nd_right);
|
|
}
|
|
]?
|
|
term(pnd)
|
|
[
|
|
/* AddOperator */
|
|
[ '+' | '-' | OR ]
|
|
{ *pnd = MkNode(Oper, *pnd, NULLNODE, &dot); }
|
|
term(&((*pnd)->nd_right))
|
|
]*
|
|
;
|
|
|
|
/* Inline in "SimpleExpression"
|
|
AddOperator:
|
|
'+' | '-' | OR
|
|
;
|
|
*/
|
|
|
|
term(struct node **pnd;)
|
|
{
|
|
}:
|
|
factor(pnd)
|
|
[
|
|
/* MulOperator */
|
|
[ '*' | '/' | DIV | MOD | AND | '&' ]
|
|
{ *pnd = MkNode(Oper, *pnd, NULLNODE, &dot); }
|
|
factor(&((*pnd)->nd_right))
|
|
]*
|
|
;
|
|
|
|
/* inline in "term"
|
|
MulOperator:
|
|
'*' | '/' | DIV | MOD | AND | '&'
|
|
;
|
|
*/
|
|
|
|
factor(register struct node **p;)
|
|
{
|
|
struct node *nd;
|
|
} :
|
|
qualident(0, (struct def **) 0, (char *) 0, p)
|
|
[
|
|
designator_tail(p)?
|
|
[
|
|
{ *p = MkNode(Call, *p, NULLNODE, &dot); }
|
|
ActualParameters(&((*p)->nd_right))
|
|
]?
|
|
|
|
|
bare_set(&nd)
|
|
{ nd->nd_left = *p; *p = nd; }
|
|
]
|
|
|
|
|
bare_set(p)
|
|
| %default
|
|
number(p)
|
|
|
|
|
STRING { *p = MkLeaf(Value, &dot);
|
|
(*p)->nd_type = toktype;
|
|
}
|
|
|
|
|
'(' expression(p) ')'
|
|
|
|
|
NOT { *p = MkLeaf(Uoper, &dot); }
|
|
factor(&((*p)->nd_right))
|
|
;
|
|
|
|
bare_set(struct node **pnd;)
|
|
{
|
|
register struct node *nd;
|
|
} :
|
|
'{' { dot.tk_symb = SET;
|
|
*pnd = nd = MkLeaf(Xset, &dot);
|
|
nd->nd_type = bitset_type;
|
|
}
|
|
[
|
|
element(nd)
|
|
[ { nd = nd->nd_right; }
|
|
',' element(nd)
|
|
]*
|
|
]?
|
|
'}'
|
|
;
|
|
|
|
ActualParameters(struct node **pnd;):
|
|
'(' ExpList(pnd)? ')'
|
|
;
|
|
|
|
element(struct node *nd;)
|
|
{
|
|
struct node *nd1;
|
|
} :
|
|
expression(&nd1)
|
|
[
|
|
UPTO
|
|
{ nd1 = MkNode(Link, nd1, NULLNODE, &dot);}
|
|
expression(&(nd1->nd_right))
|
|
]?
|
|
{ nd->nd_right = MkNode(Link, nd1, NULLNODE, &dot);
|
|
nd->nd_right->nd_symb = ',';
|
|
}
|
|
;
|
|
|
|
designator(struct node **pnd;)
|
|
:
|
|
qualident(0, (struct def **) 0, (char *) 0, pnd)
|
|
designator_tail(pnd)?
|
|
;
|
|
|
|
designator_tail(struct node **pnd;):
|
|
visible_designator_tail(pnd)
|
|
[
|
|
selector(pnd)
|
|
|
|
|
visible_designator_tail(pnd)
|
|
]*
|
|
;
|
|
|
|
visible_designator_tail(register struct node **pnd;):
|
|
'[' { *pnd = MkNode(Arrsel, *pnd, NULLNODE, &dot); }
|
|
expression(&((*pnd)->nd_right))
|
|
[
|
|
','
|
|
{ *pnd = MkNode(Arrsel, *pnd, NULLNODE, &dot);
|
|
(*pnd)->nd_symb = '[';
|
|
}
|
|
expression(&((*pnd)->nd_right))
|
|
]*
|
|
']'
|
|
|
|
|
'^' { *pnd = MkNode(Arrow, NULLNODE, *pnd, &dot); }
|
|
;
|