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