Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file ppx_let_expander.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176openBaseopenPpxlibopenAst_builder.DefaultmoduleList=structincludeListletreduce_exnl~f=matchlwith|[]->invalid_arg"List.reduce_exn"|hd::tl->fold_lefttl~init:hd~f;;endmoduleExtension_name=structtypet=|Bind|Bind_open|Map|Map_openletoperator_name=function|Bind|Bind_open->"bind"|Map|Map_open->"map";;letto_string=function|Bind->"bind"|Bind_open->"bind_open"|Map->"map"|Map_open->"map_open";;endletlet_syntax~modul:Longident.t=matchmodulwith|None->Lident"Let_syntax"|Someid->Ldot(id.txt,"Let_syntax");;letopen_on_rhs~loc~modul=Located.mk~loc(Longident.Ldot(let_syntax~modul,"Open_on_rhs"));;leteoperator~loc~modulfunc=letlid:Longident.t=Ldot(let_syntax~modul,func)inpexp_ident~loc(Located.mk~loclid);;letexpand_with_tmp_vars~locbindingsexpr~f=matchbindingswith|[_]->f~locbindingsexpr|_->lettmp_vars=List.mapbindings~f:(fun_->gen_symbol~prefix:"__let_syntax"())inlets_rhs_tmp_var(* s/rhs/tmp_var *)=List.map2_exnbindingstmp_vars~f:(funvbvar->{vbwithpvb_expr=evar~loc:vb.pvb_expr.pexp_locvar})inlets_lhs_tmp_var(* s/lhs/tmp_var *)=List.map2_exnbindingstmp_vars~f:(funvbvar->{vbwithpvb_pat=pvar~loc:vb.pvb_pat.ppat_locvar})inpexp_let~locNonrecursives_lhs_tmp_var(f~locs_rhs_tmp_varexpr);;letbind_apply~loc~modulextension_name~arg~fn=pexp_apply~loc(eoperator~loc~modul(Extension_name.operator_nameextension_name))[Nolabel,arg;Labelled"f",fn];;letmaybe_openextension_name~to_open:module_to_openexpr=letloc=expr.pexp_locinmatch(extension_name:Extension_name.t)with|Bind|Map->expr|Bind_open|Map_open->pexp_open~locOverride(module_to_open~loc)expr;;letexpand_letextension_name~loc~modulbindingsbody=ifList.is_emptybindingstheninvalid_arg"expand_let: list of bindings must be non-empty";(* Build expression [both E1 (both E2 (both ...))] *)letnested_boths=letrev_boths=List.rev_mapbindings~f:(funvb->vb.pvb_expr)inList.reduce_exnrev_boths~f:(funacce->letloc=e.pexp_locineapply~loc(eoperator~loc~modul"both")[e;acc])in(* Build pattern [(P1, (P2, ...))] *)letnested_patterns=letrev_patts=List.rev_mapbindings~f:(funvb->vb.pvb_pat)inList.reduce_exnrev_patts~f:(funaccp->letloc=p.ppat_locinppat_tuple~loc[p;acc])inbind_apply~loc~modulextension_name~arg:nested_boths~fn:(pexp_fun~locNolabelNonenested_patternsbody);;letexpand_matchextension_name~loc~modulexprcases=bind_apply~loc~modulextension_name~arg:(maybe_openextension_name~to_open:(open_on_rhs~modul)expr)~fn:(pexp_function~loccases);;letexpand_ifextension_name~locexprthen_else_=expand_matchextension_name~locexpr[case~lhs:(pbool~loctrue)~guard:None~rhs:then_;case~lhs:(pbool~locfalse)~guard:None~rhs:else_];;letexpand~modulextension_nameexpr=letloc=expr.pexp_locinletexpansion=matchexpr.pexp_descwith|Pexp_let(Nonrecursive,bindings,expr)->letbindings=List.mapbindings~f:(funvb->letpvb_pat=(* Temporary hack tentatively detecting that the parser
has expanded `let x : t = e` into `let x : t = (e : t)`.
For reference, here is the relevant part of the parser:
https://github.com/ocaml/ocaml/blob/4.07/parsing/parser.mly#L1628 *)matchvb.pvb_pat.ppat_desc,vb.pvb_expr.pexp_descwith|(Ppat_constraint(p,{ptyp_desc=Ptyp_poly([],t1);_}),Pexp_constraint(_,t2))whenphys_equalt1t2->p|_->vb.pvb_patin{vbwithpvb_pat;pvb_expr=maybe_openextension_name~to_open:(open_on_rhs~modul)vb.pvb_expr})inexpand_with_tmp_vars~locbindingsexpr~f:(expand_letextension_name~modul)|Pexp_let(Recursive,_,_)->Location.raise_errorf~loc"'let%%%s' may not be recursive"(Extension_name.to_stringextension_name)|Pexp_match(expr,cases)->expand_matchextension_name~loc~modulexprcases|Pexp_ifthenelse(expr,then_,else_)->letelse_=matchelse_with|Someelse_->else_|None->Location.raise_errorf~loc"'if%%%s' must include an else branch"(Extension_name.to_stringextension_name)inexpand_ifextension_name~loc~modulexprthen_else_|_->Location.raise_errorf~loc"'%%%s' can only be used with 'let', 'match', and 'if'"(Extension_name.to_stringextension_name)in{expansionwithpexp_attributes=expr.pexp_attributes@expansion.pexp_attributes};;