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