]> git.xonotic.org Git - xonotic/gmqcc.git/blob - ast.c
ir.c: importing ir_block
[xonotic/gmqcc.git] / ast.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "ast.h"
6
7 #define ast_setfunc(me, fn, what) ( *(void**)&((me)->fn) = what )
8
9 #define ast_instantiate(T, ctx, destroyfn)                    \
10     T *self = (T*)mem_a(sizeof(T));                           \
11     ast_node_init((ast_node*)self, ctx);                      \
12     ast_setfunc(&((ast_node*)self)->node, destroy, destroyfn)
13
14 /* It must not be possible to get here. */
15 static void _ast_node_destroy(ast_node *self)
16 {
17     fprintf(stderr, "ast node missing destroy()\n");
18     abort();
19 }
20
21 /* Initialize main ast node aprts */
22 static void ast_node_init(ast_node *self, lex_ctx_t ctx)
23 {
24     self->node.context = ctx;
25     self->node.destroy = &_ast_node_destroy;
26 }
27
28 /* General expression initialization */
29 static void ast_expression_init(ast_expression *self,
30                                 ast_expression_codegen *codegen)
31 {
32     ast_setfunc(&self->expression, codegen, codegen);
33 }
34
35 ast_value* ast_value_new(lex_ctx_t ctx, const char *name, qc_type_t t)
36 {
37     ast_instantiate(ast_value, ctx, ast_value_delete);
38     ast_expression_init((ast_expression*)self,
39                         (ast_expression_codegen*)&ast_value_codegen);
40
41     self->name = name ? util_strdup(name) : NULL;
42     self->vtype = t;
43     self->next = NULL;
44     MEM_VECTOR_INIT(self, params);
45     self->has_constval = false;
46     memset(&self->cvalue, 0, sizeof(self->cvalue));
47
48     self->ir_v = NULL;
49
50     return self;
51 }
52 MEM_VEC_FUNCTIONS(ast_value, ast_value*, params)
53
54 void ast_value_delete(ast_value* self)
55 {
56     size_t i;
57     if (self->name)
58         mem_d((void*)self->name);
59     for (i = 0; i < self->params_count; ++i)
60         ast_delete(self->params[i]);
61     MEM_VECTOR_CLEAR(self, params);
62     if (self->next)
63         ast_delete(self->next);
64     if (self->has_constval) {
65         switch (self->vtype)
66         {
67         case qc_string:
68             mem_d((void*)self->cvalue.vstring);
69             break;
70         /* NOTE: delete function? currently collected in
71          * the parser structure
72          */
73         default:
74             break;
75         }
76     }
77     mem_d(self);
78 }
79
80 void ast_value_set_name(ast_value *self, const char *name)
81 {
82     if (self->name)
83         mem_d((void*)self->name);
84     self->name = util_strdup(name);
85 }
86
87 ast_binary* ast_binary_new(lex_ctx_t ctx, qc_op_t op,
88                            ast_value* left, ast_value* right)
89 {
90     ast_instantiate(ast_binary, ctx, ast_binary_delete);
91     ast_expression_init((ast_expression*)self, (ast_expression_codegen*)codegen);
92
93     self->op = op;
94     self->left = left;
95     self->right = right;
96
97     return self;
98 }
99
100 void ast_binary_delete(ast_binary *self)
101 {
102     mem_d(self);
103 }
104
105 ast_block* ast_block_new(lex_ctx_t ctx)
106 {
107     ast_instantiate(ast_block, ctx, ast_block_delete);
108     ast_expression_init((ast_expression*)self,
109                         (ast_expression_codegen*)&ast_block_codegen);
110
111     MEM_VECTOR_INIT(self, locals);
112     MEM_VECTOR_INIT(self, exprs);
113
114     return self;
115 }
116 MEM_VEC_FUNCTIONS(ast_block, ast_value*, locals)
117 MEM_VEC_FUNCTIONS(ast_block, ast_expression*, exprs)
118
119 void ast_block_delete(ast_block *self)
120 {
121     size_t i;
122     for (i = 0; i < self->locals_count; ++i)
123         ast_delete(self->locals[i]);
124     MEM_VECTOR_CLEAR(self, locals);
125     for (i = 0; i < self->exprs_count; ++i)
126         ast_delete(self->exprs[i]);
127     MEM_VECTOR_CLEAR(self, exprs);
128     mem_d(self);
129 }
130
131 ast_function* ast_function_new(lex_ctx_t ctx, const char *name, ast_value *vtype)
132 {
133     ast_instantiate(ast_function, ctx, ast_function_delete);
134
135     self->vtype = vtype;
136     self->name = name ? util_strdup(name) : NULL;
137     MEM_VECTOR_INIT(self, blocks);
138
139     return self;
140 }
141
142 MEM_VEC_FUNCTIONS(ast_function, ast_block*, blocks)
143
144 void ast_function_delete(ast_function *self)
145 {
146     size_t i;
147     if (self->name)
148         mem_d((void*)self->name);
149     if (self->vtype)
150         ast_value_delete(self->vtype);
151     for (i = 0; i < self->blocks_count; ++i)
152         ast_delete(self->blocks[i]);
153     MEM_VECTOR_CLEAR(self, blocks);
154     mem_d(self);
155 }
156
157 /*********************************************************************/
158 /* AST codegen aprt
159  */
160
161 static qbool ast_value_gen_global(ir_builder *ir, ast_value *self, ir_value **out)
162 {
163     ir_value *v;
164     *out = NULL;
165
166     /* Generate functions */
167     if (self->vtype == qc_function && self->has_constval)
168     {
169         /* Without has_constval it would be invalid... function pointers actually have
170          * type qc_pointer and next with type qc_function
171          */
172         ast_function *func = self->cvalue.vfunc;
173         if (!ast_function_codegen(func, ir))
174             return false;
175
176         /* Here we do return NULL anyway */
177         return true;
178     }
179     else if (self->vtype == qc_function && !self->has_constval) {
180         fprintf(stderr,
181         "!v->has_constval <- qc_function body missing - FIXME: remove when implementing prototypes\n");
182         fprintf(stderr, "Value: %s\n", self->_name);
183         abort();
184     }
185
186     v = ir_builder_create_global(ir, self->_name, self->vtype);
187     self->ir_v = v;
188
189     *out = v;
190     return true;
191 }
192
193 qbool ast_value_codegen(ast_value *self, ast_function *func, ir_value **out)
194 {
195     if (!func)
196         return ast_value_gen_global(parser.ir, self, out);
197     return false;
198 }
199
200 qbool ast_function_codegen(ast_function *self, ir_builder *builder)
201 {
202     size_t i;
203     for (i = 0; i < self->blocks_count; ++i)
204     {
205         ast_expression *expr;
206         ir_value *out;
207
208         expr = (ast_expression*)self->blocks[i];
209
210         if (!(expr->expression.codegen)(expr, self, &out))
211         {
212             /* there was an error while building this expression... */
213             return false;
214         }
215         (void)out;
216     }
217     return true;
218 }
219
220 qbool ast_block_codegen(ast_block *self, ir_function *func, ir_value **out)
221 {
222     return false;
223 }
224
225 qbool ast_bin_store_codegen(ast_binary *self, ir_function *func, ir_value **out)
226 {
227     return false;
228 }