aboutsummaryrefslogtreecommitdiff
path: root/vernac/attributes.ml
blob: ce77256eddbc3ff3d71c6ad8c3c68b470486c6b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
(************************************************************************)
(*         *   The Coq Proof Assistant / The Coq Development Team       *)
(*  v      *   INRIA, CNRS and contributors - Copyright 1999-2018       *)
(* <O___,, *       (see CREDITS file for the list of authors)           *)
(*   \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 CErrors
open Vernacexpr

type deprecation = { since : string option ; note : string option }

let mk_deprecation ?(since=None) ?(note=None) () =
  { since ; note }

type t = {
  locality : bool option;
  polymorphic : bool;
  template : bool option;
  program : bool;
  deprecated : deprecation option;
}

let mk_atts ?(locality=None) ?(polymorphic=false) ?(template=None) ?(program=false) ?(deprecated=None) () =
  { locality ; polymorphic ; program ; deprecated; template }

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")
       | "template" when atts.template = None ->
         assert_empty k v;
         polymorphism, { atts with template = Some true }
       | "notemplate" when atts.template = None ->
         assert_empty k v;
         polymorphism, { atts with template = Some false }
       | "template" | "notemplate" ->
         user_err Pp.(str "Templateness 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