1 /*
2 constfold.c
3
4 expression constant folding
5
6 Copyright (C) 2004 Bill Currie <bill@taniwha.org>
7
8 Author: Bill Currie <bill@taniwha.org>
9 Date: 2004/01/22
10
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License
13 as published by the Free Software Foundation; either version 2
14 of the License, or (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19
20 See the GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to:
24
25 Free Software Foundation, Inc.
26 59 Temple Place - Suite 330
27 Boston, MA 02111-1307, USA
28
29 */
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #ifdef HAVE_STRING_H
35 # include <string.h>
36 #endif
37 #ifdef HAVE_STRINGS_H
38 # include <strings.h>
39 #endif
40 #include <stdlib.h>
41
42 #include <QF/dstring.h>
43 #include <QF/mathlib.h>
44
45 #include "diagnostic.h"
46 #include "expr.h"
47 #include "options.h"
48 #include "qfcc.h"
49 #include "strpool.h"
50 #include "type.h"
51 #include "qc-parse.h"
52
53 typedef expr_t *(*operation_t) (int op, expr_t *e, expr_t *e1, expr_t *e2);
54 typedef expr_t *(*unaryop_t) (int op, expr_t *e, expr_t *e1);
55
56 static expr_t *
cf_cast_expr(type_t * type,expr_t * e)57 cf_cast_expr (type_t *type, expr_t *e)
58 {
59 e = cast_expr (type, e);
60 return e;
61 }
62
63 static int
valid_op(int op,int * valid_ops)64 valid_op (int op, int *valid_ops)
65 {
66 while (*valid_ops && op != *valid_ops)
67 valid_ops++;
68 return *valid_ops == op;
69 }
70
71 static expr_t *
do_op_string(int op,expr_t * e,expr_t * e1,expr_t * e2)72 do_op_string (int op, expr_t *e, expr_t *e1, expr_t *e2)
73 {
74 const char *s1, *s2;
75 static dstring_t *temp_str;
76 static int valid[] = {'=', '+', LT, GT, LE, GE, EQ, NE, 0};
77
78 if (!valid_op (op, valid))
79 return error (e1, "invalid operand for string");
80
81 if (is_compare (op) || is_logic (op)) {
82 if (options.code.progsversion > PROG_ID_VERSION)
83 e->e.expr.type = &type_integer;
84 else
85 e->e.expr.type = &type_float;
86 } else {
87 e->e.expr.type = &type_string;
88 }
89
90 if (op == '=' || !is_constant (e1) || !is_constant (e2))
91 return e;
92
93 s1 = expr_string (e1);
94 s2 = expr_string (e2);
95 if (!s1)
96 s1 = "";
97 if (!s2)
98 s2 = "";
99
100 switch (op) {
101 case '+':
102 if (!temp_str)
103 temp_str = dstring_newstr ();
104 dstring_clearstr (temp_str);
105 dstring_appendstr (temp_str, s1);
106 dstring_appendstr (temp_str, s2);
107 e = new_string_expr (save_string (temp_str->str));
108 break;
109 case LT:
110 e = new_integer_expr (strcmp (s1, s2) < 0);
111 break;
112 case GT:
113 e = new_integer_expr (strcmp (s1, s2) > 0);
114 break;
115 case LE:
116 e = new_integer_expr (strcmp (s1, s2) <= 0);
117 break;
118 case GE:
119 e = new_integer_expr (strcmp (s1, s2) >= 0);
120 break;
121 case EQ:
122 e = new_integer_expr (strcmp (s1, s2) == 0);
123 break;
124 case NE:
125 e = new_integer_expr (strcmp (s1, s2));
126 break;
127 default:
128 internal_error (e1, 0);
129 }
130 e->file = e1->file;
131 e->line = e1->line;
132 return e;
133 }
134
135 static expr_t *
convert_to_float(expr_t * e)136 convert_to_float (expr_t *e)
137 {
138 if (get_type (e) == &type_float)
139 return e;
140
141 switch (e->type) {
142 case ex_value:
143 switch (e->e.value->type) {
144 case ev_integer:
145 convert_int (e);
146 return e;
147 case ev_short:
148 convert_short (e);
149 return e;
150 default:
151 internal_error (e, 0);
152 }
153 break;
154 case ex_symbol:
155 case ex_expr:
156 case ex_uexpr:
157 case ex_temp:
158 case ex_block:
159 e = cf_cast_expr (&type_float, e);
160 return e;
161 default:
162 internal_error (e, 0);
163 }
164 }
165
166 static expr_t *
do_op_float(int op,expr_t * e,expr_t * e1,expr_t * e2)167 do_op_float (int op, expr_t *e, expr_t *e1, expr_t *e2)
168 {
169 float f1, f2;
170 expr_t *conv;
171 type_t *type = &type_float;
172 static int valid[] = {
173 '=', '+', '-', '*', '/', '&', '|', '^', '%',
174 SHL, SHR, AND, OR, LT, GT, LE, GE, EQ, NE, 0
175 };
176
177 if (!valid_op (op, valid))
178 return error (e1, "invalid operator for float");
179
180 if (op == '=' || op == PAS) {
181 if ((type = get_type (e1)) != &type_float) {
182 //FIXME optimize casting a constant
183 e->e.expr.e2 = e2 = cf_cast_expr (type, e2);
184 } else if ((conv = convert_to_float (e2)) != e2) {
185 e->e.expr.e2 = e2 = conv;
186 }
187 } else {
188 if ((conv = convert_to_float (e1)) != e1) {
189 e->e.expr.e1 = e1 = conv;
190 }
191 if ((conv = convert_to_float (e2)) != e2) {
192 e->e.expr.e2 = e2 = conv;
193 }
194 }
195 if (is_compare (op) || is_logic (op)) {
196 if (options.code.progsversion > PROG_ID_VERSION)
197 type = &type_integer;
198 else
199 type = &type_float;
200 }
201 e->e.expr.type = type;
202
203 if (op == '*' && is_constant (e1) && expr_float (e1) == 1)
204 return e2;
205 if (op == '*' && is_constant (e2) && expr_float (e2) == 1)
206 return e1;
207 if (op == '*' && is_constant (e1) && expr_float (e1) == 0)
208 return e1;
209 if (op == '*' && is_constant (e2) && expr_float (e2) == 0)
210 return e2;
211 if (op == '/' && is_constant (e2) && expr_float (e2) == 1)
212 return e1;
213 if (op == '/' && is_constant (e2) && expr_float (e2) == 0)
214 return error (e, "division by zero");
215 if (op == '/' && is_constant (e1) && expr_float (e1) == 0)
216 return e1;
217 if (op == '+' && is_constant (e1) && expr_float (e1) == 0)
218 return e2;
219 if (op == '+' && is_constant (e2) && expr_float (e2) == 0)
220 return e1;
221 if (op == '-' && is_constant (e2) && expr_float (e2) == 0)
222 return e1;
223
224 if (op == '=' || !is_constant (e1) || !is_constant (e2))
225 return e;
226
227 f1 = expr_float (e1);
228 f2 = expr_float (e2);
229
230 switch (op) {
231 case '+':
232 e = new_float_expr (f1 + f2);
233 break;
234 case '-':
235 e = new_float_expr (f1 - f2);
236 break;
237 case '*':
238 e = new_float_expr (f1 * f2);
239 break;
240 case '/':
241 if (!f2)
242 return error (e1, "divide by zero");
243 e = new_float_expr (f1 / f2);
244 break;
245 case '&':
246 e = new_float_expr ((int)f1 & (int)f2);
247 break;
248 case '|':
249 e = new_float_expr ((int)f1 | (int)f2);
250 break;
251 case '^':
252 e = new_float_expr ((int)f1 ^ (int)f2);
253 break;
254 case '%':
255 e = new_float_expr ((int)f1 % (int)f2);
256 break;
257 case SHL:
258 e = new_float_expr ((int)f1 << (int)f2);
259 break;
260 case SHR:
261 e = new_float_expr ((int)f1 >> (int)f2);
262 break;
263 case AND:
264 e = new_integer_expr (f1 && f2);
265 break;
266 case OR:
267 e = new_integer_expr (f1 || f2);
268 break;
269 case LT:
270 e = new_integer_expr (f1 < f2);
271 break;
272 case GT:
273 e = new_integer_expr (f1 > f2);
274 break;
275 case LE:
276 e = new_integer_expr (f1 <= f2);
277 break;
278 case GE:
279 e = new_integer_expr (f1 >= f2);
280 break;
281 case EQ:
282 e = new_integer_expr (f1 == f2);
283 break;
284 case NE:
285 e = new_integer_expr (f1 != f2);
286 break;
287 default:
288 internal_error (e1, 0);
289 }
290 e->file = e1->file;
291 e->line = e1->line;
292 return e;
293 }
294
295 static expr_t *
do_op_vector(int op,expr_t * e,expr_t * e1,expr_t * e2)296 do_op_vector (int op, expr_t *e, expr_t *e1, expr_t *e2)
297 {
298 const float *v1, *v2;
299 vec3_t v, float_vec;
300 static int valid[] = {'=', '+', '-', '*', EQ, NE, 0};
301 expr_t *t;
302
303 if (get_type (e1) != &type_vector) {
304
305 if (op != '*')
306 return error (e1, "invalid operator for vector");
307
308 t = e1;
309 e->e.expr.e1 = e1 = e2;
310 e2 = t;
311 }
312 if (get_type (e2) != &type_vector) {
313 e->e.expr.e2 = e2 = convert_to_float (e2);
314 if (op != '*' && op != '/')
315 return error (e1, "invalid operator for vector");
316 } else {
317 if (!valid_op (op, valid))
318 return error (e1, "invalid operator for vector");
319 }
320 if (is_compare (op) || is_logic (op)) {
321 if (options.code.progsversion > PROG_ID_VERSION)
322 e->e.expr.type = &type_integer;
323 else
324 e->e.expr.type = &type_float;
325 } else if (op == '*' && get_type (e2) == &type_vector) {
326 e->e.expr.type = &type_float;
327 } else if (op == '/' && !is_constant (e1)) {
328 e2 = fold_constants (binary_expr ('/', new_float_expr (1), e2));
329 e = fold_constants (binary_expr ('*', e1, e2));
330 } else {
331 e->e.expr.type = &type_vector;
332 }
333
334 if (op == '*' && is_float_val (e2) && expr_float (e2) == 1)
335 return e1;
336 if (op == '*' && is_float_val (e2) && expr_float (e2) == 0)
337 return new_vector_expr (vec3_origin);
338 if (op == '/' && is_float_val (e2) && expr_float (e2) == 1)
339 return e1;
340 if (op == '/' && is_float_val (e2) && expr_float (e2) == 0)
341 return error (e, "division by zero");
342 if (op == '+' && is_constant (e1) && VectorIsZero (expr_vector (e1)))
343 return e2;
344 if (op == '+' && is_constant (e2) && VectorIsZero (expr_vector (e2)))
345 return e1;
346 if (op == '-' && is_constant (e1) && VectorIsZero (expr_vector (e1))
347 && is_constant (e2)) {
348 vec3_t v;
349 VectorNegate (expr_vector (e2), v);
350 e = new_vector_expr (v);
351 e->file = e2->file;
352 e->line = e2->line;
353 return e;
354 }
355 if (op == '-' && is_constant (e2) && VectorIsZero (expr_vector (e2)))
356 return e1;
357
358 if (op == '=' || !is_constant (e1) || !is_constant (e2))
359 return e;
360
361 if (is_float_val (e1)) {
362 float_vec[0] = expr_float (e1);
363 v2 = float_vec;
364 v1 = expr_vector (e2);
365 } else if (is_float_val (e2)) {
366 float_vec[0] = expr_float (e2);
367 v2 = float_vec;
368 v1 = expr_vector (e1);
369 } else {
370 v1 = expr_vector (e1);
371 v2 = expr_vector (e2);
372 }
373
374 switch (op) {
375 case '+':
376 VectorAdd (v1, v2, v);
377 e = new_vector_expr (v);
378 break;
379 case '-':
380 VectorSubtract (v1, v2, v);
381 e = new_vector_expr (v);
382 break;
383 case '/':
384 if (!v2[0])
385 return error (e1, "divide by zero");
386 VectorScale (v1, 1 / v2[0], v);
387 e = new_vector_expr (v);
388 break;
389 case '*':
390 if (get_type (e2) == &type_vector) {
391 e = new_float_expr (DotProduct (v1, v2));
392 } else {
393 VectorScale (v1, v2[0], v);
394 e = new_vector_expr (v);
395 }
396 break;
397 case EQ:
398 e = new_integer_expr (VectorCompare (v1, v2));
399 break;
400 case NE:
401 e = new_integer_expr (!VectorCompare (v1, v2));
402 break;
403 default:
404 internal_error (e1, 0);
405 }
406 e->file = e1->file;
407 e->line = e1->line;
408 return e;
409 }
410
411 static expr_t *
do_op_entity(int op,expr_t * e,expr_t * e1,expr_t * e2)412 do_op_entity (int op, expr_t *e, expr_t *e1, expr_t *e2)
413 {
414 type_t *type = get_type (e2);
415
416 if ((op == '.' || op == '&') && type->type == ev_field) {
417 return e;
418 }
419 if (op == EQ || op == NE) {
420 if (options.code.progsversion > PROG_ID_VERSION)
421 e->e.expr.type = &type_integer;
422 else
423 e->e.expr.type = &type_float;
424 return e;
425 }
426 if (op != '=' || type != &type_entity)
427 return error (e1, "invalid operator for entity");
428 e->e.expr.type = &type_entity;
429 return e;
430 }
431
432 static expr_t *
do_op_field(int op,expr_t * e,expr_t * e1,expr_t * e2)433 do_op_field (int op, expr_t *e, expr_t *e1, expr_t *e2)
434 {
435 if (op != '=')
436 return error (e1, "invalid operator for field");
437 e->e.expr.type = &type_field;
438 return e;
439 }
440
441 static expr_t *
do_op_func(int op,expr_t * e,expr_t * e1,expr_t * e2)442 do_op_func (int op, expr_t *e, expr_t *e1, expr_t *e2)
443 {
444 if (op == 'c') {
445 e->e.expr.type = get_type (e1)->t.func.type;
446 return e;
447 }
448 if (op == EQ || op == NE) {
449 if (options.code.progsversion > PROG_ID_VERSION)
450 e->e.expr.type = &type_integer;
451 else
452 e->e.expr.type = &type_float;
453 return e;
454 }
455 if (op != '=')
456 return error (e1, "invalid operator for func");
457 e->e.expr.type = &type_function;
458 return e;
459 }
460
461 static expr_t *
do_op_pointer(int op,expr_t * e,expr_t * e1,expr_t * e2)462 do_op_pointer (int op, expr_t *e, expr_t *e1, expr_t *e2)
463 {
464 type_t *type;
465 static int valid[] = {'=', PAS, '-', '&', 'M', '.', EQ, NE, 0};
466
467 if (is_integral (type = get_type (e2)) && (op == '-' || op == '+')) {
468 // pointer arithmetic
469 expr_t *ptoi = new_alias_expr (type, e1);
470 e->e.expr.e1 = ptoi;
471 e = fold_constants (e);
472 return new_alias_expr (get_type (e1), e);
473 }
474 if (!valid_op (op, valid))
475 return error (e1, "invalid operator for pointer: %s",
476 get_op_string (op));
477
478 if (op == '-') {
479 type = get_type (e1);
480 if (type != get_type (e2))
481 return error (e2, "invalid operands to binary -");
482 e1 = new_alias_expr (&type_integer, e1);
483 e2 = new_alias_expr (&type_integer, e2);
484 e = binary_expr ('-', e1, e2);
485 if (type_size (type) != 1)
486 e = binary_expr ('/', e, new_integer_expr (type_size (type)));
487 return e;
488 }
489 if (op == PAS && (type = get_type (e1)->t.fldptr.type) != get_type (e2)) {
490 // make sure auto-convertions happen
491 expr_t *tmp = new_temp_def_expr (type);
492 expr_t *ass = new_binary_expr ('=', tmp, e2);
493
494 tmp->file = e1->file;
495 ass->line = e2->line;
496 ass->file = e2->file;
497 ass = fold_constants (ass);
498 if (e->e.expr.e2 == tmp)
499 internal_error (e2, 0);
500 e->e.expr.e2 = ass->e.expr.e2;
501 }
502 if (op == EQ || op == NE) {
503 if (options.code.progsversion > PROG_ID_VERSION)
504 e->e.expr.type = &type_integer;
505 else
506 e->e.expr.type = &type_float;
507 }
508 if (op != PAS && op != '.' && op != '&' && op != 'M'
509 && extract_type (e1) != extract_type (e2))
510 return type_mismatch (e1, e2, op);
511 if ((op == '.' || op == '&') && get_type (e2) == &type_uinteger)
512 e->e.expr.e2 = cf_cast_expr (&type_integer, e2);
513 return e;
514 }
515
516 static expr_t *
do_op_quatvect(int op,expr_t * e,expr_t * e1,expr_t * e2)517 do_op_quatvect (int op, expr_t *e, expr_t *e1, expr_t *e2)
518 {
519 if (op != '*')
520 return error (e1, "invalid operator for quaternion and vector");
521 if (is_constant (e1) && QuatIsZero (expr_quaternion (e1)))
522 return new_vector_expr (vec3_origin);
523 if (is_constant (e2) && VectorIsZero (expr_vector (e2)))
524 return new_vector_expr (vec3_origin);
525 if (is_constant (e1) && is_constant (e2)) {
526 const vec_t *q, *v;
527 vec3_t r;
528
529 q = expr_quaternion (e1);
530 v = expr_vector (e2);
531 QuatMultVec (q, v, r);
532 return new_vector_expr (r);
533 }
534 e->e.expr.type = &type_vector;
535 return e;
536 }
537
538 static expr_t *
do_op_quaternion(int op,expr_t * e,expr_t * e1,expr_t * e2)539 do_op_quaternion (int op, expr_t *e, expr_t *e1, expr_t *e2)
540 {
541 const float *q1, *q2;
542 quat_t q, float_quat;
543 static int valid[] = {'=', '+', '-', '*', EQ, NE, 0};
544 expr_t *t;
545
546 if (get_type (e1) != &type_quaternion) {
547
548 if (op != '*' && op != '/')
549 return error (e1, "invalid operator for quaternion");
550
551 if (op == '*') {
552 t = e1;
553 e->e.expr.e1 = e1 = e2;
554 e2 = t;
555 }
556 }
557 if (get_type (e2) != &type_quaternion) {
558 e->e.expr.e2 = e2 = convert_to_float (e2);
559 if (op != '*' && op != '/')
560 return error (e1, "invalid operator for quaternion");
561 } else {
562 if (!valid_op (op, valid))
563 return error (e1, "invalid operator for quaternion");
564 }
565 if (is_compare (op) || is_logic (op)) {
566 if (options.code.progsversion > PROG_ID_VERSION)
567 e->e.expr.type = &type_integer;
568 else
569 e->e.expr.type = &type_float;
570 } else if (op == '/' && !is_constant (e1)) {
571 e2 = fold_constants (binary_expr ('/', new_float_expr (1), e2));
572 e = fold_constants (binary_expr ('*', e1, e2));
573 } else {
574 e->e.expr.type = &type_quaternion;
575 }
576
577 if (op == '*' && is_float_val (e2) && expr_float (e2) == 1)
578 return e1;
579 if (op == '*' && is_float_val (e2) && expr_float (e2) == 0)
580 return new_quaternion_expr (quat_origin);
581 if (op == '/' && is_float_val (e2) && expr_float (e2) == 1)
582 return e1;
583 if (op == '/' && is_float_val (e2) && expr_float (e2) == 0)
584 return error (e, "division by zero");
585 if (op == '+' && is_constant (e1) && QuatIsZero (expr_quaternion (e1)))
586 return e2;
587 if (op == '+' && is_constant (e2) && QuatIsZero (expr_quaternion (e2)))
588 return e1;
589 if (op == '-' && is_constant (e2) && QuatIsZero (expr_quaternion (e2)))
590 return e1;
591
592 if (op == '=' || !is_constant (e1) || !is_constant (e2))
593 return e;
594
595 if (is_float_val (e1)) {
596 float_quat[0] = expr_float (e1);
597 q2 = float_quat;
598 q1 = expr_quaternion (e2);
599 } else if (is_float_val (e2)) {
600 float_quat[0] = expr_float (e2);
601 q2 = float_quat;
602 q1 = expr_quaternion (e1);
603 } else {
604 q1 = expr_quaternion (e1);
605 q2 = expr_quaternion (e2);
606 }
607
608 switch (op) {
609 case '+':
610 QuatAdd (q1, q2, q);
611 e = new_quaternion_expr (q);
612 break;
613 case '-':
614 QuatSubtract (q1, q2, q);
615 e = new_quaternion_expr (q);
616 break;
617 case '/':
618 if (is_float_val (e2)) {
619 QuatScale (q1, 1 / expr_float (e2), q);
620 } else {
621 QuatInverse (q2, q);
622 QuatScale (q2, expr_float (e1), q);
623 }
624 e = new_quaternion_expr (q);
625 break;
626 case '*':
627 if (get_type (e2) == &type_quaternion) {
628 QuatMult (q1, q2, q);
629 } else {
630 QuatScale (q1, q2[0], q);
631 }
632 e = new_quaternion_expr (q);
633 break;
634 case EQ:
635 e = new_integer_expr (QuatCompare (q1, q2));
636 break;
637 case NE:
638 e = new_integer_expr (!QuatCompare (q1, q2));
639 break;
640 default:
641 internal_error (e1, 0);
642 }
643 e->file = e1->file;
644 e->line = e1->line;
645 return e;
646 }
647
648 static expr_t *
do_op_integer(int op,expr_t * e,expr_t * e1,expr_t * e2)649 do_op_integer (int op, expr_t *e, expr_t *e1, expr_t *e2)
650 {
651 int i1, i2;
652 static int valid[] = {
653 '=', '+', '-', '*', '/', '&', '|', '^', '%',
654 SHL, SHR, AND, OR, LT, GT, LE, GE, EQ, NE, 0
655 };
656
657 if (!valid_op (op, valid))
658 return error (e1, "invalid operator for integer");
659
660 if (is_short_val (e1))
661 convert_short_int (e1);
662
663 if (is_short_val (e2))
664 convert_short_int (e2);
665
666 if (is_compare (op) || is_logic (op)) {
667 if (options.code.progsversion > PROG_ID_VERSION)
668 e->e.expr.type = &type_integer;
669 else
670 e->e.expr.type = &type_float;
671 } else {
672 e->e.expr.type = &type_integer;
673 }
674
675 if (op == '*' && is_constant (e1) && expr_integer (e1) == 1)
676 return e2;
677 if (op == '*' && is_constant (e2) && expr_integer (e2) == 1)
678 return e1;
679 if (op == '*' && is_constant (e1) && expr_integer (e1) == 0)
680 return e1;
681 if (op == '*' && is_constant (e2) && expr_integer (e2) == 0)
682 return e2;
683 if (op == '/' && is_constant (e2) && expr_integer (e2) == 1)
684 return e1;
685 if (op == '/' && is_constant (e2) && expr_integer (e2) == 0)
686 return error (e, "division by zero");
687 if (op == '/' && is_constant (e1) && expr_integer (e1) == 0)
688 return e1;
689 if (op == '+' && is_constant (e1) && expr_integer (e1) == 0)
690 return e2;
691 if (op == '+' && is_constant (e2) && expr_integer (e2) == 0)
692 return e1;
693 if (op == '-' && is_constant (e2) && expr_integer (e2) == 0)
694 return e1;
695
696 if (op == '=' || !is_constant (e1) || !is_constant (e2))
697 return e;
698
699 i1 = expr_integer (e1);
700 i2 = expr_integer (e2);
701
702 switch (op) {
703 case '+':
704 e = new_integer_expr (i1 + i2);
705 break;
706 case '-':
707 e = new_integer_expr (i1 - i2);
708 break;
709 case '*':
710 e = new_integer_expr (i1 * i2);
711 break;
712 case '/':
713 if (options.warnings.integer_divide)
714 warning (e2, "%d / %d == %d", i1, i2, i1 / i2);
715 e = new_integer_expr (i1 / i2);
716 break;
717 case '&':
718 e = new_integer_expr (i1 & i2);
719 break;
720 case '|':
721 e = new_integer_expr (i1 | i2);
722 break;
723 case '^':
724 e = new_integer_expr (i1 ^ i2);
725 break;
726 case '%':
727 e = new_integer_expr (i1 % i2);
728 break;
729 case SHL:
730 e = new_integer_expr (i1 << i2);
731 break;
732 case SHR:
733 e = new_integer_expr (i1 >> i2);
734 break;
735 case AND:
736 e = new_integer_expr (i1 && i2);
737 break;
738 case OR:
739 e = new_integer_expr (i1 || i2);
740 break;
741 case LT:
742 e = new_integer_expr (i1 < i2);
743 break;
744 case GT:
745 e = new_integer_expr (i1 > i2);
746 break;
747 case LE:
748 e = new_integer_expr (i1 <= i2);
749 break;
750 case GE:
751 e = new_integer_expr (i1 >= i2);
752 break;
753 case EQ:
754 e = new_integer_expr (i1 == i2);
755 break;
756 case NE:
757 e = new_integer_expr (i1 != i2);
758 break;
759 default:
760 internal_error (e1, 0);
761 }
762 e->file = e1->file;
763 e->line = e1->line;
764 return e;
765 }
766
767 static expr_t *
do_op_uinteger(int op,expr_t * e,expr_t * e1,expr_t * e2)768 do_op_uinteger (int op, expr_t *e, expr_t *e1, expr_t *e2)
769 {
770 return e;
771 }
772
773 static expr_t *
do_op_short(int op,expr_t * e,expr_t * e1,expr_t * e2)774 do_op_short (int op, expr_t *e, expr_t *e1, expr_t *e2)
775 {
776 short i1, i2;
777 static int valid[] = {
778 '=', '+', '-', '*', '/', '&', '|', '^', '%',
779 SHL, SHR, AND, OR, LT, GT, LE, GE, EQ, NE, 0
780 };
781
782 if (!valid_op (op, valid))
783 return error (e1, "invalid operator for short");
784
785 if (is_compare (op) || is_logic (op)) {
786 if (options.code.progsversion > PROG_ID_VERSION)
787 e->e.expr.type = &type_integer;
788 else
789 e->e.expr.type = &type_float;
790 } else {
791 e->e.expr.type = &type_short;
792 }
793
794 if (op == '=' || !is_constant (e1) || !is_constant (e2))
795 return e;
796
797 i1 = expr_short (e1);
798 i2 = expr_short (e2);
799
800 switch (op) {
801 case '+':
802 e = new_short_expr (i1 + i2);
803 break;
804 case '-':
805 e = new_short_expr (i1 - i2);
806 break;
807 case '*':
808 e = new_short_expr (i1 * i2);
809 break;
810 case '/':
811 if (options.warnings.integer_divide)
812 warning (e2, "%d / %d == %d", i1, i2, i1 / i2);
813 e = new_short_expr (i1 / i2);
814 break;
815 case '&':
816 e = new_short_expr (i1 & i2);
817 break;
818 case '|':
819 e = new_short_expr (i1 | i2);
820 break;
821 case '^':
822 e = new_short_expr (i1 ^ i2);
823 break;
824 case '%':
825 e = new_short_expr (i1 % i2);
826 break;
827 case SHL:
828 e = new_short_expr (i1 << i2);
829 break;
830 case SHR:
831 e = new_short_expr (i1 >> i2);
832 break;
833 case AND:
834 e = new_short_expr (i1 && i2);
835 break;
836 case OR:
837 e = new_short_expr (i1 || i2);
838 break;
839 case LT:
840 e = new_integer_expr (i1 < i2);
841 break;
842 case GT:
843 e = new_integer_expr (i1 > i2);
844 break;
845 case LE:
846 e = new_integer_expr (i1 <= i2);
847 break;
848 case GE:
849 e = new_integer_expr (i1 >= i2);
850 break;
851 case EQ:
852 e = new_integer_expr (i1 == i2);
853 break;
854 case NE:
855 e = new_integer_expr (i1 != i2);
856 break;
857 default:
858 internal_error (e1, 0);
859 }
860 e->file = e1->file;
861 e->line = e1->line;
862 return e;
863 }
864
865 static expr_t *
do_op_struct(int op,expr_t * e,expr_t * e1,expr_t * e2)866 do_op_struct (int op, expr_t *e, expr_t *e1, expr_t *e2)
867 {
868 type_t *type;
869
870 if (op != '=' && op != 'm')
871 return error (e1, "invalid operator for struct");
872 if ((type = get_type (e1)) != get_type (e2))
873 return type_mismatch (e1, e2, op);
874 e->e.expr.type = type;
875 return e;
876 }
877
878 static expr_t *
do_op_compound(int op,expr_t * e,expr_t * e1,expr_t * e2)879 do_op_compound (int op, expr_t *e, expr_t *e1, expr_t *e2)
880 {
881 type_t *t1 = get_type (e1);
882 type_t *t2 = get_type (e2);
883 if (is_struct (t1) && is_struct (t2))
884 return do_op_struct (op, e, e1, e2);
885 if (is_scalar (t1) && is_scalar (t2)) {
886 if (is_enum (t1)) {
887 if (t2->type == ev_float)
888 return do_op_float (op, e, e1, e2);
889 return do_op_integer (op, e, e1, e2);
890 }
891 if (is_enum (t2)) {
892 if (t1->type == ev_float)
893 return do_op_float (op, e, e1, e2);
894 return do_op_integer (op, e, e1, e2);
895 }
896 }
897 return error (e1, "invalid operator for compound");
898 }
899
900 static operation_t *do_op[ev_type_count];
901 static expr_t *
do_op_invalid(int op,expr_t * e,expr_t * e1,expr_t * e2)902 do_op_invalid (int op, expr_t *e, expr_t *e1, expr_t *e2)
903 {
904 type_t *t1 = get_type (e1);
905 type_t *t2 = get_type (e2);
906
907 if (e->e.expr.op == 'm')
908 return e; // assume the rest of the compiler got it right
909 if (is_scalar (t1) && is_scalar (t2)) {
910 // one or both expressions are an enum, and the other is one of
911 // int, float or short. Treat the enum as the other type, or as
912 // the default type if both are enum.
913 etype_t t;
914 if (!is_enum (t1))
915 t = t1->type;
916 else if (!is_enum (t2))
917 t = t2->type;
918 else
919 t = type_default->type;
920 return do_op[t][t] (op, e, e1, e2);
921 } else {
922 dstring_t *enc1 = dstring_newstr ();
923 dstring_t *enc2 = dstring_newstr ();
924
925 print_type_str (enc1, t1);
926 print_type_str (enc2, t2);
927
928 //print_expr (e);
929 e1 = error (e1, "invalid operands for binary %s: %s %s",
930 get_op_string (op), enc1->str, enc2->str);
931 dstring_delete (enc1);
932 dstring_delete (enc2);
933 return e1;
934 }
935 }
936
937 static operation_t op_void[ev_type_count] = {
938 do_op_invalid, // ev_void
939 do_op_invalid, // ev_string
940 do_op_invalid, // ev_float
941 do_op_invalid, // ev_vector
942 do_op_invalid, // ev_entity
943 do_op_invalid, // ev_field
944 do_op_invalid, // ev_func
945 do_op_invalid, // ev_pointer
946 do_op_invalid, // ev_quaternion
947 do_op_invalid, // ev_integer
948 do_op_invalid, // ev_uinteger
949 do_op_invalid, // ev_short
950 do_op_invalid, // ev_invalid
951 };
952
953 static operation_t op_string[ev_type_count] = {
954 do_op_invalid, // ev_void
955 do_op_string, // ev_string
956 do_op_invalid, // ev_float
957 do_op_invalid, // ev_vector
958 do_op_invalid, // ev_entity
959 do_op_invalid, // ev_field
960 do_op_invalid, // ev_func
961 do_op_invalid, // ev_pointer
962 do_op_invalid, // ev_quaternion
963 do_op_invalid, // ev_integer
964 do_op_invalid, // ev_uinteger
965 do_op_invalid, // ev_short
966 do_op_invalid, // ev_invalid
967 };
968
969 static operation_t op_float[ev_type_count] = {
970 do_op_invalid, // ev_void
971 do_op_invalid, // ev_string
972 do_op_float, // ev_float
973 do_op_vector, // ev_vector
974 do_op_invalid, // ev_entity
975 do_op_invalid, // ev_field
976 do_op_invalid, // ev_func
977 do_op_invalid, // ev_pointer
978 do_op_quaternion, // ev_quaternion
979 do_op_float, // ev_integer
980 do_op_float, // ev_uinteger
981 do_op_float, // ev_short
982 do_op_invalid, // ev_invalid
983 };
984
985 static operation_t op_vector[ev_type_count] = {
986 do_op_invalid, // ev_void
987 do_op_invalid, // ev_string
988 do_op_vector, // ev_float
989 do_op_vector, // ev_vector
990 do_op_invalid, // ev_entity
991 do_op_invalid, // ev_field
992 do_op_invalid, // ev_func
993 do_op_invalid, // ev_pointer
994 do_op_invalid, // ev_quaternion
995 do_op_vector, // ev_integer
996 do_op_vector, // ev_uinteger
997 do_op_vector, // ev_short
998 do_op_invalid, // ev_invalid
999 };
1000
1001 static operation_t op_entity[ev_type_count] = {
1002 do_op_invalid, // ev_void
1003 do_op_invalid, // ev_string
1004 do_op_invalid, // ev_float
1005 do_op_invalid, // ev_vector
1006 do_op_entity, // ev_entity
1007 do_op_entity, // ev_field
1008 do_op_invalid, // ev_func
1009 do_op_invalid, // ev_pointer
1010 do_op_invalid, // ev_quaternion
1011 do_op_invalid, // ev_integer
1012 do_op_invalid, // ev_uinteger
1013 do_op_invalid, // ev_short
1014 do_op_invalid, // ev_invalid
1015 };
1016
1017 static operation_t op_field[ev_type_count] = {
1018 do_op_invalid, // ev_void
1019 do_op_invalid, // ev_string
1020 do_op_invalid, // ev_float
1021 do_op_invalid, // ev_vector
1022 do_op_invalid, // ev_entity
1023 do_op_field, // ev_field
1024 do_op_invalid, // ev_func
1025 do_op_invalid, // ev_pointer
1026 do_op_invalid, // ev_quaternion
1027 do_op_invalid, // ev_integer
1028 do_op_invalid, // ev_uinteger
1029 do_op_invalid, // ev_short
1030 do_op_invalid, // ev_invalid
1031 };
1032
1033 static operation_t op_func[ev_type_count] = {
1034 do_op_func, // ev_void
1035 do_op_func, // ev_string
1036 do_op_func, // ev_float
1037 do_op_func, // ev_vector
1038 do_op_func, // ev_entity
1039 do_op_func, // ev_field
1040 do_op_func, // ev_func
1041 do_op_func, // ev_pointer
1042 do_op_func, // ev_quaternion
1043 do_op_func, // ev_integer
1044 do_op_func, // ev_uinteger
1045 do_op_func, // ev_short
1046 do_op_func, // ev_invalid
1047 };
1048
1049 static operation_t op_pointer[ev_type_count] = {
1050 do_op_pointer, // ev_void
1051 do_op_pointer, // ev_string
1052 do_op_pointer, // ev_float
1053 do_op_pointer, // ev_vector
1054 do_op_pointer, // ev_entity
1055 do_op_pointer, // ev_field
1056 do_op_pointer, // ev_func
1057 do_op_pointer, // ev_pointer
1058 do_op_pointer, // ev_quaternion
1059 do_op_pointer, // ev_integer
1060 do_op_pointer, // ev_uinteger
1061 do_op_pointer, // ev_short
1062 do_op_pointer, // ev_invalid
1063 };
1064
1065 static operation_t op_quaternion[ev_type_count] = {
1066 do_op_invalid, // ev_void
1067 do_op_invalid, // ev_string
1068 do_op_quaternion, // ev_float
1069 do_op_quatvect, // ev_vector
1070 do_op_invalid, // ev_entity
1071 do_op_invalid, // ev_field
1072 do_op_invalid, // ev_func
1073 do_op_invalid, // ev_pointer
1074 do_op_quaternion, // ev_quaternion
1075 do_op_quaternion, // ev_integer
1076 do_op_quaternion, // ev_uinteger
1077 do_op_quaternion, // ev_short
1078 do_op_invalid, // ev_invalid
1079 };
1080
1081 static operation_t op_integer[ev_type_count] = {
1082 do_op_invalid, // ev_void
1083 do_op_invalid, // ev_string
1084 do_op_float, // ev_float
1085 do_op_vector, // ev_vector
1086 do_op_invalid, // ev_entity
1087 do_op_invalid, // ev_field
1088 do_op_invalid, // ev_func
1089 do_op_invalid, // ev_pointer
1090 do_op_quaternion, // ev_quaternion
1091 do_op_integer, // ev_integer
1092 do_op_uinteger, // ev_uinteger
1093 do_op_integer, // ev_short
1094 do_op_invalid, // ev_invalid
1095 };
1096
1097 static operation_t op_uinteger[ev_type_count] = {
1098 do_op_invalid, // ev_void
1099 do_op_invalid, // ev_string
1100 do_op_float, // ev_float
1101 do_op_vector, // ev_vector
1102 do_op_invalid, // ev_entity
1103 do_op_invalid, // ev_field
1104 do_op_invalid, // ev_func
1105 do_op_invalid, // ev_pointer
1106 do_op_quaternion, // ev_quaternion
1107 do_op_uinteger, // ev_integer
1108 do_op_uinteger, // ev_uinteger
1109 do_op_uinteger, // ev_short
1110 do_op_invalid, // ev_invalid
1111 };
1112
1113 static operation_t op_short[ev_type_count] = {
1114 do_op_invalid, // ev_void
1115 do_op_invalid, // ev_string
1116 do_op_float, // ev_float
1117 do_op_vector, // ev_vector
1118 do_op_invalid, // ev_entity
1119 do_op_invalid, // ev_field
1120 do_op_invalid, // ev_func
1121 do_op_invalid, // ev_pointer
1122 do_op_quaternion, // ev_quaternion
1123 do_op_integer, // ev_integer
1124 do_op_uinteger, // ev_uinteger
1125 do_op_short, // ev_short
1126 do_op_invalid, // ev_invalid
1127 };
1128
1129 static operation_t op_compound[ev_type_count] = {
1130 do_op_invalid, // ev_void
1131 do_op_invalid, // ev_string
1132 do_op_compound, // ev_float
1133 do_op_invalid, // ev_vector
1134 do_op_invalid, // ev_entity
1135 do_op_invalid, // ev_field
1136 do_op_invalid, // ev_func
1137 do_op_invalid, // ev_pointer
1138 do_op_invalid, // ev_quaternion
1139 do_op_compound, // ev_integer
1140 do_op_compound, // ev_uinteger
1141 do_op_compound, // ev_short
1142 do_op_compound, // ev_invalid
1143 };
1144
1145 static operation_t *do_op[ev_type_count] = {
1146 op_void, // ev_void
1147 op_string, // ev_string
1148 op_float, // ev_float
1149 op_vector, // ev_vector
1150 op_entity, // ev_entity
1151 op_field, // ev_field
1152 op_func, // ev_func
1153 op_pointer, // ev_pointer
1154 op_quaternion, // ev_quaternion
1155 op_integer, // ev_integer
1156 op_uinteger, // ev_uinteger
1157 op_short, // ev_short
1158 op_compound, // ev_invalid
1159 };
1160
1161 static unaryop_t do_unary_op[ev_type_count];
1162 static expr_t *
uop_invalid(int op,expr_t * e,expr_t * e1)1163 uop_invalid (int op, expr_t *e, expr_t *e1)
1164 {
1165 type_t *t1 = get_type (e1);
1166 if (is_scalar (t1)) {
1167 // The expression is an enum. Treat the enum as the default type.
1168 etype_t t;
1169 t = type_default->type;
1170 return do_unary_op[t] (op, e, e1);
1171 } else {
1172 dstring_t *enc1 = dstring_newstr ();
1173
1174 print_type_str (enc1, t1);
1175
1176 //print_expr (e);
1177 e1 = error (e1, "invalid operand for unary %s: %s",
1178 get_op_string (op), enc1->str);
1179 dstring_delete (enc1);
1180 return e1;
1181 }
1182 }
1183
1184 static expr_t *
uop_string(int op,expr_t * e,expr_t * e1)1185 uop_string (int op, expr_t *e, expr_t *e1)
1186 {
1187 // + - ! ~ *
1188 static int valid[] = { '!', 0 };
1189 const char *s;
1190
1191 if (!valid_op (op, valid))
1192 return error (e1, "invalid unary operator for string: %s",
1193 get_op_string (op));
1194
1195 if (!is_constant (e1))
1196 return e;
1197
1198 s = expr_string (e1);
1199 return new_integer_expr (!s || !s[0]);
1200 }
1201
1202 static expr_t *
uop_float(int op,expr_t * e,expr_t * e1)1203 uop_float (int op, expr_t *e, expr_t *e1)
1204 {
1205 static int valid[] = { '+', '-', '!', '~', 'C', 0 };
1206
1207 if (!valid_op (op, valid))
1208 return error (e1, "invalid unary operator for float: %s",
1209 get_op_string (op));
1210 if (op == '+')
1211 return e1;
1212 if (op == 'C' && get_type (e) != &type_integer)
1213 return error (e1, "invalid cast of float");
1214 if (!is_constant (e1))
1215 return e;
1216 switch (op) {
1217 case '-':
1218 return new_float_expr (-expr_float (e1));
1219 case '!':
1220 print_type (get_type (e));
1221 return new_integer_expr (!expr_float (e1));
1222 case '~':
1223 return new_float_expr (~(int) expr_float (e1));
1224 case 'C':
1225 return new_integer_expr (expr_float (e1));
1226 }
1227 internal_error (e, "float unary op blew up");
1228 }
1229
1230 static expr_t *
uop_vector(int op,expr_t * e,expr_t * e1)1231 uop_vector (int op, expr_t *e, expr_t *e1)
1232 {
1233 static int valid[] = { '+', '-', '!', 0 };
1234 vec3_t v;
1235
1236 if (!valid_op (op, valid))
1237 return error (e1, "invalid unary operator for vector: %s",
1238 get_op_string (op));
1239 if (op == '+')
1240 return e1;
1241 if (!is_constant (e1))
1242 return e;
1243 switch (op) {
1244 case '-':
1245 VectorNegate (expr_vector (e), v);
1246 return new_vector_expr (v);
1247 case '!':
1248 return new_integer_expr (!VectorIsZero (expr_vector (e1)));
1249 }
1250 internal_error (e, "vector unary op blew up");
1251 }
1252
1253 static expr_t *
uop_entity(int op,expr_t * e,expr_t * e1)1254 uop_entity (int op, expr_t *e, expr_t *e1)
1255 {
1256 static int valid[] = { '!', 0 };
1257
1258 if (!valid_op (op, valid))
1259 return error (e1, "invalid unary operator for entity: %s",
1260 get_op_string (op));
1261 if (!is_constant (e1))
1262 return e;
1263 switch (op) {
1264 case '!':
1265 internal_error (e, "!entity");
1266 }
1267 internal_error (e, "entity unary op blew up");
1268 }
1269
1270 static expr_t *
uop_field(int op,expr_t * e,expr_t * e1)1271 uop_field (int op, expr_t *e, expr_t *e1)
1272 {
1273 static int valid[] = { '!', 0 };
1274
1275 if (!valid_op (op, valid))
1276 return error (e1, "invalid unary operator for field: %s",
1277 get_op_string (op));
1278 if (!is_constant (e1))
1279 return e;
1280 switch (op) {
1281 case '!':
1282 internal_error (e, "!field");
1283 }
1284 internal_error (e, "field unary op blew up");
1285 }
1286
1287 static expr_t *
uop_func(int op,expr_t * e,expr_t * e1)1288 uop_func (int op, expr_t *e, expr_t *e1)
1289 {
1290 static int valid[] = { '!', 0 };
1291
1292 if (!valid_op (op, valid))
1293 return error (e1, "invalid unary operator for func: %s",
1294 get_op_string (op));
1295 if (!is_constant (e1))
1296 return e;
1297 switch (op) {
1298 case '!':
1299 internal_error (e, "!func");
1300 }
1301 internal_error (e, "func unary op blew up");
1302 }
1303
1304 static expr_t *
uop_pointer(int op,expr_t * e,expr_t * e1)1305 uop_pointer (int op, expr_t *e, expr_t *e1)
1306 {
1307 static int valid[] = { '!', '.', 0 };
1308
1309 if (!valid_op (op, valid))
1310 return error (e1, "invalid unary operator for pointer: %s",
1311 get_op_string (op));
1312 if (!is_constant (e1))
1313 return e;
1314 switch (op) {
1315 case '!':
1316 internal_error (e, "!pointer");
1317 case '.':
1318 debug (e, ".pointer");
1319 return e;
1320 }
1321 internal_error (e, "pointer unary op blew up");
1322 }
1323
1324 static expr_t *
uop_quaternion(int op,expr_t * e,expr_t * e1)1325 uop_quaternion (int op, expr_t *e, expr_t *e1)
1326 {
1327 static int valid[] = { '+', '-', '!', '~', 0 };
1328 quat_t q;
1329
1330 if (!valid_op (op, valid))
1331 return error (e1, "invalid unary operator for quaternion: %s",
1332 get_op_string (op));
1333 if (op == '+')
1334 return e1;
1335 if (!is_constant (e1))
1336 return e;
1337 switch (op) {
1338 case '-':
1339 QuatNegate (expr_vector (e), q);
1340 return new_quaternion_expr (q);
1341 case '!':
1342 return new_integer_expr (!QuatIsZero (expr_quaternion (e1)));
1343 case '~':
1344 QuatConj (expr_vector (e), q);
1345 return new_quaternion_expr (q);
1346 }
1347 internal_error (e, "quaternion unary op blew up");
1348 }
1349
1350 static expr_t *
uop_integer(int op,expr_t * e,expr_t * e1)1351 uop_integer (int op, expr_t *e, expr_t *e1)
1352 {
1353 static int valid[] = { '+', '-', '!', '~', 'C', 0 };
1354
1355 if (!valid_op (op, valid))
1356 return error (e1, "invalid unary operator for int: %s",
1357 get_op_string (op));
1358 if (op == '+')
1359 return e1;
1360 if (op == 'C' && get_type (e) != &type_float)
1361 return error (e1, "invalid cast of int");
1362 if (!is_constant (e1))
1363 return e;
1364 switch (op) {
1365 case '-':
1366 return new_integer_expr (-expr_integer (e1));
1367 case '!':
1368 return new_integer_expr (!expr_integer (e1));
1369 case '~':
1370 return new_integer_expr (~expr_integer (e1));
1371 case 'C':
1372 return new_float_expr (expr_integer (e1));
1373 }
1374 internal_error (e, "integer unary op blew up");
1375 }
1376
1377 static expr_t *
uop_uinteger(int op,expr_t * e,expr_t * e1)1378 uop_uinteger (int op, expr_t *e, expr_t *e1)
1379 {
1380 static int valid[] = { '+', '-', '!', '~', 0 };
1381
1382 if (!valid_op (op, valid))
1383 return error (e1, "invalid unary operator for uint: %s",
1384 get_op_string (op));
1385 if (op == '+')
1386 return e1;
1387 if (!is_constant (e1))
1388 return e;
1389 switch (op) {
1390 case '-':
1391 return new_uinteger_expr (-expr_uinteger (e1));
1392 case '!':
1393 return new_integer_expr (!expr_uinteger (e1));
1394 case '~':
1395 return new_uinteger_expr (~expr_uinteger (e1));
1396 }
1397 internal_error (e, "uinteger unary op blew up");
1398 }
1399
1400 static expr_t *
uop_short(int op,expr_t * e,expr_t * e1)1401 uop_short (int op, expr_t *e, expr_t *e1)
1402 {
1403 static int valid[] = { '+', '-', '!', '~', 0 };
1404
1405 if (!valid_op (op, valid))
1406 return error (e1, "invalid unary operator for short: %s",
1407 get_op_string (op));
1408 if (op == '+')
1409 return e1;
1410 if (!is_constant (e1))
1411 return e;
1412 switch (op) {
1413 case '-':
1414 return new_short_expr (-expr_short (e1));
1415 case '!':
1416 return new_integer_expr (!expr_short (e1));
1417 case '~':
1418 return new_short_expr (~expr_short (e1));
1419 }
1420 internal_error (e, "short unary op blew up");
1421 }
1422
1423 static expr_t *
uop_compound(int op,expr_t * e,expr_t * e1)1424 uop_compound (int op, expr_t *e, expr_t *e1)
1425 {
1426 type_t *t1 = get_type (e1);
1427
1428 if (is_scalar (t1)) {
1429 if (is_enum (t1)) {
1430 return uop_integer (op, e, e1);
1431 }
1432 }
1433 return error (e1, "invalid operand for unary %s", get_op_string (op));
1434 }
1435
1436 static unaryop_t do_unary_op[ev_type_count] = {
1437 uop_invalid, // ev_void
1438 uop_string, // ev_string
1439 uop_float, // ev_float
1440 uop_vector, // ev_vector
1441 uop_entity, // ev_entity
1442 uop_field, // ev_field
1443 uop_func, // ev_func
1444 uop_pointer, // ev_pointer
1445 uop_quaternion, // ev_quaternion
1446 uop_integer, // ev_integer
1447 uop_uinteger, // ev_uinteger
1448 uop_short, // ev_short
1449 uop_compound, // ev_invalid
1450 };
1451
1452 expr_t *
fold_constants(expr_t * e)1453 fold_constants (expr_t *e)
1454 {
1455 int op;
1456 expr_t *e1, *e2;
1457 etype_t t1, t2;
1458
1459 if (e->type == ex_block) {
1460 expr_t *block = new_block_expr ();
1461 expr_t *next;
1462
1463 block->e.block.result = e->e.block.result;
1464 block->line = e->line;
1465 block->file = e->file;
1466
1467 for (e = e->e.block.head; e; e = next) {
1468 next = e->next;
1469 e = fold_constants (e);
1470 e->next = 0;
1471 append_expr (block, e);
1472 }
1473
1474 return block;
1475 }
1476 if (e->type == ex_bool) {
1477 e->e.bool.e = fold_constants (e->e.bool.e);
1478 return e;
1479 }
1480 if (e->type == ex_uexpr) {
1481 if (!e->e.expr.e1)
1482 return e;
1483 op = e->e.expr.op;
1484 e->e.expr.e1 = e1 = fold_constants (e->e.expr.e1);
1485 if (e1->type == ex_error)
1486 return e1;
1487 if (op == 'A' || op == 'g' || op == 'r')
1488 return e;
1489 t1 = extract_type (e1);
1490 if (t1 >= ev_type_count || !do_unary_op[t1]) {
1491 print_expr (e);
1492 internal_error (e, "invalid type: %d", t1);
1493 }
1494 return do_unary_op[t1] (op, e, e1);
1495 }
1496
1497 if (e->type != ex_expr)
1498 return e;
1499
1500 op = e->e.expr.op;
1501
1502 e->e.expr.e1 = e1 = fold_constants (e->e.expr.e1);
1503 if (e1->type == ex_error)
1504 return e1;
1505 t1 = extract_type (e1);
1506
1507 if (op == 'i' || op == 'n' || op == 'c')
1508 return e;
1509
1510 e->e.expr.e2 = e2 = fold_constants (e->e.expr.e2);
1511 if (e2->type == ex_error)
1512 return e2;
1513
1514 if (e2->type == ex_label || e2->type == ex_labelref)
1515 return e;
1516
1517 t2 = extract_type (e2);
1518
1519 if (op == 's')
1520 return e;
1521
1522 if (t1 >= ev_type_count || t2 >= ev_type_count
1523 || !do_op[t1] || !do_op[t1][t2])
1524 internal_error (e, "invalid type");
1525 return do_op[t1][t2] (op, e, e1, e2);
1526 }
1527