X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=ast.c;h=0f5b05ca4a98383e22e61f4989c451ce94e353e5;hb=6dfdf69a8e96ea2f5f5e6f89bbe8fd6262268846;hp=995ba094efa04432e655135b489e7e61fb3b7148;hpb=6df3c625b0f8501b2ed2ecc61e29d104f28f84b8;p=xonotic%2Fgmqcc.git diff --git a/ast.c b/ast.c index 995ba09..0f5b05c 100644 --- a/ast.c +++ b/ast.c @@ -75,6 +75,7 @@ static void ast_expression_init(ast_expression *self, self->expression.params = NULL; self->expression.count = 0; self->expression.flags = 0; + self->expression.varparam = NULL; } static void ast_expression_delete(ast_expression *self) @@ -347,6 +348,8 @@ ast_value* ast_value_new(lex_ctx ctx, const char *name, int t) self->getter = NULL; self->desc = NULL; + self->argcounter = NULL; + return self; } @@ -354,6 +357,8 @@ void ast_value_delete(ast_value* self) { if (self->name) mem_d((void*)self->name); + if (self->argcounter) + mem_d((void*)self->argcounter); if (self->hasvalue) { switch (self->expression.vtype) { @@ -913,6 +918,8 @@ void ast_call_delete(ast_call *self) bool ast_call_check_types(ast_call *self) { + char texp[1024]; + char tgot[1024]; size_t i; bool retval = true; const ast_expression *func = self->func; @@ -923,8 +930,6 @@ bool ast_call_check_types(ast_call *self) for (i = 0; i < count; ++i) { if (!ast_compare_type(self->params[i], (ast_expression*)(func->expression.params[i]))) { - char texp[1024]; - char tgot[1024]; ast_type_to_string(self->params[i], tgot, sizeof(tgot)); ast_type_to_string((ast_expression*)func->expression.params[i], texp, sizeof(texp)); compile_error(ast_ctx(self), "invalid type for parameter %u in function call: expected %s, got %s", @@ -933,6 +938,20 @@ bool ast_call_check_types(ast_call *self) retval = false; } } + count = vec_size(self->params); + if (count > vec_size(func->expression.params) && func->expression.varparam) { + for (; i < count; ++i) { + if (!ast_compare_type(self->params[i], func->expression.varparam)) + { + ast_type_to_string(self->params[i], tgot, sizeof(tgot)); + ast_type_to_string(func->expression.varparam, texp, sizeof(texp)); + compile_error(ast_ctx(self), "invalid type for parameter %u in function call: expected %s, got %s", + (unsigned int)(i+1), texp, tgot); + /* we don't immediately return */ + retval = false; + } + } + } return retval; } @@ -1055,6 +1074,8 @@ ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype) vtype->hasvalue = true; vtype->constval.vfunc = self; + self->varargs = NULL; + return self; } @@ -1077,6 +1098,8 @@ void ast_function_delete(ast_function *self) vec_free(self->blocks); vec_free(self->breakblocks); vec_free(self->continueblocks); + if (self->varargs) + ast_delete(self->varargs); mem_d(self); } @@ -1386,7 +1409,7 @@ bool ast_local_codegen(ast_value *self, ir_function *func, bool param) func->flags |= IR_FLAG_HAS_ARRAYS; - if (param) { + if (param && !(self->expression.flags & AST_FLAG_IS_VARARG)) { compile_error(ast_ctx(self), "array-parameters are not supported"); return false; } @@ -1552,6 +1575,11 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) } } + if (self->varargs) { + if (!ast_local_codegen(self->varargs, self->ir_func, true)) + return false; + } + if (self->builtin) { irf->builtin = self->builtin; return true;