gmqcc icon indicating copy to clipboard operation
gmqcc copied to clipboard

AST Macros

Open graphitemaster opened this issue 12 years ago • 4 comments

They should work as functions, being inlined at compile time, with each argument simply being an ast itself. Is what I gather of implementing this cleanly. I like Perls quasi keyword, but I don't like how it attempts to do it. Let me suggest an example of how this could work.

macro loop (n) // note no actual "type" on arguments
{
   /// {{{ ... }}} like perl
   for (float i = 0; i < {{{n}}}; i++) {
      {{{body}}}
   }
}

void foo() {
    loop(100) {
        // do stuff
    }
}

the {{{}}} are just expansions (via copy) from the AST's end. There are some implicit ones we can generate from them, like {{{body}}}, which would be the body added around the invocation of loop itself (so that the loop gets the body). The reason we need these sorts of predefined ASTs is because making loop work with the body as an argument, i.e:

macro loop(n,b) { for(float i = 0; i < {{{n}}}; i++) {{{b}}} }

would require loop to be used as:

loop(100, {/* code */})

Which looks very terrible.

graphitemaster avatar Nov 27 '12 15:11 graphitemaster

Might be good do note that when they are AST macros and you don't actually use a {{{body}}} in there, then the following will NOT work:

macro for_stuff(n) { for (float i = 0; i < n; ++i) }
// used as
for_stuff(5) {
    print("Foo\n");
}

because parsing the macro definition itself will give you a parse error about a missing body for the for loop in it.

The nice part about ast macros is that a lot of checking (specifically syntax within the macro definition) will happen while parsing the macro definition, so if there's a syntax error it'll be shown in there. While with the preprocessor macros you'll end up getting an error at each use of the macro, and with huge macros it's hard to find the actual point of failure. Plus, there'll be syntax checking at the macro's use for the actual parameters directly.

It may be good to have the possibility to request a specific type in a macro parameter though. So that for instance the macro can create a counter variable accessible in the body by taking a variable-name as parameter. Note that in the above macro, the i will not be accessible if we have hygienic macros!

Blub avatar Nov 28 '12 11:11 Blub

Implementation wise we'd need to add copy-ctors to ast nodes. Which are also required for inlining. So I'm referencing #35 here.

Blub avatar Dec 01 '12 21:12 Blub

I would also like AST macros to return values (e.g. by also adding a syntax like gcc's ({ ... }) construct.

Furthermore, I would really also like a replacement for #ifdef

divVerent avatar Feb 10 '13 17:02 divVerent

Will this work? If yes, why is x in the right scope? If no, why not?

macro do { {{{body}}} }
do { float x; }
do { float foo() { return x; } }

Or would it be better to have a second simple CPP mode that only supports argumentless #define/#undef and #ifdef/#else/#endif?

divVerent avatar Feb 10 '13 18:02 divVerent