1 /* $Id: expr.c,v 1.18 1994/06/24 10:59:46 ceriel Exp $ */
3 /* This file contains the expression evaluator. It exports the following
5 - int eval_cond(p_tree p)
6 This routine evaluates the conditional expression indicated by p
7 and returns 1 if it evaluates to TRUE, or 0 if it could not be
8 evaluated for some reason or if it evalutes to FALSE.
9 If the expression cannot be evaluated, an error message is given.
10 - int eval_desig(p_tree p, t_addr *paddr, long **psize, p_type *ptp)
11 This routine evaluates the expression indicated by p, which should
12 result in a designator. The result of the expression is an address
13 which is to be found in *paddr. *psize will contain the size of the
14 designated object, and *ptp its type.
15 If the expression cannot be evaluated or does not result in a
16 designator, 0 is returned and an error message is given.
17 Otherwise, 1 is returned.
18 - int eval_expr(p_tree p, char **pbuf, long **psize, p_type *ptp)
19 This routine evaluates the expression indicated by p.
20 The result of the expression is left in *pbuf.
21 *psize will contain the size of the value, and *ptp its type.
22 If the expression cannot be evaluated, 0 is returned and an error
23 message is given. Otherwise, 1 is returned.
24 - int convert(char **pbuf, long *psize, p_type *ptp, p_type tp, long size)
25 This routine tries to convert the value in pbuf of size psize
26 and type ptp to type tp with size size. It returns 0 if this fails,
27 while producing an error message. Otherwise, it returns 1 and
28 the resulting value, type and size are left in pbuf, ptp, and
30 - long get_int(char *buf, long size, int class)
31 Returns the value of size 'size', residing in 'buf', of 'class'
32 T_INTEGER, T_UNSIGNED, or T_ENUM.
33 - int put_int(char *buf, long size, long value)
34 Stores the value 'value' of size 'size' in 'buf'.
35 - double get_real(char *buf, long size)
36 Returns the real value of size 'size', residing in 'buf'.
37 T_INTEGER, T_UNSIGNED, or T_ENUM.
38 - int put_real(char *buf, long size, double value)
39 Stores the value 'value' of size 'size' in 'buf'.
58 extern int stack_offset;
59 extern char *strcpy();
60 extern t_addr *get_EM_regs();
61 extern char *memcpy();
62 extern char *malloc(), *realloc();
64 #define malloc_succeeded(p) if (! (p)) {\
65 error("could not allocate enough memory");\
69 /* static t_addr get_addr(p_symbol sym; long *psize);
70 Get the address of the object indicated by sym. Returns 0 on failure,
71 address on success. *psize will contain size of object.
72 For local variables or parameters, the 'stack_offset' variable is
73 used to determine from which stack frame the search must start.
77 register p_symbol sym;
80 p_type tp = sym->sy_type;
81 long size = tp->ty_size;
87 switch(sym->sy_class) {
89 /* exists if child exists; nm_value contains addres */
90 return (t_addr) sym->sy_name.nm_value;
93 /* first find the stack frame in which it resides */
94 symsc = base_scope(sym->sy_scope);
96 /* now symsc contains the scope where the storage for sym is
97 allocated. Now find it on the stack of child.
102 if (! (EM_regs = get_EM_regs(i++))) {
106 error("%s not available", sym->sy_idf->id_text);
109 sc = base_scope(get_scope_from_addr(EM_regs[2]));
110 if (! sc || sc->sc_start > EM_regs[2]) {
111 error("%s not available", sym->sy_idf->id_text);
115 if (sc == symsc) break; /* found it */
118 if (sym->sy_class == LOCVAR) {
119 /* Either local variable or value parameter */
120 return EM_regs[sym->sy_name.nm_value < 0 ? 0 : 1] +
121 (t_addr) sym->sy_name.nm_value;
124 /* If we get here, we have a var parameter. Get the parameters
125 of the current procedure invocation.
128 p_type proctype = sc->sc_definedby->sy_type;
132 size = proctype->ty_nbparams;
133 if (has_static_link(sc)) size += pointer_size;
134 AB = malloc((unsigned) size);
136 error("could not allocate enough memory");
139 if (! get_bytes(size, EM_regs[1], AB)) {
142 if ((size = tp->ty_size) == 0) {
143 size = compute_size(tp, AB);
146 a = (t_addr) get_int(AB+sym->sy_name.nm_value, pointer_size, T_UNSIGNED);
151 error("%s is not a variable", sym->sy_idf->id_text);
164 *pbuf = malloc((unsigned) size);
166 error("could not allocate enough memory");
169 if (! get_bytes(size, a, *pbuf)) return 0;
175 /* static int get_value(p_symbol sym; char **pbuf; long *psize);
176 Get the value of the symbol indicated by sym. Return 0 on failure,
177 1 on success. On success, 'pbuf' contains the value, and 'psize' contains
178 the size. For 'pbuf', storage is allocated by malloc; this storage must
179 be freed by caller (I don't like this any more than you do, but caller
180 does not know sizes).
181 For local variables or parameters, the 'stack_offset' variable is
182 used to determine from which stack frame the search must start.
185 get_value(sym, pbuf, psize)
186 register p_symbol sym;
190 p_type tp = sym->sy_type;
193 long size = tp->ty_size;
196 switch(sym->sy_class) {
198 *pbuf = malloc((unsigned) size);
200 error("could not allocate enough memory");
203 switch(tp->ty_class) {
205 put_real(*pbuf, size, sym->sy_const.co_rval);
211 put_int(*pbuf, size, sym->sy_const.co_ival);
214 memcpy(*pbuf, sym->sy_const.co_setval, (int) size);
217 memcpy(*pbuf, sym->sy_const.co_sval, (int) size);
220 fatal("strange constant");
227 a = get_addr(sym, psize);
228 retval = get_v(a, pbuf, *psize);
232 a = get_addr(sym->sy_descr, psize);
233 retval = get_v(a, pbuf, *psize);
235 size = get_int(*pbuf, *psize, T_INTEGER);
236 retval = get_v(a+*psize, pbuf, *psize);
238 size += get_int(*pbuf, *psize, T_INTEGER);
239 put_int(*pbuf, *psize, size);
243 a = get_addr(sym->sy_descr, psize);
244 retval = get_v(a, pbuf, *psize);
249 if (*pbuf) free(*pbuf);
258 /* buffer to integer and vice versa routines */
261 get_int(buf, size, class)
271 if (class == T_INTEGER && l >= 0x7F) l -= 256;
272 else if (class != T_INTEGER && l < 0) l += 256;
275 l = *((short *) buf);
276 if (class == T_INTEGER && l >= 0x7FFF) l -= 65536;
277 else if (class != T_INTEGER && l < 0) l += 65536;
285 put_int(buf, size, value)
295 *((short *) buf) = value;
298 *((long *) buf) = value;
304 /* buffer to real and vice versa routines */
313 return *((float *) buf);
315 return *((double *) buf);
320 put_real(buf, size, value)
327 *((float *) buf) = value;
330 *((double *) buf) = value;
337 convert(pbuf, psize, ptp, tp, size)
340 register p_type *ptp;
344 /* Convert the value in pbuf, of size psize and type ptp, to type
345 tp and leave the resulting value in pbuf, the resulting size
346 in psize, and the resulting type in ptp.
351 if (*ptp == tp) return 1;
353 *pbuf = realloc(*pbuf, (unsigned int) size);
354 malloc_succeeded(*pbuf);
356 if ((*ptp)->ty_class == T_SUBRANGE) *ptp = (*ptp)->ty_base;
357 if (tp && *ptp) switch((*ptp)->ty_class) {
362 l = get_int(*pbuf, *psize, (*ptp)->ty_class);
363 if (tp == bool_type) l = l != 0;
364 switch(tp->ty_class) {
370 put_int(*pbuf, size, l);
377 (*ptp)->ty_class == T_INTEGER
379 : (double) (unsigned long) l);
388 d = get_real(*pbuf, *psize);
389 switch(tp->ty_class) {
395 if (tp == bool_type) put_int(*pbuf, size, (long) (d != 0));
396 else put_int(*pbuf, size, (long) d);
401 put_real(*pbuf, size, d);
412 error("illegal conversion");
424 p_type target_tp = currlang->has_bool_type ? bool_type : int_type;
426 if (eval_expr(p, &buf, &size, &tp)) {
427 if (convert(&buf, &size, &tp, target_tp, target_tp->ty_size)) {
428 val = get_int(buf, size, T_UNSIGNED);
430 return (int) (val != 0);
437 /* one routine for each unary operator */
440 not_op(p, pbuf, psize, ptp)
446 p_type target_tp = currlang->has_bool_type ? bool_type : int_type;
448 if (eval_expr(p->t_args[0], pbuf, psize, ptp) &&
449 convert(pbuf, psize, ptp, target_tp, target_tp->ty_size)) {
450 put_int(*pbuf, *psize, (long) !get_int(*pbuf, *psize, T_UNSIGNED));
457 bnot_op(p, pbuf, psize, ptp)
463 if (eval_expr(p->t_args[0], pbuf, psize, ptp)) {
464 switch((*ptp)->ty_class) {
469 put_int(*pbuf, *psize, ~get_int(*pbuf, *psize, T_UNSIGNED));
472 error("illegal operand type(s)");
480 ptr_addr(p, paddr, psize, ptp)
488 if (eval_expr(p->t_args[0], &buf, psize, ptp)) {
489 switch((*ptp)->ty_class) {
491 *ptp = (*ptp)->ty_ptrto;
492 *psize = (*ptp)->ty_size;
493 *paddr = get_int(buf, pointer_size, T_UNSIGNED);
497 error("illegal operand of DEREF");
506 deref_op(p, pbuf, psize, ptp)
514 if (ptr_addr(p, &addr, psize, ptp)) {
515 *pbuf = malloc((unsigned) *psize);
516 malloc_succeeded(*pbuf);
517 if (! get_bytes(*psize, addr, *pbuf)) {
528 addr_op(p, pbuf, psize, ptp)
536 if (eval_desig(p->t_args[0], &addr, psize, ptp)) {
537 *pbuf = malloc((unsigned) pointer_size);
538 malloc_succeeded(*pbuf);
539 put_int(*pbuf, pointer_size, (long) addr);
540 address_type->ty_ptrto = *ptp;
548 unmin_op(p, pbuf, psize, ptp)
554 if (eval_expr(p->t_args[0], pbuf, psize, ptp)) {
555 switch((*ptp)->ty_class) {
560 put_int(*pbuf, *psize, -get_int(*pbuf, *psize, (*ptp)->ty_class));
563 put_real(*pbuf, *psize, -get_real(*pbuf, *psize));
566 error("illegal operand of unary -");
574 unplus_op(p, pbuf, psize, ptp)
580 if (eval_expr(p->t_args[0], pbuf, psize, ptp)) {
581 switch((*ptp)->ty_class) {
589 error("illegal operand of unary +");
596 static int (*un_op[])() = {
633 if (tp1->ty_class == T_SUBRANGE) tp1 = tp1->ty_base;
634 if (tp2->ty_class == T_SUBRANGE) tp2 = tp2->ty_base;
635 if (tp1 == tp2) return tp2;
636 if (tp2->ty_class == T_REAL) {
637 p_type tmp = tp1; tp1 = tp2; tp2 = tmp;
639 if (tp1->ty_class == T_REAL) {
640 switch(tp2->ty_class) {
646 return tp1->ty_size > tp2->ty_size ? tp1 : tp2;
648 error("illegal type combination");
652 if (tp2->ty_class == T_POINTER) {
653 p_type tmp = tp1; tp1 = tp2; tp2 = tmp;
655 if (tp1->ty_class == T_POINTER) {
656 switch(tp2->ty_class) {
663 error("illegal type combination");
667 if (tp2->ty_class == T_UNSIGNED) {
668 p_type tmp = tp1; tp1 = tp2; tp2 = tmp;
670 if (tp1->ty_class == T_UNSIGNED) {
671 switch(tp2->ty_class) {
674 if (tp1->ty_size >= tp2->ty_size) return tp1;
679 error("illegal type combination");
683 if (tp2->ty_class == T_INTEGER) {
684 p_type tmp = tp1; tp1 = tp2; tp2 = tmp;
686 if (tp1->ty_class == T_INTEGER) {
687 switch(tp2->ty_class) {
689 if (tp1->ty_size >= tp2->ty_size) return tp1;
694 error("illegal type combination");
698 error("illegal type combination");
703 andor_op(p, pbuf, psize, ptp)
713 p_type target_tp = currlang->has_bool_type ? bool_type : int_type;
715 if (eval_expr(p->t_args[0], pbuf, psize, ptp) &&
716 convert(pbuf, psize, ptp, target_tp, target_tp->ty_size) &&
717 eval_expr(p->t_args[1], &buf, &size, &tp) &&
718 convert(&buf, &size, &tp, target_tp, target_tp->ty_size)) {
719 l1 = get_int(*pbuf, *psize, T_UNSIGNED);
720 l2 = get_int(buf, size, T_UNSIGNED);
723 p->t_whichoper == E_AND
734 arith_op(p, pbuf, psize, ptp)
744 p_type tp, balance_tp;
746 if (!(eval_expr(p->t_args[0], pbuf, psize, ptp) &&
747 eval_expr(p->t_args[1], &buf, &size, &tp))) {
750 if ((*ptp)->ty_class == T_POINTER) {
751 if (currlang != c_dep ||
752 (p->t_whichoper != E_PLUS && p->t_whichoper != E_MIN)) {
753 error("illegal operand type(s)");
757 l1 = get_int(*pbuf, *psize, T_UNSIGNED);
758 if (tp->ty_class == T_POINTER) {
759 if (p->t_whichoper != E_MIN) {
760 error("illegal operand type(s)");
764 l2 = get_int(buf, size, T_UNSIGNED);
766 *pbuf = Realloc(*pbuf, (unsigned) long_size);
767 put_int(*pbuf, long_size, (l1 - l2)/(*ptp)->ty_ptrto->ty_size);
771 if (! convert(&buf, &size, &tp, long_type, long_size)) {
775 l2 = get_int(buf, size, T_INTEGER) * (*ptp)->ty_ptrto->ty_size;
778 if (p->t_whichoper == E_PLUS) l1 += l2;
780 put_int(*pbuf, *psize, l1);
783 if ((balance_tp = balance(*ptp, tp)) &&
784 convert(pbuf, psize, ptp, balance_tp, balance_tp->ty_size) &&
785 convert(&buf, &size, &tp, balance_tp, balance_tp->ty_size)) {
786 switch(balance_tp->ty_class) {
790 l1 = get_int(*pbuf, *psize, balance_tp->ty_class);
791 l2 = get_int(buf, size, balance_tp->ty_class);
794 switch(p->t_whichoper) {
816 error("division by 0");
819 if (balance_tp->ty_class == T_INTEGER) {
820 if ((l1 < 0) != (l2 < 0)) {
821 if (l1 < 0) l1 = - l1;
823 if (p->t_whichoper == E_DIV) {
824 l1 = -((l1+l2-1)/l2);
832 else l1 = (unsigned long) l1 /
838 error("modulo by 0");
841 if (balance_tp->ty_class == T_INTEGER) {
842 if ((l1 < 0) != (l2 < 0)) {
843 if (l1 < 0) l1 = - l1;
845 if (p->t_whichoper == E_MOD) {
846 l1 = ((l1+l2-1)/l2)*l2 - l1;
849 l1 = (l1/l2)*l2 - l1;
854 else l1 = (unsigned long) l1 %
858 put_int(*pbuf, *psize, l1);
861 d1 = get_real(*pbuf, *psize);
862 d2 = get_real(buf, size);
865 switch(p->t_whichoper) {
869 error("division by 0.0");
884 put_real(*pbuf, *psize, d1);
887 error("illegal operand type(s)");
898 sft_op(p, pbuf, psize, ptp)
909 if (eval_expr(p->t_args[0], pbuf, psize, ptp) &&
910 eval_expr(p->t_args[1], &buf, &size, &tp) &&
911 convert(&buf, &size, &tp, int_type, int_size)) {
913 if (tp->ty_class == T_SUBRANGE) {
916 switch(tp->ty_class) {
920 l1 = get_int(*pbuf, *psize, tp->ty_class);
921 l2 = get_int(buf, size, T_INTEGER);
924 switch(p->t_whichoper) {
929 if (tp->ty_class == T_INTEGER) l1 >>= (int) l2;
930 else l1 = (unsigned long) l1 >> (int) l2;
935 error("illegal operand type(s)");
946 cmp_op(p, pbuf, psize, ptp)
956 p_type tp, balance_tp;
958 if (eval_expr(p->t_args[0], pbuf, psize, ptp) &&
959 eval_expr(p->t_args[1], &buf, &size, &tp) &&
960 (balance_tp = balance(*ptp, tp)) &&
961 convert(pbuf, psize, ptp, balance_tp, balance_tp->ty_size) &&
962 convert(&buf, &size, &tp, balance_tp, balance_tp->ty_size)) {
963 switch(balance_tp->ty_class) {
968 l1 = get_int(*pbuf, *psize, balance_tp->ty_class);
969 l2 = get_int(buf, size, balance_tp->ty_class);
972 switch(p->t_whichoper) {
980 if (balance_tp->ty_class == T_INTEGER) {
983 else l1 = (unsigned long) l1 <=
987 if (balance_tp->ty_class == T_INTEGER) {
990 else l1 = (unsigned long) l1 <
994 if (balance_tp->ty_class == T_INTEGER) {
997 else l1 = (unsigned long) l1 >=
1001 if (balance_tp->ty_class == T_INTEGER) {
1004 else l1 = (unsigned long) l1 >
1014 d1 = get_real(*pbuf, *psize);
1015 d2 = get_real(buf, size);
1018 switch(p->t_whichoper) {
1044 error("illegal operand type(s)");
1048 if (*psize < int_size) {
1050 *pbuf = realloc(*pbuf, (unsigned int) int_size);
1051 malloc_succeeded(*pbuf);
1053 else *psize = int_size;
1054 if (currlang->has_bool_type) {
1057 else *ptp = int_type;
1058 put_int(*pbuf, *psize, l1);
1066 in_op(p, pbuf, psize, ptp)
1076 int sft = int_size == 2 ? 4 : 5;
1078 if (eval_expr(p->t_args[0], pbuf, psize, ptp) &&
1079 eval_expr(p->t_args[1], &buf, &size, &tp)) {
1080 if (tp->ty_class != T_SET) {
1081 error("right-hand side of IN not a set");
1085 if (! convert(pbuf, psize, ptp, tp->ty_setbase, int_size)) {
1089 l = get_int(*pbuf, *psize, (*ptp)->ty_class) - tp->ty_setlow;
1092 && (((int *) buf)[(int)(l>>sft)] & (1 << (l & ((1 << sft)-1))));
1094 *pbuf = realloc(*pbuf, (unsigned) int_size);
1095 malloc_succeeded(*pbuf);
1097 *ptp = currlang->has_bool_type ? bool_type : int_type;
1098 put_int(*pbuf, *psize, l);
1105 array_addr(p, paddr, psize, ptp)
1116 if (eval_desig(p->t_args[0], paddr, psize, ptp) &&
1117 eval_expr(p->t_args[1], &buf, &size, &tp)) {
1118 if ((*ptp)->ty_class != T_ARRAY && (*ptp)->ty_class != T_POINTER) {
1119 error("illegal left-hand side of [");
1123 if ((*ptp)->ty_class == T_POINTER) {
1124 if (! get_bytes(pointer_size, *paddr, (char *) paddr)) {
1128 *paddr = get_int((char *) paddr, pointer_size, T_UNSIGNED);
1130 if (! convert(&buf, &size, &tp, int_type, int_size)) {
1134 l = get_int(buf, size, T_INTEGER);
1137 if ((*ptp)->ty_class == T_ARRAY) {
1138 if (l < (*ptp)->ty_lb || l > (*ptp)->ty_hb) {
1139 error("array bound error");
1143 *ptp = (*ptp)->ty_elements;
1144 l *= (*currlang->arrayelsize)((*ptp)->ty_size);
1147 *ptp = (*ptp)->ty_ptrto;
1148 l *= (*ptp)->ty_size;
1150 *psize = (*ptp)->ty_size;
1158 array_op(p, pbuf, psize, ptp)
1166 if (array_addr(p, &a, psize, ptp)) {
1167 *pbuf = malloc((unsigned int) *psize);
1168 malloc_succeeded(*pbuf);
1169 if (! get_bytes(*psize, a, *pbuf)) {
1178 select_addr(p, paddr, psize, ptp)
1185 register struct fields *f;
1188 if (eval_desig(p->t_args[0], paddr, psize, ptp)) {
1190 if (tp->ty_class != T_STRUCT && tp->ty_class != T_UNION) {
1191 error("SELECT on non-struct");
1194 if (p->t_args[1]->t_oper != OP_NAME) {
1195 error("right-hand side of SELECT not a name");
1198 for (nf = tp->ty_nfields, f = tp->ty_fields; nf; nf--, f++) {
1199 if (! strcmp(f->fld_name, p->t_args[1]->t_str)) break;
1202 error("'%s' not found", p->t_args[1]->t_str);
1206 /* ??? this needs some work for bitfields ??? */
1207 *paddr += f->fld_pos>>3;
1208 *psize = f->fld_bitsize >> 3;
1216 select_op(p, pbuf, psize, ptp)
1223 if (select_addr(p, &a, psize, ptp)) {
1224 *pbuf = malloc((unsigned int) *psize);
1225 malloc_succeeded(*pbuf);
1226 if (! get_bytes(*psize, a, *pbuf)) {
1237 derselect_op(p, pbuf, psize, ptp)
1247 t.t_whichoper = E_DEREF;
1248 t.t_args[0] = p->t_args[0];
1250 p->t_whichoper = E_SELECT;
1251 retval = eval_expr(p, pbuf, psize, ptp);
1252 p->t_args[0] = t.t_args[0];
1253 p->t_whichoper = E_DERSELECT;
1257 static int (*bin_op[])() = {
1290 eval_expr(p, pbuf, psize, ptp)
1296 register p_symbol sym;
1303 if (eval_expr(p->t_args[0], pbuf, psize, ptp)) retval = 1;
1307 sym = identify(p, VAR|REGVAR|LOCVAR|VARPAR|CONST|LBOUND|UBOUND);
1308 if (! sym) return 0;
1309 if (! get_value(sym, pbuf, psize)) {
1312 *ptp = sym->sy_type;
1317 *pbuf = malloc((unsigned int) long_size);
1318 malloc_succeeded(*pbuf);
1321 put_int(*pbuf, long_size, p->t_ival);
1326 *pbuf = malloc((unsigned int) double_size);
1327 malloc_succeeded(*pbuf);
1328 *psize = double_size;
1330 put_real(*pbuf, double_size, p->t_fval);
1335 *psize = strlen(p->t_sval)+1;
1336 *pbuf = malloc((unsigned int)*psize);
1337 malloc_succeeded(*pbuf);
1339 strcpy(*pbuf, p->t_sval);
1344 retval = (*un_op[p->t_whichoper])(p, pbuf, psize, ptp);
1348 retval = (*bin_op[p->t_whichoper])(p, pbuf, psize, ptp);
1362 if ((*ptp)->ty_class == T_CROSS) {
1363 *ptp = (*ptp)->ty_cross;
1364 if (! *ptp) *ptp = void_type;
1371 eval_desig(p, paddr, psize, ptp)
1377 register p_symbol sym;
1384 sym = identify(p, VAR|REGVAR|LOCVAR|VARPAR);
1385 if (! sym) return 0;
1386 if (! (a = get_addr(sym, psize))) {
1390 *ptp = sym->sy_type;
1395 switch(p->t_whichoper) {
1397 if (ptr_addr(p, paddr, psize, ptp)) {
1402 print_node(db_out, p, 0);
1403 fputs(" not a designator\n", db_out);
1409 switch(p->t_whichoper) {
1411 if (array_addr(p, paddr, psize, ptp)) {
1416 if (select_addr(p, paddr, psize, ptp)) {
1421 print_node(db_out, p, 0);
1422 fputs(" not a designator\n", db_out);
1427 error("illegal designator");
1434 if ((*ptp)->ty_class == T_CROSS) {
1435 *ptp = (*ptp)->ty_cross;
1438 print_node(db_out, p, 0);
1439 fputs(" designator has unknown type\n", db_out);