src/Pure/Isar/outer_keyword.ML
author wenzelm
Thu Aug 07 13:45:03 2008 +0200 (2008-08-07)
changeset 27768 398c64b2acef
parent 27526 69618a03b6f7
child 27805 2e533bcd1343
permissions -rw-r--r--
adapted Scan.extend_lexicon/merge_lexicons;
wenzelm@17059
     1
(*  Title:      Pure/Isar/outer_keyword.ML
wenzelm@17059
     2
    ID:         $Id$
wenzelm@17059
     3
    Author:     Makarius
wenzelm@17059
     4
wenzelm@27357
     5
Isar command keyword classification and global keyword tables.
wenzelm@17059
     6
*)
wenzelm@17059
     7
wenzelm@17059
     8
signature OUTER_KEYWORD =
wenzelm@17059
     9
sig
wenzelm@17059
    10
  type T
wenzelm@17059
    11
  val kind_of: T -> string
wenzelm@17059
    12
  val control: T
wenzelm@17059
    13
  val diag: T
wenzelm@17059
    14
  val thy_begin: T
wenzelm@17059
    15
  val thy_switch: T
wenzelm@17059
    16
  val thy_end: T
wenzelm@17059
    17
  val thy_heading: T
wenzelm@17059
    18
  val thy_decl: T
wenzelm@17059
    19
  val thy_script: T
wenzelm@17059
    20
  val thy_goal: T
wenzelm@17059
    21
  val qed: T
wenzelm@17059
    22
  val qed_block: T
wenzelm@17059
    23
  val qed_global: T
wenzelm@17059
    24
  val prf_heading: T
wenzelm@17059
    25
  val prf_goal: T
wenzelm@17059
    26
  val prf_block: T
wenzelm@17059
    27
  val prf_open: T
wenzelm@17059
    28
  val prf_close: T
wenzelm@17059
    29
  val prf_chain: T
wenzelm@17059
    30
  val prf_decl: T
wenzelm@17059
    31
  val prf_asm: T
wenzelm@17059
    32
  val prf_asm_goal: T
wenzelm@17059
    33
  val prf_script: T
wenzelm@17059
    34
  val kinds: string list
wenzelm@17059
    35
  val update_tags: string -> string list -> string list
wenzelm@17059
    36
  val tag: string -> T -> T
wenzelm@17059
    37
  val tags_of: T -> string list
wenzelm@17059
    38
  val tag_theory: T -> T
wenzelm@17059
    39
  val tag_proof: T -> T
wenzelm@17059
    40
  val tag_ml: T -> T
wenzelm@27357
    41
  val get_lexicons: unit -> Scan.lexicon * Scan.lexicon
wenzelm@27357
    42
  val is_keyword: string -> bool
wenzelm@27357
    43
  val dest_keywords: unit -> string list
wenzelm@27357
    44
  val dest_commands: unit -> string list
wenzelm@27357
    45
  val command_keyword: string -> T option
wenzelm@27357
    46
  val command_tags: string -> string list
wenzelm@27357
    47
  val report: unit -> unit
wenzelm@27357
    48
  val keyword: string -> unit
wenzelm@27357
    49
  val command: string -> T -> unit
wenzelm@27440
    50
  val is_theory: string -> bool
wenzelm@27440
    51
  val is_proof: string -> bool
wenzelm@27520
    52
  val is_diag: string -> bool
wenzelm@17059
    53
end;
wenzelm@17059
    54
wenzelm@17059
    55
structure OuterKeyword: OUTER_KEYWORD =
wenzelm@17059
    56
struct
wenzelm@17059
    57
wenzelm@27357
    58
(** keyword classification **)
wenzelm@17059
    59
wenzelm@17059
    60
datatype T = Keyword of string * string list;
wenzelm@17059
    61
wenzelm@17059
    62
fun kind s = Keyword (s, []);
wenzelm@17059
    63
