]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
TYPE_FUNCTION values which are not constant are now allowed to be generated, they...
authorWolfgang (Blub) Bumiller <blub@speed.at>
Tue, 21 Aug 2012 14:01:28 +0000 (16:01 +0200)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Tue, 21 Aug 2012 14:01:28 +0000 (16:01 +0200)
data/functions.qc
ir.c
parser.c

index 7e479c173d9d64cc8bcad992b76ed2e5fc608728..bf12f1dd43accf5b76ea3661b5c7f9c88eaad821 100644 (file)
@@ -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 28a81f9a435a222ad5a0963a418d6071682007e0..01e297ffbdebd1f0eb2641394e095129f981f555 100644 (file)
--- 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));
index ea1e24d310008d4dd5d2cdd643e11a681a10dd75..9db84bbc2de1ebd15d3b96fdf9982c914e3ca005 100644 (file)
--- 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(&param->expression, params, &fval->expression, params);
+                param = fval;
+            }
+
             if (isfield) {
                 fld = ast_value_new(ctx, param->name, TYPE_FIELD);
                 fld->expression.next = (ast_expression*)param;