blackhole89 / macros

A more powerful C/C++ preprocessor.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Emitting top-level declarations

ChengCat opened this issue · comments

The feature of emitting top-level declarations would be useful. I am not sure whether this could be added into this library though, since this library only knows about token streams and balanced brackets.

As an example, this feature could be used to implement anonymous functions for C. See
https://github.com/eudoxia0/cmacro#lambda

There's a few slightly clumsy ways of getting approximately that functionality right now. The key problem is that it's hard to tell where the appropriate "top level" is situated. One way is to tell the preprocessor manually:

@global $counter (0)
@global $lambda_bodies @[] 

@define lambda {
    ( (@^$args) -> @^[{}]$type $body ) => (
        @set $counter (@calc($counter+1))
        @push_back $lambda_bodies (
            $type lam@@$counter ($args)
            $body
        )
        lam@@$counter 
    )   
}

@define top_level {
    ( @^$everything ) => (
        // the following forces evaluation of $everything.
        // maybe this should become a first-class @eval
        @set $everything ($everything) 
        @for($l : $lambda_bodies)($l)
        $everything
    )   
}

top_level;

void test()
{
    auto a = lambda (int a, int b) -> int { return a+b; };
    auto b = lambda (int c) -> int { return -c; };
}

Here, the top_level macro reads everything (the whole file) that follows it and processes it first, then emits the lambdas collected from it, then emits the processed rest of the file. Alternatively, you could follow something like the approach in the silly-reflection example on the playground page and try to redefine functions bodies themselves so that all lambdas in them are emitted before the function.

More importantly, I wasn't actually aware of cmacro; thanks of pointing me to it!

Wow, that's a clever way to do this. I didn't thought of it. Thanks!