Hello,
I am looking for PPX metaquot example to generate code to iterate over a dynamic number of lists. Assume this is the correct method.
This is the only example I see and if I set the loc it compiles but I haven’t executed it.
I modify it like this.
let list_gen ~ctxt =
let loc = Expansion_context.Deriver.derived_item_loc ctxt in
The logic I am trying to generate is similar to this.
element_of_A = function call to calculate someting
element_of_B = function call to calculate someting
…
upto ‘n’ lists followed by other logic.
So if there 2 lists there are two lines and 3 lines for 3 lists.
I have already setup dune and generate very simple functions(@@Deriving) but not list iteration code. It is basically working.
(preprocess
(pps ppxlib.metaquot ppx_deriving.show ppx_deriving.ord)))
Where can I find more such examples ? I’ve already looked at the tutorials.
Update : I think this example has nothing to do with list iteration.
Thanks.
I believe that ppx/pattern.ml · master · Thierry Martinez / pattern · GitLab has subset of functions which I managed to compile.
I have isolated these.
let mismatch ~loc pat : Ppxlib.expression =
[%expr
__mismatch_count_ref := index + 1;
let ident = Printf.sprintf "@%d" index in
let loc = Location.none in
Error {
common = Ppxlib.Ast_helper.Pat.var { loc; txt = ident };
mismatches = [{
ident;
expected = Parsetree.(
[%e (Ppxlib_metaquot.Expr.lift Location.none)#pattern pat]);
got = quoted; }]}]
let mismatch_here ~loc pat : Ppxlib.expression =
[%expr
let index = !__mismatch_count_ref in
[%e mismatch ~loc pat]]
let rec extract_pat_list (pat : Ppxlib.pattern) =
match pat with
| [%pat? []] -> []
| [%pat? [%p? hd] :: [%p? tl]] -> hd :: extract_pat_list tl
| _ -> raise Exit
let single_match ~loc make_matcher pat pattern quoted_pattern build_common
: string list * Ppxlib.expression =
let bindings, sub_matcher = make_matcher pat in
bindings, [%expr
match __value__ with
| [%p pattern] ->
begin
match
let (quoted : Ppxlib.expression option) =
match quoted with
| None -> None
| Some quoted ->
match Pattern_runtime.elim_type_constraints quoted with
| [%p quoted_pattern] ->
Some arg
| _ -> None in
let __value__ = sub in [%e sub_matcher] with
| Ok bindings -> Ok bindings
| Error error ->
Error {
common =
(let loc = Location.none in
[%e build_common]);
mismatches = error.mismatches }
end
| _ ->
[%e mismatch_here ~loc pat]]
These are not part of the OCaml libraries ?? Even though I haven’t used them fully they seem to be very helpful.
My current attempt without using these functions is this.
let function_generator ~ctxt _input _is_private =
let loc = Expansion_context.Deriver.derived_item_loc ctxt in
let expr = [%expr [1; 2; 3]] in
let pattern = [%pat? [%p ppat_var ~loc { txt = "Pattern_test"; loc }]] in
let match_expr =
[%expr
match [%e expr] with
| [%p pattern] -> [[%e evar ~loc "Pattern_test"]]
]
in
let value_binding = Ast_builder.Default.value_binding ~loc ~pat:pattern ~expr:match_expr in
let generated_code = [pstr_value ~loc Nonrecursive [value_binding]]
in
List.iter (fun item ->
Format.printf "Generated Code: %a@." Pprintast.structure_item item
) generated_code;
generated_code
let generator () = Deriving.Generator.V2.make (args ()) function_generator
let _ = Deriving.add "name" ~str_type_decl:(generator ())
Generated Code: let Pattern_test =
match [1; 2; 3] with | Pattern_test -> [Pattern_test]
I think no tutorial addresses this concern. It is a pity because the learning curve is steep.
Thanks.