src/Pure/Tools/codegen_names.ML
author haftmann
Mon, 25 Sep 2006 17:04:12 +0200
changeset 20697 12952535fc2c
parent 20585 3fe913d70177
child 20835 27d049062b56
permissions -rw-r--r--
added code_instname
haftmann@20353
     1
(*  Title:      Pure/Tools/codegen_names.ML
haftmann@20353
     2
    ID:         $Id$
haftmann@20353
     3
    Author:     Florian Haftmann, TU Muenchen
haftmann@20353
     4
haftmann@20386
     5
Name policies for code generation: prefixing any name by corresponding theory name,
haftmann@20386
     6
conversion to alphanumeric representation. Mappings are incrementally cached.
haftmann@20353
     7
*)
haftmann@20353
     8
haftmann@20353
     9
signature CODEGEN_NAMES =
haftmann@20353
    10
sig
haftmann@20386
    11
  type tyco = string
haftmann@20386
    12
  type const = string
haftmann@20353
    13
  val class: theory -> class -> class
haftmann@20697
    14
  val class_rev: theory -> class -> class option
haftmann@20353
    15
  val tyco: theory -> tyco -> tyco
haftmann@20697
    16
  val tyco_rev: theory -> tyco -> tyco option
haftmann@20386
    17
  val tyco_force: tyco * string -> theory -> theory
haftmann@20353
    18
  val instance: theory -> class * tyco -> string
haftmann@20697
    19
  val instance_rev: theory -> string -> (class * tyco) option
haftmann@20697
    20
  val instance_force: (class * tyco) * string -> theory -> theory
haftmann@20585
    21
  val const: theory -> CodegenConsts.const -> const
haftmann@20697
    22
  val const_rev: theory -> const -> CodegenConsts.const option
haftmann@20585
    23
  val const_force: CodegenConsts.const * const -> theory -> theory
haftmann@20353
    24
  val purify_var: string -> string
haftmann@20697
    25
  val has_nsp: string -> string -> bool
haftmann@20697
    26
  val nsp_module: string
haftmann@20697
    27
  val nsp_class: string
haftmann@20697
    28
  val nsp_tyco: string
haftmann@20697
    29
  val nsp_inst: string
haftmann@20697
    30
  val nsp_fun: string
haftmann@20697
    31
  val nsp_classop: string
haftmann@20697
    32
  val nsp_dtco: string
haftmann@20697
    33
  val nsp_eval: string
haftmann@20353
    34
end;
haftmann@20353
    35
haftmann@20353
    36
structure CodegenNames: CODEGEN_NAMES =
haftmann@20353
    37
struct
haftmann@20353
    38
haftmann@20353
    39
haftmann@20353
    40
(* theory data *)
haftmann@20353
    41
haftmann@20353
    42
type tyco = string;
haftmann@20353
    43
type const = string;
haftmann@20353
    44
val inst_ord = prod_ord fast_string_ord fast_string_ord;
haftmann@20353
    45
val eq_inst = is_equal o inst_ord;
haftmann@20386
    46
structure Consttab = CodegenConsts.Consttab;
haftmann@20353
    47
haftmann@20353
    48
structure Insttab =
haftmann@20353
    49
  TableFun(
haftmann@20353
    50
    type key = class * tyco;
haftmann@20353
    51
    val ord = inst_ord;
haftmann@20353
    52
  );
haftmann@20353
    53
haftmann@20353
    54
datatype names = Names of {
haftmann@20353
    55
  class: class Symtab.table * class Symtab.table,
haftmann@20353
    56
  tyco: tyco Symtab.table * tyco Symtab.table,
haftmann@20353
    57
  instance: string Insttab.table * (class * tyco) Symtab.table,
haftmann@20353
    58
  const: const Consttab.table * (string * typ list) Symtab.table
haftmann@20353
    59
}
haftmann@20353
    60
haftmann@20353
    61
val empty_names = Names {
haftmann@20353
    62
  class = (Symtab.empty, Symtab.empty),
haftmann@20353
    63
  tyco = (Symtab.empty, Symtab.empty),
haftmann@20353
    64
  instance = (Insttab.empty, Symtab.empty),
haftmann@20353
    65
  const = (Consttab.empty, Symtab.empty)
haftmann@20353
    66
};
haftmann@20353
    67
haftmann@20353
    68
local
haftmann@20353
    69
  fun mk_names (class, tyco, instance, const) =
