]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - parser.c
Revert "Actually works now"
[xonotic/gmqcc.git] / parser.c
index eac983ee3b643259f3ffb92b482febae4ffea749..5b4ed658f96f5236ed04f7db1aed7d1a4dabd534 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -4917,32 +4917,44 @@ static ast_value *parse_arraysize(parser_t *parser, ast_value *var)
         return NULL;
     }
 
-    cexp = parse_expression_leave(parser, true, false, false);
+    if (parser->tok != ']') {
+        cexp = parse_expression_leave(parser, true, false, false);
 
-    if (!cexp || !ast_istype(cexp, ast_value)) {
-        if (cexp)
-            ast_unref(cexp);
-        ast_delete(var);
-        parseerror(parser, "expected array-size as constant positive integer");
-        return NULL;
+        if (!cexp || !ast_istype(cexp, ast_value)) {
+            if (cexp)
+                ast_unref(cexp);
+            ast_delete(var);
+            parseerror(parser, "expected array-size as constant positive integer");
+            return NULL;
+        }
+        cval = (ast_value*)cexp;
+    }
+    else {
+        cexp = NULL;
+        cval = NULL;
     }
-    cval = (ast_value*)cexp;
 
     tmp = ast_value_new(ctx, "<type[]>", TYPE_ARRAY);
     tmp->expression.next = (ast_expression*)var;
     var = tmp;
 
-    if (cval->expression.vtype == TYPE_INTEGER)
-        tmp->expression.count = cval->constval.vint;
-    else if (cval->expression.vtype == TYPE_FLOAT)
-        tmp->expression.count = cval->constval.vfloat;
-    else {
+    if (cval) {
+        if (cval->expression.vtype == TYPE_INTEGER)
+            tmp->expression.count = cval->constval.vint;
+        else if (cval->expression.vtype == TYPE_FLOAT)
+            tmp->expression.count = cval->constval.vfloat;
+        else {
+            ast_unref(cexp);
+            ast_delete(var);
+            parseerror(parser, "array-size must be a positive integer constant");
+            return NULL;
+        }
+
         ast_unref(cexp);
-        ast_delete(var);
-        parseerror(parser, "array-size must be a positive integer constant");
-        return NULL;
+    } else {
+        var->expression.count = -1;
+        var->expression.flags |= AST_FLAG_ARRAY_INIT;
     }
-    ast_unref(cexp);
 
     if (parser->tok != ']') {
         ast_delete(var);
@@ -5192,12 +5204,30 @@ static bool parser_check_qualifiers(parser_t *parser, const ast_value *var, cons
     return true;
 }
 
+static bool create_array_accessors(parser_t *parser, ast_value *var)
+{
+    char name[1024];
+    util_snprintf(name, sizeof(name), "%s##SET", var->name);
+    if (!parser_create_array_setter(parser, var, name))
+        return false;
+    util_snprintf(name, sizeof(name), "%s##GET", var->name);
+    if (!parser_create_array_getter(parser, var, var->expression.next, name))
+        return false;
+    return true;
+}
+
 static bool parse_array(parser_t *parser, ast_value *array)
 {
+    size_t i;
+    if (array->initlist) {
+        parseerror(parser, "array already initialized elsewhere");
+        return false;
+    }
     if (!parser_next(parser)) {
         parseerror(parser, "parse error in array initializer");
         return false;
     }
+    i = 0;
     while (parser->tok != '}') {
         ast_value *v = (ast_value*)parse_expression_leave(parser, true, false, false);
         if (!v)
@@ -5208,6 +5238,10 @@ static bool parse_array(parser_t *parser, ast_value *array)
             return false;
         }
         vec_push(array->initlist, v->constval);
+        if (v->expression.vtype == TYPE_STRING) {
+            array->initlist[i].vstring = util_strdupe(array->initlist[i].vstring);
+            ++i;
+        }
         ast_unref(v);
         if (parser->tok == '}')
             break;
@@ -5226,6 +5260,16 @@ static bool parse_array(parser_t *parser, ast_value *array)
         return false;
     }
     */
+
+    if (array->expression.flags & AST_FLAG_ARRAY_INIT) {
+        if (array->expression.count != (size_t)-1) {
+            parseerror(parser, "array `%s' has already been initialized with %u elements",
+                       array->name, (unsigned)array->expression.count);
+        }
+        array->expression.count = vec_size(array->initlist);
+        if (!create_array_accessors(parser, array))
+            return false;
+    }
     return true;
 }
 
@@ -5662,13 +5706,10 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
          * deal with arrays
          */
         if (var->expression.vtype == TYPE_ARRAY) {
-            char name[1024];
-            util_snprintf(name, sizeof(name), "%s##SET", var->name);
-            if (!parser_create_array_setter(parser, var, name))
-                goto cleanup;
-            util_snprintf(name, sizeof(name), "%s##GET", var->name);
-            if (!parser_create_array_getter(parser, var, var->expression.next, name))
-                goto cleanup;
+            if (var->expression.count != (size_t)-1) {
+                if (!create_array_accessors(parser, var))
+                    goto cleanup;
+            }
         }
         else if (!localblock && !nofields &&
                  var->expression.vtype == TYPE_FIELD &&
@@ -5841,6 +5882,7 @@ skipvar:
                 break;
             }
 
+            var->hasvalue = true;
             if (!parse_array(parser, var))
                 break;
         }