]> git.xonotic.org Git - xonotic/gmqcc.git/blob - ast.c
ast_return
[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);                            \
36     ( (ast_node*)self )->node.destroy = (ast_node_delete*)destroyfn
37
38 /* It must not be possible to get here. */
39 static GMQCC_NORETURN void _ast_node_destroy(ast_node *self)
40 {
41     fprintf(stderr, "ast node missing destroy()\n");
42     abort();
43 }
44
45 /* Initialize main ast node aprts */
46 static void ast_node_init(ast_node *self, lex_ctx ctx)
47 {
48     self->node.context = ctx;
49     self->node.destroy = &_ast_node_destroy;
50     self->node.keep    = false;
51 }
52
53 /* General expression initialization */
54 static void ast_expression_init(ast_expression *self,
55                                 ast_expression_codegen *codegen)
56 {
57     self->expression.codegen = codegen;
58     self->expression.vtype   = TYPE_VOID;
59     self->expression.next    = NULL;
60 }
61
62 static void ast_expression_delete(ast_expression *self)
63 {
64     if (self->expression.next)
65         ast_delete(self->expression.next);
66 }
67
68 static void ast_expression_delete_full(ast_expression *self)
69 {
70     ast_expression_delete(self);
71     mem_d(self);
72 }
73
74 static ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex)
75 {
76     const ast_expression_common *cpex;
77     ast_expression_common *selfex;
78
79     if (!ex)
80         return NULL;
81     else
82     {
83         ast_instantiate(ast_expression, ctx, ast_expression_delete_full);
84
85         cpex   = &ex->expression;
86         selfex = &self->expression;
87
88         selfex->vtype = cpex->vtype;
89         if (cpex->next)
90         {
91             selfex->next = ast_type_copy(ctx, cpex->next);
92             if (!selfex->next) {
93                 mem_d(self);
94                 return NULL;
95             }
96         }
97         else
98             selfex->next = NULL;
99
100         /* This may never be codegen()d */
101         selfex->codegen = NULL;
102         return self;
103     }
104 }
105
106 ast_value* ast_value_new(lex_ctx ctx, const char *name, int t)
107 {
108     ast_instantiate(ast_value, ctx, ast_value_delete);
109     ast_expression_init((ast_expression*)self,
110                         (ast_expression_codegen*)&ast_value_codegen);
111     self->expression.node.keep = true; /* keep */
112
113     self->name = name ? util_strdup(name) : NULL;
114     self->expression.vtype = t;
115     self->expression.next  = NULL;
116     MEM_VECTOR_INIT(self, params);
117     self->isconst = false;
118     memset(&self->constval, 0, sizeof(self->constval));
119
120     self->ir_v    = NULL;
121
122     return self;
123 }
124 MEM_VEC_FUNCTIONS(ast_value, ast_value*, params)
125
126 void ast_value_delete(ast_value* self)
127 {
128     size_t i;
129     if (self->name)
130         mem_d((void*)self->name);
131     for (i = 0; i < self->params_count; ++i)
132         ast_value_delete(self->params[i]); /* delete, the ast_function is expected to die first */
133     MEM_VECTOR_CLEAR(self, params);
134     if (self->isconst) {
135         switch (self->expression.vtype)
136         {
137         case TYPE_STRING:
138             mem_d((void*)self->constval.vstring);
139             break;
140         case TYPE_FUNCTION:
141             /* unlink us from the function node */
142             self->constval.vfunc->vtype = NULL;
143             break;
144         /* NOTE: delete function? currently collected in
145          * the parser structure
146          */
147         default:
148             break;
149         }
150     }
151     ast_expression_delete((ast_expression*)self);
152     mem_d(self);
153 }
154
155 bool ast_value_set_name(ast_value *self, const char *name)
156 {
157     if (self->name)
158         mem_d((void*)self->name);
159     self->name = util_strdup(name);
160     return !!self->name;
161 }
162
163 ast_binary* ast_binary_new(lex_ctx ctx, int op,
164                            ast_expression* left, ast_expression* right)
165 {
166     ast_instantiate(ast_binary, ctx, ast_binary_delete);
167     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_binary_codegen);
168
169     self->op = op;
170     self->left = left;
171     self->right = right;
172
173     return self;
174 }
175
176 void ast_binary_delete(ast_binary *self)
177 {
178     ast_unref(self->left);
179     ast_unref(self->right);
180     ast_expression_delete((ast_expression*)self);
181     mem_d(self);
182 }
183
184 ast_unary* ast_unary_new(lex_ctx ctx, int op,
185                          ast_expression *expr)
186 {
187     ast_instantiate(ast_unary, ctx, ast_unary_delete);
188     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_unary_codegen);
189
190     self->op = op;
191     self->operand = expr;
192
193     return self;
194 }
195
196 void ast_unary_delete(ast_unary *self)
197 {
198     ast_unref(self->operand);
199     ast_expression_delete((ast_expression*)self);
200     mem_d(self);
201 }
202
203 ast_return* ast_return_new(lex_ctx ctx, int op,
204                          ast_expression *expr)
205 {
206     ast_instantiate(ast_return, ctx, ast_return_delete);
207     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_return_codegen);
208
209     self->operand = expr;
210
211     return self;
212 }
213
214 void ast_return_delete(ast_return *self)
215 {
216     ast_unref(self->operand);
217     ast_expression_delete((ast_expression*)self);
218     mem_d(self);
219 }
220
221 ast_entfield* ast_entfield_new(lex_ctx ctx, ast_expression *entity, ast_expression *field)
222 {
223     const ast_expression *outtype;
224
225     ast_instantiate(ast_entfield, ctx, ast_entfield_delete);
226
227     if (field->expression.vtype != TYPE_FIELD) {
228         mem_d(self);
229         return NULL;
230     }
231
232     outtype = field->expression.next;
233     if (!outtype) {
234         mem_d(self);
235         /* Error: field has no type... */
236         return NULL;
237     }
238
239     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_entfield_codegen);
240
241     self->expression.vtype = outtype->expression.vtype;
242     self->expression.next  = ast_type_copy(ctx, outtype->expression.next);
243
244     self->entity = entity;
245     self->field  = field;
246
247     return self;
248 }
249
250 void ast_entfield_delete(ast_entfield *self)
251 {
252     ast_unref(self->entity);
253     ast_unref(self->field);
254     ast_expression_delete((ast_expression*)self);
255     mem_d(self);
256 }
257
258 ast_ifthen* ast_ifthen_new(lex_ctx ctx, ast_expression *cond, ast_expression *ontrue, ast_expression *onfalse)
259 {
260     ast_instantiate(ast_ifthen, ctx, ast_ifthen_delete);
261     if (!ontrue && !onfalse) {
262         /* because it is invalid */
263         mem_d(self);
264         return NULL;
265     }
266     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_ifthen_codegen);
267
268     self->cond     = cond;
269     self->on_true  = ontrue;
270     self->on_false = onfalse;
271
272     return self;
273 }
274
275 void ast_ifthen_delete(ast_ifthen *self)
276 {
277     ast_unref(self->cond);
278     if (self->on_true)
279         ast_unref(self->on_true);
280     if (self->on_false)
281         ast_unref(self->on_false);
282     ast_expression_delete((ast_expression*)self);
283     mem_d(self);
284 }
285
286 ast_ternary* ast_ternary_new(lex_ctx ctx, ast_expression *cond, ast_expression *ontrue, ast_expression *onfalse)
287 {
288     ast_instantiate(ast_ternary, ctx, ast_ternary_delete);
289     /* This time NEITHER must be NULL */
290     if (!ontrue || !onfalse) {
291         mem_d(self);
292         return NULL;
293     }
294     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_ternary_codegen);
295
296     self->cond     = cond;
297     self->on_true  = ontrue;
298     self->on_false = onfalse;
299     self->phi_out  = NULL;
300
301     return self;
302 }
303
304 void ast_ternary_delete(ast_ternary *self)
305 {
306     ast_unref(self->cond);
307     ast_unref(self->on_true);
308     ast_unref(self->on_false);
309     ast_expression_delete((ast_expression*)self);
310     mem_d(self);
311 }
312
313 ast_loop* ast_loop_new(lex_ctx ctx,
314                        ast_expression *initexpr,
315                        ast_expression *precond,
316                        ast_expression *postcond,
317                        ast_expression *increment,
318                        ast_expression *body)
319 {
320     ast_instantiate(ast_loop, ctx, ast_loop_delete);
321     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_loop_codegen);
322
323     self->initexpr  = initexpr;
324     self->precond   = precond;
325     self->postcond  = postcond;
326     self->increment = increment;
327     self->body      = body;
328
329     return self;
330 }
331
332 void ast_loop_delete(ast_loop *self)
333 {
334     if (self->initexpr)
335         ast_unref(self->initexpr);
336     if (self->precond)
337         ast_unref(self->precond);
338     if (self->postcond)
339         ast_unref(self->postcond);
340     if (self->increment)
341         ast_unref(self->increment);
342     if (self->body)
343         ast_unref(self->body);
344     ast_expression_delete((ast_expression*)self);
345     mem_d(self);
346 }
347
348 ast_call* ast_call_new(lex_ctx ctx,
349                        ast_expression *funcexpr)
350 {
351     ast_instantiate(ast_call, ctx, ast_call_delete);
352     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_call_codegen);
353
354     MEM_VECTOR_INIT(self, params);
355
356     self->func = funcexpr;
357
358     return self;
359 }
360 MEM_VEC_FUNCTIONS(ast_call, ast_expression*, params)
361
362 void ast_call_delete(ast_call *self)
363 {
364     size_t i;
365     for (i = 0; i < self->params_count; ++i)
366         ast_unref(self->params[i]);
367     MEM_VECTOR_CLEAR(self, params);
368
369     if (self->func)
370         ast_unref(self->func);
371
372     ast_expression_delete((ast_expression*)self);
373     mem_d(self);
374 }
375
376 ast_store* ast_store_new(lex_ctx ctx, int op,
377                          ast_value *dest, ast_expression *source)
378 {
379     ast_instantiate(ast_store, ctx, ast_store_delete);
380     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_store_codegen);
381
382     self->op = op;
383     self->dest = dest;
384     self->source = source;
385
386     return self;
387 }
388
389 void ast_store_delete(ast_store *self)
390 {
391     ast_unref(self->dest);
392     ast_unref(self->source);
393     ast_expression_delete((ast_expression*)self);
394     mem_d(self);
395 }
396
397 ast_block* ast_block_new(lex_ctx ctx)
398 {
399     ast_instantiate(ast_block, ctx, ast_block_delete);
400     ast_expression_init((ast_expression*)self,
401                         (ast_expression_codegen*)&ast_block_codegen);
402
403     MEM_VECTOR_INIT(self, locals);
404     MEM_VECTOR_INIT(self, exprs);
405
406     return self;
407 }
408 MEM_VEC_FUNCTIONS(ast_block, ast_value*, locals)
409 MEM_VEC_FUNCTIONS(ast_block, ast_expression*, exprs)
410
411 void ast_block_delete(ast_block *self)
412 {
413     size_t i;
414     for (i = 0; i < self->exprs_count; ++i)
415         ast_unref(self->exprs[i]);
416     MEM_VECTOR_CLEAR(self, exprs);
417     for (i = 0; i < self->locals_count; ++i)
418         ast_delete(self->locals[i]);
419     MEM_VECTOR_CLEAR(self, locals);
420     ast_expression_delete((ast_expression*)self);
421     mem_d(self);
422 }
423
424 ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype)
425 {
426     ast_instantiate(ast_function, ctx, ast_function_delete);
427
428     if (!vtype ||
429         vtype->isconst ||
430         vtype->expression.vtype != TYPE_FUNCTION)
431     {
432         mem_d(self);
433         return NULL;
434     }
435
436     self->vtype = vtype;
437     self->name = name ? util_strdup(name) : NULL;
438     MEM_VECTOR_INIT(self, blocks);
439
440     self->labelcount = 0;
441     self->builtin = 0;
442
443     self->ir_func = NULL;
444     self->curblock = NULL;
445
446     self->breakblock    = NULL;
447     self->continueblock = NULL;
448
449     vtype->isconst = true;
450     vtype->constval.vfunc = self;
451
452     return self;
453 }
454
455 MEM_VEC_FUNCTIONS(ast_function, ast_block*, blocks)
456
457 void ast_function_delete(ast_function *self)
458 {
459     size_t i;
460     if (self->name)
461         mem_d((void*)self->name);
462     if (self->vtype) {
463         /* ast_value_delete(self->vtype); */
464         self->vtype->isconst = false;
465         self->vtype->constval.vfunc = NULL;
466         /* We use unref - if it was stored in a global table it is supposed
467          * to be deleted from *there*
468          */
469         ast_unref(self->vtype);
470     }
471     for (i = 0; i < self->blocks_count; ++i)
472         ast_delete(self->blocks[i]);
473     MEM_VECTOR_CLEAR(self, blocks);
474     mem_d(self);
475 }
476
477 static void ast_util_hexitoa(char *buf, size_t size, unsigned int num)
478 {
479     unsigned int base = 10;
480 #define checknul() do { if (size == 1) { *buf = 0; return; } } while (0)
481 #define addch(x) do { *buf++ = (x); --size; checknul(); } while (0)
482     if (size < 1)
483         return;
484     checknul();
485     if (!num)
486         addch('0');
487     else {
488         while (num)
489         {
490             int digit = num % base;
491             num /= base;
492             addch('0' + digit);
493         }
494     }
495
496     *buf = 0;
497 #undef addch
498 #undef checknul
499 }
500
501 const char* ast_function_label(ast_function *self, const char *prefix)
502 {
503     size_t id = (self->labelcount++);
504     size_t len = strlen(prefix);
505     strncpy(self->labelbuf, prefix, sizeof(self->labelbuf));
506     ast_util_hexitoa(self->labelbuf + len, sizeof(self->labelbuf)-len, id);
507     return self->labelbuf;
508 }
509
510 /*********************************************************************/
511 /* AST codegen part
512  * by convention you must never pass NULL to the 'ir_value **out'
513  * parameter. If you really don't care about the output, pass a dummy.
514  * But I can't imagine a pituation where the output is truly unnecessary.
515  */
516
517 bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_value **out)
518 {
519     /* NOTE: This is the codegen for a variable used in an expression.
520      * It is not the codegen to generate the value. For this purpose,
521      * ast_local_codegen and ast_global_codegen are to be used before this
522      * is executed. ast_function_codegen should take care of its locals,
523      * and the ast-user should take care of ast_global_codegen to be used
524      * on all the globals.
525      */
526     if (!self->ir_v) {
527         printf("ast_value used before generated (%s)\n", self->name);
528         return false;
529     }
530     *out = self->ir_v;
531     return true;
532 }
533
534 bool ast_global_codegen(ast_value *self, ir_builder *ir)
535 {
536     ir_value *v = NULL;
537     if (self->isconst && self->expression.vtype == TYPE_FUNCTION)
538     {
539         ir_function *func = ir_builder_create_function(ir, self->name, self->expression.next->expression.vtype);
540         if (!func)
541             return false;
542
543         self->constval.vfunc->ir_func = func;
544         self->ir_v = func->value;
545         /* The function is filled later on ast_function_codegen... */
546         return true;
547     }
548
549     v = ir_builder_create_global(ir, self->name, self->expression.vtype);
550     if (!v)
551         return false;
552
553     if (self->isconst) {
554         switch (self->expression.vtype)
555         {
556             case TYPE_FLOAT:
557                 if (!ir_value_set_float(v, self->constval.vfloat))
558                     goto error;
559                 break;
560             case TYPE_VECTOR:
561                 if (!ir_value_set_vector(v, self->constval.vvec))
562                     goto error;
563                 break;
564             case TYPE_STRING:
565                 if (!ir_value_set_string(v, self->constval.vstring))
566                     goto error;
567                 break;
568             case TYPE_FUNCTION:
569                 printf("global of type function not properly generated\n");
570                 goto error;
571                 /* Cannot generate an IR value for a function,
572                  * need a pointer pointing to a function rather.
573                  */
574             default:
575                 printf("TODO: global constant type %i\n", self->expression.vtype);
576                 break;
577         }
578     }
579
580     /* link us to the ir_value */
581     self->ir_v = v;
582     return true;
583
584 error: /* clean up */
585     ir_value_delete(v);
586     return false;
587 }
588
589 bool ast_local_codegen(ast_value *self, ir_function *func, bool param)
590 {
591     ir_value *v = NULL;
592     if (self->isconst && self->expression.vtype == TYPE_FUNCTION)
593     {
594         /* Do we allow local functions? I think not...
595          * this is NOT a function pointer atm.
596          */
597         return false;
598     }
599
600     v = ir_function_create_local(func, self->name, self->expression.vtype, param);
601     if (!v)
602         return false;
603
604     /* A constant local... hmmm...
605      * I suppose the IR will have to deal with this
606      */
607     if (self->isconst) {
608         switch (self->expression.vtype)
609         {
610             case TYPE_FLOAT:
611                 if (!ir_value_set_float(v, self->constval.vfloat))
612                     goto error;
613                 break;
614             case TYPE_VECTOR:
615                 if (!ir_value_set_vector(v, self->constval.vvec))
616                     goto error;
617                 break;
618             case TYPE_STRING:
619                 if (!ir_value_set_string(v, self->constval.vstring))
620                     goto error;
621                 break;
622             default:
623                 printf("TODO: global constant type %i\n", self->expression.vtype);
624                 break;
625         }
626     }
627
628     /* link us to the ir_value */
629     self->ir_v = v;
630     return true;
631
632 error: /* clean up */
633     ir_value_delete(v);
634     return false;
635 }
636
637 bool ast_function_codegen(ast_function *self, ir_builder *ir)
638 {
639     ir_function *irf;
640     ir_value    *dummy;
641     size_t    i;
642
643     irf = self->ir_func;
644     if (!irf) {
645         printf("ast_function's related ast_value was not generated yet\n");
646         return false;
647     }
648
649     /* fill the parameter list */
650     for (i = 0; i < self->vtype->params_count; ++i)
651     {
652         if (!ir_function_params_add(irf, self->vtype->params[i]->expression.vtype))
653             return false;
654         if (!self->builtin) {
655             if (!ast_local_codegen(self->vtype->params[i], self->ir_func, true))
656                 return false;
657         }
658     }
659
660     if (self->builtin) {
661         irf->builtin = self->builtin;
662         return true;
663     }
664
665     self->curblock = ir_function_create_block(irf, "entry");
666     if (!self->curblock)
667         return false;
668
669     for (i = 0; i < self->blocks_count; ++i) {
670         ast_expression_codegen *gen = self->blocks[i]->expression.codegen;
671         if (!(*gen)((ast_expression*)self->blocks[i], self, false, &dummy))
672             return false;
673     }
674
675     /* TODO: check return types */
676     if (!self->curblock->is_return)
677     {
678         if (!self->vtype->expression.next ||
679             self->vtype->expression.next->expression.vtype == TYPE_VOID)
680         {
681             return ir_block_create_return(self->curblock, NULL);
682         }
683         else
684         {
685             /* error("missing return"); */
686             return false;
687         }
688     }
689     return true;
690 }
691
692 /* Note, you will not see ast_block_codegen generate ir_blocks.
693  * To the AST and the IR, blocks are 2 different things.
694  * In the AST it represents a block of code, usually enclosed in
695  * curly braces {...}.
696  * While in the IR it represents a block in terms of control-flow.
697  */
698 bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_value **out)
699 {
700     size_t i;
701
702     /* We don't use this
703      * Note: an ast-representation using the comma-operator
704      * of the form: (a, b, c) = x should not assign to c...
705      */
706     (void)lvalue;
707
708     /* output is NULL at first, we'll have each expression
709      * assign to out output, thus, a comma-operator represention
710      * using an ast_block will return the last generated value,
711      * so: (b, c) + a  executed both b and c, and returns c,
712      * which is then added to a.
713      */
714     *out = NULL;
715
716     /* generate locals */
717     for (i = 0; i < self->locals_count; ++i)
718     {
719         if (!ast_local_codegen(self->locals[i], func->ir_func, false))
720             return false;
721     }
722
723     for (i = 0; i < self->exprs_count; ++i)
724     {
725         ast_expression_codegen *gen = self->exprs[i]->expression.codegen;
726         if (!(*gen)(self->exprs[i], func, false, out))
727             return false;
728     }
729
730     return true;
731 }
732
733 bool ast_store_codegen(ast_store *self, ast_function *func, bool lvalue, ir_value **out)
734 {
735     ast_expression_codegen *cgen;
736     ir_value *left, *right;
737
738     cgen = self->dest->expression.codegen;
739     /* lvalue! */
740     if (!(*cgen)((ast_expression*)(self->dest), func, true, &left))
741         return false;
742
743     cgen = self->source->expression.codegen;
744     /* rvalue! */
745     if (!(*cgen)((ast_expression*)(self->source), func, false, &right))
746         return false;
747
748     if (!ir_block_create_store_op(func->curblock, self->op, left, right))
749         return false;
750
751     /* Theoretically, an assinment returns its left side as an
752      * lvalue, if we don't need an lvalue though, we return
753      * the right side as an rvalue, otherwise we have to
754      * somehow know whether or not we need to dereference the pointer
755      * on the left side - that is: OP_LOAD if it was an address.
756      * Also: in original QC we cannot OP_LOADP *anyway*.
757      */
758     *out = (lvalue ? left : right);
759
760     return true;
761 }
762
763 bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_value **out)
764 {
765     ast_expression_codegen *cgen;
766     ir_value *left, *right;
767
768     /* In the context of a binary operation, we can disregard
769      * the lvalue flag.
770      */
771      (void)lvalue;
772
773     cgen = self->left->expression.codegen;
774     /* lvalue! */
775     if (!(*cgen)((ast_expression*)(self->left), func, false, &left))
776         return false;
777
778     cgen = self->right->expression.codegen;
779     /* rvalue! */
780     if (!(*cgen)((ast_expression*)(self->right), func, false, &right))
781         return false;
782
783     *out = ir_block_create_binop(func->curblock, ast_function_label(func, "bin"),
784                                  self->op, left, right);
785     if (!*out)
786         return false;
787
788     return true;
789 }
790
791 bool ast_unary_codegen(ast_unary *self, ast_function *func, bool lvalue, ir_value **out)
792 {
793     ast_expression_codegen *cgen;
794     ir_value *operand;
795
796     /* In the context of a unary operation, we can disregard
797      * the lvalue flag.
798      */
799     (void)lvalue;
800
801     cgen = self->operand->expression.codegen;
802     /* lvalue! */
803     if (!(*cgen)((ast_expression*)(self->operand), func, false, &operand))
804         return false;
805
806     *out = ir_block_create_unary(func->curblock, ast_function_label(func, "unary"),
807                                  self->op, operand);
808     if (!*out)
809         return false;
810
811     return true;
812 }
813
814 bool ast_return_codegen(ast_return *self, ast_function *func, bool lvalue, ir_value **out)
815 {
816     ast_expression_codegen *cgen;
817     ir_value *operand;
818
819     /* In the context of a return operation, we can disregard
820      * the lvalue flag.
821      */
822     (void)lvalue;
823
824     cgen = self->operand->expression.codegen;
825     /* lvalue! */
826     if (!(*cgen)((ast_expression*)(self->operand), func, false, &operand))
827         return false;
828
829     if (!ir_block_create_return(func->curblock, operand))
830         return false;
831
832     return true;
833 }
834
835 bool ast_entfield_codegen(ast_entfield *self, ast_function *func, bool lvalue, ir_value **out)
836 {
837     ast_expression_codegen *cgen;
838     ir_value *ent, *field;
839
840     /* This function needs to take the 'lvalue' flag into account!
841      * As lvalue we provide a field-pointer, as rvalue we provide the
842      * value in a temp.
843      */
844
845     cgen = self->entity->expression.codegen;
846     if (!(*cgen)((ast_expression*)(self->entity), func, false, &ent))
847         return false;
848
849     cgen = self->field->expression.codegen;
850     if (!(*cgen)((ast_expression*)(self->field), func, false, &field))
851         return false;
852
853     if (lvalue) {
854         /* address! */
855         *out = ir_block_create_fieldaddress(func->curblock, ast_function_label(func, "efa"),
856                                             ent, field);
857     } else {
858         *out = ir_block_create_load_from_ent(func->curblock, ast_function_label(func, "efv"),
859                                              ent, field, self->expression.vtype);
860     }
861     if (!*out)
862         return false;
863
864     /* Hm that should be it... */
865     return true;
866 }
867
868 bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_value **out)
869 {
870     ast_expression_codegen *cgen;
871
872     ir_value *condval;
873     ir_value *dummy;
874
875     ir_block *cond = func->curblock;
876     ir_block *ontrue;
877     ir_block *onfalse;
878     ir_block *merge;
879
880     /* We don't output any value, thus also don't care about r/lvalue */
881     (void)out;
882     (void)lvalue;
883
884     /* generate the condition */
885     func->curblock = cond;
886     cgen = self->cond->expression.codegen;
887     if (!(*cgen)((ast_expression*)(self->cond), func, false, &condval))
888         return false;
889
890     /* on-true path */
891
892     if (self->on_true) {
893         /* create on-true block */
894         ontrue = ir_function_create_block(func->ir_func, ast_function_label(func, "ontrue"));
895         if (!ontrue)
896             return false;
897
898         /* enter the block */
899         func->curblock = ontrue;
900
901         /* generate */
902         cgen = self->on_true->expression.codegen;
903         if (!(*cgen)((ast_expression*)(self->on_true), func, false, &dummy))
904             return false;
905     } else
906         ontrue = NULL;
907
908     /* on-false path */
909     if (self->on_false) {
910         /* create on-false block */
911         onfalse = ir_function_create_block(func->ir_func, ast_function_label(func, "onfalse"));
912         if (!onfalse)
913             return false;
914
915         /* enter the block */
916         func->curblock = onfalse;
917
918         /* generate */
919         cgen = self->on_false->expression.codegen;
920         if (!(*cgen)((ast_expression*)(self->on_false), func, false, &dummy))
921             return false;
922     } else
923         onfalse = NULL;
924
925     /* Merge block were they all merge in to */
926     merge = ir_function_create_block(func->ir_func, ast_function_label(func, "endif"));
927     if (!merge)
928         return false;
929
930     /* add jumps ot the merge block */
931     if (ontrue && !ir_block_create_jump(ontrue, merge))
932         return false;
933     if (onfalse && !ir_block_create_jump(onfalse, merge))
934         return false;
935
936     /* we create the if here, that way all blocks are ordered :)
937      */
938     if (!ir_block_create_if(cond, condval,
939                             (ontrue  ? ontrue  : merge),
940                             (onfalse ? onfalse : merge)))
941     {
942         return false;
943     }
944
945     /* Now enter the merge block */
946     func->curblock = merge;
947
948     return true;
949 }
950
951 bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_value **out)
952 {
953     ast_expression_codegen *cgen;
954
955     ir_value *condval;
956     ir_value *trueval, *falseval;
957     ir_instr *phi;
958
959     ir_block *cond = func->curblock;
960     ir_block *ontrue;
961     ir_block *onfalse;
962     ir_block *merge;
963
964     /* In theory it shouldn't be possible to pass through a node twice, but
965      * in case we add any kind of optimization pass for the AST itself, it
966      * may still happen, thus we remember a created ir_value and simply return one
967      * if it already exists.
968      */
969     if (self->phi_out) {
970         *out = self->phi_out;
971         return true;
972     }
973
974     /* Ternary can never create an lvalue... */
975     if (lvalue)
976         return false;
977
978     /* In the following, contraty to ast_ifthen, we assume both paths exist. */
979
980     /* generate the condition */
981     func->curblock = cond;
982     cgen = self->cond->expression.codegen;
983     if (!(*cgen)((ast_expression*)(self->cond), func, false, &condval))
984         return false;
985
986     /* create on-true block */
987     ontrue = ir_function_create_block(func->ir_func, ast_function_label(func, "tern_T"));
988     if (!ontrue)
989         return false;
990     else
991     {
992         /* enter the block */
993         func->curblock = ontrue;
994
995         /* generate */
996         cgen = self->on_true->expression.codegen;
997         if (!(*cgen)((ast_expression*)(self->on_true), func, false, &trueval))
998             return false;
999     }
1000
1001     /* create on-false block */
1002     onfalse = ir_function_create_block(func->ir_func, ast_function_label(func, "tern_F"));
1003     if (!onfalse)
1004         return false;
1005     else
1006     {
1007         /* enter the block */
1008         func->curblock = onfalse;
1009
1010         /* generate */
1011         cgen = self->on_false->expression.codegen;
1012         if (!(*cgen)((ast_expression*)(self->on_false), func, false, &falseval))
1013             return false;
1014     }
1015
1016     /* create merge block */
1017     merge = ir_function_create_block(func->ir_func, ast_function_label(func, "tern_out"));
1018     if (!merge)
1019         return false;
1020     /* jump to merge block */
1021     if (!ir_block_create_jump(ontrue, merge))
1022         return false;
1023     if (!ir_block_create_jump(onfalse, merge))
1024         return false;
1025
1026     /* create if instruction */
1027     if (!ir_block_create_if(cond, condval, ontrue, onfalse))
1028         return false;
1029
1030     /* Now enter the merge block */
1031     func->curblock = merge;
1032
1033     /* Here, now, we need a PHI node
1034      * but first some sanity checking...
1035      */
1036     if (trueval->vtype != falseval->vtype) {
1037         /* error("ternary with different types on the two sides"); */
1038         return false;
1039     }
1040
1041     /* create PHI */
1042     phi = ir_block_create_phi(merge, ast_function_label(func, "phi"), trueval->vtype);
1043     if (!phi ||
1044         !ir_phi_add(phi, ontrue,  trueval) ||
1045         !ir_phi_add(phi, onfalse, falseval))
1046     {
1047         return false;
1048     }
1049
1050     self->phi_out = ir_phi_value(phi);
1051     *out = self->phi_out;
1052
1053     return true;
1054 }
1055
1056 bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value **out)
1057 {
1058     ast_expression_codegen *cgen;
1059
1060     ir_value *dummy      = NULL;
1061     ir_value *precond    = NULL;
1062     ir_value *postcond   = NULL;
1063
1064     /* Since we insert some jumps "late" so we have blocks
1065      * ordered "nicely", we need to keep track of the actual end-blocks
1066      * of expressions to add the jumps to.
1067      */
1068     ir_block *bbody      = NULL, *end_bbody      = NULL;
1069     ir_block *bprecond   = NULL, *end_bprecond   = NULL;
1070     ir_block *bpostcond  = NULL, *end_bpostcond  = NULL;
1071     ir_block *bincrement = NULL, *end_bincrement = NULL;
1072     ir_block *bout       = NULL, *bin            = NULL;
1073
1074     /* let's at least move the outgoing block to the end */
1075     size_t    bout_id;
1076
1077     /* 'break' and 'continue' need to be able to find the right blocks */
1078     ir_block *bcontinue     = NULL;
1079     ir_block *bbreak        = NULL;
1080
1081     ir_block *old_bcontinue = NULL;
1082     ir_block *old_bbreak    = NULL;
1083
1084     ir_block *tmpblock      = NULL;
1085
1086     (void)lvalue;
1087     (void)out;
1088
1089     /* NOTE:
1090      * Should we ever need some kind of block ordering, better make this function
1091      * move blocks around than write a block ordering algorithm later... after all
1092      * the ast and ir should work together, not against each other.
1093      */
1094
1095     /* initexpr doesn't get its own block, it's pointless, it could create more blocks
1096      * anyway if for example it contains a ternary.
1097      */
1098     if (self->initexpr)
1099     {
1100         cgen = self->initexpr->expression.codegen;
1101         if (!(*cgen)((ast_expression*)(self->initexpr), func, false, &dummy))
1102             return false;
1103     }
1104
1105     /* Store the block from which we enter this chaos */
1106     bin = func->curblock;
1107
1108     /* The pre-loop condition needs its own block since we
1109      * need to be able to jump to the start of that expression.
1110      */
1111     if (self->precond)
1112     {
1113         bprecond = ir_function_create_block(func->ir_func, ast_function_label(func, "pre_loop_cond"));
1114         if (!bprecond)
1115             return false;
1116
1117         /* the pre-loop-condition the least important place to 'continue' at */
1118         bcontinue = bprecond;
1119
1120         /* enter */
1121         func->curblock = bprecond;
1122
1123         /* generate */
1124         cgen = self->precond->expression.codegen;
1125         if (!(*cgen)((ast_expression*)(self->precond), func, false, &precond))
1126             return false;
1127
1128         end_bprecond = func->curblock;
1129     } else {
1130         bprecond = end_bprecond = NULL;
1131     }
1132
1133     /* Now the next blocks won't be ordered nicely, but we need to
1134      * generate them this early for 'break' and 'continue'.
1135      */
1136     if (self->increment) {
1137         bincrement = ir_function_create_block(func->ir_func, ast_function_label(func, "loop_increment"));
1138         if (!bincrement)
1139             return false;
1140         bcontinue = bincrement; /* increment comes before the pre-loop-condition */
1141     } else {
1142         bincrement = end_bincrement = NULL;
1143     }
1144
1145     if (self->postcond) {
1146         bpostcond = ir_function_create_block(func->ir_func, ast_function_label(func, "post_loop_cond"));
1147         if (!bpostcond)
1148             return false;
1149         bcontinue = bpostcond; /* postcond comes before the increment */
1150     } else {
1151         bpostcond = end_bpostcond = NULL;
1152     }
1153
1154     bout_id = func->ir_func->blocks_count;
1155     bout = ir_function_create_block(func->ir_func, ast_function_label(func, "after_loop"));
1156     if (!bout)
1157         return false;
1158     bbreak = bout;
1159
1160     /* The loop body... */
1161     if (self->body)
1162     {
1163         bbody = ir_function_create_block(func->ir_func, ast_function_label(func, "loop_body"));
1164         if (!bbody)
1165             return false;
1166
1167         /* enter */
1168         func->curblock = bbody;
1169
1170         old_bbreak          = func->breakblock;
1171         old_bcontinue       = func->continueblock;
1172         func->breakblock    = bbreak;
1173         func->continueblock = bcontinue;
1174
1175         /* generate */
1176         cgen = self->body->expression.codegen;
1177         if (!(*cgen)((ast_expression*)(self->body), func, false, &dummy))
1178             return false;
1179
1180         end_bbody = func->curblock;
1181         func->breakblock    = old_bbreak;
1182         func->continueblock = old_bcontinue;
1183     }
1184
1185     /* post-loop-condition */
1186     if (self->postcond)
1187     {
1188         /* enter */
1189         func->curblock = bpostcond;
1190
1191         /* generate */
1192         cgen = self->postcond->expression.codegen;
1193         if (!(*cgen)((ast_expression*)(self->postcond), func, false, &postcond))
1194             return false;
1195
1196         end_bpostcond = func->curblock;
1197     }
1198
1199     /* The incrementor */
1200     if (self->increment)
1201     {
1202         /* enter */
1203         func->curblock = bincrement;
1204
1205         /* generate */
1206         cgen = self->increment->expression.codegen;
1207         if (!(*cgen)((ast_expression*)(self->increment), func, false, &dummy))
1208             return false;
1209
1210         end_bincrement = func->curblock;
1211     }
1212
1213     /* In any case now, we continue from the outgoing block */
1214     func->curblock = bout;
1215
1216     /* Now all blocks are in place */
1217     /* From 'bin' we jump to whatever comes first */
1218     if      (bprecond)   tmpblock = bprecond;
1219     else if (bbody)      tmpblock = bbody;
1220     else if (bpostcond)  tmpblock = bpostcond;
1221     else                 tmpblock = bout;
1222     if (!ir_block_create_jump(bin, tmpblock))
1223         return false;
1224
1225     /* From precond */
1226     if (bprecond)
1227     {
1228         ir_block *ontrue, *onfalse;
1229         if      (bbody)      ontrue = bbody;
1230         else if (bincrement) ontrue = bincrement;
1231         else if (bpostcond)  ontrue = bpostcond;
1232         else                 ontrue = bprecond;
1233         onfalse = bout;
1234         if (!ir_block_create_if(end_bprecond, precond, ontrue, onfalse))
1235             return false;
1236     }
1237
1238     /* from body */
1239     if (bbody)
1240     {
1241         if      (bincrement) tmpblock = bincrement;
1242         else if (bpostcond)  tmpblock = bpostcond;
1243         else if (bprecond)   tmpblock = bprecond;
1244         else                 tmpblock = bout;
1245         if (!ir_block_create_jump(end_bbody, tmpblock))
1246             return false;
1247     }
1248
1249     /* from increment */
1250     if (bincrement)
1251     {
1252         if      (bpostcond)  tmpblock = bpostcond;
1253         else if (bprecond)   tmpblock = bprecond;
1254         else if (bbody)      tmpblock = bbody;
1255         else                 tmpblock = bout;
1256         if (!ir_block_create_jump(end_bincrement, tmpblock))
1257             return false;
1258     }
1259
1260     /* from postcond */
1261     if (bpostcond)
1262     {
1263         ir_block *ontrue, *onfalse;
1264         if      (bprecond)   ontrue = bprecond;
1265         else if (bbody)      ontrue = bbody;
1266         else if (bincrement) ontrue = bincrement;
1267         else                 ontrue = bpostcond;
1268         onfalse = bout;
1269         if (!ir_block_create_if(end_bpostcond, postcond, ontrue, onfalse))
1270             return false;
1271     }
1272
1273     /* Move 'bout' to the end */
1274     if (!ir_function_blocks_remove(func->ir_func, bout_id) ||
1275         !ir_function_blocks_add(func->ir_func, bout))
1276     {
1277         ir_block_delete(bout);
1278         return false;
1279     }
1280
1281     return true;
1282 }
1283
1284 bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value **out)
1285 {
1286     ast_expression_codegen *cgen;
1287     ir_value_vector         params;
1288     ir_instr               *callinstr;
1289     size_t i;
1290
1291     ir_value *funval = NULL;
1292
1293     /* return values are never rvalues */
1294     (void)lvalue;
1295
1296     cgen = self->func->expression.codegen;
1297     if (!(*cgen)((ast_expression*)(self->func), func, false, &funval))
1298         return false;
1299     if (!funval)
1300         return false;
1301
1302     MEM_VECTOR_INIT(&params, v);
1303
1304     /* parameters */
1305     for (i = 0; i < self->params_count; ++i)
1306     {
1307         ir_value *param;
1308         ast_expression *expr = self->params[i];
1309
1310         cgen = expr->expression.codegen;
1311         if (!(*cgen)(expr, func, false, &param))
1312             goto error;
1313         if (!param)
1314             goto error;
1315         if (!ir_value_vector_v_add(&params, param))
1316             goto error;
1317     }
1318
1319     callinstr = ir_block_create_call(func->curblock, ast_function_label(func, "call"), funval);
1320     if (!callinstr)
1321         goto error;
1322
1323     for (i = 0; i < params.v_count; ++i) {
1324         if (!ir_call_param(callinstr, params.v[i]))
1325             goto error;
1326     }
1327
1328     *out = ir_call_value(callinstr);
1329
1330     return true;
1331 error:
1332     MEM_VECTOR_CLEAR(&params, v);
1333     return false;
1334 }