fun kind_of (Keyword (s, _)) = s;
wenzelm@17059
    64
wenzelm@17059
    65
wenzelm@17059
    66
(* kinds *)
wenzelm@17059
    67
wenzelm@17059
    68
val control = kind "control";
wenzelm@17059
    69
val diag = kind "diag";
wenzelm@17059
    70
val thy_begin = kind "theory-begin";
wenzelm@17059
    71
val thy_switch = kind "theory-switch";
wenzelm@17059
    72
val thy_end = kind "theory-end";
wenzelm@17059
    73
val thy_heading = kind "theory-heading";
wenzelm@17059
    74
val thy_decl = kind "theory-decl";
wenzelm@17059
    75
val thy_script = kind "theory-script";
wenzelm@17059
    76
val thy_goal = kind "theory-goal";
wenzelm@17059
    77
val qed = kind "qed";
wenzelm@17059
    78
val qed_block = kind "qed-block";
wenzelm@17059
    79
val qed_global = kind "qed-global";
wenzelm@17059
    80
val prf_heading = kind "proof-heading";
wenzelm@17059
    81
val prf_goal = kind "proof-goal";
wenzelm@17059
    82
val prf_block = kind "proof-block";
wenzelm@17059
    83
val prf_open = kind "proof-open";
wenzelm@17059
    84
val prf_close = kind "proof-close";
wenzelm@17059
    85
val prf_chain = kind "proof-chain";
wenzelm@17059
    86
val prf_decl = kind "proof-decl";
wenzelm@17059
    87
val prf_asm = kind "proof-asm";
wenzelm@17059
    88
val prf_asm_goal = kind "proof-asm-goal";
wenzelm@17059
    89
val prf_script = kind "proof-script";
wenzelm@17059
    90
wenzelm@17059
    91
val kinds = [control, diag, thy_begin, thy_switch, thy_end, thy_heading, thy_decl, thy_script,
wenzelm@17059
    92
  thy_goal, qed, qed_block, qed_global, prf_heading, prf_goal, prf_block, prf_open, prf_close,
wenzelm@17059
    93
  prf_chain, prf_decl, prf_asm, prf_asm_goal, prf_script] |> map kind_of;
wenzelm@17059
    94
wenzelm@17059
    95
wenzelm@17059
    96
(* tags *)
wenzelm@17059
    97
haftmann@17270
    98
fun update_tags t ts = t :: remove (op = : string * string -> bool) t ts;
wenzelm@17059
    99
wenzelm@17059
   100
fun tag t (Keyword (s, ts)) = Keyword (s, update_tags t ts);
wenzelm@17059
   101
fun tags_of (Keyword (_, ts)) = ts;
wenzelm@17059
   102
wenzelm@17059
   103
val tag_theory = tag "theory";
wenzelm@17059
   104
val tag_proof = tag "proof";
wenzelm@17059
   105
val tag_ml = tag "ML";
wenzelm@17059
   106
wenzelm@27357
   107
wenzelm@27357
   108
wenzelm@27357
   109
(** global keyword tables **)
wenzelm@27357
   110
wenzelm@27357
   111
local
wenzelm@27357
   112
wenzelm@27357
   113
val global_commands = ref (Symtab.empty: T Symtab.table);
wenzelm@27357
   114
val global_lexicons = ref (Scan.empty_lexicon, Scan.empty_lexicon);
wenzelm@27357
   115
wenzelm@27357
   116
in
wenzelm@27357
   117
wenzelm@27357
   118
fun get_commands () = CRITICAL (fn () => ! global_commands);
wenzelm@27357
   119
fun get_lexicons () = CRITICAL (fn () => ! global_lexicons);
wenzelm@27357
   120
wenzelm@27357
   121
fun change_commands f = CRITICAL (fn () => change global_commands f);
wenzelm@27526
   122
fun change_lexicons f = CRITICAL (fn () => change global_lexicons f);
wenzelm@27357
   123
