]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
replacing the current [[accumulate]] implementation: shorter and simpler, and also...
authorWolfgang Bumiller <wry.git@bumiller.com>
Fri, 18 Oct 2013 09:26:41 +0000 (11:26 +0200)
committerWolfgang Bumiller <wry.git@bumiller.com>
Fri, 18 Oct 2013 09:26:41 +0000 (11:26 +0200)
ast.c
ast.h
ir.c
ir.h
parser.c

diff --git a/ast.c b/ast.c
index 21a29ead5cf193a45616635a08f6aa7df7352c09..dbd23f14db04889f3e17a0b977db503aac5904dc 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -1213,9 +1213,6 @@ ast_function* ast_function_new(lex_ctx_t ctx, const char *name, ast_value *vtype
     self->fixedparams      = NULL;
     self->return_value     = NULL;
 
-    self->accumulate   = NULL;
-    self->accumulation = 0;
-
     return self;
 
 cleanup:
@@ -1873,16 +1870,6 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir)
         }
     }
 
-    /* generate the call for any accumulation */
-    if (self->accumulate) {
-        ast_call *call = ast_call_new(ast_ctx(self), (ast_expression*)self->accumulate->vtype);
-        for (i = 0; i < vec_size(ec->params); i++)
-            vec_push(call->params, (ast_expression*)ec->params[i]);
-        vec_push(vec_last(self->blocks)->exprs, (ast_expression*)call);
-
-        self->ir_func->flags |= IR_FLAG_ACCUMULATE;
-    }
-
     for (i = 0; i < vec_size(self->blocks); ++i) {
         cgen = self->blocks[i]->expression.codegen;
         if (!(*cgen)((ast_expression*)self->blocks[i], self, false, &dummy))
diff --git a/ast.h b/ast.h
index 5d198e4f92ea4659992e2e26fa219318b7b862eb..1dbfa72b53886c3b5257b7eb6751efbcd7a77318 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -617,10 +617,6 @@ struct ast_function_s
 
     int builtin;
 
-    /* function accumulation */
-    ast_function *accumulate;    /* pointer to the next function in the chain */
-    size_t        accumulation;  /* base functions # of accumulations         */
-
     ir_function *ir_func;
     ir_block    *curblock;
     ir_block    **breakblocks;
diff --git a/ir.c b/ir.c
index fbb79f2e6cd0e03005cb7c5167fe229279e485bc..7d83720c4d4afb3cd56ec90a08b9cc1ad7dde9d3 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -1586,10 +1586,6 @@ bool ir_block_create_return(ir_block *self, lex_ctx_t ctx, ir_value *v)
 
     self->final = true;
 
-    /* can eliminate the return instructions for accumulation */
-    if (self->owner->flags & IR_FLAG_ACCUMULATE)
-        return true;
-
     self->is_return = true;
     in = ir_instr_new(ctx, self, INSTR_RETURN);
     if (!in)
diff --git a/ir.h b/ir.h
index 507a2317e461c6251d39656cb8101ff25d0a4b49..3c236ea7f12e83200656afd82697abd08946d69e 100644 (file)
--- a/ir.h
+++ b/ir.h
@@ -232,7 +232,6 @@ typedef struct ir_function_s
 #define IR_FLAG_HAS_GOTO          (1<<3)
 #define IR_FLAG_INCLUDE_DEF       (1<<4)
 #define IR_FLAG_ERASEABLE         (1<<5)
-#define IR_FLAG_ACCUMULATE        (1<<6)
 #define IR_FLAG_MASK_NO_OVERLAP     (IR_FLAG_HAS_ARRAYS | IR_FLAG_HAS_UNINITIALIZED)
 #define IR_FLAG_MASK_NO_LOCAL_TEMPS (IR_FLAG_HAS_ARRAYS | IR_FLAG_HAS_UNINITIALIZED)
 
index 82ce53b0a47a84deeb0b422fc32c1558c8412681..c7257bb9281b52ee75b0670fe21b84f901e5df41 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -3984,59 +3984,28 @@ static bool parse_function_body(parser_t *parser, ast_value *var)
         }
     }
 
