From 19b66800aef1013f3d2dfad2358c632bdf3df3a7 Mon Sep 17 00:00:00 2001 From: "Wolfgang (Blub) Bumiller" Date: Tue, 21 Aug 2012 16:01:28 +0200 Subject: [PATCH] TYPE_FUNCTION values which are not constant are now allowed to be generated, they are function pointers. --- data/functions.qc | 10 ++++++++++ ir.c | 11 ++++++++--- parser.c | 17 ++++++++++++++--- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/data/functions.qc b/data/functions.qc index 7e479c1..bf12f1d 100644 --- a/data/functions.qc +++ b/data/functions.qc @@ -15,6 +15,14 @@ float(entity targ) visible = { return targ.vis; }; +void() printworking = { + print("Working\n"); +}; + +void(void() callback) testcallback = { + callback(); +}; + void() main = { local entity pawn, pawn2; @@ -26,4 +34,6 @@ void() main = { if (!visible(pawn.other)) print("Yes\n"); + + testcallback(printworking); }; diff --git a/ir.c b/ir.c index 28a81f9..01e297f 100644 --- a/ir.c +++ b/ir.c @@ -2718,9 +2718,14 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global) case TYPE_FUNCTION: if (code_defs_add(def) < 0) return false; - ir_value_code_setaddr(global, code_globals_elements); - code_globals_add(code_functions_elements); - return gen_global_function(self, global); + if (!global->isconst) { + ir_value_code_setaddr(global, code_globals_add(0)); + return global->code.globaladdr >= 0; + } else { + ir_value_code_setaddr(global, code_globals_elements); + code_globals_add(code_functions_elements); + return gen_global_function(self, global); + } case TYPE_VARIANT: /* assume biggest type */ ir_value_code_setaddr(global, code_globals_add(0)); diff --git a/parser.c b/parser.c index ea1e24d..9db84bb 100644 --- a/parser.c +++ b/parser.c @@ -317,7 +317,7 @@ static ast_value *parser_parse_type(parser_t *parser, int basetype, bool *isfunc ast_value *param; ast_value *fld; bool isfield = false; - bool dummy; + bool isfuncparam = false; if (!parser_next(parser)) goto on_error; @@ -337,8 +337,7 @@ static ast_value *parser_parse_type(parser_t *parser, int basetype, bool *isfunc if (!parser_next(parser)) goto on_error; - param = parser_parse_type(parser, temptype, &dummy); - (void)dummy; + param = parser_parse_type(parser, temptype, &isfuncparam); if (!param) goto on_error; @@ -351,6 +350,18 @@ static ast_value *parser_parse_type(parser_t *parser, int basetype, bool *isfunc goto on_error; } + /* This comes before the isfield part! */ + if (isfuncparam) { + ast_value *fval = ast_value_new(ast_ctx(param), param->name, TYPE_FUNCTION); + if (!fval) { + ast_delete(param); + goto on_error; + } + fval->expression.next = (ast_expression*)param; + MEM_VECTOR_MOVE(¶m->expression, params, &fval->expression, params); + param = fval; + } + if (isfield) { fld = ast_value_new(ctx, param->name, TYPE_FIELD); fld->expression.next = (ast_expression*)param; -- 2.39.2