haftmann@20353
    70
    Names { class = class, tyco = tyco, instance = instance, const = const};
haftmann@20353
    71
  fun map_names f (Names { class, tyco, instance, const }) =
haftmann@20353
    72
    mk_names (f (class, tyco, instance, const));
haftmann@20353
    73
  val eq_string = op = : string * string -> bool;
haftmann@20353
    74
in
haftmann@20353
    75
  fun merge_names (Names { class = (class1, classrev1), tyco = (tyco1, tycorev1),
haftmann@20353
    76
      instance = (instance1, instancerev1), const = (const1, constrev1) },
haftmann@20353
    77
    Names { class = (class2, classrev2), tyco = (tyco2, tycorev2),
haftmann@20353
    78
      instance = (instance2, instancerev2), const = (const2, constrev2) }) =
haftmann@20353
    79
    mk_names ((Symtab.merge eq_string (class1, class2), Symtab.merge eq_string (classrev1, classrev2)),
haftmann@20353
    80
      (Symtab.merge eq_string (tyco1, tyco2), Symtab.merge eq_string (tycorev1, tycorev2)),
haftmann@20353
    81
      (Insttab.merge eq_string (instance1, instance2), Symtab.merge eq_inst (instancerev1, instancerev2)),
haftmann@20386
    82
      (Consttab.merge eq_string (const1, const2), Symtab.merge CodegenConsts.eq_const (constrev1, constrev2)));
haftmann@20353
    83
  fun map_class f = map_names
haftmann@20353
    84
    (fn (class, tyco, inst, const) => (f class, tyco, inst, const));
haftmann@20353
    85
  fun map_tyco f = map_names
haftmann@20353
    86
    (fn (class, tyco, inst, const) => (class, f tyco, inst, const));
haftmann@20353
    87
  fun map_inst f = map_names
haftmann@20353
    88
    (fn (class, tyco, inst, const) => (class, tyco, f inst, const));
haftmann@20353
    89
  fun map_const f = map_names
haftmann@20353
    90
    (fn (class, tyco, inst, const) => (class, tyco, inst, f const));
haftmann@20353
    91
haftmann@20353
    92
end; (*local*)
haftmann@20353
    93
haftmann@20456
    94
structure CodeName = TheoryDataFun
haftmann@20353
    95
(struct
haftmann@20353
    96
  val name = "Pure/codegen_names";
haftmann@20353
    97
  type T = names ref;
haftmann@20353
    98
  val empty = ref empty_names;
haftmann@20353
    99
  fun copy (ref names) = ref names;
haftmann@20353
   100
  val extend = copy;
haftmann@20353
   101
  fun merge _ (ref names1, ref names2) = ref (merge_names (names1, names2));
haftmann@20353
   102
  fun print _ _ = ();
haftmann@20353
   103
end);
haftmann@20353
   104
haftmann@20456
   105
val _ = Context.add_setup CodeName.init;
haftmann@20353
   106
haftmann@20353
   107
haftmann@20353
   108
(* forward lookup with cache update *)
haftmann@20353
   109
haftmann@20353
   110
fun get thy get_tabs get upd_names upd policy x =
haftmann@20353
   111
  let
haftmann@20456
   112
    val names_ref = CodeName.get thy
haftmann@20353
   113
    val (Names names) = ! names_ref;
haftmann@20353
   114
    fun mk_unique used name =
haftmann@20353
   115
      let
haftmann@20353
   116
        fun mk_name 0 = name
haftmann@20353
   117
          | mk_name i = name ^ "_" ^ string_of_int i
haftmann@20353
   118
        fun find_name i =
haftmann@20353
   119
          let
haftmann@20353
   120
            val name = mk_name i
haftmann@20353
   121
          in
haftmann@20353
   122
            if used name
haftmann@20353
   123
            then find_name (i+1)
haftmann@20353
   124
            else name
haftmann@20353
   125
          end;
haftmann@20353
   126
        val name = find_name 0;
haftmann@20353
   127
      in name end;
haftmann@20353
   128
    val tabs = get_tabs names;
haftmann@20353
   129
    fun declare name =
haftmann@20353
   130
      let
haftmann@20353
   131
        val names' = upd_names (K (upd (x, name) (fst tabs),
haftmann@20353
   132
          Symtab.update_new (name, x) (snd tabs))) (Names names)
