Couple of weeks ago I've put Parrot's jit prototype on hold. One of the major issue was C macro preprocessor. Now, it's time to unhold it
Problems with C macro preprocessor
There is quite few problems with processing of C macros. All of them are based on “source level” preprocessing. And, in theory, C macros can change semantic of program very dramatically. For example ,code>foo(bar, baz) can be expanded to something awful like
(bar*)baz->blerg->foo(thingy, baz). In this case we change semantic of
barfrom being “function argument“ to “type”,
foofrom “function name” to “struct field”.
And it's not “out of thin air” example. All VTABLE access wrapped in such macros. E.g.
VTABLE_get_bool(interp, pmc)expanded as
pmc->vtable->get_bool(interp, pmc). And we have quite few such macros in our codebase. As you can see we derive “get_bool” from “VTABLE_get_bool”. And added intermediate step to access “vtable” attribute of “pmc”.
There are more of such “interesting” things with C macros. “String concatenations” is another beautiful example. Etc, etc, etc. I don't blame C for it. For many-many years “source filters” serve same purpose in Perl. And now using of “source filters” is highly discouraged in Perl.
Devel::Declarechanged the landscape totally.
In previous episode of our “soap opera” I stuck in parsing this macros. I was trying to change NQP's parsing on-fly to reparse and reprocess C macros. I was running in circles pushing for something like “recursive parsing of C source code within constraints of my understanding of NQP”. EPIC FAIL. And then I decided to choose simpler path.
Simple C macro processing
Preamble: Parrot's style guide is prohibit many-many “clever C hackerish tricks”. And based on this I switched from solving “Parsing C macros” problem in general to “Parsing macros used in parrot”. And this is actually helped a lot.
There is 2 big things about it. No. Not “big”, but “BIG”:
- Set of macros are mostly predefined.
- Most of them have “function semantic”. E.g.
VTABLE_foo()is parsed as function and I can handle macros in only one place.
YOU_NAME_IT. In this case macros should just produce different AST tree. There is the code for current “prototype-within-prototype”. In future I (or someone who is willing to beat me) will implement generating of this file from original macro definitions. But it's a good start.
Next time — type analyses.