Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file sig_state.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156(** 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] and the ghost
module as dependency. *)letcreate_sign:Path.t->Sign.t=funsign_path->letsign=Sign.dummy()inletdep={dep_symbols=StrMap.empty;dep_open=true}inletdeps=Path.Map.singletonSign.Ghost.pathdepin{signwithsign_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. *);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;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.signatureexpopropmstratopaqidpostypimplinbeginmatchdefwith|Sometwhennotopaq->sym.sym_def:=Some(cleanupt)|_->()end;letin_scope=StrMap.addid.eltsymss.in_scopein{sswithin_scope},sym(** [add_builtin ss b s] generates a new signature state from [ss] by mapping
the builtin string [b] to the symbol [s], and by updating the notation of
[s] when [b] is a builtin used for printing. *)letadd_builtin:sig_state->string->sym->sig_state=funssbs->(* Update the notation of [s] if [b] is a builtin used for printing. *)letn=matchbwith|"nat_zero"->Zero|"nat_succ"->Succ!(s.sym_nota)|"pos_one"->PosOne|"pos_double"->PosDouble|"pos_succ_double"->PosSuccDouble|"int_zero"->IntZero|"int_positive"->IntPos|"int_negative"->IntNeg|_->NoNotationinbeginmatchnwith|NoNotation->()|_->s.sym_nota:=nend;(* Update the builtins of the current signature. *)Sign.add_builtinss.signaturebs;(* Update the builtins of the sig_state. *)letbuiltins=StrMap.addbsss.builtinsin{sswithbuiltins}(** [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, possibly masking symbols with the same name. *)letopen_sign:sig_state->Sign.t->sig_state=funsssign->letf_key_v1v2=Somev2in(* hides previous symbols *)letin_scope=StrMap.unionfss.in_scope!(sign.sign_symbols)inletopen_paths=Path.Set.addsign.sign_pathss.open_pathsin{sswithin_scope;open_paths}(** [of_sign sign] creates a state from the signature [sign] and open it as
well as the ghost signature. *)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 ss 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~prvss{elt=(mp,s);pos}->lets=matchmpwith|[]->(* Symbol in scope. *)begintryStrMap.findsss.in_scopewithNot_found->fatalpos"Unknown object %s."send|[m]whenStrMap.memmss.alias_path->(* Aliased module path. *)begin(* The signature must be loaded (alias is mapped). *)letsign=tryPath.Map.find(StrMap.findmss.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<>ss.signature.sign_paththenifnot(Path.Map.memmp!(ss.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=ss.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