]> git.xonotic.org Git - xonotic/gmqcc.git/blob - ast.c
ast_label, and labels later used for goto
[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_label* ast_label_new(lex_ctx ctx, const char *name)
804 {
805     ast_instantiate(ast_label, ctx, ast_label_delete);
806     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_label_codegen);
807
808     self->name    = util_strdup(name);
809     self->irblock = NULL;
810
811     return self;
812 }
813
814 void ast_label_delete(ast_label *self)
815 {
816     mem_d((void*)self->name);
817     ast_expression_delete((ast_expression*)self);
818     mem_d(self);
819 }
820
821 ast_call* ast_call_new(lex_ctx ctx,
822                        ast_expression *funcexpr)
823 {
824     ast_instantiate(ast_call, ctx, ast_call_delete);
825     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_call_codegen);
826
827     ast_side_effects(self) = true;
828
829     self->params = NULL;
830     self->func   = funcexpr;
831
832     self->expression.vtype = funcexpr->expression.next->expression.vtype;
833     if (funcexpr->expression.next->expression.next)
834         self->expression.next = ast_type_copy(ctx, funcexpr->expression.next->expression.next);
835
836     return self;
837 }
838
839 void ast_call_delete(ast_call *self)
840 {
841     size_t i;
842     for (i = 0; i < vec_size(self->params); ++i)
843         ast_unref(self->params[i]);
844     vec_free(self->params);
845
846     if (self->func)
847         ast_unref(self->func);
848
849     ast_expression_delete((ast_expression*)self);
850     mem_d(self);
851 }
852
853 bool ast_call_check_types(ast_call *self)
854 {
855     size_t i;
856     bool   retval = true;
857     const  ast_expression *func = self->func;
858     size_t count = vec_size(self->params);
859     if (count > vec_size(func->expression.params))
860         count = vec_size(func->expression.params);
861
862     for (i = 0; i < count; ++i) {
863         if (!ast_compare_type(self->params[i], (ast_expression*)(func->expression.params[i]))) {
864             char texp[1024];
865             char tgot[1024];
866             ast_type_to_string(self->params[i], tgot, sizeof(tgot));
867             ast_type_to_string((ast_expression*)func->expression.params[i], texp, sizeof(texp));
868             asterror(ast_ctx(self), "invalid type for parameter %u in function call: expected %s, got %s",
869                      (unsigned int)(i+1), texp, tgot);
870             /* we don't immediately return */
871             retval = false;
872         }
873     }
874     return retval;
875 }
876
877 ast_store* ast_store_new(lex_ctx ctx, int op,
878                          ast_expression *dest, ast_expression *source)
879 {
880     ast_instantiate(ast_store, ctx, ast_store_delete);
881     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_store_codegen);
882
883     ast_side_effects(self) = true;
884
885     self->op = op;
886     self->dest = dest;
887     self->source = source;
888
889     self->expression.vtype = dest->expression.vtype;
890     if (dest->expression.next) {
891         self->expression.next = ast_type_copy(ctx, dest);
892         if (!self->expression.next) {
893             ast_delete(self);
894             return NULL;
895         }
896     }
897     else
898         self->expression.next = NULL;
899
900     return self;
901 }
902
903 void ast_store_delete(ast_store *self)
904 {
905     ast_unref(self->dest);
906     ast_unref(self->source);
907     ast_expression_delete((ast_expression*)self);
908     mem_d(self);
909 }
910
911 ast_block* ast_block_new(lex_ctx ctx)
912 {
913     ast_instantiate(ast_block, ctx, ast_block_delete);
914     ast_expression_init((ast_expression*)self,
915                         (ast_expression_codegen*)&ast_block_codegen);
916
917     self->locals  = NULL;
918     self->exprs   = NULL;
919     self->collect = NULL;
920
921     return self;
922 }
923
924 void ast_block_add_expr(ast_block *self, ast_expression *e)
925 {
926     ast_propagate_effects(self, e);
927     vec_push(self->exprs, e);
928 }
929
930 void ast_block_collect(ast_block *self, ast_expression *expr)
931 {
932     vec_push(self->collect, expr);
933     expr->expression.node.keep = true;
934 }
935
936 void ast_block_delete(ast_block *self)
937 {
938     size_t i;
939     for (i = 0; i < vec_size(self->exprs); ++i)
940         ast_unref(self->exprs[i]);
941     vec_free(self->exprs);
942     for (i = 0; i < vec_size(self->locals); ++i)
943         ast_delete(self->locals[i]);
944     vec_free(self->locals);
945     for (i = 0; i < vec_size(self->collect); ++i)
946         ast_delete(self->collect[i]);
947     vec_free(self->collect);
948     ast_expression_delete((ast_expression*)self);
949     mem_d(self);
950 }
951
952 bool ast_block_set_type(ast_block *self, ast_expression *from)
953 {
954     if (self->expression.next)
955         ast_delete(self->expression.next);
956     self->expression.vtype = from->expression.vtype;
957     if (from->expression.next) {
958         self->expression.next = ast_type_copy(self->expression.node.context, from->expression.next);
959         if (!self->expression.next)
960             return false;
961     }
962     else
963         self->expression.next = NULL;
964     return true;
965 }
966
967 ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype)
968 {
969     ast_instantiate(ast_function, ctx, ast_function_delete);
970
971     if (!vtype ||
972         vtype->hasvalue ||
973         vtype->expression.vtype != TYPE_FUNCTION)
974     {
975         asterror(ast_ctx(self), "internal error: ast_function_new condition %i %i type=%i",
976                  (int)!vtype,
977                  (int)vtype->hasvalue,
978                  vtype->expression.vtype);
979         mem_d(self);
980         return NULL;
981     }
982
983     self->vtype  = vtype;
984     self->name   = name ? util_strdup(name) : NULL;
985     self->blocks = NULL;
986
987     self->labelcount = 0;
988     self->builtin = 0;
989
990     self->ir_func = NULL;
991     self->curblock = NULL;
992
993     self->breakblock    = NULL;
994     self->continueblock = NULL;
995
996     vtype->hasvalue = true;
997     vtype->constval.vfunc = self;
998
999     return self;
1000 }
1001
1002 void ast_function_delete(ast_function *self)
1003 {
1004     size_t i;
1005     if (self->name)
1006         mem_d((void*)self->name);
1007     if (self->vtype) {
1008         /* ast_value_delete(self->vtype); */
1009         self->vtype->hasvalue = false;
1010         self->vtype->constval.vfunc = NULL;
1011         /* We use unref - if it was stored in a global table it is supposed
1012          * to be deleted from *there*
1013          */
1014         ast_unref(self->vtype);
1015     }
1016     for (i = 0; i < vec_size(self->blocks); ++i)
1017         ast_delete(self->blocks[i]);
1018     vec_free(self->blocks);
1019     mem_d(self);
1020 }
1021
1022 const char* ast_function_label(ast_function *self, const char *prefix)
1023 {
1024     size_t id;
1025     size_t len;
1026     char  *from;
1027
1028     if (!opts_dump && !opts_dumpfin)
1029         return NULL;
1030
1031     id  = (self->labelcount++);
1032     len = strlen(prefix);
1033
1034     from = self->labelbuf + sizeof(self->labelbuf)-1;
1035     *from-- = 0;
1036     do {
1037         unsigned int digit = id % 10;
1038         *from = digit + '0';
1039         id /= 10;
1040     } while (id);
1041     memcpy(from - len, prefix, len);
1042     return from - len;
1043 }
1044
1045 /*********************************************************************/
1046 /* AST codegen part
1047  * by convention you must never pass NULL to the 'ir_value **out'
1048  * parameter. If you really don't care about the output, pass a dummy.
1049  * But I can't imagine a pituation where the output is truly unnecessary.
1050  */
1051
1052 bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_value **out)
1053 {
1054     (void)func;
1055     (void)lvalue;
1056     /* NOTE: This is the codegen for a variable used in an expression.
1057      * It is not the codegen to generate the value. For this purpose,
1058      * ast_local_codegen and ast_global_codegen are to be used before this
1059      * is executed. ast_function_codegen should take care of its locals,
1060      * and the ast-user should take care of ast_global_codegen to be used
1061      * on all the globals.
1062      */
1063     if (!self->ir_v) {
1064         char typename[1024];
1065         ast_type_to_string((ast_expression*)self, typename, sizeof(typename));
1066         asterror(ast_ctx(self), "ast_value used before generated %s %s", typename, self->name);
1067         return false;
1068     }
1069     *out = self->ir_v;
1070     return true;
1071 }
1072
1073 bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
1074 {
1075     ir_value *v = NULL;
1076
1077     if (self->hasvalue && self->expression.vtype == TYPE_FUNCTION)
1078     {
1079         ir_function *func = ir_builder_create_function(ir, self->name, self->expression.next->expression.vtype);
1080         if (!func)
1081             return false;
1082         func->context = ast_ctx(self);
1083         func->value->context = ast_ctx(self);
1084
1085         self->constval.vfunc->ir_func = func;
1086         self->ir_v = func->value;
1087         /* The function is filled later on ast_function_codegen... */
1088         return true;
1089     }
1090
1091     if (isfield && self->expression.vtype == TYPE_FIELD) {
1092         ast_expression *fieldtype = self->expression.next;
1093
1094         if (self->hasvalue) {
1095             asterror(ast_ctx(self), "TODO: constant field pointers with value");
1096             goto error;
1097         }
1098
1099         if (fieldtype->expression.vtype == TYPE_ARRAY) {
1100             size_t ai;
1101             char   *name;
1102             size_t  namelen;
1103
1104             ast_expression_common *elemtype;
1105             int                    vtype;
1106             ast_value             *array = (ast_value*)fieldtype;
1107
1108             if (!ast_istype(fieldtype, ast_value)) {
1109                 asterror(ast_ctx(self), "internal error: ast_value required");
1110                 return false;
1111             }
1112
1113             /* we are lame now - considering the way QC works we won't tolerate arrays > 1024 elements */
1114             if (!array->expression.count || array->expression.count > opts_max_array_size)
1115                 asterror(ast_ctx(self), "Invalid array of size %lu", (unsigned long)array->expression.count);
1116
1117             elemtype = &array->expression.next->expression;
1118             vtype = elemtype->vtype;
1119
1120             v = ir_builder_create_field(ir, self->name, vtype);
1121             if (!v) {
1122                 asterror(ast_ctx(self), "ir_builder_create_global failed");
1123                 return false;
1124             }
1125             if (vtype == TYPE_FIELD)
1126                 v->fieldtype = elemtype->next->expression.vtype;
1127             v->context = ast_ctx(self);
1128             array->ir_v = self->ir_v = v;
1129
1130             namelen = strlen(self->name);
1131             name    = (char*)mem_a(namelen + 16);
1132             strcpy(name, self->name);
1133
1134             array->ir_values = (ir_value**)mem_a(sizeof(array->ir_values[0]) * array->expression.count);
1135             array->ir_values[0] = v;
1136             for (ai = 1; ai < array->expression.count; ++ai) {
1137                 snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
1138                 array->ir_values[ai] = ir_builder_create_field(ir, name, vtype);
1139                 if (!array->ir_values[ai]) {
1140                     mem_d(name);
1141                     asterror(ast_ctx(self), "ir_builder_create_global failed");
1142                     return false;
1143                 }
1144                 if (vtype == TYPE_FIELD)
1145                     array->ir_values[ai]->fieldtype = elemtype->next->expression.vtype;
1146                 array->ir_values[ai]->context = ast_ctx(self);
1147             }
1148             mem_d(name);
1149         }
1150         else
1151         {
1152             v = ir_builder_create_field(ir, self->name, self->expression.next->expression.vtype);
1153             if (!v)
1154                 return false;
1155             v->context = ast_ctx(self);
1156             self->ir_v = v;
1157         }
1158         return true;
1159     }
1160
1161     if (self->expression.vtype == TYPE_ARRAY) {
1162         size_t ai;
1163         char   *name;
1164         size_t  namelen;
1165
1166         ast_expression_common *elemtype = &self->expression.next->expression;
1167         int vtype = elemtype->vtype;
1168
1169         /* same as with field arrays */
1170         if (!self->expression.count || self->expression.count > opts_max_array_size)
1171             asterror(ast_ctx(self), "Invalid array of size %lu", (unsigned long)self->expression.count);
1172
1173         v = ir_builder_create_global(ir, self->name, vtype);
1174         if (!v) {
1175             asterror(ast_ctx(self), "ir_builder_create_global failed");
1176             return false;
1177         }
1178         if (vtype == TYPE_FIELD)
1179             v->fieldtype = elemtype->next->expression.vtype;
1180         v->context = ast_ctx(self);
1181
1182         namelen = strlen(self->name);
1183         name    = (char*)mem_a(namelen + 16);
1184         strcpy(name, self->name);
1185
1186         self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->expression.count);
1187         self->ir_values[0] = v;
1188         for (ai = 1; ai < self->expression.count; ++ai) {
1189             snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
1190             self->ir_values[ai] = ir_builder_create_global(ir, name, vtype);
1191             if (!self->ir_values[ai]) {
1192                 mem_d(name);
1193                 asterror(ast_ctx(self), "ir_builder_create_global failed");
1194                 return false;
1195             }
1196             if (vtype == TYPE_FIELD)
1197                 self->ir_values[ai]->fieldtype = elemtype->next->expression.vtype;
1198             self->ir_values[ai]->context = ast_ctx(self);
1199         }
1200         mem_d(name);
1201     }
1202     else
1203     {
1204         /* Arrays don't do this since there's no "array" value which spans across the
1205          * whole thing.
1206          */
1207         v = ir_builder_create_global(ir, self->name, self->expression.vtype);
1208         if (!v) {
1209             asterror(ast_ctx(self), "ir_builder_create_global failed");
1210             return false;
1211         }
1212         if (self->expression.vtype == TYPE_FIELD)
1213             v->fieldtype = self->expression.next->expression.vtype;
1214         v->context = ast_ctx(self);
1215     }
1216
1217     if (self->hasvalue) {
1218         switch (self->expression.vtype)
1219         {
1220             case TYPE_FLOAT:
1221                 if (!ir_value_set_float(v, self->constval.vfloat))
1222                     goto error;
1223                 break;
1224             case TYPE_VECTOR:
1225                 if (!ir_value_set_vector(v, self->constval.vvec))
1226                     goto error;
1227                 break;
1228             case TYPE_STRING:
1229                 if (!ir_value_set_string(v, self->constval.vstring))
1230                     goto error;
1231                 break;
1232             case TYPE_ARRAY:
1233                 asterror(ast_ctx(self), "TODO: global constant array");
1234                 break;
1235             case TYPE_FUNCTION:
1236                 asterror(ast_ctx(self), "global of type function not properly generated");
1237                 goto error;
1238                 /* Cannot generate an IR value for a function,
1239                  * need a pointer pointing to a function rather.
1240                  */
1241             default:
1242                 asterror(ast_ctx(self), "TODO: global constant type %i", self->expression.vtype);
1243                 break;
1244         }
1245     }
1246
1247     /* link us to the ir_value */
1248     self->ir_v = v;
1249     return true;
1250
1251 error: /* clean up */
1252     ir_value_delete(v);
1253     return false;
1254 }
1255
1256 bool ast_local_codegen(ast_value *self, ir_function *func, bool param)
1257 {
1258     ir_value *v = NULL;
1259     if (self->hasvalue && self->expression.vtype == TYPE_FUNCTION)
1260     {
1261         /* Do we allow local functions? I think not...
1262          * this is NOT a function pointer atm.
1263          */
1264         return false;
1265     }
1266
1267     if (self->expression.vtype == TYPE_ARRAY) {
1268         size_t ai;
1269         char   *name;
1270         size_t  namelen;
1271
1272         ast_expression_common *elemtype = &self->expression.next->expression;
1273         int vtype = elemtype->vtype;
1274
1275         if (param) {
1276             asterror(ast_ctx(self), "array-parameters are not supported");
1277             return false;
1278         }
1279
1280         /* we are lame now - considering the way QC works we won't tolerate arrays > 1024 elements */
1281         if (!self->expression.count || self->expression.count > opts_max_array_size) {
1282             asterror(ast_ctx(self), "Invalid array of size %lu", (unsigned long)self->expression.count);
1283         }
1284
1285         self->ir_values = (ir_value**)mem_a(sizeof(self->ir_values[0]) * self->expression.count);
1286         if (!self->ir_values) {
1287             asterror(ast_ctx(self), "failed to allocate array values");
1288             return false;
1289         }
1290
1291         v = ir_function_create_local(func, self->name, vtype, param);
1292         if (!v) {
1293             asterror(ast_ctx(self), "ir_function_create_local failed");
1294             return false;
1295         }
1296         if (vtype == TYPE_FIELD)
1297             v->fieldtype = elemtype->next->expression.vtype;
1298         v->context = ast_ctx(self);
1299
1300         namelen = strlen(self->name);
1301         name    = (char*)mem_a(namelen + 16);
1302         strcpy(name, self->name);
1303
1304         self->ir_values[0] = v;
1305         for (ai = 1; ai < self->expression.count; ++ai) {
1306             snprintf(name + namelen, 16, "[%u]", (unsigned int)ai);
1307             self->ir_values[ai] = ir_function_create_local(func, name, vtype, param);
1308             if (!self->ir_values[ai]) {
1309                 asterror(ast_ctx(self), "ir_builder_create_global failed");
1310                 return false;
1311             }
1312             if (vtype == TYPE_FIELD)
1313                 self->ir_values[ai]->fieldtype = elemtype->next->expression.vtype;
1314             self->ir_values[ai]->context = ast_ctx(self);
1315         }
1316     }
1317     else
1318     {
1319         v = ir_function_create_local(func, self->name, self->expression.vtype, param);
1320         if (!v)
1321             return false;
1322         if (self->expression.vtype == TYPE_FIELD)
1323             v->fieldtype = self->expression.next->expression.vtype;
1324         v->context = ast_ctx(self);
1325     }
1326
1327     /* A constant local... hmmm...
1328      * I suppose the IR will have to deal with this
1329      */
1330     if (self->hasvalue) {
1331         switch (self->expression.vtype)
1332         {
1333             case TYPE_FLOAT:
1334                 if (!ir_value_set_float(v, self->constval.vfloat))
1335                     goto error;
1336                 break;
1337             case TYPE_VECTOR:
1338                 if (!ir_value_set_vector(v, self->constval.vvec))
1339                     goto error;
1340                 break;
1341             case TYPE_STRING:
1342                 if (!ir_value_set_string(v, self->constval.vstring))
1343                     goto error;
1344                 break;
1345             default:
1346                 asterror(ast_ctx(self), "TODO: global constant type %i", self->expression.vtype);
1347                 break;
1348         }
1349     }
1350
1351     /* link us to the ir_value */
1352     self->ir_v = v;
1353
1354     if (self->setter) {
1355         if (!ast_global_codegen(self->setter, func->owner, false) ||
1356             !ast_function_codegen(self->setter->constval.vfunc, func->owner) ||
1357             !ir_function_finalize(self->setter->constval.vfunc->ir_func))
1358             return false;
1359     }
1360     if (self->getter) {
1361         if (!ast_global_codegen(self->getter, func->owner, false) ||
1362             !ast_function_codegen(self->getter->constval.vfunc, func->owner) ||
1363             !ir_function_finalize(self->getter->constval.vfunc->ir_func))
1364             return false;
1365     }
1366     return true;
1367
1368 error: /* clean up */
1369     ir_value_delete(v);
1370     return false;
1371 }
1372
1373 bool ast_function_codegen(ast_function *self, ir_builder *ir)
1374 {
1375     ir_function *irf;
1376     ir_value    *dummy;
1377     ast_expression_common *ec;
1378     size_t    i;
1379
1380     (void)ir;
1381
1382     irf = self->ir_func;
1383     if (!irf) {
1384         asterror(ast_ctx(self), "ast_function's related ast_value was not generated yet");
1385         return false;
1386     }
1387
1388     /* fill the parameter list */
1389     ec = &self->vtype->expression;
1390     for (i = 0; i < vec_size(ec->params); ++i)
1391     {
1392         vec_push(irf->params, ec->params[i]->expression.vtype);
1393         if (!self->builtin) {
1394             if (!ast_local_codegen(ec->params[i], self->ir_func, true))
1395                 return false;
1396         }
1397     }
1398
1399     if (self->builtin) {
1400         irf->builtin = self->builtin;
1401         return true;
1402     }
1403
1404     if (!vec_size(self->blocks)) {
1405         asterror(ast_ctx(self), "function `%s` has no body", self->name);
1406         return false;
1407     }
1408
1409     self->curblock = ir_function_create_block(irf, "entry");
1410     if (!self->curblock) {
1411         asterror(ast_ctx(self), "failed to allocate entry block for `%s`", self->name);
1412         return false;
1413     }
1414
1415     for (i = 0; i < vec_size(self->blocks); ++i) {
1416         ast_expression_codegen *gen = self->blocks[i]->expression.codegen;
1417         if (!(*gen)((ast_expression*)self->blocks[i], self, false, &dummy))
1418             return false;
1419     }
1420
1421     /* TODO: check return types */
1422     if (!self->curblock->is_return)
1423     {
1424         return ir_block_create_return(self->curblock, NULL);
1425         /* From now on the parser has to handle this situation */
1426 #if 0
1427         if (!self->vtype->expression.next ||
1428             self->vtype->expression.next->expression.vtype == TYPE_VOID)
1429         {
1430             return ir_block_create_return(self->curblock, NULL);
1431         }
1432         else
1433         {
1434             /* error("missing return"); */
1435             asterror(ast_ctx(self), "function `%s` missing return value", self->name);
1436             return false;
1437         }
1438 #endif
1439     }
1440     return true;
1441 }
1442
1443 /* Note, you will not see ast_block_codegen generate ir_blocks.
1444  * To the AST and the IR, blocks are 2 different things.
1445  * In the AST it represents a block of code, usually enclosed in
1446  * curly braces {...}.
1447  * While in the IR it represents a block in terms of control-flow.
1448  */
1449 bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_value **out)
1450 {
1451     size_t i;
1452
1453     /* We don't use this
1454      * Note: an ast-representation using the comma-operator
1455      * of the form: (a, b, c) = x should not assign to c...
1456      */
1457     if (lvalue) {
1458         asterror(ast_ctx(self), "not an l-value (code-block)");
1459         return false;
1460     }
1461
1462     if (self->expression.outr) {
1463         *out = self->expression.outr;
1464         return true;
1465     }
1466
1467     /* output is NULL at first, we'll have each expression
1468      * assign to out output, thus, a comma-operator represention
1469      * using an ast_block will return the last generated value,
1470      * so: (b, c) + a  executed both b and c, and returns c,
1471      * which is then added to a.
1472      */
1473     *out = NULL;
1474
1475     /* generate locals */
1476     for (i = 0; i < vec_size(self->locals); ++i)
1477     {
1478         if (!ast_local_codegen(self->locals[i], func->ir_func, false)) {
1479             if (opts_debug)
1480                 asterror(ast_ctx(self), "failed to generate local `%s`", self->locals[i]->name);
1481             return false;
1482         }
1483     }
1484
1485     for (i = 0; i < vec_size(self->exprs); ++i)
1486     {
1487         ast_expression_codegen *gen = self->exprs[i]->expression.codegen;
1488         if (func->curblock->final) {
1489             asterror(ast_ctx(self->exprs[i]), "unreachable statement");
1490             return false;
1491         }
1492         if (!(*gen)(self->exprs[i], func, false, out))
1493             return false;
1494     }
1495
1496     self->expression.outr = *out;
1497
1498     return true;
1499 }
1500
1501 bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_value **out)
1502 {
1503     ast_expression_codegen *cgen;
1504     ir_value *left  = NULL;
1505     ir_value *right = NULL;
1506
1507     ast_value       *arr;
1508     ast_value       *idx = 0;
1509     ast_array_index *ai = NULL;
1510
1511     if (lvalue && self->expression.outl) {
1512         *out = self->expression.outl;
1513         return true;
1514     }
1515
1516     if (!lvalue && self->expression.outr) {
1517         *out = self->expression.outr;
1518         return true;
1519     }
1520
1521     if (ast_istype(self->dest, ast_array_index))
1522     {
1523
1524         ai = (ast_array_index*)self->dest;
1525         idx = (ast_value*)ai->index;
1526
1527         if (ast_istype(ai->index, ast_value) && idx->hasvalue)
1528             ai = NULL;
1529     }
1530
1531     if (ai) {
1532         /* we need to call the setter */
1533         ir_value  *iridx, *funval;
1534         ir_instr  *call;
1535
1536         if (lvalue) {
1537             asterror(ast_ctx(self), "array-subscript assignment cannot produce lvalues");
1538             return false;
1539         }
1540
1541         arr = (ast_value*)ai->array;
1542         if (!ast_istype(ai->array, ast_value) || !arr->setter) {
1543             asterror(ast_ctx(self), "value has no setter (%s)", arr->name);
1544             return false;
1545         }
1546
1547         cgen = idx->expression.codegen;
1548         if (!(*cgen)((ast_expression*)(idx), func, false, &iridx))
1549             return false;
1550
1551         cgen = arr->setter->expression.codegen;
1552         if (!(*cgen)((ast_expression*)(arr->setter), func, true, &funval))
1553             return false;
1554
1555         cgen = self->source->expression.codegen;
1556         if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
1557             return false;
1558
1559         call = ir_block_create_call(func->curblock, ast_function_label(func, "store"), funval);
1560         if (!call)
1561             return false;
1562         ir_call_param(call, iridx);
1563         ir_call_param(call, right);
1564         self->expression.outr = right;
1565     }
1566     else
1567     {
1568         /* regular code */
1569
1570         cgen = self->dest->expression.codegen;
1571         /* lvalue! */
1572         if (!(*cgen)((ast_expression*)(self->dest), func, true, &left))
1573             return false;
1574         self->expression.outl = left;
1575
1576         cgen = self->source->expression.codegen;
1577         /* rvalue! */
1578         if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
1579             return false;
1580
1581         if (!ir_block_create_store_op(func->curblock, self->op, left, right))
1582             return false;
1583         self->expression.outr = right;
1584     }
1585
1586     /* Theoretically, an assinment returns its left side as an
1587      * lvalue, if we don't need an lvalue though, we return
1588      * the right side as an rvalue, otherwise we have to
1589      * somehow know whether or not we need to dereference the pointer
1590      * on the left side - that is: OP_LOAD if it was an address.
1591      * Also: in original QC we cannot OP_LOADP *anyway*.
1592      */
1593     *out = (lvalue ? left : right);
1594
1595     return true;
1596 }
1597
1598 bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_value **out)
1599 {
1600     ast_expression_codegen *cgen;
1601     ir_value *left, *right;
1602
1603     /* A binary operation cannot yield an l-value */
1604     if (lvalue) {
1605         asterror(ast_ctx(self), "not an l-value (binop)");
1606         return false;
1607     }
1608
1609     if (self->expression.outr) {
1610         *out = self->expression.outr;
1611         return true;
1612     }
1613
1614     if (OPTS_FLAG(SHORT_LOGIC) &&
1615         (self->op == INSTR_AND || self->op == INSTR_OR))
1616     {
1617         /* short circuit evaluation */
1618         ir_block *other, *merge;
1619         ir_block *from_left, *from_right;
1620         ir_instr *phi;
1621         size_t    merge_id;
1622         uint16_t  notop;
1623
1624         /* Note about casting to true boolean values:
1625          * We use a single NOT for sub expressions, and an
1626          * overall NOT at the end, and for that purpose swap
1627          * all the jump conditions in order for the NOT to get
1628          * doubled.
1629          * ie: (a && b) usually becomes (!!a ? !!b : !!a)
1630          * but we translate this to (!(!a ? !a : !b))
1631          */
1632
1633         merge_id = vec_size(func->ir_func->blocks);
1634         merge = ir_function_create_block(func->ir_func, ast_function_label(func, "sce_merge"));
1635
1636         cgen = self->left->expression.codegen;
1637         if (!(*cgen)((ast_expression*)(self->left), func, false, &left))
1638             return false;
1639         if (!OPTS_FLAG(PERL_LOGIC)) {
1640             notop = type_not_instr[left->vtype];
1641             if (notop == AINSTR_END) {
1642                 asterror(ast_ctx(self), "don't know how to cast to bool...");
1643                 return false;
1644             }
1645             left = ir_block_create_unary(func->curblock,
1646                                          ast_function_label(func, "sce_not"),
1647                                          notop,
1648                                          left);
1649         }
1650         from_left = func->curblock;
1651
1652         other = ir_function_create_block(func->ir_func, ast_function_label(func, "sce_other"));
1653         if ( !(self->op == INSTR_OR) != !OPTS_FLAG(PERL_LOGIC) ) {
1654             if (!ir_block_create_if(func->curblock, left, other, merge))
1655                 return false;
1656         } else {
1657             if (!ir_block_create_if(func->curblock, left, merge, other))
1658                 return false;
1659         }
1660         /* use the likely flag */
1661         vec_last(func->curblock->instr)->likely = true;
1662
1663         func->curblock = other;
1664         cgen = self->right->expression.codegen;
1665         if (!(*cgen)((ast_expression*)(self->right), func, false, &right))
1666             return false;
1667         if (!OPTS_FLAG(PERL_LOGIC)) {
1668             notop = type_not_instr[right->vtype];
1669             if (notop == AINSTR_END) {
1670                 asterror(ast_ctx(self), "don't know how to cast to bool...");
1671                 return false;
1672             }
1673             right = ir_block_create_unary(func->curblock,
1674                                           ast_function_label(func, "sce_not"),
1675                                           notop,
1676                                           right);
1677         }
1678         from_right = func->curblock;
1679
1680         if (!ir_block_create_jump(func->curblock, merge))
1681             return false;
1682
1683         vec_remove(func->ir_func->blocks, merge_id, 1);
1684         vec_push(func->ir_func->blocks, merge);
1685
1686         func->curblock = merge;
1687         phi = ir_block_create_phi(func->curblock, ast_function_label(func, "sce_value"), TYPE_FLOAT);
1688         ir_phi_add(phi, from_left, left);
1689         ir_phi_add(phi, from_right, right);
1690         *out = ir_phi_value(phi);
1691         if (!OPTS_FLAG(PERL_LOGIC)) {
1692             notop = type_not_instr[(*out)->vtype];
1693             if (notop == AINSTR_END) {
1694                 asterror(ast_ctx(self), "don't know how to cast to bool...");
1695                 return false;
1696             }
1697             *out = ir_block_create_unary(func->curblock,
1698                                          ast_function_label(func, "sce_final_not"),
1699                                          notop,
1700                                          *out);
1701         }
1702         if (!*out)
1703             return false;
1704         self->expression.outr = *out;
1705         return true;
1706     }
1707
1708     cgen = self->left->expression.codegen;
1709     if (!(*cgen)((ast_expression*)(self->left), func, false, &left))
1710         return false;
1711
1712     cgen = self->right->expression.codegen;
1713     if (!(*cgen)((ast_expression*)(self->right), func, false, &right))
1714         return false;
1715
1716     *out = ir_block_create_binop(func->curblock, ast_function_label(func, "bin"),
1717                                  self->op, left, right);
1718     if (!*out)
1719         return false;
1720     self->expression.outr = *out;
1721
1722     return true;
1723 }
1724
1725 bool ast_binstore_codegen(ast_binstore *self, ast_function *func, bool lvalue, ir_value **out)
1726 {
1727     ast_expression_codegen *cgen;
1728     ir_value *leftl = NULL, *leftr, *right, *bin;
1729
1730     ast_value       *arr;
1731     ast_value       *idx = 0;
1732     ast_array_index *ai = NULL;
1733     ir_value        *iridx = NULL;
1734
1735     if (lvalue && self->expression.outl) {
1736         *out = self->expression.outl;
1737         return true;
1738     }
1739
1740     if (!lvalue && self->expression.outr) {
1741         *out = self->expression.outr;
1742         return true;
1743     }
1744
1745     if (ast_istype(self->dest, ast_array_index))
1746     {
1747
1748         ai = (ast_array_index*)self->dest;
1749         idx = (ast_value*)ai->index;
1750
1751         if (ast_istype(ai->index, ast_value) && idx->hasvalue)
1752             ai = NULL;
1753     }
1754
1755     /* for a binstore we need both an lvalue and an rvalue for the left side */
1756     /* rvalue of destination! */
1757     if (ai) {
1758         cgen = idx->expression.codegen;
1759         if (!(*cgen)((ast_expression*)(idx), func, false, &iridx))
1760             return false;
1761     }
1762     cgen = self->dest->expression.codegen;
1763     if (!(*cgen)((ast_expression*)(self->dest), func, false, &leftr))
1764         return false;
1765
1766     /* source as rvalue only */
1767     cgen = self->source->expression.codegen;
1768     if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
1769         return false;
1770
1771     /* now the binary */
1772     bin = ir_block_create_binop(func->curblock, ast_function_label(func, "binst"),
1773                                 self->opbin, leftr, right);
1774     self->expression.outr = bin;
1775
1776
1777     if (ai) {
1778         /* we need to call the setter */
1779         ir_value  *funval;
1780         ir_instr  *call;
1781
1782         if (lvalue) {
1783             asterror(ast_ctx(self), "array-subscript assignment cannot produce lvalues");
1784             return false;
1785         }
1786
1787         arr = (ast_value*)ai->array;
1788         if (!ast_istype(ai->array, ast_value) || !arr->setter) {
1789             asterror(ast_ctx(self), "value has no setter (%s)", arr->name);
1790             return false;
1791         }
1792
1793         cgen = arr->setter->expression.codegen;
1794         if (!(*cgen)((ast_expression*)(arr->setter), func, true, &funval))
1795             return false;
1796
1797         call = ir_block_create_call(func->curblock, ast_function_label(func, "store"), funval);
1798         if (!call)
1799             return false;
1800         ir_call_param(call, iridx);
1801         ir_call_param(call, bin);
1802         self->expression.outr = bin;
1803     } else {
1804         /* now store them */
1805         cgen = self->dest->expression.codegen;
1806         /* lvalue of destination */
1807         if (!(*cgen)((ast_expression*)(self->dest), func, true, &leftl))
1808             return false;
1809         self->expression.outl = leftl;
1810
1811         if (!ir_block_create_store_op(func->curblock, self->opstore, leftl, bin))
1812             return false;
1813         self->expression.outr = bin;
1814     }
1815
1816     /* Theoretically, an assinment returns its left side as an
1817      * lvalue, if we don't need an lvalue though, we return
1818      * the right side as an rvalue, otherwise we have to
1819      * somehow know whether or not we need to dereference the pointer
1820      * on the left side - that is: OP_LOAD if it was an address.
1821      * Also: in original QC we cannot OP_LOADP *anyway*.
1822      */
1823     *out = (lvalue ? leftl : bin);
1824
1825     return true;
1826 }
1827
1828 bool ast_unary_codegen(ast_unary *self, ast_function *func, bool lvalue, ir_value **out)
1829 {
1830     ast_expression_codegen *cgen;
1831     ir_value *operand;
1832
1833     /* An unary operation cannot yield an l-value */
1834     if (lvalue) {
1835         asterror(ast_ctx(self), "not an l-value (binop)");
1836         return false;
1837     }
1838
1839     if (self->expression.outr) {
1840         *out = self->expression.outr;
1841         return true;
1842     }
1843
1844     cgen = self->operand->expression.codegen;
1845     /* lvalue! */
1846     if (!(*cgen)((ast_expression*)(self->operand), func, false, &operand))
1847         return false;
1848
1849     *out = ir_block_create_unary(func->curblock, ast_function_label(func, "unary"),
1850                                  self->op, operand);
1851     if (!*out)
1852         return false;
1853     self->expression.outr = *out;
1854
1855     return true;
1856 }
1857
1858 bool ast_return_codegen(ast_return *self, ast_function *func, bool lvalue, ir_value **out)
1859 {
1860     ast_expression_codegen *cgen;
1861     ir_value *operand;
1862
1863     *out = NULL;
1864
1865     /* In the context of a return operation, we don't actually return
1866      * anything...
1867      */
1868     if (lvalue) {
1869         asterror(ast_ctx(self), "return-expression is not an l-value");
1870         return false;
1871     }
1872
1873     if (self->expression.outr) {
1874         asterror(ast_ctx(self), "internal error: ast_return cannot be reused, it bears no result!");
1875         return false;
1876     }
1877     self->expression.outr = (ir_value*)1;
1878
1879     if (self->operand) {
1880         cgen = self->operand->expression.codegen;
1881         /* lvalue! */
1882         if (!(*cgen)((ast_expression*)(self->operand), func, false, &operand))
1883             return false;
1884
1885         if (!ir_block_create_return(func->curblock, operand))
1886             return false;
1887     } else {
1888         if (!ir_block_create_return(func->curblock, NULL))
1889             return false;
1890     }
1891
1892     return true;
1893 }
1894
1895 bool ast_entfield_codegen(ast_entfield *self, ast_function *func, bool lvalue, ir_value **out)
1896 {
1897     ast_expression_codegen *cgen;
1898     ir_value *ent, *field;
1899
1900     /* This function needs to take the 'lvalue' flag into account!
1901      * As lvalue we provide a field-pointer, as rvalue we provide the
1902      * value in a temp.
1903      */
1904
1905     if (lvalue && self->expression.outl) {
1906         *out = self->expression.outl;
1907         return true;
1908     }
1909
1910     if (!lvalue && self->expression.outr) {
1911         *out = self->expression.outr;
1912         return true;
1913     }
1914
1915     cgen = self->entity->expression.codegen;
1916     if (!(*cgen)((ast_expression*)(self->entity), func, false, &ent))
1917         return false;
1918
1919     cgen = self->field->expression.codegen;
1920     if (!(*cgen)((ast_expression*)(self->field), func, false, &field))
1921         return false;
1922
1923     if (lvalue) {
1924         /* address! */
1925         *out = ir_block_create_fieldaddress(func->curblock, ast_function_label(func, "efa"),
1926                                             ent, field);
1927     } else {
1928         *out = ir_block_create_load_from_ent(func->curblock, ast_function_label(func, "efv"),
1929                                              ent, field, self->expression.vtype);
1930     }
1931     if (!*out) {
1932         asterror(ast_ctx(self), "failed to create %s instruction (output type %s)",
1933                  (lvalue ? "ADDRESS" : "FIELD"),
1934                  type_name[self->expression.vtype]);
1935         return false;
1936     }
1937
1938     if (lvalue)
1939         self->expression.outl = *out;
1940     else
1941         self->expression.outr = *out;
1942
1943     /* Hm that should be it... */
1944     return true;
1945 }
1946
1947 bool ast_member_codegen(ast_member *self, ast_function *func, bool lvalue, ir_value **out)
1948 {
1949     ast_expression_codegen *cgen;
1950     ir_value *vec;
1951
1952     /* in QC this is always an lvalue */
1953     (void)lvalue;
1954     if (self->expression.outl) {
1955         *out = self->expression.outl;
1956         return true;
1957     }
1958
1959     cgen = self->owner->expression.codegen;
1960     if (!(*cgen)((ast_expression*)(self->owner), func, true, &vec))
1961         return false;
1962
1963     if (vec->vtype != TYPE_VECTOR &&
1964         !(vec->vtype == TYPE_FIELD && self->owner->expression.next->expression.vtype == TYPE_VECTOR))
1965     {
1966         return false;
1967     }
1968
1969     *out = ir_value_vector_member(vec, self->field);
1970     self->expression.outl = *out;
1971
1972     return (*out != NULL);
1973 }
1974
1975 bool ast_array_index_codegen(ast_array_index *self, ast_function *func, bool lvalue, ir_value **out)
1976 {
1977     ast_value *arr;
1978     ast_value *idx;
1979
1980     if (!lvalue && self->expression.outr) {
1981         *out = self->expression.outr;
1982     }
1983     if (lvalue && self->expression.outl) {
1984         *out = self->expression.outl;
1985     }
1986
1987     if (!ast_istype(self->array, ast_value)) {
1988         asterror(ast_ctx(self), "array indexing this way is not supported");
1989         /* note this would actually be pointer indexing because the left side is
1990          * not an actual array but (hopefully) an indexable expression.
1991          * Once we get integer arithmetic, and GADDRESS/GSTORE/GLOAD instruction
1992          * support this path will be filled.
1993          */
1994         return false;
1995     }
1996
1997     arr = (ast_value*)self->array;
1998     idx = (ast_value*)self->index;
1999
2000     if (!ast_istype(self->index, ast_value) || !idx->hasvalue) {
2001         /* Time to use accessor functions */
2002         ast_expression_codegen *cgen;
2003         ir_value               *iridx, *funval;
2004         ir_instr               *call;
2005
2006         if (lvalue) {
2007             asterror(ast_ctx(self), "(.2) array indexing here needs a compile-time constant");
2008             return false;
2009         }
2010
2011         if (!arr->getter) {
2012             asterror(ast_ctx(self), "value has no getter, don't know how to index it");
2013             return false;
2014         }
2015
2016         cgen = self->index->expression.codegen;
2017         if (!(*cgen)((ast_expression*)(self->index), func, true, &iridx))
2018             return false;
2019
2020         cgen = arr->getter->expression.codegen;
2021         if (!(*cgen)((ast_expression*)(arr->getter), func, true, &funval))
2022             return false;
2023
2024         call = ir_block_create_call(func->curblock, ast_function_label(func, "fetch"), funval);
2025         if (!call)
2026             return false;
2027         ir_call_param(call, iridx);
2028
2029         *out = ir_call_value(call);
2030         self->expression.outr = *out;
2031         return true;
2032     }
2033
2034     if (idx->expression.vtype == TYPE_FLOAT)
2035         *out = arr->ir_values[(int)idx->constval.vfloat];
2036     else if (idx->expression.vtype == TYPE_INTEGER)
2037         *out = arr->ir_values[idx->constval.vint];
2038     else {
2039         asterror(ast_ctx(self), "array indexing here needs an integer constant");
2040         return false;
2041     }
2042     return true;
2043 }
2044
2045 bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_value **out)
2046 {
2047     ast_expression_codegen *cgen;
2048
2049     ir_value *condval;
2050     ir_value *dummy;
2051
2052     ir_block *cond = func->curblock;
2053     ir_block *ontrue;
2054     ir_block *onfalse;
2055     ir_block *ontrue_endblock = NULL;
2056     ir_block *onfalse_endblock = NULL;
2057     ir_block *merge;
2058
2059     /* We don't output any value, thus also don't care about r/lvalue */
2060     (void)out;
2061     (void)lvalue;
2062
2063     if (self->expression.outr) {
2064         asterror(ast_ctx(self), "internal error: ast_ifthen cannot be reused, it bears no result!");
2065         return false;
2066     }
2067     self->expression.outr = (ir_value*)1;
2068
2069     /* generate the condition */
2070     cgen = self->cond->expression.codegen;
2071     if (!(*cgen)((ast_expression*)(self->cond), func, false, &condval))
2072         return false;
2073     /* update the block which will get the jump - because short-logic or ternaries may have changed this */
2074     cond = func->curblock;
2075
2076     /* on-true path */
2077
2078     if (self->on_true) {
2079         /* create on-true block */
2080         ontrue = ir_function_create_block(func->ir_func, ast_function_label(func, "ontrue"));
2081         if (!ontrue)
2082             return false;
2083
2084         /* enter the block */
2085         func->curblock = ontrue;
2086
2087         /* generate */
2088         cgen = self->on_true->expression.codegen;
2089         if (!(*cgen)((ast_expression*)(self->on_true), func, false, &dummy))
2090             return false;
2091
2092         /* we now need to work from the current endpoint */
2093         ontrue_endblock = func->curblock;
2094     } else
2095         ontrue = NULL;
2096
2097     /* on-false path */
2098     if (self->on_false) {
2099         /* create on-false block */
2100         onfalse = ir_function_create_block(func->ir_func, ast_function_label(func, "onfalse"));
2101         if (!onfalse)
2102             return false;
2103
2104         /* enter the block */
2105         func->curblock = onfalse;
2106
2107         /* generate */
2108         cgen = self->on_false->expression.codegen;
2109         if (!(*cgen)((ast_expression*)(self->on_false), func, false, &dummy))
2110             return false;
2111
2112         /* we now need to work from the current endpoint */
2113         onfalse_endblock = func->curblock;
2114     } else
2115         onfalse = NULL;
2116
2117     /* Merge block were they all merge in to */
2118     merge = ir_function_create_block(func->ir_func, ast_function_label(func, "endif"));
2119     if (!merge)
2120         return false;
2121     /* add jumps ot the merge block */
2122     if (ontrue && !ontrue_endblock->final && !ir_block_create_jump(ontrue_endblock, merge))
2123         return false;
2124     if (onfalse && !onfalse_endblock->final && !ir_block_create_jump(onfalse_endblock, merge))
2125         return false;
2126
2127     /* we create the if here, that way all blocks are ordered :)
2128      */
2129     if (!ir_block_create_if(cond, condval,
2130                             (ontrue  ? ontrue  : merge),
2131                             (onfalse ? onfalse : merge)))
2132     {
2133         return false;
2134     }
2135
2136     /* Now enter the merge block */
2137     func->curblock = merge;
2138
2139     return true;
2140 }
2141
2142 bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_value **out)
2143 {
2144     ast_expression_codegen *cgen;
2145
2146     ir_value *condval;
2147     ir_value *trueval, *falseval;
2148     ir_instr *phi;
2149
2150     ir_block *cond = func->curblock;
2151     ir_block *ontrue;
2152     ir_block *onfalse;
2153     ir_block *merge;
2154
2155     /* Ternary can never create an lvalue... */
2156     if (lvalue)
2157         return false;
2158
2159     /* In theory it shouldn't be possible to pass through a node twice, but
2160      * in case we add any kind of optimization pass for the AST itself, it
2161      * may still happen, thus we remember a created ir_value and simply return one
2162      * if it already exists.
2163      */
2164     if (self->expression.outr) {
2165         *out = self->expression.outr;
2166         return true;
2167     }
2168
2169     /* In the following, contraty to ast_ifthen, we assume both paths exist. */
2170
2171     /* generate the condition */
2172     func->curblock = cond;
2173     cgen = self->cond->expression.codegen;
2174     if (!(*cgen)((ast_expression*)(self->cond), func, false, &condval))
2175         return false;
2176
2177     /* create on-true block */
2178     ontrue = ir_function_create_block(func->ir_func, ast_function_label(func, "tern_T"));
2179     if (!ontrue)
2180         return false;
2181     else
2182     {
2183         /* enter the block */
2184         func->curblock = ontrue;
2185
2186         /* generate */
2187         cgen = self->on_true->expression.codegen;
2188         if (!(*cgen)((ast_expression*)(self->on_true), func, false, &trueval))
2189             return false;
2190     }
2191
2192     /* create on-false block */
2193     onfalse = ir_function_create_block(func->ir_func, ast_function_label(func, "tern_F"));
2194     if (!onfalse)
2195         return false;
2196     else
2197     {
2198         /* enter the block */
2199         func->curblock = onfalse;
2200
2201         /* generate */
2202         cgen = self->on_false->expression.codegen;
2203         if (!(*cgen)((ast_expression*)(self->on_false), func, false, &falseval))
2204             return false;
2205     }
2206
2207     /* create merge block */
2208     merge = ir_function_create_block(func->ir_func, ast_function_label(func, "tern_out"));
2209     if (!merge)
2210         return false;
2211     /* jump to merge block */
2212     if (!ir_block_create_jump(ontrue, merge))
2213         return false;
2214     if (!ir_block_create_jump(onfalse, merge))
2215         return false;
2216
2217     /* create if instruction */
2218     if (!ir_block_create_if(cond, condval, ontrue, onfalse))
2219         return false;
2220
2221     /* Now enter the merge block */
2222     func->curblock = merge;
2223
2224     /* Here, now, we need a PHI node
2225      * but first some sanity checking...
2226      */
2227     if (trueval->vtype != falseval->vtype) {
2228         /* error("ternary with different types on the two sides"); */
2229         return false;
2230     }
2231
2232     /* create PHI */
2233     phi = ir_block_create_phi(merge, ast_function_label(func, "phi"), trueval->vtype);
2234     if (!phi)
2235         return false;
2236     ir_phi_add(phi, ontrue,  trueval);
2237     ir_phi_add(phi, onfalse, falseval);
2238
2239     self->expression.outr = ir_phi_value(phi);
2240     *out = self->expression.outr;
2241
2242     return true;
2243 }
2244
2245 bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value **out)
2246 {
2247     ast_expression_codegen *cgen;
2248
2249     ir_value *dummy      = NULL;
2250     ir_value *precond    = NULL;
2251     ir_value *postcond   = NULL;
2252
2253     /* Since we insert some jumps "late" so we have blocks
2254      * ordered "nicely", we need to keep track of the actual end-blocks
2255      * of expressions to add the jumps to.
2256      */
2257     ir_block *bbody      = NULL, *end_bbody      = NULL;
2258     ir_block *bprecond   = NULL, *end_bprecond   = NULL;
2259     ir_block *bpostcond  = NULL, *end_bpostcond  = NULL;
2260     ir_block *bincrement = NULL, *end_bincrement = NULL;
2261     ir_block *bout       = NULL, *bin            = NULL;
2262
2263     /* let's at least move the outgoing block to the end */
2264     size_t    bout_id;
2265
2266     /* 'break' and 'continue' need to be able to find the right blocks */
2267     ir_block *bcontinue     = NULL;
2268     ir_block *bbreak        = NULL;
2269
2270     ir_block *old_bcontinue = NULL;
2271     ir_block *old_bbreak    = NULL;
2272
2273     ir_block *tmpblock      = NULL;
2274
2275     (void)lvalue;
2276     (void)out;
2277
2278     if (self->expression.outr) {
2279         asterror(ast_ctx(self), "internal error: ast_loop cannot be reused, it bears no result!");
2280         return false;
2281     }
2282     self->expression.outr = (ir_value*)1;
2283
2284     /* NOTE:
2285      * Should we ever need some kind of block ordering, better make this function
2286      * move blocks around than write a block ordering algorithm later... after all
2287      * the ast and ir should work together, not against each other.
2288      */
2289
2290     /* initexpr doesn't get its own block, it's pointless, it could create more blocks
2291      * anyway if for example it contains a ternary.
2292      */
2293     if (self->initexpr)
2294     {
2295         cgen = self->initexpr->expression.codegen;
2296         if (!(*cgen)((ast_expression*)(self->initexpr), func, false, &dummy))
2297             return false;
2298     }
2299
2300     /* Store the block from which we enter this chaos */
2301     bin = func->curblock;
2302
2303     /* The pre-loop condition needs its own block since we
2304      * need to be able to jump to the start of that expression.
2305      */
2306     if (self->precond)
2307     {
2308         bprecond = ir_function_create_block(func->ir_func, ast_function_label(func, "pre_loop_cond"));
2309         if (!bprecond)
2310             return false;
2311
2312         /* the pre-loop-condition the least important place to 'continue' at */
2313         bcontinue = bprecond;
2314
2315         /* enter */
2316         func->curblock = bprecond;
2317
2318         /* generate */
2319         cgen = self->precond->expression.codegen;
2320         if (!(*cgen)((ast_expression*)(self->precond), func, false, &precond))
2321             return false;
2322
2323         end_bprecond = func->curblock;
2324     } else {
2325         bprecond = end_bprecond = NULL;
2326     }
2327
2328     /* Now the next blocks won't be ordered nicely, but we need to
2329      * generate them this early for 'break' and 'continue'.
2330      */
2331     if (self->increment) {
2332         bincrement = ir_function_create_block(func->ir_func, ast_function_label(func, "loop_increment"));
2333         if (!bincrement)
2334             return false;
2335         bcontinue = bincrement; /* increment comes before the pre-loop-condition */
2336     } else {
2337         bincrement = end_bincrement = NULL;
2338     }
2339
2340     if (self->postcond) {
2341         bpostcond = ir_function_create_block(func->ir_func, ast_function_label(func, "post_loop_cond"));
2342         if (!bpostcond)
2343             return false;
2344         bcontinue = bpostcond; /* postcond comes before the increment */
2345     } else {
2346         bpostcond = end_bpostcond = NULL;
2347     }
2348
2349     bout_id = vec_size(func->ir_func->blocks);
2350     bout = ir_function_create_block(func->ir_func, ast_function_label(func, "after_loop"));
2351     if (!bout)
2352         return false;
2353     bbreak = bout;
2354
2355     /* The loop body... */
2356     if (self->body)
2357     {
2358         bbody = ir_function_create_block(func->ir_func, ast_function_label(func, "loop_body"));
2359         if (!bbody)
2360             return false;
2361
2362         /* enter */
2363         func->curblock = bbody;
2364
2365         old_bbreak          = func->breakblock;
2366         old_bcontinue       = func->continueblock;
2367         func->breakblock    = bbreak;
2368         func->continueblock = bcontinue;
2369
2370         /* generate */
2371         cgen = self->body->expression.codegen;
2372         if (!(*cgen)((ast_expression*)(self->body), func, false, &dummy))
2373             return false;
2374
2375         end_bbody = func->curblock;
2376         func->breakblock    = old_bbreak;
2377         func->continueblock = old_bcontinue;
2378     }
2379
2380     /* post-loop-condition */
2381     if (self->postcond)
2382     {
2383         /* enter */
2384         func->curblock = bpostcond;
2385
2386         /* generate */
2387         cgen = self->postcond->expression.codegen;
2388         if (!(*cgen)((ast_expression*)(self->postcond), func, false, &postcond))
2389             return false;
2390
2391         end_bpostcond = func->curblock;
2392     }
2393
2394     /* The incrementor */
2395     if (self->increment)
2396     {
2397         /* enter */
2398         func->curblock = bincrement;
2399
2400         /* generate */
2401         cgen = self->increment->expression.codegen;
2402         if (!(*cgen)((ast_expression*)(self->increment), func, false, &dummy))
2403             return false;
2404
2405         end_bincrement = func->curblock;
2406     }
2407
2408     /* In any case now, we continue from the outgoing block */
2409     func->curblock = bout;
2410
2411     /* Now all blocks are in place */
2412     /* From 'bin' we jump to whatever comes first */
2413     if      (bprecond)   tmpblock = bprecond;
2414     else if (bbody)      tmpblock = bbody;
2415     else if (bpostcond)  tmpblock = bpostcond;
2416     else                 tmpblock = bout;
2417     if (!ir_block_create_jump(bin, tmpblock))
2418         return false;
2419
2420     /* From precond */
2421     if (bprecond)
2422     {
2423         ir_block *ontrue, *onfalse;
2424         if      (bbody)      ontrue = bbody;
2425         else if (bincrement) ontrue = bincrement;
2426         else if (bpostcond)  ontrue = bpostcond;
2427         else                 ontrue = bprecond;
2428         onfalse = bout;
2429         if (!ir_block_create_if(end_bprecond, precond, ontrue, onfalse))
2430             return false;
2431     }
2432
2433     /* from body */
2434     if (bbody)
2435     {
2436         if      (bincrement) tmpblock = bincrement;
2437         else if (bpostcond)  tmpblock = bpostcond;
2438         else if (bprecond)   tmpblock = bprecond;
2439         else                 tmpblock = bout;
2440         if (!end_bbody->final && !ir_block_create_jump(end_bbody, tmpblock))
2441             return false;
2442     }
2443
2444     /* from increment */
2445     if (bincrement)
2446     {
2447         if      (bpostcond)  tmpblock = bpostcond;
2448         else if (bprecond)   tmpblock = bprecond;
2449         else if (bbody)      tmpblock = bbody;
2450         else                 tmpblock = bout;
2451         if (!ir_block_create_jump(end_bincrement, tmpblock))
2452             return false;
2453     }
2454
2455     /* from postcond */
2456     if (bpostcond)
2457     {
2458         ir_block *ontrue, *onfalse;
2459         if      (bprecond)   ontrue = bprecond;
2460         else if (bbody)      ontrue = bbody;
2461         else if (bincrement) ontrue = bincrement;
2462         else                 ontrue = bpostcond;
2463         onfalse = bout;
2464         if (!ir_block_create_if(end_bpostcond, postcond, ontrue, onfalse))
2465             return false;
2466     }
2467
2468     /* Move 'bout' to the end */
2469     vec_remove(func->ir_func->blocks, bout_id, 1);
2470     vec_push(func->ir_func->blocks, bout);
2471
2472     return true;
2473 }
2474
2475 bool ast_breakcont_codegen(ast_breakcont *self, ast_function *func, bool lvalue, ir_value **out)
2476 {
2477     ir_block *target;
2478
2479     *out = NULL;
2480
2481     if (lvalue) {
2482         asterror(ast_ctx(self), "break/continue expression is not an l-value");
2483         return false;
2484     }
2485
2486     if (self->expression.outr) {
2487         asterror(ast_ctx(self), "internal error: ast_breakcont cannot be reused!");
2488         return false;
2489     }
2490     self->expression.outr = (ir_value*)1;
2491
2492     if (self->is_continue)
2493         target = func->continueblock;
2494     else
2495         target = func->breakblock;
2496
2497     if (!ir_block_create_jump(func->curblock, target))
2498         return false;
2499     return true;
2500 }
2501
2502 bool ast_switch_codegen(ast_switch *self, ast_function *func, bool lvalue, ir_value **out)
2503 {
2504     ast_expression_codegen *cgen;
2505
2506     ast_switch_case *def_case  = NULL;
2507     ir_block        *def_bfall = NULL;
2508
2509     ir_value *dummy     = NULL;
2510     ir_value *irop      = NULL;
2511     ir_block *old_break = NULL;
2512     ir_block *bout      = NULL;
2513     ir_block *bfall     = NULL;
2514     size_t    bout_id;
2515     size_t    c;
2516
2517     char      typestr[1024];
2518     uint16_t  cmpinstr;
2519
2520     if (lvalue) {
2521         asterror(ast_ctx(self), "switch expression is not an l-value");
2522         return false;
2523     }
2524
2525     if (self->expression.outr) {
2526         asterror(ast_ctx(self), "internal error: ast_switch cannot be reused!");
2527         return false;
2528     }
2529     self->expression.outr = (ir_value*)1;
2530
2531     (void)lvalue;
2532     (void)out;
2533
2534     cgen = self->operand->expression.codegen;
2535     if (!(*cgen)((ast_expression*)(self->operand), func, false, &irop))
2536         return false;
2537
2538     if (!vec_size(self->cases))
2539         return true;
2540
2541     cmpinstr = type_eq_instr[irop->vtype];
2542     if (cmpinstr >= AINSTR_END) {
2543         ast_type_to_string(self->operand, typestr, sizeof(typestr));
2544         asterror(ast_ctx(self), "invalid type to perform a switch on: %s", typestr);
2545         return false;
2546     }
2547
2548     bout_id = vec_size(func->ir_func->blocks);
2549     bout = ir_function_create_block(func->ir_func, ast_function_label(func, "after_switch"));
2550     if (!bout)
2551         return false;
2552
2553     /* setup the break block */
2554     old_break        = func->breakblock;
2555     func->breakblock = bout;
2556
2557     /* Now create all cases */
2558     for (c = 0; c < vec_size(self->cases); ++c) {
2559         ir_value *cond, *val;
2560         ir_block *bcase, *bnot;
2561         size_t bnot_id;
2562
2563         ast_switch_case *swcase = &self->cases[c];
2564
2565         if (swcase->value) {
2566             /* A regular case */
2567             /* generate the condition operand */
2568             cgen = swcase->value->expression.codegen;
2569             if (!(*cgen)((ast_expression*)(swcase->value), func, false, &val))
2570                 return false;
2571             /* generate the condition */
2572             cond = ir_block_create_binop(func->curblock, ast_function_label(func, "switch_eq"), cmpinstr, irop, val);
2573             if (!cond)
2574                 return false;
2575
2576             bcase = ir_function_create_block(func->ir_func, ast_function_label(func, "case"));
2577             bnot_id = vec_size(func->ir_func->blocks);
2578             bnot = ir_function_create_block(func->ir_func, ast_function_label(func, "not_case"));
2579             if (!bcase || !bnot)
2580                 return false;
2581             if (!ir_block_create_if(func->curblock, cond, bcase, bnot))
2582                 return false;
2583
2584             /* Make the previous case-end fall through */
2585             if (bfall && !bfall->final) {
2586                 if (!ir_block_create_jump(bfall, bcase))
2587                     return false;
2588             }
2589
2590             /* enter the case */
2591             func->curblock = bcase;
2592             cgen = swcase->code->expression.codegen;
2593             if (!(*cgen)((ast_expression*)swcase->code, func, false, &dummy))
2594                 return false;
2595
2596             /* remember this block to fall through from */
2597             bfall = func->curblock;
2598
2599             /* enter the else and move it down */
2600             func->curblock = bnot;
2601             vec_remove(func->ir_func->blocks, bnot_id, 1);
2602             vec_push(func->ir_func->blocks, bnot);
2603         } else {
2604             /* The default case */
2605             /* Remember where to fall through from: */
2606             def_bfall = bfall;
2607             bfall     = NULL;
2608             /* remember which case it was */
2609             def_case  = swcase;
2610         }
2611     }
2612
2613     /* Jump from the last bnot to bout */
2614     if (bfall && !bfall->final && !ir_block_create_jump(bfall, bout)) {
2615         /*
2616         astwarning(ast_ctx(bfall), WARN_???, "missing break after last case");
2617         */
2618         return false;
2619     }
2620
2621     /* If there was a default case, put it down here */
2622     if (def_case) {
2623         ir_block *bcase;
2624
2625         /* No need to create an extra block */
2626         bcase = func->curblock;
2627
2628         /* Insert the fallthrough jump */
2629         if (def_bfall && !def_bfall->final) {
2630             if (!ir_block_create_jump(def_bfall, bcase))
2631                 return false;
2632         }
2633
2634         /* Now generate the default code */
2635         cgen = def_case->code->expression.codegen;
2636         if (!(*cgen)((ast_expression*)def_case->code, func, false, &dummy))
2637             return false;
2638     }
2639
2640     /* Jump from the last bnot to bout */
2641     if (!func->curblock->final && !ir_block_create_jump(func->curblock, bout))
2642         return false;
2643     /* enter the outgoing block */
2644     func->curblock = bout;
2645
2646     /* restore the break block */
2647     func->breakblock = old_break;
2648
2649     /* Move 'bout' to the end, it's nicer */
2650     vec_remove(func->ir_func->blocks, bout_id, 1);
2651     vec_push(func->ir_func->blocks, bout);
2652
2653     return true;
2654 }
2655
2656 bool ast_label_codegen(ast_label *self, ast_function *func, bool lvalue, ir_value **out)
2657 {
2658     *out = NULL;
2659     if (lvalue) {
2660         asterror(ast_ctx(self), "internal error: ast_label cannot be an lvalue");
2661         return false;
2662     }
2663
2664     /* simply create a new block and jump to it */
2665     self->irblock = ir_function_create_block(func->ir_func, self->name);
2666     if (!self->irblock) {
2667         asterror(ast_ctx(self), "failed to allocate label block `%s`", self->name);
2668         return false;
2669     }
2670     if (!func->curblock->final) {
2671         if (!ir_block_create_jump(func->curblock, self->irblock))
2672             return false;
2673     }
2674
2675     /* enter the new block */
2676     func->curblock = self->irblock;
2677     return true;
2678 }
2679
2680 bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value **out)
2681 {
2682     ast_expression_codegen *cgen;
2683     ir_value              **params;
2684     ir_instr               *callinstr;
2685     size_t i;
2686
2687     ir_value *funval = NULL;
2688
2689     /* return values are never lvalues */
2690     if (lvalue) {
2691         asterror(ast_ctx(self), "not an l-value (function call)");
2692         return false;
2693     }
2694
2695     if (self->expression.outr) {
2696         *out = self->expression.outr;
2697         return true;
2698     }
2699
2700     cgen = self->func->expression.codegen;
2701     if (!(*cgen)((ast_expression*)(self->func), func, false, &funval))
2702         return false;
2703     if (!funval)
2704         return false;
2705
2706     params = NULL;
2707
2708     /* parameters */
2709     for (i = 0; i < vec_size(self->params); ++i)
2710     {
2711         ir_value *param;
2712         ast_expression *expr = self->params[i];
2713
2714         cgen = expr->expression.codegen;
2715         if (!(*cgen)(expr, func, false, &param))
2716             goto error;
2717         if (!param)
2718             goto error;
2719         vec_push(params, param);
2720     }
2721
2722     callinstr = ir_block_create_call(func->curblock, ast_function_label(func, "call"), funval);
2723     if (!callinstr)
2724         goto error;
2725
2726     for (i = 0; i < vec_size(params); ++i) {
2727         ir_call_param(callinstr, params[i]);
2728     }
2729
2730     *out = ir_call_value(callinstr);
2731     self->expression.outr = *out;
2732
2733     vec_free(params);
2734     return true;
2735 error:
2736     vec_free(params);
2737     return false;
2738 }