author | haftmann |
Wed, 06 Sep 2006 13:48:02 +0200 | |
changeset 20485 | 3078fd2eec7b |
parent 20466 | 7c20ddbd911b |
child 20600 | 6d75e02ed285 |
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 |
|
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
9 |
signature CODEGEN_PACKAGE = |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
10 |
sig |
20456 | 11 |
include BASIC_CODEGEN_THINGOL; |
12 |
val codegen_term: term -> theory -> iterm * theory; |
|
20389 | 13 |
val eval_term: (string (*reference name!*) * 'a ref) * term |
14 |
-> theory -> 'a * theory; |
|
19884 | 15 |
val is_dtcon: string -> bool; |
16 |
val consts_of_idfs: theory -> string list -> (string * typ) list; |
|
17 |
val idfs_of_consts: theory -> (string * typ) list -> string list; |
|
19967 | 18 |
val get_root_module: theory -> CodegenThingol.module * theory; |
19884 | 19 |
val get_ml_fun_datatype: theory -> (string -> string) |
20456 | 20 |
-> ((string * ((iterm list * iterm) list * CodegenThingol.typscheme)) list -> Pretty.T) |
21 |
* ((string * ((vname * sort) list * (string * itype list) list)) list -> Pretty.T); |
|
18702 | 22 |
|
20401 | 23 |
val add_pretty_list: string -> string -> string -> (Pretty.T list -> Pretty.T) |
24 |
-> ((string -> string) * (string -> string)) option -> int * string |
|
25 |
-> theory -> theory; |
|
26 |
val add_pretty_ml_string: string -> string -> string -> string |
|
27 |
-> (string -> string) -> (string -> string) -> string -> theory -> theory; |
|
20175 | 28 |
val purge_code: theory -> theory; |
18217 | 29 |
|
19884 | 30 |
type appgen; |
20439 | 31 |
val add_appconst: string * appgen -> theory -> theory; |
18702 | 32 |
val appgen_default: appgen; |
20353 | 33 |
val appgen_rep_bin: (theory -> term -> IntInf.int) -> appgen; |
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
34 |
val appgen_char: (term -> int option) -> appgen; |
20105 | 35 |
val appgen_case: (theory -> term |
36 |
-> ((string * typ) list * ((term * typ) * (term * term) list)) option) |
|
37 |
-> appgen; |
|
38 |
val appgen_let: appgen; |
|
19038 | 39 |
val appgen_wfrec: appgen; |
18217 | 40 |
|
19008 | 41 |
val print_code: theory -> unit; |
18231 | 42 |
structure CodegenData: THEORY_DATA; |
20456 | 43 |
structure Code: THEORY_DATA; |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
44 |
end; |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
45 |
|
18217 | 46 |
structure CodegenPackage : CODEGEN_PACKAGE = |
18169
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
47 |
struct |
45def66f86cb
added modules for code generator generation two, not operational yet
haftmann
parents:
diff
changeset
|
48 |
|
18850 | 49 |
open CodegenThingol; |
18217 | 50 |
|
20439 | 51 |
(** preliminaries **) |
52 |
||
18702 | 53 |
(* shallow name spaces *) |
18217 | 54 |
|
20216 | 55 |
val nsp_module = ""; (*a dummy by convention*) |
18217 | 56 |
val nsp_class = "class"; |
18454 | 57 |
val nsp_tyco = "tyco"; |
18217 | 58 |
val nsp_const = "const"; |
18454 | 59 |
val nsp_dtcon = "dtcon"; |
18217 | 60 |
val nsp_mem = "mem"; |
61 |
val nsp_inst = "inst"; |
|
20216 | 62 |
val nsp_eval = "EVAL"; (*only for evaluation*) |
18217 | 63 |
|
19038 | 64 |
fun add_nsp shallow name = |
65 |
name |
|
66 |
|> NameSpace.unpack |
|
67 |
|> split_last |
|
68 |
|> apsnd (single #> cons shallow) |
|
69 |
|> (op @) |
|
70 |
|> NameSpace.pack; |
|
71 |
||
72 |
fun dest_nsp nsp idf = |
|
73 |
let |
|
74 |
val idf' = NameSpace.unpack idf; |
|
75 |
val (idf'', idf_base) = split_last idf'; |
|
76 |
val (modl, shallow) = split_last idf''; |
|
77 |
in |
|
78 |
if nsp = shallow |
|
79 |
then (SOME o NameSpace.pack) (modl @ [idf_base]) |
|
80 |
else NONE |
|
81 |
end; |
|
82 |
||
20386 | 83 |
fun if_nsp nsp f idf = |
84 |
Option.map f (dest_nsp nsp idf); |
|
19956 | 85 |
|
18702 | 86 |
val serializers = ref ( |
87 |
Symtab.empty |
|
88 |
|> Symtab.update ( |
|
20456 | 89 |
#SML CodegenSerializer.serializers |
18702 | 90 |
|> apsnd (fn seri => seri |
20183 | 91 |
nsp_dtcon |
20389 | 92 |
[[nsp_module], [nsp_class, nsp_tyco], |
20428 | 93 |
[nsp_const, nsp_dtcon, nsp_class, nsp_mem, nsp_inst]] |
18702 | 94 |
) |
95 |
) |
|
96 |
|> Symtab.update ( |
|
20456 | 97 |
#Haskell CodegenSerializer.serializers |
18702 | 98 |
|> apsnd (fn seri => seri |
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19884
diff
changeset
|
99 |
(nsp_dtcon, [nsp_module, nsp_class, nsp_tyco, nsp_dtcon]) |
20389 | 100 |
[[nsp_module], [nsp_class], [nsp_tyco], [nsp_const, nsp_mem], |
20428 | 101 |
[nsp_dtcon], [nsp_inst]] |
18702 | 102 |
) |
103 |
) |
|
104 |
); |
|
18217 | 105 |
|
106 |
||
20439 | 107 |
(* theory data *) |
18217 | 108 |
|
20466 | 109 |
type appgen = theory -> ((sort -> sort) * Sorts.algebra) * Consts.T -> CodegenTheorems.thmtab |
20456 | 110 |
-> bool * string list option -> (string * typ) * term list -> transact -> iterm * transact; |
20439 | 111 |
|
112 |
type appgens = (int * (appgen * stamp)) Symtab.table; |
|
18217 | 113 |
|
20386 | 114 |
fun merge_appgens (x : appgens * appgens) = |
20105 | 115 |
Symtab.merge (fn ((bounds1, (_, stamp1)), (bounds2, (_, stamp2))) => |
20439 | 116 |
bounds1 = bounds2 andalso stamp1 = stamp2) x; |
18217 | 117 |
|
18702 | 118 |
type target_data = { |
20428 | 119 |
syntax_class: ((string * (string -> string option)) * stamp) Symtab.table, |
120 |
syntax_inst: unit Symtab.table, |
|
18516 | 121 |
syntax_tyco: (itype CodegenSerializer.pretty_syntax * stamp) Symtab.table, |
20105 | 122 |
syntax_const: (iterm CodegenSerializer.pretty_syntax * stamp) Symtab.table |
18217 | 123 |
}; |
124 |
||
18702 | 125 |
fun merge_target_data |
20428 | 126 |
({ syntax_class = syntax_class1, syntax_inst = syntax_inst1, |
127 |
syntax_tyco = syntax_tyco1, syntax_const = syntax_const1 }, |
|
128 |
{ syntax_class = syntax_class2, syntax_inst = syntax_inst2, |
|
129 |
syntax_tyco = syntax_tyco2, syntax_const = syntax_const2 }) = |
|
130 |
{ syntax_class = Symtab.merge (eq_snd (op =)) (syntax_class1, syntax_class2), |
|
131 |
syntax_inst = Symtab.merge (op =) (syntax_inst1, syntax_inst2), |
|
18865 | 132 |
syntax_tyco = Symtab.merge (eq_snd (op =)) (syntax_tyco1, syntax_tyco2), |
18702 | 133 |
syntax_const = Symtab.merge (eq_snd (op =)) (syntax_const1, syntax_const2) } : target_data; |
18217 | 134 |
|
20456 | 135 |
structure Code = TheoryDataFun |
136 |
(struct |
|
137 |
val name = "Pure/code"; |
|
138 |
type T = module; |
|
139 |
val empty = empty_module; |
|
140 |
val copy = I; |
|
141 |
val extend = I; |
|
142 |
fun merge _ = merge_module; |
|
143 |
fun print thy module = |
|
144 |
(Pretty.writeln o Pretty.chunks) [pretty_module module, pretty_deps module]; |
|
145 |
end); |
|
146 |
||
18217 | 147 |
structure CodegenData = TheoryDataFun |
148 |
(struct |
|
19953
2f54a51f1801
class package refinements, slight code generation refinements
haftmann
parents:
19884
diff
changeset
|
149 |
val name = "Pure/codegen_package"; |
18217 | 150 |
type T = { |
20105 | 151 |
appgens: appgens, |
18702 | 152 |
target_data: target_data Symtab.table |
18217 | 153 |
}; |
154 |
val empty = { |
|
20105 | 155 |
appgens = Symtab.empty, |
18702 | 156 |
target_data = |
18217 | 157 |
Symtab.empty |
18702 | 158 |
|> Symtab.fold (fn (target, _) => |
18865 | 159 |
Symtab.update (target, |
20428 | 160 |
{ syntax_class = Symtab.empty, syntax_inst = Symtab.empty, |
161 |
syntax_tyco = Symtab.empty, syntax_const = Symtab.empty }) |
|
18702 | 162 |
) (! serializers) |
18217 | 163 |
} : T; |
164 |
val copy = I; |
|
165 |
val extend = I; |
|
166 |
fun merge _ ( |
|
20456 | 167 |
{ appgens = appgens1, target_data = target_data1 }, |
168 |
{ appgens = appgens2, target_data = target_data2 } |
|
18217 | 169 |
) = { |
20105 | 170 |
appgens = merge_appgens (appgens1, appgens2), |
19025 | 171 |
target_data = Symtab.join (K merge_target_data) (target_data1, target_data2) |
18217 | 172 |
}; |
20456 | 173 |
fun print _ _ = (); |
18217 | 174 |
end); |
175 |
||
20456 | 176 |
val _ = Context.add_setup (Code.init #> CodegenData.init); |
18708 | 177 |
|
18217 | 178 |
fun map_codegen_data f thy = |
179 |
case CodegenData.get thy |
|
20456 | 180 |
of { appgens, target_data } => |
181 |
let val (appgens, target_data) = |
|
182 |
f (appgens, target_data) |
|
183 |
in CodegenData.put { appgens = appgens, |
|
20386 | 184 |
target_data = target_data } thy end; |
18217 | 185 |
|
20456 | 186 |
fun check_serializer target = |
187 |
case Symtab.lookup (!serializers) target |
|
188 |
of SOME seri => () |
|
189 |
| NONE => error ("Unknown code target language: " ^ quote target); |
|
190 |
||
20439 | 191 |
fun get_serializer target = |
192 |
case Symtab.lookup (!serializers) target |
|
193 |
of SOME seri => seri |
|
194 |
| NONE => Scan.fail_with (fn _ => "Unknown code target language: " ^ quote target) (); |
|
195 |
||
196 |
fun serialize thy target seri cs = |
|
197 |
let |
|
20456 | 198 |
val data = CodegenData.get thy; |
199 |
val code = Code.get thy; |
|
20439 | 200 |
val target_data = |
201 |
(the oo Symtab.lookup) (#target_data data) target; |
|
202 |
val syntax_class = #syntax_class target_data; |
|
203 |
val syntax_inst = #syntax_inst target_data; |
|
204 |
val syntax_tyco = #syntax_tyco target_data; |
|
205 |
val syntax_const = #syntax_const target_data; |
|
206 |
fun fun_of syntax = (Option.map fst oo Symtab.lookup) syntax; |
|
207 |
in |
|
208 |
seri (fun_of syntax_class, fun_of syntax_tyco, fun_of syntax_const) |
|
209 |
(Symtab.keys syntax_class @ Symtab.keys syntax_inst |
|
210 |
@ Symtab.keys syntax_tyco @ Symtab.keys syntax_const, cs) code : unit |
|
211 |
end; |
|
212 |
||
213 |
fun map_target_data target f = |
|
214 |
let |
|
20456 | 215 |
val _ = check_serializer target; |
20439 | 216 |
in |
20456 | 217 |
map_codegen_data (fn (appgens, target_data) => |
218 |
(appgens, Symtab.map_entry target (fn { syntax_class, syntax_inst, syntax_tyco, syntax_const } => |
|
20439 | 219 |
let |
220 |
val (syntax_class, syntax_inst, syntax_tyco, syntax_const) = |
|
221 |
f (syntax_class, syntax_inst, syntax_tyco, syntax_const) |
|
222 |
in { |
|
223 |
syntax_class = syntax_class, |
|
224 |
syntax_inst = syntax_inst, |
|
225 |
syntax_tyco = syntax_tyco, |
|
226 |
syntax_const = syntax_const } : target_data |
|
227 |
end |
|
228 |
) target_data) |
|
229 |
) |
|
230 |
end; |
|
231 |
||
20456 | 232 |
val print_code = Code.print; |
18217 | 233 |
|
20456 | 234 |
val purge_code = Code.map (K CodegenThingol.empty_module); |
20439 | 235 |
|
236 |
fun purge_defs NONE = purge_code |
|
237 |
| purge_defs (SOME []) = I |
|
238 |
| purge_defs (SOME cs) = purge_code; |
|
18454 | 239 |
|
18865 | 240 |
|
20386 | 241 |
(* name handling *) |
242 |
||
243 |
fun idf_of_class thy class = |
|
244 |
CodegenNames.class thy class |
|
245 |
|> add_nsp nsp_class; |
|
246 |
||
247 |
fun class_of_idf thy = if_nsp nsp_class (CodegenNames.class_rev thy); |
|
248 |
||
249 |
fun idf_of_tyco thy tyco = |
|
250 |
CodegenNames.tyco thy tyco |
|
251 |
|> add_nsp nsp_tyco; |
|
252 |
||
253 |
fun tyco_of_idf thy = if_nsp nsp_tyco (CodegenNames.tyco_rev thy); |
|
254 |
||
255 |
fun idf_of_inst thy inst = |
|
256 |
CodegenNames.instance thy inst |
|
257 |
|> add_nsp nsp_inst; |
|
258 |
||
259 |
fun inst_of_idf thy = if_nsp nsp_inst (CodegenNames.instance_rev thy); |
|
260 |
||
261 |
fun idf_of_const thy thmtab (c_ty as (c, ty)) = |
|
262 |
if is_some (CodegenTheorems.get_dtyp_of_cons thmtab c_ty) then |
|
263 |
CodegenNames.const thy c_ty |
|
264 |
|> add_nsp nsp_dtcon |
|
265 |
else if (is_some o CodegenConsts.class_of_classop thy o CodegenConsts.typinst_of_typ thy) c_ty then |
|
266 |
CodegenNames.const thy c_ty |
|
267 |
|> add_nsp nsp_mem |
|
268 |
else |
|
269 |
CodegenNames.const thy c_ty |
|
270 |
|> add_nsp nsp_const; |
|
271 |
||
20428 | 272 |
fun idf_of_classop thy c_ty = |
273 |
CodegenNames.const thy c_ty |
|
274 |
|> add_nsp nsp_mem; |
|
275 |
||
20386 | 276 |
fun const_of_idf thy idf = |
277 |
case dest_nsp nsp_const idf |
|
278 |
of SOME c => CodegenNames.const_rev thy c |> SOME |
|
279 |
| _ => (case dest_nsp nsp_dtcon idf |
|
280 |
of SOME c => CodegenNames.const_rev thy c |> SOME |
|
281 |
| _ => (case dest_nsp nsp_mem idf |
|
282 |
of SOME c => CodegenNames.const_rev thy c |> SOME |
|
283 |
| _ => NONE)); |
|
284 |
||
285 |
||
18865 | 286 |
|
20439 | 287 |
(** code extraction **) |
18865 | 288 |
|
20386 | 289 |
(* extraction kernel *) |
18865 | 290 |
|
20439 | 291 |
fun check_strict thy f x (false, _) = |
19884 | 292 |
false |
20439 | 293 |
| check_strict thy f x (_, SOME targets) = |
19884 | 294 |
exists ( |
20389 | 295 |
is_none o (fn tab => Symtab.lookup tab x) o f o the |
296 |
o (Symtab.lookup ((#target_data o CodegenData.get) thy)) |
|
19884 | 297 |
) targets |
20439 | 298 |
| check_strict thy f x (true, _) = |
19884 | 299 |
true; |
300 |
||
20439 | 301 |
fun no_strict (_, targets) = (false, targets); |
20386 | 302 |
|
20456 | 303 |
fun ensure_def_class thy algbr thmtab strct cls trns = |
20386 | 304 |
let |
20466 | 305 |
fun defgen_class thy (algbr as ((proj_sort, _), _)) thmtab strct cls trns = |
20386 | 306 |
case class_of_idf thy cls |
18865 | 307 |
of SOME cls => |
308 |
let |
|
19283 | 309 |
val (v, cs) = (ClassPackage.the_consts_sign thy) cls; |
20456 | 310 |
val superclasses = (proj_sort o Sign.super_classes thy) cls |
20386 | 311 |
val idfs = map (idf_of_const thy thmtab) cs; |
18865 | 312 |
in |
313 |
trns |
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19283
diff
changeset
|
314 |
|> debug_msg (fn _ => "trying defgen class declaration for " ^ quote cls) |
20456 | 315 |
|> fold_map (ensure_def_class thy algbr thmtab strct) superclasses |
316 |
||>> (fold_map (exprgen_type thy algbr thmtab strct) o map snd) cs |
|
317 |
|-> (fn (supcls, memtypes) => succeed |
|
318 |
(Class (supcls, (unprefix "'" v, idfs ~~ memtypes)))) |
|
18865 | 319 |
end |
320 |
| _ => |
|
321 |
trns |
|
20389 | 322 |
|> fail ("No class definition found for " ^ quote cls); |
20386 | 323 |
val cls' = idf_of_class thy cls; |
18454 | 324 |
in |
325 |
trns |
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19283
diff
changeset
|
326 |
|> debug_msg (fn _ => "generating class " ^ quote cls) |
20456 | 327 |
|> ensure_def (defgen_class thy algbr thmtab strct) true ("generating class " ^ quote cls) cls' |
18865 | 328 |
|> pair cls' |
329 |
end |
|
20456 | 330 |
and ensure_def_tyco thy algbr thmtab strct tyco trns = |
18865 | 331 |
let |
20386 | 332 |
val tyco' = idf_of_tyco thy tyco; |
20439 | 333 |
val strict = check_strict thy #syntax_tyco tyco' strct; |
20456 | 334 |
fun defgen_datatype thy algbr thmtab strct dtco trns = |
20386 | 335 |
case tyco_of_idf thy dtco |
18963 | 336 |
of SOME dtco => |
20353 | 337 |
(case CodegenTheorems.get_dtyp_spec thmtab dtco |
20456 | 338 |
of SOME (vs, cos) => |
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19283
diff
changeset
|
339 |
trns |
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19283
diff
changeset
|
340 |
|> debug_msg (fn _ => "trying defgen datatype for " ^ quote dtco) |
20456 | 341 |
|> fold_map (exprgen_tyvar_sort thy algbr thmtab strct) vs |
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19806
diff
changeset
|
342 |
||>> fold_map (fn (c, tys) => |
20456 | 343 |
fold_map (exprgen_type thy algbr thmtab strct) tys |
344 |
#-> (fn tys' => pair (idf_of_const thy thmtab (c, tys ---> Type (dtco, map TFree vs)), tys'))) cos |
|
345 |
|-> (fn (vs, cos) => succeed (Datatype (vs, cos))) |
|
18963 | 346 |
| NONE => |
347 |
trns |
|
20389 | 348 |
|> fail ("No datatype found for " ^ quote dtco)) |
18963 | 349 |
| NONE => |
350 |
trns |
|
20389 | 351 |
|> fail ("Not a type constructor: " ^ quote dtco) |
18865 | 352 |
in |
353 |
trns |
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19283
diff
changeset
|
354 |
|> debug_msg (fn _ => "generating type constructor " ^ quote tyco) |
20456 | 355 |
|> ensure_def (defgen_datatype thy algbr thmtab strct) strict |
20389 | 356 |
("generating type constructor " ^ quote tyco) tyco' |
18865 | 357 |
|> pair tyco' |
358 |
end |
|
20466 | 359 |
and exprgen_tyvar_sort thy (algbr as ((proj_sort, _), _)) thmtab strct (v, sort) trns = |
18516 | 360 |
trns |
20456 | 361 |
|> fold_map (ensure_def_class thy algbr thmtab strct) (proj_sort sort) |
18865 | 362 |
|-> (fn sort => pair (unprefix "'" v, sort)) |
20456 | 363 |
and exprgen_type thy algbr thmtab strct (TVar _) trns = |
20389 | 364 |
error "TVar encountered in typ during code generation" |
20456 | 365 |
| exprgen_type thy algbr thmtab strct (TFree vs) trns = |
18516 | 366 |
trns |
20456 | 367 |
|> exprgen_tyvar_sort thy algbr thmtab strct vs |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
368 |
|-> (fn (v, sort) => pair (ITyVar v)) |
20456 | 369 |
| exprgen_type thy algbr thmtab strct (Type ("fun", [t1, t2])) trns = |
18516 | 370 |
trns |
20456 | 371 |
|> exprgen_type thy algbr thmtab strct t1 |
372 |
||>> exprgen_type thy algbr thmtab strct t2 |
|
18516 | 373 |
|-> (fn (t1', t2') => pair (t1' `-> t2')) |
20456 | 374 |
| exprgen_type thy algbr thmtab strct (Type (tyco, tys)) trns = |
18516 | 375 |
trns |
20456 | 376 |
|> ensure_def_tyco thy algbr thmtab strct tyco |
377 |
||>> fold_map (exprgen_type thy algbr thmtab strct) tys |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19806
diff
changeset
|
378 |
|-> (fn (tyco, tys) => pair (tyco `%% tys)); |
18516 | 379 |
|
20466 | 380 |
fun exprgen_typinst thy (algbr as ((proj_sort, algebra), consts)) thmtab strct (ty_ctxt, sort_decl) trns = |
20456 | 381 |
let |
382 |
val pp = Sign.pp thy; |
|
383 |
datatype inst = |
|
384 |
Inst of (class * string) * inst list list |
|
385 |
| Contxt of (string * sort) * (class list * int); |
|
386 |
fun classrel (l as Contxt (v_sort, (classes, n)), _) class = |
|
387 |
Contxt (v_sort, (class :: classes, n)) |
|
388 |
| classrel (Inst ((_, tyco), lss), _) class = |
|
389 |
Inst ((class, tyco), lss); |
|
390 |
fun constructor tyco iss class = |
|
391 |
Inst ((class, tyco), (map o map) fst iss); |
|
392 |
fun variable (TFree (v, sort)) = |
|
393 |
let |
|
394 |
val sort' = proj_sort sort; |
|
395 |
in map_index (fn (n, class) => (Contxt ((v, sort'), ([], n)), class)) sort' end; |
|
396 |
val insts = Sorts.of_sort_derivation pp algebra |
|
397 |
{classrel = classrel, constructor = constructor, variable = variable} |
|
398 |
(ty_ctxt, proj_sort sort_decl); |
|
399 |
fun mk_dict (Inst (inst, instss)) trns = |
|
400 |
trns |
|
401 |
|> ensure_def_inst thy algbr thmtab strct inst |
|
402 |
||>> (fold_map o fold_map) mk_dict instss |
|
403 |
|-> (fn (inst, instss) => pair (Instance (inst, instss))) |
|
404 |
| mk_dict (Contxt ((v, sort), (classes, k))) trns = |
|
18517 | 405 |
trns |
20456 | 406 |
|> fold_map (ensure_def_class thy algbr thmtab strct) classes |
407 |
|-> (fn classes => pair (Context (classes, (unprefix "'" v, |
|
408 |
if length sort = 1 then ~1 else k)))) |
|
409 |
in |
|
410 |
trns |
|
411 |
|> fold_map mk_dict insts |
|
412 |
end |
|
20466 | 413 |
and exprgen_typinst_const thy (algbr as (_, consts)) thmtab strct (c, ty_ctxt) trns = |
414 |
let |
|
415 |
val idf = idf_of_const thy thmtab (c, ty_ctxt) |
|
416 |
val ty_decl = Consts.declaration consts idf; |
|
417 |
val insts = (op ~~ o apsnd (map (snd o dest_TVar)) oo pairself) |
|
418 |
(curry (Consts.typargs consts) idf) (ty_ctxt, ty_decl); |
|
20456 | 419 |
in |
420 |
trns |
|
421 |
|> fold_map (exprgen_typinst thy algbr thmtab strct) insts |
|
422 |
end |
|
423 |
and ensure_def_inst thy algbr thmtab strct (cls, tyco) trns = |
|
424 |
let |
|
20466 | 425 |
fun defgen_inst thy (algbr as ((proj_sort, _), _)) thmtab strct inst trns = |
20386 | 426 |
case inst_of_idf thy inst |
19956 | 427 |
of SOME (class, tyco) => |
18865 | 428 |
let |
20456 | 429 |
val (vs, memdefs) = ClassPackage.the_inst_sign thy (class, tyco); |
20389 | 430 |
val (_, members) = ClassPackage.the_consts_sign thy class; |
20456 | 431 |
val arity_typ = Type (tyco, (map TFree vs)); |
432 |
val superclasses = (proj_sort o Sign.super_classes thy) class |
|
18865 | 433 |
fun gen_suparity supclass trns = |
434 |
trns |
|
20456 | 435 |
|> ensure_def_class thy algbr thmtab strct supclass |
20466 | 436 |
||>> exprgen_typinst thy algbr thmtab strct (arity_typ, [supclass]) |
437 |
|-> (fn (supclass, [Instance (supints, lss)]) => pair (supclass, (supints, lss))); |
|
20386 | 438 |
fun gen_membr ((m0, ty0), (m, ty)) trns = |
18865 | 439 |
trns |
20456 | 440 |
|> ensure_def_const thy algbr thmtab strct (m0, ty0) |
441 |
||>> exprgen_term thy algbr thmtab strct (Const (m, ty)); |
|
18865 | 442 |
in |
443 |
trns |
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19283
diff
changeset
|
444 |
|> debug_msg (fn _ => "trying defgen class instance for (" ^ quote cls |
18865 | 445 |
^ ", " ^ quote tyco ^ ")") |
20456 | 446 |
|> ensure_def_class thy algbr thmtab strct class |
447 |
||>> ensure_def_tyco thy algbr thmtab strct tyco |
|
448 |
||>> fold_map (exprgen_tyvar_sort thy algbr thmtab strct) vs |
|
449 |
||>> fold_map gen_suparity superclasses |
|
20389 | 450 |
||>> fold_map gen_membr (members ~~ memdefs) |
18885 | 451 |
|-> (fn ((((class, tyco), arity), suparities), memdefs) => |
20389 | 452 |
succeed (Classinst ((class, (tyco, arity)), (suparities, memdefs)))) |
18865 | 453 |
end |
454 |
| _ => |
|
20389 | 455 |
trns |> fail ("No class instance found for " ^ quote inst); |
20386 | 456 |
val inst = idf_of_inst thy (cls, tyco); |
18865 | 457 |
in |
458 |
trns |
|
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19283
diff
changeset
|
459 |
|> debug_msg (fn _ => "generating instance " ^ quote cls ^ " / " ^ quote tyco) |
20456 | 460 |
|> ensure_def (defgen_inst thy algbr thmtab strct) true |
18865 | 461 |
("generating instance " ^ quote cls ^ " / " ^ quote tyco) inst |
462 |
|> pair inst |
|
463 |
end |
|
20456 | 464 |
and ensure_def_const thy algbr thmtab strct (c, ty) trns = |
18865 | 465 |
let |
20456 | 466 |
fun defgen_datatypecons thy algbr thmtab strct co trns = |
20386 | 467 |
case CodegenTheorems.get_dtyp_of_cons thmtab ((the o const_of_idf thy) co) |
468 |
of SOME tyco => |
|
18865 | 469 |
trns |
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19283
diff
changeset
|
470 |
|> debug_msg (fn _ => "trying defgen datatype constructor for " ^ quote co) |
20456 | 471 |
|> ensure_def_tyco thy algbr thmtab strct tyco |
20386 | 472 |
|-> (fn _ => succeed Bot) |
18865 | 473 |
| _ => |
474 |
trns |
|
20389 | 475 |
|> fail ("Not a datatype constructor: " |
476 |
^ (quote o CodegenConsts.string_of_const_typ thy) (c, ty)); |
|
20456 | 477 |
fun defgen_clsmem thy algbr thmtab strct m trns = |
20386 | 478 |
case CodegenConsts.class_of_classop thy |
479 |
((CodegenConsts.typinst_of_typ thy o the o const_of_idf thy) m) |
|
480 |
of SOME class => |
|
481 |
trns |
|
482 |
|> debug_msg (fn _ => "trying defgen class member for " ^ quote m) |
|
20456 | 483 |
|> ensure_def_class thy algbr thmtab strct class |
20386 | 484 |
|-> (fn _ => succeed Bot) |
485 |
| _ => |
|
20389 | 486 |
trns |> fail ("No class found for " ^ (quote o CodegenConsts.string_of_const_typ thy) (c, ty)) |
20466 | 487 |
fun defgen_funs thy (algbr as (_, consts)) thmtab strct c' trns = |
20456 | 488 |
case CodegenTheorems.get_fun_thms thmtab ((the o const_of_idf thy) c') |
489 |
of eq_thms as eq_thm :: _ => |
|
490 |
let |
|
491 |
val msg = cat_lines ("generating code for theorems " :: map string_of_thm eq_thms); |
|
492 |
val ty = (Logic.unvarifyT o CodegenTheorems.extr_typ thy) eq_thm; |
|
20466 | 493 |
val vs = (map dest_TFree o Consts.typargs consts) (c', ty); |
20456 | 494 |
fun dest_eqthm eq_thm = |
495 |
let |
|
496 |
val ((t, args), rhs) = |
|
20466 | 497 |
(apfst strip_comb o Logic.dest_equals o Logic.unvarify o prop_of) eq_thm; |
20456 | 498 |
in case t |
499 |
of Const (c', _) => if c' = c then (args, rhs) |
|
500 |
else error ("Illegal function equation for " ^ quote c |
|
501 |
^ ", actually defining " ^ quote c') |
|
502 |
| _ => error ("Illegal function equation for " ^ quote c) |
|
503 |
end; |
|
504 |
fun exprgen_eq (args, rhs) trns = |
|
505 |
trns |
|
506 |
|> fold_map (exprgen_term thy algbr thmtab strct) args |
|
507 |
||>> exprgen_term thy algbr thmtab strct rhs; |
|
508 |
fun checkvars (args, rhs) = |
|
509 |
if CodegenThingol.vars_distinct args then (args, rhs) |
|
510 |
else error ("Repeated variables on left hand side of function") |
|
511 |
in |
|
512 |
trns |
|
513 |
|> message msg (fn trns => trns |
|
514 |
|> fold_map (exprgen_eq o dest_eqthm) eq_thms |
|
515 |
|-> (fn eqs => pair (map checkvars eqs)) |
|
516 |
||>> fold_map (exprgen_tyvar_sort thy algbr thmtab strct) vs |
|
517 |
||>> exprgen_type thy algbr thmtab strct ty |
|
518 |
|-> (fn ((eqs, vs), ty) => succeed (Fun (eqs, (vs, ty))))) |
|
519 |
end |
|
520 |
| [] => |
|
521 |
trns |
|
522 |
|> fail ("No defining equations found for " |
|
523 |
^ (quote o CodegenConsts.string_of_const_typ thy) (c, ty)); |
|
20439 | 524 |
fun get_defgen thmtab strct idf strict = |
20386 | 525 |
if (is_some oo dest_nsp) nsp_const idf |
20456 | 526 |
then defgen_funs thy algbr thmtab strct strict |
20386 | 527 |
else if (is_some oo dest_nsp) nsp_mem idf |
20456 | 528 |
then defgen_clsmem thy algbr thmtab strct strict |
20386 | 529 |
else if (is_some oo dest_nsp) nsp_dtcon idf |
20456 | 530 |
then defgen_datatypecons thy algbr thmtab strct strict |
20389 | 531 |
else error ("Illegal shallow name space for constant: " ^ quote idf); |
20386 | 532 |
val idf = idf_of_const thy thmtab (c, ty); |
20439 | 533 |
val strict = check_strict thy #syntax_const idf strct; |
18865 | 534 |
in |
535 |
trns |
|
20389 | 536 |
|> debug_msg (fn _ => "generating constant " |
537 |
^ (quote o CodegenConsts.string_of_const_typ thy) (c, ty)) |
|
20439 | 538 |
|> ensure_def (get_defgen thmtab strct idf) strict ("generating constant " |
20389 | 539 |
^ CodegenConsts.string_of_const_typ thy (c, ty)) idf |
18963 | 540 |
|> pair idf |
18865 | 541 |
end |
20456 | 542 |
and exprgen_term thy algbr thmtab strct (Const (f, ty)) trns = |
18517 | 543 |
trns |
20456 | 544 |
|> appgen thy algbr thmtab strct ((f, ty), []) |
18516 | 545 |
|-> (fn e => pair e) |
20456 | 546 |
| exprgen_term thy algbr thmtab strct (Var _) trns = |
20389 | 547 |
error "Var encountered in term during code generation" |
20456 | 548 |
| exprgen_term thy algbr thmtab strct (Free (v, ty)) trns = |
18516 | 549 |
trns |
20456 | 550 |
|> exprgen_type thy algbr thmtab strct ty |
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
551 |
|-> (fn ty => pair (IVar v)) |
20456 | 552 |
| exprgen_term thy algbr thmtab strct (Abs (raw_v, ty, raw_t)) trns = |
19136 | 553 |
let |
20386 | 554 |
val (v, t) = Syntax.variant_abs (CodegenNames.purify_var raw_v, ty, raw_t); |
19136 | 555 |
in |
556 |
trns |
|
20456 | 557 |
|> exprgen_type thy algbr thmtab strct ty |
558 |
||>> exprgen_term thy algbr thmtab strct t |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
559 |
|-> (fn (ty, e) => pair ((v, ty) `|-> e)) |
19136 | 560 |
end |
20456 | 561 |
| exprgen_term thy algbr thmtab strct (t as t1 $ t2) trns = |
18516 | 562 |
let |
563 |
val (t', ts) = strip_comb t |
|
564 |
in case t' |
|
565 |
of Const (f, ty) => |
|
566 |
trns |
|
20456 | 567 |
|> appgen thy algbr thmtab strct ((f, ty), ts) |
18516 | 568 |
|-> (fn e => pair e) |
569 |
| _ => |
|
570 |
trns |
|
20456 | 571 |
|> exprgen_term thy algbr thmtab strct t' |
572 |
||>> fold_map (exprgen_term thy algbr thmtab strct) ts |
|
18516 | 573 |
|-> (fn (e, es) => pair (e `$$ es)) |
18865 | 574 |
end |
20456 | 575 |
and appgen_default thy algbr thmtab strct ((c, ty), ts) trns = |
18865 | 576 |
trns |
20456 | 577 |
|> ensure_def_const thy algbr thmtab strct (c, ty) |
578 |
||>> exprgen_type thy algbr thmtab strct ty |
|
579 |
||>> exprgen_typinst_const thy algbr thmtab strct (c, ty) |
|
580 |
||>> fold_map (exprgen_term thy algbr thmtab strct) ts |
|
19816
a8c8ed1c85e0
removed 'primitive definitions' added (non)strict generation, minor fixes
haftmann
parents:
19806
diff
changeset
|
581 |
|-> (fn (((c, ty), ls), es) => |
19202 | 582 |
pair (IConst (c, (ls, ty)) `$$ es)) |
20456 | 583 |
and appgen thy algbr thmtab strct ((f, ty), ts) trns = |
20105 | 584 |
case Symtab.lookup ((#appgens o CodegenData.get) thy) f |
585 |
of SOME (i, (ag, _)) => |
|
586 |
if length ts < i then |
|
18865 | 587 |
let |
20105 | 588 |
val tys = Library.take (i - length ts, ((fst o strip_type) ty)); |
20192
956cd30ef3be
renamed Name.give_names to Name.names and moved Name.alphanum to Symbol.alphanum
haftmann
parents:
20191
diff
changeset
|
589 |
val vs = Name.names (Name.declare f Name.context) "a" tys; |
18865 | 590 |
in |
591 |
trns |
|
20456 | 592 |
|> fold_map (exprgen_type thy algbr thmtab strct) tys |
593 |
||>> ag thy algbr thmtab strct ((f, ty), ts @ map Free vs) |
|
20105 | 594 |
|-> (fn (tys, e) => pair (map2 (fn (v, _) => pair v) vs tys `|--> e)) |
18865 | 595 |
end |
20105 | 596 |
else if length ts > i then |
18865 | 597 |
trns |
20456 | 598 |
|> ag thy algbr thmtab strct ((f, ty), Library.take (i, ts)) |
599 |
||>> fold_map (exprgen_term thy algbr thmtab strct) (Library.drop (i, ts)) |
|
19167
f237c0cb3882
refined representation of codegen intermediate language
haftmann
parents:
19150
diff
changeset
|
600 |
|-> (fn (e, es) => pair (e `$$ es)) |
18865 | 601 |
else |
602 |
trns |
|
20456 | 603 |
|> ag thy algbr thmtab strct ((f, ty), ts) |
18865 | 604 |
| NONE => |
605 |
trns |
|
20456 | 606 |
|> appgen_default thy algbr thmtab strct ((f, ty), ts); |
18516 | 607 |
|
18702 | 608 |
|
20439 | 609 |
(* parametrized application generators, for instantiation in object logic *) |
610 |
(* (axiomatic extensions of extraction kernel *) |
|
18217 | 611 |
|
20485 | 612 |
fun appgen_rep_bin int_of_numeral thy algbr thmtab strct (app as (c, ts)) trns = |
613 |
case try (int_of_numeral thy) (list_comb (Const c, ts)) |
|
20353 | 614 |
of SOME i => if i < 0 then (*preprocessor eliminates negative numerals*) |
615 |
trns |
|
20456 | 616 |
|> appgen_default thy algbr thmtab (no_strict strct) app |
19884 | 617 |
else |
618 |
trns |
|
20485 | 619 |
|> appgen_default thy algbr thmtab (no_strict strct) app |
620 |
|-> (fn e => pair (CodegenThingol.INum (i, e))) |
|
19884 | 621 |
| NONE => |
622 |
trns |
|
20485 | 623 |
|> appgen_default thy algbr thmtab (no_strict strct) app; |
18217 | 624 |
|
20456 | 625 |
fun appgen_char char_to_index thy algbr thmtab strct (app as ((_, ty), _)) trns = |
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
626 |
case (char_to_index o list_comb o apfst Const) app |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
627 |
of SOME i => |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
628 |
trns |
20456 | 629 |
|> exprgen_type thy algbr thmtab strct ty |
630 |
||>> appgen_default thy algbr thmtab strct app |
|
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
631 |
|-> (fn (_, e0) => pair (IChar (chr i, e0))) |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
632 |
| NONE => |
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
633 |
trns |
20456 | 634 |
|> appgen_default thy algbr thmtab strct app; |
19607
07eeb832f28d
introduced characters for code generator; some improved code lemmas for some list functions
haftmann
parents:
19597
diff
changeset
|
635 |
|
20456 | 636 |
fun appgen_case dest_case_expr thy algbr thmtab strct (app as (c_ty, ts)) trns = |
20105 | 637 |
let |
638 |
val SOME ([], ((st, sty), ds)) = dest_case_expr thy (list_comb (Const c_ty, ts)); |
|
639 |
fun clausegen (dt, bt) trns = |
|
640 |
trns |
|
20456 | 641 |
|> exprgen_term thy algbr thmtab strct dt |
642 |
||>> exprgen_term thy algbr thmtab strct bt; |
|
20105 | 643 |
in |
644 |
trns |
|
20456 | 645 |
|> exprgen_term thy algbr thmtab strct st |
646 |
||>> exprgen_type thy algbr thmtab strct sty |
|
20105 | 647 |
||>> fold_map clausegen ds |
20456 | 648 |
||>> appgen_default thy algbr thmtab strct app |
20105 | 649 |
|-> (fn (((se, sty), ds), e0) => pair (ICase (((se, sty), ds), e0))) |
650 |
end; |
|
651 |
||
20456 | 652 |
fun appgen_let thy algbr thmtab strct (app as (_, [st, ct])) trns = |
20105 | 653 |
trns |
20456 | 654 |
|> exprgen_term thy algbr thmtab strct ct |
655 |
||>> exprgen_term thy algbr thmtab strct st |
|
656 |
||>> appgen_default thy algbr thmtab strct app |
|
20105 | 657 |
|-> (fn (((v, ty) `|-> be, se), e0) => |
658 |
pair (ICase (((se, ty), case be |
|
659 |
of ICase (((IVar w, _), ds), _) => if v = w then ds else [(IVar v, be)] |
|
660 |
| _ => [(IVar v, be)] |
|
661 |
), e0)) |
|
662 |
| (_, e0) => pair e0); |
|
663 |
||
20456 | 664 |
fun appgen_wfrec thy algbr thmtab strct ((c, ty), [_, tf, tx]) trns = |
19038 | 665 |
let |
20386 | 666 |
val ty_def = (op ---> o apfst tl o strip_type o Logic.unvarifyT o Sign.the_const_type thy) c; |
19038 | 667 |
val ty' = (op ---> o apfst tl o strip_type) ty; |
20386 | 668 |
val idf = idf_of_const thy thmtab (c, ty); |
19038 | 669 |
in |
670 |
trns |
|
20386 | 671 |
|> ensure_def ((K o fail) "no extraction for wfrec") false ("generating wfrec") idf |
20456 | 672 |
|> exprgen_type thy algbr thmtab strct ty' |
673 |
||>> exprgen_type thy algbr thmtab strct ty_def |
|
674 |
||>> exprgen_term thy algbr thmtab strct tf |
|
675 |
||>> exprgen_term thy algbr thmtab strct tx |
|
20434 | 676 |
|-> (fn (((_, ty), tf), tx) => pair (IConst (idf, ([], ty)) `$ tf `$ tx)) |
19038 | 677 |
end; |
678 |
||
20439 | 679 |
fun add_appconst (c, appgen) thy = |
680 |
let |
|
681 |
val i = (length o fst o strip_type o Sign.the_const_type thy) c |
|
682 |
in map_codegen_data |
|
20456 | 683 |
(fn (appgens, target_data) => |
684 |
(appgens |> Symtab.update (c, (i, (appgen, stamp ()))), |
|
20439 | 685 |
target_data)) thy |
686 |
end; |
|
687 |
||
18217 | 688 |
|
18516 | 689 |
|
20439 | 690 |
(** code generation interfaces **) |
18516 | 691 |
|
20439 | 692 |
fun generate cs targets init gen it thy = |
20466 | 693 |
let |
694 |
val thmtab = CodegenTheorems.mk_thmtab thy cs; |
|
695 |
val qnaming = NameSpace.qualified_names NameSpace.default_naming |
|
696 |
val algebr = ClassPackage.operational_algebra thy; |
|
697 |
fun ops_of_class class = |
|
698 |
let |
|
699 |
val (v, ops) = ClassPackage.the_consts_sign thy class; |
|
700 |
val ops_tys = map (fn (c, ty) => |
|
701 |
(c, (Logic.varifyT o map_type_tfree (fn u as (w, _) => |
|
702 |
if w = v then TFree (v, [class]) else TFree u)) ty)) ops; |
|
703 |
in |
|
704 |
map (fn (c, ty) => (idf_of_const thy thmtab (c, ty), ty)) ops_tys |
|
705 |
end; |
|
706 |
val classops = maps ops_of_class (Sorts.classes (snd algebr)); |
|
707 |
val consttab = Consts.empty |
|
708 |
|> fold (fn (c, ty) => Consts.declare qnaming |
|
709 |
(((idf_of_const thy thmtab o CodegenConsts.typ_of_typinst thy) c, ty), true)) |
|
710 |
(CodegenTheorems.get_fun_typs thmtab) |
|
711 |
|> fold (Consts.declare qnaming o rpair true) classops; |
|
712 |
val algbr = (algebr, consttab); |
|
713 |
in |
|
714 |
thy |
|
715 |
|> CodegenTheorems.notify_dirty |
|
716 |
|> `Code.get |
|
717 |
|> (fn (modl, thy) => |
|
718 |
(start_transact init (gen thy algbr thmtab |
|
719 |
(true, targets) it) modl, thy)) |
|
720 |
|-> (fn (x, modl) => Code.map (K modl) #> pair x) |
|
721 |
end; |
|
18516 | 722 |
|
20353 | 723 |
fun consts_of t = |
724 |
fold_aterms (fn Const c => cons c | _ => I) t []; |
|
725 |
||
20105 | 726 |
fun codegen_term t thy = |
20353 | 727 |
let |
728 |
val _ = Thm.cterm_of thy t; |
|
729 |
in |
|
730 |
thy |
|
20439 | 731 |
|> generate (consts_of t) (SOME []) NONE exprgen_term t |
20353 | 732 |
end; |
19136 | 733 |
|
734 |
val is_dtcon = has_nsp nsp_dtcon; |
|
735 |
||
736 |
fun consts_of_idfs thy = |
|
20386 | 737 |
map (the o const_of_idf thy); |
19150 | 738 |
|
20353 | 739 |
fun idfs_of_consts thy cs = |
20439 | 740 |
map (idf_of_const thy (CodegenTheorems.mk_thmtab thy cs)) cs; |
19150 | 741 |
|
19967 | 742 |
fun get_root_module thy = |
743 |
thy |
|
744 |
|> CodegenTheorems.notify_dirty |
|
20456 | 745 |
|> `Code.get; |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
746 |
|
20213 | 747 |
fun eval_term (ref_spec, t) thy = |
748 |
let |
|
20401 | 749 |
val _ = Term.fold_atyps (fn _ => |
750 |
error ("Term" ^ Sign.string_of_term thy t ^ "is polymorhpic")) |
|
751 |
(Term.fastype_of t); |
|
20389 | 752 |
fun preprocess_term t = |
753 |
let |
|
754 |
val x = Free (Name.variant (add_term_names (t, [])) "x", fastype_of t); |
|
755 |
(* fake definition *) |
|
756 |
val eq = setmp quick_and_dirty true (SkipProof.make_thm thy) |
|
757 |
(Logic.mk_equals (x, t)); |
|
758 |
fun err () = error "preprocess_term: bad preprocessor" |
|
759 |
in case map prop_of (CodegenTheorems.preprocess thy [eq]) |
|
760 |
of [Const ("==", _) $ x' $ t'] => if x = x' then t' else err () |
|
761 |
| _ => err () |
|
762 |
end; |
|
20213 | 763 |
val target_data = |
20456 | 764 |
((fn data => (the o Symtab.lookup data) "SML") o #target_data o CodegenData.get) thy; |
20428 | 765 |
val eval = CodegenSerializer.eval_term nsp_eval nsp_dtcon [[nsp_module], [nsp_class, nsp_tyco], [nsp_const, nsp_dtcon, nsp_class, nsp_mem, nsp_inst], [nsp_eval]] |
20213 | 766 |
((Option.map fst oo Symtab.lookup) (#syntax_tyco target_data), |
767 |
(Option.map fst oo Symtab.lookup) (#syntax_const target_data)) |
|
768 |
(Symtab.keys (#syntax_tyco target_data) @ Symtab.keys (#syntax_const target_data)) |
|
769 |
in |
|
770 |
thy |
|
20389 | 771 |
|> codegen_term (preprocess_term t) |
20456 | 772 |
||>> `Code.get |
20213 | 773 |
|-> (fn (t', modl) => `(fn _ => eval (ref_spec, t') modl)) |
774 |
end; |
|
775 |
||
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
776 |
fun get_ml_fun_datatype thy resolv = |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
777 |
let |
19150 | 778 |
val target_data = |
20456 | 779 |
((fn data => (the o Symtab.lookup data) "SML") o #target_data o CodegenData.get) thy; |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
780 |
in |
20183 | 781 |
CodegenSerializer.ml_fun_datatype nsp_dtcon |
19042
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
782 |
((Option.map fst oo Symtab.lookup o #syntax_tyco) target_data, |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
783 |
(Option.map fst oo Symtab.lookup o #syntax_const) target_data) |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
784 |
resolv |
630b8dd0b31a
exported some interfaces useful for other code generator approaches
haftmann
parents:
19038
diff
changeset
|
785 |
end; |
18516 | 786 |
|
787 |
||
788 |
||
20439 | 789 |
(** target syntax **) |
18702 | 790 |
|
20439 | 791 |
local |
18702 | 792 |
|
20456 | 793 |
fun gen_add_syntax_class prep_class prep_const target raw_class (syntax, raw_ops) thy = |
20428 | 794 |
let |
795 |
val class = (idf_of_class thy o prep_class thy) raw_class; |
|
796 |
val ops = (map o apfst) (idf_of_classop thy o prep_const thy) raw_ops; |
|
797 |
val syntax_ops = AList.lookup (op =) ops; |
|
798 |
in |
|
799 |
thy |
|
20439 | 800 |
|> map_target_data target (fn (syntax_class, syntax_inst, syntax_tyco, syntax_const) => |
801 |
(syntax_class |> Symtab.update (class, |
|
802 |
((syntax, syntax_ops), stamp ())), |
|
803 |
syntax_inst, syntax_tyco, syntax_const)) |
|
20428 | 804 |
end; |
18865 | 805 |
|
20456 | 806 |
fun gen_add_syntax_inst prep_class prep_tyco target (raw_class, raw_tyco) thy = |
20428 | 807 |
let |
808 |
val inst = idf_of_inst thy (prep_class thy raw_class, prep_tyco thy raw_tyco); |
|
809 |
in |
|
810 |
thy |
|
20439 | 811 |
|> map_target_data target (fn (syntax_class, syntax_inst, syntax_tyco, syntax_const) => |
812 |
(syntax_class, syntax_inst |> Symtab.update (inst, ()), |
|
813 |
syntax_tyco, syntax_const)) |
|
20428 | 814 |
end; |
815 |
||
20439 | 816 |
fun gen_add_syntax_tyco prep_tyco raw_tyco target syntax thy = |
18217 | 817 |
let |
20439 | 818 |
val tyco = (idf_of_tyco thy o prep_tyco thy) raw_tyco; |
18217 | 819 |
in |
20439 | 820 |
thy |
821 |
|> map_target_data target (fn (syntax_class, syntax_inst, syntax_tyco, syntax_const) => |
|
822 |
(syntax_class, syntax_inst, syntax_tyco |
|
823 |
|> Symtab.update (tyco, (syntax, stamp ())), syntax_const)) |
|
824 |
end; |
|
825 |
||
826 |
fun gen_add_syntax_const prep_const raw_c target syntax thy = |
|
827 |
let |
|
828 |
val c_ty = prep_const thy raw_c; |
|
829 |
val c = idf_of_const thy (CodegenTheorems.mk_thmtab thy [c_ty]) c_ty; |
|
830 |
in |
|
831 |
thy |
|
832 |
|> map_target_data target (fn (syntax_class, syntax_inst, syntax_tyco, syntax_const) => |
|
833 |
(syntax_class, syntax_inst, syntax_tyco, syntax_const |
|
834 |
|> Symtab.update (c, (syntax, stamp ())))) |
|
18217 | 835 |
end; |
836 |
||
20456 | 837 |
fun read_type thy raw_tyco = |
838 |
let |
|
839 |
val tyco = Sign.intern_type thy raw_tyco; |
|
840 |
val _ = if Sign.declared_tyname thy tyco then () |
|
841 |
else error ("No such type constructor: " ^ quote raw_tyco); |
|
842 |
in tyco end; |
|
843 |
||
20439 | 844 |
fun idfs_of_const_names thy cs = |
845 |
let |
|
846 |
val cs' = AList.make (fn c => Sign.the_const_type thy c) cs |
|
847 |
val thmtab = CodegenTheorems.mk_thmtab thy cs' |
|
848 |
in AList.make (idf_of_const thy thmtab) cs' end; |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
849 |
|
20439 | 850 |
fun read_quote reader consts_of target get_init gen raw_it thy = |
18217 | 851 |
let |
20439 | 852 |
val it = reader thy raw_it; |
853 |
val cs = consts_of it; |
|
18217 | 854 |
in |
20439 | 855 |
thy |
20456 | 856 |
|> generate cs (SOME [target]) ((SOME o get_init) thy) gen [it] |
20439 | 857 |
|-> (fn [it'] => pair it') |
18217 | 858 |
end; |
859 |
||
20439 | 860 |
fun parse_quote num_of reader consts_of target get_init gen adder = |
861 |
CodegenSerializer.parse_syntax num_of |
|
862 |
(read_quote reader consts_of target get_init gen) |
|
863 |
#-> (fn modifier => pair (modifier #-> adder target)); |
|
864 |
||
865 |
in |
|
866 |
||
20456 | 867 |
val add_syntax_class = gen_add_syntax_class ClassPackage.read_class CodegenConsts.read_const_typ; |
868 |
val add_syntax_inst = gen_add_syntax_inst ClassPackage.read_class read_type; |
|
20439 | 869 |
|
20456 | 870 |
fun parse_syntax_tyco target raw_tyco = |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
871 |
let |
20456 | 872 |
fun intern thy = read_type thy raw_tyco; |
20439 | 873 |
fun num_of thy = Sign.arity_number thy (intern thy); |
874 |
fun idf_of thy = idf_of_tyco thy (intern thy); |
|
875 |
fun read_typ thy = |
|
876 |
Sign.read_typ (thy, K NONE); |
|
877 |
in |
|
20456 | 878 |
parse_quote num_of read_typ (K []) target idf_of (fold_map oooo exprgen_type) |
879 |
(gen_add_syntax_tyco read_type raw_tyco) |
|
20439 | 880 |
end; |
881 |
||
20456 | 882 |
fun parse_syntax_const target raw_const = |
20439 | 883 |
let |
884 |
fun intern thy = CodegenConsts.read_const_typ thy raw_const; |
|
885 |
fun num_of thy = (length o fst o strip_type o Sign.the_const_type thy o fst o intern) thy; |
|
886 |
fun idf_of thy = |
|
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
887 |
let |
20439 | 888 |
val c_ty = intern thy; |
889 |
val c = idf_of_const thy (CodegenTheorems.mk_thmtab thy [c_ty]) c_ty; |
|
890 |
in c end; |
|
891 |
in |
|
20456 | 892 |
parse_quote num_of Sign.read_term consts_of target idf_of (fold_map oooo exprgen_term) |
20439 | 893 |
(gen_add_syntax_const CodegenConsts.read_const_typ raw_const) |
894 |
end; |
|
895 |
||
896 |
fun add_pretty_list target nill cons mk_list mk_char_string target_cons thy = |
|
897 |
let |
|
898 |
val [(_, nil''), (cons', cons'')] = idfs_of_const_names thy [nill, cons]; |
|
20401 | 899 |
val pr = CodegenSerializer.pretty_list nil'' cons'' mk_list mk_char_string target_cons; |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
900 |
in |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
901 |
thy |
20439 | 902 |
|> gen_add_syntax_const (K I) cons' target pr |
18704
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
903 |
end; |
2c86ced392a8
substantial improvement in serialization handling
haftmann
parents:
18702
diff
changeset
|
904 |
|
20439 | 905 |
fun add_pretty_ml_string target nill cons str mk_char mk_string target_implode thy = |
20401 | 906 |
let |
20439 | 907 |
val [(_, nil''), (_, cons''), (str', _)] = idfs_of_const_names thy [nill, cons, str]; |
908 |
val pr = CodegenSerializer.pretty_ml_string nil'' cons'' mk_char mk_string target_implode; |
|
20401 | 909 |
in |
910 |
thy |
|
20439 | 911 |
|> gen_add_syntax_const (K I) str' target pr |
20401 | 912 |
end; |
913 |
||
20439 | 914 |
end; (*local*) |
915 |
||
18217 | 916 |
|
18516 | 917 |
|
20439 | 918 |
(** toplevel interface and setup **) |
18756 | 919 |
|
920 |
local |
|
19150 | 921 |
|
20439 | 922 |
fun code raw_cs seris thy = |
18217 | 923 |
let |
20439 | 924 |
val cs = map (CodegenConsts.read_const_typ thy) raw_cs; |
20456 | 925 |
val targets = case map fst seris |
926 |
of [] => NONE |
|
927 |
| xs => SOME xs; |
|
20439 | 928 |
val seris' = map_filter (fn (target, SOME seri) => SOME (target, seri) | _ => NONE) seris; |
929 |
fun generate' thy = case cs |
|
930 |
of [] => ([], thy) |
|
931 |
| _ => |
|
18702 | 932 |
thy |
20456 | 933 |
|> generate cs targets NONE (fold_map oooo ensure_def_const) cs; |
20439 | 934 |
fun serialize' thy [] (target, seri) = |
935 |
serialize thy target seri NONE : unit |
|
936 |
| serialize' thy cs (target, seri) = |
|
937 |
serialize thy target seri (SOME cs) : unit; |
|
18217 | 938 |
in |
939 |
thy |
|
20439 | 940 |
|> generate' |
941 |
|-> (fn cs => tap (fn thy => map (serialize' thy cs) seris')) |
|
18217 | 942 |
end; |
943 |
||
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19283
diff
changeset
|
944 |
fun purge_consts raw_ts thy = |
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19283
diff
changeset
|
945 |
let |
20386 | 946 |
val cs = map (CodegenConsts.read_const_typ thy) raw_ts; |
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19283
diff
changeset
|
947 |
in fold CodegenTheorems.purge_defs cs thy end; |
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19283
diff
changeset
|
948 |
|
18217 | 949 |
structure P = OuterParse |
950 |
and K = OuterKeyword |
|
951 |
||
20456 | 952 |
val parse_target = P.name >> tap check_serializer; |
953 |
||
954 |
fun zip_list (x::xs) f g = |
|
955 |
f x #-> (fn y => fold_map (fn x => g |-- f x >> pair x) xs |
|
956 |
#-> (fn xys => pair ((x, y) :: xys))); |
|
957 |
||
958 |
fun parse_multi_syntax parse_thing parse_syntax = |
|
959 |
P.and_list1 parse_thing |
|
960 |
#-> (fn things => Scan.repeat1 (P.$$$ "(" |-- parse_target :-- |
|
961 |
(fn target => zip_list things (parse_syntax target) |
|
962 |
(P.$$$ "and")) --| P.$$$ ")")) |
|
963 |
||
18217 | 964 |
in |
965 |
||
20456 | 966 |
val (codeK, |
20428 | 967 |
syntax_classK, syntax_instK, syntax_tycoK, syntax_constK, |
20386 | 968 |
purgeK) = |
20456 | 969 |
("code_gen", |
970 |
"code_class", "code_instance", "code_type", "code_const", |
|
20386 | 971 |
"code_purge"); |
18335 | 972 |
|
20439 | 973 |
val codeP = |
974 |
OuterSyntax.command codeK "generate and serialize executable code for constants" K.thy_decl ( |
|
975 |
Scan.repeat P.term |
|
976 |
-- Scan.repeat (P.$$$ "(" |-- |
|
977 |
P.name :-- (fn target => (get_serializer target >> SOME) || pair NONE) |
|
978 |
--| P.$$$ ")") |
|
979 |
>> (fn (raw_cs, seris) => Toplevel.theory (code raw_cs seris)) |
|
980 |
); |
|
981 |
||
18865 | 982 |
val syntax_classP = |
19884 | 983 |
OuterSyntax.command syntax_classK "define code syntax for class" K.thy_decl ( |
20456 | 984 |
parse_multi_syntax P.xname |
985 |
(fn _ => fn _ => P.string -- Scan.optional (P.$$$ "where" |-- Scan.repeat1 |
|
986 |
(P.term --| (P.$$$ "\\<equiv>" || P.$$$ "==") -- P.string)) []) |
|
987 |
>> (Toplevel.theory oo fold) (fn (target, syns) => |
|
988 |
fold (fn (raw_class, syn) => add_syntax_class target raw_class syn) syns) |
|
18865 | 989 |
); |
990 |
||
20428 | 991 |
val syntax_instP = |
992 |
OuterSyntax.command syntax_instK "define code syntax for instance" K.thy_decl ( |
|
20456 | 993 |
parse_multi_syntax (P.xname --| P.$$$ "::" -- P.xname) |
994 |
(fn _ => fn _ => P.name #-> |
|
995 |
(fn "-" => Scan.succeed () | _ => Scan.fail_with (fn _ => "\"-\" expected") ())) |
|
996 |
>> (Toplevel.theory oo fold) (fn (target, syns) => |
|
997 |
fold (fn (raw_inst, ()) => add_syntax_inst target raw_inst) syns) |
|
20428 | 998 |
); |
999 |
||
18217 | 1000 |
val syntax_tycoP = |
1001 |
OuterSyntax.command syntax_tycoK "define code syntax for type constructor" K.thy_decl ( |
|
18702 | 1002 |
Scan.repeat1 ( |
20456 | 1003 |
parse_multi_syntax P.xname parse_syntax_tyco |
18702 | 1004 |
) |
20456 | 1005 |
>> (Toplevel.theory o (fold o fold) (fold snd o snd)) |
18217 | 1006 |
); |
1007 |
||
1008 |
val syntax_constP = |
|
1009 |
OuterSyntax.command syntax_constK "define code syntax for constant" K.thy_decl ( |
|
18702 | 1010 |
Scan.repeat1 ( |
20456 | 1011 |
parse_multi_syntax P.term parse_syntax_const |
18702 | 1012 |
) |
20456 | 1013 |
>> (Toplevel.theory o (fold o fold) (fold snd o snd)) |
18217 | 1014 |
); |
1015 |
||
19341
3414c04fbc39
added definitional code generator module: codegen_theorems.ML
haftmann
parents:
19283
diff
changeset
|
1016 |
val purgeP = |
20175 | 1017 |
OuterSyntax.command purgeK "purge all incrementally generated code" K.thy_decl |
1018 |
(Scan.succeed (Toplevel.theory purge_code)); |
|
18516 | 1019 |
|
20456 | 1020 |
val _ = OuterSyntax.add_parsers [codeP, |
20439 | 1021 |
syntax_classP, syntax_instP, syntax_tycoP, syntax_constP, purgeP]; |
18217 | 1022 |
|
1023 |
end; (* local *) |
|
1024 |
||
20439 | 1025 |
(*code basis change notifications*) |
1026 |
val _ = Context.add_setup (CodegenTheorems.add_notify purge_defs); |
|
1027 |
||
18217 | 1028 |
end; (* struct *) |