(************************************************************************) (* * The Rocq Prover / The Rocq 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) *) (************************************************************************)
open Vernacexpr open Synterp
let vernac_pperr_endline = CDebug.create ~name:"vernacinterp" ()
let real_error_loc ~cmdloc ~eloc = if Loc.finer eloc cmdloc then eloc else cmdloc
let locate_if_not_already ?loc (e, info) =
(e, Option.cata (Loc.add_loc info) info (real_error_loc ~cmdloc:loc ~eloc:(Loc.get_loc info)))
let with_interp_state ~unfreeze_transient st = let with_local_state synterp_st f =
unfreeze_transient synterp_st; let v = f () in
Vernacstate.Interp.invalidate_cache ();
Vernacstate.unfreeze_full_state st;
(), v in
{ VernacControl.with_local_state }
let interp_control_gen ~loc ~st ~unfreeze_transient control f = let noop = st.Vernacstate.interp.lemmas, st.Vernacstate.interp.program in let control, res =
VernacControl.under_control ~loc
~with_local_state:(with_interp_state ~unfreeze_transient st)
control
~noop
f in if VernacControl.after_last_phase ~loc control then noop else res
(* [loc] is the [Loc.t] of the vernacular command being interpreted. *) let rec interp_expr ?loc ~st cmd = let before_univs = Global.universes () in let pstack, pm = with_generic_atts ~check:false cmd.attrs (fun ~atts ->
interp_expr_core ?loc ~atts ~st cmd.expr) in let after_univs = Global.universes () in if before_univs == after_univs then pstack, pm else let f = Declare.Proof.update_sigma_univs after_univs in Option.map (Vernacstate.LemmaStack.map ~f) pstack, pm
and interp_expr_core ?loc ~atts ~st c = match c with
(* The STM should handle that, but LOAD bypasses the STM... *)
| VernacSynPure VernacAbortAll -> CErrors.user_err (Pp.str "AbortAll cannot be used through the Load command")
| VernacSynPure VernacRestart -> CErrors.user_err (Pp.str "Restart cannot be used through the Load command")
| VernacSynPure VernacUndo _ -> CErrors.user_err (Pp.str "Undo cannot be used through the Load command")
| VernacSynPure VernacUndoTo _ -> CErrors.user_err (Pp.str "UndoTo cannot be used through the Load command")
(* Resetting *)
| VernacSynPure VernacResetName _ -> CErrors.anomaly (Pp.str "VernacResetName not handled by Stm.")
| VernacSynPure VernacResetInitial -> CErrors.anomaly (Pp.str "VernacResetInitial not handled by Stm.")
| VernacSynPure VernacBack _ -> CErrors.anomaly (Pp.str "VernacBack not handled by Stm.")
| v -> let fv = Vernacentries.translate_vernac ?loc ~atts v in let stack = st.Vernacstate.interp.lemmas in let program = st.Vernacstate.interp.program in let {Vernactypes.prog; proof; opaque_access=(); }, () = Vernactypes.run fv {
prog=program;
proof=stack;
opaque_access=();
} in
proof, prog
and vernac_load ~verbosely entries = (* Note that no proof should be open here, so the state here is just token for now *) let st = Vernacstate.freeze_full_state () in let v_mod = if verbosely then Flags.verbosely else Flags.silently in let interp_entry (stack, pm) (CAst.{ loc; v = cmd }, synterp_st) =
Vernacstate.Synterp.unfreeze synterp_st; let st = Vernacstate.{ synterp = synterp_st; interp = { st.interp with Interp.lemmas = stack; program = pm }} in
v_mod (interp_control ~st) (CAst.make ?loc cmd) in let pm = st.Vernacstate.interp.program in let stack = st.Vernacstate.interp.lemmas in let stack, pm =
Dumpglob.with_glob_output Dumpglob.NoGlob
(fun () -> List.fold_left interp_entry (stack, pm) entries) () in (* If Load left a proof open, we fail too. *) ifOption.has_some stack then
CErrors.user_err Pp.(str "Files processed by Load cannot leave open proofs.");
stack, pm
(* XXX: This won't properly set the proof mode, as of today, it is controlledbytheSTM.Thus,wewouldneedaccessinformationfrom theclassifier.TheproperfixistomoveittotheSTM,however, thewaytheproofmodeissettheremakesthetasknontrivial withoutaconsiderableamountofrefactoring.
*)
(* Interpreting a possibly delayed proof *) let interp_qed_delayed ~proof ~st pe = let stack = st.Vernacstate.interp.lemmas in let pm = st.Vernacstate.interp.program in let stack = Option.cata (fun stack -> snd @@ Vernacstate.LemmaStack.pop stack) None stack in let pm = NeList.map_head (fun pm -> match pe with
| Admitted ->
Declare.Proof.save_lemma_admitted_delayed ~pm ~proof
| Proved (_,idopt) -> let pm = Declare.Proof.save_lemma_proved_delayed ~pm ~proof ~idopt in
pm)
pm in
stack, pm
(* Be careful with the cache here in case of an exception. *) let interp_gen ~verbosely ~st ~interp_fn cmd = try let v_mod = if verbosely then Flags.verbosely else Flags.silently in let ontop = v_mod (interp_fn ~st) cmd in
Vernacstate.Declare.set ontop [@ocaml.warning "-3"];
Vernacstate.Interp.freeze_interp_state () with exn -> let exn = Exninfo.capture exn in let exn = locate_if_not_already ?loc:cmd.CAst.loc exn in
Vernacstate.Interp.invalidate_cache ();
Exninfo.iraise exn
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.