From: Wolfgang (Blub) Bumiller Date: Sun, 11 Nov 2012 15:22:09 +0000 (+0100) Subject: Store accessors in the ast_value for access from within the ast - generate accessors... X-Git-Tag: 0.1~19^2~33 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=1ab303c52800bcc0027878c4acb40503780aa1e2;p=xonotic%2Fgmqcc.git Store accessors in the ast_value for access from within the ast - generate accessors after generating all the globals to not mess up the order of globals in the output --- diff --git a/ast.c b/ast.c index cd6662f..bba0aa5 100644 --- a/ast.c +++ b/ast.c @@ -327,6 +327,9 @@ ast_value* ast_value_new(lex_ctx ctx, const char *name, int t) self->ir_values = NULL; self->ir_value_count = 0; + self->setter = NULL; + self->getter = NULL; + return self; } @@ -918,7 +921,9 @@ bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_valu * on all the globals. */ if (!self->ir_v) { - asterror(ast_ctx(self), "ast_value used before generated (%s)", self->name); + char typename[1024]; + ast_type_to_string((ast_expression*)self, typename, sizeof(typename)); + asterror(ast_ctx(self), "ast_value used before generated %s %s", typename, self->name); return false; } *out = self->ir_v; @@ -928,6 +933,7 @@ bool ast_value_codegen(ast_value *self, ast_function *func, bool lvalue, ir_valu bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield) { ir_value *v = NULL; + if (self->isconst && self->expression.vtype == TYPE_FUNCTION) { ir_function *func = ir_builder_create_function(ir, self->name, self->expression.next->expression.vtype); diff --git a/ast.h b/ast.h index 6af3ad0..b46aee1 100644 --- a/ast.h +++ b/ast.h @@ -166,6 +166,10 @@ struct ast_value_s ir_value *ir_v; ir_value **ir_values; size_t ir_value_count; + + /* ONLY for arrays in progs version up to 6 */ + ast_value *setter; + ast_value *getter; }; ast_value* ast_value_new(lex_ctx ctx, const char *name, int qctype); diff --git a/parser.c b/parser.c index 534f810..7ce3374 100644 --- a/parser.c +++ b/parser.c @@ -2327,7 +2327,6 @@ static bool parser_create_array_setter(parser_t *parser, ast_value *array, const ast_value *fval = NULL; ast_block *body; ast_value *index, *value; - varentry_t entry; if (!ast_istype(array->expression.next, ast_value)) { parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type"); @@ -2389,14 +2388,7 @@ static bool parser_create_array_setter(parser_t *parser, ast_value *array, const if (!ast_function_blocks_add(func, body)) goto cleanup2; - entry.name = util_strdup(funcname); - entry.var = (ast_expression*)fval; - if (!parser_t_globals_add(parser, entry)) { - mem_d(entry.name); - goto cleanup2; - } - if (!parser_t_functions_add(parser, func)) - goto cleanup2; + array->setter = fval; return true; cleanup: @@ -2417,7 +2409,6 @@ static bool parser_create_array_getter(parser_t *parser, ast_value *array, const ast_value *fval = NULL; ast_block *body; ast_value *index; - varentry_t entry; if (!ast_istype(array->expression.next, ast_value)) { parseerror(parser, "internal error: array accessor needs to build an ast_value with a copy of the element type"); @@ -2471,14 +2462,7 @@ static bool parser_create_array_getter(parser_t *parser, ast_value *array, const if (!ast_function_blocks_add(func, body)) goto cleanup2; - entry.name = util_strdup(funcname); - entry.var = (ast_expression*)fval; - if (!parser_t_globals_add(parser, entry)) { - mem_d(entry.name); - goto cleanup2; - } - if (!parser_t_functions_add(parser, func)) - goto cleanup2; + array->getter = fval; return true; cleanup: @@ -3545,6 +3529,30 @@ bool parser_finish(const char *output) return false; } } + for (i = 0; i < parser->globals_count; ++i) { + ast_value *asvalue; + if (!ast_istype(parser->globals[i].var, ast_value)) + continue; + asvalue = (ast_value*)(parser->globals[i].var); + if (asvalue->setter) { + if (!ast_global_codegen(asvalue->setter, ir, false) || + !ast_function_codegen(asvalue->setter->constval.vfunc, ir)) + { + printf("failed to generate setter for %s\n", parser->globals[i].name); + ir_builder_delete(ir); + return false; + } + } + if (asvalue->getter) { + if (!ast_global_codegen(asvalue->getter, ir, false) || + !ast_function_codegen(asvalue->getter->constval.vfunc, ir)) + { + printf("failed to generate getter for %s\n", parser->globals[i].name); + ir_builder_delete(ir); + return false; + } + } + } for (i = 0; i < parser->functions_count; ++i) { if (!ast_function_codegen(parser->functions[i], ir)) { printf("failed to generate function %s\n", parser->functions[i]->name);