haftmann@20353
   133
      in (names_ref := names'; name) end;
haftmann@20353
   134
  in case get (fst tabs) x
haftmann@20353
   135
   of SOME name => name
haftmann@20353
   136
    | NONE => let
haftmann@20353
   137
        val used = Symtab.defined (snd tabs);
haftmann@20353
   138
        val raw_name = policy thy x;
haftmann@20353
   139
        val name = mk_unique used raw_name;
haftmann@20353
   140
      in declare name end
haftmann@20353
   141
  end;
haftmann@20353
   142
haftmann@20353
   143
haftmann@20353
   144
(* backward lookup *)
haftmann@20353
   145
haftmann@20353
   146
fun rev thy get_tabs errname name =
haftmann@20353
   147
  let
haftmann@20456
   148
    val names_ref = CodeName.get thy
haftmann@20353
   149
    val (Names names) = ! names_ref;
haftmann@20353
   150
    val tab = (snd o get_tabs) names;
haftmann@20353
   151
  in case Symtab.lookup tab name
haftmann@20353
   152
   of SOME x => x
haftmann@20389
   153
    | NONE => error ("No such " ^ errname ^ ": " ^ quote name)
haftmann@20353
   154
  end;
haftmann@20353
   155
haftmann@20353
   156
haftmann@20353
   157
(* theory name lookup *)
haftmann@20353
   158
haftmann@20353
   159
fun thyname_of thy f errmsg x =
haftmann@20353
   160
  let
haftmann@20353
   161
    fun thy_of thy =
haftmann@20353
   162
      if f thy x then case get_first thy_of (Theory.parents_of thy)
haftmann@20353
   163
        of NONE => SOME thy
haftmann@20353
   164
         | thy => thy
haftmann@20353
   165
      else NONE;
haftmann@20353
   166
  in case thy_of thy
haftmann@20353
   167
   of SOME thy => Context.theory_name thy
haftmann@20353
   168
    | NONE => error (errmsg x) end;
haftmann@20353
   169
haftmann@20353
   170
fun thyname_of_class thy =
haftmann@20353
   171
  thyname_of thy (fn thy => member (op =) (Sign.classes thy))
haftmann@20353
   172
    (fn class => "thyname_of_class: no such class: " ^ quote class);
haftmann@20353
   173
haftmann@20353
   174
fun thyname_of_tyco thy =
haftmann@20353
   175
  thyname_of thy Sign.declared_tyname
haftmann@20353
   176
    (fn tyco => "thyname_of_tyco: no such type constructor: " ^ quote tyco);
haftmann@20353
   177
haftmann@20353
   178
fun thyname_of_instance thy =
haftmann@20353
   179
  let
haftmann@20353
   180
    fun test_instance thy (class, tyco) =
haftmann@20353
   181
      can (Sorts.mg_domain (Sign.classes_of thy) tyco) [class]
haftmann@20353
   182
  in thyname_of thy test_instance
haftmann@20353
   183
    (fn (class, tyco) => "thyname_of_instance: no such instance: " ^ quote class ^ ", " ^ quote tyco)
haftmann@20353
   184
  end;
haftmann@20353
   185
haftmann@20353
   186
fun thyname_of_const thy =
haftmann@20353
   187
  thyname_of thy Sign.declared_const
haftmann@20353
   188
    (fn c => "thyname_of_const: no such constant: " ^ quote c);
haftmann@20353
   189
haftmann@20353
   190
haftmann@20353
   191
(* purification of identifiers *)
haftmann@20353
   192
haftmann@20353
   193
val purify_name =
haftmann@20353
   194
  let
haftmann@20353
   195
    fun is_valid s = Symbol.is_ascii_letter s orelse Symbol.is_ascii_digit s orelse s = "'";
haftmann@20353
   196
    val is_junk = not o is_valid andf Symbol.not_eof;
haftmann@20353
   197
    val junk = Scan.any is_junk;
haftmann@20353
   198
    val scan_valids = Symbol.scanner "Malformed input"
haftmann@20353
   199
      ((junk |--
haftmann@20353
   200
        (Scan.optional (Scan.one Symbol.is_ascii_letter) "x" ^^ (Scan.any is_valid >> implode)
haftmann@20353
   201
        --| junk))
haftmann@20353
   202
      -- Scan.repeat ((Scan.any1 is_valid >> implode) --| junk) >> op ::);
haftmann@20353
   203
  in explode #> scan_valids #> space_implode "_" end;
haftmann@20353
   204
haftmann@20353
   205
fun purify_op "0" = "zero"
haftmann@20353
   206
  | purify_op "1" = "one"
haftmann@20353
   207
  | purify_op s =
haftmann@20353
   208
      let
haftmann@20353
   209
        fun rep_op "+" = SOME "sum"
haftmann@20353
   210
          | rep_op "-" = SOME "diff"
haftmann@20353
   211
          | rep_op "*" = SOME "prod"
haftmann@20353
   212
          | rep_op "/" = SOME "quotient"
haftmann@20353
   213
          | rep_op "&" = SOME "conj"
haftmann@20353
   214
          | rep_op "|" = SOME "disj"
haftmann@20353
   215
          | rep_op "=" = SOME "eq"
haftmann@20353
   216
          | rep_op "~" = SOME "inv"
haftmann@20353
   217
          | rep_op "@" = SOME "append"
haftmann@20353
   218
          | rep_op s = NONE;
haftmann@20353
   219
        val scan_valids = Symbol.scanner "Malformed input"
haftmann@20386
   220
           (Scan.repeat (Scan.some rep_op || Scan.one Symbol.not_eof));
haftmann@20353
   221
      in (explode #> scan_valids #> implode) s end;
haftmann@20353
   222
haftmann@20353
   223
val purify_lower = explode #> nth_map 0 Symbol.to_ascii_lower #> implode;
haftmann@20353
   224
val purify_upper = explode #> nth_map 0 Symbol.to_ascii_upper #> implode;
haftmann@20353
   225
haftmann@20389
   226
fun purify_var "" = "x"
haftmann@20389
   227
  | purify_var v =
haftmann@20389
   228
      if nth (explode v) 0 = "'"
haftmann@20389
   229
      then (unprefix "'" #> purify_name #> purify_lower #> prefix "'") v
haftmann@20389
   230
      else (purify_name #> purify_lower) v;
haftmann@20353
   231
haftmann@20353
   232
val purify_idf = purify_op #> purify_name;
haftmann@20353
   233
val purify_prefix = map (purify_idf #> purify_upper);
haftmann@20353
   234
val purify_base = purify_idf #> purify_lower;
haftmann@20353
   235
haftmann@20353
   236
haftmann@20386
   237
(* explicit given names with cache update *)
haftmann@20353
   238
haftmann@20386
   239
fun tyco_force (tyco, name) thy =
haftmann@20386
   240
  let
haftmann@20386
   241
    val names = NameSpace.unpack name;
haftmann@20386
   242
    val (prefix, base) = split_last (NameSpace.unpack name);
haftmann@20386
   243
    val prefix' = purify_prefix prefix;
haftmann@20386
   244
    val base' = purify_base base;
haftmann@20386
   245
    val _ = if (base' = base) andalso forall (op =) (prefix' ~~ prefix)
haftmann@20386
   246
      then ()
haftmann@20386
   247
      else
haftmann@20389
   248
        error ("Name violates naming conventions: " ^ quote name
haftmann@20386
   249
          ^ "; perhaps try with " ^ quote (NameSpace.pack (prefix' @ [base'])))
haftmann@20456
   250
    val names_ref = CodeName.get thy;
haftmann@20386
   251
    val (Names names) = ! names_ref;
haftmann@20386
   252
    val (tycotab, tycorev) = #tyco names;
haftmann@20386
   253
    val _ = if Symtab.defined tycotab tyco
haftmann@20389
   254
      then error ("Type constructor already named: " ^ quote tyco)
haftmann@20386
   255
      else ();
haftmann@20386
   256
    val _ = if Symtab.defined tycorev name
haftmann@20389
   257
      then error ("Name already given to type constructor: " ^ quote name)
haftmann@20386
   258
      else ();
haftmann@20386
   259
    val _ = names_ref := map_tyco (K (Symtab.update_new (tyco, name) tycotab,
haftmann@20386
   260
          Symtab.update_new (name, tyco) tycorev)) (Names names);
haftmann@20386
   261
  in
haftmann@20386
   262
    thy
haftmann@20386
   263
  end;
haftmann@20386
   264
haftmann@20585
   265
fun const_force (c_tys as (c, _), name) thy =
haftmann@20353
   266
  let
haftmann@20353
   267
    val names = NameSpace.unpack name;
haftmann@20353
   268
    val (prefix, base) = split_last (NameSpace.unpack name);
haftmann@20353
   269
    val prefix' = purify_prefix prefix;
haftmann@20353
   270
    val base' = purify_base base;
haftmann@20353
   271
    val _ = if (base' = base) andalso forall (op =) (prefix' ~~ prefix)
haftmann@20353
   272
      then ()
haftmann@20353
   273
      else
haftmann@20389
   274
        error ("Name violates naming conventions: " ^ quote name
haftmann@20353
   275
          ^ "; perhaps try with " ^ quote (NameSpace.pack (prefix' @ [base'])))
haftmann@20456
   276
    val names_ref = CodeName.get thy;
haftmann@20353
   277
    val (Names names) = ! names_ref;
haftmann@20353
   278
    val (const, constrev) = #const names;
haftmann@20353
   279
    val _ = if Consttab.defined const c_tys
haftmann@20389
   280
      then error ("Constant already named: " ^ quote (CodegenConsts.string_of_const thy c_tys))
haftmann@20353
   281
      else ();
haftmann@20353
   282
    val _ = if Symtab.defined constrev name
haftmann@20389
   283
      then error ("Name already given to constant: " ^ quote name)
haftmann@20353
   284
      else ();
haftmann@20353
   285
    val _ = names_ref := map_const (K (Consttab.update_new (c_tys, name) const,
haftmann@20353
   286
          Symtab.update_new (name, c_tys) constrev)) (Names names);
haftmann@20353
   287
  in
haftmann@20353
   288
    thy
haftmann@20353
   289
  end;
haftmann@20353
   290
haftmann@20697
   291
fun instance_force (instance, name) thy =
haftmann@20697
   292
  let
haftmann@20697
   293
    val names = NameSpace.unpack name;
haftmann@20697
   294
    val (prefix, base) = split_last (NameSpace.unpack name);
haftmann@20697
   295
    val prefix' = purify_prefix prefix;
haftmann@20697
   296
    val base' = purify_base base;
haftmann@20697
   297
    val _ = if (base' = base) andalso forall (op =) (prefix' ~~ prefix)
haftmann@20697
   298
      then ()
haftmann@20697
   299
      else
haftmann@20697
   300
        error ("Name violates naming conventions: " ^ quote name
haftmann@20697
   301
          ^ "; perhaps try with " ^ quote (NameSpace.pack (prefix' @ [base'])))
haftmann@20697
   302
    val names_ref = CodeName.get thy;
haftmann@20697
   303
    val (Names names) = ! names_ref;
haftmann@20697
   304
    val (inst, instrev) = #instance names;
haftmann@20697
   305
    val _ = if Insttab.defined inst instance
haftmann@20697
   306
      then error ("Instance already named: " ^ quote (fst instance) ^ ", " ^ quote (snd instance))
haftmann@20697
   307
      else ();
haftmann@20697
   308
    val _ = if Symtab.defined instrev name
haftmann@20697
   309
      then error ("Name already given to instance: " ^ quote name)
haftmann@20697
   310
      else ();
haftmann@20697
   311
    val _ = names_ref := map_inst (K (Insttab.update_new (instance, name) inst,
haftmann@20697
   312
          Symtab.update_new (name, instance) instrev)) (Names names);
haftmann@20697
   313
  in
haftmann@20697
   314
    thy
haftmann@20697
   315
  end;
haftmann@20697
   316
haftmann@20353
   317
haftmann@20353
   318
(* naming policies *)
haftmann@20353
   319
haftmann@20353
   320
fun policy thy get_basename get_thyname name =
haftmann@20353
   321
  let
haftmann@20353
   322
    val prefix = (purify_prefix o NameSpace.unpack o get_thyname thy) name;
haftmann@20353
   323
    val base = (purify_base o get_basename) name;
haftmann@20353
   324
  in NameSpace.pack (prefix @ [base]) end;
haftmann@20353
   325
haftmann@20353
   326
fun class_policy thy = policy thy NameSpace.base thyname_of_class;
haftmann@20353
   327
fun tyco_policy thy = policy thy NameSpace.base thyname_of_tyco;
haftmann@20353
   328
fun instance_policy thy = policy thy (fn (class, tyco) => 
haftmann@20353
   329
  NameSpace.base class ^ "_" ^ NameSpace.base tyco) thyname_of_instance;
haftmann@20353
   330
haftmann@20585
   331
fun force_thyname thy (c, tys) =
haftmann@20585
   332
  case AxClass.class_of_param thy c
haftmann@20585
   333
   of SOME class => (case tys
haftmann@20585
   334
       of [Type (tyco, _)] => SOME (thyname_of_instance thy (class, tyco))
haftmann@20585
   335
        | _ => NONE)
haftmann@20585
   336
    | NONE => (case CodegenConsts.find_def thy (c, tys)
haftmann@20585
   337
   of SOME ((thyname, _), _) => SOME thyname
haftmann@20585
   338
    | NONE => NONE);
haftmann@20386
   339
haftmann@20353
   340
fun const_policy thy (c, tys) =
haftmann@20386
   341
  case force_thyname thy (c, tys)
haftmann@20353
   342
   of NONE => policy thy NameSpace.base thyname_of_const c
haftmann@20353
   343
    | SOME thyname => let
haftmann@20353
   344
        val prefix = (purify_prefix o NameSpace.unpack) thyname;
haftmann@20353
   345
        val tycos = map_filter (fn Type (tyco, _) => SOME tyco | _ => NONE) tys;
haftmann@20386
   346
        val base = map (purify_base o NameSpace.base) (c :: tycos);
haftmann@20386
   347
      in NameSpace.pack (prefix @ [space_implode "_" base]) end;
haftmann@20353
   348
haftmann@20353
   349
haftmann@20697
   350
(* shallow name spaces *)
haftmann@20697
   351
haftmann@20697
   352
val nsp_module = ""; (*a dummy by convention*)
haftmann@20697
   353
val nsp_class = "class";
haftmann@20697
   354
val nsp_tyco = "tyco";
haftmann@20697
   355
val nsp_inst = "inst";
haftmann@20697
   356
val nsp_fun = "fun";
haftmann@20697
   357
val nsp_classop = "classop";
haftmann@20697
   358
val nsp_dtco = "dtco";
haftmann@20697
   359
val nsp_eval = "EVAL"; (*only for evaluation*)
haftmann@20697
   360
haftmann@20697
   361
fun add_nsp shallow name =
haftmann@20697
   362
  name
haftmann@20697
   363
  |> NameSpace.unpack
haftmann@20697
   364
  |> split_last
haftmann@20697
   365
  |> apsnd (single #> cons shallow)
haftmann@20697
   366
  |> (op @)
haftmann@20697
   367
  |> NameSpace.pack;
haftmann@20697
   368
haftmann@20697
   369
fun dest_nsp nsp nspname =
haftmann@20697
   370
  let
haftmann@20697
   371
    val xs = NameSpace.unpack nspname;
haftmann@20697
   372
    val (ys, base) = split_last xs;
haftmann@20697
   373
    val (module, shallow) = split_last ys;
haftmann@20697
   374
  in
haftmann@20697
   375
    if nsp = shallow
haftmann@20697
   376
   then (SOME o NameSpace.pack) (module @ [base])
haftmann@20697
   377
    else NONE
haftmann@20697
   378
  end;
haftmann@20697
   379
haftmann@20697
   380
val has_nsp = is_some oo dest_nsp;
haftmann@20697
   381
haftmann@20697
   382
fun if_nsp nsp f idf =
haftmann@20697
   383
  Option.map f (dest_nsp nsp idf);
haftmann@20697
   384
haftmann@20697
   385
haftmann@20353
   386
(* external interfaces *)
haftmann@20353
   387
haftmann@20353
   388
fun class thy =
haftmann@20697
   389
  get thy #class Symtab.lookup map_class Symtab.update class_policy
haftmann@20697
   390
  #> add_nsp nsp_class;
haftmann@20353
   391
fun tyco thy =
haftmann@20697
   392
  get thy #tyco Symtab.lookup map_tyco Symtab.update tyco_policy
haftmann@20697
   393
  #> add_nsp nsp_tyco;
haftmann@20353
   394
fun instance thy =
haftmann@20697
   395
  get thy #instance Insttab.lookup map_inst Insttab.update instance_policy
haftmann@20697
   396
  #> add_nsp nsp_inst;
haftmann@20697
   397
fun const thy c_ty = case CodegenConsts.norm thy c_ty
haftmann@20697
   398
 of (c_tys as (c, tys)) => add_nsp (if (is_some o CodegenData.get_datatype_of_constr thy) c_tys
haftmann@20697
   399
     then nsp_dtco
haftmann@20697
   400
   else if (is_some o AxClass.class_of_param thy) c andalso
haftmann@20697
   401
    case tys of [TFree _] => true | [TVar _] => true | _ => false
haftmann@20697
   402
     then nsp_classop
haftmann@20697
   403
   else nsp_fun)
haftmann@20697
   404
  (get thy #const Consttab.lookup map_const Consttab.update const_policy c_tys);
haftmann@20353
   405
haftmann@20697
   406
fun class_rev thy =
haftmann@20697
   407
  dest_nsp nsp_class
haftmann@20697
   408
  #> Option.map (rev thy #class "class");
haftmann@20697
   409
fun tyco_rev thy =
haftmann@20697
   410
  dest_nsp nsp_tyco
haftmann@20697
   411
  #> Option.map (rev thy #tyco "type constructor");
haftmann@20697
   412
fun instance_rev thy =
haftmann@20697
   413
  dest_nsp nsp_inst
haftmann@20697
   414
  #> Option.map (rev thy #instance "instance");
haftmann@20697
   415
fun const_rev thy nspname =
haftmann@20697
   416
  (case dest_nsp nsp_fun nspname
haftmann@20697
   417
   of name as SOME _ => name
haftmann@20697
   418
    | _ => (case dest_nsp nsp_dtco nspname
haftmann@20697
   419
   of name as SOME _ => name
haftmann@20697
   420
    | _ => (case dest_nsp nsp_classop nspname
haftmann@20697
   421
   of name as SOME _ => name
haftmann@20697
   422
    | _ => NONE)))
haftmann@20697
   423
  |> Option.map (rev thy #const "constant");
haftmann@20353
   424
haftmann@20353
   425
haftmann@20353
   426
(* outer syntax *)
haftmann@20353
   427
haftmann@20353
   428
local
haftmann@20353
   429
haftmann@20353
   430
structure P = OuterParse
haftmann@20353
   431
and K = OuterKeyword
haftmann@20353
   432
haftmann@20386
   433
fun const_force_e (raw_c, name) thy =
haftmann@20585
   434
  const_force (CodegenConsts.read_const thy raw_c, name) thy;
haftmann@20353
   435
haftmann@20386
   436
fun tyco_force_e (raw_tyco, name) thy =
haftmann@20386
   437
  tyco_force (Sign.intern_type thy raw_tyco, name) thy;
haftmann@20386
   438
haftmann@20697
   439
fun instance_force_e ((raw_tyco, raw_class), name) thy =
haftmann@20697
   440
  instance_force ((Sign.intern_class thy raw_class, Sign.intern_type thy raw_tyco), name) thy;
haftmann@20697
   441
haftmann@20697
   442
val (constnameK, typenameK, instnameK) = ("code_constname", "code_typename", "code_instname");
haftmann@20353
   443
haftmann@20353
   444
val constnameP =
haftmann@20353
   445
  OuterSyntax.command constnameK "declare code name for constant" K.thy_decl (
haftmann@20386
   446
    Scan.repeat1 (P.term -- P.name)
haftmann@20386
   447
    >> (fn aliasses =>
haftmann@20386
   448
          Toplevel.theory (fold const_force_e aliasses))
haftmann@20386
   449
  );
haftmann@20386
   450
haftmann@20386
   451
val typenameP =
haftmann@20386
   452
  OuterSyntax.command typenameK "declare code name for type constructor" K.thy_decl (
haftmann@20697
   453
    Scan.repeat1 (P.xname -- P.name)
haftmann@20386
   454
    >> (fn aliasses =>
haftmann@20386
   455
          Toplevel.theory (fold tyco_force_e aliasses))
haftmann@20353
   456
  );
haftmann@20353
   457
haftmann@20697
   458
val instnameP =
haftmann@20697
   459
  OuterSyntax.command instnameK "declare code name for instance relation" K.thy_decl (
haftmann@20697
   460
    Scan.repeat1 ((P.xname --| P.$$$ "::" -- P.xname) -- P.name)
haftmann@20697
   461
    >> (fn aliasses =>
haftmann@20697
   462
          Toplevel.theory (fold instance_force_e aliasses))
haftmann@20697
   463
  );
haftmann@20697
   464
haftmann@20353
   465
in
haftmann@20353
   466
haftmann@20697
   467
val _ = OuterSyntax.add_parsers [constnameP, typenameP, instnameP];
haftmann@20353
   468
haftmann@20353
   469
haftmann@20353
   470
end; (*local*)
haftmann@20353
   471
haftmann@20353
   472
end;