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".
5 /* $Id: expr.c,v 1.18 1994/06/27 07:59:41 ceriel Exp $ */
6 /* EXPRESSION TREE HANDLING */
11 #include "botch_free.h"
14 #include <flt_arith.h>
28 extern char *symbol2str();
29 extern char options[];
36 /* The rank of the operator oper is returned.
40 return 0; /* INT2INT etc. */
53 return 2; /* monadic */
106 /* The token in dot is converted into an expression, a
107 pointer to which is stored in *expp.
109 register struct expr *ex = new_expr();
112 ex->ex_file = dot.tk_file;
113 ex->ex_line = dot.tk_line;
125 crash("bad conversion to expression");
131 register struct expr *expr;
133 /* Dot contains an identifier which is turned into an
135 Note that this constitutes an applied occurrence of
138 register struct idf *idf = dot.tk_idf; /* != 0*/
139 register struct def *def = idf->id_def;
143 /* function call, declare name implicitly (3.3.2.2) */
145 warning("implicit declaration of function %s"
147 add_def(idf, EXTERN, funint_type, level);
149 if (!is_anon_idf(idf))
150 error("%s undefined", idf->id_text);
151 /* declare idf anyway */
152 add_def(idf, 0, error_type, level);
159 if (! def->df_used) {
160 #ifndef PREPEND_SCOPES
161 code_scope(idf->id_text, def);
162 #endif /* PREPEND_SCOPES */
167 expr->ex_type = def->df_type;
168 if (expr->ex_type == error_type) {
169 expr->ex_flags |= EX_ERROR;
172 ( def->df_type->tp_fund == FUNCTION ||
173 def->df_type->tp_fund == ARRAY ||
176 if (def->df_type->tp_typequal & TQ_CONST)
177 expr->ex_flags |= EX_READONLY;
178 if (def->df_type->tp_typequal & TQ_VOLATILE)
179 expr->ex_flags |= EX_VOLATILE;
180 expr->ex_class = Value;
181 if (def->df_sc == ENUM) {
182 expr->VL_CLASS = Const;
183 expr->VL_VALUE = def->df_address;
187 if (def->df_sc == STATIC && def->df_level >= L_LOCAL) {
188 expr->VL_CLASS = Label;
189 expr->VL_LBL = def->df_address;
190 expr->VL_VALUE = (arith)0;
194 expr->VL_CLASS = Name;
196 expr->VL_VALUE = (arith)0;
200 string2expr(expp, str, len)
201 register struct expr **expp;
205 /* The string in the argument is converted into an expression,
206 a pointer to which is stored in *expp.
208 register struct expr *ex = new_expr();
211 ex->ex_file = dot.tk_file;
212 ex->ex_line = dot.tk_line;
213 ex->ex_type = string_type;
214 /* ex->ex_type = qualifier_type(ex->ex_type, TQ_CONST); */
215 ex->ex_flags |= EX_READONLY;
216 /* ex->ex_lvalue = 0; */
217 ex->ex_class = String;
225 /* Dot contains an integer constant which is turned
228 fill_int_expr(expr, dot.tk_ival, dot.tk_fund);
232 register struct expr *expr;
234 /* Dot contains a floating point constant which is turned
242 expr->ex_type = float_type;
245 expr->ex_type = double_type;
248 expr->ex_type = lngdbl_type;
251 crash("(float2expr) bad fund %s\n", symbol2str(fund));
253 expr->ex_class = Float;
254 flt_str2flt(dot.tk_fval, &(expr->FL_ARITH));
256 ASSERT(flt_status != FLT_NOFLT);
257 if (flt_status == FLT_OVFL)
258 expr_warning(expr,"internal floating point overflow");
262 intexpr(ivalue, fund)
266 /* The value ivalue is turned into an integer expression of
267 the size indicated by fund.
269 register struct expr *expr = new_expr();
271 expr->ex_file = dot.tk_file;
272 expr->ex_line = dot.tk_line;
273 fill_int_expr(expr, ivalue, fund);
277 fill_int_expr(ex, ivalue, fund)
278 register struct expr *ex;
282 /* Details derived from ivalue and fund are put into the
283 constant integer expression ex.
287 ex->ex_type = int_type;
290 ex->ex_type = uint_type;
293 ex->ex_type = long_type;
296 ex->ex_type = ulong_type;
299 crash("(fill_int_expr) bad fund %s\n", symbol2str(fund));
302 ex->ex_class = Value;
303 ex->VL_CLASS = Const;
304 ex->VL_VALUE = ivalue;
309 new_oper(tp, e1, oper, e2)
311 register struct expr *e1, *e2;
313 /* A new expression is constructed which consists of the
314 operator oper which has e1 and e2 as operands; for a
315 monadic operator e1 == NILEXPR.
316 During the construction of the right recursive initialisation
317 tree it is possible for e2 to be NILEXPR.
319 register struct expr *expr = new_expr();
320 register struct oper *op;
323 register struct expr *e = e2;
325 while (e->ex_class == Oper && e->OP_LEFT)
327 expr->ex_file = e->ex_file;
328 expr->ex_line = e->ex_line;
332 register struct expr *e = e1;
334 while (e->ex_class == Oper && e->OP_RIGHT)
336 expr->ex_file = e->ex_file;
337 expr->ex_line = e->ex_line;
340 expr->ex_file = dot.tk_file;
341 expr->ex_line = dot.tk_line;
345 expr->ex_class = Oper;
346 /* combine depths and flags of both expressions */
348 int e1_depth = e1 ? e1->ex_depth : 0;
349 int e1_flags = e1 ? e1->ex_flags : 0;
352 (e1_depth > e2->ex_depth ? e1_depth : e2->ex_depth) + 1;
353 expr->ex_flags = (e1_flags | e2->ex_flags)
354 & ~(EX_PARENS | EX_READONLY | EX_VOLATILE );
357 * A function call should be evaluated first when possible. Just say
358 * that the expression tree is very deep.
363 op = &expr->ex_object.ex_oper;
377 /* The expression expr is checked for constancy.
379 There are 6 places where constant expressions occur in C:
381 2. in a global initialization
382 3. as size in an array declaration
383 4. as value in an enum declaration
384 5. as width in a bit field
385 6. as case value in a switch
387 The constant expression in a global initialization is
388 handled separately (by IVAL()).
390 There are various disparate restrictions on each of
391 the others in the various C compilers. I have tried some
392 hypotheses to unify them, but all have failed.
394 Special problems (of which there is only one, sizeof in
395 Preprocessor #if) have to be dealt with locally
397 register struct expr *expr = *expp;
400 print_expr("constant_expression", expr);
402 switch(expr->ex_type->tp_fund) {
408 if (is_ld_cst(expr)) {
411 expr_error(expr, "expression is not constant");
414 expr_error(expr, "non-numerical constant expression");
420 init_expression(eppp, expr)
421 register struct expr ***eppp;
424 /* The expression expr is added to the tree designated
425 indirectly by **eppp.
426 The natural form of a tree representing an
427 initial_value_list is right-recursive, ie. with the
428 left-most comma as main operator. The iterative grammar in
429 expression.g, however, tends to produce a left-recursive
430 tree, ie. one with the right-most comma as its main
432 To produce a right-recursive tree from the iterative
433 grammar, we keep track of the address of the pointer where
434 the next expression must be hooked in.
436 **eppp = new_oper(void_type, expr, INITCOMMA, NILEXPR);
437 *eppp = &(**eppp)->OP_RIGHT;
442 register struct expr *expr;
444 /* An expression is a `load-time constant' if it is of the form
445 <idf> +/- <integral> or <integral>.
448 if (expr->ex_class == String)
451 return expr->ex_lvalue == 0 && expr->ex_class == Value;
458 /* An expression is a `compile-time constant' if it is a
459 load-time constant, and the idf is not there.
461 return is_ld_cst(expr) && expr->VL_CLASS == Const;
468 /* An expression is a `floating-point constant' if it consists
471 return expr->ex_class == Float;
476 register struct expr *expr;
480 switch(expr->ex_class) {
482 return expr->VL_VALUE == 0;
484 flt_arith2flt((arith) 0, &var, 0);
485 return flt_cmp(&var, &(expr->FL_ARITH)) == 0;
490 free_expression(expr)
491 register struct expr *expr;
493 /* The expression expr is freed recursively.
496 if (expr->ex_class == Oper) {
497 free_expression(expr->OP_LEFT);
498 free_expression(expr->OP_RIGHT);