123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428letbuild_patpat:Ppxlib.expression=[%exprPpxlib.Ast_helper.Pat.mk[%epat]]letbuild_pat_constructctorarg:Ppxlib.expression=build_pat[%exprPpat_construct([%eMetaquot.Exp.locMetaquot.Exp.longidentctor],[%eifMetapp.ast_version>=(4,14)then[%exprOption.map(funx->([],x))[%earg]]elsearg])]letbuild_pat_tupletuple:Ppxlib.expression=build_pat[%exprPpat_tuple[%eMetapp.Exp.listtuple]]letsubi=Printf.sprintf"sub%d"iletquotedi=Printf.sprintf"quoted%d"iletpat_var_of_string~locs=Ppxlib.Ast_helper.Pat.var{loc;txt=s}letexp_var_of_string~locs=Ppxlib.Ast_helper.Exp.ident{loc;txt=Lidents}letpat_tuple_or_value~loclist:Ppxlib.pattern=matchlistwith|[]->[%pat?()]|[value]->value|_->Ppxlib.Ast_helper.Pat.tuple~loclistletexp_tuple_or_value~loclist:Ppxlib.expression=matchlistwith|[]->[%expr()]|[value]->value|_->Ppxlib.Ast_helper.Exp.tuple~loclistletmismatch~locpat:Ppxlib.expression=[%expr__mismatch_count_ref:=index+1;letident=Printf.sprintf"@%d"indexinletloc=Location.noneinError{common=Ppxlib.Ast_helper.Pat.var{loc;txt=ident};mismatches=[{ident;expected=[%eMetaquot.Exp.patternpat];got=quoted;}]}]letmismatch_here~locpat:Ppxlib.expression=[%exprletindex=!__mismatch_count_refin[%emismatch~locpat]]letpat_of_binders~locbinders=pat_tuple_or_value~loc(binders|>List.mapbeginfuntxt->Ppxlib.Ast_helper.Pat.var{loc;txt}end)letexp_of_binders~locbinders=exp_tuple_or_value~loc(binders|>List.mapbeginfunx->Ppxlib.Ast_helper.Exp.ident{loc;txt=Lidentx}end)letrecextract_pat_list(pat:Ppxlib.pattern)=matchpatwith|[%pat?[]]->[]|[%pat?[%p?hd]::[%p?tl]]->hd::extract_pat_listtl|_->raiseExitletmultiple_match~locmake_matcherpatternsget_patterndestruct(destruct_quoted:Ppxlib.expression->stringlist->Ppxlib.expression->Ppxlib.expression->Ppxlib.expression)build_common=letsubs=List.mapi(funi_->subi)patternsinletsub_pats=List.map(pat_var_of_string~loc)subsinletquoteds=List.mapi(funi_->quotedi)patternsindestructsub_pats(fun():(stringlist*Ppxlib.expression)->letbinders,subpatterns=patterns|>List.mapibeginfuniarg:(stringlist*Ppxlib.expression)->letbinders,subpattern=make_matcher(get_patternarg)inbinders,[%exprletquoted=[%eexp_var_of_string~loc(quotedi)]inlet__value__=[%eexp_var_of_string~loc(subi)]in[%esubpattern]]end|>List.splitinletall_binders=binders|>List.flatteninall_binders,[%exprlet[%ppat_tuple_or_value~loc(List.mapbeginfunpat:Ppxlib.pattern->[%pat?([%ppat_var_of_string~locpat]:Ppxlib.expressionoption)]endquoteds)]=matchquotedwith|None->[%eexp_tuple_or_value~loc(patterns|>List.mapibeginfuni_:Ppxlib.expression->[%exprNone]end)]|Somequoted->[%edestruct_quoted[%exprPattern.elim_type_constraintsquoted]quoteds(exp_tuple_or_value~loc(patterns|>List.mapibeginfuni_:Ppxlib.expression->[%exprSome[%eexp_var_of_string~loc(quotedi)]]end))(exp_tuple_or_value~loc(patterns|>List.mapibeginfuni_:Ppxlib.expression->[%exprNone]end))]inmatch[%eexp_tuple_or_value~locsubpatterns]with|[%ppat_tuple_or_value~loc(binders|>List.mapbeginfunbinders:Ppxlib.pattern->[%pat?Ok[%ppat_of_binders~locbinders]]end)]->Ok[%eexp_of_binders~locall_binders]|[%ppat_tuple_or_value~locsub_pats]->letcommon=letloc=Location.nonein[%ebuild_common(subs|>List.mapbeginfunsub:Ppxlib.expression->[%expr(match[%eexp_var_of_string~locsub]with|Ok_->[%ebuild_pat[%exprPpat_any]]|Errorerror->error.common)]end)]inletmismatches=List.flatten[%eList.fold_rightbeginfunsublist:Ppxlib.expression->[%expr(match[%eexp_var_of_string~locsub]with|Ok_->[]|Errorerror->error.mismatches)::[%elist]]endsubs[%expr[]]]inError{common;mismatches}])letmultiple_match_tuple~locmake_matcherargsdestruct(destruct_quoted:Ppxlib.pattern->Ppxlib.pattern)build_common=multiple_match~locmake_matcherargsFun.id(funsub_patsk->destruct(Ppxlib.Ast_helper.Pat.tuple~locsub_pats)k)(funquotedquotedssuccessnone->[%exprmatch[%equoted]with|[%pdestruct_quoted[%pat?{pexp_desc=Pexp_tuple[%pList.fold_rightbeginfunvarlist:Ppxlib.pattern->[%pat?[%ppat_var_of_string~locvar]::[%plist]]endquoteds[%pat?[]]];_}]]->[%esuccess]|_->[%enone]])(funargs->build_common(build_pat_tupleargs))letmultiple_match_record~locmake_matcherfieldsclosed_flagdestruct(destruct_quoted:Ppxlib.pattern->Ppxlib.pattern)build_common=multiple_match~locmake_matcherfields(fun(_label,pat)->pat)(funsub_patsk->destruct(Ppxlib.Ast_helper.Pat.record(List.combine(List.mapfstfields)sub_pats)closed_flag)k)(funquotedquotedssuccessnone->[%exprletextract_field[%ppat_tuple_or_value~loc(List.map(pat_var_of_string~loc)quoteds)]((label:Longident.tLocation.loc),value)=[%ePpxlib.Ast_helper.Exp.match_[%exprlabel.txt](List.mapi(funi((label:Longident.tLocation.loc),_)->Ppxlib.Ast_helper.Exp.case(Metaquot.Pat.longidentlabel.txt)(exp_tuple_or_value~loc(List.mapibeginfunjq:Ppxlib.expression->ifi=jthen[%exprSomevalue]elseexp_var_of_string~locqendquoteds)))fields@[Ppxlib.Ast_helper.Exp.case(Ppxlib.Ast_helper.Pat.any~loc())(exp_tuple_or_value~loc(List.map(exp_var_of_string~loc)quoteds))])]inmatch[%equoted]with|[%pdestruct_quoted[%pat?{pexp_desc=Pexp_record(fields,None);_}]]->beginmatchList.fold_leftextract_field[%enone]fieldswith|[%ppat_tuple_or_value~loc(List.map(funq:Ppxlib.pattern->[%pat?Some[%ppat_var_of_string~locq]])quoteds)]->[%esuccess]|_->[%enone]end|_->[%enone]])(funargs->build_common(build_pat[%exprPpat_record([%eMetapp.Exp.list(List.map2(fun(label,_)value->Ppxlib.Ast_helper.Exp.tuple[Metaquot.Exp.locMetaquot.Exp.longidentlabel;value])fieldsargs)],[%eMetaquot.Exp.closed_flagclosed_flag])]))letsingle_match~locmake_matcherpatpatternquoted_patternbuild_common:stringlist*Ppxlib.expression=letbindings,sub_matcher=make_matcherpatinbindings,[%exprmatch__value__with|[%ppattern]->beginmatchlet(quoted:Ppxlib.expressionoption)=matchquotedwith|None->None|Somequoted->matchPattern.elim_type_constraintsquotedwith|[%pquoted_pattern]->Somearg|_->Noneinlet__value__=subin[%esub_matcher]with|Okbindings->Okbindings|Errorerror->Error{common=(letloc=Location.nonein[%ebuild_common]);mismatches=error.mismatches}end|_->[%emismatch_here~locpat]]letrecmake_matcher'make_matcher(pat:Ppxlib.pattern)(type_constr:Ppxlib.pattern->Ppxlib.pattern):stringlist*Ppxlib.expression=letloc=pat.ppat_locinPpxlib.Ast_helper.with_default_locloc@@fun()->matchpatwith|[%pat?([%p?pat]:[%t?ty])]->make_matcher'make_matcherpatbeginfuncontents->[%pat?([%pcontents]:[%tty])]end|[%pat?_]->[],[%exprOk()]|{ppat_desc=Ppat_varx}->[x.txt],[%exprOk__value__]|{ppat_desc=Ppat_alias(pat,x)}->letbinders,matcher=make_matcherpatin(x.txt::binders),[%exprmatch[%ematcher]with|Ok[%ppat_of_binders~locbinders]->Ok[%eexp_of_binders~loc("__value__"::binders)]|Errore->Errore]|{ppat_desc=Ppat_constantconstant;_}->[],[%exprmatch__value__with|[%ptype_constr(Ppxlib.Ast_helper.Pat.constant~locconstant)]->Ok()|_->[%emismatch_here~locpat]]|[%pat?([%p?a]|[%p?b])]->letbinders_a,(a:Ppxlib.expression)=make_matcherainletbinders_b,(b:Ppxlib.expression)=make_matcherbinbeginmatchList.find_opt(funx->not(List.memxbinders_b))binders_awith|None->()|Somex->Location.raise_errorf~loc:a.pexp_loc"%s is bound here but is not bound in the right-hand side"xend;beginmatchList.find_opt(funx->not(List.memxbinders_a))binders_bwith|None->()|Somex->Location.raise_errorf~loc:b.pexp_loc"%s is bound here but is not bound in the left-hand side"xend;binders_a,[%exprletindex=!__mismatch_count_refinmatch[%ea]with|Okbindings->Okbindings|Error_->match[%eb]with|Ok[%ppat_of_binders~locbinders_b]->Ok[%eexp_of_binders~locbinders_a]|Errorerror_b->[%emismatch~locpat]]|{ppat_desc=Ppat_construct(ctor,None);_}->[],[%exprmatch__value__with|[%ptype_constr(Ppxlib.Ast_helper.Pat.constructctorNone)]->Ok()|_->[%emismatch_here~locpat]]|{ppat_desc=Ppat_construct(ctor,Somearg);_}->make_matcher_construct_with_argmake_matcherpattype_constrctorarg|{ppat_desc=Ppat_tupleargs;_}->multiple_match_tuple~locmake_matcherargs(funsub_patsk:(stringlist*Ppxlib.expression)->letbinders,result=k()inbinders,[%exprmatch__value__with[%ptype_constrsub_pats]->[%eresult]])Fun.idFun.id|{ppat_desc=Ppat_record(fields,closed_flag);_}->multiple_match_record~locmake_matcherfieldsclosed_flag(funsub_patsk:(stringlist*Ppxlib.expression)->letbinders,result=k()inbinders,[%exprmatch__value__with[%ptype_constrsub_pats]->[%eresult]])Fun.idFun.id|_->Location.raise_errorf~loc"unimplemented: %a"Ppxlib.Pprintast.patternpatandmake_matcher_construct_with_argmake_matcher(pat:Ppxlib.pattern)(type_constr:Ppxlib.pattern->Ppxlib.pattern)(ctor:Ppxlib.longident_loc)(arg:Metapp.Pat.Construct.Arg.t):stringlist*Ppxlib.expression=letloc=pat.ppat_locinmatchsnd(Metapp.Pat.Construct.Arg.destructarg)with|[%pat?_]->[],[%exprmatch__value__with|[%ptype_constr(Ppxlib.Ast_helper.Pat.constructctor(Some[%pat?_]))]->Ok()|_->[%emismatch_here~locpat]]|{ppat_desc=Ppat_tupleargs;_}->beginmatchmatchctor,argswith|{txt=Lident"::";_},[hd;tl]->begintrySome(hd::extract_pat_listtl)withExit->Noneend|_->Nonewith|None->multiple_match_tuple~locmake_matcherargs(funsub_patsk:(stringlist*Ppxlib.expression)->letbinders,result=k()inbinders,[%exprmatch__value__with|[%ptype_constr(Ppxlib.Ast_helper.Pat.constructctor(Somesub_pats))]->[%eresult]|_->[%emismatch_here~locpat]])(funquoteds->[%pat?{pexp_desc=Pexp_construct(_ctor,Some[%pquoteds]);_}])(funargs->build_pat_constructctor[%expr(Some[%eargs])])|Somelist->letrecmake_quoted_patt_listlist:Ppxlib.pattern=matchlistwith|[]->[%pat?{pexp_desc=Pexp_construct({txt=Lident"[]";_},None);_}]|hd::tl->[%pat?{pexp_desc=Pexp_construct({txt=Lident"::";_},Some({pexp_desc=Pexp_tuple[[%phd];[%pmake_quoted_patt_listtl]];_}));_}]inletrecmake_quoted_expr_listlist:Ppxlib.expression=matchlistwith|[]->build_pat_construct(Metapp.mkloc(Longident.Lident"[]"))[%exprNone]|hd::tl->build_pat_construct(Metapp.mkloc(Longident.Lident"::"))[%exprSome[%ebuild_pat_tuple[hd;make_quoted_expr_listtl]]]inmultiple_match~locmake_matcherlistFun.id(funsub_patsk:(stringlist*Ppxlib.expression)->letbinders,result=k()inbinders,[%exprmatch__value__with|[%ptype_constr(Metapp.Pat.listsub_pats)]->[%eresult]|_->[%emismatch_here~locpat]])(funquotedquotedssuccessnone->[%exprmatch[%equoted]with|[%pmake_quoted_patt_list(List.map(pat_var_of_string~loc)quoteds)]->[%esuccess]|_->[%enone]])make_quoted_expr_listend|{ppat_desc=Ppat_record(fields,closed_flag);_}->multiple_match_record~locmake_matcherfieldsclosed_flag(funsub_patsk:(stringlist*Ppxlib.expression)->letbinders,result=k()inbinders,[%exprmatch__value__with|[%ptype_constr(Ppxlib.Ast_helper.Pat.constructctor(Somesub_pats))]->[%eresult]|_->[%emismatch_here~locpat]])(funquoteds->[%pat?{pexp_desc=Pexp_construct(_ctor,Some[%pquoteds]);_}])(funargs->build_pat_constructctor[%expr(Some[%eargs])])|pat->single_match~locmake_matcherpat(type_constr(Ppxlib.Ast_helper.Pat.constructctor(Some[%pat?sub])))([%pat?{pexp_desc=Pexp_construct(_ctor,Somearg);_}])(build_pat_constructctor[%expr(Someerror.common)])letrecmake_matcher(pat:Ppxlib.pattern):stringlist*Ppxlib.expression=letbindings,matcher=make_matcher'make_matcherpatFun.idinbindings,[%expr([%ematcher]:_Pattern.pattern_result)]letmake_pat~loc~path:_pat=letbinders,result=make_matcherpatin[%expr(fun?quoted__value__->let__mismatch_count_ref=ref0inbeginmatch[%eresult]with|Ok[%ppat_of_binders~locbinders]->(Ok[%eifbinders=[]then[%expr()]elsePpxlib.Ast_helper.Exp.object_~loc(Ppxlib.Ast_helper.Cstr.mk(Ppxlib.Ast_helper.Pat.any~loc())(binders|>List.map(funx->(Ppxlib.Ast_helper.Cf.method_~loc{loc;txt=x}Public(Ppxlib.Ast_helper.Cf.concreteFresh(Ppxlib.Ast_helper.Exp.ident{loc;txt=Lidentx}))))))]:(_,_)result)|Errore->(Errore:(_,_)result)end)[@ocaml.warning"-26-27"]]letextension=Ppxlib.Extension.declare"pattern"ExpressionPpxlib.Ast_pattern.(ppat__none)make_patlet()=Ppxlib.Driver.register_transformation"pattern.ppx"~rules:[Ppxlib.Context_free.Rule.extensionextension]