From: Wolfgang (Blub) Bumiller Date: Fri, 30 Nov 2012 20:03:57 +0000 (+0100) Subject: remember if an ast_value is a field-declaration, build fields before globals X-Git-Tag: 0.1.9~159 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=316298650e21c2f81c04e1124ef2943306386ae5;p=xonotic%2Fgmqcc.git remember if an ast_value is a field-declaration, build fields before globals --- diff --git a/ast.c b/ast.c index 9ad45fa..d797fc1 100644 --- a/ast.c +++ b/ast.c @@ -322,6 +322,7 @@ ast_value* ast_value_new(lex_ctx ctx, const char *name, int t) self->name = name ? util_strdup(name) : NULL; self->expression.vtype = t; self->expression.next = NULL; + self->isfield = false; self->cvq = CV_NONE; self->hasvalue = false; self->uses = 0; diff --git a/ast.h b/ast.h index acf00c0..a7fd7b8 100644 --- a/ast.h +++ b/ast.h @@ -159,7 +159,8 @@ struct ast_value_s ast_value *next; */ - bool cvq; /* const/var qualifier */ + bool cvq; /* const/var qualifier */ + bool isfield; /* this declares a field */ bool hasvalue; union { double vfloat; diff --git a/parser.c b/parser.c index 3c889b5..87a1514 100644 --- a/parser.c +++ b/parser.c @@ -3812,7 +3812,8 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield if (!localblock) { /* deal with global variables, fields, functions */ - if (!nofields && var->expression.vtype == TYPE_FIELD) { + if (!nofields && var->expression.vtype == TYPE_FIELD && parser->tok != '=') { + var->isfield = true; vec_push(parser->fields, (ast_expression*)var); util_htset(parser->htfields, var->name, var); if (isvector) { @@ -3900,7 +3901,10 @@ skipvar: if (parser->tok == ',') goto another; + /* if (!var || (!localblock && !nofields && basetype->expression.vtype == TYPE_FIELD)) { + */ + if (!var) { parseerror(parser, "missing comma or semicolon while parsing variables"); break; } @@ -4008,7 +4012,7 @@ skipvar: if (!localblock) { cval = (ast_value*)cexp; - if (!ast_istype(cval, ast_value) || !cval->hasvalue || cval->cvq != CV_CONST) + if (!ast_istype(cval, ast_value) || ((!cval->hasvalue || cval->cvq != CV_CONST) && !cval->isfield)) parseerror(parser, "cannot initialize a global constant variable with a non-constant expression"); else { @@ -4462,11 +4466,14 @@ bool parser_finish(const char *output) return false; } } - for (i = 0; i < vec_size(parser->globals); ++i) { + for (i = 0; i < vec_size(parser->fields); ++i) { ast_value *asvalue; - if (!ast_istype(parser->globals[i], ast_value)) + asvalue = (ast_value*)(parser->fields[i]->expression.next); + + if (!ast_istype((ast_expression*)asvalue, ast_value)) + continue; + if (asvalue->expression.vtype != TYPE_ARRAY) continue; - asvalue = (ast_value*)(parser->globals[i]); if (asvalue->setter) { if (!ast_global_codegen(asvalue->setter, ir, false) || !ast_function_codegen(asvalue->setter->constval.vfunc, ir) || @@ -4488,14 +4495,11 @@ bool parser_finish(const char *output) } } } - for (i = 0; i < vec_size(parser->fields); ++i) { + for (i = 0; i < vec_size(parser->globals); ++i) { ast_value *asvalue; - asvalue = (ast_value*)(parser->fields[i]->expression.next); - - if (!ast_istype((ast_expression*)asvalue, ast_value)) - continue; - if (asvalue->expression.vtype != TYPE_ARRAY) + if (!ast_istype(parser->globals[i], ast_value)) continue; + asvalue = (ast_value*)(parser->globals[i]); if (asvalue->setter) { if (!ast_global_codegen(asvalue->setter, ir, false) || !ast_function_codegen(asvalue->setter->constval.vfunc, ir) ||