]> git.rm.cloudns.org Git - xonotic/gmqcc.git/commitdiff
Implement subscripting for __VA_ARGS__, and added test-case. This only works on...
authorDale Weiler <killfieldengine@gmail.com>
Sun, 27 Jan 2013 12:55:56 +0000 (12:55 +0000)
committerDale Weiler <killfieldengine@gmail.com>
Sun, 27 Jan 2013 12:55:56 +0000 (12:55 +0000)
ftepp.c
lexer.h
tests/pp_va_args.qc
tests/pp_va_args.tmpl

diff --git a/ftepp.c b/ftepp.c
index e3e91e7ccdc72d887b409135cdca49d283dff64e..b2697579f36b9df869a60e8e6626d8df64947697 100644 (file)
--- a/ftepp.c
+++ b/ftepp.c
@@ -408,11 +408,48 @@ static bool ftepp_define_body(ftepp_t *ftepp, ppmacro *macro)
 {
     pptoken *ptok;
     while (ftepp->token != TOKEN_EOL && ftepp->token < TOKEN_EOF) {
-        if (macro->variadic && !strcmp(ftepp_tokval(ftepp), "__VA_ARGS__"))
-            ftepp->token = TOKEN_VA_ARGS;
-        ptok = pptoken_make(ftepp);
-        vec_push(macro->output, ptok);
-        ftepp_next(ftepp);
+        size_t index;
+        if (macro->variadic && !strcmp(ftepp_tokval(ftepp), "__VA_ARGS__")) {
+            /* remember the token */
+            if (ftepp_next(ftepp) == '#' &&
+                ftepp_next(ftepp) == '#' &&
+                ftepp_next(ftepp) == '[')
+            {
+                if (ftepp_next(ftepp) != TOKEN_INTCONST) {
+                    ftepp_error(ftepp, "expected index for __VA_ARGS__ subscript");
+                    return false;
+                }
+
+                index = atoi(ftepp_tokval(ftepp));
+
+                if (ftepp_next(ftepp) != ']') {
+                    ftepp_error(ftepp, "expected `]` in __VA_ARGS__ subscript");
+                    return false;
+                }
+
+                /*
+                 * mark it as an array to be handled later as such and not
+                 * as traditional __VA_ARGS__
+                 */
+                ftepp->token = TOKEN_VA_ARGS_ARRAY;
+                ptok = pptoken_make(ftepp);
+                ptok->constval.i = index;
+                vec_push(macro->output, ptok);
+                ftepp_next(ftepp);
+            } else {
+                int old = ftepp->token;
+                ftepp->token = TOKEN_VA_ARGS;
+                ptok = pptoken_make(ftepp);
+                vec_push(macro->output, ptok);
+                ftepp->token = old;
+            }
+        }
+        else
+        {
+            ptok = pptoken_make(ftepp);
+            vec_push(macro->output, ptok);
+            ftepp_next(ftepp);
+        }
     }
     /* recursive expansion can cause EOFs here */
     if (ftepp->token != TOKEN_EOL && ftepp->token != TOKEN_EOF) {
@@ -673,6 +710,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
                 }
                 if (!varargs)
                     break;
+
                 pi = 0;
                 ftepp_param_out(ftepp, &params[pi + vararg_start]);
                 for (++pi; pi < varargs; ++pi) {
@@ -680,6 +718,17 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
                     ftepp_param_out(ftepp, &params[pi + vararg_start]);
                 }
                 break;
+
+            case TOKEN_VA_ARGS_ARRAY:
+                if (out->constval.i >= varargs) {
+                    ftepp_error(ftepp, "subscript of `[%u]` is out of bounds for `__VA_ARGS__`", out->constval.i);
+                    vec_free(old_string);
+                    return false;
+                }
+
+                ftepp_param_out(ftepp, &params[out->constval.i + vararg_start]);
+                break;
+
             case TOKEN_IDENT:
             case TOKEN_TYPENAME:
             case TOKEN_KEYWORD:
diff --git a/lexer.h b/lexer.h
index 71ff198eed024b66c1932830d26148cd45e0d514..75fb83e9320fc159d432819c408b3abf339270c7 100644 (file)
--- a/lexer.h
+++ b/lexer.h
@@ -75,6 +75,7 @@ enum {
     TOKEN_ATTRIBUTE_CLOSE, /* ]] */
 
     TOKEN_VA_ARGS, /* for the ftepp only */
+    TOKEN_VA_ARGS_ARRAY, /* for the ftepp only */
 
     TOKEN_STRINGCONST, /* not the typename but an actual "string" */
     TOKEN_CHARCONST,
index f73372cd8af784d0f20c1381ed3950457bc6d6ec..f54533b80f2e237a5eb97121f7fde1e54784b2c0 100644 (file)
@@ -1,9 +1,12 @@
 void print(...) = #1;
 
 #define NOPARENS(...) __VA_ARGS__
-#define callem(func, args) func(NOPARENS args)
+#define callem(func, args) func NOPARENS(args)
+
+#define callen(func, ...) func __VA_ARGS__##[0]
 
 void main() {
     print(NOPARENS("hello ", "world\n"));
     callem(print, ("Yay", ", there\n"));
+    callen(print, ("Woah",", there\n"));
 }
index cf6ed161e89e40510d3c23cb5076a373f23e24b0..c6e0c14b53521cfc779a4b8389ea1a4962564f56 100644 (file)
@@ -4,3 +4,4 @@ T: -execute
 C: -std=fteqcc
 M: hello world
 M: Yay, there
+M: Woah, there