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