X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=ast.c;h=0b61fe0653afbf5b6b6701ff714d0ee98899656c;hb=8dccf69060478c5665052dddaa6845d9e5d34f6c;hp=56db3f94f872b678930e934ea9ca679c20bd4b25;hpb=31ba1ec6c1302aa466bd25b9e275b5cc16303808;p=xonotic%2Fgmqcc.git diff --git a/ast.c b/ast.c index 56db3f9..0b61fe0 100644 --- a/ast.c +++ b/ast.c @@ -32,7 +32,7 @@ if (!self) { \ return NULL; \ } \ - ast_node_init((ast_node*)self, ctx); \ + ast_node_init((ast_node*)self, ctx, TYPE_##T); \ ( (ast_node*)self )->node.destroy = (ast_node_delete*)destroyfn /* It must not be possible to get here. */ @@ -43,11 +43,12 @@ static GMQCC_NORETURN void _ast_node_destroy(ast_node *self) } /* Initialize main ast node aprts */ -static void ast_node_init(ast_node *self, lex_ctx ctx) +static void ast_node_init(ast_node *self, lex_ctx ctx, int nodetype) { self->node.context = ctx; self->node.destroy = &_ast_node_destroy; self->node.keep = false; + self->node.nodetype = nodetype; } /* General expression initialization */ @@ -57,12 +58,18 @@ static void ast_expression_init(ast_expression *self, self->expression.codegen = codegen; self->expression.vtype = TYPE_VOID; self->expression.next = NULL; + MEM_VECTOR_INIT(&self->expression, params); } static void ast_expression_delete(ast_expression *self) { + size_t i; if (self->expression.next) ast_delete(self->expression.next); + for (i = 0; i < self->expression.params_count; ++i) { + ast_delete(self->expression.params[i]); + } + MEM_VECTOR_CLEAR(&self->expression, params); } static void ast_expression_delete_full(ast_expression *self) @@ -71,9 +78,26 @@ static void ast_expression_delete_full(ast_expression *self) mem_d(self); } +MEM_VEC_FUNCTIONS(ast_expression_common, ast_value*, params) + +static ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex); +static ast_value* ast_value_copy(const ast_value *self) +{ + ast_value *cp = ast_value_new(self->expression.node.context, self->name, self->expression.vtype); + if (self->expression.next) { + cp->expression.next = ast_type_copy(self->expression.node.context, self->expression.next); + if (!cp->expression.next) { + ast_value_delete(cp); + return NULL; + } + } + return cp; +} + static ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex) { - const ast_expression_common *cpex; + size_t i; + const ast_expression_common *fromex; ast_expression_common *selfex; if (!ex) @@ -82,23 +106,32 @@ static ast_expression* ast_type_copy(lex_ctx ctx, const ast_expression *ex) { ast_instantiate(ast_expression, ctx, ast_expression_delete_full); - cpex = &ex->expression; + fromex = &ex->expression; selfex = &self->expression; - selfex->vtype = cpex->vtype; - if (cpex->next) + /* This may never be codegen()d */ + selfex->codegen = NULL; + + selfex->vtype = fromex->vtype; + if (fromex->next) { - selfex->next = ast_type_copy(ctx, cpex->next); + selfex->next = ast_type_copy(ctx, fromex->next); if (!selfex->next) { - mem_d(self); + ast_expression_delete_full(self); return NULL; } } else selfex->next = NULL; - /* This may never be codegen()d */ - selfex->codegen = NULL; + for (i = 0; i < fromex->params_count; ++i) { + ast_value *v = ast_value_copy(fromex->params[i]); + if (!v || !ast_expression_common_params_add(selfex, v)) { + ast_expression_delete_full(self); + return NULL; + } + } + return self; } } @@ -113,7 +146,6 @@ ast_value* ast_value_new(lex_ctx ctx, const char *name, int t) self->name = name ? util_strdup(name) : NULL; self->expression.vtype = t; self->expression.next = NULL; - MEM_VECTOR_INIT(self, params); self->isconst = false; memset(&self->constval, 0, sizeof(self->constval)); @@ -121,16 +153,11 @@ ast_value* ast_value_new(lex_ctx ctx, const char *name, int t) return self; } -MEM_VEC_FUNCTIONS(ast_value, ast_value*, params) void ast_value_delete(ast_value* self) { - size_t i; if (self->name) mem_d((void*)self->name); - for (i = 0; i < self->params_count; ++i) - ast_value_delete(self->params[i]); /* delete, the ast_function is expected to die first */ - MEM_VECTOR_CLEAR(self, params); if (self->isconst) { switch (self->expression.vtype) { @@ -152,6 +179,11 @@ void ast_value_delete(ast_value* self) mem_d(self); } +bool GMQCC_WARN ast_value_params_add(ast_value *self, ast_value *p) +{ + return ast_expression_common_params_add(&self->expression, p); +} + bool ast_value_set_name(ast_value *self, const char *name) { if (self->name) @@ -200,8 +232,7 @@ void ast_unary_delete(ast_unary *self) mem_d(self); } -ast_return* ast_return_new(lex_ctx ctx, int op, - ast_expression *expr) +ast_return* ast_return_new(lex_ctx ctx, ast_expression *expr) { ast_instantiate(ast_return, ctx, ast_return_delete); ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_return_codegen); @@ -374,7 +405,7 @@ void ast_call_delete(ast_call *self) } ast_store* ast_store_new(lex_ctx ctx, int op, - ast_value *dest, ast_expression *source) + ast_expression *dest, ast_expression *source) { ast_instantiate(ast_store, ctx, ast_store_delete); ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_store_codegen); @@ -421,6 +452,19 @@ void ast_block_delete(ast_block *self) mem_d(self); } +bool ast_block_set_type(ast_block *self, ast_expression *from) +{ + if (self->expression.next) + ast_delete(self->expression.next); + self->expression.vtype = from->expression.vtype; + if (from->expression.next) { + self->expression.next = ast_type_copy(self->expression.node.context, from->expression.next); + if (!self->expression.next) + return false; + } + return true; +} + ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype) { ast_instantiate(ast_function, ctx, ast_function_delete); @@ -638,6 +682,7 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) { ir_function *irf; ir_value *dummy; + ast_expression_common *ec; size_t i; irf = self->ir_func; @@ -647,12 +692,13 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) } /* fill the parameter list */ - for (i = 0; i < self->vtype->params_count; ++i) + ec = &self->vtype->expression; + for (i = 0; i < ec->params_count; ++i) { - if (!ir_function_params_add(irf, self->vtype->params[i]->expression.vtype)) + if (!ir_function_params_add(irf, ec->params[i]->expression.vtype)) return false; if (!self->builtin) { - if (!ast_local_codegen(self->vtype->params[i], self->ir_func, true)) + if (!ast_local_codegen(ec->params[i], self->ir_func, true)) return false; } } @@ -1327,6 +1373,7 @@ bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value *out = ir_call_value(callinstr); + MEM_VECTOR_CLEAR(¶ms, v); return true; error: MEM_VECTOR_CLEAR(¶ms, v);