From 99bab760064aebe3e2dd9e3ecaabc2ab125367e2 Mon Sep 17 00:00:00 2001 From: "Wolfgang (Blub) Bumiller" Date: Mon, 20 Aug 2012 18:09:41 +0200 Subject: [PATCH] Creating the ast_function for a function only when encountering its body, so if no body is specified it works like a function pointer - just like QC wants it --- data/vars.qc | 2 ++ parser.c | 54 +++++++++++++++++++++++++++++++++++----------------- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/data/vars.qc b/data/vars.qc index c652aeb..19ba392 100644 --- a/data/vars.qc +++ b/data/vars.qc @@ -8,6 +8,8 @@ string(float) ftos = #2; entity() spawn = #3; void(entity) kill = #4; +float multi, decla, ration; + .void(string x) printit; float(vector different_name, vector b) dot; diff --git a/parser.c b/parser.c index 79634bc..c768555 100644 --- a/parser.c +++ b/parser.c @@ -1857,7 +1857,6 @@ static bool create_vector_members(parser_t *parser, ast_value *var, static bool parser_variable(parser_t *parser, ast_block *localblock) { bool isfunc = false; - ast_function *func = NULL; lex_ctx ctx; ast_value *var; varentry_t varent; @@ -1883,7 +1882,6 @@ static bool parser_variable(parser_t *parser, ast_block *localblock) { hadproto = false; olddecl = NULL; - func = NULL; isparam = false; ctx = parser_ctx(parser); @@ -2006,11 +2004,9 @@ static bool parser_variable(parser_t *parser, ast_block *localblock) * as return type */ fval = ast_value_new(ctx, var->name, TYPE_FUNCTION); - func = ast_function_new(ctx, var->name, fval); - if (!fval || !func) { + if (!fval) { ast_value_delete(var); if (fval) ast_value_delete(fval); - if (func) ast_function_delete(func); return false; } @@ -2026,7 +2022,6 @@ static bool parser_variable(parser_t *parser, ast_block *localblock) parseerror(parser, "conflicting types for `%s`, previous declaration was here: %s:%i", proto->name, ast_ctx(proto).file, ast_ctx(proto).line); - ast_function_delete(func); ast_value_delete(fval); return false; } @@ -2037,20 +2032,10 @@ static bool parser_variable(parser_t *parser, ast_block *localblock) ast_ctx(proto) = ast_ctx(fval); /* now ditch the rest of the new data */ - ast_function_delete(func); ast_value_delete(fval); fval = proto; - func = proto->constval.vfunc; hadproto = true; } - else - { - if (!parser_t_functions_add(parser, func)) { - ast_function_delete(func); - ast_value_delete(fval); - return false; - } - } var = fval; } @@ -2138,12 +2123,14 @@ nextvar: } if (parser->tok == '#') { + ast_function *func; + if (localblock) { parseerror(parser, "cannot declare builtins within functions"); ast_value_delete(typevar); return false; } - if (!isfunc || !func) { + if (!isfunc) { parseerror(parser, "unexpected builtin number, '%s' is not a function", var->name); ast_value_delete(typevar); return false; @@ -2164,6 +2151,20 @@ nextvar: return false; } + func = ast_function_new(ast_ctx(var), var->name, var); + if (!func) { + parseerror(parser, "failed to allocate function for `%s`", var->name); + ast_value_delete(typevar); + return false; + } + if (!parser_t_functions_add(parser, func)) { + parseerror(parser, "failed to allocate slot for function `%s`", var->name); + ast_function_delete(func); + var->constval.vfunc = NULL; + ast_value_delete(typevar); + return false; + } + func->builtin = -parser_token(parser)->constval.i; if (!parser_next(parser)) { @@ -2172,6 +2173,7 @@ nextvar: } } else if (parser->tok == '{' || parser->tok == '[') { /* function body */ + ast_function *func; ast_function *old; ast_block *block; size_t parami; @@ -2406,6 +2408,24 @@ nextvar: } } + func = ast_function_new(ast_ctx(var), var->name, var); + if (!func) { + parseerror(parser, "failed to allocate function for `%s`", var->name); + ast_block_delete(block); + parser->function = old; + ast_value_delete(typevar); + return false; + } + if (!parser_t_functions_add(parser, func)) { + parseerror(parser, "failed to allocate slot for function `%s`", var->name); + ast_function_delete(func); + var->constval.vfunc = NULL; + ast_value_delete(typevar); + ast_block_delete(block); + parser->function = old; + return false; + } + parser->function = func; if (!parser_parse_block_into(parser, block, true)) { ast_block_delete(block);