Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file ppx_genprint.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234# 1 "ppx_genprint.cppo.ml"openPpxlibopenCaml(*
extract from compiler call, add to tuple argument to 'print', use to find the cmt file.
lid "include_dirs", make_list make_string !Clflags.include_dirs;
lid "load_path", make_list make_string (Load_path.get_paths ());
the cmt for current file with be stored alongside the object.
the load-path should be byte/native for dune.
difference with include-dirs? load-path includes 'include-dirs under 4.08
*)letenvar_setname=tryignore@@Sys.getenvname;truewith_->falseletremove_extensions=envar_set"GENPRINT_REMOVE"letcount=ref0letcwd=Sys.getcwd()letfullpathf=ifFilename.is_relativefthenFilename.concatcwdfelsefletgetwordsl=List.fold_left(funmsg(_,word)->matchword.pexp_descwith|Pexp_identid->letword'=Longident.nameid.txtin(word'^" "^msg)|Pexp_construct({txt=Lidentlid},_)->(lid^" "^msg)(* | Pexp_constant _-> *)|_->Location.raise_errorf~loc:word.pexp_loc"this should be a word")""lletset_loadpathlocopt=letloc=matchlocoptwith|None->Location.none|Someloc->locin(* should be setup from a ppx.context *)# 48 "ppx_genprint.cppo.ml"letlp=Ocaml_common.Load_path.get_paths()in# 50 "ppx_genprint.cppo.ml"letlp=List.mapfullpathlpinletexpl=[%expr[%eAst_builder.Default.((elist~loc(List.map(estring~loc)lp)))]]in[[%strilet__loadpath=[%eexpl]]],[](* put this value into every compiled unit once *)let()=Driver.register_transformation~enclose_impl:set_loadpath"genprint-loadpath"~extensions:[](* cache mode can be detected by examining data as loaded
(* used internally *)
val ppx_mode: bool ref
let set_ppxmode locopt =
let loc = match locopt with
| None-> Location.none
| Some loc->loc
in
[[%stri let _ = Genprint.ppx_mode:=true ]], []
(* put this value into every compiled unit once *)
let () =
Driver.register_transformation
~enclose_impl:set_ppxmode
"genprint-ppxmode" ~extensions:[]
*)letexpand~loc~path(e:expression)=incrcount;(*free-form text before the value including capitalisation *)letwords,e=matche.pexp_descwith|Pexp_apply(e,el)->beginmatchList.revelwith|[]->assertfalse(* would not be an apply without something *)|(_,v)::tl->(* the last arg is the expression to eval *)letmsg=getwords@@tl@[Nolabel,e]inmsg,vend|_->"",einifremove_extensionsthen[%exprlet_=[%ee]in()]else[%expr[%eAst_builder.Default.(pexp_apply~loc(pexp_apply~loc(pexp_ident~loc(Located.mk~loc(Longident.parse"Genprint.print")))[Nolabel,estring~locwords;Nolabel,pexp_tuple~loc[(eint~loc!count);(estring~loc@@Filename.basenamepath);(pexp_ident~loc(Located.mk~loc(Longident.parse"__loadpath")));]])[Nolabel,e])]]letgenprint=Extension.declare"pr"Extension.Context.expressionAst_pattern.(pstr((pstr_eval__nil)^::nil))expandlet()=Driver.register_transformation"genprint"~extensions:[genprint]letexpand~loc~path(payload:payload)=incrcount;(* let open Ast_builder.Default in *)letwords=matchpayloadwith|PStr[]->""|PStr[{pstr_desc=Pstr_eval(e,_)}]->beginmatche.pexp_descwith|Pexp_apply(e,el)->getwords@@(List.revel)@[Nolabel,e]|_->getwords[Nolabel,e]end|_->Location.raise_errorf~loc"improper syntax: empty or non-keyword word and Words"inifremove_extensionsthen[%exprfunx->x]else[%expr[%eAst_builder.Default.(pexp_apply~loc(pexp_ident~loc(Located.mk~loc(Longident.parse"Genprint.print_with_return")))[Nolabel,estring~locwords;Nolabel,pexp_tuple~loc[(eint~loc!count);(estring~loc@@Filename.basenamepath);(pexp_ident~loc(Located.mk~loc(Longident.parse"__loadpath")));]])]]letgenprint=Extension.declare"prr"Extension.Context.expression(* Ast_pattern.(pstr ((pstr_eval __ nil) ^:: nil)) *)Ast_pattern.(((__)))expandlet()=Driver.register_transformation"genprint-with-return"~extensions:[genprint](* custom printer installation *)letexpand~loc~path(fn:expression)=incrcount;ifremove_extensionsthen[%exprlet_=[%efn]in()]else[%expr[%eAst_builder.Default.(pexp_apply~loc(pexp_ident~loc(Located.mk~loc(Longident.parse"Genprint.install_printer")))[Nolabel,fn;Nolabel,pexp_tuple~loc[(eint~loc!count);(estring~loc@@Filename.basenamepath);(pexp_ident~loc(Located.mk~loc(Longident.parse"__loadpath")));]])]]letgenprint=Extension.declare"install_printer"Extension.Context.expressionAst_pattern.(pstr((pstr_eval__nil)^::nil))expandlet()=Driver.register_transformation"genprint-install-printer"~extensions:[genprint]letremove_printer~loc~path(fn:expression)=incrcount;ifremove_extensionsthen[%exprlet_=[%efn]in()]else[%expr[%eAst_builder.Default.(pexp_apply~loc(pexp_ident~loc(Located.mk~loc(Longident.parse"Genprint.remove_printer")))[Nolabel,fn;Nolabel,pexp_tuple~loc[(eint~loc!count);(estring~loc@@Filename.basenamepath);(pexp_ident~loc(Located.mk~loc(Longident.parse"__loadpath")));]])]]letgenprint=Extension.declare"remove_printer"Extension.Context.expressionAst_pattern.(pstr((pstr_eval__nil)^::nil))remove_printerlet()=Driver.register_transformation"genprint-remove-printer"~extensions:[genprint](*
let expand_ff ~loc ~path (lid : longident) (el : (arg_label * expression) list) =
...
let genprint_freeform =
Extension.declare
"prs"
Extension.Context.expression
(* pattern appearing in [%pr <sss> v] is the application of the ident to the value *)
Ast_pattern.(pstr ((pstr_eval (pexp_apply (pexp_ident __) ( __) ) nil ) ^:: nil))
expand_ff
*)