1 /*
2 	expr.c
3 
4 	expression construction and manipulations
5 
6 	Copyright (C) 2001 Bill Currie <bill@taniwha.org>
7 
8 	Author: Bill Currie <bill@taniwha.org>
9 	Date: 2001/06/15
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/alloc.h"
43 #include "QF/dstring.h"
44 #include "QF/mathlib.h"
45 #include "QF/sys.h"
46 #include "QF/va.h"
47 
48 #include "qfcc.h"
49 #include "class.h"
50 #include "def.h"
51 #include "defspace.h"
52 #include "diagnostic.h"
53 #include "emit.h"
54 #include "expr.h"
55 #include "function.h"
56 #include "idstuff.h"
57 #include "method.h"
58 #include "options.h"
59 #include "reloc.h"
60 #include "shared.h"
61 #include "strpool.h"
62 #include "struct.h"
63 #include "symtab.h"
64 #include "type.h"
65 #include "value.h"
66 #include "qc-parse.h"
67 
68 static expr_t *free_exprs;
69 
70 type_t     *ev_types[ev_type_count] = {
71 	&type_void,
72 	&type_string,
73 	&type_float,
74 	&type_vector,
75 	&type_entity,
76 	&type_field,
77 	&type_function,
78 	&type_pointer,
79 	&type_quaternion,
80 	&type_integer,
81 	&type_uinteger,
82 	&type_short,
83 	&type_invalid,
84 };
85 
86 void
convert_name(expr_t * e)87 convert_name (expr_t *e)
88 {
89 	symbol_t   *sym;
90 	expr_t     *new;
91 
92 	if (e->type != ex_symbol)
93 		return;
94 
95 	sym = e->e.symbol;
96 
97 	if (!strcmp (sym->name, "__PRETTY_FUNCTION__")
98 		&& current_func) {
99 		new = new_string_expr (current_func->name);
100 		goto convert;
101 	}
102 	if (!strcmp (sym->name, "__FUNCTION__")
103 		&& current_func) {
104 		new = new_string_expr (current_func->def->name);
105 		goto convert;
106 	}
107 	if (!strcmp (sym->name, "__LINE__")
108 		&& current_func) {
109 		new = new_integer_expr (e->line);
110 		goto convert;
111 	}
112 	if (!strcmp (sym->name, "__INFINITY__")
113 		&& current_func) {
114 		new = new_float_expr (INFINITY);
115 		goto convert;
116 	}
117 	if (!strcmp (sym->name, "__FILE__")
118 		&& current_func) {
119 		new = new_string_expr (GETSTR (e->file));
120 		goto convert;
121 	}
122 	if (!sym->table) {
123 		error (e, "%s undefined", sym->name);
124 		sym->type = type_default;
125 		//FIXME need a def
126 		return;
127 	}
128 	if (sym->sy_type == sy_expr) {
129 		new = copy_expr (sym->s.expr);
130 		goto convert;
131 	}
132 	if (sym->sy_type == sy_type)
133 		internal_error (e, "unexpected typedef");
134 	// var, const and func shouldn't need extra handling
135 	return;
136 convert:
137 	e->type = new->type;
138 	e->e = new->e;
139 }
140 
141 type_t *
get_type(expr_t * e)142 get_type (expr_t *e)
143 {
144 	convert_name (e);
145 	switch (e->type) {
146 		case ex_labelref:
147 			return &type_void;
148 		case ex_label:
149 		case ex_error:
150 			return 0;					// something went very wrong
151 		case ex_bool:
152 			if (options.code.progsversion == PROG_ID_VERSION)
153 				return &type_float;
154 			return &type_integer;
155 		case ex_nil:
156 		case ex_state:
157 			return &type_void;
158 		case ex_block:
159 			if (e->e.block.result)
160 				return get_type (e->e.block.result);
161 			return &type_void;
162 		case ex_expr:
163 		case ex_uexpr:
164 			return e->e.expr.type;
165 		case ex_symbol:
166 			return e->e.symbol->type;
167 		case ex_temp:
168 			return e->e.temp.type;
169 		case ex_value:
170 			if (e->e.value->type == ev_func)
171 				return e->e.value->v.func_val.type;
172 			if (e->e.value->type == ev_pointer)
173 				return pointer_type (e->e.value->v.pointer.type);
174 			if (e->e.value->type == ev_field)
175 				return field_type (e->e.value->v.pointer.type);
176 			if (e->e.value->type == ev_integer
177 				&& options.code.progsversion == PROG_ID_VERSION) {
178 				convert_int (e);
179 			}
180 			return ev_types[e->e.value->type];
181 	}
182 	return 0;
183 }
184 
185 etype_t
extract_type(expr_t * e)186 extract_type (expr_t *e)
187 {
188 	type_t     *type = get_type (e);
189 
190 	if (type)
191 		return type->type;
192 	return ev_type_count;
193 }
194 
195 expr_t *
type_mismatch(expr_t * e1,expr_t * e2,int op)196 type_mismatch (expr_t *e1, expr_t *e2, int op)
197 {
198 	dstring_t  *t1 = dstring_newstr ();
199 	dstring_t  *t2 = dstring_newstr ();
200 
201 	print_type_str (t1, get_type (e1));
202 	print_type_str (t2, get_type (e2));
203 
204 	e1 = error (e1, "type mismatch: %s %s %s",
205 				t1->str, get_op_string (op), t2->str);
206 	dstring_delete (t1);
207 	dstring_delete (t2);
208 	return e1;
209 }
210 
211 expr_t *
param_mismatch(expr_t * e,int param,const char * fn,type_t * t1,type_t * t2)212 param_mismatch (expr_t *e, int param, const char *fn, type_t *t1, type_t *t2)
213 {
214 	dstring_t  *s1 = dstring_newstr ();
215 	dstring_t  *s2 = dstring_newstr ();
216 
217 	print_type_str (s1, t1);
218 	print_type_str (s2, t2);
219 
220 	e = error (e, "type mismatch for parameter %d of %s: expected %s, got %s",
221 			   param, fn, s1->str, s2->str);
222 	dstring_delete (s1);
223 	dstring_delete (s2);
224 	return e;
225 }
226 
227 expr_t *
cast_error(expr_t * e,type_t * t1,type_t * t2)228 cast_error (expr_t *e, type_t *t1, type_t *t2)
229 {
230 	dstring_t  *s1 = dstring_newstr ();
231 	dstring_t  *s2 = dstring_newstr ();
232 
233 	print_type_str (s1, t1);
234 	print_type_str (s2, t2);
235 
236 	e =  error (e, "can not cast from %s to %s", s1->str, s2->str);
237 	dstring_delete (s1);
238 	dstring_delete (s2);
239 	return e;
240 }
241 
242 expr_t *
test_error(expr_t * e,type_t * t)243 test_error (expr_t *e, type_t *t)
244 {
245 	dstring_t  *s = dstring_newstr ();
246 
247 	print_type_str (s, t);
248 
249 	e =  error (e, "%s cannot be tested", s->str);
250 	dstring_delete (s);
251 	return e;
252 }
253 
254 expr_t *
new_expr(void)255 new_expr (void)
256 {
257 	expr_t     *e;
258 
259 	ALLOC (16384, expr_t, exprs, e);
260 
261 	e->line = pr.source_line;
262 	e->file = pr.source_file;
263 	return e;
264 }
265 
266 expr_t *
copy_expr(expr_t * e)267 copy_expr (expr_t *e)
268 {
269 	expr_t     *n;
270 	expr_t     *t;
271 
272 	if (!e)
273 		return 0;
274 	switch (e->type) {
275 		case ex_error:
276 		case ex_symbol:
277 		case ex_nil:
278 		case ex_value:
279 			// nothing to do here
280 			n = new_expr ();
281 			*n = *e;
282 			n->line = pr.source_line;
283 			n->file = pr.source_file;
284 			return n;
285 		case ex_state:
286 			return new_state_expr (copy_expr (e->e.state.frame),
287 								   copy_expr (e->e.state.think),
288 								   copy_expr (e->e.state.step));
289 		case ex_bool:
290 			n = new_expr ();
291 			*n = *e;
292 			n->line = pr.source_line;
293 			n->file = pr.source_file;
294 			if (e->e.bool.true_list) {
295 				int         count = e->e.bool.true_list->size;
296 				size_t      size = (size_t)&((ex_list_t *) 0)->e[count];
297 				n->e.bool.true_list = malloc (size);
298 				while (count--)
299 					n->e.bool.true_list->e[count] =
300 						copy_expr (e->e.bool.true_list->e[count]);
301 			}
302 			if (e->e.bool.false_list) {
303 				int         count = e->e.bool.false_list->size;
304 				size_t      size = (size_t)&((ex_list_t *) 0)->e[count];
305 				n->e.bool.false_list = malloc (size);
306 				while (count--)
307 					n->e.bool.false_list->e[count] =
308 						copy_expr (e->e.bool.false_list->e[count]);
309 			}
310 			n->e.bool.e = copy_expr (e->e.bool.e);
311 			return n;
312 		case ex_label:
313 			/// Create a fresh label
314 			return new_label_expr ();
315 		case ex_labelref:
316 			return new_label_ref (e->e.labelref.label);
317 		case ex_block:
318 			n = new_expr ();
319 			*n = *e;
320 			n->line = pr.source_line;
321 			n->file = pr.source_file;
322 			n->e.block.head = 0;
323 			n->e.block.tail = &n->e.block.head;
324 			n->e.block.result = 0;
325 			for (t = e->e.block.head; t; t = t->next) {
326 				if (t == e->e.block.result) {
327 					n->e.block.result = copy_expr (t);
328 					append_expr (n, n->e.block.result);
329 				} else {
330 					append_expr (n, copy_expr (t));
331 				}
332 			}
333 			if (e->e.block.result && !n->e.block.result)
334 				internal_error (e, "bogus block result?");
335 			break;
336 		case ex_expr:
337 			n = new_expr ();
338 			*n = *e;
339 			n->line = pr.source_line;
340 			n->file = pr.source_file;
341 			n->e.expr.e1 = copy_expr (e->e.expr.e1);
342 			n->e.expr.e2 = copy_expr (e->e.expr.e2);
343 			return n;
344 		case ex_uexpr:
345 			n = new_expr ();
346 			*n = *e;
347 			n->line = pr.source_line;
348 			n->file = pr.source_file;
349 			n->e.expr.e1 = copy_expr (e->e.expr.e1);
350 			return n;
351 		case ex_temp:
352 			n = new_expr ();
353 			*n = *e;
354 			n->line = pr.source_line;
355 			n->file = pr.source_file;
356 			n->e.temp.expr = copy_expr (e->e.temp.expr);
357 			return n;
358 	}
359 	internal_error (e, "invalid expression");
360 }
361 
362 const char *
new_label_name(void)363 new_label_name (void)
364 {
365 	static int  label = 0;
366 	int         lnum = ++label;
367 	const char *fname = current_func->sym->name;
368 	char       *lname;
369 
370 	lname = nva ("$%s_%d", fname, lnum);
371 	SYS_CHECKMEM (lname);
372 	return lname;
373 }
374 
375 static expr_t *
new_error_expr(void)376 new_error_expr (void)
377 {
378 	expr_t     *e = new_expr ();
379 	e->type = ex_error;
380 	return e;
381 }
382 
383 expr_t *
new_state_expr(expr_t * frame,expr_t * think,expr_t * step)384 new_state_expr (expr_t *frame, expr_t *think, expr_t *step)
385 {
386 	expr_t     *s = new_expr ();
387 
388 	s->type = ex_state;
389 	s->e.state.frame = frame;
390 	s->e.state.think = think;
391 	s->e.state.step = step;
392 	return s;
393 }
394 
395 expr_t *
new_bool_expr(ex_list_t * true_list,ex_list_t * false_list,expr_t * e)396 new_bool_expr (ex_list_t *true_list, ex_list_t *false_list, expr_t *e)
397 {
398 	expr_t     *b = new_expr ();
399 
400 	b->type = ex_bool;
401 	b->e.bool.true_list = true_list;
402 	b->e.bool.false_list = false_list;
403 	b->e.bool.e = e;
404 	return b;
405 }
406 
407 expr_t *
new_label_expr(void)408 new_label_expr (void)
409 {
410 
411 	expr_t     *l = new_expr ();
412 
413 	l->type = ex_label;
414 	l->e.label.name = new_label_name ();
415 	return l;
416 }
417 
418 expr_t *
new_label_ref(ex_label_t * label)419 new_label_ref (ex_label_t *label)
420 {
421 
422 	expr_t     *l = new_expr ();
423 
424 	l->type = ex_labelref;
425 	l->e.labelref.label = label;
426 	label->used++;
427 	return l;
428 }
429 
430 expr_t *
new_block_expr(void)431 new_block_expr (void)
432 {
433 	expr_t     *b = new_expr ();
434 
435 	b->type = ex_block;
436 	b->e.block.head = 0;
437 	b->e.block.tail = &b->e.block.head;
438 	return b;
439 }
440 
441 expr_t *
new_binary_expr(int op,expr_t * e1,expr_t * e2)442 new_binary_expr (int op, expr_t *e1, expr_t *e2)
443 {
444 	expr_t     *e = new_expr ();
445 
446 	if (e1->type == ex_error)
447 		return e1;
448 	if (e2 && e2->type == ex_error)
449 		return e2;
450 
451 	e->type = ex_expr;
452 	e->e.expr.op = op;
453 	e->e.expr.e1 = e1;
454 	e->e.expr.e2 = e2;
455 	return e;
456 }
457 
458 expr_t *
new_unary_expr(int op,expr_t * e1)459 new_unary_expr (int op, expr_t *e1)
460 {
461 	expr_t     *e = new_expr ();
462 
463 	if (e1 && e1->type == ex_error)
464 		return e1;
465 
466 	e->type = ex_uexpr;
467 	e->e.expr.op = op;
468 	e->e.expr.e1 = e1;
469 	return e;
470 }
471 
472 expr_t *
new_symbol_expr(symbol_t * symbol)473 new_symbol_expr (symbol_t *symbol)
474 {
475 	expr_t     *e = new_expr ();
476 	e->type = ex_symbol;
477 	e->e.symbol = symbol;
478 	return e;
479 }
480 
481 expr_t *
new_temp_def_expr(type_t * type)482 new_temp_def_expr (type_t *type)
483 {
484 	expr_t     *e = new_expr ();
485 
486 	e->type = ex_temp;
487 	e->e.temp.type = type;
488 	return e;
489 }
490 
491 expr_t *
new_nil_expr(void)492 new_nil_expr (void)
493 {
494 	expr_t     *e = new_expr ();
495 	e->type = ex_nil;
496 	return e;
497 }
498 
499 expr_t *
new_value_expr(ex_value_t * value)500 new_value_expr (ex_value_t *value)
501 {
502 	expr_t     *e = new_expr ();
503 	e->type = ex_value;
504 	e->e.value = value;
505 	return e;
506 }
507 
508 expr_t *
new_name_expr(const char * name)509 new_name_expr (const char *name)
510 {
511 	expr_t     *e = new_expr ();
512 	symbol_t   *sym;
513 
514 	sym = symtab_lookup (current_symtab, name);
515 	if (!sym)
516 		sym = new_symbol (name);
517 	e->type = ex_symbol;
518 	e->e.symbol = sym;
519 	return e;
520 }
521 
522 expr_t *
new_string_expr(const char * string_val)523 new_string_expr (const char *string_val)
524 {
525 	expr_t     *e = new_expr ();
526 	e->type = ex_value;
527 	e->e.value = new_string_val (string_val);
528 	return e;
529 }
530 
531 expr_t *
new_float_expr(float float_val)532 new_float_expr (float float_val)
533 {
534 	expr_t     *e = new_expr ();
535 	e->type = ex_value;
536 	e->e.value = new_float_val (float_val);
537 	return e;
538 }
539 
540 expr_t *
new_vector_expr(const float * vector_val)541 new_vector_expr (const float *vector_val)
542 {
543 	expr_t     *e = new_expr ();
544 	e->type = ex_value;
545 	e->e.value = new_vector_val (vector_val);
546 	return e;
547 }
548 
549 expr_t *
new_entity_expr(int entity_val)550 new_entity_expr (int entity_val)
551 {
552 	expr_t     *e = new_expr ();
553 	e->type = ex_value;
554 	e->e.value = new_entity_val (entity_val);
555 	return e;
556 }
557 
558 expr_t *
new_field_expr(int field_val,type_t * type,def_t * def)559 new_field_expr (int field_val, type_t *type, def_t *def)
560 {
561 	expr_t     *e = new_expr ();
562 	e->type = ex_value;
563 	e->e.value = new_field_val (field_val, type, def);
564 	return e;
565 }
566 
567 expr_t *
new_func_expr(int func_val,type_t * type)568 new_func_expr (int func_val, type_t *type)
569 {
570 	expr_t     *e = new_expr ();
571 	e->type = ex_value;
572 	e->e.value = new_func_val (func_val, type);
573 	return e;
574 }
575 
576 expr_t *
new_pointer_expr(int val,type_t * type,def_t * def)577 new_pointer_expr (int val, type_t *type, def_t *def)
578 {
579 	expr_t     *e = new_expr ();
580 	e->type = ex_value;
581 	e->e.value = new_pointer_val (val, type, def);
582 	return e;
583 }
584 
585 expr_t *
new_quaternion_expr(const float * quaternion_val)586 new_quaternion_expr (const float *quaternion_val)
587 {
588 	expr_t     *e = new_expr ();
589 	e->type = ex_value;
590 	e->e.value = new_quaternion_val (quaternion_val);
591 	return e;
592 }
593 
594 expr_t *
new_integer_expr(int integer_val)595 new_integer_expr (int integer_val)
596 {
597 	expr_t     *e = new_expr ();
598 	e->type = ex_value;
599 	e->e.value = new_integer_val (integer_val);
600 	return e;
601 }
602 
603 expr_t *
new_uinteger_expr(unsigned uinteger_val)604 new_uinteger_expr (unsigned uinteger_val)
605 {
606 	expr_t     *e = new_expr ();
607 	e->type = ex_value;
608 	e->e.value = new_uinteger_val (uinteger_val);
609 	return e;
610 }
611 
612 expr_t *
new_short_expr(short short_val)613 new_short_expr (short short_val)
614 {
615 	expr_t     *e = new_expr ();
616 	e->type = ex_value;
617 	e->e.value = new_short_val (short_val);
618 	return e;
619 }
620 
621 int
is_constant(expr_t * e)622 is_constant (expr_t *e)
623 {
624 	if (e->type == ex_nil || e->type == ex_value || e->type == ex_labelref
625 		|| (e->type == ex_symbol && e->e.symbol->sy_type == sy_const)
626 		|| (e->type == ex_symbol && e->e.symbol->sy_type == sy_var
627 			&& e->e.symbol->s.def->constant))
628 		return 1;
629 	return 0;
630 }
631 
632 expr_t *
constant_expr(expr_t * e)633 constant_expr (expr_t *e)
634 {
635 	expr_t     *new;
636 	symbol_t   *sym;
637 	ex_value_t *value;
638 
639 	if (!is_constant (e))
640 		return e;
641 	if (e->type == ex_nil || e->type == ex_value || e->type == ex_labelref)
642 		return e;
643 	if (e->type != ex_symbol)
644 		return e;
645 	sym = e->e.symbol;
646 	if (sym->sy_type == sy_const) {
647 		value = sym->s.value;
648 	} else if (sym->sy_type == sy_var && sym->s.def->constant) {
649 		//FIXME pointers and fields
650 		internal_error (e, "what to do here?");
651 		//memset (&value, 0, sizeof (value));
652 		//memcpy (&value.v, &D_INT (sym->s.def),
653 				//type_size (sym->s.def->type) * sizeof (pr_type_t));
654 	} else {
655 		return e;
656 	}
657 	new = new_expr ();
658 	new->type = ex_value;
659 	new->line = e->line;
660 	new->file = e->file;
661 	new->e.value = value;
662 	return new;
663 }
664 
665 int
is_string_val(expr_t * e)666 is_string_val (expr_t *e)
667 {
668 	if (e->type == ex_nil)
669 		return 1;
670 	if (e->type == ex_value && e->e.value->type == ev_string)
671 		return 1;
672 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
673 		&& e->e.symbol->type->type == ev_string)
674 		return 1;
675 	return 0;
676 }
677 
678 const char *
expr_string(expr_t * e)679 expr_string (expr_t *e)
680 {
681 	if (e->type == ex_nil)
682 		return 0;
683 	if (e->type == ex_value && e->e.value->type == ev_string)
684 		return e->e.value->v.string_val;
685 	internal_error (e, "not a string constant");
686 }
687 
688 int
is_float_val(expr_t * e)689 is_float_val (expr_t *e)
690 {
691 	if (e->type == ex_nil)
692 		return 1;
693 	if (e->type == ex_value && e->e.value->type == ev_float)
694 		return 1;
695 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
696 		&& e->e.symbol->type->type == ev_float)
697 		return 1;
698 	return 0;
699 }
700 
701 float
expr_float(expr_t * e)702 expr_float (expr_t *e)
703 {
704 	if (e->type == ex_nil)
705 		return 0;
706 	if (e->type == ex_value && e->e.value->type == ev_float)
707 		return e->e.value->v.float_val;
708 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
709 		&& e->e.symbol->type->type == ev_float)
710 		return e->e.symbol->s.value->v.float_val;
711 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_var
712 		&& e->e.symbol->s.def->constant
713 		&& is_float (e->e.symbol->s.def->type))
714 		return D_FLOAT (e->e.symbol->s.def);
715 	internal_error (e, "not a float constant");
716 }
717 
718 int
is_vector_val(expr_t * e)719 is_vector_val (expr_t *e)
720 {
721 	if (e->type == ex_nil)
722 		return 1;
723 	if (e->type == ex_value && e->e.value->type == ev_vector)
724 		return 1;
725 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
726 		&& e->e.symbol->type->type == ev_vector)
727 		return 1;
728 	return 0;
729 }
730 
731 const float *
expr_vector(expr_t * e)732 expr_vector (expr_t *e)
733 {
734 	if (e->type == ex_nil)
735 		return vec3_origin;
736 	if (e->type == ex_value && e->e.value->type == ev_vector)
737 		return e->e.value->v.vector_val;
738 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
739 		&& e->e.symbol->type->type == ev_vector)
740 		return e->e.symbol->s.value->v.vector_val;
741 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_var
742 		&& e->e.symbol->s.def->constant
743 		&& e->e.symbol->s.def->type->type == ev_vector)
744 		return D_VECTOR (e->e.symbol->s.def);
745 	internal_error (e, "not a vector constant");
746 }
747 
748 int
is_quaternion_val(expr_t * e)749 is_quaternion_val (expr_t *e)
750 {
751 	if (e->type == ex_nil)
752 		return 1;
753 	if (e->type == ex_value && e->e.value->type == ev_quat)
754 		return 1;
755 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
756 		&& e->e.symbol->type->type == ev_quat)
757 		return 1;
758 	return 0;
759 }
760 
761 const float *
expr_quaternion(expr_t * e)762 expr_quaternion (expr_t *e)
763 {
764 	if (e->type == ex_nil)
765 		return quat_origin;
766 	if (e->type == ex_value && e->e.value->type == ev_quat)
767 		return e->e.value->v.quaternion_val;
768 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
769 		&& e->e.symbol->type->type == ev_quat)
770 		return e->e.symbol->s.value->v.quaternion_val;
771 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_var
772 		&& e->e.symbol->s.def->constant
773 		&& e->e.symbol->s.def->type->type == ev_quat)
774 		return D_QUAT (e->e.symbol->s.def);
775 	internal_error (e, "not a quaternion constant");
776 }
777 
778 int
is_integer_val(expr_t * e)779 is_integer_val (expr_t *e)
780 {
781 	if (e->type == ex_nil)
782 		return 1;
783 	if (e->type == ex_value && e->e.value->type == ev_integer)
784 		return 1;
785 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
786 		&& (e->e.symbol->type->type == ev_integer
787 			|| is_enum (e->e.symbol->type)))
788 		return 1;
789 	return 0;
790 }
791 
792 int
expr_integer(expr_t * e)793 expr_integer (expr_t *e)
794 {
795 	if (e->type == ex_nil)
796 		return 0;
797 	if (e->type == ex_value && e->e.value->type == ev_integer)
798 		return e->e.value->v.integer_val;
799 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
800 		&& (e->e.symbol->type->type == ev_integer
801 			|| is_enum (e->e.symbol->type)))
802 		return e->e.symbol->s.value->v.integer_val;
803 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_var
804 		&& e->e.symbol->s.def->constant
805 		&& is_integral (e->e.symbol->s.def->type))
806 		return D_INT (e->e.symbol->s.def);
807 	internal_error (e, "not an integer constant");
808 }
809 
810 unsigned
expr_uinteger(expr_t * e)811 expr_uinteger (expr_t *e)
812 {
813 	if (e->type == ex_nil)
814 		return 0;
815 	if (e->type == ex_value && e->e.value->type == ev_uinteger)
816 		return e->e.value->v.uinteger_val;
817 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
818 		&& e->e.symbol->type->type == ev_uinteger)
819 		return e->e.symbol->s.value->v.uinteger_val;
820 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_var
821 		&& e->e.symbol->s.def->constant
822 		&& is_integral (e->e.symbol->s.def->type))
823 		return D_INT (e->e.symbol->s.def);
824 	internal_error (e, "not an unsigned constant");
825 }
826 
827 int
is_short_val(expr_t * e)828 is_short_val (expr_t *e)
829 {
830 	if (e->type == ex_nil)
831 		return 1;
832 	if (e->type == ex_value && e->e.value->type == ev_short)
833 		return 1;
834 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
835 		&& e->e.symbol->type->type == ev_short)
836 		return 1;
837 	return 0;
838 }
839 
840 short
expr_short(expr_t * e)841 expr_short (expr_t *e)
842 {
843 	if (e->type == ex_nil)
844 		return 0;
845 	if (e->type == ex_value && e->e.value->type == ev_short)
846 		return e->e.value->v.short_val;
847 	if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
848 		&& e->e.symbol->type->type == ev_short)
849 		return e->e.symbol->s.value->v.short_val;
850 	internal_error (e, "not a short constant");
851 }
852 
853 expr_t *
new_self_expr(void)854 new_self_expr (void)
855 {
856 	symbol_t   *sym;
857 
858 	sym = make_symbol (".self", &type_entity, pr.near_data, sc_extern);
859 	if (!sym->table)
860 		symtab_addsymbol (pr.symtab, sym);
861 	return new_symbol_expr (sym);
862 }
863 
864 expr_t *
new_this_expr(void)865 new_this_expr (void)
866 {
867 	symbol_t   *sym;
868 
869 	sym = make_symbol (".this", field_type (&type_id), pr.near_data, sc_extern);
870 	if (!sym->table)
871 		symtab_addsymbol (pr.symtab, sym);
872 	return new_symbol_expr (sym);
873 }
874 
875 expr_t *
new_alias_expr(type_t * type,expr_t * expr)876 new_alias_expr (type_t *type, expr_t *expr)
877 {
878 	expr_t     *alias;
879 
880 	if (expr->type == ex_value)
881 		return new_value_expr (alias_value (expr->e.value, type));
882 	alias = new_unary_expr ('A', expr);
883 	alias->e.expr.type = type;
884 	//if (expr->type == ex_uexpr && expr->e.expr.op == 'A')
885 	//	bug (alias, "aliasing an alias expression");
886 	alias->file = expr->file;
887 	alias->line = expr->line;
888 	return alias;
889 }
890 
891 static expr_t *
param_expr(const char * name,type_t * type)892 param_expr (const char *name, type_t *type)
893 {
894 	symbol_t   *sym;
895 	expr_t     *sym_expr;
896 
897 	sym = make_symbol (name, &type_param, pr.symtab->space, sc_extern);
898 	if (!sym->table)
899 		symtab_addsymbol (pr.symtab, sym);
900 	sym_expr = new_symbol_expr (sym);
901 	return new_alias_expr (type, sym_expr);
902 }
903 
904 expr_t *
new_ret_expr(type_t * type)905 new_ret_expr (type_t *type)
906 {
907 	return param_expr (".return", type);
908 }
909 
910 expr_t *
new_param_expr(type_t * type,int num)911 new_param_expr (type_t *type, int num)
912 {
913 	return param_expr (va (".param_%d", num), type);
914 }
915 
916 expr_t *
new_move_expr(expr_t * e1,expr_t * e2,type_t * type,int indirect)917 new_move_expr (expr_t *e1, expr_t *e2, type_t *type, int indirect)
918 {
919 	expr_t     *e = new_binary_expr (indirect ? 'M' : 'm', e1, e2);
920 	e->e.expr.type = type;
921 	return e;
922 }
923 
924 expr_t *
append_expr(expr_t * block,expr_t * e)925 append_expr (expr_t *block, expr_t *e)
926 {
927 	if (block->type != ex_block)
928 		internal_error (block, "not a block expression");
929 
930 	if (!e || e->type == ex_error)
931 		return block;
932 
933 	if (e->next)
934 		internal_error (e, "append_expr: expr loop detected");
935 
936 	*block->e.block.tail = e;
937 	block->e.block.tail = &e->next;
938 
939 	return block;
940 }
941 
942 static symbol_t *
get_struct_field(type_t * t1,expr_t * e1,expr_t * e2)943 get_struct_field (type_t *t1, expr_t *e1, expr_t *e2)
944 {
945 	symtab_t   *strct = t1->t.symtab;
946 	symbol_t   *sym = e2->e.symbol;//FIXME need to check
947 	symbol_t   *field;
948 
949 	if (!strct) {
950 		error (e1, "dereferencing pointer to incomplete type");
951 		return 0;
952 	}
953 	field = symtab_lookup (strct, sym->name);
954 	if (!field && t1 != &type_entity) {
955 		error (e2, "'%s' has no member named '%s'", t1->name + 4, sym->name);
956 		e1->type = ex_error;
957 	}
958 	return field;
959 }
960 
961 static expr_t *
field_expr(expr_t * e1,expr_t * e2)962 field_expr (expr_t *e1, expr_t *e2)
963 {
964 	type_t     *t1, *t2;
965 	expr_t     *e;
966 
967 	if (e1->type == ex_error)
968 		return e1;
969 	t1 = get_type (e1);
970 	if (t1->type == ev_entity) {
971 		symbol_t   *field = 0;
972 
973 		if (e2->type == ex_symbol)
974 			field = get_struct_field (&type_entity, e1, e2);
975 		if (field) {
976 			e2 = new_field_expr (0, field->type, field->s.def);
977 			e = new_binary_expr ('.', e1, e2);
978 			e->e.expr.type = field->type;
979 			return e;
980 		} else {
981 			t2 = get_type (e2);
982 			if (e2->type == ex_error)
983 				return e2;
984 			if (t2->type == ev_field) {
985 				e = new_binary_expr ('.', e1, e2);
986 				e->e.expr.type = t2->t.fldptr.type;
987 				return e;
988 			}
989 		}
990 	} else if (t1->type == ev_pointer) {
991 		if (is_struct (t1->t.fldptr.type)) {
992 			symbol_t   *field;
993 
994 			field = get_struct_field (t1->t.fldptr.type, e1, e2);
995 			if (!field)
996 				return e1;
997 
998 			e2->type = ex_value;
999 			e2->e.value = new_short_val (field->s.offset);
1000 			e = new_binary_expr ('&', e1, e2);
1001 			e->e.expr.type = pointer_type (field->type);
1002 			return unary_expr ('.', e);
1003 		} else if (obj_is_class (t1->t.fldptr.type)) {
1004 			class_t    *class = t1->t.fldptr.type->t.class;
1005 			symbol_t   *sym = e2->e.symbol;//FIXME need to check
1006 			symbol_t   *ivar;
1007 
1008 			ivar = class_find_ivar (class, vis_protected, sym->name);
1009 			if (!ivar)
1010 				return new_error_expr ();
1011 			e2->type = ex_value;
1012 			e2->e.value = new_short_val (ivar->s.offset);
1013 			e = new_binary_expr ('&', e1, e2);
1014 			e->e.expr.type = pointer_type (ivar->type);
1015 			return unary_expr ('.', e);
1016 		}
1017 	} else if (t1->type == ev_vector || t1->type == ev_quat
1018 			   || is_struct (t1)) {
1019 		symbol_t   *field;
1020 
1021 		field = get_struct_field (t1, e1, e2);
1022 		if (!field)
1023 			return e1;
1024 
1025 		if (e1->type == ex_expr && e1->e.expr.op == '.'
1026 			&& get_type (e1->e.expr.e1) == &type_entity) {
1027 			// undo the . expression
1028 			e2 = e1->e.expr.e2;
1029 			e1 = e1->e.expr.e1;
1030 			// offset the field expresion
1031 			if (e2->type == ex_symbol) {
1032 				symbol_t   *sym;
1033 				def_t      *def;
1034 				sym = symtab_lookup (pr.entity_fields, e2->e.symbol->name);
1035 				if (!sym) {
1036 					internal_error (e2, "failed to find entity field %s",
1037 									e2->e.symbol->name);
1038 				}
1039 				def = sym->s.def;
1040 				e2 = new_field_expr (0, field->type, def);
1041 			} else if (e2->type != ex_value || e2->e.value->type != ev_field) {
1042 				internal_error (e2, "unexpected field exression");
1043 			}
1044 			e2->e.value = new_field_val (e2->e.value->v.pointer.val + field->s.offset, field->type, e2->e.value->v.pointer.def);
1045 			// create a new . expression
1046 			return field_expr (e1, e2);
1047 		} else {
1048 			e2->type = ex_value;
1049 			e2->e.value = new_short_val (field->s.offset);
1050 			e = address_expr (e1, e2, field->type);
1051 			return unary_expr ('.', e);
1052 		}
1053 	} else if (obj_is_class (t1)) {
1054 		//Class instance variables aren't allowed and thus declaring one
1055 		//is treated as an error, so this is a follow-on error.
1056 		return error (e1, "class instance access");
1057 	}
1058 	return type_mismatch (e1, e2, '.');
1059 }
1060 
1061 expr_t *
test_expr(expr_t * e)1062 test_expr (expr_t *e)
1063 {
1064 	static float zero[4] = {0, 0, 0, 0};
1065 	expr_t     *new = 0;
1066 	type_t     *type;
1067 
1068 	if (e->type == ex_error)
1069 		return e;
1070 
1071 	type = get_type (e);
1072 	if (e->type == ex_error)
1073 		return e;
1074 	switch (type->type) {
1075 		case ev_type_count:
1076 			internal_error (e, 0);
1077 		case ev_void:
1078 			if (options.traditional) {
1079 				if (options.warnings.traditional)
1080 					warning (e, "void has no value");
1081 				return e;
1082 			}
1083 			return error (e, "void has no value");
1084 		case ev_string:
1085 			new = new_string_expr (0);
1086 			break;
1087 		case ev_uinteger:
1088 		case ev_integer:
1089 		case ev_short:
1090 			if (type_default != &type_integer)
1091 				return new_alias_expr (type_default, e);
1092 			return e;
1093 		case ev_float:
1094 			if (options.code.fast_float
1095 				|| options.code.progsversion == PROG_ID_VERSION) {
1096 				if (type_default != &type_float)
1097 					return new_alias_expr (type_default, e);
1098 				return e;
1099 			}
1100 			new = new_float_expr (0);
1101 			break;
1102 		case ev_vector:
1103 			new = new_vector_expr (zero);
1104 			break;
1105 		case ev_entity:
1106 			return new_alias_expr (type_default, e);
1107 		case ev_field:
1108 			return new_alias_expr (type_default, e);
1109 		case ev_func:
1110 			return new_alias_expr (type_default, e);
1111 		case ev_pointer:
1112 			return new_alias_expr (type_default, e);
1113 		case ev_quat:
1114 			new = new_quaternion_expr (zero);
1115 			break;
1116 		case ev_invalid:
1117 			if (is_enum (type)) {
1118 				new = new_nil_expr ();
1119 				break;
1120 			}
1121 			return test_error (e, get_type (e));
1122 	}
1123 	new->line = e->line;
1124 	new->file = e->file;
1125 	new = binary_expr (NE, e, new);
1126 	new->line = e->line;
1127 	new->file = e->file;
1128 	return fold_constants (new);
1129 }
1130 
1131 void
backpatch(ex_list_t * list,expr_t * label)1132 backpatch (ex_list_t *list, expr_t *label)
1133 {
1134 	int         i;
1135 	expr_t     *e;
1136 
1137 	if (!list)
1138 		return;
1139 	if (!label || label->type != ex_label)
1140 		internal_error (label, "not a label");
1141 
1142 	for (i = 0; i < list->size; i++) {
1143 		e = list->e[i];
1144 		if (e->type == ex_uexpr && e->e.expr.op == 'g')
1145 			e->e.expr.e1 = label;
1146 		else if (e->type == ex_expr && (e->e.expr.op == 'i'
1147 										|| e->e.expr.op == 'n'))
1148 			e->e.expr.e2 = label;
1149 		else {
1150 			internal_error (e, 0);
1151 		}
1152 		label->e.label.used++;
1153 	}
1154 }
1155 
1156 static ex_list_t *
merge(ex_list_t * l1,ex_list_t * l2)1157 merge (ex_list_t *l1, ex_list_t *l2)
1158 {
1159 	ex_list_t  *m;
1160 
1161 	if (!l1 && !l2)
1162 		internal_error (0, 0);
1163 	if (!l2)
1164 		return l1;
1165 	if (!l1)
1166 		return l2;
1167 	m = malloc ((size_t)&((ex_list_t *)0)->e[l1->size + l2->size]);
1168 	m->size = l1->size + l2->size;
1169 	memcpy (m->e, l1->e, l1->size * sizeof (expr_t *));
1170 	memcpy (m->e + l1->size, l2->e, l2->size * sizeof (expr_t *));
1171 	return m;
1172 }
1173 
1174 static ex_list_t *
make_list(expr_t * e)1175 make_list (expr_t *e)
1176 {
1177 	ex_list_t  *m;
1178 
1179 	m = malloc ((size_t)&((ex_list_t *) 0)->e[1]);
1180 	m->size = 1;
1181 	m->e[0] = e;
1182 	return m;
1183 }
1184 
1185 expr_t *
convert_bool(expr_t * e,int block)1186 convert_bool (expr_t *e, int block)
1187 {
1188 	expr_t     *b;
1189 
1190 	if (e->type == ex_expr && (e->e.expr.op == '=' || e->e.expr.op == PAS)) {
1191 		expr_t     *src;
1192 		if (!e->paren && options.warnings.precedence)
1193 			warning (e, "suggest parentheses around assignment "
1194 					 "used as truth value");
1195 		src = e->e.expr.e2;
1196 		if (src->type == ex_block) {
1197 			src = new_temp_def_expr (get_type (src));
1198 			e = new_binary_expr (e->e.expr.op, e->e.expr.e1,
1199 								 assign_expr (src, e->e.expr.e2));
1200 		}
1201 		b = convert_bool (src, 1);
1202 		if (b->type == ex_error)
1203 			return b;
1204 		// insert the assignment into the bool's block
1205 		e->next = b->e.bool.e->e.block.head;
1206 		b->e.bool.e->e.block.head = e;
1207 		if (b->e.bool.e->e.block.tail == &b->e.bool.e->e.block.head) {
1208 			// shouldn't happen, but just in case
1209 			b->e.bool.e->e.block.tail = &e->next;
1210 		}
1211 		return b;
1212 	}
1213 
1214 	if (e->type == ex_uexpr && e->e.expr.op == '!') {
1215 		e = convert_bool (e->e.expr.e1, 0);
1216 		if (e->type == ex_error)
1217 			return e;
1218 		e = unary_expr ('!', e);
1219 	}
1220 	if (e->type != ex_bool) {
1221 		e = test_expr (e);
1222 		if (e->type == ex_error)
1223 			return e;
1224 		if (is_integer_val (e)) {
1225 			b = goto_expr (0);
1226 			if (expr_integer (e))
1227 				e = new_bool_expr (make_list (b), 0, b);
1228 			else
1229 				e = new_bool_expr (0, make_list (b), b);
1230 		} else {
1231 			b = new_block_expr ();
1232 			append_expr (b, branch_expr ('i', e, 0));
1233 			append_expr (b, goto_expr (0));
1234 			e = new_bool_expr (make_list (b->e.block.head),
1235 							   make_list (b->e.block.head->next), b);
1236 		}
1237 	}
1238 	if (block && e->e.bool.e->type != ex_block) {
1239 		expr_t     *block = new_block_expr ();
1240 		append_expr (block, e->e.bool.e);
1241 		e->e.bool.e = block;
1242 	}
1243 	return e;
1244 }
1245 
1246 static expr_t *
convert_from_bool(expr_t * e,type_t * type)1247 convert_from_bool (expr_t *e, type_t *type)
1248 {
1249 	expr_t     *zero;
1250 	expr_t     *one;
1251 	expr_t     *cond;
1252 
1253 	if (type == &type_float) {
1254 		one = new_float_expr (1);
1255 		zero = new_float_expr (0);
1256 	} else if (type == &type_integer) {
1257 		one = new_integer_expr (1);
1258 		zero = new_integer_expr (0);
1259 	} else if (is_enum (type) && enum_as_bool (type, &zero, &one)) {
1260 		// don't need to do anything
1261 	} else if (type == &type_uinteger) {
1262 		one = new_uinteger_expr (1);
1263 		zero = new_uinteger_expr (0);
1264 	} else {
1265 		return error (e, "can't convert from bool value");
1266 	}
1267 	cond = new_expr ();
1268 	*cond = *e;
1269 	cond->next = 0;
1270 
1271 	cond = conditional_expr (cond, one, zero);
1272 	e->type = cond->type;
1273 	e->e = cond->e;
1274 	return e;
1275 }
1276 
1277 expr_t *
bool_expr(int op,expr_t * label,expr_t * e1,expr_t * e2)1278 bool_expr (int op, expr_t *label, expr_t *e1, expr_t *e2)
1279 {
1280 	expr_t     *block;
1281 
1282 	if (!options.code.short_circuit)
1283 		return binary_expr (op, e1, e2);
1284 
1285 	e1 = convert_bool (e1, 0);
1286 	if (e1->type == ex_error)
1287 		return e1;
1288 
1289 	e2 = convert_bool (e2, 0);
1290 	if (e2->type == ex_error)
1291 		return e2;
1292 
1293 	block = new_block_expr ();
1294 	append_expr (block, e1);
1295 	append_expr (block, label);
1296 	append_expr (block, e2);
1297 
1298 	switch (op) {
1299 		case OR:
1300 			backpatch (e1->e.bool.false_list, label);
1301 			return new_bool_expr (merge (e1->e.bool.true_list,
1302 										 e2->e.bool.true_list),
1303 								  e2->e.bool.false_list, block);
1304 			break;
1305 		case AND:
1306 			backpatch (e1->e.bool.true_list, label);
1307 			return new_bool_expr (e2->e.bool.true_list,
1308 								  merge (e1->e.bool.false_list,
1309 										 e2->e.bool.false_list), block);
1310 			break;
1311 	}
1312 	internal_error (e1, 0);
1313 }
1314 
1315 void
convert_int(expr_t * e)1316 convert_int (expr_t *e)
1317 {
1318 	float       float_val = expr_integer (e);
1319 	e->type = ex_value;
1320 	e->e.value = new_float_val (float_val);
1321 }
1322 
1323 void
convert_short(expr_t * e)1324 convert_short (expr_t *e)
1325 {
1326 	float       float_val = expr_short (e);
1327 	e->type = ex_value;
1328 	e->e.value = new_float_val (float_val);
1329 }
1330 
1331 void
convert_short_int(expr_t * e)1332 convert_short_int (expr_t *e)
1333 {
1334 	float       integer_val = expr_short (e);
1335 	e->type = ex_value;
1336 	e->e.value = new_integer_val (integer_val);
1337 }
1338 
1339 void
convert_nil(expr_t * e,type_t * t)1340 convert_nil (expr_t *e, type_t *t)
1341 {
1342 	e->type = ex_value;
1343 	e->e.value = new_nil_val (t);
1344 }
1345 
1346 int
is_compare(int op)1347 is_compare (int op)
1348 {
1349 	if (op == EQ || op == NE || op == LE || op == GE || op == LT || op == GT
1350 		|| op == '>' || op == '<')
1351 		return 1;
1352 	return 0;
1353 }
1354 
1355 int
is_math_op(int op)1356 is_math_op (int op)
1357 {
1358 	if (op == '*' || op == '/' || op == '+' || op == '-')
1359 		return 1;
1360 	return 0;
1361 }
1362 
1363 int
is_logic(int op)1364 is_logic (int op)
1365 {
1366 	if (op == OR || op == AND)
1367 		return 1;
1368 	return 0;
1369 }
1370 
1371 static expr_t *
check_precedence(int op,expr_t * e1,expr_t * e2)1372 check_precedence (int op, expr_t *e1, expr_t *e2)
1373 {
1374 	if (e1->type == ex_uexpr && e1->e.expr.op == '!' && !e1->paren) {
1375 		if (options.traditional) {
1376 			if (op != AND && op != OR && op != '=') {
1377 				notice (e1, "precedence of `!' and `%s' inverted for "
1378 							"traditional code", get_op_string (op));
1379 				e1->e.expr.e1->paren = 1;
1380 				return unary_expr ('!', binary_expr (op, e1->e.expr.e1, e2));
1381 			}
1382 		} else if (op == '&' || op == '|') {
1383 			if (options.warnings.precedence)
1384 				warning (e1, "ambiguous logic. Suggest explicit parentheses "
1385 						 "with expressions involving ! and %s",
1386 						 get_op_string (op));
1387 		}
1388 	}
1389 	if (options.traditional) {
1390 		if (e2->type == ex_expr && !e2->paren) {
1391 			if (((op == '&' || op == '|')
1392 				 && (is_math_op (e2->e.expr.op) || is_compare (e2->e.expr.op)))
1393 				|| (op == '='
1394 					&& (e2->e.expr.op == OR || e2->e.expr.op == AND))) {
1395 				notice (e1, "precedence of `%s' and `%s' inverted for "
1396 							"traditional code", get_op_string (op),
1397 							get_op_string (e2->e.expr.op));
1398 				e1 = binary_expr (op, e1, e2->e.expr.e1);
1399 				e1->paren = 1;
1400 				return binary_expr (e2->e.expr.op, e1, e2->e.expr.e2);
1401 			}
1402 			if (((op == EQ || op == NE) && is_compare (e2->e.expr.op))
1403 				|| (op == OR && e2->e.expr.op == AND)
1404 				|| (op == '|' && e2->e.expr.op == '&')) {
1405 				notice (e1, "precedence of `%s' raised to `%s' for "
1406 							"traditional code", get_op_string (op),
1407 							get_op_string (e2->e.expr.op));
1408 				e1 = binary_expr (op, e1, e2->e.expr.e1);
1409 				e1->paren = 1;
1410 				return binary_expr (e2->e.expr.op, e1, e2->e.expr.e2);
1411 			}
1412 		} else if (e1->type == ex_expr && !e1->paren) {
1413 			if (((op == '&' || op == '|')
1414 				 && (is_math_op (e1->e.expr.op) || is_compare (e1->e.expr.op)))
1415 				|| (op == '='
1416 					&& (e1->e.expr.op == OR || e1->e.expr.op == AND))) {
1417 				notice (e1, "precedence of `%s' and `%s' inverted for "
1418 							"traditional code", get_op_string (op),
1419 							get_op_string (e1->e.expr.op));
1420 				e2 = binary_expr (op, e1->e.expr.e2, e2);
1421 				e2->paren = 1;
1422 				return binary_expr (e1->e.expr.op, e1->e.expr.e1, e2);
1423 			}
1424 		}
1425 	} else {
1426 		if (e2->type == ex_expr && !e2->paren) {
1427 			if ((op == '&' || op == '|' || op == '^')
1428 				&& (is_math_op (e2->e.expr.op)
1429 					|| is_compare (e2->e.expr.op))) {
1430 				if (options.warnings.precedence)
1431 					warning (e2, "suggest parentheses around %s in "
1432 							 "operand of %c",
1433 							 is_compare (e2->e.expr.op)
1434 							 		? "comparison"
1435 							 		: get_op_string (e2->e.expr.op),
1436 							 op);
1437 			}
1438 		}
1439 		if (e1->type == ex_expr && !e1->paren) {
1440 			if ((op == '&' || op == '|' || op == '^')
1441 				&& (is_math_op (e1->e.expr.op)
1442 					|| is_compare (e1->e.expr.op))) {
1443 				if (options.warnings.precedence)
1444 					warning (e1, "suggest parentheses around %s in "
1445 							 "operand of %c",
1446 							 is_compare (e1->e.expr.op)
1447 							 		? "comparison"
1448 							 		: get_op_string (e1->e.expr.op),
1449 							 op);
1450 			}
1451 		}
1452 	}
1453 	return 0;
1454 }
1455 
1456 static int
has_function_call(expr_t * e)1457 has_function_call (expr_t *e)
1458 {
1459 	switch (e->type) {
1460 		case ex_bool:
1461 			return has_function_call (e->e.bool.e);
1462 		case ex_block:
1463 			if (e->e.block.is_call)
1464 				return 1;
1465 			for (e = e->e.block.head; e; e = e->next)
1466 				if (has_function_call (e))
1467 					return 1;
1468 			return 0;
1469 		case ex_expr:
1470 			if (e->e.expr.op == 'c')
1471 				return 1;
1472 			return (has_function_call (e->e.expr.e1)
1473 					|| has_function_call (e->e.expr.e2));
1474 		case ex_uexpr:
1475 			if (e->e.expr.op != 'g')
1476 				return has_function_call (e->e.expr.e1);
1477 		default:
1478 			return 0;
1479 	}
1480 }
1481 
1482 expr_t *
binary_expr(int op,expr_t * e1,expr_t * e2)1483 binary_expr (int op, expr_t *e1, expr_t *e2)
1484 {
1485 	type_t     *t1, *t2;
1486 	type_t     *type = 0;
1487 	expr_t     *e;
1488 
1489 	if (e1->type == ex_error)
1490 		return e1;
1491 	if (e2->type == ex_error)
1492 		return e2;
1493 
1494 	convert_name (e1);
1495 	if (e1->type == ex_block && e1->e.block.is_call
1496 		&& has_function_call (e2) && e1->e.block.result) {
1497 		e = new_temp_def_expr (get_type (e1->e.block.result));
1498 		e1 = assign_expr (e, e1);
1499 	}
1500 
1501 	if (op == '.')
1502 		return field_expr (e1, e2);
1503 
1504 	convert_name (e2);
1505 	if (op == OR || op == AND) {
1506 		e1 = test_expr (e1);
1507 		e2 = test_expr (e2);
1508 	}
1509 
1510 	if (e1->type == ex_error)
1511 		return e1;
1512 	if (e2->type == ex_error)
1513 		return e2;
1514 	t1 = get_type (e1);
1515 	t2 = get_type (e2);
1516 	if (!t1 || !t2)
1517 		internal_error (e1, 0);
1518 	if (op == EQ || op == NE) {
1519 		if (e1->type == ex_nil) {
1520 			t1 = t2;
1521 			convert_nil (e1, t1);
1522 		} else if (e2->type == ex_nil) {
1523 			t2 = t1;
1524 			convert_nil (e2, t2);
1525 		}
1526 	}
1527 
1528 	if (e1->type == ex_bool)
1529 		e1 = convert_from_bool (e1, t2);
1530 
1531 	if (e2->type == ex_bool)
1532 		e2 = convert_from_bool (e2, t1);
1533 
1534 	if ((e = check_precedence (op, e1, e2)))
1535 		return e;
1536 
1537 	type = t1;
1538 
1539 	if (is_compare (op) || is_logic (op)) {
1540 		if (options.code.progsversion > PROG_ID_VERSION)
1541 			type = &type_integer;
1542 		else
1543 			type = &type_float;
1544 	} else if (op == '*' && t1 == &type_vector && t2 == &type_vector) {
1545 		type = &type_float;
1546 	}
1547 	if (!type)
1548 		internal_error (e1, 0);
1549 
1550 	if (options.code.progsversion == PROG_ID_VERSION) {
1551 		switch (op) {
1552 			case '%':
1553 				{
1554 					expr_t     *tmp1, *tmp2, *tmp3, *tmp4, *t1, *t2;
1555 					e = new_block_expr ();
1556 					t1 = new_temp_def_expr (&type_float);
1557 					t2 = new_temp_def_expr (&type_float);
1558 					tmp1 = new_temp_def_expr (&type_float);
1559 					tmp2 = new_temp_def_expr (&type_float);
1560 					tmp3 = new_temp_def_expr (&type_float);
1561 					tmp4 = new_temp_def_expr (&type_float);
1562 
1563 					append_expr (e, assign_expr (t1, e1));
1564 					e1 = binary_expr ('&', t1, t1);
1565 					append_expr (e, assign_expr (tmp1, e1));
1566 
1567 					append_expr (e, assign_expr (t2, e2));
1568 					e2 = binary_expr ('&', t2, t2);
1569 					append_expr (e, assign_expr (tmp2, e2));
1570 
1571 					e1 = binary_expr ('/', tmp1, tmp2);
1572 					append_expr (e, assign_expr (tmp3, e1));
1573 
1574 					e2 = binary_expr ('&', tmp3, tmp3);
1575 					append_expr (e, assign_expr (tmp4, e2));
1576 
1577 					e1 = binary_expr ('*', tmp2, tmp4);
1578 					e2 = binary_expr ('-', tmp1, e1);
1579 					e->e.block.result = e2;
1580 					return e;
1581 				}
1582 				break;
1583 		}
1584 	}
1585 	e = new_binary_expr (op, e1, e2);
1586 	e->e.expr.type = type;
1587 	return e;
1588 }
1589 
1590 expr_t *
asx_expr(int op,expr_t * e1,expr_t * e2)1591 asx_expr (int op, expr_t *e1, expr_t *e2)
1592 {
1593 	if (e1->type == ex_error)
1594 		return e1;
1595 	else if (e2->type == ex_error)
1596 		return e2;
1597 	else {
1598 		expr_t     *e = new_expr ();
1599 
1600 		*e = *e1;
1601 		e2->paren = 1;
1602 		return assign_expr (e, binary_expr (op, e1, e2));
1603 	}
1604 }
1605 
1606 expr_t *
unary_expr(int op,expr_t * e)1607 unary_expr (int op, expr_t *e)
1608 {
1609 	vec3_t      v;
1610 	quat_t      q;
1611 	const char *s;
1612 
1613 	convert_name (e);
1614 	if (e->type == ex_error)
1615 		return e;
1616 	switch (op) {
1617 		case '-':
1618 			if (!is_math (get_type (e)))
1619 				return error (e, "invalid type for unary -");
1620 			if (is_constant (e)) {
1621 				switch (extract_type (e)) {
1622 					case ev_string:
1623 					case ev_entity:
1624 					case ev_field:
1625 					case ev_func:
1626 					case ev_pointer:
1627 						internal_error (e, "type check failed!");
1628 					case ev_float:
1629 						return new_float_expr (-expr_float (e));
1630 					case ev_vector:
1631 						VectorNegate (expr_vector (e), v);
1632 						return new_vector_expr (v);
1633 					case ev_quat:
1634 						QuatNegate (expr_vector (e), q);
1635 						return new_vector_expr (q);
1636 					case ev_integer:
1637 						return new_integer_expr (-expr_integer (e));
1638 					case ev_uinteger:
1639 						return new_uinteger_expr (-expr_uinteger (e));
1640 					case ev_short:
1641 						return new_short_expr (-expr_short (e));
1642 					case ev_invalid:
1643 					case ev_type_count:
1644 					case ev_void:
1645 						break;
1646 				}
1647 				internal_error (e, "weird expression type");
1648 			}
1649 			switch (e->type) {
1650 				case ex_value:	// should be handled above
1651 				case ex_error:
1652 				case ex_label:
1653 				case ex_labelref:
1654 				case ex_state:
1655 					internal_error (e, 0);
1656 				case ex_uexpr:
1657 					if (e->e.expr.op == '-')
1658 						return e->e.expr.e1;
1659 				case ex_block:
1660 					if (!e->e.block.result)
1661 						return error (e, "invalid type for unary -");
1662 				case ex_expr:
1663 				case ex_bool:
1664 				case ex_temp:
1665 					{
1666 						expr_t     *n = new_unary_expr (op, e);
1667 
1668 						n->e.expr.type = e->e.expr.type;
1669 						return n;
1670 					}
1671 				case ex_symbol:
1672 					{
1673 						expr_t     *n = new_unary_expr (op, e);
1674 
1675 						n->e.expr.type = e->e.symbol->type;
1676 						return n;
1677 					}
1678 				case ex_nil:
1679 					return error (e, "invalid type for unary -");
1680 			}
1681 			break;
1682 		case '!':
1683 			if (is_constant (e)) {
1684 				switch (extract_type (e)) {
1685 					case ev_entity:
1686 					case ev_field:
1687 					case ev_func:
1688 					case ev_pointer:
1689 						internal_error (e, 0);
1690 					case ev_string:
1691 						s = expr_string (e);
1692 						return new_integer_expr (!s || !s[0]);
1693 					case ev_float:
1694 						return new_integer_expr (!expr_float (e));
1695 					case ev_vector:
1696 						return new_integer_expr (!VectorIsZero (expr_vector (e)));
1697 					case ev_quat:
1698 						return new_integer_expr (!QuatIsZero (expr_quaternion (e)));
1699 					case ev_integer:
1700 						return new_integer_expr (!expr_integer (e));
1701 					case ev_uinteger:
1702 						return new_uinteger_expr (!expr_uinteger (e));
1703 					case ev_short:
1704 						return new_short_expr (!expr_short (e));
1705 					case ev_invalid:
1706 					case ev_type_count:
1707 					case ev_void:
1708 						break;
1709 				}
1710 				internal_error (e, "weird expression type");
1711 			}
1712 			switch (e->type) {
1713 				case ex_value:	// should be handled above
1714 				case ex_error:
1715 				case ex_label:
1716 				case ex_labelref:
1717 				case ex_state:
1718 					internal_error (e, 0);
1719 				case ex_bool:
1720 					return new_bool_expr (e->e.bool.false_list,
1721 										  e->e.bool.true_list, e);
1722 				case ex_block:
1723 					if (!e->e.block.result)
1724 						return error (e, "invalid type for unary !");
1725 				case ex_uexpr:
1726 				case ex_expr:
1727 				case ex_symbol:
1728 				case ex_temp:
1729 					{
1730 						expr_t     *n = new_unary_expr (op, e);
1731 
1732 						if (options.code.progsversion > PROG_ID_VERSION)
1733 							n->e.expr.type = &type_integer;
1734 						else
1735 							n->e.expr.type = &type_float;
1736 						return n;
1737 					}
1738 				case ex_nil:
1739 					return error (e, "invalid type for unary !");
1740 			}
1741 			break;
1742 		case '~':
1743 			if (is_constant (e)) {
1744 				switch (extract_type (e)) {
1745 					case ev_string:
1746 					case ev_entity:
1747 					case ev_field:
1748 					case ev_func:
1749 					case ev_pointer:
1750 					case ev_vector:
1751 						return error (e, "invalid type for unary ~");
1752 					case ev_float:
1753 						return new_float_expr (~(int) expr_float (e));
1754 					case ev_quat:
1755 						QuatConj (expr_vector (e), q);
1756 						return new_vector_expr (q);
1757 					case ev_integer:
1758 						return new_integer_expr (~expr_integer (e));
1759 					case ev_uinteger:
1760 						return new_uinteger_expr (~expr_uinteger (e));
1761 					case ev_short:
1762 						return new_short_expr (~expr_short (e));
1763 					case ev_invalid:
1764 					case ev_type_count:
1765 					case ev_void:
1766 						break;
1767 				}
1768 				internal_error (e, "weird expression type");
1769 			}
1770 			switch (e->type) {
1771 				case ex_value:	// should be handled above
1772 				case ex_error:
1773 				case ex_label:
1774 				case ex_labelref:
1775 				case ex_state:
1776 					internal_error (e, 0);
1777 				case ex_uexpr:
1778 					if (e->e.expr.op == '~')
1779 						return e->e.expr.e1;
1780 					goto bitnot_expr;
1781 				case ex_block:
1782 					if (!e->e.block.result)
1783 						return error (e, "invalid type for unary ~");
1784 					goto bitnot_expr;
1785 				case ex_expr:
1786 				case ex_bool:
1787 				case ex_symbol:
1788 				case ex_temp:
1789 bitnot_expr:
1790 					if (options.code.progsversion == PROG_ID_VERSION) {
1791 						expr_t     *n1 = new_integer_expr (-1);
1792 						return binary_expr ('-', n1, e);
1793 					} else {
1794 						expr_t     *n = new_unary_expr (op, e);
1795 						type_t     *t = get_type (e);
1796 
1797 						if (t != &type_integer && t != &type_float
1798 							&& t != &type_quaternion)
1799 							return error (e, "invalid type for unary ~");
1800 						n->e.expr.type = t;
1801 						return n;
1802 					}
1803 				case ex_nil:
1804 					return error (e, "invalid type for unary ~");
1805 			}
1806 			break;
1807 		case '.':
1808 			if (extract_type (e) != ev_pointer)
1809 				return error (e, "invalid type for unary .");
1810 			e = new_unary_expr ('.', e);
1811 			e->e.expr.type = get_type (e->e.expr.e1)->t.fldptr.type;
1812 			return e;
1813 		case '+':
1814 			if (!is_math (get_type (e)))
1815 				return error (e, "invalid type for unary +");
1816 			return e;
1817 	}
1818 	internal_error (e, 0);
1819 }
1820 
1821 expr_t *
build_function_call(expr_t * fexpr,type_t * ftype,expr_t * params)1822 build_function_call (expr_t *fexpr, type_t *ftype, expr_t *params)
1823 {
1824 	expr_t     *e;
1825 	int         arg_count = 0, parm_count = 0;
1826 	int         i;
1827 	expr_t     *args = 0, **a = &args;
1828 	type_t     *arg_types[MAX_PARMS];
1829 	expr_t     *arg_exprs[MAX_PARMS][2];
1830 	int         arg_expr_count = 0;
1831 	expr_t     *call;
1832 	expr_t     *err = 0;
1833 
1834 	for (e = params; e; e = e->next) {
1835 		if (e->type == ex_error)
1836 			return e;
1837 		arg_count++;
1838 	}
1839 
1840 	if (arg_count > MAX_PARMS) {
1841 		return error (fexpr, "more than %d parameters", MAX_PARMS);
1842 	}
1843 	if (ftype->t.func.num_params < -1) {
1844 		if (-arg_count > ftype->t.func.num_params + 1) {
1845 			if (!options.traditional)
1846 				return error (fexpr, "too few arguments");
1847 			if (options.warnings.traditional)
1848 				warning (fexpr, "too few arguments");
1849 		}
1850 		parm_count = -ftype->t.func.num_params - 1;
1851 	} else if (ftype->t.func.num_params >= 0) {
1852 		if (arg_count > ftype->t.func.num_params) {
1853 			return error (fexpr, "too many arguments");
1854 		} else if (arg_count < ftype->t.func.num_params) {
1855 			if (!options.traditional)
1856 				return error (fexpr, "too few arguments");
1857 			if (options.warnings.traditional)
1858 				warning (fexpr, "too few arguments");
1859 		}
1860 		parm_count = ftype->t.func.num_params;
1861 	}
1862 	for (i = arg_count - 1, e = params; i >= 0; i--, e = e->next) {
1863 		type_t     *t = get_type (e);
1864 
1865 		if (!type_size (t))
1866 			err = error (e, "type of formal parameter %d is incomplete",
1867 						 i + 1);
1868 		if (type_size (t) > type_size (&type_param))
1869 			err = error (e, "formal parameter %d is too large to be passed by"
1870 						 " value", i + 1);
1871 		if (ftype->t.func.param_types[i] == &type_float
1872 			&& is_integer_val (e)) {
1873 			convert_int (e);
1874 			t = &type_float;
1875 		}
1876 		if (i < parm_count) {
1877 			if (e->type == ex_nil)
1878 				convert_nil (e, t = ftype->t.func.param_types[i]);
1879 			if (e->type == ex_bool)
1880 				convert_from_bool (e, ftype->t.func.param_types[i]);
1881 			if (e->type == ex_error)
1882 				return e;
1883 			if (!type_assignable (ftype->t.func.param_types[i], t)) {
1884 				err = param_mismatch (e, i + 1, fexpr->e.symbol->name,
1885 									  ftype->t.func.param_types[i], t);
1886 			}
1887 			t = ftype->t.func.param_types[i];
1888 		} else {
1889 			if (e->type == ex_nil)
1890 				convert_nil (e, t = type_nil);
1891 			if (e->type == ex_bool)
1892 				convert_from_bool (e, get_type (e));
1893 			if (is_integer_val (e)
1894 				&& options.code.progsversion == PROG_ID_VERSION)
1895 				convert_int (e);
1896 			if (is_integer_val (e) && options.warnings.vararg_integer)
1897 				warning (e, "passing integer constant into ... function");
1898 		}
1899 		arg_types[arg_count - 1 - i] = t;
1900 	}
1901 	if (err)
1902 		return err;
1903 
1904 	call = new_block_expr ();
1905 	call->e.block.is_call = 1;
1906 	for (e = params, i = 0; e; e = e->next, i++) {
1907 		if (has_function_call (e)) {
1908 			*a = new_temp_def_expr (arg_types[i]);
1909 			arg_exprs[arg_expr_count][0] = cast_expr (arg_types[i], e);
1910 			arg_exprs[arg_expr_count][1] = *a;
1911 			arg_expr_count++;
1912 		} else {
1913 			*a = cast_expr (arg_types[i], e);
1914 		}
1915 		a = &(*a)->next;
1916 	}
1917 	for (i = 0; i < arg_expr_count - 1; i++) {
1918 		append_expr (call, assign_expr (arg_exprs[i][1], arg_exprs[i][0]));
1919 	}
1920 	if (arg_expr_count) {
1921 		e = assign_expr (arg_exprs[arg_expr_count - 1][1],
1922 						 arg_exprs[arg_expr_count - 1][0]);
1923 		append_expr (call, e);
1924 	}
1925 	e = new_binary_expr ('c', fexpr, args);
1926 	e->e.expr.type = ftype->t.func.type;
1927 	append_expr (call, e);
1928 	if (ftype->t.func.type != &type_void) {
1929 		call->e.block.result = new_ret_expr (ftype->t.func.type);
1930 	} else if (options.traditional) {
1931 		call->e.block.result = new_ret_expr (&type_float);
1932 	}
1933 	return call;
1934 }
1935 
1936 expr_t *
function_expr(expr_t * fexpr,expr_t * params)1937 function_expr (expr_t *fexpr, expr_t *params)
1938 {
1939 	type_t     *ftype;
1940 
1941 	find_function (fexpr, params);
1942 	ftype = get_type (fexpr);
1943 
1944 	if (fexpr->type == ex_error)
1945 		return fexpr;
1946 	if (ftype->type != ev_func) {
1947 		if (fexpr->type == ex_symbol)
1948 			return error (fexpr, "Called object \"%s\" is not a function",
1949 						  fexpr->e.symbol->name);
1950 		else
1951 			return error (fexpr, "Called object is not a function");
1952 	}
1953 
1954 	if (fexpr->type == ex_symbol && params && is_string_val (params)) {
1955 		// FIXME eww, I hate this, but it's needed :(
1956 		// FIXME make a qc hook? :)
1957 		if (strncmp (fexpr->e.symbol->name, "precache_sound", 14) == 0)
1958 			PrecacheSound (expr_string (params), fexpr->e.symbol->name[14]);
1959 		else if (strncmp (fexpr->e.symbol->name, "precache_model", 14) == 0)
1960 			PrecacheModel (expr_string (params), fexpr->e.symbol->name[14]);
1961 		else if (strncmp (fexpr->e.symbol->name, "precache_file", 13) == 0)
1962 			PrecacheFile (expr_string (params), fexpr->e.symbol->name[13]);
1963 	}
1964 
1965 	return build_function_call (fexpr, ftype, params);
1966 }
1967 
1968 expr_t *
branch_expr(int op,expr_t * test,expr_t * label)1969 branch_expr (int op, expr_t *test, expr_t *label)
1970 {
1971 	if (label && label->type != ex_label)
1972 		internal_error (label, "not a label");
1973 	if (label)
1974 		label->e.label.used++;
1975 	return new_binary_expr (op, test, label);
1976 }
1977 
1978 expr_t *
goto_expr(expr_t * label)1979 goto_expr (expr_t *label)
1980 {
1981 	if (label && label->type != ex_label)
1982 		internal_error (label, "not a label");
1983 	if (label)
1984 		label->e.label.used++;
1985 	return new_unary_expr ('g', label);
1986 }
1987 
1988 expr_t *
return_expr(function_t * f,expr_t * e)1989 return_expr (function_t *f, expr_t *e)
1990 {
1991 	type_t     *t;
1992 
1993 	if (!e) {
1994 		if (f->sym->type->t.func.type != &type_void) {
1995 			if (options.traditional) {
1996 				if (options.warnings.traditional)
1997 					warning (e,
1998 							 "return from non-void function without a value");
1999 				e = new_nil_expr ();
2000 			} else {
2001 				e = error (e, "return from non-void function without a value");
2002 				return e;
2003 			}
2004 		}
2005 		return new_unary_expr ('r', 0);
2006 	}
2007 
2008 	t = get_type (e);
2009 
2010 	if (e->type == ex_error)
2011 		return e;
2012 	if (f->sym->type->t.func.type == &type_void) {
2013 		if (!options.traditional)
2014 			return error (e, "returning a value for a void function");
2015 		if (options.warnings.traditional)
2016 			warning (e, "returning a value for a void function");
2017 	}
2018 	if (e->type == ex_bool)
2019 		e = convert_from_bool (e, f->sym->type->t.func.type);
2020 	if (f->sym->type->t.func.type == &type_float && is_integer_val (e)) {
2021 		convert_int (e);
2022 		t = &type_float;
2023 	}
2024 	if (t == &type_void) {
2025 		if (e->type == ex_nil) {
2026 			t = f->sym->type->t.func.type;
2027 			convert_nil (e, t);
2028 			if (e->type == ex_nil)
2029 				return error (e, "invalid return type for NIL");
2030 		} else {
2031 			if (!options.traditional)
2032 				return error (e, "void value not ignored as it ought to be");
2033 			if (options.warnings.traditional)
2034 				warning (e, "void value not ignored as it ought to be");
2035 			//FIXME does anything need to be done here?
2036 		}
2037 	}
2038 	if (!type_assignable (f->sym->type->t.func.type, t)) {
2039 		if (!options.traditional)
2040 			return error (e, "type mismatch for return value of %s",
2041 						  f->sym->name);
2042 		if (options.warnings.traditional)
2043 			warning (e, "type mismatch for return value of %s",
2044 					 f->sym->name);
2045 	} else {
2046 		if (f->sym->type->t.func.type != t)
2047 			e = cast_expr (f->sym->type->t.func.type, e);
2048 	}
2049 	return new_unary_expr ('r', e);
2050 }
2051 
2052 expr_t *
conditional_expr(expr_t * cond,expr_t * e1,expr_t * e2)2053 conditional_expr (expr_t *cond, expr_t *e1, expr_t *e2)
2054 {
2055 	expr_t     *block = new_block_expr ();
2056 	type_t     *type1 = get_type (e1);
2057 	type_t     *type2 = get_type (e2);
2058 	expr_t     *tlabel = new_label_expr ();
2059 	expr_t     *flabel = new_label_expr ();
2060 	expr_t     *elabel = new_label_expr ();
2061 
2062 	if (cond->type == ex_error)
2063 		return cond;
2064 	if (e1->type == ex_error)
2065 		return e1;
2066 	if (e2->type == ex_error)
2067 		return e2;
2068 
2069 	cond = convert_bool (cond, 1);
2070 	if (cond->type == ex_error)
2071 		return cond;
2072 
2073 	backpatch (cond->e.bool.true_list, tlabel);
2074 	backpatch (cond->e.bool.false_list, flabel);
2075 
2076 	block->e.block.result = (type1 == type2) ? new_temp_def_expr (type1) : 0;
2077 	append_expr (block, cond);
2078 	append_expr (cond->e.bool.e, flabel);
2079 	if (block->e.block.result)
2080 		append_expr (block, assign_expr (block->e.block.result, e2));
2081 	else
2082 		append_expr (block, e2);
2083 	append_expr (block, goto_expr (elabel));
2084 	append_expr (block, tlabel);
2085 	if (block->e.block.result)
2086 		append_expr (block, assign_expr (block->e.block.result, e1));
2087 	else
2088 		append_expr (block, e1);
2089 	append_expr (block, elabel);
2090 	return block;
2091 }
2092 
2093 expr_t *
incop_expr(int op,expr_t * e,int postop)2094 incop_expr (int op, expr_t *e, int postop)
2095 {
2096 	expr_t     *one;
2097 
2098 	if (e->type == ex_error)
2099 		return e;
2100 
2101 	one = new_integer_expr (1);		// integer constants get auto-cast to float
2102 	if (postop) {
2103 		expr_t     *t1, *t2;
2104 		type_t     *type = get_type (e);
2105 		expr_t     *block = new_block_expr ();
2106 		expr_t     *res = new_expr ();
2107 
2108 		if (e->type == ex_error)	// get_type failed
2109 			return e;
2110 		t1 = new_temp_def_expr (type);
2111 		t2 = new_temp_def_expr (type);
2112 		append_expr (block, assign_expr (t1, e));
2113 		append_expr (block, assign_expr (t2, binary_expr (op, t1, one)));
2114 		res = copy_expr (e);
2115 		if (res->type == ex_uexpr && res->e.expr.op == '.')
2116 			res = pointer_expr (address_expr (res, 0, 0));
2117 		append_expr (block, assign_expr (res, t2));
2118 		block->e.block.result = t1;
2119 		return block;
2120 	} else {
2121 		return asx_expr (op, e, one);
2122 	}
2123 }
2124 
2125 expr_t *
array_expr(expr_t * array,expr_t * index)2126 array_expr (expr_t *array, expr_t *index)
2127 {
2128 	type_t     *array_type = get_type (array);
2129 	type_t     *index_type = get_type (index);
2130 	expr_t     *scale;
2131 	expr_t     *e;
2132 	int         ind = 0;
2133 
2134 	if (array->type == ex_error)
2135 		return array;
2136 	if (index->type == ex_error)
2137 		return index;
2138 
2139 	if (array_type->type != ev_pointer && !is_array (array_type))
2140 		return error (array, "not an array");
2141 	if (!is_integral (index_type))
2142 		return error (index, "invalid array index type");
2143 	if (is_short_val (index))
2144 		ind = expr_short (index);
2145 	if (is_integer_val (index))
2146 		ind = expr_integer (index);
2147 	if (array_type->t.func.num_params
2148 		&& is_constant (index)
2149 		&& (ind < array_type->t.array.base
2150 			|| ind - array_type->t.array.base >= array_type->t.array.size))
2151 			return error (index, "array index out of bounds");
2152 	scale = new_integer_expr (type_size (array_type->t.array.type));
2153 	index = binary_expr ('*', index, scale);
2154 	index = binary_expr ('-', index,
2155 				 binary_expr ('*',
2156 							  new_integer_expr (array_type->t.array.base),
2157 							  scale));
2158 	index = fold_constants (index);
2159 	if (is_short_val (index))
2160 		ind = expr_short (index);
2161 	if (is_integer_val (index))
2162 		ind = expr_integer (index);
2163 	if ((is_constant (index) && ind < 32768 && ind >= -32768))
2164 		index = new_short_expr (ind);
2165 	if (is_array (array_type)) {
2166 		e = address_expr (array, index, array_type->t.array.type);
2167 	} else {
2168 		if (!is_short_val (index) || expr_short (index)) {
2169 			e = new_binary_expr ('&', array, index);
2170 			//e->e.expr.type = array_type->aux_type;
2171 			e->e.expr.type = array_type;
2172 		} else {
2173 			e = array;
2174 		}
2175 	}
2176 	e = unary_expr ('.', e);
2177 	return e;
2178 }
2179 
2180 expr_t *
pointer_expr(expr_t * pointer)2181 pointer_expr (expr_t *pointer)
2182 {
2183 	type_t     *pointer_type = get_type (pointer);
2184 
2185 	if (pointer->type == ex_error)
2186 		return pointer;
2187 	if (pointer_type->type != ev_pointer)
2188 		return error (pointer, "not a pointer");
2189 	return array_expr (pointer, new_integer_expr (0));
2190 }
2191 
2192 expr_t *
address_expr(expr_t * e1,expr_t * e2,type_t * t)2193 address_expr (expr_t *e1, expr_t *e2, type_t *t)
2194 {
2195 	expr_t     *e;
2196 
2197 	if (e1->type == ex_error)
2198 		return e1;
2199 
2200 	if (!t)
2201 		t = get_type (e1);
2202 
2203 	switch (e1->type) {
2204 		case ex_symbol:
2205 			if (e1->e.symbol->sy_type == sy_var) {
2206 				def_t      *def = e1->e.symbol->s.def;
2207 				type_t     *type = def->type;
2208 
2209 				if (is_array (type)) {
2210 					e = e1;
2211 					e->type = ex_value;
2212 					e->e.value = new_pointer_val (0, t, def);
2213 				} else {
2214 					e = new_pointer_expr (0, t, def);
2215 					e->line = e1->line;
2216 					e->file = e1->file;
2217 				}
2218 				break;
2219 			}
2220 			return error (e1, "invalid type for unary &");
2221 		case ex_expr:
2222 			if (e1->e.expr.op == '.') {
2223 				e = e1;
2224 				e->e.expr.op = '&';
2225 				e->e.expr.type = pointer_type (e->e.expr.type);
2226 				break;
2227 			}
2228 			if (e1->e.expr.op == 'm') {
2229 				// direct move, so obtain the address of the source
2230 				e = address_expr (e1->e.expr.e2, 0, t);
2231 				break;
2232 			}
2233 			if (e1->e.expr.op == 'M') {
2234 				// indirect move, so we already have the address of the source
2235 				e = e1->e.expr.e2;
2236 				break;
2237 			}
2238 			return error (e1, "invalid type for unary &");
2239 		case ex_uexpr:
2240 			if (e1->e.expr.op == '.') {
2241 				e = e1->e.expr.e1;
2242 				if (e->type == ex_expr && e->e.expr.op == '.') {
2243 					e->e.expr.type = pointer_type (e->e.expr.type);
2244 					e->e.expr.op = '&';
2245 				}
2246 				break;
2247 			}
2248 			if (e1->e.expr.op == 'A') {
2249 				if (!t)
2250 					t = e1->e.expr.type;
2251 				return address_expr (e1->e.expr.e1, e2, t);
2252 			}
2253 			return error (e1, "invalid type for unary &");
2254 		case ex_block:
2255 			if (!e1->e.block.result)
2256 				return error (e1, "invalid type for unary &");
2257 			e1->e.block.result = address_expr (e1->e.block.result, e2, t);
2258 			return e1;
2259 		case ex_label:
2260 			return new_label_ref (&e1->e.label);
2261 		default:
2262 			return error (e1, "invalid type for unary &");
2263 	}
2264 	if (e2) {
2265 		if (e2->type == ex_error)
2266 			return e2;
2267 		if (e->type == ex_value && e->e.value->type == ev_pointer
2268 			&& is_short_val (e2)) {
2269 			e->e.value = new_pointer_val (e->e.value->v.pointer.val + expr_short (e2), t, e->e.value->v.pointer.def);
2270 		} else {
2271 			if (!is_short_val (e2) || expr_short (e2)) {
2272 				if (e->type == ex_expr && e->e.expr.op == '&') {
2273 					e = new_binary_expr ('&', e->e.expr.e1,
2274 										 binary_expr ('+', e->e.expr.e2, e2));
2275 				} else {
2276 					e = new_binary_expr ('&', e, e2);
2277 				}
2278 			}
2279 			if (e->type == ex_expr || e->type == ex_uexpr)
2280 				e->e.expr.type = pointer_type (t);
2281 		}
2282 	}
2283 	return e;
2284 }
2285 
2286 expr_t *
build_if_statement(expr_t * test,expr_t * s1,expr_t * els,expr_t * s2)2287 build_if_statement (expr_t *test, expr_t *s1, expr_t *els, expr_t *s2)
2288 {
2289 	int         line = pr.source_line;
2290 	string_t    file = pr.source_file;
2291 	expr_t     *if_expr;
2292 	expr_t     *tl = new_label_expr ();
2293 	expr_t     *fl = new_label_expr ();
2294 
2295 	pr.source_line = test->line;
2296 	pr.source_file = test->file;
2297 
2298 	if_expr = new_block_expr ();
2299 
2300 	test = convert_bool (test, 1);
2301 	if (test->type != ex_error) {
2302 		backpatch (test->e.bool.true_list, tl);
2303 		backpatch (test->e.bool.false_list, fl);
2304 		append_expr (test->e.bool.e, tl);
2305 		append_expr (if_expr, test);
2306 	}
2307 	append_expr (if_expr, s1);
2308 
2309 	if (els) {
2310 		pr.source_line = els->line;
2311 		pr.source_file = els->file;
2312 	}
2313 
2314 	if (s2) {
2315 		expr_t     *nl = new_label_expr ();
2316 		append_expr (if_expr, goto_expr (nl));
2317 
2318 		append_expr (if_expr, fl);
2319 		append_expr (if_expr, s2);
2320 		append_expr (if_expr, nl);
2321 	} else {
2322 		append_expr (if_expr, fl);
2323 	}
2324 
2325 	pr.source_line = line;
2326 	pr.source_file = file;
2327 
2328 	return if_expr;
2329 }
2330 
2331 expr_t *
build_while_statement(expr_t * test,expr_t * statement,expr_t * break_label,expr_t * continue_label)2332 build_while_statement (expr_t *test, expr_t *statement,
2333 					   expr_t *break_label, expr_t *continue_label)
2334 {
2335 	int         line = pr.source_line;
2336 	string_t    file = pr.source_file;
2337 	expr_t     *l1 = new_label_expr ();
2338 	expr_t     *l2 = break_label;
2339 	expr_t     *while_expr;
2340 
2341 	pr.source_line = test->line;
2342 	pr.source_file = test->file;
2343 
2344 	while_expr = new_block_expr ();
2345 
2346 	append_expr (while_expr, goto_expr (continue_label));
2347 	append_expr (while_expr, l1);
2348 	append_expr (while_expr, statement);
2349 	append_expr (while_expr, continue_label);
2350 
2351 	test = convert_bool (test, 1);
2352 	if (test->type != ex_error) {
2353 		backpatch (test->e.bool.true_list, l1);
2354 		backpatch (test->e.bool.false_list, l2);
2355 		append_expr (test->e.bool.e, l2);
2356 		append_expr (while_expr, test);
2357 	}
2358 
2359 	pr.source_line = line;
2360 	pr.source_file = file;
2361 
2362 	return while_expr;
2363 }
2364 
2365 expr_t *
build_do_while_statement(expr_t * statement,expr_t * test,expr_t * break_label,expr_t * continue_label)2366 build_do_while_statement (expr_t *statement, expr_t *test,
2367 						  expr_t *break_label, expr_t *continue_label)
2368 {
2369 	expr_t *l1 = new_label_expr ();
2370 	int         line = pr.source_line;
2371 	string_t    file = pr.source_file;
2372 	expr_t     *do_while_expr;
2373 
2374 	pr.source_line = test->line;
2375 	pr.source_file = test->file;
2376 
2377 	do_while_expr = new_block_expr ();
2378 
2379 	append_expr (do_while_expr, l1);
2380 	append_expr (do_while_expr, statement);
2381 	append_expr (do_while_expr, continue_label);
2382 
2383 	test = convert_bool (test, 1);
2384 	if (test->type != ex_error) {
2385 		backpatch (test->e.bool.true_list, l1);
2386 		backpatch (test->e.bool.false_list, break_label);
2387 		append_expr (test->e.bool.e, break_label);
2388 		append_expr (do_while_expr, test);
2389 	}
2390 
2391 	pr.source_line = line;
2392 	pr.source_file = file;
2393 
2394 	return do_while_expr;
2395 }
2396 
2397 expr_t *
build_for_statement(expr_t * init,expr_t * test,expr_t * next,expr_t * statement,expr_t * break_label,expr_t * continue_label)2398 build_for_statement (expr_t *init, expr_t *test, expr_t *next,
2399 					 expr_t *statement,
2400 					 expr_t *break_label, expr_t *continue_label)
2401 {
2402 	expr_t     *tl = new_label_expr ();
2403 	expr_t     *fl = break_label;
2404 	expr_t     *l1 = 0;
2405 	expr_t     *t;
2406 	int         line = pr.source_line;
2407 	string_t    file = pr.source_file;
2408 	expr_t     *for_expr;
2409 
2410 	if (next)
2411 		t = next;
2412 	else if (test)
2413 		t = test;
2414 	else if (init)
2415 		t = init;
2416 	else
2417 		t = continue_label;
2418 	pr.source_line = t->line;
2419 	pr.source_file = t->file;
2420 
2421 	for_expr = new_block_expr ();
2422 
2423 	append_expr (for_expr, init);
2424 	if (test) {
2425 		l1 = new_label_expr ();
2426 		append_expr (for_expr, goto_expr (l1));
2427 	}
2428 	append_expr (for_expr, tl);
2429 	append_expr (for_expr, statement);
2430 	append_expr (for_expr, continue_label);
2431 	append_expr (for_expr, next);
2432 	if (test) {
2433 		append_expr (for_expr, l1);
2434 		test = convert_bool (test, 1);
2435 		if (test->type != ex_error) {
2436 			backpatch (test->e.bool.true_list, tl);
2437 			backpatch (test->e.bool.false_list, fl);
2438 			append_expr (test->e.bool.e, fl);
2439 			append_expr (for_expr, test);
2440 		}
2441 	} else {
2442 		append_expr (for_expr, goto_expr (tl));
2443 		append_expr (for_expr, fl);
2444 	}
2445 
2446 	pr.source_line = line;
2447 	pr.source_file = file;
2448 
2449 	return for_expr;
2450 }
2451 
2452 expr_t *
build_state_expr(expr_t * frame,expr_t * think,expr_t * step)2453 build_state_expr (expr_t *frame, expr_t *think, expr_t *step)
2454 {
2455 	if (is_integer_val (frame))
2456 		convert_int (frame);
2457 	if (!type_assignable (&type_float, get_type (frame)))
2458 		return error (frame, "invalid type for frame number");
2459 	if (extract_type (think) != ev_func)
2460 		return error (think, "invalid type for think");
2461 	if (step) {
2462 		if (is_integer_val (step))
2463 			convert_int (step);
2464 		if (!type_assignable (&type_float, get_type (step)))
2465 			return error (step, "invalid type for frame number");
2466 	}
2467 	return new_state_expr (frame, think, step);
2468 }
2469 
2470 expr_t *
think_expr(symbol_t * think_sym)2471 think_expr (symbol_t *think_sym)
2472 {
2473 	symbol_t   *sym;
2474 
2475 	if (think_sym->table)
2476 		return new_symbol_expr (think_sym);
2477 
2478 	sym = symtab_lookup (current_symtab, "think");
2479 	if (sym && sym->sy_type == sy_var && sym->type
2480 		&& sym->type->type == ev_field
2481 		&& sym->type->t.fldptr.type->type == ev_func) {
2482 		think_sym->type = sym->type->t.fldptr.type;
2483 	} else {
2484 		think_sym->type = &type_function;
2485 	}
2486 	think_sym = function_symbol (think_sym, 0, 1);
2487 	make_function (think_sym, 0, current_symtab->space, current_storage);
2488 	return new_symbol_expr (think_sym);
2489 }
2490 
2491 static int
is_indirect(expr_t * e)2492 is_indirect (expr_t *e)
2493 {
2494 	if (e->type == ex_block && e->e.block.result)
2495 		return is_indirect (e->e.block.result);
2496 	if (e->type == ex_expr && e->e.expr.op == '.')
2497 		return 1;
2498 	if (!(e->type == ex_uexpr && e->e.expr.op == '.'))
2499 		return 0;
2500 	e = e->e.expr.e1;
2501 	if (e->type != ex_value || e->e.value->type != ev_pointer
2502 		|| !(POINTER_VAL (e->e.value->v.pointer) >= 0
2503 			 && POINTER_VAL (e->e.value->v.pointer) < 65536)) {
2504 		return 1;
2505 	}
2506 	return 0;
2507 }
2508 
2509 static inline int
is_lvalue(expr_t * e)2510 is_lvalue (expr_t *e)
2511 {
2512 	if (e->type == ex_symbol) {
2513 		switch (e->e.symbol->sy_type) {
2514 			case sy_var:
2515 				return 1;
2516 			case sy_const:
2517 				return 0;
2518 			case sy_type:
2519 				return 0;
2520 			case sy_expr:
2521 				return 0;
2522 			case sy_func:
2523 				return 0;
2524 			case sy_class:
2525 				return 0;
2526 		}
2527 	}
2528 	if (e->type == ex_temp)
2529 		return 1;
2530 	if (e->type == ex_expr && e->e.expr.op == '.')
2531 		return 1;
2532 	if (e->type == ex_uexpr && e->e.expr.op == '.')
2533 		return 1;
2534 	if (e->type == ex_uexpr && e->e.expr.op == 'A')
2535 		return is_lvalue (e->e.expr.e1);
2536 	return 0;
2537 }
2538 
2539 expr_t *
assign_expr(expr_t * e1,expr_t * e2)2540 assign_expr (expr_t *e1, expr_t *e2)
2541 {
2542 	int         op = '=';
2543 	type_t     *t1, *t2, *type;
2544 	expr_t     *e;
2545 
2546 	convert_name (e1);
2547 	convert_name (e2);
2548 
2549 	if (e1->type == ex_error)
2550 		return e1;
2551 	if (e2->type == ex_error)
2552 		return e2;
2553 
2554 	e1 = fold_constants (e1);
2555 	e2 = fold_constants (e2);
2556 
2557 	if (options.traditional) {
2558 		if (e2->type == ex_expr && !e2->paren
2559 			&& (e2->e.expr.op == AND || e2->e.expr.op == OR)) {
2560 			notice (e2, "precedence of `%s' and `%s' inverted for "
2561 						"traditional code", get_op_string (op),
2562 						get_op_string (e2->e.expr.op));
2563 			e1 = assign_expr (e1, e2->e.expr.e1);
2564 			e1->paren = 1;
2565 			return binary_expr (e2->e.expr.op, e1, e2->e.expr.e2);
2566 		}
2567 	}
2568 
2569 	if (!is_lvalue (e1)) {
2570 		if (options.traditional)
2571 			warning (e1, "invalid lvalue in assignment");
2572 		else
2573 			return error (e1, "invalid lvalue in assignment");
2574 	}
2575 	t1 = get_type (e1);
2576 	t2 = get_type (e2);
2577 	if (!t1 || !t2)
2578 		internal_error (e1, 0);
2579 	//XXX func = func ???
2580 	if (t1->type == ev_pointer && is_array (t2)) {
2581 		e2 = address_expr (e2, 0, t2->t.fldptr.type);
2582 		t2 = get_type (e2);
2583 	}
2584 	if (e2->type == ex_bool)
2585 		e2 = convert_from_bool (e2, t1);
2586 
2587 	if (t1->type != ev_void && e2->type == ex_nil) {
2588 		t2 = t1;
2589 		convert_nil (e2, t2);
2590 	}
2591 
2592 	e2->rvalue = 1;
2593 
2594 	if (!type_assignable (t1, t2)) {
2595 		if (options.traditional) {
2596 			if (t1->type == ev_func && t2->type == ev_func) {
2597 				warning (e1, "assignment between disparate function types");
2598 			} else if (t1->type == ev_float && t2->type == ev_vector) {
2599 				warning (e1, "assignment of vector to float");
2600 				e2 = binary_expr ('.', e2, new_name_expr ("x"));
2601 			} else if (t1->type == ev_vector && t2->type == ev_float) {
2602 				warning (e1, "assignment of float to vector");
2603 				e1 = binary_expr ('.', e1, new_name_expr ("x"));
2604 			} else {
2605 				return type_mismatch (e1, e2, op);
2606 			}
2607 		} else {
2608 			return type_mismatch (e1, e2, op);
2609 		}
2610 	}
2611 	type = t1;
2612 	if (is_indirect (e1) && is_indirect (e2)) {
2613 		if (is_struct (get_type (e2))) {
2614 			e1 = address_expr (e1, 0, 0);
2615 			e2 = address_expr (e2, 0, 0);
2616 			e = new_move_expr (e1, e2, t2, 1);
2617 		} else {
2618 			expr_t     *temp = new_temp_def_expr (t1);
2619 
2620 			e = new_block_expr ();
2621 			append_expr (e, assign_expr (temp, e2));
2622 			append_expr (e, assign_expr (e1, temp));
2623 			e->e.block.result = temp;
2624 		}
2625 		return e;
2626 	} else if (is_indirect (e1)) {
2627 		if (is_struct (get_type (e1))) {
2628 			e1 = address_expr (e1, 0, 0);
2629 			e2 = address_expr (e2, 0, 0);
2630 			return new_move_expr (e1, e2, t1, 1);
2631 		}
2632 		if (e1->type == ex_expr) {
2633 			if (get_type (e1->e.expr.e1) == &type_entity) {
2634 				type = e1->e.expr.type;
2635 				e1->e.expr.type = pointer_type (type);
2636 				e1->e.expr.op = '&';
2637 			}
2638 			op = PAS;
2639 		} else {
2640 			e = e1->e.expr.e1;
2641 			if ((e->type != ex_value || e->e.value->type != ev_pointer)
2642 				|| !(POINTER_VAL (e->e.value->v.pointer) > 0
2643 					 && POINTER_VAL (e->e.value->v.pointer) < 65536)) {
2644 				e1 = e;
2645 				op = PAS;
2646 			}
2647 		}
2648 	} else if (is_indirect (e2)) {
2649 		if (is_struct (get_type (e1))) {
2650 			e1 = address_expr (e1, 0, 0);
2651 			e2 = address_expr (e2, 0, 0);
2652 			e2->rvalue = 1;
2653 			return new_move_expr (e1, e2, t2, 1);
2654 		}
2655 		if (e2->type == ex_uexpr) {
2656 			e = e2->e.expr.e1;
2657 			if ((e->type != ex_value || e->e.value->type != ev_pointer)
2658 				|| !(POINTER_VAL (e->e.value->v.pointer) > 0
2659 					 && POINTER_VAL (e->e.value->v.pointer) < 65536)) {
2660 				if (e->type == ex_expr && e->e.expr.op == '&'
2661 					&& e->e.expr.type->type == ev_pointer
2662 					&& !is_constant (e)) {
2663 					e2 = e;
2664 					e2->e.expr.op = '.';
2665 					e2->e.expr.type = t2;
2666 					e2->rvalue = 1;
2667 				}
2668 			}
2669 		}
2670 	}
2671 	if (is_struct (get_type (e1))) {
2672 		return new_move_expr (e1, e2, get_type (e1), 0);
2673 	}
2674 	if (!type)
2675 		internal_error (e1, 0);
2676 
2677 	e = new_binary_expr (op, e1, e2);
2678 	e->e.expr.type = type;
2679 	return e;
2680 }
2681 
2682 expr_t *
cast_expr(type_t * type,expr_t * e)2683 cast_expr (type_t *type, expr_t *e)
2684 {
2685 	expr_t    *c;
2686 	type_t    *e_type;
2687 
2688 	convert_name (e);
2689 
2690 	if (e->type == ex_error)
2691 		return e;
2692 
2693 	e_type = get_type (e);
2694 
2695 	if (type == e_type)
2696 		return e;
2697 
2698 	if ((type == type_default && is_enum (e_type))
2699 		|| (is_enum (type) && e_type == type_default))
2700 		return e;
2701 	if (!(type->type == ev_pointer
2702 		  && (e_type->type == ev_pointer || is_integral (e_type)
2703 			  || is_array (e_type)))
2704 		&& !(is_integral (type) && e_type->type == ev_pointer)
2705 		&& !(type->type == ev_func && e_type->type == ev_func)
2706 		&& !(is_scalar (type) && is_scalar (e_type))) {
2707 		return cast_error (e, e_type, type);
2708 	}
2709 	if (is_array (e_type))
2710 		return address_expr (e, 0, 0);
2711 	if (is_constant (e) && is_scalar (type) && is_scalar (e_type)) {
2712 		ex_value_t *val = 0;
2713 		if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const) {
2714 			val = e->e.symbol->s.value;
2715 		} else if (e->type == ex_value) {
2716 			val = e->e.value;
2717 		} else if (e->type == ex_nil) {
2718 			convert_nil (e, type);
2719 			return e;
2720 		}
2721 		if (!val)
2722 			internal_error (e, "unexpected constant expression type");
2723 		e->e.value = convert_value (val, type);
2724 		e->type = ex_value;
2725 		c = e;
2726 	} else if ((is_float (type) && is_integral (e_type))
2727 		|| (is_integral (type) && is_float (e_type))) {
2728 		c = new_unary_expr ('C', e);
2729 		c->e.expr.type = type;
2730 	} else if (e->type == ex_uexpr && e->e.expr.op == '.') {
2731 		e->e.expr.type = type;
2732 		c = e;
2733 	} else {
2734 		c = new_alias_expr (type, e);
2735 	}
2736 	return c;
2737 }
2738 
2739 expr_t *
selector_expr(keywordarg_t * selector)2740 selector_expr (keywordarg_t *selector)
2741 {
2742 	dstring_t  *sel_id = dstring_newstr ();
2743 	expr_t     *sel;
2744 	symbol_t   *sel_sym;
2745 	symbol_t   *sel_table;
2746 	int         index;
2747 
2748 	selector = copy_keywordargs (selector);
2749 	selector = (keywordarg_t *) reverse_params ((param_t *) selector);
2750 	selector_name (sel_id, selector);
2751 	index = selector_index (sel_id->str);
2752 	index *= type_size (type_SEL.t.fldptr.type);
2753 	sel_sym = make_symbol ("_OBJ_SELECTOR_TABLE_PTR", &type_SEL,
2754 						   pr.near_data, sc_static);
2755 	if (!sel_sym->table) {
2756 		symtab_addsymbol (pr.symtab, sel_sym);
2757 		sel_table = make_symbol ("_OBJ_SELECTOR_TABLE",
2758 								 array_type (type_SEL.t.fldptr.type, 0),
2759 								 pr.far_data, sc_extern);
2760 		if (!sel_table->table)
2761 			symtab_addsymbol (pr.symtab, sel_table);
2762 		reloc_def_def (sel_table->s.def, sel_sym->s.def);
2763 	}
2764 	sel = new_symbol_expr (sel_sym);
2765 	dstring_delete (sel_id);
2766 	sel = new_binary_expr ('&', sel, new_short_expr (index));
2767 	sel->e.expr.type = &type_SEL;
2768 	return sel;
2769 }
2770 
2771 expr_t *
protocol_expr(const char * protocol)2772 protocol_expr (const char *protocol)
2773 {
2774 	return error (0, "not implemented");
2775 }
2776 
2777 expr_t *
encode_expr(type_t * type)2778 encode_expr (type_t *type)
2779 {
2780 	dstring_t  *encoding = dstring_newstr ();
2781 	expr_t     *e;
2782 
2783 	encode_type (encoding, type);
2784 	e = new_string_expr (encoding->str);
2785 	free (encoding);
2786 	return e;
2787 }
2788 
2789 expr_t *
super_expr(class_type_t * class_type)2790 super_expr (class_type_t *class_type)
2791 {
2792 	symbol_t   *sym;
2793 	expr_t     *super;
2794 	expr_t     *e;
2795 	expr_t     *super_block;
2796 	class_t    *class;
2797 
2798 	if (!class_type)
2799 		return error (0, "`super' used outside of class implementation");
2800 
2801 	class = extract_class (class_type);
2802 
2803 	if (!class->super_class)
2804 		return error (0, "%s has no super class", class->name);
2805 
2806 	sym = symtab_lookup (current_symtab, ".super");
2807 	if (!sym || sym->table != current_symtab) {
2808 		sym = new_symbol (".super");
2809 		initialize_def (sym, &type_obj_super, 0, current_symtab->space,
2810 						sc_local);
2811 	}
2812 	super = new_symbol_expr (sym);
2813 
2814 	super_block = new_block_expr ();
2815 
2816 	e = assign_expr (binary_expr ('.', super, new_name_expr ("self")),
2817 								  new_name_expr ("self"));
2818 	append_expr (super_block, e);
2819 
2820 	e = new_symbol_expr (class_pointer_symbol (class));
2821 	e = assign_expr (binary_expr ('.', super, new_name_expr ("class")),
2822 					 binary_expr ('.', e, new_name_expr ("super_class")));
2823 	append_expr (super_block, e);
2824 
2825 	e = address_expr (super, 0, 0);
2826 	super_block->e.block.result = e;
2827 	return super_block;
2828 }
2829 
2830 expr_t *
message_expr(expr_t * receiver,keywordarg_t * message)2831 message_expr (expr_t *receiver, keywordarg_t *message)
2832 {
2833 	expr_t     *args = 0, **a = &args;
2834 	expr_t     *selector = selector_expr (message);
2835 	expr_t     *call;
2836 	keywordarg_t *m;
2837 	int         self = 0, super = 0, class_msg = 0;
2838 	type_t     *rec_type;
2839 	type_t     *return_type;
2840 	type_t     *method_type = &type_IMP;
2841 	class_t    *class = 0;
2842 	method_t   *method;
2843 	expr_t     *send_msg;
2844 
2845 	if (receiver->type == ex_symbol
2846 		&& strcmp (receiver->e.symbol->name, "super") == 0) {
2847 		super = 1;
2848 
2849 		receiver = super_expr (current_class);
2850 
2851 		if (receiver->type == ex_error)
2852 			return receiver;
2853 		receiver = cast_expr (&type_id, receiver);	//FIXME better way?
2854 		class = extract_class (current_class);
2855 		rec_type = class->type;
2856 	} else {
2857 		if (receiver->type == ex_symbol) {
2858 			if (strcmp (receiver->e.symbol->name, "self") == 0)
2859 				self = 1;
2860 			if (receiver->e.symbol->sy_type == sy_class) {
2861 				class = receiver->e.symbol->type->t.class;
2862 				class_msg = 1;
2863 				receiver = new_symbol_expr (class_pointer_symbol (class));
2864 			}
2865 		} else if (receiver->type == ex_nil) {
2866 			convert_nil (receiver, &type_id);
2867 		}
2868 		rec_type = get_type (receiver);
2869 
2870 		if (receiver->type == ex_error)
2871 			return receiver;
2872 
2873 		if (rec_type == &type_id || rec_type == &type_Class) {
2874 		} else {
2875 			if (rec_type->type == ev_pointer)
2876 				rec_type = rec_type->t.fldptr.type;
2877 			if (!obj_is_class (rec_type))
2878 				return error (receiver, "not a class/object");
2879 
2880 			if (self) {
2881 				if (!class)
2882 					class = extract_class (current_class);
2883 				if (rec_type == &type_obj_class)
2884 					class_msg = 1;
2885 			} else {
2886 				if (!class)
2887 					class = rec_type->t.class;
2888 			}
2889 		}
2890 	}
2891 
2892 	return_type = &type_id;
2893 	method = class_message_response (class, class_msg, selector);
2894 	if (method)
2895 		return_type = method->type->t.func.type;
2896 
2897 	for (m = message; m; m = m->next) {
2898 		*a = m->expr;
2899 		while ((*a))
2900 			a = &(*a)->next;
2901 	}
2902 	*a = selector;
2903 	a = &(*a)->next;
2904 	*a = receiver;
2905 
2906 	send_msg = send_message (super);
2907 	if (method) {
2908 		expr_t      *err;
2909 		if ((err = method_check_params (method, args)))
2910 			return err;
2911 		method_type = method->type;
2912 	}
2913 	call = build_function_call (send_msg, method_type, args);
2914 
2915 	if (call->type == ex_error)
2916 		return receiver;
2917 
2918 	call->e.block.result = new_ret_expr (return_type);
2919 	return call;
2920 }
2921 
2922 expr_t *
sizeof_expr(expr_t * expr,struct type_s * type)2923 sizeof_expr (expr_t *expr, struct type_s *type)
2924 {
2925 	if (!((!expr) ^ (!type)))
2926 		internal_error (0, 0);
2927 	if (!type)
2928 		type = get_type (expr);
2929 	expr = new_integer_expr (type_size (type));
2930 	return expr;
2931 }
2932