Pristine Ack-5.5
[Ack-5.5.git] / lang / cem / cemcom / expr.c
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 /* $Id: expr.c,v 3.28 1994/06/24 12:03:38 ceriel Exp $ */
6 /* EXPRESSION TREE HANDLING */
7
8 #include        "lint.h"
9 #include        "nofloat.h"
10 #include        "botch_free.h"
11 #include        <alloc.h>
12 #include        "idf.h"
13 #include        "arith.h"
14 #include        "def.h"
15 #include        "type.h"
16 #include        "label.h"
17 #include        "expr.h"
18 #include        "LLlex.h"
19 #include        "Lpars.h"
20 #include        "decspecs.h"
21 #include        "declar.h"
22 #include        "sizes.h"
23 #include        "level.h"
24 #include        "noRoption.h"
25 #include        "use_tmp.h"
26
27 extern char *symbol2str();
28 extern char options[];
29
30 int
31 rank_of(oper)
32         int oper;
33 {
34         /*      The rank of the operator oper is returned.
35         */
36         switch (oper)   {
37         default:
38                 return 0;                       /* INT2INT etc. */
39         case '[':
40         case '(':
41         case '.':
42         case ARROW:
43         case PARCOMMA:
44                 return 1;
45         case '!':
46         case PLUSPLUS:
47         case MINMIN:
48         case CAST:
49         case SIZEOF:
50                 return 2;                       /* monadic */
51         case '*':
52         case '/':
53         case '%':
54                 return 3;
55         case '+':
56         case '-':
57                 return 4;
58         case LEFT:
59         case RIGHT:
60                 return 5;
61         case '<':
62         case '>':
63         case LESSEQ:
64         case GREATEREQ:
65                 return 6;
66         case EQUAL:
67         case NOTEQUAL:
68                 return 7;
69         case '&':
70                 return 8;
71         case '^':
72                 return 9;
73         case '|':
74                 return 10;
75         case AND:
76                 return 11;
77         case OR:
78                 return 12;
79         case '?':
80         case ':':
81                 return 13;
82         case '=':
83         case PLUSAB:
84         case MINAB:
85         case TIMESAB:
86         case DIVAB:
87         case MODAB:
88         case RIGHTAB:
89         case LEFTAB:
90         case ANDAB:
91         case XORAB:
92         case ORAB:
93                 return 14;
94         case ',':
95                 return 15;
96         }
97         /*NOTREACHED*/
98 }
99
100 #ifndef NOROPTION
101 int
102 rank_of_expression(ex)
103         register struct expr *ex;
104 {
105         /*      Returns the rank of the top node in the expression.
106         */
107         if (!ex || (ex->ex_flags & EX_PARENS) || ex->ex_class != Oper)
108                 return 0;
109         return rank_of(ex->OP_OPER);
110 }
111
112 check_conditional(expr, oper, pos_descr)
113         register struct expr *expr;
114         char *pos_descr;
115 {
116         /*      Warn if restricted C is in effect and the expression expr,
117                 which occurs at the position pos_descr, is not lighter than
118                 the operator oper.
119         */
120         if (options['R'] && rank_of_expression(expr) >= rank_of(oper))
121                 expr_warning(expr, "%s %s is ungrammatical",
122                         symbol2str(expr->OP_OPER), pos_descr);
123 }
124 #endif
125
126 dot2expr(expp)
127         struct expr **expp;
128 {
129         /*      The token in dot is converted into an expression, a
130                 pointer to which is stored in *expp.
131         */
132         register struct expr *ex = new_expr();
133
134         *expp = ex;
135         ex->ex_file = dot.tk_file;
136         ex->ex_line = dot.tk_line;
137         switch (DOT)    {
138         case IDENTIFIER:
139                 idf2expr(ex);
140                 break;
141         case STRING:
142                 string2expr(ex);
143                 break;
144         case INTEGER:
145                 int2expr(ex);
146                 break;
147 #ifndef NOFLOAT
148         case FLOATING:
149                 float2expr(ex);
150                 break;
151 #endif /* NOFLOAT */
152         default:
153                 crash("bad conversion to expression");
154                 /*NOTREACHED*/
155         }
156 }
157
158 idf2expr(expr)
159         register struct expr *expr;
160 {
161         /*      Dot contains an identifier which is turned into an
162                 expression.
163                 Note that this constitutes an applied occurrence of
164                 the identifier.
165         */
166         register struct idf *idf = dot.tk_idf;  /* != 0*/
167         register struct def *def = idf->id_def;
168         
169         if (def == 0)   {
170                 if (AHEAD == '(') /* function call, declare name IMPLICITly */
171                         add_def(idf, IMPLICIT, funint_type, level); /* RM 13 */
172                 else    {
173                         if (!is_anon_idf(idf))
174                                 error("identifier %s undefined", idf->id_text);
175                         /* declare idf anyway */
176                         add_def(idf, 0, error_type, level);
177                 }
178                 def = idf->id_def;
179         }
180         /* now def != 0 */
181         if (def->df_type->tp_fund == LABEL) {
182                 expr_error(expr, "illegal use of label %s", idf->id_text);
183                 expr->ex_type = error_type;
184         }
185         else {
186 #ifndef LINT
187                 if (! def->df_used) {
188                         def->df_used = 1;
189 #ifndef PREPEND_SCOPES
190                         code_scope(idf->id_text, def);
191 #endif /* PREPEND_SCOPES */
192                 }
193 #endif  /* LINT */
194                 expr->ex_type = def->df_type;
195                 if (expr->ex_type == error_type)
196                         expr->ex_flags |= EX_ERROR;
197         }
198         expr->ex_lvalue =
199                 (       def->df_type->tp_fund == FUNCTION ||
200                         def->df_type->tp_fund == ARRAY ||
201                         def->df_sc == ENUM
202                 ) ? 0 : 1;
203         expr->ex_class = Value;
204         if (def->df_sc == ENUM) {
205                 expr->VL_CLASS = Const;
206                 expr->VL_VALUE = def->df_address;
207         }
208 #ifndef LINT
209         else
210         if (def->df_sc == STATIC && def->df_level >= L_LOCAL) {
211                 expr->VL_CLASS = Label;
212                 expr->VL_LBL = def->df_address;
213                 expr->VL_VALUE = (arith)0;
214         }
215 #endif  /* LINT */
216         else {
217                 expr->VL_CLASS = Name;
218                 expr->VL_IDF = idf;
219                 expr->VL_VALUE = (arith)0;
220         }
221 }
222
223 string2expr(expr)
224         register struct expr *expr;
225 {
226         /*      Dot contains a string which is turned into an expression.
227         */
228         expr->ex_type = string_type;
229         expr->ex_lvalue = 0;
230         expr->ex_class = String;
231         expr->SG_VALUE = dot.tk_bts;
232         expr->SG_LEN = dot.tk_len;
233         expr->SG_DATLAB = 0;
234 }
235
236 int2expr(expr)
237         struct expr *expr;
238 {
239         /*      Dot contains an integer constant which is turned
240                 into an expression.
241         */
242         fill_int_expr(expr, dot.tk_ival, dot.tk_fund);
243 }
244
245 #ifndef NOFLOAT
246 float2expr(expr)
247         register struct expr *expr;
248 {
249         /*      Dot contains a floating point constant which is turned
250                 into an expression.
251         */
252         expr->ex_type = double_type;
253         expr->ex_class = Float;
254         expr->FL_VALUE = dot.tk_fval;
255         expr->FL_DATLAB = 0;
256 }
257 #endif /* NOFLOAT */
258
259 struct expr*
260 intexpr(ivalue, fund)
261         arith ivalue;
262         int fund;
263 {
264         /*      The value ivalue is turned into an integer expression of
265                 the size indicated by fund.
266         */
267         register struct expr *expr = new_expr();
268         
269         expr->ex_file = dot.tk_file;
270         expr->ex_line = dot.tk_line;
271         fill_int_expr(expr, ivalue, fund);
272         return expr;
273 }
274
275 fill_int_expr(ex, ivalue, fund)
276         register struct expr *ex;
277         arith ivalue;
278         int fund;
279 {
280         /*      Details derived from ivalue and fund are put into the
281                 constant integer expression ex.
282         */
283         switch (fund) {
284         case INT:
285                 ex->ex_type = int_type;
286                 break;
287         case INTEGER:
288                 if (ivalue >= 0 && ivalue <= max_int) {
289                         ex->ex_type = int_type;
290                         break;
291                 }
292                 /*FALL THROUGH*/
293         case LONG:
294                 ex->ex_type = 
295                         (ivalue & (1L << (8*long_size - 1))) ? ulong_type
296                                 : long_type;
297                 break;
298         case UNSIGNED:
299                 /*      We cannot make a test like
300                                 ivalue <= max_unsigned
301                         because, if
302                                 sizeof(long) == int_size
303                         holds, max_unsigned may be a negative long in
304                         which case the comparison results in an unexpected
305                         answer.  We assume that the type "unsigned long"
306                         is not part of portable C !
307                 */
308                 ex->ex_type = 
309                         (ivalue & ~max_int) ?
310                           ( (ivalue & ~max_unsigned) ? 
311                               ( ivalue & (1L<<(8*long_size-1)) ?
312                                         ulong_type : long_type
313                               ) : uint_type
314                           ) : int_type;
315                 break;
316         default:
317                 crash("(intexpr) bad fund %s\n", symbol2str(fund));
318                 /*NOTREACHED*/
319         }
320         ex->ex_class = Value;
321         ex->VL_CLASS = Const;
322         ex->VL_VALUE = ivalue;
323         cut_size(ex);
324 }
325
326 struct expr *
327 new_oper(tp, e1, oper, e2)
328         struct type *tp;
329         register struct expr *e1, *e2;
330 {
331         /*      A new expression is constructed which consists of the
332                 operator oper which has e1 and e2 as operands; for a
333                 monadic operator e1 == NILEXPR.
334                 During the construction of the right recursive initialisation
335                 tree it is possible for e2 to be NILEXPR.
336         */
337         register struct expr *expr = new_expr();
338         register struct oper *op;
339
340         if (e2) {
341                 register struct expr *e = e2;
342                 
343                 while (e->ex_class == Oper && e->OP_LEFT)
344                         e = e->OP_LEFT;
345                 expr->ex_file = e->ex_file;
346                 expr->ex_line = e->ex_line;
347         }
348         else
349         if (e1) {
350                 register struct expr *e = e1;
351                 
352                 while (e->ex_class == Oper && e->OP_RIGHT)
353                         e = e->OP_RIGHT;
354                 expr->ex_file = e->ex_file;
355                 expr->ex_line = e->ex_line;
356         }
357         else    {
358                 expr->ex_file = dot.tk_file;
359                 expr->ex_line = dot.tk_line;
360         }
361
362         expr->ex_type = tp;
363         expr->ex_class = Oper;
364         /* combine depths and flags of both expressions */
365         if (e2) {
366                 int e1_depth = e1 ? e1->ex_depth : 0;
367                 int e1_flags = e1 ? e1->ex_flags : 0;
368                 
369                 expr->ex_depth =
370                         (e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth) + 1;
371                 expr->ex_flags = (e1_flags | e2->ex_flags) & ~EX_PARENS;
372         }
373         op = &expr->ex_object.ex_oper;
374         op->op_type = tp;
375         op->op_oper = oper;
376         op->op_left = e1;
377         op->op_right = e2;
378 #ifdef  LINT
379         lint_new_oper(expr);
380 #endif  /* LINT */
381         return expr;
382 }
383
384 chk_cst_expr(expp)
385         register struct expr **expp;
386 {
387         /*      The expression expr is checked for constancy.
388         
389                 There are 6 places where constant expressions occur in C:
390                 1.      after #if
391                 2.      in a global initialization
392                 3.      as size in an array declaration
393                 4.      as value in an enum declaration
394                 5.      as width in a bit field
395                 6.      as case value in a switch
396                 
397                 The constant expression in a global initialization is
398                 handled separately (by IVAL()).
399                 
400                 There are various disparate restrictions on each of
401                 the others in the various C compilers.  I have tried some
402                 hypotheses to unify them, but all have failed.
403                 
404                 This routine will give a warning for those operators
405                 not allowed by K&R, under the R-option only.  The anomalies
406                 are cast, logical operators and the expression comma.
407                 Special problems (of which there is only one, sizeof in
408                 Preprocessor #if) have to be dealt with locally
409                 
410                 Note that according to K&R the negation ! is illegal in
411                 constant expressions and is indeed rejected by the
412                 Ritchie compiler.
413         */
414         register struct expr *expr = *expp;
415         register int fund = expr->ex_type->tp_fund;
416         register int flags = expr->ex_flags;
417         int err = 0;
418         
419 #ifdef  DEBUG
420         print_expr("constant_expression", expr);
421 #endif  /* DEBUG */
422         if (    fund != CHAR && fund != SHORT && fund != INT &&
423                 fund != ENUM && fund != LONG
424         )
425                 expr_error(expr, "non-numerical constant expression"), err++;
426         else
427         if (!is_ld_cst(expr))
428                 expr_error(expr, "expression is not constant"), err++;
429 #ifndef NOROPTION
430         if (options['R'])       {
431                 if (flags & EX_CAST)
432                         expr_warning(expr, "cast in constant expression");
433                 if (flags & EX_LOGICAL)
434                         expr_warning(expr,
435                                 "logical operator in constant expression");
436                 if (flags & EX_COMMA)
437                         expr_warning(expr,
438                                 "expression comma in constant expression");
439         }
440 #endif /* NOROPTION */
441         if (err)
442                 erroneous2int(expp);
443 }
444
445 init_expression(eppp, expr)
446         register struct expr ***eppp, *expr;
447 {
448         /*      The expression expr is added to the tree designated
449                 indirectly by **eppp.
450                 The natural form of a tree representing an
451                 initial_value_list is right-recursive, ie. with the
452                 left-most comma as main operator. The iterative grammar in
453                 expression.g, however, tends to produce a left-recursive
454                 tree, ie. one with the right-most comma as its main
455                 operator.
456                 To produce a right-recursive tree from the iterative
457                 grammar, we keep track of the address of the pointer where
458                 the next expression must be hooked in.
459         */
460         **eppp = new_oper(void_type, expr, INITCOMMA, NILEXPR);
461         *eppp = &(**eppp)->OP_RIGHT;
462 }
463
464 int
465 is_ld_cst(expr)
466         register struct expr *expr;
467 {
468         /*      An expression is a `load-time constant' if it is of the form
469                 <idf> +/- <integral> or <integral>.
470         */
471 #ifdef  LINT
472         if (expr->ex_class == String)
473                 return 1;
474 #endif  /* LINT */
475         return expr->ex_lvalue == 0 && expr->ex_class == Value;
476 }
477
478 int
479 is_cp_cst(expr)
480         register struct expr *expr;
481 {
482         /*      An expression is a `compile-time constant' if it is a
483                 load-time constant, and the idf is not there.
484         */
485         return is_ld_cst(expr) && expr->VL_CLASS == Const;
486 }
487
488 #ifndef NOFLOAT
489 int
490 is_fp_cst(expr)
491         register struct expr *expr;
492 {
493         /*      An expression is a `floating-point constant' if it consists
494                 of the float only.
495         */
496         return expr->ex_class == Float;
497 }
498 #endif /* NOFLOAT */
499
500 free_expression(expr)
501         register struct expr *expr;
502 {
503         /*      The expression expr is freed recursively.
504         */
505         if (expr) {
506                 if (expr->ex_class == Oper)     {
507                         free_expression(expr->OP_LEFT);
508                         free_expression(expr->OP_RIGHT);
509                 }
510                 free_expr(expr);
511         }
512 }