]> git.xonotic.org Git - xonotic/gmqcc.git/blob - ast.c
use INSTR_STATE by default, add -femulate-state to switch to emulation, and -state...
[xonotic/gmqcc.git] / ast.c
1 /*
2  * Copyright (C) 2012, 2013, 2014
3  *     Wolfgang Bumiller
4  *     Dale Weiler
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy of
7  * this software and associated documentation files (the "Software"), to deal in
8  * the Software without restriction, including without limitation the rights to
9  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10  * of the Software, and to permit persons to whom the Software is furnished to do
11  * so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "gmqcc.h"
28 #include "ast.h"
29 #include "parser.h"
30
31 #define ast_instantiate(T, ctx, destroyfn)                          \
32     T* self = (T*)mem_a(sizeof(T));                                 \
33     if (!self) {                                                    \
34         return NULL;                                                \
35     }                                                               \
36     ast_node_init((ast_node*)self, ctx, TYPE_##T);                  \
37     ( (ast_node*)self )->destroy = (ast_node_delete*)destroyfn
38
39 /*
40  * forward declarations, these need not be in ast.h for obvious
41  * static reasons.
42  */
43 static bool ast_member_codegen(ast_member*, ast_function*, bool lvalue, ir_value**);
44 static void ast_array_index_delete(ast_array_index*);
45 static bool ast_array_index_codegen(ast_array_index*, ast_function*, bool lvalue, ir_value**);
46 static void ast_argpipe_delete(ast_argpipe*);
47 static bool ast_argpipe_codegen(ast_argpipe*, ast_function*, bool lvalue, ir_value**);
48 static void ast_store_delete(ast_store*);
49 static bool ast_store_codegen(ast_store*, ast_function*, bool lvalue, ir_value**);
50 static void ast_ifthen_delete(ast_ifthen*);
51 static bool ast_ifthen_codegen(ast_ifthen*, ast_function*, bool lvalue, ir_value**);
52 static void ast_ternary_delete(ast_ternary*);
53 static bool ast_ternary_codegen(ast_ternary*, ast_function*, bool lvalue, ir_value**);
54 static void ast_loop_delete(ast_loop*);
55 static bool ast_loop_codegen(ast_loop*, ast_function*, bool lvalue, ir_value**);
56 static void ast_breakcont_delete(ast_breakcont*);
57 static bool ast_breakcont_codegen(ast_breakcont*, ast_function*, bool lvalue, ir_value**);
58 static void ast_switch_delete(ast_switch*);
59 static bool ast_switch_codegen(ast_switch*, ast_function*, bool lvalue, ir_value**);
60 static void ast_label_delete(ast_label*);
61 static void ast_label_register_goto(ast_label*, ast_goto*);
62 static bool ast_label_codegen(ast_label*, ast_function*, bool lvalue, ir_value**);
63 static bool ast_goto_codegen(ast_goto*, ast_function*, bool lvalue, ir_value**);
64 static void ast_goto_delete(ast_goto*);
65 static void ast_call_delete(ast_call*);
66 static bool ast_call_codegen(ast_call*, ast_function*, bool lvalue, ir_value**);
67 static bool ast_block_codegen(ast_block*, ast_function*, bool lvalue, ir_value**);
68 static void ast_unary_delete(ast_unary*);
69 static bool ast_unary_codegen(ast_unary*, ast_function*, bool lvalue, ir_value**);
70 static void ast_entfield_delete(ast_entfield*);
71 static bool ast_entfield_codegen(ast_entfield*, ast_function*, bool lvalue, ir_value**);
72 static void ast_return_delete(ast_return*);
73 static bool ast_return_codegen(ast_return*, ast_function*, bool lvalue, ir_value**);
74 static void ast_binstore_delete(ast_binstore*);
75 static bool ast_binstore_codegen(ast_binstore*, ast_function*, bool lvalue, ir_value**);
76 static void ast_binary_delete(ast_binary*);
77 static bool ast_binary_codegen(ast_binary*, ast_function*, bool lvalue, ir_value**);
78 static bool ast_state_codegen(ast_state*, ast_function*, bool lvalue, ir_value**);
79
80 /* It must not be possible to get here. */
81 static GMQCC_NORETURN void _ast_node_destroy(ast_node *self)
82 {
83     (void)self;
84     con_err("ast node missing destroy()\n");
85     exit(EXIT_FAILURE);
86 }
87
88 /* Initialize main ast node aprts */
89 static void ast_node_init(ast_node *self, lex_ctx_t ctx, int nodetype)
90 {
91     self->context = ctx;
92     self->destroy = &_ast_node_destroy;
93     self->keep    = false;
94     self->nodetype = nodetype;
95     self->side_effects = false;
96 }
97
98 /* weight and side effects */
99 static void _ast_propagate_effects(ast_node *self, ast_node *other)
100 {
101     if (ast_side_effects(other))
102         ast_side_effects(self) = true;
103 }
104 #define ast_propagate_effects(s,o) _ast_propagate_effects(((ast_node*)(s)), ((ast_node*)(o)))
105
106 /* General expression initialization */
107 static void ast_expression_init(ast_expression *self,
108                                 ast_expression_codegen *codegen)
109 {
110     self->codegen  = codegen;
111     self->vtype    = TYPE_VOID;
112     self->next     = NULL;
113     self->outl     = NULL;
114     self->outr     = NULL;
115     self->params   = NULL;
116     self->count    = 0;
117     self->varparam = NULL;
118     self->flags    = 0;
119     if (OPTS_OPTION_BOOL(OPTION_COVERAGE))
120         self->flags |= AST_FLAG_BLOCK_COVERAGE;
121 }
122
123 static void ast_expression_delete(ast_expression *self)
124 {
125     size_t i;
126     if (self->next)
127         ast_delete(self->next);
128     for (i = 0; i < vec_size(self->params); ++i) {
129         ast_delete(self->params[i]);
130     }
131     vec_free(self->params);
132     if (self->varparam)
133         ast_delete(self->varparam);
134 }
135
136 static void ast_expression_delete_full(ast_expression *self)
137 {
138     ast_expression_delete(self);
139     mem_d(self);
140 }
141
142 ast_value* ast_value_copy(const ast_value *self)
143 {
144     size_t i;
145     const ast_expression *fromex;
146     ast_expression       *selfex;
147     ast_value *cp = ast_value_new(self->expression.node.context, self->name, self->expression.vtype);
148     if (self->expression.next) {
149         cp->expression.next = ast_type_copy(self->expression.node.context, self->expression.next);
150     }
151     fromex   = &self->expression;
152     selfex = &cp->expression;
153     selfex->count    = fromex->count;
154     selfex->flags    = fromex->flags;
155     for (i = 0; i < vec_size(fromex->params); ++i) {
156         ast_value *v = ast_value_copy(fromex->params[i]);
157         vec_push(selfex->params, v);
158     }
159     return cp;
160 }
161
162 void ast_type_adopt_impl(ast_expression *self, const ast_expression *other)
163 {
164     size_t i;
165     const ast_expression *fromex;
166     ast_expression       *selfex;
167     self->vtype = other->vtype;
168     if (other->next) {
169         self->next = (ast_expression*)ast_type_copy(ast_ctx(self), other->next);
170     }
171     fromex = other;
172     selfex = self;
173     selfex->count    = fromex->count;
174     selfex->flags    = fromex->flags;
175     for (i = 0; i < vec_size(fromex->params); ++i) {
176         ast_value *v = ast_value_copy(fromex->params[i]);
177         vec_push(selfex->params, v);
178     }
179 }
180
181 static ast_expression* ast_shallow_type(lex_ctx_t ctx, int vtype)
182 {
183     ast_instantiate(ast_expression, ctx, ast_expression_delete_full);
184     ast_expression_init(self, NULL);
185     self->codegen = NULL;
186     self->next    = NULL;
187     self->vtype   = vtype;
188     return self;
189 }
190
191 ast_expression* ast_type_copy(lex_ctx_t ctx, const ast_expression *ex)
192 {
193     size_t i;
194     const ast_expression *fromex;
195     ast_expression       *selfex;
196
197     if (!ex)
198         return NULL;
199     else
200     {
201         ast_instantiate(ast_expression, ctx, ast_expression_delete_full);
202         ast_expression_init(self, NULL);
203
204         fromex = ex;
205         selfex = self;
206
207         /* This may never be codegen()d */
208         selfex->codegen = NULL;
209
210         selfex->vtype = fromex->vtype;
211         if (fromex->next)
212             selfex->next = ast_type_copy(ctx, fromex->next);
213         else
214             selfex->next = NULL;
215
216         selfex->count    = fromex->count;
217         selfex->flags    = fromex->flags;
218         for (i = 0; i < vec_size(fromex->params); ++i) {
219             ast_value *v = ast_value_copy(fromex->params[i]);
220             vec_push(selfex->params, v);
221         }
222
223         return self;
224     }
225 }
226
227 bool ast_compare_type(ast_expression *a, ast_expression *b)
228 {
229     if (a->vtype == TYPE_NIL ||
230         b->vtype == TYPE_NIL)
231         return true;
232     if (a->vtype != b->vtype)
233         return false;
234     if (!a->next != !b->next)
235         return false;
236     if (vec_size(a->params) != vec_size(b->params))
237         return false;
238     if ((a->flags & AST_FLAG_TYPE_MASK) !=
239         (b->flags & AST_FLAG_TYPE_MASK) )
240     {
241         return false;
242     }
243     if (vec_size(a->params)) {
244         size_t i;
245         for (i = 0; i < vec_size(a->params); ++i) {
246             if (!ast_compare_type((ast_expression*)a->params[i],
247                                   (ast_expression*)b->params[i]))
248                 return false;
249         }
250     }
251     if (a->next)
252         return ast_compare_type(a->next, b->next);
253     return true;
254 }
255
256 static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsize, size_t pos)
257 {
258     const char *typestr;
259     size_t typelen;
260     size_t i;
261
262     if (!e) {
263         if (pos + 6 >= bufsize)
264             goto full;
265         util_strncpy(buf + pos, "(null)", 6);
266         return pos + 6;
267     }
268
269     if (pos + 1 >= bufsize)
270         goto full;
271
272     switch (e->vtype) {
273         case TYPE_VARIANT:
274             util_strncpy(buf + pos, "(variant)", 9);
275             return pos + 9;
276
277         case TYPE_FIELD:
278             buf[pos++] = '.';
279             return ast_type_to_string_impl(e->next, buf, bufsize, pos);
280
281         case TYPE_POINTER:
282             if (pos + 3 >= bufsize)
283                 goto full;
284             buf[pos++] = '*';
285             buf[pos++] = '(';
286             pos = ast_type_to_string_impl(e->next, buf, bufsize, pos);
287             if (pos + 1 >= bufsize)
288                 goto full;
289             buf[pos++] = ')';
290             return pos;
291
292         case TYPE_FUNCTION:
293             pos = ast_type_to_string_impl(e->next, buf, bufsize, pos);
294             if (pos + 2 >= bufsize)
295                 goto full;
296             if (!vec_size(e->params)) {
297                 buf[pos++] = '(';
298                 buf[pos++] = ')';
299                 return pos;
300             }
301             buf[pos++] = '(';
302             pos = ast_type_to_string_impl((ast_expression*)(e->params[0]), buf, bufsize, pos);
303             for (i = 1; i < vec_size(e->params); ++i) {
304                 if (pos + 2 >= bufsize)
305                     goto full;
306                 buf[pos++] = ',';
307                 buf[pos++] = ' ';
308                 pos = ast_type_to_string_impl((ast_expression*)(e->params[i]), buf, bufsize, pos);
309             }
310             if (pos + 1 >= bufsize)
311                 goto full;
312             buf[pos++] = ')';
313             return pos;
314
315         case TYPE_ARRAY:
316             pos = ast_type_to_string_impl(e->next, buf, bufsize, pos);
317             if (pos + 1 >= bufsize)
318                 goto full;
319             buf[pos++] = '[';
320             pos += util_snprintf(buf + pos, bufsize - pos - 1, "%i", (int)e->count);
321             if (pos + 1 >= bufsize)
322                 goto full;
323             buf[pos++] = ']';
324             return pos;
325
326         default:
327             typestr = type_name[e->vtype];
328             typelen = strlen(typestr);
329             if (pos + typelen >= bufsize)
330                 goto full;
331             util_strncpy(buf + pos, typestr, typelen);
332             return pos + typelen;
333     }
334
335 full:
336     buf[bufsize-3] = '.';
337     buf[bufsize-2] = '.';
338     buf[bufsize-1] = '.';
339     return bufsize;
340 }
341
342 void ast_type_to_string(ast_expression *e, char *buf, size_t bufsize)
343 {
344     size_t pos = ast_type_to_string_impl(e, buf, bufsize-1, 0);
345     buf[pos] = 0;
346 }
347
348 static bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_value **out);
349 ast_value* ast_value_new(lex_ctx_t ctx, const char *name, int t)
350 {
351     ast_instantiate(ast_value, ctx, ast_value_delete);
352     ast_expression_init((ast_expression*)self,
353                         (ast_expression_codegen*)&ast_value_codegen);
354     self->expression.node.keep = true; /* keep */
355
356     self->name = name ? util_strdup(name) : NULL;
357     self->expression.vtype = t;
358     self->expression.next  = NULL;
359     self->isfield  = false;
360     self->cvq      = CV_NONE;
361     self->hasvalue = false;
362     self->isimm    = false;
363     self->uses     = 0;
364     memset(&self->constval, 0, sizeof(self->constval));
365     self->initlist = NULL;
366
367     self->ir_v           = NULL;
368     self->ir_values      = NULL;
369     self->ir_value_count = 0;
370
371     self->setter = NULL;
372     self->getter = NULL;
373     self->desc   = NULL;
374
375     self->argcounter = NULL;
376     self->intrinsic = false;
377
378     return self;
379 }
380
381 void ast_value_delete(ast_value* self)
382 {
383     if (self->name)
384         mem_d((void*)self->name);
385     if (self->argcounter)
386         mem_d((void*)self->argcounter);
387     if (self->hasvalue) {
388         switch (self->expression.vtype)
389         {
390         case TYPE_STRING:
391             mem_d((void*)self->constval.vstring);
392             break;
393         case TYPE_FUNCTION:
394             /* unlink us from the function node */
395             self->constval.vfunc->vtype = NULL;
396             break;
397         /* NOTE: delete function? currently collected in
398          * the parser structure
399          */
400         default:
401             break;
402         }
403     }
404     if (self->ir_values)
405         mem_d(self->ir_values);
406
407     if (self->desc)
408         mem_d(self->desc);
409
410     if (self->initlist) {
411         if (self->expression.next->vtype == TYPE_STRING) {
412             /* strings are allocated, free them */
413             size_t i, len = vec_size(self->initlist);
414             /* in theory, len should be expression.count
415              * but let's not take any chances */
416             for (i = 0; i < len; ++i) {
417                 if (self->initlist[i].vstring)
418                     mem_d(self->initlist[i].vstring);
419             }
420         }
421         vec_free(self->initlist);
422     }
423
424     ast_expression_delete((ast_expression*)self);
425     mem_d(self);
426 }
427
428 void ast_value_params_add(ast_value *self, ast_value *p)
429 {
430     vec_push(self->expression.params, p);
431 }
432
433 bool ast_value_set_name(ast_value *self, const char *name)
434 {
435     if (self->name)
436         mem_d((void*)self->name);
437     self->name = util_strdup(name);
438     return !!self->name;
439 }
440
441 ast_binary* ast_binary_new(lex_ctx_t ctx, int op,
442                            ast_expression* left, ast_expression* right)
443 {
444     ast_instantiate(ast_binary, ctx, ast_binary_delete);
445     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_binary_codegen);
446
447     if (ast_istype(right, ast_unary) && OPTS_OPTIMIZATION(OPTIM_PEEPHOLE)) {
448         ast_unary      *unary  = ((ast_unary*)right);
449         ast_expression *normal = unary->operand;
450
451         /* make a-(-b) => a + b */
452         if (unary->op == VINSTR_NEG_F || unary->op == VINSTR_NEG_V) {
453             if (op == INSTR_SUB_F) {
454                 op = INSTR_ADD_F;
455                 right = normal;
456                 ++opts_optimizationcount[OPTIM_PEEPHOLE];
457             } else if (op == INSTR_SUB_V) {
458                 op = INSTR_ADD_V;
459                 right = normal;
460                 ++opts_optimizationcount[OPTIM_PEEPHOLE];
461             }
462         }
463     }
464
465     self->op = op;
466     self->left = left;
467     self->right = right;
468     self->right_first = false;
469
470     ast_propagate_effects(self, left);
471     ast_propagate_effects(self, right);
472
473     if (op >= INSTR_EQ_F && op <= INSTR_GT)
474         self->expression.vtype = TYPE_FLOAT;
475     else if (op == INSTR_AND || op == INSTR_OR) {
476         if (OPTS_FLAG(PERL_LOGIC))
477             ast_type_adopt(self, right);
478         else
479             self->expression.vtype = TYPE_FLOAT;
480     }
481     else if (op == INSTR_BITAND || op == INSTR_BITOR)
482         self->expression.vtype = TYPE_FLOAT;
483     else if (op == INSTR_MUL_VF || op == INSTR_MUL_FV)
484         self->expression.vtype = TYPE_VECTOR;
485     else if (op == INSTR_MUL_V)
486         self->expression.vtype = TYPE_FLOAT;
487     else
488         self->expression.vtype = left->vtype;
489
490     /* references all */
491     self->refs = AST_REF_ALL;
492
493     return self;
494 }
495
496 void ast_binary_delete(ast_binary *self)
497 {
498     if (self->refs & AST_REF_LEFT)  ast_unref(self->left);
499     if (self->refs & AST_REF_RIGHT) ast_unref(self->right);
500
501     ast_expression_delete((ast_expression*)self);
502     mem_d(self);
503 }
504
505 ast_binstore* ast_binstore_new(lex_ctx_t ctx, int storop, int op,
506                                ast_expression* left, ast_expression* right)
507 {
508     ast_instantiate(ast_binstore, ctx, ast_binstore_delete);
509     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_binstore_codegen);
510
511     ast_side_effects(self) = true;
512
513     self->opstore = storop;
514     self->opbin   = op;
515     self->dest    = left;
516     self->source  = right;
517
518     self->keep_dest = false;
519
520     ast_type_adopt(self, left);
521     return self;
522 }
523
524 void ast_binstore_delete(ast_binstore *self)
525 {
526     if (!self->keep_dest)
527         ast_unref(self->dest);
528     ast_unref(self->source);
529     ast_expression_delete((ast_expression*)self);
530     mem_d(self);
531 }
532
533 ast_unary* ast_unary_new(lex_ctx_t ctx, int op,
534                          ast_expression *expr)
535 {
536     ast_instantiate(ast_unary, ctx, ast_unary_delete);
537     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_unary_codegen);
538
539     self->op      = op;
540     self->operand = expr;
541
542
543     if (ast_istype(expr, ast_unary) && OPTS_OPTIMIZATION(OPTIM_PEEPHOLE)) {
544         ast_unary *prev = (ast_unary*)((ast_unary*)expr)->operand;
545
546         /* Handle for double negation */
547         if (((ast_unary*)expr)->op == op)
548             prev = (ast_unary*)((ast_unary*)expr)->operand;
549
550         if (ast_istype(prev, ast_unary)) {
551             ast_expression_delete((ast_expression*)self);
552             mem_d(self);
553             ++opts_optimizationcount[OPTIM_PEEPHOLE];
554             return prev;
555         }
556     }
557
558     ast_propagate_effects(self, expr);
559
560     if ((op >= INSTR_NOT_F && op <= INSTR_NOT_FNC) || op == VINSTR_NEG_F) {
561         self->expression.vtype = TYPE_FLOAT;
562     } else if (op == VINSTR_NEG_V) {
563         self->expression.vtype = TYPE_VECTOR;
564     } else {
565         compile_error(ctx, "cannot determine type of unary operation %s", util_instr_str[op]);
566     }
567
568     return self;
569 }
570
571 void ast_unary_delete(ast_unary *self)
572 {
573     if (self->operand) ast_unref(self->operand);
574     ast_expression_delete((ast_expression*)self);
575     mem_d(self);
576 }
577
578 ast_return* ast_return_new(lex_ctx_t ctx, ast_expression *expr)
579 {
580     ast_instantiate(ast_return, ctx, ast_return_delete);
581     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_return_codegen);
582
583     self->operand = expr;
584
585     if (expr)
586         ast_propagate_effects(self, expr);
587
588     return self;
589 }
590
591 void ast_return_delete(ast_return *self)
592 {
593     if (self->operand)
594         ast_unref(self->operand);
595     ast_expression_delete((ast_expression*)self);
596     mem_d(self);
597 }
598
599 ast_entfield* ast_entfield_new(lex_ctx_t ctx, ast_expression *entity, ast_expression *field)
600 {
601     if (field->vtype != TYPE_FIELD) {
602         compile_error(ctx, "ast_entfield_new with expression not of type field");
603         return NULL;
604     }
605     return ast_entfield_new_force(ctx, entity, field, field->next);
606 }
607
608 ast_entfield* ast_entfield_new_force(lex_ctx_t ctx, ast_expression *entity, ast_expression *field, const ast_expression *outtype)
609 {
610     ast_instantiate(ast_entfield, ctx, ast_entfield_delete);
611
612     if (!outtype) {
613         mem_d(self);
614         /* Error: field has no type... */
615         return NULL;
616     }
617
618     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_entfield_codegen);
619
620     self->entity = entity;
621     self->field  = field;
622     ast_propagate_effects(self, entity);
623     ast_propagate_effects(self, field);
624
625     ast_type_adopt(self, outtype);
626     return self;
627 }
628
629 void ast_entfield_delete(ast_entfield *self)
630 {
631     ast_unref(self->entity);
632     ast_unref(self->field);
633     ast_expression_delete((ast_expression*)self);
634     mem_d(self);
635 }
636
637 ast_member* ast_member_new(lex_ctx_t ctx, ast_expression *owner, unsigned int field, const char *name)
638 {
639     ast_instantiate(ast_member, ctx, ast_member_delete);
640     if (field >= 3) {
641         mem_d(self);
642         return NULL;
643     }
644
645     if (owner->vtype != TYPE_VECTOR &&
646         owner->vtype != TYPE_FIELD) {
647         compile_error(ctx, "member-access on an invalid owner of type %s", type_name[owner->vtype]);
648         mem_d(self);
649         return NULL;
650     }
651
652     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_member_codegen);
653     self->expression.node.keep = true; /* keep */
654
655     if (owner->vtype == TYPE_VECTOR) {
656         self->expression.vtype = TYPE_FLOAT;
657         self->expression.next  = NULL;
658     } else {
659         self->expression.vtype = TYPE_FIELD;
660         self->expression.next = ast_shallow_type(ctx, TYPE_FLOAT);
661     }
662
663     self->rvalue = false;
664     self->owner  = owner;
665     ast_propagate_effects(self, owner);
666
667     self->field = field;
668     if (name)
669         self->name = util_strdup(name);
670     else
671         self->name = NULL;
672
673     return self;
674 }
675
676 void ast_member_delete(ast_member *self)
677 {
678     /* The owner is always an ast_value, which has .keep=true,
679      * also: ast_members are usually deleted after the owner, thus
680      * this will cause invalid access
681     ast_unref(self->owner);
682      * once we allow (expression).x to access a vector-member, we need
683      * to change this: preferably by creating an alternate ast node for this
684      * purpose that is not garbage-collected.
685     */
686     ast_expression_delete((ast_expression*)self);
687     mem_d(self->name);
688     mem_d(self);
689 }
690
691 bool ast_member_set_name(ast_member *self, const char *name)
692 {
693     if (self->name)
694         mem_d((void*)self->name);
695     self->name = util_strdup(name);
696     return !!self->name;
697 }
698
699 ast_array_index* ast_array_index_new(lex_ctx_t ctx, ast_expression *array, ast_expression *index)
700 {
701     ast_expression *outtype;
702     ast_instantiate(ast_array_index, ctx, ast_array_index_delete);
703
704     outtype = array->next;
705     if (!outtype) {
706         mem_d(self);
707         /* Error: field has no type... */
708         return NULL;
709     }
710
711     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_array_index_codegen);
712
713     self->array = array;
714     self->index = index;
715     ast_propagate_effects(self, array);
716     ast_propagate_effects(self, index);
717
718     ast_type_adopt(self, outtype);
719     if (array->vtype == TYPE_FIELD && outtype->vtype == TYPE_ARRAY) {
720         if (self->expression.vtype != TYPE_ARRAY) {
721             compile_error(ast_ctx(self), "array_index node on type");
722             ast_array_index_delete(self);
723             return NULL;
724         }
725         self->array = outtype;
726         self->expression.vtype = TYPE_FIELD;
727     }
728
729     return self;
730 }
731
732 void ast_array_index_delete(ast_array_index *self)
733 {
734     if (self->array)
735         ast_unref(self->array);
736     if (self->index)
737         ast_unref(self->index);
738     ast_expression_delete((ast_expression*)self);
739     mem_d(self);
740 }
741
742 ast_argpipe* ast_argpipe_new(lex_ctx_t ctx, ast_expression *index)
743 {
744     ast_instantiate(ast_argpipe, ctx, ast_argpipe_delete);
745     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_argpipe_codegen);
746     self->index = index;
747     self->expression.vtype = TYPE_NOEXPR;
748     return self;
749 }
750
751 void ast_argpipe_delete(ast_argpipe *self)
752 {
753     if (self->index)
754         ast_unref(self->index);
755     ast_expression_delete((ast_expression*)self);
756     mem_d(self);
757 }
758
759 ast_ifthen* ast_ifthen_new(lex_ctx_t ctx, ast_expression *cond, ast_expression *ontrue, ast_expression *onfalse)
760 {
761     ast_instantiate(ast_ifthen, ctx, ast_ifthen_delete);
762     if (!ontrue && !onfalse) {
763         /* because it is invalid */
764         mem_d(self);
765         return NULL;
766     }
767     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_ifthen_codegen);
768
769     self->cond     = cond;
770     self->on_true  = ontrue;
771     self->on_false = onfalse;
772     ast_propagate_effects(self, cond);
773     if (ontrue)
774         ast_propagate_effects(self, ontrue);
775     if (onfalse)
776         ast_propagate_effects(self, onfalse);
777
778     return self;
779 }
780
781 void ast_ifthen_delete(ast_ifthen *self)
782 {
783     ast_unref(self->cond);
784     if (self->on_true)
785         ast_unref(self->on_true);
786     if (self->on_false)
787         ast_unref(self->on_false);
788     ast_expression_delete((ast_expression*)self);
789     mem_d(self);
790 }
791
792 ast_ternary* ast_ternary_new(lex_ctx_t ctx, ast_expression *cond, ast_expression *ontrue, ast_expression *onfalse)
793 {
794     ast_expression *exprtype = ontrue;
795     ast_instantiate(ast_ternary, ctx, ast_ternary_delete);
796     /* This time NEITHER must be NULL */
797     if (!ontrue || !onfalse) {
798         mem_d(self);
799         return NULL;
800     }
801     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_ternary_codegen);
802
803     self->cond     = cond;
804     self->on_true  = ontrue;
805     self->on_false = onfalse;
806     ast_propagate_effects(self, cond);
807     ast_propagate_effects(self, ontrue);
808     ast_propagate_effects(self, onfalse);
809
810     if (ontrue->vtype == TYPE_NIL)
811         exprtype = onfalse;
812     ast_type_adopt(self, exprtype);
813
814     return self;
815 }
816
817 void ast_ternary_delete(ast_ternary *self)
818 {
819     /* the if()s are only there because computed-gotos can set them
820      * to NULL
821      */
822     if (self->cond)     ast_unref(self->cond);
823     if (self->on_true)  ast_unref(self->on_true);
824     if (self->on_false) ast_unref(self->on_false);
825     ast_expression_delete((ast_expression*)self);
826     mem_d(self);
827 }
828
829 ast_loop* ast_loop_new(lex_ctx_t ctx,
830                        ast_expression *initexpr,
831                        ast_expression *precond, bool pre_not,
832                        ast_expression *postcond, bool post_not,
833                        ast_expression *increment,
834                        ast_expression *body)
835 {
836     ast_instantiate(ast_loop, ctx, ast_loop_delete);
837     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_loop_codegen);
838
839     self->initexpr  = initexpr;
840     self->precond   = precond;
841     self->postcond  = postcond;
842     self->increment = increment;
843     self->body      = body;
844
845     self->pre_not   = pre_not;
846     self->post_not  = post_not;
847
848     if (initexpr)
849         ast_propagate_effects(self, initexpr);
850     if (precond)
851         ast_propagate_effects(self, precond);
852     if (postcond)
853         ast_propagate_effects(self, postcond);
854     if (increment)
855         ast_propagate_effects(self, increment);
856     if (body)
857         ast_propagate_effects(self, body);
858
859     return self;
860 }
861
862 void ast_loop_delete(ast_loop *self)
863 {
864     if (self->initexpr)
865         ast_unref(self->initexpr);
866     if (self->precond)
867         ast_unref(self->precond);
868     if (self->postcond)
869         ast_unref(self->postcond);
870     if (self->increment)
871         ast_unref(self->increment);
872     if (self->body)
873         ast_unref(self->body);
874     ast_expression_delete((ast_expression*)self);
875     mem_d(self);
876 }
877
878 ast_breakcont* ast_breakcont_new(lex_ctx_t ctx, bool iscont, unsigned int levels)
879 {
880     ast_instantiate(ast_breakcont, ctx, ast_breakcont_delete);
881     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_breakcont_codegen);
882
883     self->is_continue = iscont;
884     self->levels      = levels;
885
886     return self;
887 }
888
889 void ast_breakcont_delete(ast_breakcont *self)
890 {
891     ast_expression_delete((ast_expression*)self);
892     mem_d(self);
893 }
894
895 ast_switch* ast_switch_new(lex_ctx_t ctx, ast_expression *op)
896 {
897     ast_instantiate(ast_switch, ctx, ast_switch_delete);
898     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_switch_codegen);
899
900     self->operand = op;
901     self->cases   = NULL;
902
903     ast_propagate_effects(self, op);
904
905     return self;
906 }
907
908 void ast_switch_delete(ast_switch *self)
909 {
910     size_t i;
911     ast_unref(self->operand);
912
913     for (i = 0; i < vec_size(self->cases); ++i) {
914         if (self->cases[i].value)
915             ast_unref(self->cases[i].value);
916         ast_unref(self->cases[i].code);
917     }
918     vec_free(self->cases);
919
920     ast_expression_delete((ast_expression*)self);
921     mem_d(self);
922 }
923
924 ast_label* ast_label_new(lex_ctx_t ctx, const char *name, bool undefined)
925 {
926     ast_instantiate(ast_label, ctx, ast_label_delete);
927     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_label_codegen);
928
929     self->expression.vtype = TYPE_NOEXPR;
930
931     self->name      = util_strdup(name);
932     self->irblock   = NULL;
933     self->gotos     = NULL;
934     self->undefined = undefined;
935
936     return self;
937 }
938
939 void ast_label_delete(ast_label *self)
940 {
941     mem_d((void*)self->name);
942     vec_free(self->gotos);
943     ast_expression_delete((ast_expression*)self);
944     mem_d(self);
945 }
946
947 static void ast_label_register_goto(ast_label *self, ast_goto *g)
948 {
949     vec_push(self->gotos, g);
950 }
951
952 ast_goto* ast_goto_new(lex_ctx_t ctx, const char *name)
953 {
954     ast_instantiate(ast_goto, ctx, ast_goto_delete);
955     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_goto_codegen);
956
957     self->name    = util_strdup(name);
958     self->target  = NULL;
959     self->irblock_from = NULL;
960
961     return self;
962 }
963
964 void ast_goto_delete(ast_goto *self)
965 {
966     mem_d((void*)self->name);
967     ast_expression_delete((ast_expression*)self);
968     mem_d(self);
969 }
970
971 void ast_goto_set_label(ast_goto *self, ast_label *label)
972 {
973     self->target = label;
974 }
975
976 ast_state* ast_state_new(lex_ctx_t ctx, ast_expression *frame, ast_expression *think)
977 {
978     ast_instantiate(ast_state, ctx, ast_state_delete);
979     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_state_codegen);
980     self->framenum  = frame;
981     self->nextthink = think;
982     return self;
983 }
984
985 void ast_state_delete(ast_state *self)
986 {
987     if (self->framenum)
988         ast_unref(self->framenum);
989     if (self->nextthink)
990         ast_unref(self->nextthink);
991
992     ast_expression_delete((ast_expression*)self);
993     mem_d(self);
994 }
995
996 ast_call* ast_call_new(lex_ctx_t ctx,
997                        ast_expression *funcexpr)
998 {
999     ast_instantiate(ast_call, ctx, ast_call_delete);
1000     if (!funcexpr->next) {
1001         compile_error(ctx, "not a function");
1002         mem_d(self);
1003         return NULL;
1004     }
1005     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_call_codegen);
1006
1007     ast_side_effects(self) = true;
1008
1009     self->params   = NULL;
1010     self->func     = funcexpr;
1011     self->va_count = NULL;
1012
1013     ast_type_adopt(self, funcexpr->next);
1014
1015     return self;
1016 }
1017
1018 void ast_call_delete(ast_call *self)
1019 {
1020     size_t i;
1021     for (i = 0; i < vec_size(self->params); ++i)
1022         ast_unref(self->params[i]);
1023     vec_free(self->params);
1024
1025     if (self->func)
1026         ast_unref(self->func);
1027
1028     if (self->va_count)
1029         ast_unref(self->va_count);
1030
1031     ast_expression_delete((ast_expression*)self);
1032     mem_d(self);
1033 }
1034
1035 static bool ast_call_check_vararg(ast_call *self, ast_expression *va_type, ast_expression *exp_type)
1036 {
1037     char texp[1024];
1038     char tgot[1024];
1039     if (!exp_type)
1040         return true;
1041     if (!va_type || !ast_compare_type(va_type, exp_type))
1042     {
1043         if (va_type && exp_type)
1044         {
1045             ast_type_to_string(va_type,  tgot, sizeof(tgot));
1046             ast_type_to_string(exp_type, texp, sizeof(texp));
1047             if (OPTS_FLAG(UNSAFE_VARARGS)) {
1048                 if (compile_warning(ast_ctx(self), WARN_UNSAFE_TYPES,
1049                                     "piped variadic argument differs in type: constrained to type %s, expected type %s",
1050                                     tgot, texp))
1051                     return false;
1052             } else {
1053                 compile_error(ast_ctx(self),
1054                               "piped variadic argument differs in type: constrained to type %s, expected type %s",
1055                               tgot, texp);
1056                 return false;
1057             }
1058         }
1059         else
1060         {
1061             ast_type_to_string(exp_type, texp, sizeof(texp));
1062             if (OPTS_FLAG(UNSAFE_VARARGS)) {
1063                 if (compile_warning(ast_ctx(self), WARN_UNSAFE_TYPES,
1064                                     "piped variadic argument may differ in type: expected type %s",
1065                                     texp))
1066                     return false;
1067             } else {
1068                 compile_error(ast_ctx(self),
1069                               "piped variadic argument may differ in type: expected type %s",
1070                               texp);
1071                 return false;
1072             }
1073         }
1074     }
1075     return true;
1076 }
1077
1078 bool ast_call_check_types(ast_call *self, ast_expression *va_type)
1079 {
1080     char texp[1024];
1081     char tgot[1024];
1082     size_t i;
1083     bool   retval = true;
1084     const  ast_expression *func = self->func;
1085     size_t count = vec_size(self->params);
1086     if (count > vec_size(func->params))
1087         count = vec_size(func->params);
1088
1089     for (i = 0; i < count; ++i) {
1090         if (ast_istype(self->params[i], ast_argpipe)) {
1091             /* warn about type safety instead */
1092             if (i+1 != count) {
1093                 compile_error(ast_ctx(self), "argpipe must be the last parameter to a function call");
1094                 return false;
1095             }
1096             if (!ast_call_check_vararg(self, va_type, (ast_expression*)func->params[i]))
1097                 retval = false;
1098         }
1099         else if (!ast_compare_type(self->params[i], (ast_expression*)(func->params[i])))
1100         {
1101             ast_type_to_string(self->params[i], tgot, sizeof(tgot));
1102             ast_type_to_string((ast_expression*)func->params[i], texp, sizeof(texp));
1103             compile_error(ast_ctx(self), "invalid type for parameter %u in function call: expected %s, got %s",
1104                      (unsigned int)(i+1), texp, tgot);
1105             /* we don't immediately return */
1106             retval = false;
1107         }
1108     }
1109     count = vec_size(self->params);
1110     if (count > vec_size(func->params) && func->varparam) {
1111         for (; i < count; ++i) {
1112             if (ast_istype(self->params[i], ast_argpipe)) {
1113                 /* warn about type safety instead */
1114                 if (i+1 != count) {
1115                     compile_error(ast_ctx(self), "argpipe must be the last parameter to a function call");
1116                     return false;
1117                 }
1118                 if (!ast_call_check_vararg(self, va_type, func->varparam))
1119                     retval = false;
1120             }
1121             else if (!ast_compare_type(self->params[i], func->varparam))
1122             {
1123                 ast_type_to_string(self->params[i], tgot, sizeof(tgot));
1124                 ast_type_to_string(func->varparam, texp, sizeof(texp));
1125                 compile_error(ast_ctx(self), "invalid type for variadic parameter %u in function call: expected %s, got %s",
1126                          (unsigned int)(i+1), texp, tgot);
1127                 /* we don't immediately return */
1128                 retval = false;
1129             }
1130         }
1131     }
1132     return retval;
1133 }
1134
1135 ast_store* ast_store_new(lex_ctx_t ctx, int op,
1136                          ast_expression *dest, ast_expression *source)
1137 {
1138     ast_instantiate(ast_store, ctx, ast_store_delete);
1139     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_store_codegen);
1140
1141     ast_side_effects(self) = true;
1142
1143     self->op = op;
1144     self->dest = dest;
1145     self->source = source;
1146
1147     ast_type_adopt(self, dest);
1148
1149     return self;
1150 }
1151
1152 void ast_store_delete(ast_store *self)
1153 {
1154     ast_unref(self->dest);
1155     ast_unref(self->source);
1156     ast_expression_delete((ast_expression*)self);
1157     mem_d(self);
1158 }
1159
1160 ast_block* ast_block_new(lex_ctx_t ctx)
1161 {
1162     ast_instantiate(ast_block, ctx, ast_block_delete);
1163     ast_expression_init((ast_expression*)self,
1164                         (ast_expression_codegen*)&ast_block_codegen);
1165
1166     self->locals  = NULL;
1167     self->exprs   = NULL;
1168     self->collect = NULL;
1169
1170     return self;
1171 }
1172
1173 bool ast_block_add_expr(ast_block *self, ast_expression *e)
1174 {
1175     ast_propagate_effects(self, e);
1176     vec_push(self->exprs, e);
1177     if (self->expression.next) {
1178         ast_delete(self->expression.next);
1179         self->expression.next = NULL;
1180     }
1181     ast_type_adopt(self, e);
1182     return true;
1183 }
1184
1185 void ast_block_collect(ast_block *self, ast_expression *expr)
1186 {
1187     vec_push(self->collect, expr);
1188     expr->node.keep = true;
1189 }
1190
1191 void ast_block_delete(ast_block *self)
1192 {
1193     size_t i;
1194     for (i = 0; i < vec_size(self->exprs); ++i)
1195         ast_unref(self->exprs[i]);
1196     vec_free(self->exprs);
1197     for (i = 0; i < vec_size(self->locals); ++i)
1198         ast_delete(self->locals[i]);
1199     vec_free(self->locals);
1200     for (i = 0; i < vec_size(self->collect); ++i)
1201         ast_delete(self->collect[i]);
1202     vec_free(self->collect);
1203     ast_expression_delete((ast_expression*)self);
1204     mem_d(self);
1205 }
1206
1207 void ast_block_set_type(ast_block *self, ast_expression *from)
1208 {
1209     if (self->expression.next)
1210         ast_delete(self->expression.next);
1211     ast_type_adopt(self, from);
1212 }
1213
1214 ast_function* ast_function_new(lex_ctx_t ctx, const char *name, ast_value *vtype)
1215 {
1216     ast_instantiate(ast_function, ctx, ast_function_delete);
1217
1218     if (!vtype) {
1219         compile_error(ast_ctx(self), "internal error: ast_function_new condition 0");
1220         goto cleanup;
1221     } else if (vtype->hasvalue || vtype->expression.vtype != TYPE_FUNCTION) {
1222         compile_error(ast_ctx(self), "internal error: ast_function_new condition %i %i type=%i (probably 2 bodies?)",
1223                  (int)!vtype,
1224                  (int)vtype->hasvalue,
1225                  vtype->expression.vtype);
1226         goto cleanup;
1227     }
1228
1229     self->vtype  = vtype;
1230     self->name   = name ? util_strdup(name) : NULL;
1231     self->blocks = NULL;
1232
1233     self->labelcount = 0;
1234     self->builtin = 0;
1235
1236     self->ir_func = NULL;
1237     self->curblock = NULL;
1238
1239     self->breakblocks    = NULL;
1240     self->continueblocks = NULL;
1241
1242     vtype->hasvalue = true;
1243     vtype->constval.vfunc = self;
1244
1245     self->varargs          = NULL;
1246     self->argc             = NULL;
1247     self->fixedparams      = NULL;
1248     self->return_value     = NULL;
1249
1250     self->static_names     = NULL;
1251     self->static_count     = 0;
1252
1253     return self;
1254
1255 cleanup:
1256     mem_d(self);
1257     return NULL;
1258 }
1259
1260 void ast_function_delete(ast_function *self)
1261 {
1262     size_t i;
1263     if (self->name)
1264         mem_d((void*)self->name);
1265     if (self->vtype) {
1266         /* ast_value_delete(self->vtype); */
1267         self->vtype->hasvalue = false;
1268         self->vtype->constval.vfunc = NULL;
1269         /* We use unref - if it was stored in a global table it is supposed
1270          * to be deleted from *there*
1271          */
1272         ast_unref(self->vtype);
1273     }
1274     for (i = 0; i < vec_size(self->static_names); ++i)
1275         mem_d(self->static_names[i]);
1276     vec_free(self->static_names);
1277     for (i = 0; i < vec_size(self->blocks); ++i)
1278         ast_delete(self->blocks[i]);
1279     vec_free(self->blocks);
1280     vec_free(self->breakblocks);
1281     vec_free(self->continueblocks);
1282     if (self->varargs)
1283         ast_delete(self->varargs);
1284     if (self->argc)
1285         ast_delete(self->argc);
1286     if (self->fixedparams)
1287         ast_unref(self->fixedparams);
1288     if (self->return_value)
1289         ast_unref(self->return_value);
1290     mem_d(self);
1291 }
1292
1293 const char* ast_function_label(ast_function *self, const char *prefix)
1294 {
1295     size_t id;
1296     size_t len;
1297     char  *from;
1298
1299     if (!OPTS_OPTION_BOOL(OPTION_DUMP)    &&
1300         !OPTS_OPTION_BOOL(OPTION_DUMPFIN) &&
1301         !OPTS_OPTION_BOOL(OPTION_DEBUG))
1302     {
1303         return NULL;
1304     }
1305
1306     id  = (self->labelcount++);
1307     len = strlen(prefix);
1308
1309     from = self->labelbuf + sizeof(self->labelbuf)-1;
1310     *from-- = 0;
1311     do {
1312         *from-- = (id%10) + '0';
1313         id /= 10;
1314     } while (id);
1315     ++from;
1316     memcpy(from - len, prefix, len);
1317     return from - len;
1318 }
1319
1320 /*********************************************************************/
1321 /* AST codegen part
1322  * by convention you must never pass NULL to the 'ir_value **out'
1323  * parameter. If you really don't care about the output, pass a dummy.
1324  * But I can't imagine a pituation where the output is truly unnecessary.
1325  */
1326
1327 static void _ast_codegen_output_type(ast_expression *self, ir_value *out)
1328 {
1329     if (out->vtype == TYPE_FIELD)
1330         out->fieldtype = self->next->vtype;
1331     if (out->vtype == TYPE_FUNCTION)
1332         out->outtype = self->next->vtype;
1333 }
1334
1335 #define codegen_output_type(a,o) (_ast_codegen_output_type(&((a)->expression),(o)))
1336
1337 bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_value **out)
1338 {
1339     (void)func;
1340     (void)lvalue;
1341     if (self->expression.vtype == TYPE_NIL) {
1342         *out = func->ir_func->owner->nil;
1343         return true;
1344     }
1345     /* NOTE: This is the codegen for a variable used in an expression.
1346      * It is not the codegen to generate the value. For this purpose,
1347      * ast_local_codegen and ast_global_codegen are to be used before this
1348      * is executed. ast_function_codegen should take care of its locals,
1349      * and the ast-user should take care of ast_global_codegen to be used
1350      * on all the globals.
1351      */
1352     if (!self->ir_v) {
1353         char tname[1024]; /* typename is reserved in C++ */
1354         ast_type_to_string((ast_expression*)self, tname, sizeof(tname));
1355         compile_error(ast_ctx(self), "ast_value used before generated %s %s", tname, self->name);
1356         return false;
1357     }
1358     *out = self->ir_v;
1359     return true;
1360 }
1361
1362 static bool ast_global_array_set(ast_value *self)
1363 {
1364     size_t count = vec_size(self->initlist);
1365     size_t i;
1366
1367     if (count > self->expression.count) {
1368         compile_error(ast_ctx(self), "too many elements in initializer");
1369         count = self->expression.count;
1370     }
1371     else if (count < self->expression.count) {
1372         /* add this?
1373         compile_warning(ast_ctx(self), "not all elements are initialized");
1374         */
1375     }
1376
1377     for (i = 0; i != count; ++i) {
1378         switch (self->expression.next->vtype) {
1379             case TYPE_FLOAT:
1380                 if (!ir_value_set_float(self->ir_values[i], self->initlist[i].vfloat))
1381                     return false;
1382                 break;
1383             case TYPE_VECTOR:
1384                 if (!ir_value_set_vector(self->ir_values[i], self->initlist[i].vvec))
1385                     return false;
1386                 break;
1387             case TYPE_STRING:
1388                 if (!ir_value_set_string(self->ir_values[i], self->initlist[i].vstring))
1389                     return false;
1390                 break;
1391             case TYPE_ARRAY:
1392                 /* we don't support them in any other place yet either */
1393                 compile_error(ast_ctx(self), "TODO: nested arrays");
1394                 return false;
1395             case TYPE_FUNCTION:
1396                 /* this requiers a bit more work - similar to the fields I suppose */
1397                 compile_error(ast_ctx(self), "global of type function not properly generated");
1398                 return false;
1399             case TYPE_FIELD:
1400                 if (!self->initlist[i].vfield) {
1401                     compile_error(ast_ctx(self), "field constant without vfield set");
1402                     return false;
1403                 }
1404                 if (!self->initlist[i].vfield->ir_v) {
1405                     compile_error(ast_ctx(self), "field constant generated before its field");
1406                     return false;
1407                 }
1408                 if (!ir_value_set_field(self->ir_values[i], self->initlist[i].vfield->ir_v))
1409                     return false;
1410                 break;
1411             default:
1412                 compile_error(ast_ctx(self), "TODO: global constant type %i", self->expression.vtype);
1413                 break;
1414         }
1415     }
1416     return true;
1417 }
1418
1419 static bool check_array(ast_value *self, ast_value *array)
1420 {
1421     if (array->expression.flags & AST_FLAG_ARRAY_INIT && !array->initlist) {
1422         compile_error(ast_ctx(self), "array without size: %s", self->name);
1423         return false;
1424     }
1425     /* we are lame now - considering the way QC works we won't tolerate arrays > 1024 elements */
1426     if (!array->expression.count || array->expression.count > OPTS_OPTION_U32(OPTION_MAX_ARRAY_SIZE)) {
1427         compile_error(ast_ctx(self), "Invalid array of size %lu", (unsigned long)array->expression.count);
1428         return false;
1429     }
1430     return true;
1431 }
1432
1433 bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
1434 {
1435     ir_value *v = NULL;
1436
1437     if (self->expression.vtype == TYPE_NIL) {
1438         compile_error(ast_ctx(self), "internal error: trying to generate a variable of TYPE_NIL");
1439         return false;
1440     }
1441
1442     if (self->hasvalue && self->expression.vtype == TYPE_FUNCTION)
1443     {
1444         ir_function *func = ir_builder_create_function(ir, self->name, self->expression.next->vtype);
1445         if (!func)
1446             return false;
1447         func->context = ast_ctx(self);
1448         func->value->context = ast_ctx(self);
1449
1450         self->constval.vfunc->ir_func = func;
1451         self->ir_v = func->value;
1452         if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
1453             self->ir_v->flags |= IR_FLAG_INCLUDE_DEF;
1454         if (self->expression.flags & AST_FLAG_ERASEABLE)
1455             self->ir_v->flags |= IR_FLAG_ERASEABLE;
1456         if (self->expression.flags & AST_FLAG_BLOCK_COVERAGE)
1457             func->flags |= IR_FLAG_BLOCK_COVERAGE;
1458         /* The function is filled later on ast_function_codegen... */
1459         return true;
1460     }
1461
1462     if (isfield && self->expression.vtype == TYPE_FIELD) {
1463         ast_expression *fieldtype = self->expression.next;
1464
1465         if (self->hasvalue) {
1466             compile_error(ast_ctx(self), "TODO: constant field pointers with value");
1467             goto error;
1468         }
1469
1470         if (fieldtype->vtype == TYPE_ARRAY) {
1471             size_t ai;
1472             char   *name;
1473             size_t  namelen;
1474
1475             ast_expression *elemtype;
1476             int             vtype;
1477             ast_value      *array = (ast_value*)fieldtype;
1478
1479             if (!ast_istype(fieldtype, ast_value)) {
1480                 compile_error(ast_ctx(self), "internal error: ast_value required");
1481                 return false;
1482             }
1483
1484             if (!check_array(self, array))
1485                 return false;
1486
1487             elemtype = array->expression.next;
1488             vtype = elemtype->vtype;
1489
1490             v = ir_builder_create_field(ir, self->name, vtype);
1491             if (!v) {
1492                 compile_error(ast_ctx(self), "ir_builder_create_global failed on `%s`", self->name);
1493                 return false;
1494             }
1495             v->context = ast_ctx(self);
1496             v->unique_life = true;
1497             v->locked      = true;
1498             array->ir_v = self->ir_v = v;
1499
1500             if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
1501                 self->ir_v->flags |= IR_FLAG_INCLUDE_DEF;
1502             if (self->expression.flags & AST_FLAG_ERASEABLE)
1503                 self->ir_v->flags |= IR_FLAG_ERASEABLE;
1504
1505             namelen = strlen(self->name);
1506             name    = (char*)mem_a(namelen + 16);
1507             util_strncpy(name, self->name, namelen);
1508
1509             array->ir_values = (ir_value**)mem_a(sizeof(array->ir_values[0]) * array->expression.count);
1510             array->ir_values[0] = v;
1511             for (ai = 1; ai < array->expression.count; ++ai) {
1512                 util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
1513                 array->ir_values[ai] = ir_builder_create_field(ir, name, vtype);
1514                 if (!array->ir_values[ai]) {
1515                     mem_d(name);
1516                     compile_error(ast_ctx(self), "ir_builder_create_global failed on `%s`", name);
1517                     return false;
1518                 }
1519                 array->ir_values[ai]->context = ast_ctx(self);
1520                 array->ir_values[ai]->unique_life = true;
1521                 array->ir_values[ai]->locked      = true;
1522                 if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
1523                     self->ir_values[ai]->flags |= IR_FLAG_INCLUDE_DEF;
1524             }
1525             mem_d(name);
1526         }
1527         else
1528         {
1529             v = ir_builder_create_field(ir, self->name, self->expression.next->vtype);
1530             if (!v)
1531                 return false;
1532             v->context = ast_ctx(self);
1533             self->ir_v = v;
1534             if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
1535                 self->ir_v->flags |= IR_FLAG_INCLUDE_DEF;
1536
1537             if (self->expression.flags & AST_FLAG_ERASEABLE)
1538                 self->ir_v->flags |= IR_FLAG_ERASEABLE;
1539         }
1540         return true;
1541     }
1542
1543     if (self->expression.vtype == TYPE_ARRAY) {
1544         size_t ai;
1545         char   *name;
1546         size_t  namelen;
1547
1548         ast_expression *elemtype = self->expression.next;
1549         int vtype = elemtype->vtype;
1550
1551         if (self->expression.flags & AST_FLAG_ARRAY_INIT && !self->expression.count) {
1552             compile_error(ast_ctx(self), "array `%s' has no size", self->name);
1553             return false;
1554         }
1555
1556         /* same as with field arrays */
1557         if (!check_array(self, self))
1558             return false;
1559
1560         v = ir_builder_create_global(ir, self->name, vtype);
1561         if (!v) {
1562             compile_error(ast_ctx(self), "ir_builder_create_global failed `%s`", self->name);
1563             return false;
1564         }
1565         v->context = ast_ctx(self);
1566         v->unique_life = true;
1567         v->locked      = true;
1568
1569         if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
1570             v->flags |= IR_FLAG_INCLUDE_DEF;
1571         if (self->expression.flags & AST_FLAG_ERASEABLE)
1572             self->ir_v->flags |= IR_FLAG_ERASEABLE;
1573
1574         namelen = strlen(self->name);
1575         name    = (char*)mem_a(namelen + 16);
1576         util_strncpy(name, self->name, namelen);
1577
1578         self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->expression.count);
1579         self->ir_values[0] = v;
1580         for (ai = 1; ai < self->expression.count; ++ai) {
1581             util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
1582             self->ir_values[ai] = ir_builder_create_global(ir, name, vtype);
1583             if (!self->ir_values[ai]) {
1584                 mem_d(name);
1585                 compile_error(ast_ctx(self), "ir_builder_create_global failed `%s`", name);
1586                 return false;
1587             }
1588             self->ir_values[ai]->context = ast_ctx(self);
1589             self->ir_values[ai]->unique_life = true;
1590             self->ir_values[ai]->locked      = true;
1591             if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
1592                 self->ir_values[ai]->flags |= IR_FLAG_INCLUDE_DEF;
1593         }
1594         mem_d(name);
1595     }
1596     else
1597     {
1598         /* Arrays don't do this since there's no "array" value which spans across the
1599          * whole thing.
1600          */
1601         v = ir_builder_create_global(ir, self->name, self->expression.vtype);
1602         if (!v) {
1603             compile_error(ast_ctx(self), "ir_builder_create_global failed on `%s`", self->name);
1604             return false;
1605         }
1606         codegen_output_type(self, v);
1607         v->context = ast_ctx(self);
1608     }
1609
1610     /* link us to the ir_value */
1611     v->cvq = self->cvq;
1612     self->ir_v = v;
1613
1614     if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
1615         self->ir_v->flags |= IR_FLAG_INCLUDE_DEF;
1616     if (self->expression.flags & AST_FLAG_ERASEABLE)
1617         self->ir_v->flags |= IR_FLAG_ERASEABLE;
1618
1619     /* initialize */
1620     if (self->hasvalue) {
1621         switch (self->expression.vtype)
1622         {
1623             case TYPE_FLOAT:
1624                 if (!ir_value_set_float(v, self->constval.vfloat))
1625                     goto error;
1626                 break;
1627             case TYPE_VECTOR:
1628                 if (!ir_value_set_vector(v, self->constval.vvec))
1629                     goto error;
1630                 break;
1631             case TYPE_STRING:
1632                 if (!ir_value_set_string(v, self->constval.vstring))
1633                     goto error;
1634                 break;
1635             case TYPE_ARRAY:
1636                 ast_global_array_set(self);
1637                 break;
1638             case TYPE_FUNCTION:
1639                 compile_error(ast_ctx(self), "global of type function not properly generated");
1640                 goto error;
1641                 /* Cannot generate an IR value for a function,
1642                  * need a pointer pointing to a function rather.
1643                  */
1644             case TYPE_FIELD:
1645                 if (!self->constval.vfield) {
1646                     compile_error(ast_ctx(self), "field constant without vfield set");
1647                     goto error;
1648                 }
1649                 if (!self->constval.vfield->ir_v) {
1650                     compile_error(ast_ctx(self), "field constant generated before its field");
1651                     goto error;
1652                 }
1653                 if (!ir_value_set_field(v, self->constval.vfield->ir_v))
1654                     goto error;
1655                 break;
1656             default:
1657                 compile_error(ast_ctx(self), "TODO: global constant type %i", self->expression.vtype);
1658                 break;
1659         }
1660     }
1661     return true;
1662
1663 error: /* clean up */
1664     if(v) ir_value_delete(v);
1665     return false;
1666 }
1667
1668 static bool ast_local_codegen(ast_value *self, ir_function *func, bool param)
1669 {
1670     ir_value *v = NULL;
1671
1672     if (self->expression.vtype == TYPE_NIL) {
1673         compile_error(ast_ctx(self), "internal error: trying to generate a variable of TYPE_NIL");
1674         return false;
1675     }
1676
1677     if (self->hasvalue && self->expression.vtype == TYPE_FUNCTION)
1678     {
1679         /* Do we allow local functions? I think not...
1680          * this is NOT a function pointer atm.
1681          */
1682         return false;
1683     }
1684
1685     if (self->expression.vtype == TYPE_ARRAY) {
1686         size_t ai;
1687         char   *name;
1688         size_t  namelen;
1689
1690         ast_expression *elemtype = self->expression.next;
1691         int vtype = elemtype->vtype;
1692
1693         func->flags |= IR_FLAG_HAS_ARRAYS;
1694
1695         if (param && !(self->expression.flags & AST_FLAG_IS_VARARG)) {
1696             compile_error(ast_ctx(self), "array-parameters are not supported");
1697             return false;
1698         }
1699
1700         /* we are lame now - considering the way QC works we won't tolerate arrays > 1024 elements */
1701         if (!check_array(self, self))
1702             return false;
1703
1704         self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->expression.count);
1705         if (!self->ir_values) {
1706             compile_error(ast_ctx(self), "failed to allocate array values");
1707             return false;
1708         }
1709
1710         v = ir_function_create_local(func, self->name, vtype, param);
1711         if (!v) {
1712             compile_error(ast_ctx(self), "internal error: ir_function_create_local failed");
1713             return false;
1714         }
1715         v->context = ast_ctx(self);
1716         v->unique_life = true;
1717         v->locked      = true;
1718
1719         namelen = strlen(self->name);
1720         name    = (char*)mem_a(namelen + 16);
1721         util_strncpy(name, self->name, namelen);
1722
1723         self->ir_values[0] = v;
1724         for (ai = 1; ai < self->expression.count; ++ai) {
1725             util_snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
1726             self->ir_values[ai] = ir_function_create_local(func, name, vtype, param);
1727             if (!self->ir_values[ai]) {
1728                 compile_error(ast_ctx(self), "internal_error: ir_builder_create_global failed on `%s`", name);
1729                 return false;
1730             }
1731             self->ir_values[ai]->context = ast_ctx(self);
1732             self->ir_values[ai]->unique_life = true;
1733             self->ir_values[ai]->locked      = true;
1734         }
1735         mem_d(name);
1736     }
1737     else
1738     {
1739         v = ir_function_create_local(func, self->name, self->expression.vtype, param);
1740         if (!v)
1741             return false;
1742         codegen_output_type(self, v);
1743         v->context = ast_ctx(self);
1744     }
1745
1746     /* A constant local... hmmm...
1747      * I suppose the IR will have to deal with this
1748      */
1749     if (self->hasvalue) {
1750         switch (self->expression.vtype)
1751         {
1752             case TYPE_FLOAT:
1753                 if (!ir_value_set_float(v, self->constval.vfloat))
1754                     goto error;
1755                 break;
1756             case TYPE_VECTOR:
1757                 if (!ir_value_set_vector(v, self->constval.vvec))
1758                     goto error;
1759                 break;
1760             case TYPE_STRING:
1761                 if (!ir_value_set_string(v, self->constval.vstring))
1762                     goto error;
1763                 break;
1764             default:
1765                 compile_error(ast_ctx(self), "TODO: global constant type %i", self->expression.vtype);
1766                 break;
1767         }
1768     }
1769
1770     /* link us to the ir_value */
1771     v->cvq = self->cvq;
1772     self->ir_v = v;
1773
1774     if (!ast_generate_accessors(self, func->owner))
1775         return false;
1776     return true;
1777
1778 error: /* clean up */
1779     ir_value_delete(v);
1780     return false;
1781 }
1782
1783 bool ast_generate_accessors(ast_value *self, ir_builder *ir)
1784 {
1785     size_t i;
1786     bool warn = OPTS_WARN(WARN_USED_UNINITIALIZED);
1787     if (!self->setter || !self->getter)
1788         return true;
1789     for (i = 0; i < self->expression.count; ++i) {
1790         if (!self->ir_values) {
1791             compile_error(ast_ctx(self), "internal error: no array values generated for `%s`", self->name);
1792             return false;
1793         }
1794         if (!self->ir_values[i]) {
1795             compile_error(ast_ctx(self), "internal error: not all array values have been generated for `%s`", self->name);
1796             return false;
1797         }
1798         if (self->ir_values[i]->life) {
1799             compile_error(ast_ctx(self), "internal error: function containing `%s` already generated", self->name);
1800             return false;
1801         }
1802     }
1803
1804     opts_set(opts.warn, WARN_USED_UNINITIALIZED, false);
1805     if (self->setter) {
1806         if (!ast_global_codegen  (self->setter, ir, false) ||
1807             !ast_function_codegen(self->setter->constval.vfunc, ir) ||
1808             !ir_function_finalize(self->setter->constval.vfunc->ir_func))
1809         {
1810             compile_error(ast_ctx(self), "internal error: failed to generate setter for `%s`", self->name);
1811             opts_set(opts.warn, WARN_USED_UNINITIALIZED, warn);
1812             return false;
1813         }
1814     }
1815     if (self->getter) {
1816         if (!ast_global_codegen  (self->getter, ir, false) ||
1817             !ast_function_codegen(self->getter->constval.vfunc, ir) ||
1818             !ir_function_finalize(self->getter->constval.vfunc->ir_func))
1819         {
1820             compile_error(ast_ctx(self), "internal error: failed to generate getter for `%s`", self->name);
1821             opts_set(opts.warn, WARN_USED_UNINITIALIZED, warn);
1822             return false;
1823         }
1824     }
1825     for (i = 0; i < self->expression.count; ++i) {
1826         vec_free(self->ir_values[i]->life);
1827     }
1828     opts_set(opts.warn, WARN_USED_UNINITIALIZED, warn);
1829     return true;
1830 }
1831
1832 bool ast_function_codegen(ast_function *self, ir_builder *ir)
1833 {
1834     ir_function *irf;
1835     ir_value    *dummy;
1836     ast_expression         *ec;
1837     ast_expression_codegen *cgen;
1838
1839     size_t    i;
1840
1841     (void)ir;
1842
1843     irf = self->ir_func;
1844     if (!irf) {
1845         compile_error(ast_ctx(self), "internal error: ast_function's related ast_value was not generated yet");
1846         return false;
1847     }
1848
1849     /* fill the parameter list */
1850     ec = &self->vtype->expression;
1851     for (i = 0; i < vec_size(ec->params); ++i)
1852     {
1853         if (ec->params[i]->expression.vtype == TYPE_FIELD)
1854             vec_push(irf->params, ec->params[i]->expression.next->vtype);
1855         else
1856             vec_push(irf->params, ec->params[i]->expression.vtype);
1857         if (!self->builtin) {
1858             if (!ast_local_codegen(ec->params[i], self->ir_func, true))
1859                 return false;
1860         }
1861     }
1862
1863     if (self->varargs) {
1864         if (!ast_local_codegen(self->varargs, self->ir_func, true))
1865             return false;
1866         irf->max_varargs = self->varargs->expression.count;
1867     }
1868
1869     if (self->builtin) {
1870         irf->builtin = self->builtin;
1871         return true;
1872     }
1873
1874     /* have a local return value variable? */
1875     if (self->return_value) {
1876         if (!ast_local_codegen(self->return_value, self->ir_func, false))
1877             return false;
1878     }
1879
1880     if (!vec_size(self->blocks)) {
1881         compile_error(ast_ctx(self), "function `%s` has no body", self->name);
1882         return false;
1883     }
1884
1885     irf->first = self->curblock = ir_function_create_block(ast_ctx(self), irf, "entry");
1886     if (!self->curblock) {
1887         compile_error(ast_ctx(self), "failed to allocate entry block for `%s`", self->name);
1888         return false;
1889     }
1890
1891     if (self->argc) {
1892         ir_value *va_count;
1893         ir_value *fixed;
1894         ir_value *sub;
1895         if (!ast_local_codegen(self->argc, self->ir_func, true))
1896             return false;
1897         cgen = self->argc->expression.codegen;
1898         if (!(*cgen)((ast_expression*)(self->argc), self, false, &va_count))
1899             return false;
1900         cgen = self->fixedparams->expression.codegen;
1901         if (!(*cgen)((ast_expression*)(self->fixedparams), self, false, &fixed))
1902             return false;
1903         sub = ir_block_create_binop(self->curblock, ast_ctx(self),
1904                                     ast_function_label(self, "va_count"), INSTR_SUB_F,
1905                                     ir_builder_get_va_count(ir), fixed);
1906         if (!sub)
1907             return false;
1908         if (!ir_block_create_store_op(self->curblock, ast_ctx(self), INSTR_STORE_F,
1909                                       va_count, sub))
1910         {
1911             return false;
1912         }
1913     }
1914
1915     for (i = 0; i < vec_size(self->blocks); ++i) {
1916         cgen = self->blocks[i]->expression.codegen;
1917         if (!(*cgen)((ast_expression*)self->blocks[i], self, false, &dummy))
1918             return false;
1919     }
1920
1921     /* TODO: check return types */
1922     if (!self->curblock->final)
1923     {
1924         if (!self->vtype->expression.next ||
1925             self->vtype->expression.next->vtype == TYPE_VOID)
1926         {
1927             return ir_block_create_return(self->curblock, ast_ctx(self), NULL);
1928         }
1929         else if (vec_size(self->curblock->entries) || self->curblock == irf->first)
1930         {
1931             if (self->return_value) {
1932                 cgen = self->return_value->expression.codegen;
1933                 if (!(*cgen)((ast_expression*)(self->return_value), self, false, &dummy))
1934                     return false;
1935                 return ir_block_create_return(self->curblock, ast_ctx(self), dummy);
1936             }
1937             else if (compile_warning(ast_ctx(self), WARN_MISSING_RETURN_VALUES,
1938                                 "control reaches end of non-void function (`%s`) via %s",
1939                                 self->name, self->curblock->label))
1940             {
1941                 return false;
1942             }
1943             return ir_block_create_return(self->curblock, ast_ctx(self), NULL);
1944         }
1945     }
1946     return true;
1947 }
1948
1949 static bool starts_a_label(ast_expression *ex)
1950 {
1951     while (ex && ast_istype(ex, ast_block)) {
1952         ast_block *b = (ast_block*)ex;
1953         ex = b->exprs[0];
1954     }
1955     if (!ex)
1956         return false;
1957     return ast_istype(ex, ast_label);
1958 }
1959
1960 /* Note, you will not see ast_block_codegen generate ir_blocks.
1961  * To the AST and the IR, blocks are 2 different things.
1962  * In the AST it represents a block of code, usually enclosed in
1963  * curly braces {...}.
1964  * While in the IR it represents a block in terms of control-flow.
1965  */
1966 bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_value **out)
1967 {
1968     size_t i;
1969
1970     /* We don't use this
1971      * Note: an ast-representation using the comma-operator
1972      * of the form: (a, b, c) = x should not assign to c...
1973      */
1974     if (lvalue) {
1975         compile_error(ast_ctx(self), "not an l-value (code-block)");
1976         return false;
1977     }
1978
1979     if (self->expression.outr) {
1980         *out = self->expression.outr;
1981         return true;
1982     }
1983
1984     /* output is NULL at first, we'll have each expression
1985      * assign to out output, thus, a comma-operator represention
1986      * using an ast_block will return the last generated value,
1987      * so: (b, c) + a  executed both b and c, and returns c,
1988      * which is then added to a.
1989      */
1990     *out = NULL;
1991
1992     /* generate locals */
1993     for (i = 0; i < vec_size(self->locals); ++i)
1994     {
1995         if (!ast_local_codegen(self->locals[i], func->ir_func, false)) {
1996             if (OPTS_OPTION_BOOL(OPTION_DEBUG))
1997                 compile_error(ast_ctx(self), "failed to generate local `%s`", self->locals[i]->name);
1998             return false;
1999         }
2000     }
2001
2002     for (i = 0; i < vec_size(self->exprs); ++i)
2003     {
2004         ast_expression_codegen *gen;
2005         if (func->curblock->final && !starts_a_label(self->exprs[i])) {
2006             if (compile_warning(ast_ctx(self->exprs[i]), WARN_UNREACHABLE_CODE, "unreachable statement"))
2007                 return false;
2008             continue;
2009         }
2010         gen = self->exprs[i]->codegen;
2011         if (!(*gen)(self->exprs[i], func, false, out))
2012             return false;
2013     }
2014
2015     self->expression.outr = *out;
2016
2017     return true;
2018 }
2019
2020 bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_value **out)
2021 {
2022     ast_expression_codegen *cgen;
2023     ir_value *left  = NULL;
2024     ir_value *right = NULL;
2025
2026     ast_value       *arr;
2027     ast_value       *idx = 0;
2028     ast_array_index *ai = NULL;
2029
2030     if (lvalue && self->expression.outl) {
2031         *out = self->expression.outl;
2032         return true;
2033     }
2034
2035     if (!lvalue && self->expression.outr) {
2036         *out = self->expression.outr;
2037         return true;
2038     }
2039
2040     if (ast_istype(self->dest, ast_array_index))
2041     {
2042
2043         ai = (ast_array_index*)self->dest;
2044         idx = (ast_value*)ai->index;
2045
2046         if (ast_istype(ai->index, ast_value) && idx->hasvalue && idx->cvq == CV_CONST)
2047             ai = NULL;
2048     }
2049
2050     if (ai) {
2051         /* we need to call the setter */
2052         ir_value  *iridx, *funval;
2053         ir_instr  *call;
2054
2055         if (lvalue) {
2056             compile_error(ast_ctx(self), "array-subscript assignment cannot produce lvalues");
2057             return false;
2058         }
2059
2060         arr = (ast_value*)ai->array;
2061         if (!ast_istype(ai->array, ast_value) || !arr->setter) {
2062             compile_error(ast_ctx(self), "value has no setter (%s)", arr->name);
2063             return false;
2064         }
2065
2066         cgen = idx->expression.codegen;
2067         if (!(*cgen)((ast_expression*)(idx), func, false, &iridx))
2068             return false;
2069
2070         cgen = arr->setter->expression.codegen;
2071         if (!(*cgen)((ast_expression*)(arr->setter), func, true, &funval))
2072             return false;
2073
2074         cgen = self->source->codegen;
2075         if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
2076             return false;
2077
2078         call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "store"), funval, false);
2079         if (!call)
2080             return false;
2081         ir_call_param(call, iridx);
2082         ir_call_param(call, right);
2083         self->expression.outr = right;
2084     }
2085     else
2086     {
2087         /* regular code */
2088
2089         cgen = self->dest->codegen;
2090         /* lvalue! */
2091         if (!(*cgen)((ast_expression*)(self->dest), func, true, &left))
2092             return false;
2093         self->expression.outl = left;
2094
2095         cgen = self->source->codegen;
2096         /* rvalue! */
2097         if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
2098             return false;
2099
2100         if (!ir_block_create_store_op(func->curblock, ast_ctx(self), self->op, left, right))
2101             return false;
2102         self->expression.outr = right;
2103     }
2104
2105     /* Theoretically, an assinment returns its left side as an
2106      * lvalue, if we don't need an lvalue though, we return
2107      * the right side as an rvalue, otherwise we have to
2108      * somehow know whether or not we need to dereference the pointer
2109      * on the left side - that is: OP_LOAD if it was an address.
2110      * Also: in original QC we cannot OP_LOADP *anyway*.
2111      */
2112     *out = (lvalue ? left : right);
2113
2114     return true;
2115 }
2116
2117 bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_value **out)
2118 {
2119     ast_expression_codegen *cgen;
2120     ir_value *left, *right;
2121
2122     /* A binary operation cannot yield an l-value */
2123     if (lvalue) {
2124         compile_error(ast_ctx(self), "not an l-value (binop)");
2125         return false;
2126     }
2127
2128     if (self->expression.outr) {
2129         *out = self->expression.outr;
2130         return true;
2131     }
2132
2133     if ((OPTS_FLAG(SHORT_LOGIC) || OPTS_FLAG(PERL_LOGIC)) &&
2134         (self->op == INSTR_AND || self->op == INSTR_OR))
2135     {
2136         /* NOTE: The short-logic path will ignore right_first */
2137
2138         /* short circuit evaluation */
2139         ir_block *other, *merge;
2140         ir_block *from_left, *from_right;
2141         ir_instr *phi;
2142         size_t    merge_id;
2143
2144         /* prepare end-block */
2145         merge_id = vec_size(func->ir_func->blocks);
2146         merge    = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "sce_merge"));
2147
2148         /* generate the left expression */
2149         cgen = self->left->codegen;
2150         if (!(*cgen)((ast_expression*)(self->left), func, false, &left))
2151             return false;
2152         /* remember the block */
2153         from_left = func->curblock;
2154
2155         /* create a new block for the right expression */
2156         other = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "sce_other"));
2157         if (self->op == INSTR_AND) {
2158             /* on AND: left==true -> other */
2159             if (!ir_block_create_if(func->curblock, ast_ctx(self), left, other, merge))
2160                 return false;
2161         } else {
2162             /* on OR: left==false -> other */
2163             if (!ir_block_create_if(func->curblock, ast_ctx(self), left, merge, other))
2164                 return false;
2165         }
2166         /* use the likely flag */
2167         vec_last(func->curblock->instr)->likely = true;
2168
2169         /* enter the right-expression's block */
2170         func->curblock = other;
2171         /* generate */
2172         cgen = self->right->codegen;
2173         if (!(*cgen)((ast_expression*)(self->right), func, false, &right))
2174             return false;
2175         /* remember block */
2176         from_right = func->curblock;
2177
2178         /* jump to the merge block */
2179         if (!ir_block_create_jump(func->curblock, ast_ctx(self), merge))
2180             return false;
2181
2182         vec_remove(func->ir_func->blocks, merge_id, 1);
2183         vec_push(func->ir_func->blocks, merge);
2184
2185         func->curblock = merge;
2186         phi = ir_block_create_phi(func->curblock, ast_ctx(self),
2187                                   ast_function_label(func, "sce_value"),
2188                                   self->expression.vtype);
2189         ir_phi_add(phi, from_left, left);
2190         ir_phi_add(phi, from_right, right);
2191         *out = ir_phi_value(phi);
2192         if (!*out)
2193             return false;
2194
2195         if (!OPTS_FLAG(PERL_LOGIC)) {
2196             /* cast-to-bool */
2197             if (OPTS_FLAG(CORRECT_LOGIC) && (*out)->vtype == TYPE_VECTOR) {
2198                 *out = ir_block_create_unary(func->curblock, ast_ctx(self),
2199                                              ast_function_label(func, "sce_bool_v"),
2200                                              INSTR_NOT_V, *out);
2201                 if (!*out)
2202                     return false;
2203                 *out = ir_block_create_unary(func->curblock, ast_ctx(self),
2204                                              ast_function_label(func, "sce_bool"),
2205                                              INSTR_NOT_F, *out);
2206                 if (!*out)
2207                     return false;
2208             }
2209             else if (OPTS_FLAG(FALSE_EMPTY_STRINGS) && (*out)->vtype == TYPE_STRING) {
2210                 *out = ir_block_create_unary(func->curblock, ast_ctx(self),
2211                                              ast_function_label(func, "sce_bool_s"),
2212                                              INSTR_NOT_S, *out);
2213                 if (!*out)
2214                     return false;
2215                 *out = ir_block_create_unary(func->curblock, ast_ctx(self),
2216                                              ast_function_label(func, "sce_bool"),
2217                                              INSTR_NOT_F, *out);
2218                 if (!*out)
2219                     return false;
2220             }
2221             else {
2222                 *out = ir_block_create_binop(func->curblock, ast_ctx(self),
2223                                              ast_function_label(func, "sce_bool"),
2224                                              INSTR_AND, *out, *out);
2225                 if (!*out)
2226                     return false;
2227             }
2228         }
2229
2230         self->expression.outr = *out;
2231         codegen_output_type(self, *out);
2232         return true;
2233     }
2234
2235     if (self->right_first) {
2236         cgen = self->right->codegen;
2237         if (!(*cgen)((ast_expression*)(self->right), func, false, &right))
2238             return false;
2239         cgen = self->left->codegen;
2240         if (!(*cgen)((ast_expression*)(self->left), func, false, &left))
2241             return false;
2242     } else {
2243         cgen = self->left->codegen;
2244         if (!(*cgen)((ast_expression*)(self->left), func, false, &left))
2245             return false;
2246         cgen = self->right->codegen;
2247         if (!(*cgen)((ast_expression*)(self->right), func, false, &right))
2248             return false;
2249     }
2250
2251     *out = ir_block_create_binop(func->curblock, ast_ctx(self), ast_function_label(func, "bin"),
2252                                  self->op, left, right);
2253     if (!*out)
2254         return false;
2255     self->expression.outr = *out;
2256     codegen_output_type(self, *out);
2257
2258     return true;
2259 }
2260
2261 bool ast_binstore_codegen(ast_binstore *self, ast_function *func, bool lvalue, ir_value **out)
2262 {
2263     ast_expression_codegen *cgen;
2264     ir_value *leftl = NULL, *leftr, *right, *bin;
2265
2266     ast_value       *arr;
2267     ast_value       *idx = 0;
2268     ast_array_index *ai = NULL;
2269     ir_value        *iridx = NULL;
2270
2271     if (lvalue && self->expression.outl) {
2272         *out = self->expression.outl;
2273         return true;
2274     }
2275
2276     if (!lvalue && self->expression.outr) {
2277         *out = self->expression.outr;
2278         return true;
2279     }
2280
2281     if (ast_istype(self->dest, ast_array_index))
2282     {
2283
2284         ai = (ast_array_index*)self->dest;
2285         idx = (ast_value*)ai->index;
2286
2287         if (ast_istype(ai->index, ast_value) && idx->hasvalue && idx->cvq == CV_CONST)
2288             ai = NULL;
2289     }
2290
2291     /* for a binstore we need both an lvalue and an rvalue for the left side */
2292     /* rvalue of destination! */
2293     if (ai) {
2294         cgen = idx->expression.codegen;
2295         if (!(*cgen)((ast_expression*)(idx), func, false, &iridx))
2296             return false;
2297     }
2298     cgen = self->dest->codegen;
2299     if (!(*cgen)((ast_expression*)(self->dest), func, false, &leftr))
2300         return false;
2301
2302     /* source as rvalue only */
2303     cgen = self->source->codegen;
2304     if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
2305         return false;
2306
2307     /* now the binary */
2308     bin = ir_block_create_binop(func->curblock, ast_ctx(self), ast_function_label(func, "binst"),
2309                                 self->opbin, leftr, right);
2310     self->expression.outr = bin;
2311
2312
2313     if (ai) {
2314         /* we need to call the setter */
2315         ir_value  *funval;
2316         ir_instr  *call;
2317
2318         if (lvalue) {
2319             compile_error(ast_ctx(self), "array-subscript assignment cannot produce lvalues");
2320             return false;
2321         }
2322
2323         arr = (ast_value*)ai->array;
2324         if (!ast_istype(ai->array, ast_value) || !arr->setter) {
2325             compile_error(ast_ctx(self), "value has no setter (%s)", arr->name);
2326             return false;
2327         }
2328
2329         cgen = arr->setter->expression.codegen;
2330         if (!(*cgen)((ast_expression*)(arr->setter), func, true, &funval))
2331             return false;
2332
2333         call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "store"), funval, false);
2334         if (!call)
2335             return false;
2336         ir_call_param(call, iridx);
2337         ir_call_param(call, bin);
2338         self->expression.outr = bin;
2339     } else {
2340         /* now store them */
2341         cgen = self->dest->codegen;
2342         /* lvalue of destination */
2343         if (!(*cgen)((ast_expression*)(self->dest), func, true, &leftl))
2344             return false;
2345         self->expression.outl = leftl;
2346
2347         if (!ir_block_create_store_op(func->curblock, ast_ctx(self), self->opstore, leftl, bin))
2348             return false;
2349         self->expression.outr = bin;
2350     }
2351
2352     /* Theoretically, an assinment returns its left side as an
2353      * lvalue, if we don't need an lvalue though, we return
2354      * the right side as an rvalue, otherwise we have to
2355      * somehow know whether or not we need to dereference the pointer
2356      * on the left side - that is: OP_LOAD if it was an address.
2357      * Also: in original QC we cannot OP_LOADP *anyway*.
2358      */
2359     *out = (lvalue ? leftl : bin);
2360
2361     return true;
2362 }
2363
2364 bool ast_unary_codegen(ast_unary *self, ast_function *func, bool lvalue, ir_value **out)
2365 {
2366     ast_expression_codegen *cgen;
2367     ir_value *operand;
2368
2369     /* An unary operation cannot yield an l-value */
2370     if (lvalue) {
2371         compile_error(ast_ctx(self), "not an l-value (binop)");
2372         return false;
2373     }
2374
2375     if (self->expression.outr) {
2376         *out = self->expression.outr;
2377         return true;
2378     }
2379
2380     cgen = self->operand->codegen;
2381     /* lvalue! */
2382     if (!(*cgen)((ast_expression*)(self->operand), func, false, &operand))
2383         return false;
2384
2385     *out = ir_block_create_unary(func->curblock, ast_ctx(self), ast_function_label(func, "unary"),
2386                                  self->op, operand);
2387     if (!*out)
2388         return false;
2389     self->expression.outr = *out;
2390
2391     return true;
2392 }
2393
2394 bool ast_return_codegen(ast_return *self, ast_function *func, bool lvalue, ir_value **out)
2395 {
2396     ast_expression_codegen *cgen;
2397     ir_value *operand;
2398
2399     *out = NULL;
2400
2401     /* In the context of a return operation, we don't actually return
2402      * anything...
2403      */
2404     if (lvalue) {
2405         compile_error(ast_ctx(self), "return-expression is not an l-value");
2406         return false;
2407     }
2408
2409     if (self->expression.outr) {
2410         compile_error(ast_ctx(self), "internal error: ast_return cannot be reused, it bears no result!");
2411         return false;
2412     }
2413     self->expression.outr = (ir_value*)1;
2414
2415     if (self->operand) {
2416         cgen = self->operand->codegen;
2417         /* lvalue! */
2418         if (!(*cgen)((ast_expression*)(self->operand), func, false, &operand))
2419             return false;
2420
2421         if (!ir_block_create_return(func->curblock, ast_ctx(self), operand))
2422             return false;
2423     } else {
2424         if (!ir_block_create_return(func->curblock, ast_ctx(self), NULL))
2425             return false;
2426     }
2427
2428     return true;
2429 }
2430
2431 bool ast_entfield_codegen(ast_entfield *self, ast_function *func, bool lvalue, ir_value **out)
2432 {
2433     ast_expression_codegen *cgen;
2434     ir_value *ent, *field;
2435
2436     /* This function needs to take the 'lvalue' flag into account!
2437      * As lvalue we provide a field-pointer, as rvalue we provide the
2438      * value in a temp.
2439      */
2440
2441     if (lvalue && self->expression.outl) {
2442         *out = self->expression.outl;
2443         return true;
2444     }
2445
2446     if (!lvalue && self->expression.outr) {
2447         *out = self->expression.outr;
2448         return true;
2449     }
2450
2451     cgen = self->entity->codegen;
2452     if (!(*cgen)((ast_expression*)(self->entity), func, false, &ent))
2453         return false;
2454
2455     cgen = self->field->codegen;
2456     if (!(*cgen)((ast_expression*)(self->field), func, false, &field))
2457         return false;
2458
2459     if (lvalue) {
2460         /* address! */
2461         *out = ir_block_create_fieldaddress(func->curblock, ast_ctx(self), ast_function_label(func, "efa"),
2462                                             ent, field);
2463     } else {
2464         *out = ir_block_create_load_from_ent(func->curblock, ast_ctx(self), ast_function_label(func, "efv"),
2465                                              ent, field, self->expression.vtype);
2466         /* Done AFTER error checking:
2467         codegen_output_type(self, *out);
2468         */
2469     }
2470     if (!*out) {
2471         compile_error(ast_ctx(self), "failed to create %s instruction (output type %s)",
2472                  (lvalue ? "ADDRESS" : "FIELD"),
2473                  type_name[self->expression.vtype]);
2474         return false;
2475     }
2476     if (!lvalue)
2477         codegen_output_type(self, *out);
2478
2479     if (lvalue)
2480         self->expression.outl = *out;
2481     else
2482         self->expression.outr = *out;
2483
2484     /* Hm that should be it... */
2485     return true;
2486 }
2487
2488 bool ast_member_codegen(ast_member *self, ast_function *func, bool lvalue, ir_value **out)
2489 {
2490     ast_expression_codegen *cgen;
2491     ir_value *vec;
2492
2493     /* in QC this is always an lvalue */
2494     if (lvalue && self->rvalue) {
2495         compile_error(ast_ctx(self), "not an l-value (member access)");
2496         return false;
2497     }
2498     if (self->expression.outl) {
2499         *out = self->expression.outl;
2500         return true;
2501     }
2502
2503     cgen = self->owner->codegen;
2504     if (!(*cgen)((ast_expression*)(self->owner), func, false, &vec))
2505         return false;
2506
2507     if (vec->vtype != TYPE_VECTOR &&
2508         !(vec->vtype == TYPE_FIELD && self->owner->next->vtype == TYPE_VECTOR))
2509     {
2510         return false;
2511     }
2512
2513     *out = ir_value_vector_member(vec, self->field);
2514     self->expression.outl = *out;
2515
2516     return (*out != NULL);
2517 }
2518
2519 bool ast_array_index_codegen(ast_array_index *self, ast_function *func, bool lvalue, ir_value **out)
2520 {
2521     ast_value *arr;
2522     ast_value *idx;
2523
2524     if (!lvalue && self->expression.outr) {
2525         *out = self->expression.outr;
2526         return true;
2527     }
2528     if (lvalue && self->expression.outl) {
2529         *out = self->expression.outl;
2530         return true;
2531     }
2532
2533     if (!ast_istype(self->array, ast_value)) {
2534         compile_error(ast_ctx(self), "array indexing this way is not supported");
2535         /* note this would actually be pointer indexing because the left side is
2536          * not an actual array but (hopefully) an indexable expression.
2537          * Once we get integer arithmetic, and GADDRESS/GSTORE/GLOAD instruction
2538          * support this path will be filled.
2539          */
2540         return false;
2541     }
2542
2543     arr = (ast_value*)self->array;
2544     idx = (ast_value*)self->index;
2545
2546     if (!ast_istype(self->index, ast_value) || !idx->hasvalue || idx->cvq != CV_CONST) {
2547         /* Time to use accessor functions */
2548         ast_expression_codegen *cgen;
2549         ir_value               *iridx, *funval;
2550         ir_instr               *call;
2551
2552         if (lvalue) {
2553             compile_error(ast_ctx(self), "(.2) array indexing here needs a compile-time constant");
2554             return false;
2555         }
2556
2557         if (!arr->getter) {
2558             compile_error(ast_ctx(self), "value has no getter, don't know how to index it");
2559             return false;
2560         }
2561
2562         cgen = self->index->codegen;
2563         if (!(*cgen)((ast_expression*)(self->index), func, false, &iridx))
2564             return false;
2565
2566         cgen = arr->getter->expression.codegen;
2567         if (!(*cgen)((ast_expression*)(arr->getter), func, true, &funval))
2568             return false;
2569
2570         call = ir_block_create_call(func->curblock, ast_ctx(self), ast_function_label(func, "fetch"), funval, false);
2571         if (!call)
2572             return false;
2573         ir_call_param(call, iridx);
2574
2575         *out = ir_call_value(call);
2576         self->expression.outr = *out;
2577         (*out)->vtype = self->expression.vtype;
2578         codegen_output_type(self, *out);
2579         return true;
2580     }
2581
2582     if (idx->expression.vtype == TYPE_FLOAT) {
2583         unsigned int arridx = idx->constval.vfloat;
2584         if (arridx >= self->array->count)
2585         {
2586             compile_error(ast_ctx(self), "array index out of bounds: %i", arridx);
2587             return false;
2588         }
2589         *out = arr->ir_values[arridx];
2590     }
2591     else if (idx->expression.vtype == TYPE_INTEGER) {
2592         unsigned int arridx = idx->constval.vint;
2593         if (arridx >= self->array->count)
2594         {
2595             compile_error(ast_ctx(self), "array index out of bounds: %i", arridx);
2596             return false;
2597         }
2598         *out = arr->ir_values[arridx];
2599     }
2600     else {
2601         compile_error(ast_ctx(self), "array indexing here needs an integer constant");
2602         return false;
2603     }
2604     (*out)->vtype = self->expression.vtype;
2605     codegen_output_type(self, *out);
2606     return true;
2607 }
2608
2609 bool ast_argpipe_codegen(ast_argpipe *self, ast_function *func, bool lvalue, ir_value **out)
2610 {
2611     *out = NULL;
2612     if (lvalue) {
2613         compile_error(ast_ctx(self), "argpipe node: not an lvalue");
2614         return false;
2615     }
2616     (void)func;
2617     (void)out;
2618     compile_error(ast_ctx(self), "TODO: argpipe codegen not implemented");
2619     return false;
2620 }
2621
2622 bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_value **out)
2623 {
2624     ast_expression_codegen *cgen;
2625
2626     ir_value *condval;
2627     ir_value *dummy;
2628
2629     ir_block *cond;
2630     ir_block *ontrue;
2631     ir_block *onfalse;
2632     ir_block *ontrue_endblock = NULL;
2633     ir_block *onfalse_endblock = NULL;
2634     ir_block *merge = NULL;
2635     int       fold  = 0;
2636
2637     /* We don't output any value, thus also don't care about r/lvalue */
2638     (void)out;
2639     (void)lvalue;
2640
2641     if (self->expression.outr) {
2642         compile_error(ast_ctx(self), "internal error: ast_ifthen cannot be reused, it bears no result!");
2643         return false;
2644     }
2645     self->expression.outr = (ir_value*)1;
2646
2647     /* generate the condition */
2648     cgen = self->cond->codegen;
2649     if (!(*cgen)((ast_expression*)(self->cond), func, false, &condval))
2650         return false;
2651     /* update the block which will get the jump - because short-logic or ternaries may have changed this */
2652     cond = func->curblock;
2653
2654     /* try constant folding away the condition */
2655     if ((fold = fold_cond_ifthen(condval, func, self)) != -1)
2656         return fold;
2657
2658     if (self->on_true) {
2659         /* create on-true block */
2660         ontrue = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "ontrue"));
2661         if (!ontrue)
2662             return false;
2663
2664         /* enter the block */
2665         func->curblock = ontrue;
2666
2667         /* generate */
2668         cgen = self->on_true->codegen;
2669         if (!(*cgen)((ast_expression*)(self->on_true), func, false, &dummy))
2670             return false;
2671
2672         /* we now need to work from the current endpoint */
2673         ontrue_endblock = func->curblock;
2674     } else
2675         ontrue = NULL;
2676
2677     /* on-false path */
2678     if (self->on_false) {
2679         /* create on-false block */
2680         onfalse = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "onfalse"));
2681         if (!onfalse)
2682             return false;
2683
2684         /* enter the block */
2685         func->curblock = onfalse;
2686
2687         /* generate */
2688         cgen = self->on_false->codegen;
2689         if (!(*cgen)((ast_expression*)(self->on_false), func, false, &dummy))
2690             return false;
2691
2692         /* we now need to work from the current endpoint */
2693         onfalse_endblock = func->curblock;
2694     } else
2695         onfalse = NULL;
2696
2697     /* Merge block were they all merge in to */
2698     if (!ontrue || !onfalse || !ontrue_endblock->final || !onfalse_endblock->final)
2699     {
2700         merge = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "endif"));
2701         if (!merge)
2702             return false;
2703         /* add jumps ot the merge block */
2704         if (ontrue && !ontrue_endblock->final && !ir_block_create_jump(ontrue_endblock, ast_ctx(self), merge))
2705             return false;
2706         if (onfalse && !onfalse_endblock->final && !ir_block_create_jump(onfalse_endblock, ast_ctx(self), merge))
2707             return false;
2708
2709         /* Now enter the merge block */
2710         func->curblock = merge;
2711     }
2712
2713     /* we create the if here, that way all blocks are ordered :)
2714      */
2715     if (!ir_block_create_if(cond, ast_ctx(self), condval,
2716                             (ontrue  ? ontrue  : merge),
2717                             (onfalse ? onfalse : merge)))
2718     {
2719         return false;
2720     }
2721
2722     return true;
2723 }
2724
2725 bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_value **out)
2726 {
2727     ast_expression_codegen *cgen;
2728
2729     ir_value *condval;
2730     ir_value *trueval, *falseval;
2731     ir_instr *phi;
2732
2733     ir_block *cond = func->curblock;
2734     ir_block *cond_out = NULL;
2735     ir_block *ontrue, *ontrue_out = NULL;
2736     ir_block *onfalse, *onfalse_out = NULL;
2737     ir_block *merge;
2738     int       fold  = 0;
2739
2740     /* Ternary can never create an lvalue... */
2741     if (lvalue)
2742         return false;
2743
2744     /* In theory it shouldn't be possible to pass through a node twice, but
2745      * in case we add any kind of optimization pass for the AST itself, it
2746      * may still happen, thus we remember a created ir_value and simply return one
2747      * if it already exists.
2748      */
2749     if (self->expression.outr) {
2750         *out = self->expression.outr;
2751         return true;
2752     }
2753
2754     /* In the following, contraty to ast_ifthen, we assume both paths exist. */
2755
2756     /* generate the condition */
2757     func->curblock = cond;
2758     cgen = self->cond->codegen;
2759     if (!(*cgen)((ast_expression*)(self->cond), func, false, &condval))
2760         return false;
2761     cond_out = func->curblock;
2762
2763     /* try constant folding away the condition */
2764     if ((fold = fold_cond_ternary(condval, func, self)) != -1)
2765         return fold;
2766
2767     /* create on-true block */
2768     ontrue = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "tern_T"));
2769     if (!ontrue)
2770         return false;
2771     else
2772     {
2773         /* enter the block */
2774         func->curblock = ontrue;
2775
2776         /* generate */
2777         cgen = self->on_true->codegen;
2778         if (!(*cgen)((ast_expression*)(self->on_true), func, false, &trueval))
2779             return false;
2780
2781         ontrue_out = func->curblock;
2782     }
2783
2784     /* create on-false block */
2785     onfalse = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "tern_F"));
2786     if (!onfalse)
2787         return false;
2788     else
2789     {
2790         /* enter the block */
2791         func->curblock = onfalse;
2792
2793         /* generate */
2794         cgen = self->on_false->codegen;
2795         if (!(*cgen)((ast_expression*)(self->on_false), func, false, &falseval))
2796             return false;
2797
2798         onfalse_out = func->curblock;
2799     }
2800
2801     /* create merge block */
2802     merge = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "tern_out"));
2803     if (!merge)
2804         return false;
2805     /* jump to merge block */
2806     if (!ir_block_create_jump(ontrue_out, ast_ctx(self), merge))
2807         return false;
2808     if (!ir_block_create_jump(onfalse_out, ast_ctx(self), merge))
2809         return false;
2810
2811     /* create if instruction */
2812     if (!ir_block_create_if(cond_out, ast_ctx(self), condval, ontrue, onfalse))
2813         return false;
2814
2815     /* Now enter the merge block */
2816     func->curblock = merge;
2817
2818     /* Here, now, we need a PHI node
2819      * but first some sanity checking...
2820      */
2821     if (trueval->vtype != falseval->vtype && trueval->vtype != TYPE_NIL && falseval->vtype != TYPE_NIL) {
2822         /* error("ternary with different types on the two sides"); */
2823         compile_error(ast_ctx(self), "internal error: ternary operand types invalid");
2824         return false;
2825     }
2826
2827     /* create PHI */
2828     phi = ir_block_create_phi(merge, ast_ctx(self), ast_function_label(func, "phi"), self->expression.vtype);
2829     if (!phi) {
2830         compile_error(ast_ctx(self), "internal error: failed to generate phi node");
2831         return false;
2832     }
2833     ir_phi_add(phi, ontrue_out,  trueval);
2834     ir_phi_add(phi, onfalse_out, falseval);
2835
2836     self->expression.outr = ir_phi_value(phi);
2837     *out = self->expression.outr;
2838
2839     codegen_output_type(self, *out);
2840
2841     return true;
2842 }
2843
2844 bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value **out)
2845 {
2846     ast_expression_codegen *cgen;
2847
2848     ir_value *dummy      = NULL;
2849     ir_value *precond    = NULL;
2850     ir_value *postcond   = NULL;
2851
2852     /* Since we insert some jumps "late" so we have blocks
2853      * ordered "nicely", we need to keep track of the actual end-blocks
2854      * of expressions to add the jumps to.
2855      */
2856     ir_block *bbody      = NULL, *end_bbody      = NULL;
2857     ir_block *bprecond   = NULL, *end_bprecond   = NULL;
2858     ir_block *bpostcond  = NULL, *end_bpostcond  = NULL;
2859     ir_block *bincrement = NULL, *end_bincrement = NULL;
2860     ir_block *bout       = NULL, *bin            = NULL;
2861
2862     /* let's at least move the outgoing block to the end */
2863     size_t    bout_id;
2864
2865     /* 'break' and 'continue' need to be able to find the right blocks */
2866     ir_block *bcontinue     = NULL;
2867     ir_block *bbreak        = NULL;
2868
2869     ir_block *tmpblock      = NULL;
2870
2871     (void)lvalue;
2872     (void)out;
2873
2874     if (self->expression.outr) {
2875         compile_error(ast_ctx(self), "internal error: ast_loop cannot be reused, it bears no result!");
2876         return false;
2877     }
2878     self->expression.outr = (ir_value*)1;
2879
2880     /* NOTE:
2881      * Should we ever need some kind of block ordering, better make this function
2882      * move blocks around than write a block ordering algorithm later... after all
2883      * the ast and ir should work together, not against each other.
2884      */
2885
2886     /* initexpr doesn't get its own block, it's pointless, it could create more blocks
2887      * anyway if for example it contains a ternary.
2888      */
2889     if (self->initexpr)
2890     {
2891         cgen = self->initexpr->codegen;
2892         if (!(*cgen)((ast_expression*)(self->initexpr), func, false, &dummy))
2893             return false;
2894     }
2895
2896     /* Store the block from which we enter this chaos */
2897     bin = func->curblock;
2898
2899     /* The pre-loop condition needs its own block since we
2900      * need to be able to jump to the start of that expression.
2901      */
2902     if (self->precond)
2903     {
2904         bprecond = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "pre_loop_cond"));
2905         if (!bprecond)
2906             return false;
2907
2908         /* the pre-loop-condition the least important place to 'continue' at */
2909         bcontinue = bprecond;
2910
2911         /* enter */
2912         func->curblock = bprecond;
2913
2914         /* generate */
2915         cgen = self->precond->codegen;
2916         if (!(*cgen)((ast_expression*)(self->precond), func, false, &precond))
2917             return false;
2918
2919         end_bprecond = func->curblock;
2920     } else {
2921         bprecond = end_bprecond = NULL;
2922     }
2923
2924     /* Now the next blocks won't be ordered nicely, but we need to
2925      * generate them this early for 'break' and 'continue'.
2926      */
2927     if (self->increment) {
2928         bincrement = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "loop_increment"));
2929         if (!bincrement)
2930             return false;
2931         bcontinue = bincrement; /* increment comes before the pre-loop-condition */
2932     } else {
2933         bincrement = end_bincrement = NULL;
2934     }
2935
2936     if (self->postcond) {
2937         bpostcond = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "post_loop_cond"));
2938         if (!bpostcond)
2939             return false;
2940         bcontinue = bpostcond; /* postcond comes before the increment */
2941     } else {
2942         bpostcond = end_bpostcond = NULL;
2943     }
2944
2945     bout_id = vec_size(func->ir_func->blocks);
2946     bout = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "after_loop"));
2947     if (!bout)
2948         return false;
2949     bbreak = bout;
2950
2951     /* The loop body... */
2952     /* if (self->body) */
2953     {
2954         bbody = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "loop_body"));
2955         if (!bbody)
2956             return false;
2957
2958         /* enter */
2959         func->curblock = bbody;
2960
2961         vec_push(func->breakblocks,    bbreak);
2962         if (bcontinue)
2963             vec_push(func->continueblocks, bcontinue);
2964         else
2965             vec_push(func->continueblocks, bbody);
2966
2967         /* generate */
2968         if (self->body) {
2969             cgen = self->body->codegen;
2970             if (!(*cgen)((ast_expression*)(self->body), func, false, &dummy))
2971                 return false;
2972         }
2973
2974         end_bbody = func->curblock;
2975         vec_pop(func->breakblocks);
2976         vec_pop(func->continueblocks);
2977     }
2978
2979     /* post-loop-condition */
2980     if (self->postcond)
2981     {
2982         /* enter */
2983         func->curblock = bpostcond;
2984
2985         /* generate */
2986         cgen = self->postcond->codegen;
2987         if (!(*cgen)((ast_expression*)(self->postcond), func, false, &postcond))
2988             return false;
2989
2990         end_bpostcond = func->curblock;
2991     }
2992
2993     /* The incrementor */
2994     if (self->increment)
2995     {
2996         /* enter */
2997         func->curblock = bincrement;
2998
2999         /* generate */
3000         cgen = self->increment->codegen;
3001         if (!(*cgen)((ast_expression*)(self->increment), func, false, &dummy))
3002             return false;
3003
3004         end_bincrement = func->curblock;
3005     }
3006
3007     /* In any case now, we continue from the outgoing block */
3008     func->curblock = bout;
3009
3010     /* Now all blocks are in place */
3011     /* From 'bin' we jump to whatever comes first */
3012     if      (bprecond)   tmpblock = bprecond;
3013     else                 tmpblock = bbody;    /* can never be null */
3014
3015     /* DEAD CODE
3016     else if (bpostcond)  tmpblock = bpostcond;
3017     else                 tmpblock = bout;
3018     */
3019
3020     if (!ir_block_create_jump(bin, ast_ctx(self), tmpblock))
3021         return false;
3022
3023     /* From precond */
3024     if (bprecond)
3025     {
3026         ir_block *ontrue, *onfalse;
3027         ontrue = bbody; /* can never be null */
3028
3029         /* all of this is dead code
3030         else if (bincrement) ontrue = bincrement;
3031         else                 ontrue = bpostcond;
3032         */
3033
3034         onfalse = bout;
3035         if (self->pre_not) {
3036             tmpblock = ontrue;
3037             ontrue   = onfalse;
3038             onfalse  = tmpblock;
3039         }
3040         if (!ir_block_create_if(end_bprecond, ast_ctx(self), precond, ontrue, onfalse))
3041             return false;
3042     }
3043
3044     /* from body */
3045     if (bbody)
3046     {
3047         if      (bincrement) tmpblock = bincrement;
3048         else if (bpostcond)  tmpblock = bpostcond;
3049         else if (bprecond)   tmpblock = bprecond;
3050         else                 tmpblock = bbody;
3051         if (!end_bbody->final && !ir_block_create_jump(end_bbody, ast_ctx(self), tmpblock))
3052             return false;
3053     }
3054
3055     /* from increment */
3056     if (bincrement)
3057     {
3058         if      (bpostcond)  tmpblock = bpostcond;
3059         else if (bprecond)   tmpblock = bprecond;
3060         else if (bbody)      tmpblock = bbody;
3061         else                 tmpblock = bout;
3062         if (!ir_block_create_jump(end_bincrement, ast_ctx(self), tmpblock))
3063             return false;
3064     }
3065
3066     /* from postcond */
3067     if (bpostcond)
3068     {
3069         ir_block *ontrue, *onfalse;
3070         if      (bprecond)   ontrue = bprecond;
3071         else                 ontrue = bbody; /* can never be null */
3072
3073         /* all of this is dead code
3074         else if (bincrement) ontrue = bincrement;
3075         else                 ontrue = bpostcond;
3076         */
3077
3078         onfalse = bout;
3079         if (self->post_not) {
3080             tmpblock = ontrue;
3081             ontrue   = onfalse;
3082             onfalse  = tmpblock;
3083         }
3084         if (!ir_block_create_if(end_bpostcond, ast_ctx(self), postcond, ontrue, onfalse))
3085             return false;
3086     }
3087
3088     /* Move 'bout' to the end */
3089     vec_remove(func->ir_func->blocks, bout_id, 1);
3090     vec_push(func->ir_func->blocks, bout);
3091
3092     return true;
3093 }
3094
3095 bool ast_breakcont_codegen(ast_breakcont *self, ast_function *func, bool lvalue, ir_value **out)
3096 {
3097     ir_block *target;
3098
3099     *out = NULL;
3100
3101     if (lvalue) {
3102         compile_error(ast_ctx(self), "break/continue expression is not an l-value");
3103         return false;
3104     }
3105
3106     if (self->expression.outr) {
3107         compile_error(ast_ctx(self), "internal error: ast_breakcont cannot be reused!");
3108         return false;
3109     }
3110     self->expression.outr = (ir_value*)1;
3111
3112     if (self->is_continue)
3113         target = func->continueblocks[vec_size(func->continueblocks)-1-self->levels];
3114     else
3115         target = func->breakblocks[vec_size(func->breakblocks)-1-self->levels];
3116
3117     if (!target) {
3118         compile_error(ast_ctx(self), "%s is lacking a target block", (self->is_continue ? "continue" : "break"));
3119         return false;
3120     }
3121
3122     if (!ir_block_create_jump(func->curblock, ast_ctx(self), target))
3123         return false;
3124     return true;
3125 }
3126
3127 bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_value **out)
3128 {
3129     ast_expression_codegen *cgen;
3130
3131     ast_switch_case *def_case     = NULL;
3132     ir_block        *def_bfall    = NULL;
3133     ir_block        *def_bfall_to = NULL;
3134     bool set_def_bfall_to = false;
3135
3136     ir_value *dummy     = NULL;
3137     ir_value *irop      = NULL;
3138     ir_block *bout      = NULL;
3139     ir_block *bfall     = NULL;
3140     size_t    bout_id;
3141     size_t    c;
3142
3143     char      typestr[1024];
3144     uint16_t  cmpinstr;
3145
3146     if (lvalue) {
3147         compile_error(ast_ctx(self), "switch expression is not an l-value");
3148         return false;
3149     }
3150
3151     if (self->expression.outr) {
3152         compile_error(ast_ctx(self), "internal error: ast_switch cannot be reused!");
3153         return false;
3154     }
3155     self->expression.outr = (ir_value*)1;
3156
3157     (void)lvalue;
3158     (void)out;
3159
3160     cgen = self->operand->codegen;
3161     if (!(*cgen)((ast_expression*)(self->operand), func, false, &irop))
3162         return false;
3163
3164     if (!vec_size(self->cases))
3165         return true;
3166
3167     cmpinstr = type_eq_instr[irop->vtype];
3168     if (cmpinstr >= VINSTR_END) {
3169         ast_type_to_string(self->operand, typestr, sizeof(typestr));
3170         compile_error(ast_ctx(self), "invalid type to perform a switch on: %s", typestr);
3171         return false;
3172     }
3173
3174     bout_id = vec_size(func->ir_func->blocks);
3175     bout = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "after_switch"));
3176     if (!bout)
3177         return false;
3178
3179     /* setup the break block */
3180     vec_push(func->breakblocks, bout);
3181
3182     /* Now create all cases */
3183     for (c = 0; c < vec_size(self->cases); ++c) {
3184         ir_value *cond, *val;
3185         ir_block *bcase, *bnot;
3186         size_t bnot_id;
3187
3188         ast_switch_case *swcase = &self->cases[c];
3189
3190         if (swcase->value) {
3191             /* A regular case */
3192             /* generate the condition operand */
3193             cgen = swcase->value->codegen;
3194             if (!(*cgen)((ast_expression*)(swcase->value), func, false, &val))
3195                 return false;
3196             /* generate the condition */
3197             cond = ir_block_create_binop(func->curblock, ast_ctx(self), ast_function_label(func, "switch_eq"), cmpinstr, irop, val);
3198             if (!cond)
3199                 return false;
3200
3201             bcase = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "case"));
3202             bnot_id = vec_size(func->ir_func->blocks);
3203             bnot = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "not_case"));
3204             if (!bcase || !bnot)
3205                 return false;
3206             if (set_def_bfall_to) {
3207                 set_def_bfall_to = false;
3208                 def_bfall_to = bcase;
3209             }
3210             if (!ir_block_create_if(func->curblock, ast_ctx(self), cond, bcase, bnot))
3211                 return false;
3212
3213             /* Make the previous case-end fall through */
3214             if (bfall && !bfall->final) {
3215                 if (!ir_block_create_jump(bfall, ast_ctx(self), bcase))
3216                     return false;
3217             }
3218
3219             /* enter the case */
3220             func->curblock = bcase;
3221             cgen = swcase->code->codegen;
3222             if (!(*cgen)((ast_expression*)swcase->code, func, false, &dummy))
3223                 return false;
3224
3225             /* remember this block to fall through from */
3226             bfall = func->curblock;
3227
3228             /* enter the else and move it down */
3229             func->curblock = bnot;
3230             vec_remove(func->ir_func->blocks, bnot_id, 1);
3231             vec_push(func->ir_func->blocks, bnot);
3232         } else {
3233             /* The default case */
3234             /* Remember where to fall through from: */
3235             def_bfall = bfall;
3236             bfall     = NULL;
3237             /* remember which case it was */
3238             def_case  = swcase;
3239             /* And the next case will be remembered */
3240             set_def_bfall_to = true;
3241         }
3242     }
3243
3244     /* Jump from the last bnot to bout */
3245     if (bfall && !bfall->final && !ir_block_create_jump(bfall, ast_ctx(self), bout)) {
3246         /*
3247         astwarning(ast_ctx(bfall), WARN_???, "missing break after last case");
3248         */
3249         return false;
3250     }
3251
3252     /* If there was a default case, put it down here */
3253     if (def_case) {
3254         ir_block *bcase;
3255
3256         /* No need to create an extra block */
3257         bcase = func->curblock;
3258
3259         /* Insert the fallthrough jump */
3260         if (def_bfall && !def_bfall->final) {
3261             if (!ir_block_create_jump(def_bfall, ast_ctx(self), bcase))
3262                 return false;
3263         }
3264
3265         /* Now generate the default code */
3266         cgen = def_case->code->codegen;
3267         if (!(*cgen)((ast_expression*)def_case->code, func, false, &dummy))
3268             return false;
3269
3270         /* see if we need to fall through */
3271         if (def_bfall_to && !func->curblock->final)
3272         {
3273             if (!ir_block_create_jump(func->curblock, ast_ctx(self), def_bfall_to))
3274                 return false;
3275         }
3276     }
3277
3278     /* Jump from the last bnot to bout */
3279     if (!func->curblock->final && !ir_block_create_jump(func->curblock, ast_ctx(self), bout))
3280         return false;
3281     /* enter the outgoing block */
3282     func->curblock = bout;
3283
3284     /* restore the break block */
3285     vec_pop(func->breakblocks);
3286
3287     /* Move 'bout' to the end, it's nicer */
3288     vec_remove(func->ir_func->blocks, bout_id, 1);
3289     vec_push(func->ir_func->blocks, bout);
3290
3291     return true;
3292 }
3293
3294 bool ast_label_codegen(ast_label *self, ast_function *func, bool lvalue, ir_value **out)
3295 {
3296     size_t i;
3297     ir_value *dummy;
3298
3299     if (self->undefined) {
3300         compile_error(ast_ctx(self), "internal error: ast_label never defined");
3301         return false;
3302     }
3303
3304     *out = NULL;
3305     if (lvalue) {
3306         compile_error(ast_ctx(self), "internal error: ast_label cannot be an lvalue");
3307         return false;
3308     }
3309
3310     /* simply create a new block and jump to it */
3311     self->irblock = ir_function_create_block(ast_ctx(self), func->ir_func, self->name);
3312     if (!self->irblock) {
3313         compile_error(ast_ctx(self), "failed to allocate label block `%s`", self->name);
3314         return false;
3315     }
3316     if (!func->curblock->final) {
3317         if (!ir_block_create_jump(func->curblock, ast_ctx(self), self->irblock))
3318             return false;
3319     }
3320
3321     /* enter the new block */
3322     func->curblock = self->irblock;
3323
3324     /* Generate all the leftover gotos */
3325     for (i = 0; i < vec_size(self->gotos); ++i) {
3326         if (!ast_goto_codegen(self->gotos[i], func, false, &dummy))
3327             return false;
3328     }
3329
3330     return true;
3331 }
3332
3333 bool ast_goto_codegen(ast_goto *self, ast_function *func, bool lvalue, ir_value **out)
3334 {
3335     *out = NULL;
3336     if (lvalue) {
3337         compile_error(ast_ctx(self), "internal error: ast_goto cannot be an lvalue");
3338         return false;
3339     }
3340
3341     if (self->target->irblock) {
3342         if (self->irblock_from) {
3343             /* we already tried once, this is the callback */
3344             self->irblock_from->final = false;
3345             if (!ir_block_create_goto(self->irblock_from, ast_ctx(self), self->target->irblock)) {
3346                 compile_error(ast_ctx(self), "failed to generate goto to `%s`", self->name);
3347                 return false;
3348             }
3349         }
3350         else
3351         {
3352             if (!ir_block_create_goto(func->curblock, ast_ctx(self), self->target->irblock)) {
3353                 compile_error(ast_ctx(self), "failed to generate goto to `%s`", self->name);
3354                 return false;
3355             }
3356         }
3357     }
3358     else
3359     {
3360         /* the target has not yet been created...
3361          * close this block in a sneaky way:
3362          */
3363         func->curblock->final = true;
3364         self->irblock_from = func->curblock;
3365         ast_label_register_goto(self->target, self);
3366     }
3367
3368     return true;
3369 }
3370
3371 #include <stdio.h>
3372 bool ast_state_codegen(ast_state *self, ast_function *func, bool lvalue, ir_value **out)
3373 {
3374     ast_expression_codegen *cgen;
3375
3376     ir_value *frameval, *thinkval;
3377
3378     if (lvalue) {
3379         compile_error(ast_ctx(self), "not an l-value (state operation)");
3380         return false;
3381     }
3382     if (self->expression.outr) {
3383         compile_error(ast_ctx(self), "internal error: ast_state cannot be reused!");
3384         return false;
3385     }
3386     *out = NULL;
3387
3388     cgen = self->framenum->codegen;
3389     if (!(*cgen)((ast_expression*)(self->framenum), func, false, &frameval))
3390         return false;
3391     if (!frameval)
3392         return false;
3393
3394     cgen = self->nextthink->codegen;
3395     if (!(*cgen)((ast_expression*)(self->nextthink), func, false, &thinkval))
3396         return false;
3397     if (!frameval)
3398         return false;
3399
3400     if (!ir_block_create_state_op(func->curblock, ast_ctx(self), frameval, thinkval)) {
3401         compile_error(ast_ctx(self), "failed to create STATE instruction");
3402         return false;
3403     }
3404
3405     self->expression.outr = (ir_value*)1;
3406     return true;
3407 }
3408
3409 bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value **out)
3410 {
3411     ast_expression_codegen *cgen;
3412     ir_value              **params;
3413     ir_instr               *callinstr;
3414     size_t i;
3415
3416     ir_value *funval = NULL;
3417
3418     /* return values are never lvalues */
3419     if (lvalue) {
3420         compile_error(ast_ctx(self), "not an l-value (function call)");
3421         return false;
3422     }
3423
3424     if (self->expression.outr) {
3425         *out = self->expression.outr;
3426         return true;
3427     }
3428
3429     cgen = self->func->codegen;
3430     if (!(*cgen)((ast_expression*)(self->func), func, false, &funval))
3431         return false;
3432     if (!funval)
3433         return false;
3434
3435     params = NULL;
3436
3437     /* parameters */
3438     for (i = 0; i < vec_size(self->params); ++i)
3439     {
3440         ir_value *param;
3441         ast_expression *expr = self->params[i];
3442
3443         cgen = expr->codegen;
3444         if (!(*cgen)(expr, func, false, &param))
3445             goto error;
3446         if (!param)
3447             goto error;
3448         vec_push(params, param);
3449     }
3450
3451     /* varargs counter */
3452     if (self->va_count) {
3453         ir_value   *va_count;
3454         ir_builder *builder = func->curblock->owner->owner;
3455         cgen = self->va_count->codegen;
3456         if (!(*cgen)((ast_expression*)(self->va_count), func, false, &va_count))
3457             return false;
3458         if (!ir_block_create_store_op(func->curblock, ast_ctx(self), INSTR_STORE_F,
3459                                       ir_builder_get_va_count(builder), va_count))
3460         {
3461             return false;
3462         }
3463     }
3464
3465     callinstr = ir_block_create_call(func->curblock, ast_ctx(self),
3466                                      ast_function_label(func, "call"),
3467                                      funval, !!(self->func->flags & AST_FLAG_NORETURN));
3468     if (!callinstr)
3469         goto error;
3470
3471     for (i = 0; i < vec_size(params); ++i) {
3472         ir_call_param(callinstr, params[i]);
3473     }
3474
3475     *out = ir_call_value(callinstr);
3476     self->expression.outr = *out;
3477
3478     codegen_output_type(self, *out);
3479
3480     vec_free(params);
3481     return true;
3482 error:
3483     vec_free(params);
3484     return false;
3485 }