Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file ppx_fun.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124(*
The following code was extracted and adapted from ppx_fun
- Original source: https://github.com/little-arhat/ppx_fun
ppx_fun did not install under OCaml5. Ppx_core (which was deprecated) has been
replaced with Ppxlib, and some code could be simplified in the process.
*)openStdLabelsopenPpxlibopenPpxlib.Ast_builder.Default[@@@metalocloc]typeplaceholder=|Anonymous|Numberedofinttypecontext={used:intlist;highest:placeholderoption;}letparse_placeholders=ifs="__"thenSomeAnonymouselse(trySome(Scanf.sscanfs"_%d"(funi->Numberedi))with|Scanf.Scan_failure_->None);;letset_addlel=ifList.memel~set:lthenlelseel::lletfold_downto~init~fstartfinish=letrecauxcountercurrent=ifcounter<finishthencurrentelseaux(counter-1)(fcurrentcounter)inifstart<finishthenraise(Invalid_argument"start cannot be less then finish!")elseauxstartinit;;letreplace_and_count_placeholdersprefix=object(_self)inherit[context]Ast_traverse.fold_mapassupermethod!expressioneacc=lete',acc'=super#expressioneaccinmatche'.pexp_descwith|Pexp_ident{txt=Longident.Lidents;loc}->letmaybe_placeholder=parse_placeholdersin(matchmaybe_placeholder,acc'with|SomeAnonymous,{highest=SomeAnonymous;_}->evar~locprefix,acc'|SomeAnonymous,{highest=None;_}->evar~locprefix,{acc'withhighest=SomeAnonymous}|SomeAnonymous,{highest=Some(Numbered_);_}->Location.raise_errorf~loc"ppx_fun: can't use anonymous and numbered placeholders in the same \
expression!"|Some(Numbered_),{highest=SomeAnonymous;_}->Location.raise_errorf~loc"ppx_fun: can't use anonymous and numbered placeholders in the same \
expression!"|Some(Numberedcurrent),{highest=Some(Numberedhighest);used}->letname=prefix^string_of_intcurrentinlete=evar~locnameinletnew_highest=ifcurrent>highestthenNumberedcurrentelseNumberedhighestine,{used=set_addusedcurrent;highest=Somenew_highest}|Some(Numberedcurrent),{used;_}->letname=prefix^string_of_intcurrentinlete=evar~locnameine,{used=set_addusedcurrent;highest=Some(Numberedcurrent)}|None,_->e',acc')|_->e',acc'end;;letreplace_and_count_placeholders_in_exprprefixexpr=letmapper=replace_and_count_placeholdersprefixinletinit={used=[];highest=None}inmapper#expressionexprinit;;letppx_fun_expander_args~loc(expr:Parsetree.expression)=letline=loc.Location.loc_start.Lexing.pos_lnuminletprefix=Printf.sprintf"l_%d_v"lineinletinner,context=replace_and_count_placeholders_in_exprprefixexprinmatchcontext.highestwith|None->[%exprfun()->[%einner]]|SomeAnonymous->letpat=pvar~locprefixin[%exprfun[%ppat]->[%einner]]|Some(Numberedhighest)->fold_downtohighest1~init:inner~f:(funexpnum->letname=prefix^string_of_intnuminletname'=ifList.memnum~set:context.usedthennameelse"_"^nameinletpat=pvar~locname'in[%exprfun[%ppat]->[%eexp]]);;letppx_fun_expander_drop~loc(expr:Parsetree.expression)=[%exprfun_->[%eexpr]]let[@warning"-27"]extension_drop=Extension.declare"f_"Extension.Context.expressionAst_pattern.(single_expr_payload__)(fun~loc~pathe->e|>ppx_fun_expander_drop~loc);;let[@warning"-27"]extension_arg=Extension.declare"f"Extension.Context.expressionAst_pattern.(single_expr_payload__)(fun~loc~pathe->e|>ppx_fun_expander_args~loc);;letrule1=Context_free.Rule.extensionextension_argletrule2=Context_free.Rule.extensionextension_droplet()=Driver.register_transformation~rules:[rule1;rule2]"ppx_fun"