123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)type_selector=..moduletypeDEF_ARG=sigvalname:stringtypetvaldoc:stringvalpp:Format.formatter->t->unitendmoduletypeDEF=sigincludeDEF_ARGtypeidvalid:idtype_selector+=Me:tselectorvaluid:intendmoduleDef(X:DEF_ARG):DEFwithtypet=X.t=structincludeXtypeid=Idletid=Idtype_selector+=Me:tselectorletuid=Obj.Extension_constructor.(id@@of_val@@Me)endtype'adef=(moduleDEFwithtypet='a)letdef(typea)?(doc="undocumented")namepp=(moduleDef(structletname=nametypet=aletdoc=docletpp=ppend):DEFwithtypet=a)type(_,_)eq=Refl:('a,'a)eqletmaybe_eq:typeab.adef->bdef->(a,b)eqoption=funst->letmoduleS=(vals)inletmoduleT=(valt)inmatchS.MewithT.Me->SomeRefl|_->Noneletselector_of:typea.adef->aselector=fund->letmoduleD=(vald)inD.Meletname:typea.adef->string=fund->letmoduleD=(vald)inD.nameletdoc:typea.adef->string=fund->letmoduleD=(vald)inD.docletprinter:typea.adef->Format.formatter->a->unit=fund->letmoduleD=(vald)inD.ppletpp_defppfd=Format.fprintfppf"tag:%s"(named)moduleKey=structtypet=V:'adef->ttypes=S:'aselector->sletcompare(Vk0)(Vk1)=compare(S(selector_ofk0))(S(selector_ofk1))endmoduleTagSet=Map.Make(Key)typet=V:'adef*'a->ttypebinding=ttypeset=bindingTagSet.tletppppf(V(tag,v))=Format.fprintfppf"@[<1>(%a@ @[%a@])@]"pp_deftag(printertag)vletoption_mapf=functionNone->None|Somev->Some(fv)letoption_bindf=functionNone->None|Somev->fvletreveal2:typeab.adef->bdef->b->aoption=funtuv->matchmaybe_eqtuwithNone->None|SomeRefl->Somevletreveal:'a.'adef->binding->'aoption=funtag->functionV(another,v)->reveal2taganothervletunveil:'a.'adef->bindingoption->'aoption=funtag->option_bind@@revealtagletconceal:'a.'adef->'a->binding=funtagv->V(tag,v)letveil:'a.'adef->'aoption->bindingoption=funtag->option_map@@concealtagletempty=TagSet.emptyletis_empty=TagSet.is_emptyletmemtag=TagSet.mem(Key.Vtag)letaddtagv=TagSet.add(Key.Vtag)(V(tag,v))letupdatetagf=TagSet.update(Key.Vtag)(funb->veiltag@@f@@unveiltagb)letsingletontagv=TagSet.singleton(Key.Vtag)(V(tag,v))letremovetag=TagSet.remove(Key.Vtag)letrem=removetypemerger={merger:'a.'adef->'aoption->'aoption->'aoption}letmergef=TagSet.merge@@function|Key.Vtag->funab->veiltag@@f.mergertag(unveiltaga)(unveiltagb)typeunioner={unioner:'a.'adef->'a->'a->'a}letunionf=merge{merger=(funtagab->match(a,b)with|Someaa,Somebb->Some(f.unionertagaabb)|Some_,None->a|None,_->b);}(* no compare and equal, compare especially makes little sense *)letiterf=TagSet.iter(fun_->f)letfoldf=TagSet.fold(fun_->f)letfor_allp=TagSet.for_all(fun_->p)letexistsp=TagSet.exists(fun_->p)letfilterp=TagSet.filter(fun_->p)letpartitionp=TagSet.partition(fun_->p)letcardinal=TagSet.cardinalletbindingss=List.mapsnd@@TagSet.bindingssletmin_bindings=snd@@TagSet.min_bindingsletmin_binding_opts=option_mapsnd@@TagSet.min_binding_optsletmax_bindings=snd@@TagSet.max_bindingsletmax_binding_opts=option_mapsnd@@TagSet.max_binding_optsletchooses=snd@@TagSet.choosesletchoose_opts=option_mapsnd@@TagSet.choose_optsletsplittags=(fun(l,m,r)->(l,unveiltagm,r))@@TagSet.split(Key.Vtag)s(* In order to match the usual interface for maps, `find` should be different from
`find_opt` but `Logs` has `find_opt` called `find` so we favor that. *)letfindtags=option_bind(revealtag)@@TagSet.find_opt(Key.Vtag)sletfind_opttags=option_bind(revealtag)@@TagSet.find_opt(Key.Vtag)s(* This would usually be called `find` but `Logs` has it with this name. We can't
have it at both named because `Logs` has `find_opt` as `find`. *)letgettags=find_opttags|>function|None->invalid_arg(Format.asprintf"tag named %s not found in set"(nametag))|Somev->vletfind_firstps=snd@@TagSet.find_firstpsletfind_first_optps=option_mapsnd@@TagSet.find_first_optpsletfind_lastps=snd@@TagSet.find_lastpsletfind_last_optps=option_mapsnd@@TagSet.find_last_optpsletmap=TagSet.mapletmapi=TagSet.mapletpp_setppfs=Format.(fprintfppf"@[<1>{";pp_print_listppppf(bindingss);Format.fprintfppf"}@]")moduleDSL=structtype(_,_,_,_)arg=|A:('xdef*'x)->(('b->'x->'c)->'x->'d,'b,'c,'d)arg|S:('xdef*'x)->('x->'d,'b,'c,'d)arg|T:('xdef*'x)->('d,'b,'c,'d)argletatagv=A(tag,v)letstagv=S(tag,v)letttagv=T(tag,v)letpp_of_def(typea)tag=letmoduleTg=(valtag:DEFwithtypet=a)inTg.pplet(-%):typead.(?tags:set->a)->(a,Format.formatter,unit,d)arg->?tags:set->d=funf->function|A(tag,v)->fun[@warning"-16"]?(tags=empty)->f~tags:(addtagvtags)(pp_of_deftag)v|S(tag,v)->fun[@warning"-16"]?(tags=empty)->f~tags:(addtagvtags)v|T(tag,v)->fun[@warning"-16"]?(tags=empty)->f~tags:(addtagvtags)end