| author | paulson |
| Fri, 23 Dec 2005 17:34:46 +0100 | |
| changeset 18508 | c5861e128a95 |
| parent 18455 | b293c1087f1d |
| child 18515 | 1cad5c2b2a0b |
| permissions | -rw-r--r-- |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
1 |
(* Title: Pure/Tools/codegen_package.ML |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
2 |
ID: $Id$ |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
3 |
Author: Florian Haftmann, TU Muenchen |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
4 |
|
| 18217 | 5 |
Code generator from Isabelle theories to |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
6 |
intermediate language ("Thin-gol").
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
7 |
*) |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
8 |
|
| 18282 | 9 |
(*NOTE: for simplifying developement, this package contains |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
10 |
some stuff which will finally be moved upwards to HOL*) |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
11 |
|
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
12 |
signature CODEGEN_PACKAGE = |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
13 |
sig |
| 18454 | 14 |
type auxtab; |
| 18304 | 15 |
type exprgen_term; |
| 18335 | 16 |
type appgen; |
| 18217 | 17 |
type defgen; |
| 18335 | 18 |
val add_appgen: string * appgen -> theory -> theory; |
| 18217 | 19 |
val add_defgen: string * defgen -> theory -> theory; |
20 |
val add_lookup_tyco: string * string -> theory -> theory; |
|
21 |
val add_lookup_const: (string * typ) * CodegenThingol.iexpr -> theory -> theory; |
|
22 |
val add_syntax_tyco: string -> (xstring * string) |
|
23 |
* (string option * (string * string list)) option |
|
24 |
-> theory -> theory; |
|
25 |
val add_syntax_tyco_i: string -> (string * CodegenThingol.itype Codegen.mixfix list) |
|
26 |
* (string * (string * string list)) option |
|
27 |
-> theory -> theory; |
|
28 |
val add_syntax_const: string -> ((xstring * string option) * string) |
|
29 |
* (string option * (string * string list)) option |
|
30 |
-> theory -> theory; |
|
| 18454 | 31 |
val add_syntax_const_i: string -> ((string * typ) * CodegenThingol.iexpr Codegen.mixfix list) |
| 18217 | 32 |
* (string * (string * string list)) option |
33 |
-> theory -> theory; |
|
34 |
val add_alias: string * string -> theory -> theory; |
|
35 |
val set_is_datatype: (theory -> string -> bool) -> theory -> theory; |
|
| 18455 | 36 |
val set_get_all_datatype_cons : (theory -> (string * string) list) |
| 18454 | 37 |
-> theory -> theory; |
| 18217 | 38 |
|
| 18454 | 39 |
val invoke_cg_type: theory -> auxtab |
| 18217 | 40 |
-> typ -> CodegenThingol.transact -> CodegenThingol.itype * CodegenThingol.transact; |
| 18454 | 41 |
val invoke_cg_expr: theory -> auxtab |
| 18217 | 42 |
-> term -> CodegenThingol.transact -> CodegenThingol.iexpr * CodegenThingol.transact; |
| 18454 | 43 |
val ensure_def_tyco: theory -> auxtab |
| 18217 | 44 |
-> string -> CodegenThingol.transact -> string * CodegenThingol.transact; |
| 18454 | 45 |
val ensure_def_const: theory -> auxtab |
46 |
-> string * typ -> CodegenThingol.transact -> string * CodegenThingol.transact; |
|
| 18217 | 47 |
|
| 18335 | 48 |
val appgen_let: (int -> term -> term list * term) |
49 |
-> appgen; |
|
50 |
val appgen_split: (int -> term -> term list * term) |
|
51 |
-> appgen; |
|
52 |
val appgen_number_of: (term -> IntInf.int) -> (term -> term) |
|
53 |
-> appgen; |
|
54 |
val appgen_case: (theory -> string -> (string * int) list option) |
|
55 |
-> appgen; |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
56 |
val defgen_datatype: (theory -> string -> ((string * sort) list * string list) option) |
| 18335 | 57 |
-> (theory -> string * string -> typ list option) |
| 18217 | 58 |
-> defgen; |
59 |
val defgen_datacons: (theory -> string * string -> typ list option) |
|
60 |
-> defgen; |
|
61 |
val defgen_recfun: (theory -> string * typ -> (term list * term) list * typ) |
|
62 |
-> defgen; |
|
63 |
||
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
64 |
val print_codegen_generated: theory -> unit; |
| 18454 | 65 |
val rename_inconsistent: theory -> theory; |
66 |
structure InstNameMangler: NAME_MANGLER; |
|
67 |
structure ConstNameMangler: NAME_MANGLER; |
|
68 |
structure DatatypeconsNameMangler: NAME_MANGLER; |
|
| 18231 | 69 |
structure CodegenData: THEORY_DATA; |
| 18454 | 70 |
val mk_tabs: theory -> auxtab; |
71 |
val alias_get: theory -> string -> string; |
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
72 |
end; |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
73 |
|
| 18217 | 74 |
structure CodegenPackage : CODEGEN_PACKAGE = |
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
75 |
struct |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
76 |
|
| 18385 | 77 |
open CodegenThingolOp; |
78 |
infix 8 `%%; |
|
79 |
infixr 6 `->; |
|
80 |
infixr 6 `-->; |
|
81 |
infix 4 `$; |
|
82 |
infix 4 `$$; |
|
83 |
infixr 5 `|->; |
|
84 |
infixr 5 `|-->; |
|
| 18217 | 85 |
|
86 |
(* auxiliary *) |
|
87 |
||
| 18454 | 88 |
fun devarify_type ty = (fst o Type.freeze_thaw_type) ty; |
| 18335 | 89 |
fun devarify_term t = (fst o Type.freeze_thaw) t; |
| 18454 | 90 |
|
91 |
val is_number = is_some o Int.fromString; |
|
| 18217 | 92 |
|
| 18361 | 93 |
fun newline_correct s = |
94 |
s |
|
95 |
|> space_explode "\n" |
|
96 |
|> map (implode o (fn [] => [] |
|
97 |
| (" "::xs) => xs
|
|
98 |
| xs => xs) o explode) |
|
99 |
|> space_implode "\n"; |
|
| 18217 | 100 |
|
101 |
||
| 18454 | 102 |
(* shallo name spaces *) |
| 18217 | 103 |
|
104 |
val nsp_class = "class"; |
|
| 18454 | 105 |
val nsp_tyco = "tyco"; |
| 18217 | 106 |
val nsp_const = "const"; |
| 18454 | 107 |
val nsp_overl = "overl"; |
108 |
val nsp_dtcon = "dtcon"; |
|
| 18217 | 109 |
val nsp_mem = "mem"; |
110 |
val nsp_inst = "inst"; |
|
| 18385 | 111 |
val nsp_eq_inst = "eq_inst"; |
112 |
val nsp_eq_pred = "eq"; |
|
| 18217 | 113 |
|
114 |
||
| 18454 | 115 |
(* code generator data types *) |
116 |
||
117 |
structure InstNameMangler = NameManglerFun ( |
|
118 |
type ctxt = theory; |
|
119 |
type src = string * (class * string); |
|
120 |
val ord = prod_ord string_ord (prod_ord string_ord string_ord); |
|
121 |
fun mk thy ((thyname, (cls, tyco)), i) = |
|
122 |
NameSpace.base cls ^ "_" ^ NameSpace.base tyco ^ implode (replicate i "'") |
|
123 |
|> NameSpace.append thyname; |
|
124 |
fun is_valid _ _ = true; |
|
125 |
fun maybe_unique _ _ = NONE; |
|
126 |
fun re_mangle _ dst = error ("no such instance: " ^ quote dst);
|
|
127 |
); |
|
128 |
||
129 |
structure ConstNameMangler = NameManglerFun ( |
|
130 |
type ctxt = theory; |
|
131 |
type src = string * (typ * typ); |
|
132 |
val ord = prod_ord string_ord (prod_ord Term.typ_ord Term.typ_ord); |
|
133 |
fun mk thy ((c, (ty_decl, ty)), i) = |
|
134 |
let |
|
135 |
fun mangle (Type (tyco, tys)) = |
|
136 |
NameSpace.base tyco :: Library.flat (List.mapPartial mangle tys) |> SOME |
|
137 |
| mangle _ = |
|
138 |
NONE |
|
139 |
in |
|
140 |
Vartab.empty |
|
141 |
|> Sign.typ_match thy (ty_decl, ty) |
|
142 |
|> map (snd o snd) o Vartab.dest |
|
143 |
|> List.mapPartial mangle |
|
144 |
|> Library.flat |
|
145 |
|> null ? K ["x"] |
|
146 |
|> cons c |
|
147 |
|> space_implode "_" |
|
148 |
|> curry (op ^ o swap) ((implode oo replicate) i "'") |
|
149 |
end; |
|
150 |
fun is_valid _ _ = true; |
|
151 |
fun maybe_unique _ _ = NONE; |
|
152 |
fun re_mangle _ dst = error ("no such constant: " ^ quote dst);
|
|
153 |
); |
|
154 |
||
155 |
structure DatatypeconsNameMangler = NameManglerFun ( |
|
156 |
type ctxt = theory; |
|
157 |
type src = string * string; |
|
158 |
val ord = prod_ord string_ord string_ord; |
|
159 |
fun mk thy (("0", "nat"), _) =
|
|
160 |
"Nat.Zero" |
|
161 |
| mk thy ((co, dtco), i) = |
|
162 |
let |
|
163 |
fun basename 0 = NameSpace.base co |
|
| 18455 | 164 |
| basename 1 = NameSpace.base dtco ^ "_" ^ NameSpace.base co |
| 18454 | 165 |
| basename i = NameSpace.base dtco ^ "_" ^ NameSpace.base co ^ "_" ^ (implode oo replicate) (i-1) "'"; |
166 |
fun strip_dtco name = |
|
167 |
case (rev o NameSpace.unpack) name |
|
168 |
of x1::x2::xs => |
|
169 |
if x2 = NameSpace.base dtco |
|
170 |
then NameSpace.pack (x1::xs) |
|
171 |
else name |
|
172 |
| _ => name; |
|
173 |
in |
|
174 |
NameSpace.append (NameSpace.drop_base dtco) (basename i) |
|
175 |
|> strip_dtco |
|
176 |
end; |
|
177 |
fun is_valid _ _ = true; |
|
178 |
fun maybe_unique _ _ = NONE; |
|
179 |
fun re_mangle _ dst = error ("no such datatype constructor: " ^ quote dst);
|
|
180 |
); |
|
181 |
||
182 |
type auxtab = ((typ * (term list * term)) Symtab.table * string Symtab.table) |
|
183 |
* (InstNameMangler.T * ((typ * typ list) Symtab.table * ConstNameMangler.T) * DatatypeconsNameMangler.T); |
|
184 |
||
185 |
type exprgen_sort = theory -> auxtab -> (sort, sort) gen_exprgen; |
|
186 |
type exprgen_type = theory -> auxtab -> (typ, itype) gen_exprgen; |
|
187 |
type exprgen_term = theory -> auxtab -> (term, iexpr) gen_exprgen; |
|
188 |
type appgen = theory -> auxtab -> ((string * typ) * term list, iexpr) gen_exprgen; |
|
189 |
type defgen = theory -> auxtab -> gen_defgen; |
|
190 |
||
191 |
||
| 18217 | 192 |
(* serializer *) |
193 |
||
194 |
val serializer_ml = |
|
195 |
let |
|
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
196 |
val name_root = "Generated"; |
| 18282 | 197 |
val nsp_conn = [ |
| 18454 | 198 |
[nsp_class, nsp_tyco], [nsp_const, nsp_overl, nsp_dtcon, nsp_mem, nsp_inst, nsp_eq_inst, nsp_eq_pred] |
| 18217 | 199 |
]; |
| 18282 | 200 |
in CodegenSerializer.ml_from_thingol nsp_conn name_root end; |
| 18217 | 201 |
|
| 18282 | 202 |
val serializer_hs = |
203 |
let |
|
204 |
val name_root = "Generated"; |
|
205 |
val nsp_conn = [ |
|
| 18454 | 206 |
[nsp_class], [nsp_tyco], [nsp_const, nsp_overl, nsp_mem, nsp_eq_pred], [nsp_dtcon], [nsp_inst, nsp_eq_inst] |
| 18282 | 207 |
]; |
208 |
in CodegenSerializer.haskell_from_thingol nsp_conn name_root end; |
|
| 18217 | 209 |
|
210 |
||
| 18454 | 211 |
(* theory data for code generator *) |
| 18217 | 212 |
|
213 |
type gens = {
|
|
| 18304 | 214 |
exprgens_sort: (string * (exprgen_sort * stamp)) list, |
215 |
exprgens_type: (string * (exprgen_type * stamp)) list, |
|
216 |
exprgens_term: (string * (exprgen_term * stamp)) list, |
|
| 18335 | 217 |
appgens: (string * (appgen * stamp)) list, |
| 18217 | 218 |
defgens: (string * (defgen * stamp)) list |
219 |
}; |
|
220 |
||
| 18335 | 221 |
fun map_gens f { exprgens_sort, exprgens_type, exprgens_term, appgens, defgens } =
|
| 18217 | 222 |
let |
| 18335 | 223 |
val (exprgens_sort, exprgens_type, exprgens_term, appgens, defgens) = |
224 |
f (exprgens_sort, exprgens_type, exprgens_term, appgens, defgens) |
|
| 18304 | 225 |
in { exprgens_sort = exprgens_sort, exprgens_type = exprgens_type,
|
| 18454 | 226 |
exprgens_term = exprgens_term, appgens = appgens, defgens = defgens } : gens end; |
| 18217 | 227 |
|
228 |
fun merge_gens |
|
| 18304 | 229 |
({ exprgens_sort = exprgens_sort1, exprgens_type = exprgens_type1,
|
| 18335 | 230 |
exprgens_term = exprgens_term1, appgens = appgens1, defgens = defgens1 }, |
| 18304 | 231 |
{ exprgens_sort = exprgens_sort2, exprgens_type = exprgens_type2,
|
| 18335 | 232 |
exprgens_term = exprgens_term2, appgens = appgens2, defgens = defgens2 }) = |
| 18304 | 233 |
{ exprgens_sort = AList.merge (op =) (eq_snd (op =)) (exprgens_sort1, exprgens_sort2),
|
234 |
exprgens_type = AList.merge (op =) (eq_snd (op =)) (exprgens_type1, exprgens_type2), |
|
235 |
exprgens_term = AList.merge (op =) (eq_snd (op =)) (exprgens_term1, exprgens_term2), |
|
| 18335 | 236 |
appgens = AList.merge (op =) (eq_snd (op =)) (appgens1, appgens2), |
| 18304 | 237 |
defgens = AList.merge (op =) (eq_snd (op =)) (defgens1, defgens2) } : gens; |
| 18217 | 238 |
|
239 |
type lookups = {
|
|
240 |
lookups_tyco: string Symtab.table, |
|
241 |
lookups_const: (typ * iexpr) list Symtab.table |
|
242 |
} |
|
243 |
||
244 |
fun map_lookups f { lookups_tyco, lookups_const } =
|
|
245 |
let |
|
246 |
val (lookups_tyco, lookups_const) = |
|
247 |
f (lookups_tyco, lookups_const) |
|
| 18454 | 248 |
in { lookups_tyco = lookups_tyco, lookups_const = lookups_const } : lookups end;
|
| 18217 | 249 |
|
250 |
fun merge_lookups |
|
251 |
({ lookups_tyco = lookups_tyco1, lookups_const = lookups_const1 },
|
|
252 |
{ lookups_tyco = lookups_tyco2, lookups_const = lookups_const2 }) =
|
|
253 |
{ lookups_tyco = Symtab.merge (op =) (lookups_tyco1, lookups_tyco2),
|
|
| 18304 | 254 |
lookups_const = Symtab.merge (op =) (lookups_const1, lookups_const2) } : lookups; |
| 18217 | 255 |
|
256 |
type logic_data = {
|
|
257 |
is_datatype: ((theory -> string -> bool) * stamp) option, |
|
| 18455 | 258 |
get_all_datatype_cons: ((theory -> (string * string) list) * stamp) option, |
| 18217 | 259 |
alias: string Symtab.table * string Symtab.table |
260 |
}; |
|
261 |
||
| 18454 | 262 |
fun map_logic_data f { is_datatype, get_all_datatype_cons, alias } =
|
| 18217 | 263 |
let |
| 18454 | 264 |
val ((is_datatype, get_all_datatype_cons), alias) = |
265 |
f ((is_datatype, get_all_datatype_cons), alias) |
|
266 |
in { is_datatype = is_datatype, get_all_datatype_cons = get_all_datatype_cons, alias = alias } : logic_data end;
|
|
| 18217 | 267 |
|
268 |
fun merge_logic_data |
|
| 18454 | 269 |
({ is_datatype = is_datatype1, get_all_datatype_cons = get_all_datatype_cons1, alias = alias1 },
|
270 |
{ is_datatype = is_datatype2, get_all_datatype_cons = get_all_datatype_cons2, alias = alias2 }) =
|
|
| 18217 | 271 |
let |
272 |
fun merge_opt _ (x1, NONE) = x1 |
|
273 |
| merge_opt _ (NONE, x2) = x2 |
|
274 |
| merge_opt eq (SOME x1, SOME x2) = |
|
275 |
if eq (x1, x2) then SOME x1 else error ("incompatible options during merge");
|
|
276 |
in |
|
277 |
{ is_datatype = merge_opt (eq_snd (op =)) (is_datatype1, is_datatype2),
|
|
| 18454 | 278 |
get_all_datatype_cons = merge_opt (eq_snd (op =)) (get_all_datatype_cons1, get_all_datatype_cons2), |
| 18217 | 279 |
alias = (Symtab.merge (op =) (fst alias1, fst alias2), |
| 18304 | 280 |
Symtab.merge (op =) (snd alias1, snd alias2)) } : logic_data |
| 18217 | 281 |
end; |
282 |
||
283 |
type serialize_data = {
|
|
284 |
serializer: CodegenSerializer.serializer, |
|
285 |
primitives: CodegenSerializer.primitives, |
|
286 |
syntax_tyco: itype Codegen.mixfix list Symtab.table, |
|
287 |
syntax_const: iexpr Codegen.mixfix list Symtab.table |
|
288 |
}; |
|
289 |
||
290 |
fun map_serialize_data f { serializer, primitives, syntax_tyco, syntax_const } =
|
|
291 |
let |
|
292 |
val (primitives, syntax_tyco, syntax_const) = |
|
293 |
f (primitives, syntax_tyco, syntax_const) |
|
294 |
in { serializer = serializer, primitives = primitives,
|
|
| 18454 | 295 |
syntax_tyco = syntax_tyco, syntax_const = syntax_const } : serialize_data |
296 |
end; |
|
| 18217 | 297 |
|
298 |
fun merge_serialize_data |
|
299 |
({ serializer = serializer, primitives = primitives1,
|
|
300 |
syntax_tyco = syntax_tyco1, syntax_const = syntax_const1 }, |
|
| 18282 | 301 |
{serializer = _, primitives = primitives2,
|
| 18217 | 302 |
syntax_tyco = syntax_tyco2, syntax_const = syntax_const2 }) = |
303 |
{ serializer = serializer,
|
|
304 |
primitives = CodegenSerializer.merge_prims (primitives1, primitives2) : CodegenSerializer.primitives, |
|
305 |
syntax_tyco = Symtab.merge (op =) (syntax_tyco1, syntax_tyco2), |
|
| 18304 | 306 |
syntax_const = Symtab.merge (op =) (syntax_const1, syntax_const2) } : serialize_data; |
| 18217 | 307 |
|
308 |
structure CodegenData = TheoryDataFun |
|
309 |
(struct |
|
310 |
val name = "Pure/codegen_package"; |
|
311 |
type T = {
|
|
312 |
modl: module, |
|
313 |
gens: gens, |
|
314 |
lookups: lookups, |
|
315 |
logic_data: logic_data, |
|
316 |
serialize_data: serialize_data Symtab.table |
|
317 |
}; |
|
318 |
val empty = {
|
|
319 |
modl = empty_module, |
|
| 18335 | 320 |
gens = { exprgens_sort = [], exprgens_type = [], exprgens_term = [], appgens = [], defgens = [] } : gens,
|
| 18217 | 321 |
lookups = { lookups_tyco = Symtab.empty, lookups_const = Symtab.empty } : lookups,
|
| 18454 | 322 |
logic_data = { is_datatype = NONE, get_all_datatype_cons = NONE,
|
323 |
alias = (Symtab.empty, Symtab.empty) } : logic_data, |
|
| 18217 | 324 |
serialize_data = |
325 |
Symtab.empty |
|
326 |
|> Symtab.update ("ml",
|
|
| 18231 | 327 |
{ serializer = serializer_ml : CodegenSerializer.serializer,
|
| 18217 | 328 |
primitives = |
329 |
CodegenSerializer.empty_prims |
|
| 18385 | 330 |
|> CodegenSerializer.add_prim ("Eq", ("type 'a Eq = {eq: 'a -> 'a -> bool};", []))
|
| 18217 | 331 |
|> CodegenSerializer.add_prim ("fst", ("fun fst (x, _) = x;", []))
|
332 |
|> CodegenSerializer.add_prim ("snd", ("fun snd (_, y) = y;", []))
|
|
333 |
|> CodegenSerializer.add_prim ("wfrec", ("fun wfrec f x = f (wfrec f) x;", [])),
|
|
334 |
syntax_tyco = Symtab.empty, syntax_const = Symtab.empty }) |
|
335 |
|> Symtab.update ("haskell",
|
|
| 18335 | 336 |
{ serializer = serializer_hs : CodegenSerializer.serializer,
|
337 |
primitives = |
|
338 |
CodegenSerializer.empty_prims |
|
339 |
|> CodegenSerializer.add_prim ("wfrec", ("wfrec f x = f (wfrec f) x", [])),
|
|
| 18217 | 340 |
syntax_tyco = Symtab.empty, syntax_const = Symtab.empty }) |
341 |
} : T; |
|
342 |
val copy = I; |
|
343 |
val extend = I; |
|
344 |
fun merge _ ( |
|
345 |
{ modl = modl1, gens = gens1, lookups = lookups1,
|
|
346 |
serialize_data = serialize_data1, logic_data = logic_data1 }, |
|
347 |
{ modl = modl2, gens = gens2, lookups = lookups2,
|
|
348 |
serialize_data = serialize_data2, logic_data = logic_data2 } |
|
349 |
) = {
|
|
350 |
modl = merge_module (modl1, modl2), |
|
351 |
gens = merge_gens (gens1, gens2), |
|
352 |
lookups = merge_lookups (lookups1, lookups2), |
|
353 |
logic_data = merge_logic_data (logic_data1, logic_data2), |
|
354 |
serialize_data = Symtab.join (K (merge_serialize_data #> SOME)) |
|
355 |
(serialize_data1, serialize_data2) |
|
356 |
}; |
|
357 |
fun print thy _ = writeln "sorry, this stuff is too complicated..."; |
|
358 |
end); |
|
359 |
||
360 |
fun map_codegen_data f thy = |
|
361 |
case CodegenData.get thy |
|
362 |
of { modl, gens, lookups, serialize_data, logic_data } =>
|
|
363 |
let val (modl, gens, lookups, serialize_data, logic_data) = |
|
364 |
f (modl, gens, lookups, serialize_data, logic_data) |
|
365 |
in CodegenData.put { modl = modl, gens = gens, lookups = lookups,
|
|
366 |
serialize_data = serialize_data, logic_data = logic_data } thy end; |
|
367 |
||
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
368 |
val print_codegen_generated = writeln o Pretty.output o pretty_module o #modl o CodegenData.get; |
| 18217 | 369 |
|
| 18231 | 370 |
fun add_codegen_sort (name, cg) = |
| 18217 | 371 |
map_codegen_data |
372 |
(fn (modl, gens, lookups, serialize_data, logic_data) => |
|
373 |
(modl, |
|
374 |
gens |> map_gens |
|
| 18335 | 375 |
(fn (exprgens_sort, exprgens_type, exprgens_term, appgens, defgens) => |
| 18304 | 376 |
(exprgens_sort |
| 18217 | 377 |
|> Output.update_warn (op =) ("overwriting existing class code generator " ^ name) (name, (cg, stamp ())),
|
| 18335 | 378 |
exprgens_type, exprgens_term, appgens, defgens)), lookups, serialize_data, logic_data)); |
| 18217 | 379 |
|
380 |
fun add_codegen_type (name, cg) = |
|
381 |
map_codegen_data |
|
382 |
(fn (modl, gens, lookups, serialize_data, logic_data) => |
|
383 |
(modl, |
|
384 |
gens |> map_gens |
|
| 18335 | 385 |
(fn (exprgens_sort, exprgens_type, exprgens_term, appgens, defgens) => |
| 18304 | 386 |
(exprgens_sort, |
387 |
exprgens_type |
|
| 18217 | 388 |
|> Output.update_warn (op =) ("overwriting existing type code generator " ^ name) (name, (cg, stamp ())),
|
| 18335 | 389 |
exprgens_term, appgens, defgens)), lookups, serialize_data, logic_data)); |
| 18217 | 390 |
|
391 |
fun add_codegen_expr (name, cg) = |
|
392 |
map_codegen_data |
|
393 |
(fn (modl, gens, lookups, serialize_data, logic_data) => |
|
394 |
(modl, |
|
395 |
gens |> map_gens |
|
| 18335 | 396 |
(fn (exprgens_sort, exprgens_type, exprgens_term, appgens, defgens) => |
| 18304 | 397 |
(exprgens_sort, exprgens_type, |
398 |
exprgens_term |
|
| 18217 | 399 |
|> Output.update_warn (op =) ("overwriting existing expression code generator " ^ name) (name, (cg, stamp ())),
|
| 18335 | 400 |
appgens, defgens)), |
| 18217 | 401 |
lookups, serialize_data, logic_data)); |
402 |
||
| 18335 | 403 |
fun add_appgen (name, ag) = |
404 |
map_codegen_data |
|
405 |
(fn (modl, gens, lookups, serialize_data, logic_data) => |
|
406 |
(modl, |
|
407 |
gens |> map_gens |
|
408 |
(fn (exprgens_sort, exprgens_type, exprgens_term, appgens, defgens) => |
|
409 |
(exprgens_sort, exprgens_type, exprgens_term, |
|
410 |
appgens |
|
411 |
|> Output.update_warn (op =) ("overwriting existing definition application generator " ^ name) (name, (ag, stamp ())),
|
|
412 |
defgens)), lookups, serialize_data, logic_data)); |
|
413 |
||
| 18217 | 414 |
fun add_defgen (name, dg) = |
415 |
map_codegen_data |
|
416 |
(fn (modl, gens, lookups, serialize_data, logic_data) => |
|
417 |
(modl, |
|
418 |
gens |> map_gens |
|
| 18335 | 419 |
(fn (exprgens_sort, exprgens_type, exprgens_term, appgens, defgens) => |
| 18304 | 420 |
(exprgens_sort, exprgens_type, exprgens_term, |
| 18335 | 421 |
appgens, defgens |
422 |
|> Output.update_warn (op =) ("overwriting existing definition definition generator " ^ name) (name, (dg, stamp ())))),
|
|
| 18217 | 423 |
lookups, serialize_data, logic_data)); |
424 |
||
| 18454 | 425 |
fun get_defgens thy tabs = |
426 |
(map (apsnd (fn (dg, _) => dg thy tabs)) o #defgens o #gens o CodegenData.get) thy; |
|
| 18217 | 427 |
|
428 |
fun add_lookup_tyco (src, dst) = |
|
429 |
map_codegen_data |
|
430 |
(fn (modl, gens, lookups, serialize_data, logic_data) => |
|
431 |
(modl, gens, |
|
432 |
lookups |> map_lookups |
|
433 |
(fn (lookups_tyco, lookups_const) => |
|
434 |
(lookups_tyco |> Symtab.update_new (src, dst), |
|
| 18282 | 435 |
lookups_const)), |
| 18217 | 436 |
serialize_data, logic_data)); |
437 |
||
| 18454 | 438 |
val lookup_tyco = Symtab.lookup o #lookups_tyco o #lookups o CodegenData.get; |
439 |
||
| 18217 | 440 |
fun add_lookup_const ((src, ty), dst) = |
441 |
map_codegen_data |
|
442 |
(fn (modl, gens, lookups, serialize_data, logic_data) => |
|
443 |
(modl, gens, |
|
444 |
lookups |> map_lookups |
|
445 |
(fn (lookups_tyco, lookups_const) => |
|
446 |
(lookups_tyco, |
|
| 18282 | 447 |
lookups_const |> Symtab.update_multi (src, (ty, dst)))), |
| 18217 | 448 |
serialize_data, logic_data)); |
449 |
||
| 18454 | 450 |
fun lookup_const thy (f, ty) = |
451 |
(Symtab.lookup_multi o #lookups_const o #lookups o CodegenData.get) thy f |
|
452 |
|> (fn tab => AList.lookup (Sign.typ_instance thy) tab ty); |
|
453 |
||
| 18217 | 454 |
fun set_is_datatype f = |
455 |
map_codegen_data |
|
456 |
(fn (modl, gens, lookups, serialize_data, logic_data) => |
|
457 |
(modl, gens, lookups, serialize_data, |
|
458 |
logic_data |
|
| 18454 | 459 |
|> map_logic_data ((apfst o apfst) (K (SOME (f, stamp ())))))); |
460 |
||
461 |
fun is_datatype thy = |
|
462 |
case (#is_datatype o #logic_data o CodegenData.get) thy |
|
463 |
of NONE => K false |
|
464 |
| SOME (f, _) => f thy; |
|
465 |
||
466 |
fun set_get_all_datatype_cons f = |
|
467 |
map_codegen_data |
|
468 |
(fn (modl, gens, lookups, serialize_data, logic_data) => |
|
469 |
(modl, gens, lookups, serialize_data, |
|
470 |
logic_data |
|
471 |
|> map_logic_data ((apfst o apsnd) (K (SOME (f, stamp ())))))); |
|
472 |
||
473 |
fun get_all_datatype_cons thy = |
|
474 |
case (#get_all_datatype_cons o #logic_data o CodegenData.get) thy |
|
475 |
of NONE => [] |
|
476 |
| SOME (f, _) => f thy; |
|
| 18217 | 477 |
|
478 |
fun add_alias (src, dst) = |
|
479 |
map_codegen_data |
|
480 |
(fn (modl, gens, lookups, serialize_data, logic_data) => |
|
481 |
(modl, gens, lookups, serialize_data, |
|
482 |
logic_data |> map_logic_data |
|
483 |
(apsnd (fn (tab, tab_rev) => |
|
484 |
(tab |> Symtab.update (src, dst), |
|
485 |
tab_rev |> Symtab.update (dst, src)))))); |
|
486 |
||
487 |
||
| 18454 | 488 |
(* name handling *) |
| 18217 | 489 |
|
| 18454 | 490 |
val nsp_class = "class"; |
491 |
val nsp_tyco = "tyco"; |
|
492 |
val nsp_const = "const"; |
|
493 |
val nsp_overl = "overl"; |
|
494 |
val nsp_dtcon = "dtcon"; |
|
495 |
val nsp_mem = "mem"; |
|
496 |
val nsp_inst = "inst"; |
|
497 |
val nsp_eq_inst = "eq_inst"; |
|
498 |
val nsp_eq_pred = "eq"; |
|
| 18217 | 499 |
|
| 18454 | 500 |
val alias_get = perhaps o Symtab.lookup o fst o #alias o #logic_data o CodegenData.get; |
501 |
val alias_rev = perhaps o Symtab.lookup o snd o #alias o #logic_data o CodegenData.get; |
|
| 18217 | 502 |
|
| 18454 | 503 |
fun add_nsp shallow name = |
504 |
name |
|
505 |
|> NameSpace.unpack |
|
506 |
|> split_last |
|
507 |
|> apsnd (single #> cons shallow) |
|
508 |
|> (op @) |
|
509 |
|> NameSpace.pack; |
|
510 |
fun dest_nsp nsp idf = |
|
| 18217 | 511 |
let |
512 |
val idf' = NameSpace.unpack idf; |
|
513 |
val (idf'', idf_base) = split_last idf'; |
|
514 |
val (modl, shallow) = split_last idf''; |
|
515 |
in |
|
516 |
if nsp = shallow |
|
| 18454 | 517 |
then (SOME o NameSpace.pack) (modl @ [idf_base]) |
| 18217 | 518 |
else NONE |
519 |
end; |
|
520 |
||
| 18454 | 521 |
fun idf_of_name thy shallow name = |
522 |
if is_number name |
|
523 |
then name |
|
| 18217 | 524 |
else |
| 18454 | 525 |
name |
526 |
|> alias_get thy |
|
527 |
|> add_nsp shallow; |
|
528 |
fun name_of_idf thy shallow idf = |
|
529 |
idf |
|
530 |
|> dest_nsp shallow |
|
531 |
|> Option.map (alias_rev thy); |
|
| 18217 | 532 |
|
| 18454 | 533 |
(* code generator instantiation *) |
| 18217 | 534 |
|
| 18454 | 535 |
fun invoke_cg_sort thy tabs sort trns = |
| 18217 | 536 |
gen_invoke |
| 18454 | 537 |
((map (apsnd (fn (cg, _) => cg thy tabs)) o #exprgens_sort o #gens o CodegenData.get) thy) |
| 18231 | 538 |
("generating sort " ^ (quote o Sign.string_of_sort thy) sort) sort trns;
|
| 18217 | 539 |
|
| 18454 | 540 |
fun invoke_cg_type thy tabs ty trns = |
| 18217 | 541 |
gen_invoke |
| 18454 | 542 |
((map (apsnd (fn (cg, _) => cg thy tabs)) o #exprgens_type o #gens o CodegenData.get) thy) |
| 18231 | 543 |
("generating type " ^ (quote o Sign.string_of_typ thy) ty) ty trns;
|
| 18217 | 544 |
|
| 18454 | 545 |
fun invoke_cg_expr thy tabs t trns = |
| 18217 | 546 |
gen_invoke |
| 18454 | 547 |
((map (apsnd (fn (cg, _) => cg thy tabs)) o #exprgens_term o #gens o CodegenData.get) thy) |
| 18231 | 548 |
("generating expression " ^ (quote o Sign.string_of_term thy) t) t trns;
|
| 18217 | 549 |
|
| 18454 | 550 |
fun invoke_appgen thy tabs (app as ((f, ty), ts)) trns = |
| 18335 | 551 |
gen_invoke |
| 18454 | 552 |
((map (apsnd (fn (ag, _) => ag thy tabs)) o #appgens o #gens o CodegenData.get) thy) |
| 18335 | 553 |
("generating application " ^ f ^ "::" ^ (Sign.string_of_typ thy) ty
|
554 |
^ " " ^ enclose "(" ")" (commas (map (Sign.string_of_term thy) ts))) app trns;
|
|
555 |
||
| 18454 | 556 |
fun ensure_def_class thy tabs cls trns = |
557 |
let |
|
558 |
val cls' = idf_of_name thy nsp_class cls; |
|
559 |
in |
|
560 |
trns |
|
561 |
|> debug 4 (fn _ => "generating class " ^ quote cls) |
|
562 |
|> gen_ensure_def (get_defgens thy tabs) ("generating class " ^ quote cls) cls'
|
|
563 |
|> pair cls' |
|
564 |
end; |
|
| 18217 | 565 |
|
| 18454 | 566 |
fun ensure_def_inst thy (tabs as (_, (insttab, _, _))) (cls, tyco) trns = |
567 |
let |
|
568 |
val thyname = (the o AList.lookup (op =) (ClassPackage.the_tycos thy cls)) tyco; |
|
569 |
val inst = idf_of_name thy nsp_inst (InstNameMangler.get thy insttab (thyname, (cls, tyco))); |
|
570 |
in |
|
571 |
trns |
|
572 |
|> debug 4 (fn _ => "generating instance " ^ quote cls ^ " / " ^ quote tyco) |
|
573 |
|> gen_ensure_def (get_defgens thy tabs) ("generating instance " ^ quote cls ^ " / " ^ quote tyco) inst
|
|
574 |
|> pair inst |
|
575 |
end; |
|
| 18335 | 576 |
|
| 18454 | 577 |
fun ensure_def_tyco thy tabs tyco trns = |
578 |
let |
|
579 |
val tyco' = idf_of_name thy nsp_tyco tyco; |
|
580 |
in case lookup_tyco thy tyco |
|
| 18217 | 581 |
of NONE => |
582 |
trns |
|
| 18231 | 583 |
|> debug 4 (fn _ => "generating type constructor " ^ quote tyco) |
| 18454 | 584 |
|> gen_ensure_def (get_defgens thy tabs) ("generating type constructor " ^ quote tyco) tyco'
|
585 |
|> pair tyco' |
|
| 18217 | 586 |
| SOME tyco => |
587 |
trns |
|
588 |
|> pair tyco |
|
| 18454 | 589 |
end; |
590 |
||
591 |
fun idf_of_const thy (tabs as ((_, clsmemtab), (_, (overltab1, overltab2), dtcontab))) (c, ty) = |
|
592 |
let |
|
593 |
val coty = case (snd o strip_type) ty |
|
594 |
of Type (tyco, _) => tyco |
|
595 |
| _ => ""; |
|
596 |
val c' = case Symtab.lookup overltab1 c |
|
597 |
of SOME (ty_decl, tys) => ConstNameMangler.get thy overltab2 |
|
| 18455 | 598 |
(idf_of_name thy nsp_overl c, (ty_decl, (the oo find_first) (fn ty' => Sign.typ_instance thy (ty', ty)) tys)) |
| 18454 | 599 |
| NONE => case try (DatatypeconsNameMangler.get thy dtcontab) (c, coty) |
600 |
of SOME c' => idf_of_name thy nsp_dtcon c' |
|
601 |
| NONE => case Symtab.lookup clsmemtab c |
|
602 |
of SOME _ => idf_of_name thy nsp_mem c |
|
603 |
| NONE => idf_of_name thy nsp_const c; |
|
604 |
in c' end; |
|
| 18217 | 605 |
|
| 18454 | 606 |
fun recconst_of_idf thy (_, (_, (_, overltab2), _)) idf = |
607 |
case name_of_idf thy nsp_const idf |
|
608 |
of SOME c => SOME (c, Sign.the_const_constraint thy c) |
|
609 |
| NONE => ( |
|
610 |
case dest_nsp nsp_overl idf |
|
611 |
of SOME _ => |
|
612 |
idf |
|
613 |
|> ConstNameMangler.rev thy overltab2 |
|
614 |
|> apfst (the o name_of_idf thy nsp_overl) |
|
615 |
|> apsnd snd |
|
616 |
|> SOME |
|
617 |
| NONE => NONE |
|
618 |
); |
|
619 |
||
620 |
fun ensure_def_const thy (tabs as ((_, clsmemtab), (_, overltab, dtcontab))) (c, ty) trns = |
|
621 |
let |
|
622 |
val c' = idf_of_const thy tabs (c, ty); |
|
623 |
in case lookup_const thy (c, ty) |
|
| 18217 | 624 |
of NONE => |
625 |
trns |
|
| 18454 | 626 |
|> debug 4 (fn _ => "generating constant " ^ quote c) |
627 |
|> invoke_cg_type thy tabs (ty |> devarify_type) |
|
628 |
||> gen_ensure_def (get_defgens thy tabs) ("generating constant " ^ quote c) c'
|
|
629 |
|-> (fn _ => pair c') |
|
630 |
| SOME (IConst (c, ty)) => |
|
| 18217 | 631 |
trns |
| 18454 | 632 |
|> pair c |
633 |
end; |
|
| 18217 | 634 |
|
| 18454 | 635 |
fun ensure_def_eq thy tabs (dtco, (eqpred, arity)) trns = |
636 |
let |
|
637 |
val name_dtco = (the ooo name_of_idf) thy nsp_tyco dtco; |
|
638 |
val idf_eqinst = idf_of_name thy nsp_eq_inst name_dtco; |
|
639 |
val idf_eqpred = idf_of_name thy nsp_eq_pred name_dtco; |
|
640 |
fun mk_eq_pred _ trns = |
|
641 |
trns |
|
642 |
|> succeed (eqpred, []) |
|
643 |
fun mk_eq_inst _ trns = |
|
644 |
trns |
|
645 |
|> gen_ensure_def [("eqpred", mk_eq_pred)] ("generating equality predicate for " ^ quote dtco) idf_eqpred
|
|
646 |
|> succeed (Classinst (class_eq, (dtco, arity), [(fun_eq, idf_eqpred)]), []); |
|
647 |
in |
|
648 |
trns |
|
649 |
|> gen_ensure_def [("eqinst", mk_eq_inst)] ("generating equality instance for " ^ quote dtco) idf_eqinst
|
|
650 |
end; |
|
651 |
||
652 |
||
653 |
(* code generator auxiliary *) |
|
654 |
||
655 |
fun mk_fun thy tabs eqs ty trns = |
|
| 18217 | 656 |
let |
657 |
val sortctxt = ClassPackage.extract_sortctxt thy ty; |
|
658 |
fun mk_sortvar (v, sort) trns = |
|
659 |
trns |
|
| 18454 | 660 |
|> invoke_cg_sort thy tabs sort |
| 18217 | 661 |
|-> (fn sort => pair (unprefix "'" v, sort)) |
662 |
fun mk_eq (args, rhs) trns = |
|
663 |
trns |
|
| 18454 | 664 |
|> fold_map (invoke_cg_expr thy tabs o devarify_term) args |
665 |
||>> (invoke_cg_expr thy tabs o devarify_term) rhs |
|
| 18217 | 666 |
|-> (fn (args, rhs) => pair (map ipat_of_iexpr args, rhs)) |
667 |
in |
|
668 |
trns |
|
669 |
|> fold_map mk_eq eqs |
|
| 18454 | 670 |
||>> invoke_cg_type thy tabs (devarify_type ty) |
| 18217 | 671 |
||>> fold_map mk_sortvar sortctxt |
672 |
|-> (fn ((eqs, ty), sortctxt) => pair (Fun (eqs, (sortctxt, ty)))) |
|
673 |
end; |
|
674 |
||
| 18454 | 675 |
fun fix_nargs thy tabs gen (imin, imax) (t, ts) trns = |
| 18335 | 676 |
if length ts < imin then |
| 18385 | 677 |
let |
678 |
val d = imin - length ts; |
|
679 |
val vs = Term.invent_names (add_term_names (t, [])) "x" d; |
|
680 |
val tys = Library.take (d, ((fst o strip_type o fastype_of) t)); |
|
681 |
in |
|
682 |
trns |
|
683 |
|> debug 10 (fn _ => "eta-expanding") |
|
| 18454 | 684 |
|> fold_map (invoke_cg_type thy tabs) tys |
| 18385 | 685 |
||>> gen (t, ts @ map2 (curry Free) vs tys) |
686 |
|-> (fn (tys, e) => succeed ((vs ~~ tys) `|--> e)) |
|
687 |
end |
|
| 18335 | 688 |
else if length ts > imax then |
689 |
trns |
|
690 |
|> debug 10 (fn _ => "splitting arguments (" ^ string_of_int imax ^ ", " ^ string_of_int (length ts) ^ ")")
|
|
691 |
|> gen (t, Library.take (imax, ts)) |
|
| 18454 | 692 |
||>> fold_map (invoke_cg_expr thy tabs) (Library.drop (imax, ts)) |
| 18335 | 693 |
|-> succeed o mk_apps |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
694 |
else |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
695 |
trns |
| 18335 | 696 |
|> debug 10 (fn _ => "keeping arguments") |
697 |
|> gen (t, ts) |
|
698 |
|-> succeed; |
|
| 18217 | 699 |
|
700 |
||
| 18454 | 701 |
(* expression generators *) |
| 18217 | 702 |
|
| 18454 | 703 |
fun exprgen_sort_default thy tabs sort trns = |
| 18217 | 704 |
trns |
| 18454 | 705 |
|> fold_map (ensure_def_class thy tabs) (ClassPackage.syntactic_sort_of thy sort) |
| 18231 | 706 |
|-> (fn sort => succeed sort) |
| 18217 | 707 |
|
| 18454 | 708 |
fun exprgen_type_default thy tabs (TVar _) trns = |
| 18335 | 709 |
error "TVar encountered during code generation" |
| 18454 | 710 |
| exprgen_type_default thy tabs (TFree (v, sort)) trns = |
| 18217 | 711 |
trns |
| 18454 | 712 |
|> invoke_cg_sort thy tabs sort |
| 18335 | 713 |
|-> (fn sort => succeed (IVarT (v |> unprefix "'", sort))) |
| 18454 | 714 |
| exprgen_type_default thy tabs (Type ("fun", [t1, t2])) trns =
|
| 18217 | 715 |
trns |
| 18454 | 716 |
|> invoke_cg_type thy tabs t1 |
717 |
||>> invoke_cg_type thy tabs t2 |
|
| 18217 | 718 |
|-> (fn (t1', t2') => succeed (t1' `-> t2')) |
| 18454 | 719 |
| exprgen_type_default thy tabs (Type (tyco, tys)) trns = |
| 18217 | 720 |
trns |
| 18454 | 721 |
|> ensure_def_tyco thy tabs tyco |
722 |
||>> fold_map (invoke_cg_type thy tabs) tys |
|
| 18217 | 723 |
|-> (fn (tyco, tys) => succeed (tyco `%% tys)) |
724 |
||
| 18454 | 725 |
fun exprgen_term_default thy tabs (Const (f, ty)) trns = |
| 18335 | 726 |
trns |
| 18454 | 727 |
|> invoke_appgen thy tabs ((f, ty), []) |
| 18335 | 728 |
|-> (fn e => succeed e) |
| 18454 | 729 |
| exprgen_term_default thy tabs (Var ((v, i), ty)) trns = |
| 18335 | 730 |
trns |
| 18454 | 731 |
|> invoke_cg_type thy tabs ty |
| 18335 | 732 |
|-> (fn ty => succeed (IVarE (if i = 0 then v else v ^ "_" ^ string_of_int i, ty))) |
| 18454 | 733 |
| exprgen_term_default thy tabs (Free (v, ty)) trns = |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
734 |
trns |
| 18454 | 735 |
|> invoke_cg_type thy tabs ty |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
736 |
|-> (fn ty => succeed (IVarE (v, ty))) |
| 18454 | 737 |
| exprgen_term_default thy tabs (Abs (v, ty, t)) trns = |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
738 |
trns |
| 18454 | 739 |
|> invoke_cg_type thy tabs ty |
740 |
||>> invoke_cg_expr thy tabs (subst_bound (Free (v, ty), t)) |
|
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
741 |
|-> (fn (ty, e) => succeed ((v, ty) `|-> e)) |
| 18454 | 742 |
| exprgen_term_default thy tabs (t as t1 $ t2) trns = |
| 18335 | 743 |
let |
744 |
val (t', ts) = strip_comb t |
|
745 |
in case t' |
|
746 |
of Const (f, ty) => |
|
747 |
trns |
|
| 18454 | 748 |
|> invoke_appgen thy tabs ((f, ty), ts) |
| 18335 | 749 |
|-> (fn e => succeed e) |
750 |
| _ => |
|
751 |
trns |
|
| 18454 | 752 |
|> invoke_cg_expr thy tabs t' |
753 |
||>> fold_map (invoke_cg_expr thy tabs) ts |
|
| 18335 | 754 |
|-> (fn (e, es) => succeed (e `$$ es)) |
755 |
end; |
|
756 |
||
| 18454 | 757 |
|
758 |
(* application generators *) |
|
759 |
||
760 |
fun appgen_default thy tabs ((f, ty), ts) trns = |
|
| 18335 | 761 |
let |
762 |
val _ = debug 5 (fn _ => "making application of " ^ quote f) (); |
|
763 |
val ty_def = Sign.the_const_constraint thy f; |
|
| 18454 | 764 |
fun mk_lookup (ClassPackage.Instance (inst as (cls, tyco), ls)) trns = |
| 18335 | 765 |
trns |
| 18454 | 766 |
|> ensure_def_class thy tabs cls |
767 |
||>> ensure_def_inst thy tabs inst |
|
| 18335 | 768 |
||>> (fold_map o fold_map) mk_lookup ls |
769 |
|-> (fn ((cls, i), ls) => pair (ClassPackage.Instance ((cls, i), ls))) |
|
770 |
| mk_lookup (ClassPackage.Lookup (clss, (v, i))) trns = |
|
771 |
trns |
|
| 18454 | 772 |
|> fold_map (ensure_def_class thy tabs) clss |
| 18335 | 773 |
|-> (fn clss => pair (ClassPackage.Lookup (clss, (v |> unprefix "'", i)))); |
774 |
fun mk_itapp e [] = e |
|
775 |
| mk_itapp e lookup = IInst (e, lookup); |
|
776 |
in |
|
777 |
trns |
|
| 18454 | 778 |
|> ensure_def_const thy tabs (f, ty) |
| 18335 | 779 |
||>> (fold_map o fold_map) mk_lookup (ClassPackage.extract_sortlookup thy (ty_def, ty)) |
| 18454 | 780 |
||>> invoke_cg_type thy tabs ty |
781 |
||>> fold_map (invoke_cg_expr thy tabs) ts |
|
| 18335 | 782 |
|-> (fn (((f, lookup), ty), es) => |
783 |
succeed (mk_itapp (IConst (f, ty)) lookup `$$ es)) |
|
784 |
end |
|
785 |
||
| 18454 | 786 |
fun appgen_neg thy tabs (f as ("neg", Type ("fun", [ty, _])), ts) trns =
|
| 18335 | 787 |
let |
788 |
fun gen_neg _ trns = |
|
789 |
trns |
|
| 18454 | 790 |
|> invoke_cg_expr thy tabs (Const ("op >", ty --> ty --> Type ("bool", [])) $ Const ("0", ty))
|
| 18335 | 791 |
in |
792 |
trns |
|
| 18454 | 793 |
|> fix_nargs thy tabs gen_neg (0, 0) (Const f, ts) |
| 18335 | 794 |
end |
| 18454 | 795 |
| appgen_neg thy tabs ((f, _), _) trns = |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
796 |
trns |
| 18335 | 797 |
|> fail ("not a negation: " ^ quote f);
|
798 |
||
| 18454 | 799 |
fun appgen_eq thy tabs (f as ("op =", Type ("fun", [ty, _])), ts) trns =
|
| 18385 | 800 |
let |
801 |
fun mk_eq_expr (_, [t1, t2]) trns = |
|
802 |
trns |
|
| 18454 | 803 |
|> invoke_eq (invoke_cg_type thy tabs) (ensure_def_eq thy tabs) ty |
| 18385 | 804 |
|-> (fn false => error ("could not derive equality for " ^ Sign.string_of_typ thy ty)
|
805 |
| true => fn trns => trns |
|
| 18454 | 806 |
|> invoke_cg_expr thy tabs t1 |
807 |
||>> invoke_cg_expr thy tabs t2 |
|
| 18385 | 808 |
|-> (fn (e1, e2) => pair (Fun_eq `$ e1 `$ e2))) |
809 |
in |
|
810 |
trns |
|
| 18454 | 811 |
|> fix_nargs thy tabs mk_eq_expr (2, 2) (Const f, ts) |
| 18385 | 812 |
end |
| 18454 | 813 |
| appgen_eq thy tabs ((f, _), _) trns = |
| 18385 | 814 |
trns |
815 |
|> fail ("not an equality: " ^ quote f);
|
|
| 18217 | 816 |
|
817 |
||
818 |
(* definition generators *) |
|
|
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
819 |
|
| 18454 | 820 |
fun defgen_tyco_fallback thy tabs tyco trns = |
| 18217 | 821 |
if Symtab.fold (fn (_, { syntax_tyco, ... }) => fn b => b orelse Symtab.defined syntax_tyco tyco)
|
| 18282 | 822 |
((#serialize_data o CodegenData.get) thy) false |
| 18217 | 823 |
then |
824 |
trns |
|
| 18231 | 825 |
|> debug 5 (fn _ => "trying defgen tyco fallback for " ^ quote tyco) |
| 18217 | 826 |
|> succeed (Nop, []) |
827 |
else |
|
828 |
trns |
|
829 |
|> fail ("no code generation fallback for " ^ quote tyco)
|
|
830 |
||
| 18454 | 831 |
fun defgen_const_fallback thy tabs c trns = |
832 |
if Symtab.fold (fn (_, { syntax_const, ... }) => fn b => b orelse Symtab.defined syntax_const c)
|
|
| 18282 | 833 |
((#serialize_data o CodegenData.get) thy) false |
| 18217 | 834 |
then |
835 |
trns |
|
| 18454 | 836 |
|> debug 5 (fn _ => "trying defgen const fallback for " ^ quote c) |
| 18217 | 837 |
|> succeed (Nop, []) |
838 |
else |
|
839 |
trns |
|
| 18454 | 840 |
|> fail ("no code generation fallback for " ^ quote c)
|
| 18217 | 841 |
|
| 18454 | 842 |
fun defgen_defs thy (tabs as ((deftab, _), _)) c trns = |
843 |
case Symtab.lookup deftab c |
|
844 |
of SOME (ty, (args, rhs)) => |
|
| 18217 | 845 |
trns |
| 18454 | 846 |
|> debug 5 (fn _ => "trying defgen def for " ^ quote c) |
847 |
|> mk_fun thy tabs [(args, rhs)] (devarify_type ty) |
|
| 18217 | 848 |
|-> (fn def => succeed (def, [])) |
| 18454 | 849 |
| _ => trns |> fail ("no definition found for " ^ quote c);
|
| 18217 | 850 |
|
| 18454 | 851 |
fun defgen_clsdecl thy (tabs as (_, (insttab, _, _))) (cls : string) trns = |
| 18217 | 852 |
case name_of_idf thy nsp_class cls |
853 |
of SOME cls => |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
854 |
let |
| 18454 | 855 |
val memnames = ClassPackage.the_consts thy (cls : string); |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
856 |
val memtypes = map (devarify_type o ClassPackage.get_const_sign thy "'a") memnames; |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
857 |
val memctxt = map (ClassPackage.extract_sortctxt thy) memtypes; |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
858 |
val memidfs = map (idf_of_name thy nsp_mem) memnames; |
| 18454 | 859 |
fun mk_instname (tyco, thyname) = idf_of_name thy nsp_inst (InstNameMangler.get thy insttab (thyname, (cls, tyco))) |
860 |
val instnames = map mk_instname (ClassPackage.the_tycos thy cls); |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
861 |
in |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
862 |
trns |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
863 |
|> debug 5 (fn _ => "trying defgen class declaration for " ^ quote cls) |
| 18454 | 864 |
|> fold_map (ensure_def_class thy tabs) (ClassPackage.get_superclasses thy cls) |
865 |
||>> fold_map (invoke_cg_type thy tabs) memtypes |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
866 |
|-> (fn (supcls, memtypes) => succeed (Class (supcls, "a", memidfs ~~ (memctxt ~~ memtypes), []), |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
867 |
memidfs @ instnames)) |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
868 |
end |
| 18217 | 869 |
| _ => |
870 |
trns |
|
871 |
|> fail ("no class definition found for " ^ quote cls);
|
|
872 |
||
| 18454 | 873 |
fun defgen_clsmem thy tabs m trns = |
874 |
case name_of_idf thy nsp_mem m |
|
875 |
of SOME m => |
|
| 18360 | 876 |
trns |
| 18454 | 877 |
|> debug 5 (fn _ => "trying defgen class member for " ^ quote m) |
878 |
|> ensure_def_class thy tabs ((the o ClassPackage.lookup_const_class thy) m) |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
879 |
|-> (fn cls => succeed (Classmember cls, [])) |
| 18217 | 880 |
| _ => |
| 18454 | 881 |
trns |> fail ("no class member found for " ^ quote m)
|
| 18217 | 882 |
|
| 18454 | 883 |
fun defgen_clsinst thy (tabs as (_, (insttab, _, _))) inst trns = |
884 |
case Option.map (InstNameMangler.rev thy insttab) (name_of_idf thy nsp_inst inst) |
|
885 |
of SOME (_, (cls, tyco)) => |
|
| 18217 | 886 |
let |
| 18454 | 887 |
val arity = ClassPackage.get_arities thy [cls] tyco; |
888 |
val ms = map (fn m => (m, Sign.the_const_constraint thy m)) (ClassPackage.the_consts thy cls); |
|
889 |
val instmem_idfs = ClassPackage.get_inst_consts_sign thy (tyco, cls); |
|
| 18335 | 890 |
fun add_vars arity clsmems (trns as (_, modl)) = |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
891 |
case get_def modl (idf_of_name thy nsp_class cls) |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
892 |
of Class (_, _, members, _) => ((Term.invent_names |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
893 |
(tvars_of_itypes ((map (snd o snd)) members)) "a" (length arity) ~~ arity, clsmems), trns) |
| 18217 | 894 |
in |
895 |
trns |
|
| 18231 | 896 |
|> debug 5 (fn _ => "trying defgen class instance for (" ^ quote cls ^ ", " ^ quote tyco ^ ")")
|
| 18454 | 897 |
|> (fold_map o fold_map) (ensure_def_class thy tabs) arity |
898 |
||>> fold_map (ensure_def_const thy tabs) ms |
|
899 |
|-> (fn (arity, ms) => add_vars arity ms) |
|
900 |
||>> ensure_def_class thy tabs cls |
|
901 |
||>> ensure_def_tyco thy tabs tyco |
|
902 |
||>> fold_map (ensure_def_const thy tabs) instmem_idfs |
|
903 |
|-> (fn ((((arity, ms), cls), tyco), instmem_idfs) => |
|
904 |
succeed (Classinst (cls, (tyco, arity), ms ~~ instmem_idfs), [])) |
|
| 18217 | 905 |
end |
906 |
| _ => |
|
| 18454 | 907 |
trns |> fail ("no class instance found for " ^ quote inst);
|
| 18217 | 908 |
|
909 |
||
910 |
(* parametrized generators, for instantiation in HOL *) |
|
911 |
||
| 18454 | 912 |
fun appgen_let strip_abs thy tabs (f as ("Let", _), ts) trns =
|
| 18335 | 913 |
let |
914 |
fun dest_let (l as Const ("Let", _) $ t $ u) =
|
|
915 |
(case strip_abs 1 u |
|
916 |
of ([p], u') => apfst (cons (p, t)) (dest_let u') |
|
917 |
| _ => ([], l)) |
|
918 |
| dest_let t = ([], t); |
|
919 |
fun mk_let (l, r) trns = |
|
| 18217 | 920 |
trns |
| 18454 | 921 |
|> invoke_cg_expr thy tabs l |
922 |
||>> invoke_cg_expr thy tabs r |
|
| 18335 | 923 |
|-> (fn (l, r) => pair (r, ipat_of_iexpr l)); |
924 |
fun gen_let (t1, [t2, t3]) trns = |
|
925 |
let |
|
926 |
val (lets, body) = dest_let (t1 $ t2 $ t3) |
|
927 |
in |
|
928 |
trns |
|
929 |
|> fold_map mk_let lets |
|
| 18454 | 930 |
||>> invoke_cg_expr thy tabs body |
| 18335 | 931 |
|-> (fn (lets, body) => |
932 |
pair (Library.foldr (fn ((e, p), body) => ICase (e, [(p, body)])) (lets, body))) |
|
933 |
end; |
|
934 |
in |
|
935 |
trns |
|
| 18454 | 936 |
|> fix_nargs thy tabs gen_let (2, 2) (Const f, ts) |
| 18335 | 937 |
end |
| 18454 | 938 |
| appgen_let strip_abs thy tabs ((f, _), _) trns = |
| 18335 | 939 |
trns |
940 |
|> fail ("not a let: " ^ quote f);
|
|
| 18217 | 941 |
|
| 18454 | 942 |
fun appgen_split strip_abs thy tabs (f as ("split", _), ts) trns =
|
| 18335 | 943 |
let |
944 |
fun gen_split (t1, [t2]) trns = |
|
945 |
let |
|
946 |
val ([p], body) = strip_abs 1 (t1 $ t2) |
|
947 |
in |
|
948 |
trns |
|
| 18454 | 949 |
|> invoke_cg_expr thy tabs p |
950 |
||>> invoke_cg_expr thy tabs body |
|
| 18335 | 951 |
|-> (fn (IVarE v, body) => pair (IAbs (v, body))) |
952 |
end |
|
953 |
in |
|
954 |
trns |
|
| 18454 | 955 |
|> fix_nargs thy tabs gen_split (1, 1) (Const f, ts) |
| 18335 | 956 |
end |
| 18454 | 957 |
| appgen_split strip_abs thy tabs ((f, _), _) trns = |
| 18335 | 958 |
trns |
959 |
|> fail ("not a split: " ^ quote f);
|
|
960 |
||
| 18454 | 961 |
fun appgen_number_of dest_binum mk_int_to_nat thy tabs (f as ("Numeral.number_of",
|
| 18335 | 962 |
Type ("fun", [_, Type ("IntDef.int", [])])), ts) trns =
|
963 |
let |
|
964 |
fun gen_num (_, [bin]) trns = |
|
| 18217 | 965 |
trns |
| 18335 | 966 |
|> (pair (IConst ((IntInf.toString o dest_binum) bin, Type_integer)) |
967 |
handle TERM _ |
|
968 |
=> error ("not a number: " ^ Sign.string_of_term thy bin))
|
|
969 |
in |
|
970 |
trns |
|
| 18454 | 971 |
|> fix_nargs thy tabs gen_num (1, 1) (Const f, ts) |
| 18335 | 972 |
end |
| 18454 | 973 |
| appgen_number_of dest_binum mk_int_to_nat thy tabs (f as ("Numeral.number_of",
|
| 18335 | 974 |
Type ("fun", [_, Type ("nat", [])])), ts) trns =
|
975 |
let |
|
976 |
fun gen_num (_, [bin]) trns = |
|
977 |
trns |
|
| 18454 | 978 |
|> invoke_cg_expr thy tabs (mk_int_to_nat bin) |
| 18335 | 979 |
in |
980 |
trns |
|
| 18454 | 981 |
|> fix_nargs thy tabs gen_num (1, 1) (Const f, ts) |
| 18335 | 982 |
end |
| 18454 | 983 |
| appgen_number_of dest_binum mk_int_to_nat thy tabs ((f, _), _) trns = |
| 18217 | 984 |
trns |
| 18335 | 985 |
|> fail ("not a number_of: " ^ quote f);
|
| 18217 | 986 |
|
| 18454 | 987 |
fun appgen_case get_case_const_data thy tabs ((f, ty), ts) trns = |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
988 |
let |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
989 |
fun cg_case_d gen_names dty (((cname, i), ty), t) trns = |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
990 |
let |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
991 |
val vs = gen_names i; |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
992 |
val tys = Library.take (i, (fst o strip_type) ty); |
| 18330 | 993 |
val frees = map2 (curry Free) vs tys; |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
994 |
val t' = Envir.beta_norm (list_comb (t, frees)); |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
995 |
in |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
996 |
trns |
| 18454 | 997 |
|> invoke_cg_expr thy tabs (list_comb (Const (cname, tys ---> dty), frees)) |
998 |
||>> invoke_cg_expr thy tabs t' |
|
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
999 |
|-> (fn (ep, e) => pair (ipat_of_iexpr ep, e)) |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1000 |
end; |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1001 |
fun cg_case dty cs (_, ts) trns = |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1002 |
let |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1003 |
val (ts', t) = split_last ts |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1004 |
fun gen_names i = |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1005 |
variantlist (replicate i "x", foldr add_term_names |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1006 |
(map (fst o fst o dest_Var) (foldr add_term_vars [] ts)) ts) |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1007 |
in |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1008 |
trns |
| 18454 | 1009 |
|> invoke_cg_expr thy tabs t |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1010 |
||>> fold_map (cg_case_d gen_names dty) (cs ~~ ts') |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1011 |
|-> (fn (t, ds) => pair (ICase (t, ds))) |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1012 |
end; |
| 18335 | 1013 |
in |
1014 |
case get_case_const_data thy f |
|
1015 |
of NONE => |
|
1016 |
trns |
|
1017 |
|> fail ("not a case constant: " ^ quote f)
|
|
1018 |
| SOME cs => |
|
1019 |
let |
|
1020 |
val (tys, dty) = (split_last o fst o strip_type) ty; |
|
1021 |
in |
|
1022 |
trns |
|
| 18454 | 1023 |
|> fix_nargs thy tabs (cg_case dty (cs ~~ tys)) |
| 18335 | 1024 |
(length cs + 1, length cs + 1) (Const (f, ty), ts) |
1025 |
end |
|
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1026 |
end; |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1027 |
|
| 18454 | 1028 |
fun defgen_datatype get_datatype get_datacons thy (tabs as (_, (_, _, dtcontab))) dtco trns = |
1029 |
case name_of_idf thy nsp_tyco dtco |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1030 |
of SOME dtco => |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1031 |
(case get_datatype thy dtco |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1032 |
of SOME (vars, cos) => |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1033 |
let |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1034 |
val cotys = map (the o get_datacons thy o rpair dtco) cos; |
| 18454 | 1035 |
val coidfs = map (fn co => (DatatypeconsNameMangler.get thy dtcontab (co, dtco)) |> |
1036 |
idf_of_name thy nsp_dtcon) cos; |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1037 |
in |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1038 |
trns |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1039 |
|> debug 5 (fn _ => "trying defgen datatype for " ^ quote dtco) |
| 18454 | 1040 |
|> fold_map (invoke_cg_sort thy tabs) (map snd vars) |
1041 |
||>> (fold_map o fold_map) (invoke_cg_type thy tabs o devarify_type) cotys |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1042 |
|-> (fn (sorts, tys) => succeed (Datatype |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1043 |
(map2 (fn (v, _) => fn sort => (unprefix "'" v, sort)) vars sorts, coidfs ~~ tys, []), |
| 18454 | 1044 |
coidfs)) |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1045 |
end |
| 18217 | 1046 |
| NONE => |
1047 |
trns |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1048 |
|> fail ("no datatype found for " ^ quote dtco))
|
| 18217 | 1049 |
| NONE => |
1050 |
trns |
|
| 18454 | 1051 |
|> fail ("not a type constructor: " ^ quote dtco)
|
| 18335 | 1052 |
|
| 18454 | 1053 |
fun defgen_datacons get_datacons thy (tabs as (_, (_, _, dtcontab))) co trns = |
1054 |
case Option.map (DatatypeconsNameMangler.rev thy dtcontab) (name_of_idf thy nsp_dtcon co) |
|
1055 |
of SOME (co, dtco) => |
|
1056 |
trns |
|
1057 |
|> debug 5 (fn _ => "trying defgen datatype constructor for " ^ quote co) |
|
1058 |
|> ensure_def_tyco thy tabs dtco |
|
1059 |
|-> (fn tyco => succeed (Datatypecons tyco, [])) |
|
1060 |
| _ => |
|
1061 |
trns |
|
1062 |
|> fail ("not a datatype constructor: " ^ quote co);
|
|
| 18217 | 1063 |
|
| 18454 | 1064 |
fun defgen_recfun get_equations thy tabs c trns = |
1065 |
case recconst_of_idf thy tabs c |
|
1066 |
of SOME (c, ty) => |
|
| 18217 | 1067 |
let |
| 18454 | 1068 |
val (eqs, ty) = get_equations thy (c, ty); |
| 18217 | 1069 |
in |
1070 |
case eqs |
|
1071 |
of (_::_) => |
|
1072 |
trns |
|
| 18454 | 1073 |
|> debug 5 (fn _ => "trying defgen recfun for " ^ quote c) |
1074 |
|> mk_fun thy tabs eqs (devarify_type ty) |
|
| 18217 | 1075 |
|-> (fn def => succeed (def, [])) |
1076 |
| _ => |
|
1077 |
trns |
|
| 18454 | 1078 |
|> fail ("no recursive definition found for " ^ quote c)
|
| 18217 | 1079 |
end |
1080 |
| NONE => |
|
1081 |
trns |
|
| 18454 | 1082 |
|> fail ("not a constant: " ^ quote c);
|
| 18217 | 1083 |
|
1084 |
||
1085 |
(* theory interface *) |
|
1086 |
||
| 18454 | 1087 |
fun mk_tabs thy = |
| 18217 | 1088 |
let |
| 18454 | 1089 |
fun extract_defs thy = |
| 18217 | 1090 |
let |
| 18454 | 1091 |
fun dest t = |
1092 |
let |
|
1093 |
val (lhs, rhs) = Logic.dest_equals t; |
|
1094 |
val (c, args) = strip_comb lhs; |
|
1095 |
val (s, T) = dest_Const c |
|
1096 |
in if forall is_Var args then SOME (s, (T, (args, rhs))) else NONE |
|
1097 |
end handle TERM _ => NONE; |
|
1098 |
fun prep_def def = (case Codegen.preprocess thy [def] of |
|
1099 |
[def'] => prop_of def' | _ => error "mk_auxtab: bad preprocessor"); |
|
1100 |
fun add_def (name, t) defs = (case dest t of |
|
1101 |
NONE => defs |
|
1102 |
| SOME _ => (case (dest o prep_def oo Thm.get_axiom) thy name of |
|
1103 |
NONE => defs |
|
1104 |
| SOME (s, (T, (args, rhs))) => Symtab.update |
|
1105 |
(s, (T, (split_last (args @ [rhs]))) :: |
|
1106 |
if_none (Symtab.lookup defs s) []) defs)) |
|
| 18217 | 1107 |
in |
| 18454 | 1108 |
Symtab.empty |
1109 |
|> fold (Symtab.fold add_def) (map |
|
1110 |
(snd o #axioms o Theory.rep_theory) (thy :: Theory.ancestors_of thy)) |
|
| 18217 | 1111 |
end; |
| 18454 | 1112 |
fun mk_insttab thy = |
1113 |
InstNameMangler.empty |
|
1114 |
|> Symtab.fold_map |
|
1115 |
(fn (cls, (_, clsinsts)) => fold_map |
|
1116 |
(fn (tyco, thyname) => InstNameMangler.declare thy (thyname, (cls, tyco))) clsinsts) |
|
1117 |
(ClassPackage.get_classtab thy) |
|
1118 |
|-> (fn _ => I); |
|
1119 |
fun mk_overltabs thy defs = |
|
1120 |
(Symtab.empty, ConstNameMangler.empty) |
|
1121 |
|> Symtab.fold |
|
1122 |
(fn (c, [_]) => I |
|
1123 |
| ("0", _) => I
|
|
1124 |
| (c, tytab) => |
|
1125 |
(fn (overltab1, overltab2) => ( |
|
1126 |
overltab1 |
|
1127 |
|> Symtab.update_new (c, (Sign.the_const_constraint thy c, map fst tytab)), |
|
1128 |
overltab2 |
|
1129 |
|> fold (fn (ty, _) => ConstNameMangler.declare thy (idf_of_name thy nsp_overl c, (Sign.the_const_constraint thy c, ty)) #> snd) tytab |
|
1130 |
))) defs; |
|
1131 |
fun mk_dtcontab thy = |
|
1132 |
DatatypeconsNameMangler.empty |
|
1133 |
|> fold_map |
|
| 18455 | 1134 |
(fn (_, co_dtco) => DatatypeconsNameMangler.declare_multi thy co_dtco) |
1135 |
(fold (fn (co, dtco) => |
|
1136 |
let |
|
1137 |
val key = ((NameSpace.drop_base o NameSpace.drop_base) co, NameSpace.base co) |
|
1138 |
in AList.default (op =) (key, []) #> AList.map_entry (op =) key (cons (co, dtco)) end |
|
1139 |
) (get_all_datatype_cons thy) []) |
|
| 18454 | 1140 |
|-> (fn _ => I); |
1141 |
fun mk_deftab thy defs overltab = |
|
1142 |
Symtab.empty |
|
1143 |
|> Symtab.fold |
|
1144 |
(fn (c, [ty_cdef]) => |
|
1145 |
Symtab.update_new (idf_of_name thy nsp_const c, ty_cdef) |
|
1146 |
| ("0", _) => I
|
|
1147 |
| (c, cdefs) => fold (fn (ty, cdef) => |
|
1148 |
let |
|
1149 |
val c' = ConstNameMangler.get thy overltab |
|
1150 |
(idf_of_name thy nsp_overl c, (Sign.the_const_constraint thy c, ty)) |
|
1151 |
in Symtab.update_new (c', (ty, cdef)) end) cdefs) defs; |
|
1152 |
fun mk_clsmemtab thy = |
|
1153 |
Symtab.empty |
|
1154 |
|> Symtab.fold |
|
1155 |
(fn (class, (clsmems, _)) => fold |
|
1156 |
(fn clsmem => Symtab.update (clsmem, class)) clsmems) |
|
1157 |
(ClassPackage.get_classtab thy); |
|
1158 |
val defs = extract_defs thy; |
|
1159 |
val insttab = mk_insttab thy; |
|
1160 |
val overltabs = mk_overltabs thy defs; |
|
1161 |
val dtcontab = mk_dtcontab thy; |
|
1162 |
val deftab = mk_deftab thy defs (snd overltabs); |
|
1163 |
val clsmemtab = mk_clsmemtab thy; |
|
1164 |
in ((deftab, clsmemtab), (insttab, overltabs, dtcontab)) end; |
|
| 18217 | 1165 |
|
| 18335 | 1166 |
fun check_for_serializer serial_name serialize_data = |
1167 |
if Symtab.defined serialize_data serial_name |
|
1168 |
then serialize_data |
|
1169 |
else error ("unknown code serializer: " ^ quote serial_name);
|
|
1170 |
||
| 18231 | 1171 |
fun expand_module defs gen thy = |
| 18217 | 1172 |
let |
1173 |
fun put_module modl = |
|
1174 |
map_codegen_data (fn (_, gens, lookups, serialize_data, logic_data) => |
|
1175 |
(modl, gens, lookups, serialize_data, logic_data)); |
|
1176 |
val _ = put_module : module -> theory -> theory; |
|
1177 |
in |
|
1178 |
(#modl o CodegenData.get) thy |
|
1179 |
|> start_transact (gen thy defs) |
|
1180 |
|-> (fn x => fn modl => (x, put_module modl thy)) |
|
1181 |
end; |
|
1182 |
||
1183 |
||
1184 |
(* syntax *) |
|
1185 |
||
| 18361 | 1186 |
fun gen_add_syntax_tyco prep_tyco prep_mfx prep_primname prep_primdef serial_name ((raw_tyco, raw_mfx), primdef) thy = |
| 18217 | 1187 |
let |
1188 |
val tyco = prep_tyco thy raw_tyco; |
|
1189 |
val _ = if member (op =) prims tyco |
|
1190 |
then error ("attempted to re-define primitive " ^ quote tyco)
|
|
1191 |
else () |
|
1192 |
fun add_primdef NONE = I |
|
1193 |
| add_primdef (SOME (name, (def, deps))) = |
|
| 18361 | 1194 |
CodegenSerializer.add_prim (prep_primname thy tyco name, (prep_primdef def, deps)) |
| 18217 | 1195 |
in |
1196 |
thy |
|
1197 |
|> prep_mfx raw_mfx |
|
1198 |
|-> (fn mfx => map_codegen_data |
|
1199 |
(fn (modl, gens, lookups, serialize_data, logic_data) => |
|
1200 |
(modl, gens, lookups, |
|
| 18335 | 1201 |
serialize_data |> check_for_serializer serial_name |> Symtab.map_entry serial_name |
| 18217 | 1202 |
(map_serialize_data |
1203 |
(fn (primitives, syntax_tyco, syntax_const) => |
|
1204 |
(primitives |> add_primdef primdef, |
|
| 18454 | 1205 |
syntax_tyco |> Symtab.update_new (idf_of_name thy nsp_tyco tyco, mfx), |
| 18217 | 1206 |
syntax_const))), |
1207 |
logic_data))) |
|
1208 |
end; |
|
1209 |
||
| 18361 | 1210 |
val add_syntax_tyco_i = gen_add_syntax_tyco (K I) pair ((K o K) I) I; |
| 18217 | 1211 |
val add_syntax_tyco = |
1212 |
let |
|
1213 |
fun mk_name _ _ (SOME name) = name |
|
1214 |
| mk_name thy tyco NONE = |
|
1215 |
let |
|
1216 |
val name = Sign.extern_type thy tyco |
|
1217 |
in |
|
1218 |
if NameSpace.is_qualified name |
|
1219 |
then error ("no unique identifier for syntax definition: " ^ quote tyco)
|
|
1220 |
else name |
|
1221 |
end; |
|
1222 |
fun prep_mfx mfx thy = |
|
1223 |
let |
|
1224 |
val proto_mfx = Codegen.parse_mixfix |
|
1225 |
(typ_of o read_ctyp thy) mfx; |
|
| 18335 | 1226 |
fun generate thy defs = fold_map (invoke_cg_type thy defs o devarify_type) |
| 18217 | 1227 |
(Codegen.quotes_of proto_mfx); |
1228 |
in |
|
1229 |
thy |
|
| 18454 | 1230 |
|> expand_module (mk_tabs thy) generate |
| 18217 | 1231 |
|-> (fn tys => pair (Codegen.replace_quotes tys proto_mfx)) |
1232 |
end; |
|
1233 |
in |
|
| 18454 | 1234 |
gen_add_syntax_tyco Sign.intern_type |
| 18361 | 1235 |
prep_mfx mk_name (newline_correct o Symbol.strip_blanks) |
| 18217 | 1236 |
end; |
1237 |
||
| 18454 | 1238 |
fun gen_add_syntax_const prep_const prep_mfx prep_primname prep_primdef serial_name ((raw_c, raw_mfx), primdef) thy = |
| 18217 | 1239 |
let |
| 18454 | 1240 |
val (c, ty) = prep_const thy raw_c; |
1241 |
val tabs = mk_tabs thy; |
|
1242 |
val _ = if member (op =) prims c |
|
1243 |
then error ("attempted to re-define primitive " ^ quote c)
|
|
| 18217 | 1244 |
else () |
1245 |
fun add_primdef NONE = I |
|
1246 |
| add_primdef (SOME (name, (def, deps))) = |
|
| 18454 | 1247 |
CodegenSerializer.add_prim (prep_primname thy c name, (prep_primdef def, deps)) |
| 18217 | 1248 |
in |
1249 |
thy |
|
1250 |
|> prep_mfx raw_mfx |
|
1251 |
|-> (fn mfx => map_codegen_data |
|
1252 |
(fn (modl, gens, lookups, serialize_data, logic_data) => |
|
1253 |
(modl, gens, lookups, |
|
| 18335 | 1254 |
serialize_data |> check_for_serializer serial_name |> Symtab.map_entry serial_name |
| 18217 | 1255 |
(map_serialize_data |
1256 |
(fn (primitives, syntax_tyco, syntax_const) => |
|
1257 |
(primitives |> add_primdef primdef, |
|
1258 |
syntax_tyco, |
|
| 18454 | 1259 |
syntax_const |> Symtab.update_new (idf_of_const thy tabs (c, ty), mfx)))), |
| 18217 | 1260 |
logic_data))) |
1261 |
end; |
|
1262 |
||
| 18361 | 1263 |
val add_syntax_const_i = gen_add_syntax_const (K I) pair ((K o K) I) I; |
| 18217 | 1264 |
val add_syntax_const = |
1265 |
let |
|
| 18454 | 1266 |
fun prep_const thy (raw_c, raw_ty) = |
| 18217 | 1267 |
let |
| 18454 | 1268 |
val c = Sign.intern_const thy raw_c; |
| 18217 | 1269 |
val ty = |
1270 |
raw_ty |
|
1271 |
|> Option.map (Sign.read_tyname thy) |
|
| 18454 | 1272 |
|> the_default (Sign.the_const_constraint thy c); |
1273 |
in (c, ty) end; |
|
| 18217 | 1274 |
fun mk_name _ _ (SOME name) = name |
1275 |
| mk_name thy f NONE = |
|
1276 |
let |
|
1277 |
val name = Sign.extern_const thy f |
|
1278 |
in |
|
1279 |
if NameSpace.is_qualified name |
|
1280 |
then error ("no unique identifier for syntax definition: " ^ quote f)
|
|
1281 |
else name |
|
1282 |
end; |
|
1283 |
fun prep_mfx mfx thy = |
|
1284 |
let |
|
1285 |
val proto_mfx = Codegen.parse_mixfix |
|
1286 |
(term_of o read_cterm thy o rpair TypeInfer.logicT) mfx; |
|
| 18335 | 1287 |
fun generate thy defs = fold_map (invoke_cg_expr thy defs o devarify_term) |
| 18217 | 1288 |
(Codegen.quotes_of proto_mfx); |
1289 |
in |
|
1290 |
thy |
|
| 18454 | 1291 |
|> expand_module (mk_tabs thy) generate |
| 18217 | 1292 |
|-> (fn es => pair (Codegen.replace_quotes es proto_mfx)) |
1293 |
end; |
|
1294 |
in |
|
| 18361 | 1295 |
gen_add_syntax_const prep_const prep_mfx mk_name (newline_correct o Symbol.strip_blanks) |
| 18217 | 1296 |
end; |
1297 |
||
1298 |
||
1299 |
(* code generation *) |
|
1300 |
||
| 18231 | 1301 |
fun get_serializer thy serial_name = |
1302 |
(#serializer o (fn data => (the oo Symtab.lookup) data serial_name) |
|
1303 |
o #serialize_data o CodegenData.get) thy; |
|
1304 |
||
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1305 |
fun mk_const thy (f, s_ty) = |
| 18217 | 1306 |
let |
| 18231 | 1307 |
val f' = Sign.intern_const thy f; |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1308 |
val ty = case s_ty |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1309 |
of NONE => Sign.the_const_constraint thy f' |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1310 |
| SOME s => Sign.read_typ (thy, K NONE) s; |
|
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1311 |
in (f', ty) end; |
| 18231 | 1312 |
|
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1313 |
fun generate_code consts thy = |
| 18231 | 1314 |
let |
| 18454 | 1315 |
val tabs = mk_tabs thy; |
1316 |
val consts' = map (mk_const thy) consts; |
|
1317 |
fun generate thy tabs = fold_map (ensure_def_const thy tabs) consts' |
|
| 18217 | 1318 |
in |
1319 |
thy |
|
| 18454 | 1320 |
|> expand_module tabs generate |
1321 |
|-> (fn consts => pair consts) |
|
| 18217 | 1322 |
end; |
1323 |
||
1324 |
fun serialize_code serial_name filename consts thy = |
|
1325 |
let |
|
| 18282 | 1326 |
fun mk_sfun tab = |
1327 |
let |
|
| 18304 | 1328 |
fun f name = |
1329 |
Symtab.lookup tab name |
|
1330 |
|> Option.map (fn qs => (Codegen.num_args_of qs, Codegen.fillin_mixfix qs)) |
|
1331 |
in f end; |
|
| 18217 | 1332 |
val serialize_data = |
1333 |
thy |
|
1334 |
|> CodegenData.get |
|
1335 |
|> #serialize_data |
|
| 18335 | 1336 |
|> check_for_serializer serial_name |
| 18217 | 1337 |
|> (fn data => (the oo Symtab.lookup) data serial_name) |
| 18231 | 1338 |
val serializer' = (get_serializer thy serial_name) |
| 18217 | 1339 |
((mk_sfun o #syntax_tyco) serialize_data) |
1340 |
((mk_sfun o #syntax_const) serialize_data) |
|
| 18231 | 1341 |
(#primitives serialize_data); |
1342 |
val _ = serializer' : string list option -> module -> Pretty.T; |
|
| 18217 | 1343 |
val compile_it = serial_name = "ml" andalso filename = "-"; |
| 18282 | 1344 |
fun use_code code = |
| 18217 | 1345 |
if compile_it |
1346 |
then use_text Context.ml_output false code |
|
1347 |
else File.write (Path.unpack filename) (code ^ "\n"); |
|
1348 |
in |
|
1349 |
thy |
|
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1350 |
|> (if is_some consts then generate_code (the consts) else pair []) |
| 18231 | 1351 |
|-> (fn [] => `(serializer' NONE o #modl o CodegenData.get) |
1352 |
| consts => `(serializer' (SOME consts) o #modl o CodegenData.get)) |
|
| 18360 | 1353 |
|-> (fn code => ((use_code o Pretty.output) code; I)) |
| 18217 | 1354 |
end; |
1355 |
||
1356 |
||
| 18454 | 1357 |
(* inconsistent names *) |
1358 |
||
1359 |
fun rename_inconsistent thy = |
|
1360 |
let |
|
1361 |
fun get_inconsistent thyname = |
|
1362 |
let |
|
1363 |
val thy = theory thyname; |
|
1364 |
fun own_tables get = |
|
1365 |
(get thy) |
|
1366 |
|> fold (Symtab.fold (Symtab.remove (K true)) o get) (Theory.parents_of thy) |
|
1367 |
|> Symtab.keys; |
|
1368 |
val names = own_tables (#2 o #types o Type.rep_tsig o Sign.tsig_of) |
|
1369 |
@ own_tables (#2 o #declarations o Consts.dest o #consts o Sign.rep_sg); |
|
1370 |
fun diff names = |
|
1371 |
fold (fn name => |
|
1372 |
if is_prefix (op =) (NameSpace.unpack thyname) (NameSpace.unpack name) |
|
1373 |
then I |
|
1374 |
else cons (name, NameSpace.append thyname (NameSpace.base name))) names []; |
|
1375 |
in diff names end; |
|
1376 |
val inconsistent = map get_inconsistent (ThyInfo.names ()) |> Library.flat; |
|
1377 |
fun add (src, dst) thy = |
|
1378 |
if (is_some oo Symtab.lookup o fst o #alias o #logic_data o CodegenData.get) thy src |
|
1379 |
then (warning ("code generator alias already defined for " ^ quote src ^ ", will not overwrite"); thy)
|
|
1380 |
else add_alias (src, dst) thy |
|
1381 |
in fold add inconsistent thy end; |
|
1382 |
||
1383 |
||
| 18217 | 1384 |
(* toplevel interface *) |
1385 |
||
1386 |
local |
|
1387 |
||
1388 |
structure P = OuterParse |
|
1389 |
and K = OuterKeyword |
|
1390 |
||
1391 |
in |
|
1392 |
||
| 18335 | 1393 |
val (classK, generateK, serializeK, syntax_tycoK, syntax_constK, aliasK) = |
1394 |
("code_class", "code_generate", "code_serialize", "code_syntax_tyco", "code_syntax_const", "code_alias");
|
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1395 |
val (constantsK, definedK, dependingK) = |
|
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1396 |
("constants", "defined_by", "depending_on");
|
| 18335 | 1397 |
|
1398 |
val classP = |
|
1399 |
OuterSyntax.command classK "codegen data for classes" K.thy_decl ( |
|
1400 |
P.xname |
|
1401 |
-- ((P.$$$ "\\<Rightarrow>" || P.$$$ "=>") |-- (P.list1 P.name)) |
|
1402 |
-- (Scan.optional ((P.$$$ "\\<Rightarrow>" || P.$$$ "=>") |-- (P.list1 P.name)) []) |
|
1403 |
>> (fn ((name, tycos), consts) => (Toplevel.theory (ClassPackage.add_classentry name consts tycos))) |
|
1404 |
) |
|
| 18217 | 1405 |
|
1406 |
val generateP = |
|
| 18282 | 1407 |
OuterSyntax.command generateK "generate executable code for constants" K.thy_decl ( |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1408 |
Scan.repeat1 (P.name -- Scan.option (P.$$$ "::" |-- P.typ)) |
| 18217 | 1409 |
>> (fn consts => |
| 18231 | 1410 |
Toplevel.theory (generate_code consts #> snd)) |
| 18217 | 1411 |
); |
1412 |
||
1413 |
val serializeP = |
|
| 18282 | 1414 |
OuterSyntax.command serializeK "serialize executable code for constants" K.thy_decl ( |
| 18217 | 1415 |
P.name |
1416 |
-- P.name |
|
1417 |
-- Scan.option ( |
|
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1418 |
P.$$$ constantsK |
|
18247
b17724cae935
code generator: case expressions, improved name resolving
haftmann
parents:
18231
diff
changeset
|
1419 |
|-- Scan.repeat1 (P.name -- Scan.option (P.$$$ "::" |-- P.typ)) |
| 18217 | 1420 |
) |
1421 |
>> (fn ((serial_name, filename), consts) => |
|
1422 |
Toplevel.theory (serialize_code serial_name filename consts)) |
|
1423 |
); |
|
1424 |
||
1425 |
val aliasP = |
|
| 18282 | 1426 |
OuterSyntax.command aliasK "declare an alias for a theory identifier" K.thy_decl ( |
| 18217 | 1427 |
P.name |
1428 |
-- P.name |
|
1429 |
>> (fn (src, dst) => Toplevel.theory (add_alias (src, dst))) |
|
1430 |
); |
|
1431 |
||
1432 |
val syntax_tycoP = |
|
1433 |
OuterSyntax.command syntax_tycoK "define code syntax for type constructor" K.thy_decl ( |
|
| 18335 | 1434 |
P.name |
| 18217 | 1435 |
-- Scan.repeat1 ( |
1436 |
P.xname -- (P.$$$ "(" |-- P.string --| P.$$$ ")")
|
|
1437 |
-- Scan.option ( |
|
1438 |
P.$$$ definedK |
|
1439 |
|-- Scan.option (P.$$$ "(" |-- P.string --| P.$$$ ")")
|
|
| 18335 | 1440 |
-- (P.text -- Scan.optional (P.$$$ dependingK |-- P.list1 P.string) []) |
| 18217 | 1441 |
) |
1442 |
) |
|
| 18231 | 1443 |
>> (fn (serial_name, xs) => |
| 18217 | 1444 |
(Toplevel.theory oo fold) |
1445 |
(fn ((tyco, raw_mfx), raw_def) => |
|
| 18231 | 1446 |
add_syntax_tyco serial_name ((tyco, raw_mfx), raw_def)) xs) |
| 18217 | 1447 |
); |
1448 |
||
1449 |
val syntax_constP = |
|
1450 |
OuterSyntax.command syntax_constK "define code syntax for constant" K.thy_decl ( |
|
| 18335 | 1451 |
P.name |
| 18217 | 1452 |
-- Scan.repeat1 ( |
1453 |
(P.xname -- Scan.option (P.$$$ "::" |-- P.typ)) -- (P.$$$ "(" |-- P.string --| P.$$$ ")")
|
|
1454 |
-- Scan.option ( |
|
1455 |
P.$$$ definedK |
|
1456 |
|-- Scan.option (P.$$$ "(" |-- P.string --| P.$$$ ")")
|
|
| 18335 | 1457 |
-- (P.text -- Scan.optional (P.$$$ dependingK |-- P.list1 P.string) []) |
| 18217 | 1458 |
) |
1459 |
) |
|
| 18231 | 1460 |
>> (fn (serial_name, xs) => |
| 18217 | 1461 |
(Toplevel.theory oo fold) |
1462 |
(fn ((f, raw_mfx), raw_def) => |
|
| 18231 | 1463 |
add_syntax_const serial_name ((f, raw_mfx), raw_def)) xs) |
| 18217 | 1464 |
); |
1465 |
||
| 18335 | 1466 |
val _ = OuterSyntax.add_parsers [classP, generateP, serializeP, aliasP, syntax_tycoP, syntax_constP]; |
|
18380
9668764224a7
substantial improvements for class code generation
haftmann
parents:
18361
diff
changeset
|
1467 |
val _ = OuterSyntax.add_keywords ["\\<Rightarrow>", "=>", constantsK, definedK, dependingK]; |
| 18217 | 1468 |
|
1469 |
||
1470 |
(* setup *) |
|
1471 |
val _ = |
|
1472 |
let |
|
1473 |
val bool = Type ("bool", []);
|
|
1474 |
val nat = Type ("nat", []);
|
|
1475 |
val int = Type ("IntDef.int", []);
|
|
1476 |
fun list t = Type ("List.list", [t]);
|
|
1477 |
fun pair t1 t2 = Type ("*", [t1, t2]);
|
|
1478 |
val A = TVar (("'a", 0), []);
|
|
1479 |
val B = TVar (("'b", 0), []);
|
|
1480 |
in Context.add_setup [ |
|
1481 |
CodegenData.init, |
|
| 18304 | 1482 |
add_codegen_sort ("default", exprgen_sort_default),
|
1483 |
add_codegen_type ("default", exprgen_type_default),
|
|
1484 |
add_codegen_expr ("default", exprgen_term_default),
|
|
| 18335 | 1485 |
add_appgen ("default", appgen_default),
|
| 18385 | 1486 |
add_appgen ("eq", appgen_eq),
|
| 18335 | 1487 |
add_appgen ("neg", appgen_neg),
|
| 18217 | 1488 |
add_defgen ("clsdecl", defgen_clsdecl),
|
| 18231 | 1489 |
add_defgen ("tyco_fallback", defgen_tyco_fallback),
|
1490 |
add_defgen ("const_fallback", defgen_const_fallback),
|
|
| 18217 | 1491 |
add_defgen ("defs", defgen_defs),
|
1492 |
add_defgen ("clsmem", defgen_clsmem),
|
|
1493 |
add_defgen ("clsinst", defgen_clsinst),
|
|
| 18454 | 1494 |
add_alias ("op -->", "HOL.op_implies"),
|
1495 |
add_alias ("op +", "HOL.op_add"),
|
|
1496 |
add_alias ("op -", "HOL.op_minus"),
|
|
1497 |
add_alias ("op *", "HOL.op_times"),
|
|
| 18455 | 1498 |
add_alias ("op <=", "Orderings.op_le"),
|
1499 |
add_alias ("op <", "Orderings.op_lt"),
|
|
| 18454 | 1500 |
add_alias ("List.op @", "List.append"),
|
1501 |
add_alias ("List.op mem", "List.member"),
|
|
1502 |
add_alias ("Divides.op div", "Divides.div"),
|
|
1503 |
add_alias ("Divides.op dvd", "Divides.dvd"),
|
|
1504 |
add_alias ("Divides.op mod", "Divides.mod"),
|
|
| 18217 | 1505 |
add_lookup_tyco ("bool", type_bool),
|
| 18454 | 1506 |
add_lookup_tyco ("*", type_pair),
|
| 18217 | 1507 |
add_lookup_tyco ("IntDef.int", type_integer),
|
1508 |
add_lookup_tyco ("List.list", type_list),
|
|
| 18231 | 1509 |
add_lookup_const (("True", bool), Cons_true),
|
| 18217 | 1510 |
add_lookup_const (("False", bool), Cons_false),
|
1511 |
add_lookup_const (("Not", bool --> bool), Fun_not),
|
|
1512 |
add_lookup_const (("op &", bool --> bool --> bool), Fun_and),
|
|
1513 |
add_lookup_const (("op |", bool --> bool --> bool), Fun_or),
|
|
1514 |
add_lookup_const (("HOL.If", bool --> A --> A --> A), Fun_if),
|
|
1515 |
add_lookup_const (("Pair", A --> B --> pair A B), Cons_pair),
|
|
1516 |
add_lookup_const (("fst", pair A B --> A), Fun_fst),
|
|
1517 |
add_lookup_const (("snd", pair A B --> B), Fun_snd),
|
|
| 18454 | 1518 |
add_lookup_const (("List.list.Cons", A --> list A --> list A), Cons_cons),
|
1519 |
add_lookup_const (("List.list.Nil", list A), Cons_nil),
|
|
| 18217 | 1520 |
add_lookup_const (("1", nat),
|
1521 |
IApp ( |
|
1522 |
IConst ("const.Suc", IFun (IType ("type.nat", []), IFun (IType ("type.nat", []), IType ("type.nat", [])))),
|
|
1523 |
IConst ("const.Zero", IType ("type.nat", []))
|
|
1524 |
)), |
|
1525 |
add_lookup_const (("0", int), Fun_0),
|
|
1526 |
add_lookup_const (("1", int), Fun_1),
|
|
1527 |
add_lookup_const (("op +", int --> int --> int), Fun_add),
|
|
1528 |
add_lookup_const (("op *", int --> int --> int), Fun_mult),
|
|
1529 |
add_lookup_const (("uminus", int --> int), Fun_minus),
|
|
1530 |
add_lookup_const (("op <", int --> int --> bool), Fun_lt),
|
|
1531 |
add_lookup_const (("op <=", int --> int --> bool), Fun_le),
|
|
| 18454 | 1532 |
add_lookup_const (("Wellfounded_Recursion.wfrec", ((A --> B) --> A --> B) --> A --> B), Fun_wfrec)
|
| 18217 | 1533 |
] end; |
1534 |
||
1535 |
(* "op /" ??? *) |
|
1536 |
||
1537 |
end; (* local *) |
|
1538 |
||
1539 |
end; (* struct *) |