wenzelm@17059
   124
end;
wenzelm@27357
   125
wenzelm@27357
   126
wenzelm@27357
   127
(* lookup *)
wenzelm@27357
   128
wenzelm@27357
   129
fun is_keyword s = Scan.is_literal (#1 (get_lexicons ())) (Symbol.explode s);
wenzelm@27357
   130
fun dest_keywords () = Scan.dest_lexicon (#1 (get_lexicons ()));
wenzelm@27357
   131
wenzelm@27357
   132
fun dest_commands () = Symtab.keys (get_commands ());
wenzelm@27357
   133
fun command_keyword name = Symtab.lookup (get_commands ()) name;
wenzelm@27357
   134
fun command_tags name = these (Option.map tags_of (command_keyword name));
wenzelm@27357
   135
wenzelm@27357
   136
wenzelm@27357
   137
(* report *)
wenzelm@27357
   138
wenzelm@27357
   139
fun report_keyword name =
wenzelm@27357
   140
  Pretty.mark (Markup.keyword_decl name)
wenzelm@27357
   141
    (Pretty.str ("Outer syntax keyword: " ^ quote name));
wenzelm@27357
   142
wenzelm@27357
   143
fun report_command (name, kind) =
wenzelm@27357
   144
  Pretty.mark (Markup.command_decl name (kind_of kind))
wenzelm@27357
   145
    (Pretty.str ("Outer syntax command: " ^ quote name ^ " (" ^ kind_of kind ^ ")"));
wenzelm@27357
   146
wenzelm@27357
   147
fun report () =
wenzelm@27357
   148
  let val (keywords, commands) = CRITICAL (fn () =>
wenzelm@27357
   149
    (dest_keywords (), Symtab.dest (get_commands ())))
wenzelm@27357
   150
  in map report_keyword keywords @ map report_command commands end
wenzelm@27357
   151
  |> Pretty.chunks |> Pretty.writeln;
wenzelm@27357
   152
wenzelm@27357
   153
wenzelm@27357
   154
(* augment tables *)
wenzelm@27357
   155
wenzelm@27357
   156
fun keyword name =
wenzelm@27768
   157
 (change_lexicons (apfst (Scan.extend_lexicon (Symbol.explode name)));
wenzelm@27357
   158
  Pretty.writeln (report_keyword name));
wenzelm@27357
   159
wenzelm@27357
   160
fun command name kind =
wenzelm@27768
   161
 (change_lexicons (apsnd (Scan.extend_lexicon (Symbol.explode name)));
wenzelm@27357
   162
  change_commands (Symtab.update (name, kind));
wenzelm@27357
   163
  Pretty.writeln (report_command (name, kind)));
wenzelm@27357
   164
wenzelm@27433
   165
wenzelm@27433
   166
(* overall category *)
wenzelm@27433
   167
wenzelm@27440
   168
fun command_category ks name =
wenzelm@27433
   169
  (case command_keyword name of
wenzelm@27440
   170
    NONE => false
wenzelm@27440
   171
  | SOME k => member (op =) ks (kind_of k));
wenzelm@27440
   172
wenzelm@27440
   173
val is_theory = command_category
wenzelm@27440
   174
  (map kind_of [thy_begin, thy_switch, thy_end, thy_heading, thy_decl, thy_script, thy_goal]);
wenzelm@27440
   175
wenzelm@27440
   176
val is_proof = command_category
wenzelm@27440
   177
  (map kind_of [qed, qed_block, qed_global, prf_heading, prf_goal, prf_block, prf_open, prf_close,
wenzelm@27440
   178
    prf_chain, prf_decl, prf_asm, prf_asm_goal, prf_script]);
wenzelm@27433
   179
wenzelm@27520
   180
val is_diag = command_category [kind_of diag];
wenzelm@27520
   181
wenzelm@27357
   182
end;