src/Tools/code/code_name.ML
author wenzelm
Sun, 08 Mar 2009 17:26:14 +0100
changeset 30364 577edc39b501
parent 30161 c26e515f1c29
child 30648 17365ef082f3
permissions -rw-r--r--
moved basic algebra of long names from structure NameSpace to Long_Name;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
     1
(*  Title:      Tools/code/code_name.ML
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
     2
    Author:     Florian Haftmann, TU Muenchen
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
     3
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
     4
Some code generator infrastructure concerning names.
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
     5
*)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
     6
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
     7
signature CODE_NAME =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
     8
sig
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
     9
  structure StringPairTab: TABLE
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    10
  val first_upper: string -> string
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    11
  val first_lower: string -> string
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    12
  val dest_name: string -> string * string
27103
d8549f4d900b major refactorings in code generator modules
haftmann
parents: 25999
diff changeset
    13
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    14
  val purify_var: string -> string
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    15
  val purify_tvar: string -> string
25337
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    16
  val purify_sym: string -> string
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    17
  val purify_base: bool -> string -> string
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    18
  val check_modulename: string -> string
27103
d8549f4d900b major refactorings in code generator modules
haftmann
parents: 25999
diff changeset
    19
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    20
  type var_ctxt
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    21
  val make_vars: string list -> var_ctxt
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    22
  val intro_vars: string list -> var_ctxt -> var_ctxt
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    23
  val lookup_var: var_ctxt -> string -> string
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    24
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    25
  val read_const_exprs: theory -> string list -> string list * string list
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    26
  val mk_name_module: Name.context -> string option -> (string -> string option)
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    27
    -> 'a Graph.T -> string -> string
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    28
end;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    29
28054
2b84d34c5d02 restructured and split code serializer module
haftmann
parents: 28016
diff changeset
    30
structure Code_Name: CODE_NAME =
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    31
struct
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    32
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    33
(** auxiliary **)
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    34
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    35
structure StringPairTab =
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    36
  TableFun(type key = string * string val ord = prod_ord fast_string_ord fast_string_ord);
27103
d8549f4d900b major refactorings in code generator modules
haftmann
parents: 25999
diff changeset
    37
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    38
val first_upper = implode o nth_map 0 Symbol.to_ascii_upper o explode;
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    39
val first_lower = implode o nth_map 0 Symbol.to_ascii_lower o explode;
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    40
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    41
val dest_name =
30364
577edc39b501 moved basic algebra of long names from structure NameSpace to Long_Name;
wenzelm
parents: 30161
diff changeset
    42
  apfst Long_Name.implode o split_last o fst o split_last o Long_Name.explode;
27103
d8549f4d900b major refactorings in code generator modules
haftmann
parents: 25999
diff changeset
    43
d8549f4d900b major refactorings in code generator modules
haftmann
parents: 25999
diff changeset
    44
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    45
(** purification **)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    46
25337
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    47
fun purify_name upper lower =
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    48
  let
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    49
    fun is_valid s = Symbol.is_ascii_letter s orelse Symbol.is_ascii_digit s orelse s = "'";
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    50
    val is_junk = not o is_valid andf Symbol.is_regular;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    51
    val junk = Scan.many is_junk;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    52
    val scan_valids = Symbol.scanner "Malformed input"
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    53
      ((junk |--
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    54
        (Scan.optional (Scan.one Symbol.is_ascii_letter) "x" ^^ (Scan.many is_valid >> implode)
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    55
        --| junk))
25999
f8bcd311d501 added ::: / @@@ scanner combinators;
wenzelm
parents: 25597
diff changeset
    56
      ::: Scan.repeat ((Scan.many1 is_valid >> implode) --| junk));
