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