Registering an attribute transformation
Is there a better way to register an attribute transformation than this?
I'm trying to port the @pass bit and I'm stumped!
let[@pass Scheme0 => SchemeNoLet (* Declare the type of the pass*)] remove_let =
[%passes (* Start writing the passes over each non-terminal. In this case, we only have [expr] *)
let[@entry] rec expr = function (* [@entry] means that the pass function will take an entry and recurse from there *)
| `Let (id, value [@r] (* [@r] = Recursively apply this pass *), body [@r]) -> (* Matches the Scheme0 let expression *)
`Apply (`Lambda (id, body), value) (* Must be a SchemeNoLet-compatible AST *)
]
Indeed, we don't have context free rules to rewrite nodes based on their attributes so yes, as of today, you'd have to register a whole AST transformation.
We don't encourage such syntax in ppx-es and usually prefer to use extension nodes to mark nodes that must be rewritten.
You'll probably be happy to hear about #574 though. This should add what you're looking if I understood it correctly. You can find some of our concerns with this approach in the review of the PR.
I suppose you're mostly trying to preserve a pre-existing syntax. Do you have a link to the project you're trying to port?
I was trying to port Nanocaml and succeeded by replacing attributes with extensions.
Then I gave up because the design needs a major rethink.
I don't think it needs to store the the OCaml module AST in a global hash table, for example. It should be able to just operate on the AST itself.
Ah right, it's a bit of special case, feel free to ignore my comment regarding syntax as that shouldn't be a concern for you.