TADS3 macro gymnastics: accessing variadic arguments by number

T3’s preprocessor allows you to define variadic macros, but is there any way to refer to individual arguments (beyond iterating through them via #foreach)? For example:

#charset "us-ascii"
#include <adv3.h>
#include <en_us.h>

#define DefineFoozle(name, base, args...) \
        class name##Obj: ##base \
        someValue = toString(#@name) \
        test() { \
                aioSay('<<toString(someValue)>> defined with <<toString(args#ifnempty#args#argcount#args#ifempty#0#)>> args.\n '); \
                args#ifnempty#aioSay('second arg is <q>' + toString(args) + '</q>\n ');# \
        }


DefineFoozle(Foozle1, object);
DefineFoozle(Foozle2, object, 'extra1', 'extra2');

versionInfo: GameID;
gameMain: GameMainDef
        newGame() {
                local obj;

                obj = new Foozle1Obj();
                obj.test();
                obj = new Foozle2Obj();
                obj.test();
        }
;

Here we define a new macro DefineFoozle(name, base, args...). Then we can use DefineFoozle() with two or more arguments, with all the “extra” ones (beyond name and base) going into args. We can access the number of “extra” arguments with args#argcount and we can iterate over them via #foreach. But is there any way to reference the second element of args (assuming it exists)?

The line in the source above that says args#ifnempty#aioSay('second arg is <q>' + toString(args) + '</q>\n ');# lies—it never outputs the second argument. toString(args) does appear to consistently produce the first argument (although that behavior doesn’t appear to be documented anywhere). Is there any way to do what that line claims to do?

1 Like

You’re beyond what I’ve twiddled with, here…