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