]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
parsing typenames completely now with function parameters
authorWolfgang Bumiller <wolfgang.linux@bumiller.com>
Thu, 19 Jul 2012 09:41:16 +0000 (11:41 +0200)
committerWolfgang Bumiller <wolfgang.linux@bumiller.com>
Thu, 19 Jul 2012 09:41:16 +0000 (11:41 +0200)
gmqcc.h
parser.c

diff --git a/gmqcc.h b/gmqcc.h
index e5d37af936063b7d5601c93791dc959c35119dd5..56c0ba4d0a09d13ea2cf1e364611ae041b36bb2a 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -717,6 +717,16 @@ void Tself##_##mem##_clear(Tself *self) \
     (owner)->mem##_alloc = 0;       \
 }
 
+#define MEM_VECTOR_MOVE(from, mem, to, tm)   \
+{                                            \
+    (to)->tm = (from)->mem;                  \
+    (to)->tm##_count = (from)->mem##_count;  \
+    (to)->tm##_alloc = (from)->mem##_alloc;  \
+    (from)->mem = NULL;                      \
+    (from)->mem##_count = 0;                 \
+    (from)->mem##_alloc = 0;                 \
+}
+
 #define MEM_VEC_FUNCTIONS(Tself, Twhat, mem) \
 _MEM_VEC_FUN_REMOVE(Tself, Twhat, mem)       \
 _MEM_VEC_FUN_ADD(Tself, Twhat, mem)
index bc43ea71fc10fe8f917ec58ee41b84b004b5f46c..f17e9dda73e4b8b452ba082f9f635cab7c8781b7 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -60,15 +60,73 @@ ast_value* parser_find_global(parser_t *parser, const char *name)
     return NULL;
 }
 
+typedef struct {
+    MEM_VECTOR_MAKE(ast_value*, p);
+} paramlist_t;
+MEM_VEC_FUNCTIONS(paramlist_t, ast_value*, p)
+
+ast_value *parser_parse_type(parser_t *parser)
+{
+    paramlist_t params;
+    ast_value *var;
+    lex_ctx   ctx = parser_ctx(parser);
+    int vtype = parser_token(parser)->constval.t;
+
+    MEM_VECTOR_INIT(&params, p);
+
+    if (!parser_next(parser))
+        return NULL;
+
+    if (parser->tok == '(') {
+        while (true) {
+            ast_value *param;
+
+            if (!parser_next(parser)) {
+                MEM_VECTOR_CLEAR(&params, p);
+                return NULL;
+            }
+
+            param = parser_parse_type(parser);
+            if (!param) {
+                MEM_VECTOR_CLEAR(&params, p);
+                return NULL;
+            }
+
+            if (!paramlist_t_p_add(&params, param)) {
+                MEM_VECTOR_CLEAR(&params, p);
+                parseerror(parser, "Out of memory while parsing typename");
+                return NULL;
+            }
+
+            if (parser->tok == ',')
+                continue;
+            if (parser->tok == ')')
+                break;
+            MEM_VECTOR_CLEAR(&params, p);
+            parseerror(parser, "Unexpected token");
+            return NULL;
+        }
+        if (!parser_next(parser)) {
+            MEM_VECTOR_CLEAR(&params, p);
+            return NULL;
+        }
+    }
+
+    var = ast_value_new(ctx, "<unnamed>", vtype);
+    if (!var) {
+        MEM_VECTOR_CLEAR(&params, p);
+        return NULL;
+    }
+    MEM_VECTOR_MOVE(&params, p, var, params);
+    return var;
+}
+
 bool parser_do(parser_t *parser)
 {
     if (parser->tok == TOKEN_TYPENAME)
     {
-        ast_value *var;
-        int       vtype = parser->lex->tok->constval.t;
-
-        /* Declaring a variable */
-        if (!parser_next(parser))
+        ast_value *var = parser_parse_type(parser);
+        if (!var)
             return false;
 
         if (parser->tok != TOKEN_IDENT) {
@@ -76,14 +134,18 @@ bool parser_do(parser_t *parser)
             return false;
         }
 
-        var = parser_find_global(parser, parser_tokval(parser));
-
-        if (var) {
+        if (parser_find_global(parser, parser_tokval(parser))) {
+            ast_value_delete(var);
             parseerror(parser, "global already exists: %s\n", parser_tokval(parser));
             return false;
         }
 
-        var = ast_value_new(parser_ctx(parser), parser_tokval(parser), vtype);
+        if (!ast_value_set_name(var, parser_tokval(parser))) {
+            parseerror(parser, "failed to set variable name\n");
+            ast_value_delete(var);
+            return false;
+        }
+
         if (!parser_t_globals_add(parser, var))
             return false;