X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=ast.c;h=65c6934b000d2ce65dec16a0ffed4a0f897a7d80;hp=f6e96c4f116b0df0f47adad4edaaa63a02f73dfe;hb=ae251d391464763fd8293efd65627f9f9fd56572;hpb=1f8ece7f206d2ffd38d8427be00013fcd8777249 diff --git a/ast.c b/ast.c index f6e96c4..65c6934 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) @@ -170,6 +202,18 @@ ast_binary* ast_binary_new(lex_ctx ctx, int op, self->left = left; self->right = right; + if (op >= INSTR_EQ_F && op <= INSTR_GT) + self->expression.vtype = TYPE_FLOAT; + else if (op == INSTR_AND || op == INSTR_OR || + op == INSTR_BITAND || op == INSTR_BITOR) + self->expression.vtype = TYPE_FLOAT; + else if (op == INSTR_MUL_VF || op == INSTR_MUL_FV) + self->expression.vtype = TYPE_VECTOR; + else if (op == INSTR_MUL_V) + self->expression.vtype = TYPE_FLOAT; + else + self->expression.vtype = left->expression.vtype; + return self; } @@ -373,7 +417,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); @@ -420,6 +464,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); @@ -546,8 +603,10 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir) } v = ir_builder_create_global(ir, self->name, self->expression.vtype); - if (!v) + if (!v) { + printf("ir_builder_create_global failed\n"); return false; + } if (self->isconst) { switch (self->expression.vtype) @@ -637,6 +696,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; @@ -646,12 +706,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; } } @@ -1326,6 +1387,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);