]> git.rm.cloudns.org Git - xonotic/gmqcc.git/commitdiff
remember if an ast_value is a field-declaration, build fields before globals
authorWolfgang (Blub) Bumiller <blub@speed.at>
Fri, 30 Nov 2012 20:03:57 +0000 (21:03 +0100)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Fri, 30 Nov 2012 20:03:57 +0000 (21:03 +0100)
ast.c
ast.h
parser.c

diff --git a/ast.c b/ast.c
index 9ad45fa7337b7891cb9d5534e6631f10883aa4ef..d797fc125c97a61436128d4d9d6b47a79a9af27d 100644 (file)
--- 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 acf00c0a5c1d5e596035f6a53baaf1033ebb75d7..a7fd7b8a7f1cf133969de4342de56faf5093c54c 100644 (file)
--- 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;
index 3c889b51ce7e5709716527a04fb1855ce7c7303e..87a15141a38fedc1880ce12ff0741265b3db70fd 100644 (file)
--- 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) ||