-    if (var->hasvalue && !(var->expression.flags & AST_FLAG_ACCUMULATE)) {
-        parseerror(parser, "function `%s` declared with multiple bodies", var->name);
-        ast_block_delete(block);
-        goto enderr;
-    }
-
-    /* accumulation? */
-    if (var->hasvalue && var->expression.vtype == TYPE_FUNCTION) {
-        ast_value    *accum    = NULL;
-        ast_function *previous = NULL;
-        char          acname[1024];
-
-        /* only void please */
-        if (var->expression.next->vtype != TYPE_VOID) {
-            parseerror(parser, "accumulated function `%s` declared with return type `%s` (accumulated functions must return void)",
-                var->name,
-                type_name[var->expression.next->vtype]
-            );
+    if (var->hasvalue) {
+        if (!(var->expression.flags & AST_FLAG_ACCUMULATE)) {
+            parseerror(parser, "function `%s` declared with multiple bodies", var->name);
             ast_block_delete(block);
             goto enderr;
         }
+        func = var->constval.vfunc;
 
-        /* generate a new name increasing the accumulation count*/
-        util_snprintf(acname, sizeof(acname), "##ACCUMULATE_%s_%d", var->name, var->constval.vfunc->accumulation++);
-        accum = ast_value_new(parser_ctx(parser), acname, ((ast_expression*)var)->vtype);
-        if (!accum)
-            return false;
-
-        ast_type_adopt(accum, var);
-        func = ast_function_new(ast_ctx(var), NULL, accum);
-        if (!func)
-            return false;
-
-        parser_addglobal(parser, acname, (ast_expression*)accum);
-        vec_push(parser->functions, func);
-
-        /* update the previous calls accumulate pointer for the codegen */
-        previous = var->constval.vfunc;
-        while (previous->accumulate)
-            previous = previous->accumulate;
-
-        if (ast_istype(previous, ast_function))
-            previous->accumulate = func;
-
+        if (!func) {
+            parseerror(parser, "internal error: NULL function: `%s`", var->name);
+            ast_block_delete(block);
+            goto enderr;
+        }
     } else {
         func = ast_function_new(ast_ctx(var), var->name, var);
-        vec_push(parser->functions, func);
-    }
 
-    if (!func) {
-        parseerror(parser, "failed to allocate function for `%s`", var->name);
-        ast_block_delete(block);
-        goto enderr;
+        if (!func) {
+            parseerror(parser, "failed to allocate function for `%s`", var->name);
+            ast_block_delete(block);
+            goto enderr;
+        }
+        vec_push(parser->functions, func);
     }
 
     parser_enterblock(parser);
@@ -4064,13 +4033,13 @@ static bool parse_function_body(parser_t *parser, ast_value *var)
         }
     }
 
-    if (var->argcounter) {
+    if (var->argcounter && !func->argc) {
         ast_value *argc = ast_value_new(ast_ctx(var), var->argcounter, TYPE_FLOAT);
         parser_addlocal(parser, argc->name, (ast_expression*)argc);
         func->argc = argc;
     }
 
-    if (OPTS_FLAG(VARIADIC_ARGS) && var->expression.flags & AST_FLAG_VARIADIC) {
+    if (OPTS_FLAG(VARIADIC_ARGS) && var->expression.flags & AST_FLAG_VARIADIC && !func->varargs) {
         char name[1024];
         ast_value *varargs = ast_value_new(ast_ctx(var), "reserved:va_args", TYPE_ARRAY);
         varargs->expression.flags |= AST_FLAG_IS_VARARG;
@@ -4100,7 +4069,6 @@ static bool parse_function_body(parser_t *parser, ast_value *var)
 
     vec_push(func->blocks, block);
 
-
     parser->function = old;
     if (!parser_leaveblock(parser))
         retval = false;