You’ve certainly sold me on the approach you’re using. Part of the reason that I’m asking these PPX questions is that, in the process of writing my own fairly complicated transformer, I’m trying to modularize in such a way as to offer the core facilities of the transformer as a library. I’d like that library to be forward compatible, so I’m trying to learn best practices.
With forward compatibility in mind: what kind of stability and support is there with pa_ppx_parsetree
? I’m sold on the idea of it, but I’m quite attuned to IDE support and I know that supporting a superlanguage’s syntax is a heavy burden in that regard.
That said, my question was more about the API for ppxlib.metaquot
: I can’t find any functions which allow me to construct an expression with attributes. That is, one can manually write something like
{ pexp_desc = Pexp_ident(Pexp_constant(Pconst_char('a')));
pexp_loc = loc;
pexp_loc_stack = [];
pexp_attributes = [
{ attr_name = Loc.make ~loc "b";
attr_payload = PStr([]);
attr_loc = loc;
}
];
}
which is fragile: if the expression
type gets modified at all, we’re in trouble. Of course, one might write the much more legible
[%expr 'a'[@b]]
but, as we’ve discussed, ppxlib.metaquot
has its limitations and this is one of them. So instead, I was opting for the documentation-suggested Ast_builder.Default
module which contains a series of constructor functions for expressions. For instance, one can write
Ast_builder.Default.pexp_ident ~loc (Loc.make ~loc "x")
to represent the variable x
or even just
echar 'a'
to represent the character constant 'a'
as an expression. This is all very useful, but I can’t find anything in the ppxlib.metaquot
documentation or library about how to create an expression with attributes attached (or how to pattern match on an expression’s attributes) without resorting to directly interacting with the record structures. For now, I’ve written
let pexp_with_attrs (attributes : attribute list) (expr : expression)
: expression =
{ expr with pexp_attributes = attributes }
;;
so I can just
pexp_with_attrs [b_attr] @@ echar 'a'
but again: that seemed clunky, so I thought I’d ask if I was doing this properly. I’d hate to burn a bunch of time writing terribly-styled code if I’d just missed a small detail.
Thanks again for the help and perspective!