From: Wolfgang Bumiller Date: Fri, 18 Oct 2013 09:26:41 +0000 (+0200) Subject: replacing the current [[accumulate]] implementation: shorter and simpler, and also... X-Git-Tag: 0.3.5~1^2~10 X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=commitdiff_plain;h=8d5e7190261d2ed0f214ef175d8451df3dbd4dc8 replacing the current [[accumulate]] implementation: shorter and simpler, and also supports non-void return types --- diff --git a/ast.c b/ast.c index 21a29ea..dbd23f1 100644 --- 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 5d198e4..1dbfa72 100644 --- 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 fbb79f2..7d83720 100644 --- 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 507a231..3c236ea 100644 --- 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) diff --git a/parser.c b/parser.c index 82ce53b..c7257bb 100644 --- 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;