Pristine Ack-5.5
[Ack-5.5.git] / lang / m2 / comp / expression.g
1 /*
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".
4  *
5  * Author: Ceriel J.H. Jacobs
6  */
7
8 /* E X P R E S S I O N S */
9
10 /* $Id: expression.g,v 1.48 1994/06/24 12:40:50 ceriel Exp $ */
11
12 {
13 #include        "debug.h"
14
15 #include        <alloc.h>
16 #include        <em_arith.h>
17 #include        <em_label.h>
18 #include        <assert.h>
19
20 #include        "LLlex.h"
21 #include        "idf.h"
22 #include        "def.h"
23 #include        "node.h"
24 #include        "type.h"
25 #include        "chk_expr.h"
26 #include        "warning.h"
27
28 extern char     options[];
29 }
30
31 /* inline, we need room for pdp/11
32 number(t_node **p;) :
33 [
34         %default
35         INTEGER
36 |
37         REAL
38 ]                       { *p = dot2leaf(Value);
39                           (*p)->nd_type = toktype;
40                         }
41 ;
42 */
43
44 qualident(t_node **p;)
45 {
46 } :
47         IDENT   { *p = dot2leaf(Name); }
48         [
49                 selector(p)
50         ]*
51 ;
52
53 selector(register t_node **pnd;)
54 { t_node *nd;
55 } :
56         '.'     { nd = dot2leaf(Select); nd->nd_NEXT = *pnd; *pnd = nd; }
57         IDENT   { (*pnd)->nd_IDF = dot.TOK_IDF; }
58 ;
59
60 ExpList(t_node **pnd;)
61 {
62         register t_node *nd;
63 } :
64         expression(pnd)         { *pnd = nd = dot2node(Link,*pnd,NULLNODE);
65                                   nd->nd_symb = ',';
66                                 }
67         [
68                 ','             { nd->nd_RIGHT = dot2leaf(Link);
69                                   nd = nd->nd_RIGHT;
70                                 }
71                 expression(&(nd->nd_LEFT))
72         ]*
73 ;
74
75 ConstExpression(register t_node **pnd;)
76 {
77 }:
78         expression(pnd)
79         /*
80          * Changed rule in new Modula-2.
81          * Check that the expression is a constant expression and evaluate!
82          */
83                 {
84                   DO_DEBUG(options['C'], print("CONSTANT EXPRESSION\n"));
85                   DO_DEBUG(options['C'], PrNode(*pnd, 0));
86
87                   if (ChkExpression(pnd) &&
88                       (*pnd)->nd_class != Set &&
89                       (*pnd)->nd_class != Value &&
90                       ! (options['l'] && (*pnd)->nd_class == Def && IsProc((*pnd)))) {
91                         error("constant expression expected");
92                   }
93
94                   DO_DEBUG(options['C'], print("RESULTS IN\n"));
95                   DO_DEBUG(options['C'], PrNode(*pnd, 0));
96                 }
97 ;
98
99 expression(register t_node **pnd;)
100 {
101 } :
102         SimpleExpression(pnd)
103         [
104                 /* relation */
105                 [ '=' | '#' | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN ]
106                         { *pnd = dot2node(Oper, *pnd, NULLNODE); }
107                 SimpleExpression(&((*pnd)->nd_RIGHT))
108         |
109         ]
110 ;
111
112 /* Inline in expression
113 relation:
114         '=' | '#' | '<' | LESSEQUAL | '>' | GREATEREQUAL | IN
115 ;
116 */
117
118 SimpleExpression(register t_node **pnd;)
119 {
120         register t_node *nd = 0;
121 } :
122         [
123                 [ '+' | '-' ]
124                         { nd = dot2leaf(Uoper);
125                           /* priority of unary operator ??? */
126                         }
127         |
128         ]
129         term(pnd)
130                         { if (nd) {
131                                 nd->nd_RIGHT = *pnd;
132                                 *pnd = nd;
133                           }
134                           nd = *pnd;
135                         }
136         [
137                 /* AddOperator */
138                 [ '+' | '-' | OR ]
139                         { nd = dot2node(Oper, nd, NULLNODE); }
140                 term(&(nd->nd_RIGHT))
141         ]*
142                         { *pnd = nd; }
143 ;
144
145 /* Inline in "SimpleExpression"
146 AddOperator:
147         '+' | '-' | OR
148 ;
149 */
150
151 term(t_node **pnd;)
152 {
153         register t_node *nd;
154 }:
155         factor(pnd)     { nd = *pnd; }
156         [
157                 /* MulOperator */
158                 [ '*' | '/' | DIV | MOD | AND ]
159                         { nd = dot2node(Oper, nd, NULLNODE); }
160                 factor(&(nd->nd_RIGHT))
161         ]*
162                         { *pnd = nd; }
163 ;
164
165 /* inline in "term"
166 MulOperator:
167         '*' | '/' | DIV | MOD | AND
168 ;
169 */
170
171 factor(register t_node **p;)
172 {
173         register t_node *nd;
174         t_node *nd1;
175 } :
176         qualident(p)
177         [
178                 designator_tail(p)
179                 [
180                         { *p = dot2node(Call, *p, NULLNODE); }
181                         ActualParameters(&((*p)->nd_RIGHT))
182                 |
183                 ]
184         |
185                 bare_set(&nd1)
186                         { nd = nd1; nd->nd_LEFT = *p; *p = nd; }
187         ]
188 |
189         bare_set(p)
190 | %default
191         [
192                 %default
193                 INTEGER
194         |
195                 REAL
196         |
197                 STRING
198         ]               { *p = dot2leaf(Value);
199                           (*p)->nd_type = toktype;
200                         }
201 |
202         '('     { nd = dot2leaf(Uoper); }
203         expression(p)
204                 { /*    In some cases we must leave the '(' as an unary
205                         operator, because otherwise we cannot see that the
206                         factor was not a designator
207                   */
208                   register int class = (*p)->nd_class;
209
210                   if (class == Arrsel ||
211                       class == Arrow ||
212                       class == Name ||
213                       class == Select) {
214                         nd->nd_RIGHT = *p;
215                         *p = nd;
216                   }
217                   else FreeNode(nd);
218                 }
219         ')'
220 |
221         NOT             { *p = dot2leaf(Uoper); }
222         factor(&((*p)->nd_RIGHT))
223 ;
224
225 bare_set(t_node **pnd;)
226 {
227         register t_node *nd;
228 } :
229         '{'             { DOT = SET;
230                           *pnd = nd = dot2leaf(Xset);
231                           nd->nd_type = bitset_type;
232                         }
233         [
234                 element(nd)
235                 [       { nd = nd->nd_RIGHT; }
236                         ',' element(nd)
237                 ]*
238         |
239         ]
240         '}'
241 ;
242
243 ActualParameters(t_node **pnd;):
244         '(' ExpList(pnd)? ')'
245 ;
246
247 element(register t_node *nd;) :
248         expression(&(nd->nd_RIGHT))
249         [
250                 UPTO
251                         { nd->nd_RIGHT = dot2node(Link, nd->nd_RIGHT, NULLNODE);}
252                 expression(&(nd->nd_RIGHT->nd_RIGHT))
253         |
254         ]
255                         { nd->nd_RIGHT = dot2node(Link, nd->nd_RIGHT, NULLNODE);
256                           nd->nd_RIGHT->nd_symb = ',';
257                         }
258 ;
259
260 designator(t_node **pnd;)
261 :
262         qualident(pnd)
263         designator_tail(pnd)
264 ;
265
266 designator_tail(register t_node **pnd;):
267         visible_designator_tail(pnd)
268         [ %persistent
269                 %default
270                 selector(pnd)
271         |
272                 visible_designator_tail(pnd)
273         ]*
274 |
275 ;
276
277 visible_designator_tail(t_node **pnd;)
278 {
279         register t_node *nd = *pnd;
280 }:
281         '['             { nd = dot2node(Arrsel, nd, NULLNODE); }
282                 expression(&(nd->nd_RIGHT))
283                 [
284                         ','
285                         { nd = dot2node(Arrsel, nd, NULLNODE);
286                         }
287                         expression(&(nd->nd_RIGHT))
288                 ]*
289         ']'
290                         { *pnd = nd; }
291 |
292         '^'             { *pnd = dot2node(Arrow, NULLNODE, nd); }
293 ;