25337
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    57
    fun upper_lower cs = if upper then nth_map 0 Symbol.to_ascii_upper cs
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    58
      else if lower then (if forall Symbol.is_ascii_upper cs
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    59
        then map else nth_map 0) Symbol.to_ascii_lower cs
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    60
      else cs;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    61
  in
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    62
    explode
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    63
    #> scan_valids
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    64
    #> space_implode "_"
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    65
    #> explode
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    66
    #> upper_lower
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    67
    #> implode
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    68
  end;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    69
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    70
fun purify_var "" = "x"
25337
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    71
  | purify_var v = purify_name false true v;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    72
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    73
fun purify_tvar "" = "'a"
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    74
  | purify_tvar v =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    75
      (unprefix "'" #> explode #> filter Symbol.is_ascii_letter #> cons "'" #> implode) v;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    76
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    77
val purify_prefix =
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    78
  explode
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    79
  (*FIMXE should disappear as soon as hierarchical theory name spaces are available*)
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    80
  #> Symbol.scanner "Malformed name"
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    81
      (Scan.repeat ($$ "_" |-- $$ "_" >> (fn _ => ".") || Scan.one Symbol.is_regular))
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    82
  #> implode
30364
577edc39b501 moved basic algebra of long names from structure NameSpace to Long_Name;
wenzelm
parents: 30161
diff changeset
    83
  #> Long_Name.explode
25337
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    84
  #> map (purify_name true false);
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
    85
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
    86
(*FIMXE non-canonical function treating non-canonical names*)
25337
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    87
fun purify_base _ "op &" = "and"
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    88
  | purify_base _ "op |" = "or"
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    89
  | purify_base _ "op -->" = "implies"
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    90
  | purify_base _ "{}" = "empty"
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    91
  | purify_base _ "op :" = "member"
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    92
  | purify_base _ "op Int" = "intersect"
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    93
  | purify_base _ "op Un" = "union"
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    94
  | purify_base _ "*" = "product"
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    95
  | purify_base _ "+" = "sum"
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    96
  | purify_base lower s = if String.isPrefix "op =" s
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    97
      then "eq" ^ purify_name false lower s
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    98
      else purify_name false lower s;
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
    99
93da87a1d2b3 added purify_sym
haftmann
parents: 25313
diff changeset
   100
val purify_sym = purify_base false;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   101
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   102
fun check_modulename mn =
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   103
  let
30364
577edc39b501 moved basic algebra of long names from structure NameSpace to Long_Name;
wenzelm
parents: 30161
diff changeset
   104
    val mns = Long_Name.explode mn;
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   105
    val mns' = map (purify_name true false) mns;
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   106
  in
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   107
    if mns' = mns then mn else error ("Invalid module name: " ^ quote mn ^ "\n"
30364
577edc39b501 moved basic algebra of long names from structure NameSpace to Long_Name;
wenzelm
parents: 30161
diff changeset
   108
      ^ "perhaps try " ^ quote (Long_Name.implode mns'))
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   109
  end;
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   110
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   111
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   112
(** variable name contexts **)
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   113
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   114
type var_ctxt = string Symtab.table * Name.context;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   115
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   116
fun make_vars names = (fold (fn name => Symtab.update_new (name, name)) names Symtab.empty,
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   117
  Name.make_context names);
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   118
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   119
fun intro_vars names (namemap, namectxt) =
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   120
  let
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   121
    val (names', namectxt') = Name.variants names namectxt;
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   122
    val namemap' = fold2 (curry Symtab.update) names names' namemap;
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   123
  in (namemap', namectxt') end;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   124
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   125
fun lookup_var (namemap, _) name = case Symtab.lookup namemap name
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   126
 of SOME name' => name'
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   127
  | NONE => error ("Invalid name in context: " ^ quote name);
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   128
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   129
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   130
(** misc **)
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   131
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   132
fun read_const_exprs thy =
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   133
  let
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   134
    fun consts_of some_thyname =
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   135
      let
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   136
        val thy' = case some_thyname
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   137
         of SOME thyname => ThyInfo.the_theory thyname thy
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   138
          | NONE => thy;
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   139
        val cs = Symtab.fold (fn (c, (_, NONE)) => cons c | _ => I)
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   140
          ((snd o #constants o Consts.dest o #consts o Sign.rep_sg) thy') [];
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   141
        fun belongs_here c =
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   142
          not (exists (fn thy'' => Sign.declared_const thy'' c) (Theory.parents_of thy'))
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   143
      in case some_thyname
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   144
       of NONE => cs
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   145
        | SOME thyname => filter belongs_here cs
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   146
      end;
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   147
    fun read_const_expr "*" = ([], consts_of NONE)
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   148
      | read_const_expr s = if String.isSuffix ".*" s
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   149
          then ([], consts_of (SOME (unsuffix ".*" s)))
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   150
          else ([Code_Unit.read_const thy s], []);
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   151
  in pairself flat o split_list o map read_const_expr end;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   152
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   153
fun mk_name_module reserved_names module_prefix module_alias program =
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   154
  let
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   155
    fun mk_alias name = case module_alias name
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   156
     of SOME name' => name'
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   157
      | NONE => name
30364
577edc39b501 moved basic algebra of long names from structure NameSpace to Long_Name;
wenzelm
parents: 30161
diff changeset
   158
          |> Long_Name.explode
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   159
          |> map (fn name => (the_single o fst) (Name.variants [name] reserved_names))
30364
577edc39b501 moved basic algebra of long names from structure NameSpace to Long_Name;
wenzelm
parents: 30161
diff changeset
   160
          |> Long_Name.implode;
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   161
    fun mk_prefix name = case module_prefix
30364
577edc39b501 moved basic algebra of long names from structure NameSpace to Long_Name;
wenzelm
parents: 30161
diff changeset
   162
     of SOME module_prefix => Long_Name.append module_prefix name
28663
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   163
      | NONE => name;
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   164
    val tab =
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   165
      Symtab.empty
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   166
      |> Graph.fold ((fn name => Symtab.default (name, (mk_alias #> mk_prefix) name))
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   167
           o fst o dest_name o fst)
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   168
             program
bd8438543bf2 code identifier namings are no longer imperative
haftmann
parents: 28346
diff changeset
   169
  in the o Symtab.lookup tab end;
24219
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   170
e558fe311376 new structure for code generator modules
haftmann
parents:
diff changeset
   171
end;