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