123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170open!Baseopen!PpxlibopenAst_builder.DefaultopenHelpersmoduleReference=structtypet={binds:value_bindinglistlist;ident:longident_loc;args:(arg_label*expression)list}letbindtbinds={twithbinds=binds::t.binds}letmaybe_apply{binds;ident;args}~locmaybe_arg=letident=pexp_ident~locidentinletargs=matchmaybe_argwith|None->args|Somearg->args@[Nolabel,arg]inletexpr=matchargswith|[]->ident|_->pexp_apply~locidentargsinwith_let~loc~bindsexpr;;letapplyt~locarg=maybe_applyt~loc(Somearg)letto_expressiont~loc=maybe_applyt~locNoneletto_value_expressiont~loc=matchtwith|{binds=[];ident;args=[]}->pexp_ident~locident|_->fresh_lambda~loc(fun~arg->applyt~locarg);;endmoduleLambda=structtypet={binds:value_bindinglistlist;cases:cases}letbindtbinds={twithbinds=binds::t.binds}(* generic case: use [function] or [match] *)letmaybe_apply_generic~loc~bindsmaybe_argcases=letexpr=matchmaybe_argwith|None->pexp_function~loccases|Somearg->pexp_match~locargcasesinwith_let~loc~bindsexpr;;(* zero cases: synthesize an "impossible" case, i.e. [| _ -> .] *)letmaybe_apply_impossible~loc~bindsmaybe_arg=maybe_apply_generic~loc~bindsmaybe_arg[case~lhs:(ppat_any~loc)~guard:None~rhs:(pexp_unreachable~loc)];;(* one case without guard: use [fun] or [let] *)letmaybe_apply_simple~loc~bindsmaybe_argpatbody=letexpr=matchmaybe_argwith|None->pexp_fun~locNolabelNonepatbody|Somearg->pexp_let~locNonrecursive[value_binding~loc~pat~expr:arg]bodyinwith_let~loc~bindsexpr;;(* shared special-casing logic for [apply] and [to_expression] *)letmaybe_applyt~locmaybe_arg=matchtwith|{binds;cases=[]}->maybe_apply_impossible~loc~bindsmaybe_arg|{binds;cases=[{pc_lhs;pc_guard=None;pc_rhs}]}->maybe_apply_simple~loc~bindsmaybe_argpc_lhspc_rhs|{binds;cases}->maybe_apply_generic~loc~bindsmaybe_argcases;;letapplyt~locarg=maybe_applyt~loc(Somearg)letto_expressiont~loc=maybe_applyt~locNoneletto_value_expressiont~loc=matchtwith|{binds=[];cases=_}->(* lambdas without [let] are already values *)letexpr=to_expressiont~locinassert(is_value_expressionexpr);expr|_->fresh_lambda~loc(fun~arg->applyt~locarg);;endtypet=|ReferenceofReference.t|LambdaofLambda.tletof_lambdacases=Lambda{binds=[];cases}letof_reference_exnexpr=matchexpr.pexp_descwith|Pexp_identident->Reference{binds=[];ident;args=[]}|Pexp_apply({pexp_desc=Pexp_identident;_},args)->Reference{binds=[];ident;args}|_->Location.raise_errorf~loc:expr.pexp_loc"ppx_sexp_conv: internal error.\n\
[Conversion.of_reference_exn] expected an identifier possibly applied to arguments.\n\
Instead, got:\n\
%s"(Pprintast.string_of_expressionexpr);;letto_expressiont~loc=matchtwith|Referencereference->Reference.to_expression~locreference|Lambdalambda->Lambda.to_expression~loclambda;;letto_value_expressiont~loc=matchtwith|Referencereference->Reference.to_value_expression~locreference|Lambdalambda->Lambda.to_value_expression~loclambda;;letapplyt~loce=matchtwith|Referencereference->Reference.apply~locreferencee|Lambdalambda->Lambda.apply~loclambdae;;letbindtbinds=matchtwith|Referencereference->Reference(Reference.bindreferencebinds)|Lambdalambda->Lambda(Lambda.bindlambdabinds);;moduleApply_all=structtypet={bindings:value_bindinglist;arguments:patternlist;converted:expressionlist}endletgen_symbolslist~prefix=List.mapilist~f:(funi_->gen_symbol~prefix:(prefix^Int.to_stringi)());;letapply_allts~loc=letarguments_names=gen_symbolsts~prefix:"arg"inletconverted_names=gen_symbolsts~prefix:"res"inletbindings=List.map3_exntsarguments_namesconverted_names~f:(funtargconv->letexpr=apply~loct(evar~locarg)invalue_binding~loc~pat:(pvar~locconv)~expr)in({bindings;arguments=List.maparguments_names~f:(pvar~loc);converted=List.mapconverted_names~f:(evar~loc)}:Apply_all.t);;