static variables now don't get re-initialized in functions; cannot be initialized...
authorWolfgang Bumiller <wry.git@bumiller.com>
Thu, 28 Nov 2013 11:04:01 +0000 (12:04 +0100)
committerWolfgang Bumiller <wry.git@bumiller.com>
Thu, 28 Nov 2013 11:04:01 +0000 (12:04 +0100)
ast.c
ast.h
parser.c

diff --git a/ast.c b/ast.c
index 7b2da4d872fd578361c50af6ae6e231e4ea2a626..1644e243cc122626ca4ea9ba88f07be9c7490d92 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -1222,6 +1222,9 @@ ast_function* ast_function_new(lex_ctx_t ctx, const char *name, ast_value *vtype
     self->fixedparams      = NULL;
     self->return_value     = NULL;
 
+    self->static_names     = NULL;
+    self->static_count     = 0;
+
     return self;
 
 cleanup:
@@ -1243,6 +1246,9 @@ void ast_function_delete(ast_function *self)
          */
         ast_unref(self->vtype);
     }
+    for (i = 0; i < vec_size(self->static_names); ++i)
+        mem_d(self->static_names[i]);
+    vec_free(self->static_names);
     for (i = 0; i < vec_size(self->blocks); ++i)
         ast_delete(self->blocks[i]);
     vec_free(self->blocks);
diff --git a/ast.h b/ast.h
index 52858ac7f132ce14372fe7e92570593e11d2071f..26434138cb7feb1b12cffe1635596301329c4a10 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -625,6 +625,14 @@ struct ast_function_s
 
     int builtin;
 
+    /* list of used-up names for statics without the count suffix */
+    char       **static_names;
+    /* number of static variables, by convention this includes the
+     * ones without the count-suffix - remember this when dealing
+     * with savegames. uint instead of size_t as %zu in printf is
+     * C99, so no windows support. */
+    unsigned int static_count;
+
     ir_function *ir_func;
     ir_block    *curblock;
     ir_block    **breakblocks;
index c96f86212c2e99a631aa829acd4c2302fad98fb4..f3bfdfb6ff23e72b1fd674aaaab8e4ef96030472 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -5441,6 +5441,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
                      */
                     char   *defname = NULL;
                     size_t  prefix_len, ln;
+                    size_t  sn, sn_size;
 
                     ln = strlen(parser->function->name);
                     vec_append(defname, ln, parser->function->name);
@@ -5462,6 +5463,24 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
                     /* now rename the global */
                     ln = strlen(var->name);
                     vec_append(defname, ln, var->name);
+                    /* if a variable of that name already existed, add the
+                     * counter value.
+                     * The counter is incremented either way.
+                     */
+                    sn_size = vec_size(parser->function->static_names);
+                    for (sn = 0; sn != sn_size; ++sn) {
+                        if (strcmp(parser->function->static_names[sn], var->name) == 0)
+                            break;
+                    }
+                    if (sn != sn_size) {
+                        char *num = NULL;
+                        int   len = util_asprintf(&num, "#%u", parser->function->static_count);
+                        vec_append(defname, len, num);
+                        mem_d(num);
+                    }
+                    else
+                        vec_push(parser->function->static_names, util_strdup(var->name));
+                    parser->function->static_count++;
                     ast_value_set_name(var, defname);
 
                     /* push it to the to-be-generated globals */
@@ -5712,17 +5731,18 @@ skipvar:
             if (!cexp)
                 break;
 
-            if (!localblock) {
+            if (!localblock || is_static) {
                 cval = (ast_value*)cexp;
                 if (cval != parser->nil &&
                     (!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");
+                    parseerror(parser, "initializer is non constant");
                 }
                 else
                 {
-                    if (!OPTS_FLAG(INITIALIZED_NONCONSTANTS) &&
+                    if (!is_static &&
+                        !OPTS_FLAG(INITIALIZED_NONCONSTANTS) &&
                         qualifier != CV_VAR)
                     {
                         var->cvq = CV_CONST;