]> git.xonotic.org Git - xonotic/gmqcc.git/blob - ast.c
constant flag, -finitialized-nonconstants to turn initialized globals into mutable...
[xonotic/gmqcc.git] / ast.c
1 /*
2  * Copyright (C) 2012
3  *     Wolfgang Bumiller
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is furnished to do
10  * so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "gmqcc.h"
28 #include "ast.h"
29
30 #define ast_instantiate(T, ctx, destroyfn)                          \
31     T* self = (T*)mem_a(sizeof(T));                                 \
32     if (!self) {                                                    \
33         return NULL;                                                \
34     }                                                               \
35     ast_node_init((ast_node*)self, ctx, TYPE_##T);                  \
36     ( (ast_node*)self )->node.destroy = (ast_node_delete*)destroyfn
37
38
39 /* error handling */
40 static void asterror(lex_ctx ctx, const char *msg, ...)
41 {
42     va_list ap;
43     va_start(ap, msg);
44     con_cvprintmsg((void*)&ctx, LVL_ERROR, "error", msg, ap);
45     va_end(ap);
46 }
47
48 /* It must not be possible to get here. */
49 static GMQCC_NORETURN void _ast_node_destroy(ast_node *self)
50 {
51     (void)self;
52     con_err("ast node missing destroy()\n");
53     abort();
54 }
55
56 /* Initialize main ast node aprts */
57 static void ast_node_init(ast_node *self, lex_ctx ctx, int nodetype)
58 {
59     self->node.context = ctx;
60     self->node.destroy = &_ast_node_destroy;
61     self->node.keep    = false;
62     self->node.nodetype = nodetype;
63     self->node.side_effects = false;
64 }
65
66 /* weight and side effects */
67 static void _ast_propagate_effects(ast_node *self, ast_node *other)
68 {
69     if (ast_side_effects(other))
70         ast_side_effects(self) = true;
71 }
72 #define ast_propagate_effects(s,o) _ast_propagate_effects(((ast_node*)(s)), ((ast_node*)(o)))
73
74 /* General expression initialization */
75 static void ast_expression_init(ast_expression *self,
76                                 ast_expression_codegen *codegen)
77 {
78     self->expression.codegen  = codegen;
79     self->expression.vtype    = TYPE_VOID;
80     self->expression.next     = NULL;
81     self->expression.outl     = NULL;
82     self->expression.outr     = NULL;
83     self->expression.variadic = false;
84     self->expression.params   = NULL;
85 }
86
87 static void ast_expression_delete(ast_expression *self)
88 {
89     size_t i;
90     if (self->expression.next)
91         ast_delete(self->expression.next);
92     for (i = 0; i < vec_size(self->expression.params); ++i) {
93         ast_delete(self->expression.params[i]);
94     }
95     vec_free(self->expression.params);
96 }
97
98 static void ast_expression_delete_full(ast_expression *self)
99 {
100     ast_expression_delete(self);
101     mem_d(self);
102 }
103
104 ast_value* ast_value_copy(const ast_value *self)
105 {
106     size_t i;
107     const ast_expression_common *fromex;
108     ast_expression_common *selfex;
109     ast_value *cp = ast_value_new(self->expression.node.context, self->name, self->expression.vtype);
110     if (self->expression.next) {
111         cp->expression.next = ast_type_copy(self->expression.node.context, self->expression.next);
112         if (!cp->expression.next) {
113             ast_value_delete(cp);
114             return NULL;
115         }
116     }
117     fromex   = &self->expression;
118     selfex = &cp->expression;
119     selfex->variadic = fromex->variadic;
120     for (i = 0; i < vec_size(fromex->params); ++i) {
121         ast_value *v = ast_value_copy(fromex->params[i]);
122         if (!v) {
123             ast_value_delete(cp);
124             return NULL;
125         }
126         vec_push(selfex->params, v);
127     }
128     return cp;
129 }
130
131 bool ast_type_adopt_impl(ast_expression *self, const ast_expression *other)
132 {
133     size_t i;
134     const ast_expression_common *fromex;
135     ast_expression_common *selfex;
136     self->expression.vtype = other->expression.vtype;
137     if (other->expression.next) {
138         self->expression.next = (ast_expression*)ast_type_copy(ast_ctx(self), other->expression.next);
139         if (!self->expression.next)
140             return false;
141     }
142     fromex   = &other->expression;
143     selfex = &self->expression;
144     selfex->variadic = fromex->variadic;
145     for (i = 0; i < vec_size(fromex->params); ++i) {
146         ast_value *v = ast_value_copy(fromex->params[i]);
147         if (!v)
148             return false;
149         vec_push(selfex->params, v);
150     }
151     return true;
152 }
153
154 static ast_expression* ast_shallow_type(lex_ctx ctx, int vtype)
155 {
156     ast_instantiate(ast_expression, ctx, ast_expression_delete_full);
157     ast_expression_init(self, NULL);
158     self->expression.codegen = NULL;
159     self->expression.next    = NULL;
160     self->expression.vtype   = vtype;
161     return self;
162 }
163
164 ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex)
165 {
166     size_t i;
167     const ast_expression_common *fromex;
168     ast_expression_common *selfex;
169
170     if (!ex)
171         return NULL;
172     else
173     {
174         ast_instantiate(ast_expression, ctx, ast_expression_delete_full);
175         ast_expression_init(self, NULL);
176
177         fromex   = &ex->expression;
178         selfex = &self->expression;
179
180         /* This may never be codegen()d */
181         selfex->codegen = NULL;
182
183         selfex->vtype = fromex->vtype;
184         if (fromex->next)
185         {
186             selfex->next = ast_type_copy(ctx, fromex->next);
187             if (!selfex->next) {
188                 ast_expression_delete_full(self);
189                 return NULL;
190             }
191         }
192         else
193             selfex->next = NULL;
194
195         selfex->variadic = fromex->variadic;
196         for (i = 0; i < vec_size(fromex->params); ++i) {
197             ast_value *v = ast_value_copy(fromex->params[i]);
198             if (!v) {
199                 ast_expression_delete_full(self);
200                 return NULL;
201             }
202             vec_push(selfex->params, v);
203         }
204
205         return self;
206     }
207 }
208
209 bool ast_compare_type(ast_expression *a, ast_expression *b)
210 {
211     if (a->expression.vtype != b->expression.vtype)
212         return false;
213     if (!a->expression.next != !b->expression.next)
214         return false;
215     if (vec_size(a->expression.params) != vec_size(b->expression.params))
216         return false;
217     if (a->expression.variadic != b->expression.variadic)
218         return false;
219     if (vec_size(a->expression.params)) {
220         size_t i;
221         for (i = 0; i < vec_size(a->expression.params); ++i) {
222             if (!ast_compare_type((ast_expression*)a->expression.params[i],
223                                   (ast_expression*)b->expression.params[i]))
224                 return false;
225         }
226     }
227     if (a->expression.next)
228         return ast_compare_type(a->expression.next, b->expression.next);
229     return true;
230 }
231
232 static size_t ast_type_to_string_impl(ast_expression *e, char *buf, size_t bufsize, size_t pos)
233 {
234     const char *typestr;
235     size_t typelen;
236     size_t i;
237
238     if (!e) {
239         if (pos + 6 >= bufsize)
240             goto full;
241         strcpy(buf + pos, "(null)");
242         return pos + 6;
243     }
244
245     if (pos + 1 >= bufsize)
246         goto full;
247
248     switch (e->expression.vtype) {
249         case TYPE_VARIANT:
250             strcpy(buf + pos, "(variant)");
251             return pos + 9;
252
253         case TYPE_FIELD:
254             buf[pos++] = '.';
255             return ast_type_to_string_impl(e->expression.next, buf, bufsize, pos);
256
257         case TYPE_POINTER:
258             if (pos + 3 >= bufsize)
259                 goto full;
260             buf[pos++] = '*';
261             buf[pos++] = '(';
262             pos = ast_type_to_string_impl(e->expression.next, buf, bufsize, pos);
263             if (pos + 1 >= bufsize)
264                 goto full;
265             buf[pos++] = ')';
266             return pos;
267
268         case TYPE_FUNCTION:
269             pos = ast_type_to_string_impl(e->expression.next, buf, bufsize, pos);
270             if (pos + 2 >= bufsize)
271                 goto full;
272             if (!vec_size(e->expression.params)) {
273                 buf[pos++] = '(';
274                 buf[pos++] = ')';
275                 return pos;
276             }
277             buf[pos++] = '(';
278             pos = ast_type_to_string_impl((ast_expression*)(e->expression.params[0]), buf, bufsize, pos);
279             for (i = 1; i < vec_size(e->expression.params); ++i) {
280                 if (pos + 2 >= bufsize)
281                     goto full;
282                 buf[pos++] = ',';
283                 buf[pos++] = ' ';
284                 pos = ast_type_to_string_impl((ast_expression*)(e->expression.params[i]), buf, bufsize, pos);
285             }
286             if (pos + 1 >= bufsize)
287                 goto full;
288             buf[pos++] = ')';
289             return pos;
290
291         case TYPE_ARRAY:
292             pos = ast_type_to_string_impl(e->expression.next, buf, bufsize, pos);
293             if (pos + 1 >= bufsize)
294                 goto full;
295             buf[pos++] = '[';
296             pos += snprintf(buf + pos, bufsize - pos - 1, "%i", (int)e->expression.count);
297             if (pos + 1 >= bufsize)
298                 goto full;
299             buf[pos++] = ']';
300             return pos;
301
302         default:
303             typestr = type_name[e->expression.vtype];
304             typelen = strlen(typestr);
305             if (pos + typelen >= bufsize)
306                 goto full;
307             strcpy(buf + pos, typestr);
308             return pos + typelen;
309     }
310
311 full:
312     buf[bufsize-3] = '.';
313     buf[bufsize-2] = '.';
314     buf[bufsize-1] = '.';
315     return bufsize;
316 }
317
318 void ast_type_to_string(ast_expression *e, char *buf, size_t bufsize)
319 {
320     size_t pos = ast_type_to_string_impl(e, buf, bufsize-1, 0);
321     buf[pos] = 0;
322 }
323
324 ast_value* ast_value_new(lex_ctx ctx, const char *name, int t)
325 {
326     ast_instantiate(ast_value, ctx, ast_value_delete);
327     ast_expression_init((ast_expression*)self,
328                         (ast_expression_codegen*)&ast_value_codegen);
329     self->expression.node.keep = true; /* keep */
330
331     self->name = name ? util_strdup(name) : NULL;
332     self->expression.vtype = t;
333     self->expression.next  = NULL;
334     self->constant = false;
335     self->hasvalue = false;
336     self->uses    = 0;
337     memset(&self->constval, 0, sizeof(self->constval));
338
339     self->ir_v           = NULL;
340     self->ir_values      = NULL;
341     self->ir_value_count = 0;
342
343     self->setter = NULL;
344     self->getter = NULL;
345
346     return self;
347 }
348
349 void ast_value_delete(ast_value* self)
350 {
351     if (self->name)
352         mem_d((void*)self->name);
353     if (self->hasvalue) {
354         switch (self->expression.vtype)
355         {
356         case TYPE_STRING:
357             mem_d((void*)self->constval.vstring);
358             break;
359         case TYPE_FUNCTION:
360             /* unlink us from the function node */
361             self->constval.vfunc->vtype = NULL;
362             break;
363         /* NOTE: delete function? currently collected in
364          * the parser structure
365          */
366         default:
367             break;
368         }
369     }
370     if (self->ir_values)
371         mem_d(self->ir_values);
372     ast_expression_delete((ast_expression*)self);
373     mem_d(self);
374 }
375
376 void ast_value_params_add(ast_value *self, ast_value *p)
377 {
378     vec_push(self->expression.params, p);
379 }
380
381 bool ast_value_set_name(ast_value *self, const char *name)
382 {
383     if (self->name)
384         mem_d((void*)self->name);
385     self->name = util_strdup(name);
386     return !!self->name;
387 }
388
389 ast_binary* ast_binary_new(lex_ctx ctx, int op,
390                            ast_expression* left, ast_expression* right)
391 {
392     ast_instantiate(ast_binary, ctx, ast_binary_delete);
393     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_binary_codegen);
394
395     self->op = op;
396     self->left = left;
397     self->right = right;
398
399     ast_propagate_effects(self, left);
400     ast_propagate_effects(self, right);
401
402     if (op >= INSTR_EQ_F && op <= INSTR_GT)
403         self->expression.vtype = TYPE_FLOAT;
404     else if (op == INSTR_AND || op == INSTR_OR ||
405              op == INSTR_BITAND || op == INSTR_BITOR)
406         self->expression.vtype = TYPE_FLOAT;
407     else if (op == INSTR_MUL_VF || op == INSTR_MUL_FV)
408         self->expression.vtype = TYPE_VECTOR;
409     else if (op == INSTR_MUL_V)
410         self->expression.vtype = TYPE_FLOAT;
411     else
412         self->expression.vtype = left->expression.vtype;
413
414     return self;
415 }
416
417 void ast_binary_delete(ast_binary *self)
418 {
419     ast_unref(self->left);
420     ast_unref(self->right);
421     ast_expression_delete((ast_expression*)self);
422     mem_d(self);
423 }
424
425 ast_binstore* ast_binstore_new(lex_ctx ctx, int storop, int op,
426                                ast_expression* left, ast_expression* right)
427 {
428     ast_instantiate(ast_binstore, ctx, ast_binstore_delete);
429     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_binstore_codegen);
430
431     ast_side_effects(self) = true;
432
433     self->opstore = storop;
434     self->opbin   = op;
435     self->dest    = left;
436     self->source  = right;
437
438     self->expression.vtype = left->expression.vtype;
439     if (left->expression.next) {
440         self->expression.next = ast_type_copy(ctx, left);
441         if (!self->expression.next) {
442             ast_delete(self);
443             return NULL;
444         }
445     }
446     else
447         self->expression.next = NULL;
448
449     return self;
450 }
451
452 void ast_binstore_delete(ast_binstore *self)
453 {
454     ast_unref(self->dest);
455     ast_unref(self->source);
456     ast_expression_delete((ast_expression*)self);
457     mem_d(self);
458 }
459
460 ast_unary* ast_unary_new(lex_ctx ctx, int op,
461                          ast_expression *expr)
462 {
463     ast_instantiate(ast_unary, ctx, ast_unary_delete);
464     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_unary_codegen);
465
466     self->op = op;
467     self->operand = expr;
468
469     ast_propagate_effects(self, expr);
470
471     if (op >= INSTR_NOT_F && op <= INSTR_NOT_FNC) {
472         self->expression.vtype = TYPE_FLOAT;
473     } else
474         asterror(ctx, "cannot determine type of unary operation %s", asm_instr[op].m);
475
476     return self;
477 }
478
479 void ast_unary_delete(ast_unary *self)
480 {
481     ast_unref(self->operand);
482     ast_expression_delete((ast_expression*)self);
483     mem_d(self);
484 }
485
486 ast_return* ast_return_new(lex_ctx ctx, ast_expression *expr)
487 {
488     ast_instantiate(ast_return, ctx, ast_return_delete);
489     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_return_codegen);
490
491     self->operand = expr;
492
493     if (expr)
494         ast_propagate_effects(self, expr);
495
496     return self;
497 }
498
499 void ast_return_delete(ast_return *self)
500 {
501     if (self->operand)
502         ast_unref(self->operand);
503     ast_expression_delete((ast_expression*)self);
504     mem_d(self);
505 }
506
507 ast_entfield* ast_entfield_new(lex_ctx ctx, ast_expression *entity, ast_expression *field)
508 {
509     if (field->expression.vtype != TYPE_FIELD) {
510         asterror(ctx, "ast_entfield_new with expression not of type field");
511         return NULL;
512     }
513     return ast_entfield_new_force(ctx, entity, field, field->expression.next);
514 }
515
516 ast_entfield* ast_entfield_new_force(lex_ctx ctx, ast_expression *entity, ast_expression *field, const ast_expression *outtype)
517 {
518     ast_instantiate(ast_entfield, ctx, ast_entfield_delete);
519
520     if (!outtype) {
521         mem_d(self);
522         /* Error: field has no type... */
523         return NULL;
524     }
525
526     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_entfield_codegen);
527
528     self->entity = entity;
529     self->field  = field;
530     ast_propagate_effects(self, entity);
531     ast_propagate_effects(self, field);
532
533     if (!ast_type_adopt(self, outtype)) {
534         ast_entfield_delete(self);
535         return NULL;
536     }
537
538     return self;
539 }
540
541 void ast_entfield_delete(ast_entfield *self)
542 {
543     ast_unref(self->entity);
544     ast_unref(self->field);
545     ast_expression_delete((ast_expression*)self);
546     mem_d(self);
547 }
548
549 ast_member* ast_member_new(lex_ctx ctx, ast_expression *owner, unsigned int field, const char *name)
550 {
551     ast_instantiate(ast_member, ctx, ast_member_delete);
552     if (field >= 3) {
553         mem_d(self);
554         return NULL;
555     }
556
557     if (owner->expression.vtype != TYPE_VECTOR &&
558         owner->expression.vtype != TYPE_FIELD) {
559         asterror(ctx, "member-access on an invalid owner of type %s", type_name[owner->expression.vtype]);
560         mem_d(self);
561         return NULL;
562     }
563
564     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_member_codegen);
565     self->expression.node.keep = true; /* keep */
566
567     if (owner->expression.vtype == TYPE_VECTOR) {
568         self->expression.vtype = TYPE_FLOAT;
569         self->expression.next  = NULL;
570     } else {
571         self->expression.vtype = TYPE_FIELD;
572         self->expression.next = ast_shallow_type(ctx, TYPE_FLOAT);
573     }
574
575     self->owner = owner;
576     ast_propagate_effects(self, owner);
577
578     self->field = field;
579     if (name)
580         self->name = util_strdup(name);
581     else
582         self->name = NULL;
583
584     return self;
585 }
586
587 void ast_member_delete(ast_member *self)
588 {
589     /* The owner is always an ast_value, which has .keep=true,
590      * also: ast_members are usually deleted after the owner, thus
591      * this will cause invalid access
592     ast_unref(self->owner);
593      * once we allow (expression).x to access a vector-member, we need
594      * to change this: preferably by creating an alternate ast node for this
595      * purpose that is not garbage-collected.
596     */
597     ast_expression_delete((ast_expression*)self);
598     mem_d(self);
599 }
600
601 ast_array_index* ast_array_index_new(lex_ctx ctx, ast_expression *array, ast_expression *index)
602 {
603     ast_expression *outtype;
604     ast_instantiate(ast_array_index, ctx, ast_array_index_delete);
605
606     outtype = array->expression.next;
607     if (!outtype) {
608         mem_d(self);
609         /* Error: field has no type... */
610         return NULL;
611     }
612
613     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_array_index_codegen);
614
615     self->array = array;
616     self->index = index;
617     ast_propagate_effects(self, array);
618     ast_propagate_effects(self, index);
619
620     if (!ast_type_adopt(self, outtype)) {
621         ast_array_index_delete(self);
622         return NULL;
623     }
624     if (array->expression.vtype == TYPE_FIELD && outtype->expression.vtype == TYPE_ARRAY) {
625         if (self->expression.vtype != TYPE_ARRAY) {
626             asterror(ast_ctx(self), "array_index node on type");
627             ast_array_index_delete(self);
628             return NULL;
629         }
630         self->array = outtype;
631         self->expression.vtype = TYPE_FIELD;
632     }
633
634     return self;
635 }
636
637 void ast_array_index_delete(ast_array_index *self)
638 {
639     ast_unref(self->array);
640     ast_unref(self->index);
641     ast_expression_delete((ast_expression*)self);
642     mem_d(self);
643 }
644
645 ast_ifthen* ast_ifthen_new(lex_ctx ctx, ast_expression *cond, ast_expression *ontrue, ast_expression *onfalse)
646 {
647     ast_instantiate(ast_ifthen, ctx, ast_ifthen_delete);
648     if (!ontrue && !onfalse) {
649         /* because it is invalid */
650         mem_d(self);
651         return NULL;
652     }
653     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_ifthen_codegen);
654
655     self->cond     = cond;
656     self->on_true  = ontrue;
657     self->on_false = onfalse;
658     ast_propagate_effects(self, cond);
659     if (ontrue)
660         ast_propagate_effects(self, ontrue);
661     if (onfalse)
662         ast_propagate_effects(self, onfalse);
663
664     return self;
665 }
666
667 void ast_ifthen_delete(ast_ifthen *self)
668 {
669     ast_unref(self->cond);
670     if (self->on_true)
671         ast_unref(self->on_true);
672     if (self->on_false)
673         ast_unref(self->on_false);
674     ast_expression_delete((ast_expression*)self);
675     mem_d(self);
676 }
677
678 ast_ternary* ast_ternary_new(lex_ctx ctx, ast_expression *cond, ast_expression *ontrue, ast_expression *onfalse)
679 {
680     ast_instantiate(ast_ternary, ctx, ast_ternary_delete);
681     /* This time NEITHER must be NULL */
682     if (!ontrue || !onfalse) {
683         mem_d(self);
684         return NULL;
685     }
686     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_ternary_codegen);
687
688     self->cond     = cond;
689     self->on_true  = ontrue;
690     self->on_false = onfalse;
691     ast_propagate_effects(self, cond);
692     ast_propagate_effects(self, ontrue);
693     ast_propagate_effects(self, onfalse);
694
695     if (!ast_type_adopt(self, ontrue)) {
696         ast_ternary_delete(self);
697         return NULL;
698     }
699
700     return self;
701 }
702
703 void ast_ternary_delete(ast_ternary *self)
704 {
705     ast_unref(self->cond);
706     ast_unref(self->on_true);
707     ast_unref(self->on_false);
708     ast_expression_delete((ast_expression*)self);
709     mem_d(self);
710 }
711
712 ast_loop* ast_loop_new(lex_ctx ctx,
713                        ast_expression *initexpr,
714                        ast_expression *precond,
715                        ast_expression *postcond,
716                        ast_expression *increment,
717                        ast_expression *body)
718 {
719     ast_instantiate(ast_loop, ctx, ast_loop_delete);
720     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_loop_codegen);
721
722     self->initexpr  = initexpr;
723     self->precond   = precond;
724     self->postcond  = postcond;
725     self->increment = increment;
726     self->body      = body;
727
728     if (initexpr)
729         ast_propagate_effects(self, initexpr);
730     if (precond)
731         ast_propagate_effects(self, precond);
732     if (postcond)
733         ast_propagate_effects(self, postcond);
734     if (increment)
735         ast_propagate_effects(self, increment);
736     if (body)
737         ast_propagate_effects(self, body);
738
739     return self;
740 }
741
742 void ast_loop_delete(ast_loop *self)
743 {
744     if (self->initexpr)
745         ast_unref(self->initexpr);
746     if (self->precond)
747         ast_unref(self->precond);
748     if (self->postcond)
749         ast_unref(self->postcond);
750     if (self->increment)
751         ast_unref(self->increment);
752     if (self->body)
753         ast_unref(self->body);
754     ast_expression_delete((ast_expression*)self);
755     mem_d(self);
756 }
757
758 ast_breakcont* ast_breakcont_new(lex_ctx ctx, bool iscont)
759 {
760     ast_instantiate(ast_breakcont, ctx, ast_breakcont_delete);
761     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_breakcont_codegen);
762
763     self->is_continue = iscont;
764
765     return self;
766 }
767
768 void ast_breakcont_delete(ast_breakcont *self)
769 {
770     ast_expression_delete((ast_expression*)self);
771     mem_d(self);
772 }
773
774 ast_switch* ast_switch_new(lex_ctx ctx, ast_expression *op)
775 {
776     ast_instantiate(ast_switch, ctx, ast_switch_delete);
777     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_switch_codegen);
778
779     self->operand = op;
780     self->cases   = NULL;
781
782     ast_propagate_effects(self, op);
783
784     return self;
785 }
786
787 void ast_switch_delete(ast_switch *self)
788 {
789     size_t i;
790     ast_unref(self->operand);
791
792     for (i = 0; i < vec_size(self->cases); ++i) {
793         if (self->cases[i].value)
794             ast_unref(self->cases[i].value);
795         ast_unref(self->cases[i].code);
796     }
797     vec_free(self->cases);
798
799     ast_expression_delete((ast_expression*)self);
800     mem_d(self);
801 }
802
803 ast_call* ast_call_new(lex_ctx ctx,
804                        ast_expression *funcexpr)
805 {
806     ast_instantiate(ast_call, ctx, ast_call_delete);
807     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_call_codegen);
808
809     ast_side_effects(self) = true;
810
811     self->params = NULL;
812     self->func   = funcexpr;
813
814     self->expression.vtype = funcexpr->expression.next->expression.vtype;
815     if (funcexpr->expression.next->expression.next)
816         self->expression.next = ast_type_copy(ctx, funcexpr->expression.next->expression.next);
817
818     return self;
819 }
820
821 void ast_call_delete(ast_call *self)
822 {
823     size_t i;
824     for (i = 0; i < vec_size(self->params); ++i)
825         ast_unref(self->params[i]);
826     vec_free(self->params);
827
828     if (self->func)
829         ast_unref(self->func);
830
831     ast_expression_delete((ast_expression*)self);
832     mem_d(self);
833 }
834
835 bool ast_call_check_types(ast_call *self)
836 {
837     size_t i;
838     bool   retval = true;
839     const  ast_expression *func = self->func;
840     size_t count = vec_size(self->params);
841     if (count > vec_size(func->expression.params))
842         count = vec_size(func->expression.params);
843
844     for (i = 0; i < count; ++i) {
845         if (!ast_compare_type(self->params[i], (ast_expression*)(func->expression.params[i]))) {
846             char texp[1024];
847             char tgot[1024];
848             ast_type_to_string(self->params[i], tgot, sizeof(tgot));
849             ast_type_to_string((ast_expression*)func->expression.params[i], texp, sizeof(texp));
850             asterror(ast_ctx(self), "invalid type for parameter %u in function call: expected %s, got %s",
851                      (unsigned int)(i+1), texp, tgot);
852             /* we don't immediately return */
853             retval = false;
854         }
855     }
856     return retval;
857 }
858
859 ast_store* ast_store_new(lex_ctx ctx, int op,
860                          ast_expression *dest, ast_expression *source)
861 {
862     ast_instantiate(ast_store, ctx, ast_store_delete);
863     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_store_codegen);
864
865     ast_side_effects(self) = true;
866
867     self->op = op;
868     self->dest = dest;
869     self->source = source;
870
871     self->expression.vtype = dest->expression.vtype;
872     if (dest->expression.next) {
873         self->expression.next = ast_type_copy(ctx, dest);
874         if (!self->expression.next) {
875             ast_delete(self);
876             return NULL;
877         }
878     }
879     else
880         self->expression.next = NULL;
881
882     return self;
883 }
884
885 void ast_store_delete(ast_store *self)
886 {
887     ast_unref(self->dest);
888     ast_unref(self->source);
889     ast_expression_delete((ast_expression*)self);
890     mem_d(self);
891 }
892
893 ast_block* ast_block_new(lex_ctx ctx)
894 {
895     ast_instantiate(ast_block, ctx, ast_block_delete);
896     ast_expression_init((ast_expression*)self,
897                         (ast_expression_codegen*)&ast_block_codegen);
898
899     self->locals  = NULL;
900     self->exprs   = NULL;
901     self->collect = NULL;
902
903     return self;
904 }
905
906 void ast_block_add_expr(ast_block *self, ast_expression *e)
907 {
908     ast_propagate_effects(self, e);
909     vec_push(self->exprs, e);
910 }
911
912 void ast_block_collect(ast_block *self, ast_expression *expr)
913 {
914     vec_push(self->collect, expr);
915     expr->expression.node.keep = true;
916 }
917
918 void ast_block_delete(ast_block *self)
919 {
920     size_t i;
921     for (i = 0; i < vec_size(self->exprs); ++i)
922         ast_unref(self->exprs[i]);
923     vec_free(self->exprs);
924     for (i = 0; i < vec_size(self->locals); ++i)
925         ast_delete(self->locals[i]);
926     vec_free(self->locals);
927     for (i = 0; i < vec_size(self->collect); ++i)
928         ast_delete(self->collect[i]);
929     vec_free(self->collect);
930     ast_expression_delete((ast_expression*)self);
931     mem_d(self);
932 }
933
934 bool ast_block_set_type(ast_block *self, ast_expression *from)
935 {
936     if (self->expression.next)
937         ast_delete(self->expression.next);
938     self->expression.vtype = from->expression.vtype;
939     if (from->expression.next) {
940         self->expression.next = ast_type_copy(self->expression.node.context, from->expression.next);
941         if (!self->expression.next)
942             return false;
943     }
944     else
945         self->expression.next = NULL;
946     return true;
947 }
948
949 ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype)
950 {
951     ast_instantiate(ast_function, ctx, ast_function_delete);
952
953     if (!vtype ||
954         vtype->hasvalue ||
955         vtype->expression.vtype != TYPE_FUNCTION)
956     {
957         asterror(ast_ctx(self), "internal error: ast_function_new condition %i %i type=%i",
958                  (int)!vtype,
959                  (int)vtype->hasvalue,
960                  vtype->expression.vtype);
961         mem_d(self);
962         return NULL;
963     }
964
965     self->vtype  = vtype;
966     self->name   = name ? util_strdup(name) : NULL;
967     self->blocks = NULL;
968
969     self->labelcount = 0;
970     self->builtin = 0;
971
972     self->ir_func = NULL;
973     self->curblock = NULL;
974
975     self->breakblock    = NULL;
976     self->continueblock = NULL;
977
978     vtype->hasvalue = true;
979     vtype->constval.vfunc = self;
980
981     return self;
982 }
983
984 void ast_function_delete(ast_function *self)
985 {
986     size_t i;
987     if (self->name)
988         mem_d((void*)self->name);
989     if (self->vtype) {
990         /* ast_value_delete(self->vtype); */
991         self->vtype->hasvalue = false;
992         self->vtype->constval.vfunc = NULL;
993         /* We use unref - if it was stored in a global table it is supposed
994          * to be deleted from *there*
995          */
996         ast_unref(self->vtype);
997     }
998     for (i = 0; i < vec_size(self->blocks); ++i)
999         ast_delete(self->blocks[i]);
1000     vec_free(self->blocks);
1001     mem_d(self);
1002 }
1003
1004 const char* ast_function_label(ast_function *self, const char *prefix)
1005 {
1006     size_t id;
1007     size_t len;
1008     char  *from;
1009
1010     if (!opts_dump && !opts_dumpfin)
1011         return NULL;
1012
1013     id  = (self->labelcount++);
1014     len = strlen(prefix);
1015
1016     from = self->labelbuf + sizeof(self->labelbuf)-1;
1017     *from-- = 0;
1018     do {
1019         unsigned int digit = id % 10;
1020         *from = digit + '0';
1021         id /= 10;
1022     } while (id);
1023     memcpy(from - len, prefix, len);
1024     return from - len;
1025 }
1026
1027 /*********************************************************************/
1028 /* AST codegen part
1029  * by convention you must never pass NULL to the 'ir_value **out'
1030  * parameter. If you really don't care about the output, pass a dummy.
1031  * But I can't imagine a pituation where the output is truly unnecessary.
1032  */
1033
1034 bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_value **out)
1035 {
1036     (void)func;
1037     (void)lvalue;
1038     /* NOTE: This is the codegen for a variable used in an expression.
1039      * It is not the codegen to generate the value. For this purpose,
1040      * ast_local_codegen and ast_global_codegen are to be used before this
1041      * is executed. ast_function_codegen should take care of its locals,
1042      * and the ast-user should take care of ast_global_codegen to be used
1043      * on all the globals.
1044      */
1045     if (!self->ir_v) {
1046         char typename[1024];
1047         ast_type_to_string((ast_expression*)self, typename, sizeof(typename));
1048         asterror(ast_ctx(self), "ast_value used before generated %s %s", typename, self->name);
1049         return false;
1050     }
1051     *out = self->ir_v;
1052     return true;
1053 }
1054
1055 bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
1056 {
1057     ir_value *v = NULL;
1058
1059     if (self->hasvalue && self->expression.vtype == TYPE_FUNCTION)
1060     {
1061         ir_function *func = ir_builder_create_function(ir, self->name, self->expression.next->expression.vtype);
1062         if (!func)
1063             return false;
1064         func->context = ast_ctx(self);
1065         func->value->context = ast_ctx(self);
1066
1067         self->constval.vfunc->ir_func = func;
1068         self->ir_v = func->value;
1069         /* The function is filled later on ast_function_codegen... */
1070         return true;
1071     }
1072
1073     if (isfield && self->expression.vtype == TYPE_FIELD) {
1074         ast_expression *fieldtype = self->expression.next;
1075
1076         if (self->hasvalue) {
1077             asterror(ast_ctx(self), "TODO: constant field pointers with value");
1078             goto error;
1079         }
1080
1081         if (fieldtype->expression.vtype == TYPE_ARRAY) {
1082             size_t ai;
1083             char   *name;
1084             size_t  namelen;
1085
1086             ast_expression_common *elemtype;
1087             int                    vtype;
1088             ast_value             *array = (ast_value*)fieldtype;
1089
1090             if (!ast_istype(fieldtype, ast_value)) {
1091                 asterror(ast_ctx(self), "internal error: ast_value required");
1092                 return false;
1093             }
1094
1095             /* we are lame now - considering the way QC works we won't tolerate arrays > 1024 elements */
1096             if (!array->expression.count || array->expression.count > opts_max_array_size)
1097                 asterror(ast_ctx(self), "Invalid array of size %lu", (unsigned long)array->expression.count);
1098
1099             elemtype = &array->expression.next->expression;
1100             vtype = elemtype->vtype;
1101
1102             v = ir_builder_create_field(ir, self->name, vtype);
1103             if (!v) {
1104                 asterror(ast_ctx(self), "ir_builder_create_global failed");
1105                 return false;
1106             }
1107             if (vtype == TYPE_FIELD)
1108                 v->fieldtype = elemtype->next->expression.vtype;
1109             v->context = ast_ctx(self);
1110             array->ir_v = self->ir_v = v;
1111
1112             namelen = strlen(self->name);
1113             name    = (char*)mem_a(namelen + 16);
1114             strcpy(name, self->name);
1115
1116             array->ir_values = (ir_value**)mem_a(sizeof(array->ir_values[0]) * array->expression.count);
1117             array->ir_values[0] = v;
1118             for (ai = 1; ai < array->expression.count; ++ai) {
1119                 snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
1120                 array->ir_values[ai] = ir_builder_create_field(ir, name, vtype);
1121                 if (!array->ir_values[ai]) {
1122                     mem_d(name);
1123                     asterror(ast_ctx(self), "ir_builder_create_global failed");
1124                     return false;
1125                 }
1126                 if (vtype == TYPE_FIELD)
1127                     array->ir_values[ai]->fieldtype = elemtype->next->expression.vtype;
1128                 array->ir_values[ai]->context = ast_ctx(self);
1129             }
1130             mem_d(name);
1131         }
1132         else
1133         {
1134             v = ir_builder_create_field(ir, self->name, self->expression.next->expression.vtype);
1135             if (!v)
1136                 return false;
1137             v->context = ast_ctx(self);
1138             self->ir_v = v;
1139         }
1140         return true;
1141     }
1142
1143     if (self->expression.vtype == TYPE_ARRAY) {
1144         size_t ai;
1145         char   *name;
1146         size_t  namelen;
1147
1148         ast_expression_common *elemtype = &self->expression.next->expression;
1149         int vtype = elemtype->vtype;
1150
1151         /* same as with field arrays */
1152         if (!self->expression.count || self->expression.count > opts_max_array_size)
1153             asterror(ast_ctx(self), "Invalid array of size %lu", (unsigned long)self->expression.count);
1154
1155         v = ir_builder_create_global(ir, self->name, vtype);
1156         if (!v) {
1157             asterror(ast_ctx(self), "ir_builder_create_global failed");
1158             return false;
1159         }
1160         if (vtype == TYPE_FIELD)
1161             v->fieldtype = elemtype->next->expression.vtype;
1162         v->context = ast_ctx(self);
1163
1164         namelen = strlen(self->name);
1165         name    = (char*)mem_a(namelen + 16);
1166         strcpy(name, self->name);
1167
1168         self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->expression.count);
1169         self->ir_values[0] = v;
1170         for (ai = 1; ai < self->expression.count; ++ai) {
1171             snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
1172             self->ir_values[ai] = ir_builder_create_global(ir, name, vtype);
1173             if (!self->ir_values[ai]) {
1174                 mem_d(name);
1175                 asterror(ast_ctx(self), "ir_builder_create_global failed");
1176                 return false;
1177             }
1178             if (vtype == TYPE_FIELD)
1179                 self->ir_values[ai]->fieldtype = elemtype->next->expression.vtype;
1180             self->ir_values[ai]->context = ast_ctx(self);
1181         }
1182         mem_d(name);
1183     }
1184     else
1185     {
1186         /* Arrays don't do this since there's no "array" value which spans across the
1187          * whole thing.
1188          */
1189         v = ir_builder_create_global(ir, self->name, self->expression.vtype);
1190         if (!v) {
1191             asterror(ast_ctx(self), "ir_builder_create_global failed");
1192             return false;
1193         }
1194         if (self->expression.vtype == TYPE_FIELD)
1195             v->fieldtype = self->expression.next->expression.vtype;
1196         v->context = ast_ctx(self);
1197     }
1198
1199     if (self->hasvalue) {
1200         switch (self->expression.vtype)
1201         {
1202             case TYPE_FLOAT:
1203                 if (!ir_value_set_float(v, self->constval.vfloat))
1204                     goto error;
1205                 break;
1206             case TYPE_VECTOR:
1207                 if (!ir_value_set_vector(v, self->constval.vvec))
1208                     goto error;
1209                 break;
1210             case TYPE_STRING:
1211                 if (!ir_value_set_string(v, self->constval.vstring))
1212                     goto error;
1213                 break;
1214             case TYPE_ARRAY:
1215                 asterror(ast_ctx(self), "TODO: global constant array");
1216                 break;
1217             case TYPE_FUNCTION:
1218                 asterror(ast_ctx(self), "global of type function not properly generated");
1219                 goto error;
1220                 /* Cannot generate an IR value for a function,
1221                  * need a pointer pointing to a function rather.
1222                  */
1223             default:
1224                 asterror(ast_ctx(self), "TODO: global constant type %i", self->expression.vtype);
1225                 break;
1226         }
1227     }
1228
1229     /* link us to the ir_value */
1230     self->ir_v = v;
1231     return true;
1232
1233 error: /* clean up */
1234     ir_value_delete(v);
1235     return false;
1236 }
1237
1238 bool ast_local_codegen(ast_value *self, ir_function *func, bool param)
1239 {
1240     ir_value *v = NULL;
1241     if (self->hasvalue && self->expression.vtype == TYPE_FUNCTION)
1242     {
1243         /* Do we allow local functions? I think not...
1244          * this is NOT a function pointer atm.
1245          */
1246         return false;
1247     }
1248
1249     if (self->expression.vtype == TYPE_ARRAY) {
1250         size_t ai;
1251         char   *name;
1252         size_t  namelen;
1253
1254         ast_expression_common *elemtype = &self->expression.next->expression;
1255         int vtype = elemtype->vtype;
1256
1257         if (param) {
1258             asterror(ast_ctx(self), "array-parameters are not supported");
1259             return false;
1260         }
1261
1262         /* we are lame now - considering the way QC works we won't tolerate arrays > 1024 elements */
1263         if (!self->expression.count || self->expression.count > opts_max_array_size) {
1264             asterror(ast_ctx(self), "Invalid array of size %lu", (unsigned long)self->expression.count);
1265         }
1266
1267         self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->expression.count);
1268         if (!self->ir_values) {
1269             asterror(ast_ctx(self), "failed to allocate array values");
1270             return false;
1271         }
1272
1273         v = ir_function_create_local(func, self->name, vtype, param);
1274         if (!v) {
1275             asterror(ast_ctx(self), "ir_function_create_local failed");
1276             return false;
1277         }
1278         if (vtype == TYPE_FIELD)
1279             v->fieldtype = elemtype->next->expression.vtype;
1280         v->context = ast_ctx(self);
1281
1282         namelen = strlen(self->name);
1283         name    = (char*)mem_a(namelen + 16);
1284         strcpy(name, self->name);
1285
1286         self->ir_values[0] = v;
1287         for (ai = 1; ai < self->expression.count; ++ai) {
1288             snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
1289             self->ir_values[ai] = ir_function_create_local(func, name, vtype, param);
1290             if (!self->ir_values[ai]) {
1291                 asterror(ast_ctx(self), "ir_builder_create_global failed");
1292                 return false;
1293             }
1294             if (vtype == TYPE_FIELD)
1295                 self->ir_values[ai]->fieldtype = elemtype->next->expression.vtype;
1296             self->ir_values[ai]->context = ast_ctx(self);
1297         }
1298     }
1299     else
1300     {
1301         v = ir_function_create_local(func, self->name, self->expression.vtype, param);
1302         if (!v)
1303             return false;
1304         if (self->expression.vtype == TYPE_FIELD)
1305             v->fieldtype = self->expression.next->expression.vtype;
1306         v->context = ast_ctx(self);
1307     }
1308
1309     /* A constant local... hmmm...
1310      * I suppose the IR will have to deal with this
1311      */
1312     if (self->hasvalue) {
1313         switch (self->expression.vtype)
1314         {
1315             case TYPE_FLOAT:
1316                 if (!ir_value_set_float(v, self->constval.vfloat))
1317                     goto error;
1318                 break;
1319             case TYPE_VECTOR:
1320                 if (!ir_value_set_vector(v, self->constval.vvec))
1321                     goto error;
1322                 break;
1323             case TYPE_STRING:
1324                 if (!ir_value_set_string(v, self->constval.vstring))
1325                     goto error;
1326                 break;
1327             default:
1328                 asterror(ast_ctx(self), "TODO: global constant type %i", self->expression.vtype);
1329                 break;
1330         }
1331     }
1332
1333     /* link us to the ir_value */
1334     self->ir_v = v;
1335
1336     if (self->setter) {
1337         if (!ast_global_codegen(self->setter, func->owner, false) ||
1338             !ast_function_codegen(self->setter->constval.vfunc, func->owner) ||
1339             !ir_function_finalize(self->setter->constval.vfunc->ir_func))
1340             return false;
1341     }
1342     if (self->getter) {
1343         if (!ast_global_codegen(self->getter, func->owner, false) ||
1344             !ast_function_codegen(self->getter->constval.vfunc, func->owner) ||
1345             !ir_function_finalize(self->getter->constval.vfunc->ir_func))
1346             return false;
1347     }
1348     return true;
1349
1350 error: /* clean up */
1351     ir_value_delete(v);
1352     return false;
1353 }
1354
1355 bool ast_function_codegen(ast_function *self, ir_builder *ir)
1356 {
1357     ir_function *irf;
1358     ir_value    *dummy;
1359     ast_expression_common *ec;
1360     size_t    i;
1361
1362     (void)ir;
1363
1364     irf = self->ir_func;
1365     if (!irf) {
1366         asterror(ast_ctx(self), "ast_function's related ast_value was not generated yet");
1367         return false;
1368     }
1369
1370     /* fill the parameter list */
1371     ec = &self->vtype->expression;
1372     for (i = 0; i < vec_size(ec->params); ++i)
1373     {
1374         vec_push(irf->params, ec->params[i]->expression.vtype);
1375         if (!self->builtin) {
1376             if (!ast_local_codegen(ec->params[i], self->ir_func, true))
1377                 return false;
1378         }
1379     }
1380
1381     if (self->builtin) {
1382         irf->builtin = self->builtin;
1383         return true;
1384     }
1385
1386     if (!vec_size(self->blocks)) {
1387         asterror(ast_ctx(self), "function `%s` has no body", self->name);
1388         return false;
1389     }
1390
1391     self->curblock = ir_function_create_block(irf, "entry");
1392     if (!self->curblock) {
1393         asterror(ast_ctx(self), "failed to allocate entry block for `%s`", self->name);
1394         return false;
1395     }
1396
1397     for (i = 0; i < vec_size(self->blocks); ++i) {
1398         ast_expression_codegen *gen = self->blocks[i]->expression.codegen;
1399         if (!(*gen)((ast_expression*)self->blocks[i], self, false, &dummy))
1400             return false;
1401     }
1402
1403     /* TODO: check return types */
1404     if (!self->curblock->is_return)
1405     {
1406         return ir_block_create_return(self->curblock, NULL);
1407         /* From now on the parser has to handle this situation */
1408 #if 0
1409         if (!self->vtype->expression.next ||
1410             self->vtype->expression.next->expression.vtype == TYPE_VOID)
1411         {
1412             return ir_block_create_return(self->curblock, NULL);
1413         }
1414         else
1415         {
1416             /* error("missing return"); */
1417             asterror(ast_ctx(self), "function `%s` missing return value", self->name);
1418             return false;
1419         }
1420 #endif
1421     }
1422     return true;
1423 }
1424
1425 /* Note, you will not see ast_block_codegen generate ir_blocks.
1426  * To the AST and the IR, blocks are 2 different things.
1427  * In the AST it represents a block of code, usually enclosed in
1428  * curly braces {...}.
1429  * While in the IR it represents a block in terms of control-flow.
1430  */
1431 bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_value **out)
1432 {
1433     size_t i;
1434
1435     /* We don't use this
1436      * Note: an ast-representation using the comma-operator
1437      * of the form: (a, b, c) = x should not assign to c...
1438      */
1439     if (lvalue) {
1440         asterror(ast_ctx(self), "not an l-value (code-block)");
1441         return false;
1442     }
1443
1444     if (self->expression.outr) {
1445         *out = self->expression.outr;
1446         return true;
1447     }
1448
1449     /* output is NULL at first, we'll have each expression
1450      * assign to out output, thus, a comma-operator represention
1451      * using an ast_block will return the last generated value,
1452      * so: (b, c) + a  executed both b and c, and returns c,
1453      * which is then added to a.
1454      */
1455     *out = NULL;
1456
1457     /* generate locals */
1458     for (i = 0; i < vec_size(self->locals); ++i)
1459     {
1460         if (!ast_local_codegen(self->locals[i], func->ir_func, false)) {
1461             if (opts_debug)
1462                 asterror(ast_ctx(self), "failed to generate local `%s`", self->locals[i]->name);
1463             return false;
1464         }
1465     }
1466
1467     for (i = 0; i < vec_size(self->exprs); ++i)
1468     {
1469         ast_expression_codegen *gen = self->exprs[i]->expression.codegen;
1470         if (func->curblock->final) {
1471             asterror(ast_ctx(self->exprs[i]), "unreachable statement");
1472             return false;
1473         }
1474         if (!(*gen)(self->exprs[i], func, false, out))
1475             return false;
1476     }
1477
1478     self->expression.outr = *out;
1479
1480     return true;
1481 }
1482
1483 bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_value **out)
1484 {
1485     ast_expression_codegen *cgen;
1486     ir_value *left  = NULL;
1487     ir_value *right = NULL;
1488
1489     ast_value       *arr;
1490     ast_value       *idx = 0;
1491     ast_array_index *ai = NULL;
1492
1493     if (lvalue && self->expression.outl) {
1494         *out = self->expression.outl;
1495         return true;
1496     }
1497
1498     if (!lvalue && self->expression.outr) {
1499         *out = self->expression.outr;
1500         return true;
1501     }
1502
1503     if (ast_istype(self->dest, ast_array_index))
1504     {
1505
1506         ai = (ast_array_index*)self->dest;
1507         idx = (ast_value*)ai->index;
1508
1509         if (ast_istype(ai->index, ast_value) && idx->hasvalue)
1510             ai = NULL;
1511     }
1512
1513     if (ai) {
1514         /* we need to call the setter */
1515         ir_value  *iridx, *funval;
1516         ir_instr  *call;
1517
1518         if (lvalue) {
1519             asterror(ast_ctx(self), "array-subscript assignment cannot produce lvalues");
1520             return false;
1521         }
1522
1523         arr = (ast_value*)ai->array;
1524         if (!ast_istype(ai->array, ast_value) || !arr->setter) {
1525             asterror(ast_ctx(self), "value has no setter (%s)", arr->name);
1526             return false;
1527         }
1528
1529         cgen = idx->expression.codegen;
1530         if (!(*cgen)((ast_expression*)(idx), func, false, &iridx))
1531             return false;
1532
1533         cgen = arr->setter->expression.codegen;
1534         if (!(*cgen)((ast_expression*)(arr->setter), func, true, &funval))
1535             return false;
1536
1537         cgen = self->source->expression.codegen;
1538         if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
1539             return false;
1540
1541         call = ir_block_create_call(func->curblock, ast_function_label(func, "store"), funval);
1542         if (!call)
1543             return false;
1544         ir_call_param(call, iridx);
1545         ir_call_param(call, right);
1546         self->expression.outr = right;
1547     }
1548     else
1549     {
1550         /* regular code */
1551
1552         cgen = self->dest->expression.codegen;
1553         /* lvalue! */
1554         if (!(*cgen)((ast_expression*)(self->dest), func, true, &left))
1555             return false;
1556         self->expression.outl = left;
1557
1558         cgen = self->source->expression.codegen;
1559         /* rvalue! */
1560         if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
1561             return false;
1562
1563         if (!ir_block_create_store_op(func->curblock, self->op, left, right))
1564             return false;
1565         self->expression.outr = right;
1566     }
1567
1568     /* Theoretically, an assinment returns its left side as an
1569      * lvalue, if we don't need an lvalue though, we return
1570      * the right side as an rvalue, otherwise we have to
1571      * somehow know whether or not we need to dereference the pointer
1572      * on the left side - that is: OP_LOAD if it was an address.
1573      * Also: in original QC we cannot OP_LOADP *anyway*.
1574      */
1575     *out = (lvalue ? left : right);
1576
1577     return true;
1578 }
1579
1580 bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_value **out)
1581 {
1582     ast_expression_codegen *cgen;
1583     ir_value *left, *right;
1584
1585     /* A binary operation cannot yield an l-value */
1586     if (lvalue) {
1587         asterror(ast_ctx(self), "not an l-value (binop)");
1588         return false;
1589     }
1590
1591     if (self->expression.outr) {
1592         *out = self->expression.outr;
1593         return true;
1594     }
1595
1596     if (OPTS_FLAG(SHORT_LOGIC) &&
1597         (self->op == INSTR_AND || self->op == INSTR_OR))
1598     {
1599         /* short circuit evaluation */
1600         ir_block *other, *merge;
1601         ir_block *from_left, *from_right;
1602         ir_instr *phi;
1603         size_t    merge_id;
1604         uint16_t  notop;
1605
1606         /* Note about casting to true boolean values:
1607          * We use a single NOT for sub expressions, and an
1608          * overall NOT at the end, and for that purpose swap
1609          * all the jump conditions in order for the NOT to get
1610          * doubled.
1611          * ie: (a && b) usually becomes (!!a ? !!b : !!a)
1612          * but we translate this to (!(!a ? !a : !b))
1613          */
1614
1615         merge_id = vec_size(func->ir_func->blocks);
1616         merge = ir_function_create_block(func->ir_func, ast_function_label(func, "sce_merge"));
1617
1618         cgen = self->left->expression.codegen;
1619         if (!(*cgen)((ast_expression*)(self->left), func, false, &left))
1620             return false;
1621         if (!OPTS_FLAG(PERL_LOGIC)) {
1622             notop = type_not_instr[left->vtype];
1623             if (notop == AINSTR_END) {
1624                 asterror(ast_ctx(self), "don't know how to cast to bool...");
1625                 return false;
1626             }
1627             left = ir_block_create_unary(func->curblock,
1628                                          ast_function_label(func, "sce_not"),
1629                                          notop,
1630                                          left);
1631         }
1632         from_left = func->curblock;
1633
1634         other = ir_function_create_block(func->ir_func, ast_function_label(func, "sce_other"));
1635         if ( !(self->op == INSTR_OR) != !OPTS_FLAG(PERL_LOGIC) ) {
1636             if (!ir_block_create_if(func->curblock, left, other, merge))
1637                 return false;
1638         } else {
1639             if (!ir_block_create_if(func->curblock, left, merge, other))
1640                 return false;
1641         }
1642         /* use the likely flag */
1643         vec_last(func->curblock->instr)->likely = true;
1644
1645         func->curblock = other;
1646         cgen = self->right->expression.codegen;
1647         if (!(*cgen)((ast_expression*)(self->right), func, false, &right))
1648             return false;
1649         if (!OPTS_FLAG(PERL_LOGIC)) {
1650             notop = type_not_instr[right->vtype];
1651             if (notop == AINSTR_END) {
1652                 asterror(ast_ctx(self), "don't know how to cast to bool...");
1653                 return false;
1654             }
1655             right = ir_block_create_unary(func->curblock,
1656                                           ast_function_label(func, "sce_not"),
1657                                           notop,
1658                                           right);
1659         }
1660         from_right = func->curblock;
1661
1662         if (!ir_block_create_jump(func->curblock, merge))
1663             return false;
1664
1665         vec_remove(func->ir_func->blocks, merge_id, 1);
1666         vec_push(func->ir_func->blocks, merge);
1667
1668         func->curblock = merge;
1669         phi = ir_block_create_phi(func->curblock, ast_function_label(func, "sce_value"), TYPE_FLOAT);
1670         ir_phi_add(phi, from_left, left);
1671         ir_phi_add(phi, from_right, right);
1672         *out = ir_phi_value(phi);
1673         if (!OPTS_FLAG(PERL_LOGIC)) {
1674             notop = type_not_instr[(*out)->vtype];
1675             if (notop == AINSTR_END) {
1676                 asterror(ast_ctx(self), "don't know how to cast to bool...");
1677                 return false;
1678             }
1679             *out = ir_block_create_unary(func->curblock,
1680                                          ast_function_label(func, "sce_final_not"),
1681                                          notop,
1682                                          *out);
1683         }
1684         if (!*out)
1685             return false;
1686         self->expression.outr = *out;
1687         return true;
1688     }
1689
1690     cgen = self->left->expression.codegen;
1691     if (!(*cgen)((ast_expression*)(self->left), func, false, &left))
1692         return false;
1693
1694     cgen = self->right->expression.codegen;
1695     if (!(*cgen)((ast_expression*)(self->right), func, false, &right))
1696         return false;
1697
1698     *out = ir_block_create_binop(func->curblock, ast_function_label(func, "bin"),
1699                                  self->op, left, right);
1700     if (!*out)
1701         return false;
1702     self->expression.outr = *out;
1703
1704     return true;
1705 }
1706
1707 bool ast_binstore_codegen(ast_binstore *self, ast_function *func, bool lvalue, ir_value **out)
1708 {
1709     ast_expression_codegen *cgen;
1710     ir_value *leftl = NULL, *leftr, *right, *bin;
1711
1712     ast_value       *arr;
1713     ast_value       *idx = 0;
1714     ast_array_index *ai = NULL;
1715     ir_value        *iridx = NULL;
1716
1717     if (lvalue && self->expression.outl) {
1718         *out = self->expression.outl;
1719         return true;
1720     }
1721
1722     if (!lvalue && self->expression.outr) {
1723         *out = self->expression.outr;
1724         return true;
1725     }
1726
1727     if (ast_istype(self->dest, ast_array_index))
1728     {
1729
1730         ai = (ast_array_index*)self->dest;
1731         idx = (ast_value*)ai->index;
1732
1733         if (ast_istype(ai->index, ast_value) && idx->hasvalue)
1734             ai = NULL;
1735     }
1736
1737     /* for a binstore we need both an lvalue and an rvalue for the left side */
1738     /* rvalue of destination! */
1739     if (ai) {
1740         cgen = idx->expression.codegen;
1741         if (!(*cgen)((ast_expression*)(idx), func, false, &iridx))
1742             return false;
1743     }
1744     cgen = self->dest->expression.codegen;
1745     if (!(*cgen)((ast_expression*)(self->dest), func, false, &leftr))
1746         return false;
1747
1748     /* source as rvalue only */
1749     cgen = self->source->expression.codegen;
1750     if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
1751         return false;
1752
1753     /* now the binary */
1754     bin = ir_block_create_binop(func->curblock, ast_function_label(func, "binst"),
1755                                 self->opbin, leftr, right);
1756     self->expression.outr = bin;
1757
1758
1759     if (ai) {
1760         /* we need to call the setter */
1761         ir_value  *funval;
1762         ir_instr  *call;
1763
1764         if (lvalue) {
1765             asterror(ast_ctx(self), "array-subscript assignment cannot produce lvalues");
1766             return false;
1767         }
1768
1769         arr = (ast_value*)ai->array;
1770         if (!ast_istype(ai->array, ast_value) || !arr->setter) {
1771             asterror(ast_ctx(self), "value has no setter (%s)", arr->name);
1772             return false;
1773         }
1774
1775         cgen = arr->setter->expression.codegen;
1776         if (!(*cgen)((ast_expression*)(arr->setter), func, true, &funval))
1777             return false;
1778
1779         call = ir_block_create_call(func->curblock, ast_function_label(func, "store"), funval);
1780         if (!call)
1781             return false;
1782         ir_call_param(call, iridx);
1783         ir_call_param(call, bin);
1784         self->expression.outr = bin;
1785     } else {
1786         /* now store them */
1787         cgen = self->dest->expression.codegen;
1788         /* lvalue of destination */
1789         if (!(*cgen)((ast_expression*)(self->dest), func, true, &leftl))
1790             return false;
1791         self->expression.outl = leftl;
1792
1793         if (!ir_block_create_store_op(func->curblock, self->opstore, leftl, bin))
1794             return false;
1795         self->expression.outr = bin;
1796     }
1797
1798     /* Theoretically, an assinment returns its left side as an
1799      * lvalue, if we don't need an lvalue though, we return
1800      * the right side as an rvalue, otherwise we have to
1801      * somehow know whether or not we need to dereference the pointer
1802      * on the left side - that is: OP_LOAD if it was an address.
1803      * Also: in original QC we cannot OP_LOADP *anyway*.
1804      */
1805     *out = (lvalue ? leftl : bin);
1806
1807     return true;
1808 }
1809
1810 bool ast_unary_codegen(ast_unary *self, ast_function *func, bool lvalue, ir_value **out)
1811 {
1812     ast_expression_codegen *cgen;
1813     ir_value *operand;
1814
1815     /* An unary operation cannot yield an l-value */
1816     if (lvalue) {
1817         asterror(ast_ctx(self), "not an l-value (binop)");
1818         return false;
1819     }
1820
1821     if (self->expression.outr) {
1822         *out = self->expression.outr;
1823         return true;
1824     }
1825
1826     cgen = self->operand->expression.codegen;
1827     /* lvalue! */
1828     if (!(*cgen)((ast_expression*)(self->operand), func, false, &operand))
1829         return false;
1830
1831     *out = ir_block_create_unary(func->curblock, ast_function_label(func, "unary"),
1832                                  self->op, operand);
1833     if (!*out)
1834         return false;
1835     self->expression.outr = *out;
1836
1837     return true;
1838 }
1839
1840 bool ast_return_codegen(ast_return *self, ast_function *func, bool lvalue, ir_value **out)
1841 {
1842     ast_expression_codegen *cgen;
1843     ir_value *operand;
1844
1845     *out = NULL;
1846
1847     /* In the context of a return operation, we don't actually return
1848      * anything...
1849      */
1850     if (lvalue) {
1851         asterror(ast_ctx(self), "return-expression is not an l-value");
1852         return false;
1853     }
1854
1855     if (self->expression.outr) {
1856         asterror(ast_ctx(self), "internal error: ast_return cannot be reused, it bears no result!");
1857         return false;
1858     }
1859     self->expression.outr = (ir_value*)1;
1860
1861     if (self->operand) {
1862         cgen = self->operand->expression.codegen;
1863         /* lvalue! */
1864         if (!(*cgen)((ast_expression*)(self->operand), func, false, &operand))
1865             return false;
1866
1867         if (!ir_block_create_return(func->curblock, operand))
1868             return false;
1869     } else {
1870         if (!ir_block_create_return(func->curblock, NULL))
1871             return false;
1872     }
1873
1874     return true;
1875 }
1876
1877 bool ast_entfield_codegen(ast_entfield *self, ast_function *func, bool lvalue, ir_value **out)
1878 {
1879     ast_expression_codegen *cgen;
1880     ir_value *ent, *field;
1881
1882     /* This function needs to take the 'lvalue' flag into account!
1883      * As lvalue we provide a field-pointer, as rvalue we provide the
1884      * value in a temp.
1885      */
1886
1887     if (lvalue && self->expression.outl) {
1888         *out = self->expression.outl;
1889         return true;
1890     }
1891
1892     if (!lvalue && self->expression.outr) {
1893         *out = self->expression.outr;
1894         return true;
1895     }
1896
1897     cgen = self->entity->expression.codegen;
1898     if (!(*cgen)((ast_expression*)(self->entity), func, false, &ent))
1899         return false;
1900
1901     cgen = self->field->expression.codegen;
1902     if (!(*cgen)((ast_expression*)(self->field), func, false, &field))
1903         return false;
1904
1905     if (lvalue) {
1906         /* address! */
1907         *out = ir_block_create_fieldaddress(func->curblock, ast_function_label(func, "efa"),
1908                                             ent, field);
1909     } else {
1910         *out = ir_block_create_load_from_ent(func->curblock, ast_function_label(func, "efv"),
1911                                              ent, field, self->expression.vtype);
1912     }
1913     if (!*out) {
1914         asterror(ast_ctx(self), "failed to create %s instruction (output type %s)",
1915                  (lvalue ? "ADDRESS" : "FIELD"),
1916                  type_name[self->expression.vtype]);
1917         return false;
1918     }
1919
1920     if (lvalue)
1921         self->expression.outl = *out;
1922     else
1923         self->expression.outr = *out;
1924
1925     /* Hm that should be it... */
1926     return true;
1927 }
1928
1929 bool ast_member_codegen(ast_member *self, ast_function *func, bool lvalue, ir_value **out)
1930 {
1931     ast_expression_codegen *cgen;
1932     ir_value *vec;
1933
1934     /* in QC this is always an lvalue */
1935     (void)lvalue;
1936     if (self->expression.outl) {
1937         *out = self->expression.outl;
1938         return true;
1939     }
1940
1941     cgen = self->owner->expression.codegen;
1942     if (!(*cgen)((ast_expression*)(self->owner), func, true, &vec))
1943         return false;
1944
1945     if (vec->vtype != TYPE_VECTOR &&
1946         !(vec->vtype == TYPE_FIELD && self->owner->expression.next->expression.vtype == TYPE_VECTOR))
1947     {
1948         return false;
1949     }
1950
1951     *out = ir_value_vector_member(vec, self->field);
1952     self->expression.outl = *out;
1953
1954     return (*out != NULL);
1955 }
1956
1957 bool ast_array_index_codegen(ast_array_index *self, ast_function *func, bool lvalue, ir_value **out)
1958 {
1959     ast_value *arr;
1960     ast_value *idx;
1961
1962     if (!lvalue && self->expression.outr) {
1963         *out = self->expression.outr;
1964     }
1965     if (lvalue && self->expression.outl) {
1966         *out = self->expression.outl;
1967     }
1968
1969     if (!ast_istype(self->array, ast_value)) {
1970         asterror(ast_ctx(self), "array indexing this way is not supported");
1971         /* note this would actually be pointer indexing because the left side is
1972          * not an actual array but (hopefully) an indexable expression.
1973          * Once we get integer arithmetic, and GADDRESS/GSTORE/GLOAD instruction
1974          * support this path will be filled.
1975          */
1976         return false;
1977     }
1978
1979     arr = (ast_value*)self->array;
1980     idx = (ast_value*)self->index;
1981
1982     if (!ast_istype(self->index, ast_value) || !idx->hasvalue) {
1983         /* Time to use accessor functions */
1984         ast_expression_codegen *cgen;
1985         ir_value               *iridx, *funval;
1986         ir_instr               *call;
1987
1988         if (lvalue) {
1989             asterror(ast_ctx(self), "(.2) array indexing here needs a compile-time constant");
1990             return false;
1991         }
1992
1993         if (!arr->getter) {
1994             asterror(ast_ctx(self), "value has no getter, don't know how to index it");
1995             return false;
1996         }
1997
1998         cgen = self->index->expression.codegen;
1999         if (!(*cgen)((ast_expression*)(self->index), func, true, &iridx))
2000             return false;
2001
2002         cgen = arr->getter->expression.codegen;
2003         if (!(*cgen)((ast_expression*)(arr->getter), func, true, &funval))
2004             return false;
2005
2006         call = ir_block_create_call(func->curblock, ast_function_label(func, "fetch"), funval);
2007         if (!call)
2008             return false;
2009         ir_call_param(call, iridx);
2010
2011         *out = ir_call_value(call);
2012         self->expression.outr = *out;
2013         return true;
2014     }
2015
2016     if (idx->expression.vtype == TYPE_FLOAT)
2017         *out = arr->ir_values[(int)idx->constval.vfloat];
2018     else if (idx->expression.vtype == TYPE_INTEGER)
2019         *out = arr->ir_values[idx->constval.vint];
2020     else {
2021         asterror(ast_ctx(self), "array indexing here needs an integer constant");
2022         return false;
2023     }
2024     return true;
2025 }
2026
2027 bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_value **out)
2028 {
2029     ast_expression_codegen *cgen;
2030
2031     ir_value *condval;
2032     ir_value *dummy;
2033
2034     ir_block *cond = func->curblock;
2035     ir_block *ontrue;
2036     ir_block *onfalse;
2037     ir_block *ontrue_endblock = NULL;
2038     ir_block *onfalse_endblock = NULL;
2039     ir_block *merge;
2040
2041     /* We don't output any value, thus also don't care about r/lvalue */
2042     (void)out;
2043     (void)lvalue;
2044
2045     if (self->expression.outr) {
2046         asterror(ast_ctx(self), "internal error: ast_ifthen cannot be reused, it bears no result!");
2047         return false;
2048     }
2049     self->expression.outr = (ir_value*)1;
2050
2051     /* generate the condition */
2052     cgen = self->cond->expression.codegen;
2053     if (!(*cgen)((ast_expression*)(self->cond), func, false, &condval))
2054         return false;
2055     /* update the block which will get the jump - because short-logic or ternaries may have changed this */
2056     cond = func->curblock;
2057
2058     /* on-true path */
2059
2060     if (self->on_true) {
2061         /* create on-true block */
2062         ontrue = ir_function_create_block(func->ir_func, ast_function_label(func, "ontrue"));
2063         if (!ontrue)
2064             return false;
2065
2066         /* enter the block */
2067         func->curblock = ontrue;
2068
2069         /* generate */
2070         cgen = self->on_true->expression.codegen;
2071         if (!(*cgen)((ast_expression*)(self->on_true), func, false, &dummy))
2072             return false;
2073
2074         /* we now need to work from the current endpoint */
2075         ontrue_endblock = func->curblock;
2076     } else
2077         ontrue = NULL;
2078
2079     /* on-false path */
2080     if (self->on_false) {
2081         /* create on-false block */
2082         onfalse = ir_function_create_block(func->ir_func, ast_function_label(func, "onfalse"));
2083         if (!onfalse)
2084             return false;
2085
2086         /* enter the block */
2087         func->curblock = onfalse;
2088
2089         /* generate */
2090         cgen = self->on_false->expression.codegen;
2091         if (!(*cgen)((ast_expression*)(self->on_false), func, false, &dummy))
2092             return false;
2093
2094         /* we now need to work from the current endpoint */
2095         onfalse_endblock = func->curblock;
2096     } else
2097         onfalse = NULL;
2098
2099     /* Merge block were they all merge in to */
2100     merge = ir_function_create_block(func->ir_func, ast_function_label(func, "endif"));
2101     if (!merge)
2102         return false;
2103     /* add jumps ot the merge block */
2104     if (ontrue && !ontrue_endblock->final && !ir_block_create_jump(ontrue_endblock, merge))
2105         return false;
2106     if (onfalse && !onfalse_endblock->final && !ir_block_create_jump(onfalse_endblock, merge))
2107         return false;
2108
2109     /* we create the if here, that way all blocks are ordered :)
2110      */
2111     if (!ir_block_create_if(cond, condval,
2112                             (ontrue  ? ontrue  : merge),
2113                             (onfalse ? onfalse : merge)))
2114     {
2115         return false;
2116     }
2117
2118     /* Now enter the merge block */
2119     func->curblock = merge;
2120
2121     return true;
2122 }
2123
2124 bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_value **out)
2125 {
2126     ast_expression_codegen *cgen;
2127
2128     ir_value *condval;
2129     ir_value *trueval, *falseval;
2130     ir_instr *phi;
2131
2132     ir_block *cond = func->curblock;
2133     ir_block *ontrue;
2134     ir_block *onfalse;
2135     ir_block *merge;
2136
2137     /* Ternary can never create an lvalue... */
2138     if (lvalue)
2139         return false;
2140
2141     /* In theory it shouldn't be possible to pass through a node twice, but
2142      * in case we add any kind of optimization pass for the AST itself, it
2143      * may still happen, thus we remember a created ir_value and simply return one
2144      * if it already exists.
2145      */
2146     if (self->expression.outr) {
2147         *out = self->expression.outr;
2148         return true;
2149     }
2150
2151     /* In the following, contraty to ast_ifthen, we assume both paths exist. */
2152
2153     /* generate the condition */
2154     func->curblock = cond;
2155     cgen = self->cond->expression.codegen;
2156     if (!(*cgen)((ast_expression*)(self->cond), func, false, &condval))
2157         return false;
2158
2159     /* create on-true block */
2160     ontrue = ir_function_create_block(func->ir_func, ast_function_label(func, "tern_T"));
2161     if (!ontrue)
2162         return false;
2163     else
2164     {
2165         /* enter the block */
2166         func->curblock = ontrue;
2167
2168         /* generate */
2169         cgen = self->on_true->expression.codegen;
2170         if (!(*cgen)((ast_expression*)(self->on_true), func, false, &trueval))
2171             return false;
2172     }
2173
2174     /* create on-false block */
2175     onfalse = ir_function_create_block(func->ir_func, ast_function_label(func, "tern_F"));
2176     if (!onfalse)
2177         return false;
2178     else
2179     {
2180         /* enter the block */
2181         func->curblock = onfalse;
2182
2183         /* generate */
2184         cgen = self->on_false->expression.codegen;
2185         if (!(*cgen)((ast_expression*)(self->on_false), func, false, &falseval))
2186             return false;
2187     }
2188
2189     /* create merge block */
2190     merge = ir_function_create_block(func->ir_func, ast_function_label(func, "tern_out"));
2191     if (!merge)
2192         return false;
2193     /* jump to merge block */
2194     if (!ir_block_create_jump(ontrue, merge))
2195         return false;
2196     if (!ir_block_create_jump(onfalse, merge))
2197         return false;
2198
2199     /* create if instruction */
2200     if (!ir_block_create_if(cond, condval, ontrue, onfalse))
2201         return false;
2202
2203     /* Now enter the merge block */
2204     func->curblock = merge;
2205
2206     /* Here, now, we need a PHI node
2207      * but first some sanity checking...
2208      */
2209     if (trueval->vtype != falseval->vtype) {
2210         /* error("ternary with different types on the two sides"); */
2211         return false;
2212     }
2213
2214     /* create PHI */
2215     phi = ir_block_create_phi(merge, ast_function_label(func, "phi"), trueval->vtype);
2216     if (!phi)
2217         return false;
2218     ir_phi_add(phi, ontrue,  trueval);
2219     ir_phi_add(phi, onfalse, falseval);
2220
2221     self->expression.outr = ir_phi_value(phi);
2222     *out = self->expression.outr;
2223
2224     return true;
2225 }
2226
2227 bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value **out)
2228 {
2229     ast_expression_codegen *cgen;
2230
2231     ir_value *dummy      = NULL;
2232     ir_value *precond    = NULL;
2233     ir_value *postcond   = NULL;
2234
2235     /* Since we insert some jumps "late" so we have blocks
2236      * ordered "nicely", we need to keep track of the actual end-blocks
2237      * of expressions to add the jumps to.
2238      */
2239     ir_block *bbody      = NULL, *end_bbody      = NULL;
2240     ir_block *bprecond   = NULL, *end_bprecond   = NULL;
2241     ir_block *bpostcond  = NULL, *end_bpostcond  = NULL;
2242     ir_block *bincrement = NULL, *end_bincrement = NULL;
2243     ir_block *bout       = NULL, *bin            = NULL;
2244
2245     /* let's at least move the outgoing block to the end */
2246     size_t    bout_id;
2247
2248     /* 'break' and 'continue' need to be able to find the right blocks */
2249     ir_block *bcontinue     = NULL;
2250     ir_block *bbreak        = NULL;
2251
2252     ir_block *old_bcontinue = NULL;
2253     ir_block *old_bbreak    = NULL;
2254
2255     ir_block *tmpblock      = NULL;
2256
2257     (void)lvalue;
2258     (void)out;
2259
2260     if (self->expression.outr) {
2261         asterror(ast_ctx(self), "internal error: ast_loop cannot be reused, it bears no result!");
2262         return false;
2263     }
2264     self->expression.outr = (ir_value*)1;
2265
2266     /* NOTE:
2267      * Should we ever need some kind of block ordering, better make this function
2268      * move blocks around than write a block ordering algorithm later... after all
2269      * the ast and ir should work together, not against each other.
2270      */
2271
2272     /* initexpr doesn't get its own block, it's pointless, it could create more blocks
2273      * anyway if for example it contains a ternary.
2274      */
2275     if (self->initexpr)
2276     {
2277         cgen = self->initexpr->expression.codegen;
2278         if (!(*cgen)((ast_expression*)(self->initexpr), func, false, &dummy))
2279             return false;
2280     }
2281
2282     /* Store the block from which we enter this chaos */
2283     bin = func->curblock;
2284
2285     /* The pre-loop condition needs its own block since we
2286      * need to be able to jump to the start of that expression.
2287      */
2288     if (self->precond)
2289     {
2290         bprecond = ir_function_create_block(func->ir_func, ast_function_label(func, "pre_loop_cond"));
2291         if (!bprecond)
2292             return false;
2293
2294         /* the pre-loop-condition the least important place to 'continue' at */
2295         bcontinue = bprecond;
2296
2297         /* enter */
2298         func->curblock = bprecond;
2299
2300         /* generate */
2301         cgen = self->precond->expression.codegen;
2302         if (!(*cgen)((ast_expression*)(self->precond), func, false, &precond))
2303             return false;
2304
2305         end_bprecond = func->curblock;
2306     } else {
2307         bprecond = end_bprecond = NULL;
2308     }
2309
2310     /* Now the next blocks won't be ordered nicely, but we need to
2311      * generate them this early for 'break' and 'continue'.
2312      */
2313     if (self->increment) {
2314         bincrement = ir_function_create_block(func->ir_func, ast_function_label(func, "loop_increment"));
2315         if (!bincrement)
2316             return false;
2317         bcontinue = bincrement; /* increment comes before the pre-loop-condition */
2318     } else {
2319         bincrement = end_bincrement = NULL;
2320     }
2321
2322     if (self->postcond) {
2323         bpostcond = ir_function_create_block(func->ir_func, ast_function_label(func, "post_loop_cond"));
2324         if (!bpostcond)
2325             return false;
2326         bcontinue = bpostcond; /* postcond comes before the increment */
2327     } else {
2328         bpostcond = end_bpostcond = NULL;
2329     }
2330
2331     bout_id = vec_size(func->ir_func->blocks);
2332     bout = ir_function_create_block(func->ir_func, ast_function_label(func, "after_loop"));
2333     if (!bout)
2334         return false;
2335     bbreak = bout;
2336
2337     /* The loop body... */
2338     if (self->body)
2339     {
2340         bbody = ir_function_create_block(func->ir_func, ast_function_label(func, "loop_body"));
2341         if (!bbody)
2342             return false;
2343
2344         /* enter */
2345         func->curblock = bbody;
2346
2347         old_bbreak          = func->breakblock;
2348         old_bcontinue       = func->continueblock;
2349         func->breakblock    = bbreak;
2350         func->continueblock = bcontinue;
2351
2352         /* generate */
2353         cgen = self->body->expression.codegen;
2354         if (!(*cgen)((ast_expression*)(self->body), func, false, &dummy))
2355             return false;
2356
2357         end_bbody = func->curblock;
2358         func->breakblock    = old_bbreak;
2359         func->continueblock = old_bcontinue;
2360     }
2361
2362     /* post-loop-condition */
2363     if (self->postcond)
2364     {
2365         /* enter */
2366         func->curblock = bpostcond;
2367
2368         /* generate */
2369         cgen = self->postcond->expression.codegen;
2370         if (!(*cgen)((ast_expression*)(self->postcond), func, false, &postcond))
2371             return false;
2372
2373         end_bpostcond = func->curblock;
2374     }
2375
2376     /* The incrementor */
2377     if (self->increment)
2378     {
2379         /* enter */
2380         func->curblock = bincrement;
2381
2382         /* generate */
2383         cgen = self->increment->expression.codegen;
2384         if (!(*cgen)((ast_expression*)(self->increment), func, false, &dummy))
2385             return false;
2386
2387         end_bincrement = func->curblock;
2388     }
2389
2390     /* In any case now, we continue from the outgoing block */
2391     func->curblock = bout;
2392
2393     /* Now all blocks are in place */
2394     /* From 'bin' we jump to whatever comes first */
2395     if      (bprecond)   tmpblock = bprecond;
2396     else if (bbody)      tmpblock = bbody;
2397     else if (bpostcond)  tmpblock = bpostcond;
2398     else                 tmpblock = bout;
2399     if (!ir_block_create_jump(bin, tmpblock))
2400         return false;
2401
2402     /* From precond */
2403     if (bprecond)
2404     {
2405         ir_block *ontrue, *onfalse;
2406         if      (bbody)      ontrue = bbody;
2407         else if (bincrement) ontrue = bincrement;
2408         else if (bpostcond)  ontrue = bpostcond;
2409         else                 ontrue = bprecond;
2410         onfalse = bout;
2411         if (!ir_block_create_if(end_bprecond, precond, ontrue, onfalse))
2412             return false;
2413     }
2414
2415     /* from body */
2416     if (bbody)
2417     {
2418         if      (bincrement) tmpblock = bincrement;
2419         else if (bpostcond)  tmpblock = bpostcond;
2420         else if (bprecond)   tmpblock = bprecond;
2421         else                 tmpblock = bout;
2422         if (!end_bbody->final && !ir_block_create_jump(end_bbody, tmpblock))
2423             return false;
2424     }
2425
2426     /* from increment */
2427     if (bincrement)
2428     {
2429         if      (bpostcond)  tmpblock = bpostcond;
2430         else if (bprecond)   tmpblock = bprecond;
2431         else if (bbody)      tmpblock = bbody;
2432         else                 tmpblock = bout;
2433         if (!ir_block_create_jump(end_bincrement, tmpblock))
2434             return false;
2435     }
2436
2437     /* from postcond */
2438     if (bpostcond)
2439     {
2440         ir_block *ontrue, *onfalse;
2441         if      (bprecond)   ontrue = bprecond;
2442         else if (bbody)      ontrue = bbody;
2443         else if (bincrement) ontrue = bincrement;
2444         else                 ontrue = bpostcond;
2445         onfalse = bout;
2446         if (!ir_block_create_if(end_bpostcond, postcond, ontrue, onfalse))
2447             return false;
2448     }
2449
2450     /* Move 'bout' to the end */
2451     vec_remove(func->ir_func->blocks, bout_id, 1);
2452     vec_push(func->ir_func->blocks, bout);
2453
2454     return true;
2455 }
2456
2457 bool ast_breakcont_codegen(ast_breakcont *self, ast_function *func, bool lvalue, ir_value **out)
2458 {
2459     ir_block *target;
2460
2461     *out = NULL;
2462
2463     if (lvalue) {
2464         asterror(ast_ctx(self), "break/continue expression is not an l-value");
2465         return false;
2466     }
2467
2468     if (self->expression.outr) {
2469         asterror(ast_ctx(self), "internal error: ast_breakcont cannot be reused!");
2470         return false;
2471     }
2472     self->expression.outr = (ir_value*)1;
2473
2474     if (self->is_continue)
2475         target = func->continueblock;
2476     else
2477         target = func->breakblock;
2478
2479     if (!ir_block_create_jump(func->curblock, target))
2480         return false;
2481     return true;
2482 }
2483
2484 bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_value **out)
2485 {
2486     ast_expression_codegen *cgen;
2487
2488     ast_switch_case *def_case  = NULL;
2489     ir_block        *def_bfall = NULL;
2490
2491     ir_value *dummy     = NULL;
2492     ir_value *irop      = NULL;
2493     ir_block *old_break = NULL;
2494     ir_block *bout      = NULL;
2495     ir_block *bfall     = NULL;
2496     size_t    bout_id;
2497     size_t    c;
2498
2499     char      typestr[1024];
2500     uint16_t  cmpinstr;
2501
2502     if (lvalue) {
2503         asterror(ast_ctx(self), "switch expression is not an l-value");
2504         return false;
2505     }
2506
2507     if (self->expression.outr) {
2508         asterror(ast_ctx(self), "internal error: ast_switch cannot be reused!");
2509         return false;
2510     }
2511     self->expression.outr = (ir_value*)1;
2512
2513     (void)lvalue;
2514     (void)out;
2515
2516     cgen = self->operand->expression.codegen;
2517     if (!(*cgen)((ast_expression*)(self->operand), func, false, &irop))
2518         return false;
2519
2520     if (!vec_size(self->cases))
2521         return true;
2522
2523     cmpinstr = type_eq_instr[irop->vtype];
2524     if (cmpinstr >= AINSTR_END) {
2525         ast_type_to_string(self->operand, typestr, sizeof(typestr));
2526         asterror(ast_ctx(self), "invalid type to perform a switch on: %s", typestr);
2527         return false;
2528     }
2529
2530     bout_id = vec_size(func->ir_func->blocks);
2531     bout = ir_function_create_block(func->ir_func, ast_function_label(func, "after_switch"));
2532     if (!bout)
2533         return false;
2534
2535     /* setup the break block */
2536     old_break        = func->breakblock;
2537     func->breakblock = bout;
2538
2539     /* Now create all cases */
2540     for (c = 0; c < vec_size(self->cases); ++c) {
2541         ir_value *cond, *val;
2542         ir_block *bcase, *bnot;
2543         size_t bnot_id;
2544
2545         ast_switch_case *swcase = &self->cases[c];
2546
2547         if (swcase->value) {
2548             /* A regular case */
2549             /* generate the condition operand */
2550             cgen = swcase->value->expression.codegen;
2551             if (!(*cgen)((ast_expression*)(swcase->value), func, false, &val))
2552                 return false;
2553             /* generate the condition */
2554             cond = ir_block_create_binop(func->curblock, ast_function_label(func, "switch_eq"), cmpinstr, irop, val);
2555             if (!cond)
2556                 return false;
2557
2558             bcase = ir_function_create_block(func->ir_func, ast_function_label(func, "case"));
2559             bnot_id = vec_size(func->ir_func->blocks);
2560             bnot = ir_function_create_block(func->ir_func, ast_function_label(func, "not_case"));
2561             if (!bcase || !bnot)
2562                 return false;
2563             if (!ir_block_create_if(func->curblock, cond, bcase, bnot))
2564                 return false;
2565
2566             /* Make the previous case-end fall through */
2567             if (bfall && !bfall->final) {
2568                 if (!ir_block_create_jump(bfall, bcase))
2569                     return false;
2570             }
2571
2572             /* enter the case */
2573             func->curblock = bcase;
2574             cgen = swcase->code->expression.codegen;
2575             if (!(*cgen)((ast_expression*)swcase->code, func, false, &dummy))
2576                 return false;
2577
2578             /* remember this block to fall through from */
2579             bfall = func->curblock;
2580
2581             /* enter the else and move it down */
2582             func->curblock = bnot;
2583             vec_remove(func->ir_func->blocks, bnot_id, 1);
2584             vec_push(func->ir_func->blocks, bnot);
2585         } else {
2586             /* The default case */
2587             /* Remember where to fall through from: */
2588             def_bfall = bfall;
2589             bfall     = NULL;
2590             /* remember which case it was */
2591             def_case  = swcase;
2592         }
2593     }
2594
2595     /* Jump from the last bnot to bout */
2596     if (bfall && !bfall->final && !ir_block_create_jump(bfall, bout)) {
2597         /*
2598         astwarning(ast_ctx(bfall), WARN_???, "missing break after last case");
2599         */
2600         return false;
2601     }
2602
2603     /* If there was a default case, put it down here */
2604     if (def_case) {
2605         ir_block *bcase;
2606
2607         /* No need to create an extra block */
2608         bcase = func->curblock;
2609
2610         /* Insert the fallthrough jump */
2611         if (def_bfall && !def_bfall->final) {
2612             if (!ir_block_create_jump(def_bfall, bcase))
2613                 return false;
2614         }
2615
2616         /* Now generate the default code */
2617         cgen = def_case->code->expression.codegen;
2618         if (!(*cgen)((ast_expression*)def_case->code, func, false, &dummy))
2619             return false;
2620     }
2621
2622     /* Jump from the last bnot to bout */
2623     if (!func->curblock->final && !ir_block_create_jump(func->curblock, bout))
2624         return false;
2625     /* enter the outgoing block */
2626     func->curblock = bout;
2627
2628     /* restore the break block */
2629     func->breakblock = old_break;
2630
2631     /* Move 'bout' to the end, it's nicer */
2632     vec_remove(func->ir_func->blocks, bout_id, 1);
2633     vec_push(func->ir_func->blocks, bout);
2634
2635     return true;
2636 }
2637
2638 bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value **out)
2639 {
2640     ast_expression_codegen *cgen;
2641     ir_value              **params;
2642     ir_instr               *callinstr;
2643     size_t i;
2644
2645     ir_value *funval = NULL;
2646
2647     /* return values are never lvalues */
2648     if (lvalue) {
2649         asterror(ast_ctx(self), "not an l-value (function call)");
2650         return false;
2651     }
2652
2653     if (self->expression.outr) {
2654         *out = self->expression.outr;
2655         return true;
2656     }
2657
2658     cgen = self->func->expression.codegen;
2659     if (!(*cgen)((ast_expression*)(self->func), func, false, &funval))
2660         return false;
2661     if (!funval)
2662         return false;
2663
2664     params = NULL;
2665
2666     /* parameters */
2667     for (i = 0; i < vec_size(self->params); ++i)
2668     {
2669         ir_value *param;
2670         ast_expression *expr = self->params[i];
2671
2672         cgen = expr->expression.codegen;
2673         if (!(*cgen)(expr, func, false, &param))
2674             goto error;
2675         if (!param)
2676             goto error;
2677         vec_push(params, param);
2678     }
2679
2680     callinstr = ir_block_create_call(func->curblock, ast_function_label(func, "call"), funval);
2681     if (!callinstr)
2682         goto error;
2683
2684     for (i = 0; i < vec_size(params); ++i) {
2685         ir_call_param(callinstr, params[i]);
2686     }
2687
2688     *out = ir_call_value(callinstr);
2689     self->expression.outr = *out;
2690
2691     vec_free(params);
2692     return true;
2693 error:
2694     vec_free(params);
2695     return false;
2696 }