I'm trying to write simple rewriters with ppxlib to get an idea of how to do more complex things.
I'm currently struggling with metaquot. The documenation I found is this one but it just touches the surface and there's nothing in the .ml or .mli files that help understand the possibilities.
I'm trying to transform
let x = <expr>
into
let x =
let res = <expr> in
res
I dumped both ast:
[{pstr_desc =
Pstr_value (Nonrecursive,
[{pvb_pat = {ppat_desc = Ppat_var {txt = "x"}; ppat_loc_stack = []};
pvb_expr =
{pexp_desc = Pexp_constant (Pconst_integer ("23", None));
pexp_loc_stack = []}}])}]
and
[{pstr_desc =
Pstr_value (Nonrecursive,
[{pvb_pat = {ppat_desc = Ppat_var {txt = "x"}; ppat_loc_stack = []};
pvb_expr =
{pexp_desc =
Pexp_let (Nonrecursive,
[{pvb_pat =
{ppat_desc = Ppat_var {txt = "res"}; ppat_loc_stack = []};
pvb_expr =
{pexp_desc = Pexp_constant (Pconst_integer ("23", None));
pexp_loc_stack = []}}],
{pexp_desc = Pexp_ident {txt = Lident "res"}; pexp_loc_stack = []});
pexp_loc_stack = []}}])}]
So I need to transform a Pexp_constant ...
into a Pexp_let ...
I came up with this:
let wrap_with_fun_call expr loc _key =
let open Ppxlib.Ast_helper in
[%expr
[%e
Exp.let_ Nonrecursive
[
( Exp.ident
@@ { txt = Parse.longident (Lexing.from_string "res"); loc },
expr );
]
(Exp.ident @@ { txt = Parse.longident (Lexing.from_string "res"); loc })]]
But the first Exp.ident @@ ...
doesn't have the proper type and I'm stuck. I can't find anything in ppxlib that generates value_binding list
and can't find good examples on-line or documentation that would explain what the metaquot possibilities are (except the documentation I linked before)
Are there some good resources to understand better what's possible and how to do it?
There's surely an easy way to do what I want (as it is relatively simple) with metaquot but I couldn't find how.
So the answer was simply:
[%expr
let res = [%e expr] in
res]
What confused me is that I didn't write the in res
part and the error message was misleading (eval expected
)