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 lambda
s 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!