Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file sig_state.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149(** Signature state.
This module provides a record type [sig_state] containing all the
informations needed for scoping p_terms and printing terms, and functions
on this type for manipulating it. In particular, it provides functions
[open_sign], [add_symbol], [add_binop], etc. taking a [sig_state] as
argument and returning a new [sig_state] as result. These functions call
the corresponding functions of [Sign] which should not be called directly
but through the current module only, in order to setup the [sig_state]
properly. *)openLplibopenExtraopenCommonopenErroropenPosopenTimedopenTermopenSign(** [create_sign path] creates a signature with path [path] with ghost modules
as dependencies. *)letcreate_sign:Path.t->Sign.t=funsign_path->letd=Sign.dummy()inletdeps=Path.Map.singletonGhost.sign.sign_pathStrMap.emptyin{dwithsign_path;sign_deps=refdeps}(** State of the signature, including aliasing and accessible symbols. *)typesig_state={signature:Sign.t(** Current signature. *);in_scope:symStrMap.t(** Symbols in scope. *);alias_path:Path.tStrMap.t(** Alias to path map. *);path_alias:stringPath.Map.t(** Path to alias map. *);builtins:symStrMap.t(** Builtins. *);notations:floatnotationSymMap.t(** Notations. *);open_paths:Path.Set.t(** Open modules. *)}typet=sig_state(** Dummy [sig_state]. *)letdummy:sig_state={signature=Sign.dummy();in_scope=StrMap.empty;alias_path=StrMap.empty;path_alias=Path.Map.empty;builtins=StrMap.empty;notations=SymMap.empty;open_paths=Path.Set.empty}(** [add_symbol ss expo prop mstrat opaq id pos typ impl def] generates a new
signature state from [ss] by creating a new symbol with expo [e], property
[p], strategy [st], name [x], type [a], implicit arguments [impl] and
optional definition [def]. [pos] is the position of the declaration
without its definition. This new symbol is returned too. *)letadd_symbol:sig_state->expo->prop->match_strat->bool->strloc->popt->term->boollist->termoption->sig_state*sym=funssexpopropmstratopaqidpostypimpldef->letsym=Sign.add_symbolss.signatureexpopropmstratopaqidpos(cleanuptyp)implinbeginmatchdefwith|Sometwhennotopaq->sym.sym_def:=Some(cleanupt)|_->()end;letin_scope=StrMap.addid.eltsymss.in_scopein{sswithin_scope},sym(** [add_notation ss s n] maps [s] notation to [n] in [ss]. *)letadd_notation:sig_state->sym->floatnotation->sig_state=funsssn->ifs.sym_path=ss.signature.sign_paththenSign.add_notationss.signaturesn;{sswithnotations=SymMap.updates(Sign.update_notationn)ss.notations}(** [add_builtin ss n s] generates a new signature state from [ss] by mapping
the builtin [n] to [s]. *)letadd_builtin:sig_state->string->sym->sig_state=funssbuiltinsym->Sign.add_builtinss.signaturebuiltinsym;letbuiltins=StrMap.addbuiltinsymss.builtinsinletnotations=Sign.add_notation_from_builtinbuiltinsymss.notationsin{sswithbuiltins;notations}(** [open_sign ss sign] extends the signature state [ss] with every symbol of
the signature [sign]. This has the effect of putting these symbols in the
scope when (possibly masking symbols with the same name). Builtins and
notations are also handled in a similar way. *)letopen_sign:sig_state->Sign.t->sig_state=funsssign->letf_key_v1v2=Some(v2)in(* hides previous symbols *)letin_scope=StrMap.unionfss.in_scope!(sign.sign_symbols)inletbuiltins=StrMap.unionfss.builtins!(sign.sign_builtins)inletnotations=SymMap.unionfss.notations!(sign.sign_notations)inletopen_paths=Path.Set.addsign.sign_pathss.open_pathsin{sswithin_scope;builtins;notations;open_paths}(** [of_sign sign] creates a state from the signature [sign] and open it as
well as the ghost signatures. *)letof_sign:Sign.t->sig_state=funsignature->open_sign(open_sign{dummywithsignature}Ghost.sign)signature(** [find_sym] is the type of functions used to return the symbol
corresponding to a qualified / non qualified name *)typefind_sym=prt:bool->prv:bool->sig_state->qidentloc->sym(** [find_sym ~prt ~prv b st qid] returns the symbol corresponding to the
possibly qualified identifier [qid], or raises [Fatal]. The boolean [b]
indicates if the error message should mention variables when [qid] is
unqualified. [~prt] indicates whether {!constructor:Term.expo.Protec}
symbols from other modules are allowed. [~prv] indicates whether
{!constructor:Term.expo.Privat} symbols are allowed. *)letfind_sym:find_sym=fun~prt~prvst{elt=(mp,s);pos}->lets=matchmpwith|[]->(* Symbol in scope. *)begintryStrMap.findsst.in_scopewithNot_found->fatalpos"Unknown object %s."send|[m]whenStrMap.memmst.alias_path->(* Aliased module path. *)begin(* The signature must be loaded (alias is mapped). *)letsign=tryPath.Map.find(StrMap.findmst.alias_path)!loadedwith_->assertfalse(* Should not happen. *)in(* Look for the symbol. *)trySign.findsignswithNot_found->fatalpos"Unknown symbol %a.%s."Path.ppmpsend|_->(* Fully-qualified symbol. *)begin(* Check that the signature was required (or is the current one). *)ifmp<>st.signature.sign_paththenifnot(Path.Map.memmp!(st.signature.sign_deps))thenfatalpos"No module [%a] required."Path.ppmp;(* The signature must have been loaded. *)letsign=tryPath.Map.findmp!loadedwithNot_found->assertfalse(* Should not happen. *)in(* Look for the symbol. *)trySign.findsignswithNot_found->fatalpos"Unknown symbol %a.%s."Path.ppmpsendinmatch(prt,prv,s.sym_expo)with|(false,_,Protec)->ifs.sym_path=st.signature.sign_paththenselse(* Fail if symbol is not defined in the current module. *)fatalpos"Protected symbol not allowed here."|(_,false,Privat)->fatalpos"Private symbol not allowed here."|_->s