From c69ba2c734edf1861ff457573a4dafd730da094c Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <blub@speed.at>
Date: Sat, 12 Jan 2013 11:29:03 +0100
Subject: [PATCH] parsing of vararg-counter

---
 ast.c    |  4 ++++
 ast.h    |  2 ++
 parser.c | 22 ++++++++++++++++++++--
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/ast.c b/ast.c
index f42a654..2f8a2bc 100644
--- a/ast.c
+++ b/ast.c
@@ -348,6 +348,8 @@ ast_value* ast_value_new(lex_ctx ctx, const char *name, int t)
     self->getter = NULL;
     self->desc   = NULL;
 
+    self->argcounter = NULL;
+
     return self;
 }
 
@@ -355,6 +357,8 @@ void ast_value_delete(ast_value* self)
 {
     if (self->name)
         mem_d((void*)self->name);
+    if (self->argcounter)
+        mem_d((void*)self->argcounter);
     if (self->hasvalue) {
         switch (self->expression.vtype)
         {
diff --git a/ast.h b/ast.h
index b93de57..b2c4aed 100644
--- a/ast.h
+++ b/ast.h
@@ -167,6 +167,8 @@ struct ast_value_s
     const char *name;
     const char *desc;
 
+    const char *argcounter;
+
     /*
     int         vtype;
     ast_value  *next;
diff --git a/parser.c b/parser.c
index 819c1e9..6c9b2fd 100644
--- a/parser.c
+++ b/parser.c
@@ -4292,6 +4292,7 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
     bool        first = true;
     bool        variadic = false;
     ast_value  *varparam = NULL;
+    char       *argcounter = NULL;
 
     ctx = parser_ctx(parser);
 
@@ -4321,10 +4322,17 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
         if (parser->tok == TOKEN_DOTS) {
             /* '...' indicates a varargs function */
             variadic = true;
-            if (!parser_next(parser) || parser->tok != ')') {
+            if (!parser_next(parser) || (parser->tok != ')' && parser->tok != TOKEN_IDENT)) {
                 parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
                 goto on_error;
             }
+            if (parser->tok == TOKEN_IDENT) {
+                argcounter = util_strdup(parser_tokval(parser));
+                if (!parser_next(parser) || parser->tok != ')') {
+                    parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
+                    goto on_error;
+                }
+            }
         }
         else
         {
@@ -4344,10 +4352,17 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
                 variadic = true;
                 varparam = vec_last(params);
                 vec_pop(params);
-                if (!parser_next(parser) || parser->tok != ')') {
+                if (!parser_next(parser) || (parser->tok != ')' && parser->tok != TOKEN_IDENT)) {
                     parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
                     goto on_error;
                 }
+                if (parser->tok == TOKEN_IDENT) {
+                    argcounter = util_strdup(parser_tokval(parser));
+                    if (!parser_next(parser) || parser->tok != ')') {
+                        parseerror(parser, "`...` must be the last parameter of a variadic function declaration");
+                        goto on_error;
+                    }
+                }
             }
         }
     }
@@ -4374,11 +4389,14 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
 
     var->expression.params   = params;
     var->expression.varparam = (ast_expression*)varparam;
+    var->argcounter          = argcounter;
     params = NULL;
 
     return var;
 
 on_error:
+    if (argcounter)
+        mem_d(argcounter);
     ast_delete(var);
     for (i = 0; i < vec_size(params); ++i)
         ast_delete(params[i]);
-- 
2.39.5