The ultimate goal of your PPX project is to build a mapper of type Ast_mapper.mapper .
mapper is a large record type and contains mapping functions for Parsetree data Parsetree , for example
type mapper = { ... structure : mapper -> structure -> structure; signature : mapper -> signature -> signature; ... }
There is mapper Ast_mapper.default_mapper by default, and this is the starting point of your mapper: you can inherit it and override some of the record participants for your use. For a lens design, you must implement structure and signature :
let extend super = let structure self str = ... in let signature self str = ... in { super with structure; signature } let mapper = extend default_mapper
Your structure function should check the structure elements and add an appropriate value definition for each declaration of the record type. signature should do the same, but add the signatures of the lens functions:
let structure self str = List.concat (List.map (fun sitem -> match sitem.pstr_desc with | Pstr_type tds when tds_with_lenses sitem -> sitem :: sitems_for_your_lens_functions | _ -> [sitem]) str) in let signature self str = List.concat (List.map (fun sgitem -> match sgiitem.psig_desc with | Psig_type tds when tds_with_lenses sitem -> sgitem :: sgitems_for_your_lens_functions | _ -> [sgitem]) str) in
super and self are the same as OO: super is the initial screen that you are expanding, and self is the result of the extension. (Actually, for the first version of Ast_mapper , the class was used instead of the record type. If you prefer the OO style, you can use the Ast_mapper_class package Ast_mapper_class, which provides the same in the OO interface.) Anyway .. I’ll assume that in your case there isn’t need to use self or super arguments.
Once you have finished your own mapper, let Ast_mapper.apply start matching with input:
let () = let infile = .. in let outfile = .. in Ast_mapper.apply ~source:infile ~target:outfile mapper
More or less, all PPX rewrite implementations are similar to the ones above. Checking out a few small PPX implementations will surely help you understand.