aboutsummaryrefslogtreecommitdiffhomepage
path: root/vernac/vernacentries.ml
diff options
context:
space:
mode:
Diffstat (limited to 'vernac/vernacentries.ml')
-rw-r--r--vernac/vernacentries.ml72
1 files changed, 51 insertions, 21 deletions
diff --git a/vernac/vernacentries.ml b/vernac/vernacentries.ml
index 5fda1a0da..27f2a740e 100644
--- a/vernac/vernacentries.ml
+++ b/vernac/vernacentries.ml
@@ -2319,32 +2319,62 @@ let with_fail st b f =
| _ -> assert false
end
+let attributes_of_flags f atts =
+ let assert_empty k v =
+ if v <> VernacFlagEmpty
+ then user_err Pp.(str "Attribute " ++ str k ++ str " does not accept arguments")
+ in
+ List.fold_left
+ (fun (polymorphism, atts) (k, v) ->
+ match k with
+ | "program" when not atts.program ->
+ assert_empty k v;
+ (polymorphism, { atts with program = true })
+ | "program" ->
+ user_err Pp.(str "Program mode specified twice")
+ | "polymorphic" when polymorphism = None ->
+ assert_empty k v;
+ (Some true, atts)
+ | "monomorphic" when polymorphism = None ->
+ assert_empty k v;
+ (Some false, atts)
+ | ("polymorphic" | "monomorphic") ->
+ user_err Pp.(str "Polymorphism specified twice")
+ | "local" when Option.is_empty atts.locality ->
+ assert_empty k v;
+ (polymorphism, { atts with locality = Some true })
+ | "global" when Option.is_empty atts.locality ->
+ assert_empty k v;
+ (polymorphism, { atts with locality = Some false })
+ | ("local" | "global") ->
+ user_err Pp.(str "Locality specified twice")
+ | "deprecated" when Option.is_empty atts.deprecated ->
+ begin match v with
+ | VernacFlagList [ "since", VernacFlagLeaf since ; "note", VernacFlagLeaf note ]
+ | VernacFlagList [ "note", VernacFlagLeaf note ; "since", VernacFlagLeaf since ] ->
+ let since = Some since and note = Some note in
+ (polymorphism, { atts with deprecated = Some (mk_deprecation ~since ~note ()) })
+ | VernacFlagList [ "since", VernacFlagLeaf since ] ->
+ let since = Some since in
+ (polymorphism, { atts with deprecated = Some (mk_deprecation ~since ()) })
+ | VernacFlagList [ "note", VernacFlagLeaf note ] ->
+ let note = Some note in
+ (polymorphism, { atts with deprecated = Some (mk_deprecation ~note ()) })
+ | _ -> CErrors.user_err (Pp.str "Ill formed “deprecated” attribute")
+ end
+ | "deprecated" ->
+ user_err Pp.(str "Deprecation specified twice")
+ | _ -> user_err Pp.(str "Unknown attribute " ++ str k)
+ )
+ (None, atts)
+ f
+
let interp ?(verbosely=true) ?proof ~st {CAst.loc;v=c} =
let orig_univ_poly = Flags.is_universe_polymorphism () in
let orig_program_mode = Flags.is_program_mode () in
- let flags f atts =
- List.fold_left
- (fun (polymorphism, atts) f ->
- match f with
- | VernacProgram when not atts.program ->
- (polymorphism, { atts with program = true })
- | VernacProgram ->
- user_err Pp.(str "Program mode specified twice")
- | VernacPolymorphic b when polymorphism = None ->
- (Some b, atts)
- | VernacPolymorphic _ ->
- user_err Pp.(str "Polymorphism specified twice")
- | VernacLocal b when Option.is_empty atts.locality ->
- (polymorphism, { atts with locality = Some b })
- | VernacLocal _ ->
- user_err Pp.(str "Locality specified twice")
- )
- (None, atts)
- f
- in
let rec control = function
| VernacExpr (f, v) ->
- let (polymorphism, atts) = flags f { loc; locality = None; polymorphic = false; program = orig_program_mode; } in
+ let (polymorphism, atts) = attributes_of_flags f (mk_atts ~program:orig_program_mode ()) in
aux ~polymorphism ~atts v
| VernacFail v -> with_fail st true (fun () -> control v)
| VernacTimeout (n,v) ->