Normal Erlang attributes can be modified by parse tranformations. This does not apply to the "-define" attributes, as they are handled by the preprocessor. What would you do if you would like to alter the value of all macros without changing the file itself?
Ideally I want to call some modified version of the compiler which would have the following effect:
When run with input...
...
-define(constant, 45).
-define(debug(X), io:format(X)).
...
?debug(?constant) % Line: 7
...
.. and a parameter ...
something:external
the result would be some abstract form which instead of...
{call,7,
{remote,7,{atom,7,io},{atom,7,format}},
[{integer,7,45}]}
... would have:
{call,7,
{remote,7,{atom,7,something},{atom,7,external}},
[{call,7,
{remote,7,{atom,7,something},{atom,7,external}},
[]}]}
Of course the resulting code would probably not be executable, but could enable some 'quality' analysis on the usage of macros.
A syntax tree with preprocessor macros included can not be provided by the normal compiler. As you have noted macros are expanded by the preprocessor before the source is fed to the parser.
There is a way to get a pseudo-parse-tree (the normal parse tree returned by erl_parse can't represent macros): Use the module epp_dodger
epp_dodger - bypasses the Erlang preprocessor.
This module tokenises and parses most Erlang source code without expanding preprocessor directives and macro applications, as long as these are syntactically "well-behaved". Because the normal parse trees of the erl_parse module cannot represent these things (normally, they are expanded by the Erlang preprocessor epp(3) before the parser sees them), an extended syntax tree is created, using the erl_syntax module.
However this can't be integrated in a parse transform.
But you can peruse the syntax trees as you like and feed the result to the compiler if you need this. For just reasoning about the code the parse-tree and Erlang Syntax Tools are all you need.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With