123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186(************************************************************************)(* * The Coq Proof Assistant / The Coq Development Team *)(* v * Copyright INRIA, CNRS and contributors *)(* <O___,, * (see version control and CREDITS file for authors & dates) *)(* \VV/ **************************************************************)(* // * This file is distributed under the terms of the *)(* * GNU Lesser General Public License Version 2.1 *)(* * (see LICENSE file for the text of the license) *)(************************************************************************)moduleDyn=Dyn.Make()moduleStage=structtypet=Synterp|Interpletequalxy=matchx,ywith|Synterp,Synterp->true|Synterp,Interp->false|Interp,Interp->true|Interp,Synterp->falseendtype'asummary_declaration={stage:Stage.t;freeze_function:marshallable:bool->'a;unfreeze_function:'a->unit;init_function:unit->unit}moduleDecl=structtype'at='asummary_declarationendmoduleDynMap=Dyn.Map(Decl)typeml_modules=(stringoption*string)listletsum_mod:ml_modulessummary_declarationoptionref=refNoneletsum_map=refDynMap.emptyletmangleid=id^"-SUMMARY"letdeclare_ml_modules_summarydecl=sum_mod:=Somedeclletcheck_namesumname=matchDyn.namesumnamewith|None->()|Some(Dyn.Anyt)->CErrors.anomaly~label:"Summary.declare_summary"Pp.(str"Colliding summary names: "++strsumname++str" vs. "++str(Dyn.reprt)++str".")letdeclare_summary_tagsumnamedecl=let()=check_name(manglesumname)inlettag=Dyn.create(manglesumname)inlet()=sum_map:=DynMap.addtagdecl!sum_mapintagletdeclare_summarysumnamedecl=ignore(declare_summary_tagsumnamedecl)moduleID=structtype'at='aendmoduleFrozen=Dyn.Map(ID)typefrozen={summaries:Frozen.t;(** Ordered list w.r.t. the first component. *)ml_module:ml_modulesoption;(** Special handling of the ml_module summary. *)}letempty_frozen={summaries=Frozen.empty;ml_module=None}moduleHMap=Dyn.HMap(Decl)(ID)letfreeze_staged_summariesstage~marshallable:frozen=letfilter={HMap.filter=funtagdecl->Stage.equaldecl.stagestage}inletmap={HMap.map=funtagdecl->decl.freeze_function~marshallable}in{summaries=HMap.mapmap(HMap.filterfilter!sum_map);ml_module=matchstagewith|Stage.Synterp->Option.map(fundecl->decl.freeze_function~marshallable)!sum_mod|_->None;}letfreeze_summaries~marshallable:frozen=letmap={HMap.map=funtagdecl->decl.freeze_function~marshallable}in{summaries=HMap.mapmap!sum_map;ml_module=Option.map(fundecl->decl.freeze_function~marshallable)!sum_mod;}letwarn_summary_out_of_scope=letname="summary-out-of-scope"inletcategory="dev"inletdefault=CWarnings.DisabledinCWarnings.create~name~category~default(funname->Pp.str(Printf.sprintf"A Coq plugin was loaded inside a local scope (such as a Section). It is recommended to load plugins at the start of the file. Summary entry: %s"name))letunfreeze_summaries?(partial=false){summaries;ml_module}=(* The unfreezing of [ml_modules_summary] has to be anticipated since it
* may modify the content of [summaries] by loading new ML modules *)beginmatch!sum_modwith|None->CErrors.anomalyPp.(str"Undeclared ML-MODULES summary.")|Somedecl->Option.iterdecl.unfreeze_functionml_moduleend;(* We must be independent on the order of the map! *)letufz(DynMap.Any(name,decl))=trydecl.unfreeze_functionFrozen.(findnamesummaries)withNot_found->ifnotpartialthenbeginwarn_summary_out_of_scope(Dyn.reprname);decl.init_function()end;in(* String.Map.iter unfreeze_single !sum_map *)DynMap.iterufz!sum_mapletinit_summaries()=DynMap.iter(fun(DynMap.Any(_,decl))->decl.init_function())!sum_map(** For global tables registered statically before the end of coqtop
launch, the following empty [init_function] could be used. *)letnop()=()(** Summary projection *)letproject_from_summary{summaries}tag=Frozen.findtagsummariesletmodify_summarysttagv=let()=assert(Frozen.memtagst.summaries)inletsummaries=Frozen.addtagvst.summariesin{stwithsummaries}letremove_from_summarysttag=letsummaries=Frozen.removetagst.summariesin{stwithsummaries}(** All-in-one reference declaration + registration *)letref_tag?(stage=Stage.Interp)?(freeze=fun~marshallabler->r)~namex=letr=refxinlettag=declare_summary_tagname{stage;freeze_function=(fun~marshallable->freeze~marshallable!r);unfreeze_function=((:=)r);init_function=(fun()->r:=x)}inr,tagletref?stage?freeze~namex=fst@@ref_tag?stage?freeze~namexmoduleLocal=structtype'alocal_ref='aCEphemeron.keyref*'aCEphemeron.keyDyn.tagletset(r,tag)v=r:=CEphemeron.createvletget(key,name)=tryCEphemeron.get!keywithCEphemeron.InvalidKey->let{init_function}=DynMap.findname!sum_mapininit_function();CEphemeron.get!keyletref(typea)?(stage=Stage.Interp)~name(init:a):alocal_ref=let()=check_name(manglename)inlettag:aCEphemeron.keyDyn.tag=Dyn.create(manglename)inletr=Util.pervasives_ref(CEphemeron.createinit)inlet()=sum_map:=DynMap.addtag{stage;freeze_function=(fun~marshallable->!r);unfreeze_function=(funv->r:=v);init_function=(fun()->r:=CEphemeron.createinit)}!sum_mapin(r,tag)let(!)=getlet(:=)=setendletdump=Dyn.dump