89 type deftab = ((typ * string) list Symtab.table |
92 type deftab = ((typ * string) list Symtab.table |
90 * (string * typ) Symtab.table) |
93 * (string * typ) Symtab.table) |
91 * (term list * term * typ) Symtab.table |
94 * (term list * term * typ) Symtab.table |
92 * (string Insttab.table |
95 * (string Insttab.table |
93 * (string * string) Symtab.table |
96 * (string * string) Symtab.table |
94 * (class * (string * typ)) Symtab.table); |
97 * class Symtab.table); |
95 |
98 |
96 type codegen_class = theory -> deftab -> (class, class) gen_codegen; |
99 type codegen_sort = theory -> deftab -> (sort, sort) gen_codegen; |
97 type codegen_type = theory -> deftab -> (typ, itype) gen_codegen; |
100 type codegen_type = theory -> deftab -> (typ, itype) gen_codegen; |
98 type codegen_expr = theory -> deftab -> (term, iexpr) gen_codegen; |
101 type codegen_expr = theory -> deftab -> (term, iexpr) gen_codegen; |
99 type defgen = theory -> deftab -> gen_defgen; |
102 type defgen = theory -> deftab -> gen_defgen; |
100 |
103 |
101 |
104 |
125 |
128 |
126 |
129 |
127 (* theory data for codegen *) |
130 (* theory data for codegen *) |
128 |
131 |
129 type gens = { |
132 type gens = { |
130 codegens_class: (string * (codegen_class * stamp)) list, |
133 codegens_sort: (string * (codegen_sort * stamp)) list, |
131 codegens_type: (string * (codegen_type * stamp)) list, |
134 codegens_type: (string * (codegen_type * stamp)) list, |
132 codegens_expr: (string * (codegen_expr * stamp)) list, |
135 codegens_expr: (string * (codegen_expr * stamp)) list, |
133 defgens: (string * (defgen * stamp)) list |
136 defgens: (string * (defgen * stamp)) list |
134 }; |
137 }; |
135 |
138 |
136 val empty_gens = { |
139 val empty_gens = { |
137 codegens_class = Symtab.empty, codegens_type = Symtab.empty, |
140 codegens_sort = Symtab.empty, codegens_type = Symtab.empty, |
138 codegens_expr = Symtab.empty, defgens = Symtab.empty |
141 codegens_expr = Symtab.empty, defgens = Symtab.empty |
139 }; |
142 }; |
140 |
143 |
141 fun map_gens f { codegens_class, codegens_type, codegens_expr, defgens } = |
144 fun map_gens f { codegens_sort, codegens_type, codegens_expr, defgens } = |
142 let |
145 let |
143 val (codegens_class, codegens_type, codegens_expr, defgens) = |
146 val (codegens_sort, codegens_type, codegens_expr, defgens) = |
144 f (codegens_class, codegens_type, codegens_expr, defgens) |
147 f (codegens_sort, codegens_type, codegens_expr, defgens) |
145 in { codegens_class = codegens_class, codegens_type = codegens_type, |
148 in { codegens_sort = codegens_sort, codegens_type = codegens_type, |
146 codegens_expr = codegens_expr, defgens = defgens } end; |
149 codegens_expr = codegens_expr, defgens = defgens } end; |
147 |
150 |
148 fun merge_gens |
151 fun merge_gens |
149 ({ codegens_class = codegens_class1, codegens_type = codegens_type1, |
152 ({ codegens_sort = codegens_sort1, codegens_type = codegens_type1, |
150 codegens_expr = codegens_expr1, defgens = defgens1 }, |
153 codegens_expr = codegens_expr1, defgens = defgens1 }, |
151 { codegens_class = codegens_class2, codegens_type = codegens_type2, |
154 { codegens_sort = codegens_sort2, codegens_type = codegens_type2, |
152 codegens_expr = codegens_expr2, defgens = defgens2 }) = |
155 codegens_expr = codegens_expr2, defgens = defgens2 }) = |
153 { codegens_class = AList.merge (op =) (eq_snd (op =)) (codegens_class1, codegens_class2), |
156 { codegens_sort = AList.merge (op =) (eq_snd (op =)) (codegens_sort1, codegens_sort2), |
154 codegens_type = AList.merge (op =) (eq_snd (op =)) (codegens_type1, codegens_type2), |
157 codegens_type = AList.merge (op =) (eq_snd (op =)) (codegens_type1, codegens_type2), |
155 codegens_expr = AList.merge (op =) (eq_snd (op =)) (codegens_expr1, codegens_expr2), |
158 codegens_expr = AList.merge (op =) (eq_snd (op =)) (codegens_expr1, codegens_expr2), |
156 defgens = AList.merge (op =) (eq_snd (op =)) (defgens1, defgens2) }; |
159 defgens = AList.merge (op =) (eq_snd (op =)) (defgens1, defgens2) }; |
157 |
160 |
158 type lookups = { |
161 type lookups = { |
235 logic_data: logic_data, |
238 logic_data: logic_data, |
236 serialize_data: serialize_data Symtab.table |
239 serialize_data: serialize_data Symtab.table |
237 }; |
240 }; |
238 val empty = { |
241 val empty = { |
239 modl = empty_module, |
242 modl = empty_module, |
240 gens = { codegens_class = [], codegens_type = [], codegens_expr = [], defgens = [] } : gens, |
243 gens = { codegens_sort = [], codegens_type = [], codegens_expr = [], defgens = [] } : gens, |
241 lookups = { lookups_tyco = Symtab.empty, lookups_const = Symtab.empty } : lookups, |
244 lookups = { lookups_tyco = Symtab.empty, lookups_const = Symtab.empty } : lookups, |
242 logic_data = { is_datatype = NONE, alias = (Symtab.empty, Symtab.empty) } : logic_data, |
245 logic_data = { is_datatype = NONE, alias = (Symtab.empty, Symtab.empty) } : logic_data, |
243 serialize_data = |
246 serialize_data = |
244 Symtab.empty |
247 Symtab.empty |
245 |> Symtab.update ("ml", |
248 |> Symtab.update ("ml", |
246 { serializer = serializer_ml, |
249 { serializer = serializer_ml : CodegenSerializer.serializer, |
247 primitives = |
250 primitives = |
248 CodegenSerializer.empty_prims |
251 CodegenSerializer.empty_prims |
249 |> CodegenSerializer.add_prim ("fst", ("fun fst (x, _) = x;", [])) |
252 |> CodegenSerializer.add_prim ("fst", ("fun fst (x, _) = x;", [])) |
250 |> CodegenSerializer.add_prim ("snd", ("fun snd (_, y) = y;", [])) |
253 |> CodegenSerializer.add_prim ("snd", ("fun snd (_, y) = y;", [])) |
251 |> CodegenSerializer.add_prim ("wfrec", ("fun wfrec f x = f (wfrec f) x;", [])), |
254 |> CodegenSerializer.add_prim ("wfrec", ("fun wfrec f x = f (wfrec f) x;", [])), |
252 syntax_tyco = Symtab.empty, syntax_const = Symtab.empty }) |
255 syntax_tyco = Symtab.empty, syntax_const = Symtab.empty }) |
253 |> Symtab.update ("haskell", |
256 |> Symtab.update ("haskell", |
254 { serializer = serializer_hs, primitives = CodegenSerializer.empty_prims, |
257 { serializer = serializer_hs : CodegenSerializer.serializer, primitives = CodegenSerializer.empty_prims, |
255 syntax_tyco = Symtab.empty, syntax_const = Symtab.empty }) |
258 syntax_tyco = Symtab.empty, syntax_const = Symtab.empty }) |
256 } : T; |
259 } : T; |
257 val copy = I; |
260 val copy = I; |
258 val extend = I; |
261 val extend = I; |
259 fun merge _ ( |
262 fun merge _ ( |
280 in CodegenData.put { modl = modl, gens = gens, lookups = lookups, |
283 in CodegenData.put { modl = modl, gens = gens, lookups = lookups, |
281 serialize_data = serialize_data, logic_data = logic_data } thy end; |
284 serialize_data = serialize_data, logic_data = logic_data } thy end; |
282 |
285 |
283 val print_codegen_modl = writeln o Pretty.output o pretty_module o #modl o CodegenData.get; |
286 val print_codegen_modl = writeln o Pretty.output o pretty_module o #modl o CodegenData.get; |
284 |
287 |
285 fun add_codegen_class (name, cg) = |
288 fun add_codegen_sort (name, cg) = |
286 map_codegen_data |
289 map_codegen_data |
287 (fn (modl, gens, lookups, serialize_data, logic_data) => |
290 (fn (modl, gens, lookups, serialize_data, logic_data) => |
288 (modl, |
291 (modl, |
289 gens |> map_gens |
292 gens |> map_gens |
290 (fn (codegens_class, codegens_type, codegens_expr, defgens) => |
293 (fn (codegens_sort, codegens_type, codegens_expr, defgens) => |
291 (codegens_class |
294 (codegens_sort |
292 |> Output.update_warn (op =) ("overwriting existing class code generator " ^ name) (name, (cg, stamp ())), |
295 |> Output.update_warn (op =) ("overwriting existing class code generator " ^ name) (name, (cg, stamp ())), |
293 codegens_type, codegens_expr, defgens)), lookups, serialize_data, logic_data)); |
296 codegens_type, codegens_expr, defgens)), lookups, serialize_data, logic_data)); |
294 |
297 |
295 fun add_codegen_type (name, cg) = |
298 fun add_codegen_type (name, cg) = |
296 map_codegen_data |
299 map_codegen_data |
297 (fn (modl, gens, lookups, serialize_data, logic_data) => |
300 (fn (modl, gens, lookups, serialize_data, logic_data) => |
298 (modl, |
301 (modl, |
299 gens |> map_gens |
302 gens |> map_gens |
300 (fn (codegens_class, codegens_type, codegens_expr, defgens) => |
303 (fn (codegens_sort, codegens_type, codegens_expr, defgens) => |
301 (codegens_class, |
304 (codegens_sort, |
302 codegens_type |
305 codegens_type |
303 |> Output.update_warn (op =) ("overwriting existing type code generator " ^ name) (name, (cg, stamp ())), |
306 |> Output.update_warn (op =) ("overwriting existing type code generator " ^ name) (name, (cg, stamp ())), |
304 codegens_expr, defgens)), lookups, serialize_data, logic_data)); |
307 codegens_expr, defgens)), lookups, serialize_data, logic_data)); |
305 |
308 |
306 fun add_codegen_expr (name, cg) = |
309 fun add_codegen_expr (name, cg) = |
307 map_codegen_data |
310 map_codegen_data |
308 (fn (modl, gens, lookups, serialize_data, logic_data) => |
311 (fn (modl, gens, lookups, serialize_data, logic_data) => |
309 (modl, |
312 (modl, |
310 gens |> map_gens |
313 gens |> map_gens |
311 (fn (codegens_class, codegens_type, codegens_expr, defgens) => |
314 (fn (codegens_sort, codegens_type, codegens_expr, defgens) => |
312 (codegens_class, codegens_type, |
315 (codegens_sort, codegens_type, |
313 codegens_expr |
316 codegens_expr |
314 |> Output.update_warn (op =) ("overwriting existing expression code generator " ^ name) (name, (cg, stamp ())), |
317 |> Output.update_warn (op =) ("overwriting existing expression code generator " ^ name) (name, (cg, stamp ())), |
315 defgens)), |
318 defgens)), |
316 lookups, serialize_data, logic_data)); |
319 lookups, serialize_data, logic_data)); |
317 |
320 |
318 fun add_defgen (name, dg) = |
321 fun add_defgen (name, dg) = |
319 map_codegen_data |
322 map_codegen_data |
320 (fn (modl, gens, lookups, serialize_data, logic_data) => |
323 (fn (modl, gens, lookups, serialize_data, logic_data) => |
321 (modl, |
324 (modl, |
322 gens |> map_gens |
325 gens |> map_gens |
323 (fn (codegens_class, codegens_type, codegens_expr, defgens) => |
326 (fn (codegens_sort, codegens_type, codegens_expr, defgens) => |
324 (codegens_class, codegens_type, codegens_expr, |
327 (codegens_sort, codegens_type, codegens_expr, |
325 defgens |
328 defgens |
326 |> Output.update_warn (op =) ("overwriting existing definition code generator " ^ name) (name, (dg, stamp ())))), |
329 |> Output.update_warn (op =) ("overwriting existing definition code generator " ^ name) (name, (dg, stamp ())))), |
327 lookups, serialize_data, logic_data)); |
330 lookups, serialize_data, logic_data)); |
328 |
331 |
329 val get_lookups_tyco = #lookups_tyco o #lookups o CodegenData.get; |
332 val get_lookups_tyco = #lookups_tyco o #lookups o CodegenData.get; |
422 if is_datatype thy ((NameSpace.drop_base o NameSpace.drop_base) idf) |
425 if is_datatype thy ((NameSpace.drop_base o NameSpace.drop_base) idf) |
423 then (NameSpace.drop_base o NameSpace.drop_base) idf |> SOME |
426 then (NameSpace.drop_base o NameSpace.drop_base) idf |> SOME |
424 else name_of_idf thy nsp_type idf |
427 else name_of_idf thy nsp_type idf |
425 else name_of_idf thy nsp_type idf; |
428 else name_of_idf thy nsp_type idf; |
426 |
429 |
427 fun idf_of_cname thy ((overl, _), _, (_, _, clsmems)) (name, ty) = |
430 fun idf_of_cname thy ((overl, _), _, _) (name, ty) = |
428 case Symtab.lookup overl name |
431 case Symtab.lookup overl name |
429 of NONE => |
432 of NONE => idf_of_name thy nsp_const name |
430 (case Symtab.lookup clsmems name |
433 | SOME tab => (the o AList.lookup (Sign.typ_instance thy) tab) ty |
431 of NONE => idf_of_name thy nsp_const name |
|
432 | SOME (_, (idf, ty')) => |
|
433 if Type.raw_instance (ty', ty) |
|
434 then idf |
|
435 else idf_of_name thy nsp_const name) |
|
436 | SOME tab => (the o AList.lookup (Sign.typ_instance thy) tab) ty; |
|
437 |
434 |
438 fun cname_of_idf thy ((_, overl_rev), _, _) idf = |
435 fun cname_of_idf thy ((_, overl_rev), _, _) idf = |
439 case Symtab.lookup overl_rev idf |
436 case Symtab.lookup overl_rev idf |
440 of NONE => |
437 of NONE => |
441 (case name_of_idf thy nsp_const idf |
438 (case name_of_idf thy nsp_const idf |
|
439 of NONE => (case name_of_idf thy nsp_mem idf |
442 of NONE => NONE |
440 of NONE => NONE |
|
441 | SOME n => SOME (n, Sign.the_const_constraint thy n)) |
443 | SOME n => SOME (n, Sign.the_const_constraint thy n)) |
442 | SOME n => SOME (n, Sign.the_const_constraint thy n)) |
444 | s => s; |
443 | s => s; |
445 |
444 |
446 |
445 |
447 (* auxiliary *) |
446 (* auxiliary *) |
455 (if i=0 then v else v ^ string_of_int i) |> unprefix "'" |
454 (if i=0 then v else v ^ string_of_int i) |> unprefix "'" |
456 |
455 |
457 |
456 |
458 (* code generator instantiation, part 2 *) |
457 (* code generator instantiation, part 2 *) |
459 |
458 |
460 fun invoke_cg_class thy defs class trns = |
459 fun invoke_cg_sort thy defs sort trns = |
461 gen_invoke |
460 gen_invoke |
462 ((map (apsnd (fn (cg, _) => cg thy defs)) o #codegens_class o #gens o CodegenData.get) thy) |
461 ((map (apsnd (fn (cg, _) => cg thy defs)) o #codegens_sort o #gens o CodegenData.get) thy) |
463 class class trns; |
462 ("generating sort " ^ (quote o Sign.string_of_sort thy) sort) sort trns; |
464 |
463 |
465 fun invoke_cg_type thy defs ty trns = |
464 fun invoke_cg_type thy defs ty trns = |
466 gen_invoke |
465 gen_invoke |
467 ((map (apsnd (fn (cg, _) => cg thy defs)) o #codegens_type o #gens o CodegenData.get) thy) |
466 ((map (apsnd (fn (cg, _) => cg thy defs)) o #codegens_type o #gens o CodegenData.get) thy) |
468 (Sign.string_of_typ thy ty) ty trns; |
467 ("generating type " ^ (quote o Sign.string_of_typ thy) ty) ty trns; |
469 |
468 |
470 fun invoke_cg_expr thy defs t trns = |
469 fun invoke_cg_expr thy defs t trns = |
471 gen_invoke |
470 gen_invoke |
472 ((map (apsnd (fn (cg, _) => cg thy defs)) o #codegens_expr o #gens o CodegenData.get) thy) |
471 ((map (apsnd (fn (cg, _) => cg thy defs)) o #codegens_expr o #gens o CodegenData.get) thy) |
473 (Sign.string_of_term thy t) t trns; |
472 ("generating expression " ^ (quote o Sign.string_of_term thy) t) t trns; |
474 |
473 |
475 fun get_defgens thy defs = |
474 fun get_defgens thy defs = |
476 (map (apsnd (fn (dg, _) => dg thy defs)) o #defgens o #gens o CodegenData.get) thy; |
475 (map (apsnd (fn (dg, _) => dg thy defs)) o #defgens o #gens o CodegenData.get) thy; |
477 |
476 |
478 fun ensure_def_class thy defs cls_or_inst trns = |
477 fun ensure_def_class thy defs cls_or_inst trns = |
479 if cls_or_inst = "ClassSimple.Eq_proto" then error ("Krach!") |
478 trns |
480 else trns |
479 |> debug 4 (fn _ => "generating class or instance " ^ quote cls_or_inst) |
481 |> gen_ensure_def (get_defgens thy defs) ("class/instance " ^ quote cls_or_inst) cls_or_inst |
480 |> gen_ensure_def (get_defgens thy defs) ("generating class/instance " ^ quote cls_or_inst) cls_or_inst |
482 |> pair cls_or_inst; |
481 |> pair cls_or_inst; |
483 |
482 |
484 fun ensure_def_tyco thy defs tyco trns = |
483 fun ensure_def_tyco thy defs tyco trns = |
485 if NameSpace.is_qualified tyco |
484 if NameSpace.is_qualified tyco |
486 then case Option.mapPartial (Symtab.lookup (get_lookups_tyco thy)) (tname_of_idf thy tyco) |
485 then case Option.mapPartial (Symtab.lookup (get_lookups_tyco thy)) (tname_of_idf thy tyco) |
487 of NONE => |
486 of NONE => |
488 trns |
487 trns |
489 |> gen_ensure_def (get_defgens thy defs) ("type constructor " ^ quote tyco) tyco |
488 |> debug 4 (fn _ => "generating type constructor " ^ quote tyco) |
|
489 |> gen_ensure_def (get_defgens thy defs) ("generating type constructor " ^ quote tyco) tyco |
490 |> pair tyco |
490 |> pair tyco |
491 | SOME tyco => |
491 | SOME tyco => |
492 trns |
492 trns |
493 |> pair tyco |
493 |> pair tyco |
494 else (tyco, trns); |
494 else (tyco, trns); |
526 |-> (fn ((eqs, ty), sortctxt) => pair (Fun (eqs, (sortctxt, ty)))) |
527 |-> (fn ((eqs, ty), sortctxt) => pair (Fun (eqs, (sortctxt, ty)))) |
527 end; |
528 end; |
528 |
529 |
529 fun mk_app thy defs f ty_use args trns = |
530 fun mk_app thy defs f ty_use args trns = |
530 let |
531 let |
|
532 val _ = debug 5 (fn _ => "making application of " ^ quote f) (); |
531 val ty_def = Sign.the_const_constraint thy f; |
533 val ty_def = Sign.the_const_constraint thy f; |
|
534 val _ = debug 10 (fn _ => "making application (2)") (); |
532 fun mk_lookup (ClassPackage.Instance (i, ls)) trns = |
535 fun mk_lookup (ClassPackage.Instance (i, ls)) trns = |
533 trns |
536 trns |
534 |> invoke_cg_class thy defs ((idf_of_name thy nsp_class o fst) i) |
537 |> ensure_def_class thy defs ((idf_of_name thy nsp_class o fst) i) |
535 ||>> ensure_def_class thy defs (idf_of_inst thy defs i) |
538 ||>> ensure_def_class thy defs (idf_of_inst thy defs i) |
536 ||>> (fold_map o fold_map) mk_lookup ls |
539 ||>> (fold_map o fold_map) mk_lookup ls |
537 |-> (fn ((cls, i), ls) => pair (ClassPackage.Instance ((cls, i), ls))) |
540 |-> (fn ((cls, i), ls) => pair (ClassPackage.Instance ((cls, i), ls))) |
538 | mk_lookup (ClassPackage.Lookup (clss, (v, i))) trns = |
541 | mk_lookup (ClassPackage.Lookup (clss, (v, i))) trns = |
539 trns |
542 trns |
540 |> fold_map (ensure_def_class thy defs) (map (idf_of_name thy nsp_class) clss) |
543 |> fold_map (ensure_def_class thy defs) (map (idf_of_name thy nsp_class) clss) |
541 |-> (fn clss => pair (ClassPackage.Lookup (clss, (name_of_tvar (TFree (v, [])), i)))); |
544 |-> (fn clss => pair (ClassPackage.Lookup (clss, (name_of_tvar (TFree (v, [])), i)))); |
|
545 val _ = debug 10 (fn _ => "making application (3)") (); |
542 fun mk_itapp e [] = e |
546 fun mk_itapp e [] = e |
543 | mk_itapp e lookup = IInst (e, lookup); |
547 | mk_itapp e lookup = IInst (e, lookup); |
544 in |
548 in |
545 trns |
549 trns |
|
550 |> debug 10 (fn _ => "making application (4): " ^ f ^ "::" ^ Sign.string_of_typ thy ty_use) |
546 |> ensure_def_const thy defs (idf_of_cname thy defs (f, ty_use)) |
551 |> ensure_def_const thy defs (idf_of_cname thy defs (f, ty_use)) |
|
552 |> debug 10 (fn _ => "making application (5)") |
547 ||>> fold_map (invoke_cg_expr thy defs) args |
553 ||>> fold_map (invoke_cg_expr thy defs) args |
|
554 |> debug 10 (fn _ => "making application (6)") |
548 ||>> (fold_map o fold_map) mk_lookup (ClassPackage.extract_sortlookup thy (ty_def, ty_use)) |
555 ||>> (fold_map o fold_map) mk_lookup (ClassPackage.extract_sortlookup thy (ty_def, ty_use)) |
|
556 |> debug 10 (fn _ => "making application (7)") |
549 ||>> invoke_cg_type thy defs ty_use |
557 ||>> invoke_cg_type thy defs ty_use |
|
558 |> debug 10 (fn _ => "making application (8)") |
550 |-> (fn (((f, args), lookup), ty_use) => |
559 |-> (fn (((f, args), lookup), ty_use) => |
551 pair (mk_apps (mk_itapp (IConst (f, ty_use)) lookup, args))) |
560 pair (mk_apps (mk_itapp (IConst (f, ty_use)) lookup, args))) |
552 end; |
561 end; |
553 |
562 |
554 |
563 |
561 infix 4 `$$; |
570 infix 4 `$$; |
562 in |
571 in |
563 |
572 |
564 (* code generators *) |
573 (* code generators *) |
565 |
574 |
566 fun codegen_class_default thy defs cls trns = |
575 fun codegen_sort_default thy defs sort trns = |
567 trns |
576 trns |
568 |> ensure_def_class thy defs cls |
577 |> fold_map (ensure_def_class thy defs) |
569 |-> (fn cls => succeed cls) |
578 (sort |> filter (ClassPackage.is_class thy) |> map (idf_of_name thy nsp_class)) |
|
579 |-> (fn sort => succeed sort) |
570 |
580 |
571 fun codegen_type_default thy defs (v as TVar (_, sort)) trns = |
581 fun codegen_type_default thy defs (v as TVar (_, sort)) trns = |
572 trns |
582 trns |
573 |> fold_map (invoke_cg_class thy defs) (sort |> filter (ClassPackage.is_class thy) |> map (idf_of_name thy nsp_class)) |
583 |> invoke_cg_sort thy defs sort |
574 |-> (fn sort => succeed (IVarT (name_of_tvar v, sort))) |
584 |-> (fn sort => succeed (IVarT (name_of_tvar v, sort))) |
575 | codegen_type_default thy defs (v as TFree (_, sort)) trns = |
585 | codegen_type_default thy defs (v as TFree (_, sort)) trns = |
576 trns |
586 trns |
577 |> fold_map (invoke_cg_class thy defs) (sort |> filter (ClassPackage.is_class thy) |> map (idf_of_name thy nsp_class)) |
587 |> invoke_cg_sort thy defs sort |
578 |-> (fn sort => succeed (IVarT (name_of_tvar v, sort))) |
588 |-> (fn sort => succeed (IVarT (name_of_tvar v, sort))) |
579 | codegen_type_default thy defs (Type ("fun", [t1, t2])) trns = |
589 | codegen_type_default thy defs (Type ("fun", [t1, t2])) trns = |
580 trns |
590 trns |
581 |> invoke_cg_type thy defs t1 |
591 |> invoke_cg_type thy defs t1 |
582 ||>> invoke_cg_type thy defs t2 |
592 ||>> invoke_cg_type thy defs t2 |
649 in cg_neg u end; |
659 in cg_neg u end; |
650 |
660 |
651 |
661 |
652 (* definition generators *) |
662 (* definition generators *) |
653 |
663 |
654 fun defgen_fallback_tyco thy defs tyco trns = |
664 fun defgen_tyco_fallback thy defs tyco trns = |
655 if Symtab.fold (fn (_, { syntax_tyco, ... }) => fn b => b orelse Symtab.defined syntax_tyco tyco) |
665 if Symtab.fold (fn (_, { syntax_tyco, ... }) => fn b => b orelse Symtab.defined syntax_tyco tyco) |
656 ((#serialize_data o CodegenData.get) thy) false |
666 ((#serialize_data o CodegenData.get) thy) false |
657 then |
667 then |
658 trns |
668 trns |
|
669 |> debug 5 (fn _ => "trying defgen tyco fallback for " ^ quote tyco) |
659 |> succeed (Nop, []) |
670 |> succeed (Nop, []) |
660 else |
671 else |
661 trns |
672 trns |
662 |> fail ("no code generation fallback for " ^ quote tyco) |
673 |> fail ("no code generation fallback for " ^ quote tyco) |
663 |
674 |
664 fun defgen_fallback_const thy defs f trns = |
675 fun defgen_const_fallback thy defs f trns = |
665 if Symtab.fold (fn (_, { syntax_const, ... }) => fn b => b orelse Symtab.defined syntax_const f) |
676 if Symtab.fold (fn (_, { syntax_const, ... }) => fn b => b orelse Symtab.defined syntax_const f) |
666 ((#serialize_data o CodegenData.get) thy) false |
677 ((#serialize_data o CodegenData.get) thy) false |
667 then |
678 then |
668 trns |
679 trns |
|
680 |> debug 5 (fn _ => "trying defgen const fallback for " ^ quote f) |
669 |> succeed (Nop, []) |
681 |> succeed (Nop, []) |
670 else |
682 else |
671 trns |
683 trns |
672 |> fail ("no code generation fallback for " ^ quote f) |
684 |> fail ("no code generation fallback for " ^ quote f) |
673 |
685 |
674 fun defgen_defs thy (defs as (_, defs', _)) f trns = |
686 fun defgen_defs thy (defs as (_, defs', _)) f trns = |
675 case Symtab.lookup defs' f |
687 case Symtab.lookup defs' f |
676 of SOME (args, rhs, ty) => |
688 of SOME (args, rhs, ty) => |
677 trns |
689 trns |
|
690 |> debug 5 (fn _ => "trying defgen def for " ^ quote f) |
678 |> mk_fun thy defs [(args, rhs)] ty |
691 |> mk_fun thy defs [(args, rhs)] ty |
679 |-> (fn def => succeed (def, [])) |
692 |-> (fn def => succeed (def, [])) |
680 | _ => trns |> fail ("no definition found for " ^ quote f); |
693 | _ => trns |> fail ("no definition found for " ^ quote f); |
681 |
694 |
682 fun defgen_clsdecl thy defs cls trns = |
695 fun defgen_clsdecl thy defs cls trns = |
683 case name_of_idf thy nsp_class cls |
696 case name_of_idf thy nsp_class cls |
684 of SOME cls => |
697 of SOME cls => |
685 trns |
698 trns |
686 |> debug 5 (fn _ => "generating class decl " ^ quote cls) |
699 |> debug 5 (fn _ => "trying defgen class declaration for " ^ quote cls) |
687 |> fold_map (ensure_def_class thy defs) |
700 |> fold_map (ensure_def_class thy defs) |
688 (map (idf_of_name thy nsp_class) (ClassPackage.get_superclasses thy cls)) |
701 (map (idf_of_name thy nsp_class) (ClassPackage.get_superclasses thy cls)) |
689 |-> (fn supcls => succeed (Class (supcls, [], []), |
702 |-> (fn supcls => succeed (Class (supcls, [], []), |
690 map (idf_of_name thy nsp_mem) (ClassPackage.the_consts thy cls) |
703 map (idf_of_name thy nsp_mem) (ClassPackage.the_consts thy cls) |
691 @ map (curry (idf_of_inst thy defs) cls) ((map snd o ClassPackage.the_tycos thy) cls))) |
704 @ map (curry (idf_of_inst thy defs) cls) ((map fst o ClassPackage.the_tycos thy) cls))) |
692 | _ => |
705 | _ => |
693 trns |
706 trns |
694 |> fail ("no class definition found for " ^ quote cls); |
707 |> fail ("no class definition found for " ^ quote cls); |
695 |
708 |
696 fun defgen_clsmem thy (defs as (_, _, _)) f trns = |
709 fun defgen_clsmem thy (defs as (_, _, _)) f trns = |
899 (((perhaps o Symtab.lookup) ((fst o #alias o #logic_data o CodegenData.get) thy) nm) |
916 (((perhaps o Symtab.lookup) ((fst o #alias o #logic_data o CodegenData.get) thy) nm) |
900 ^ "_" ^ mangle_tyname (ty_decl, ty)) |
917 ^ "_" ^ mangle_tyname (ty_decl, ty)) |
901 val overl_lookups = map |
918 val overl_lookups = map |
902 (fn (ty, (_, (args, rhs))) => (ty, mk_idf (name, ty), args, rhs)) ds; |
919 (fn (ty, (_, (args, rhs))) => (ty, mk_idf (name, ty), args, rhs)) ds; |
903 in |
920 in |
904 (*!!!*) |
|
905 ((overl |> Symtab.update_new (name, map (fn (ty, idf, _, _) => (ty, idf)) overl_lookups), |
921 ((overl |> Symtab.update_new (name, map (fn (ty, idf, _, _) => (ty, idf)) overl_lookups), |
906 overl_rev |> fold Symtab.update_new (map (fn (ty, idf, _, _) => (idf, (name, ty))) overl_lookups)), |
922 overl_rev |> fold Symtab.update_new (map (fn (ty, idf, _, _) => (idf, (name, ty))) overl_lookups)), |
907 defs |> fold Symtab.update_new (map (fn (ty, idf, args, rhs) => (idf, (args, rhs, ty))) overl_lookups), |
923 defs |> fold Symtab.update_new (map (fn (ty, idf, args, rhs) => (idf, (args, rhs, ty))) overl_lookups), |
908 clstab) |
924 clstab) |
909 end; |
925 end; |
910 fun mk_instname thyname (cls, tyco) = |
926 fun mk_instname thyname (cls, tyco) = |
911 idf_of_name thy nsp_inst |
927 idf_of_name thy nsp_inst |
912 (NameSpace.append thyname (NameSpace.base cls ^ "_" ^ NameSpace.base tyco)) |
928 (NameSpace.append thyname (NameSpace.base cls ^ "_" ^ NameSpace.base tyco)) |
913 fun add_clsmems classtab (overl, defs, (clstab, clstab_rev, clsmems)) = |
929 fun add_clsmems classtab ((overl, overl_rev), defs, (clstab, clstab_rev, clsmems)) = |
914 (overl, defs, |
930 ((overl |
|
931 |> Symtab.fold |
|
932 (fn (class, (clsmems, _)) => |
|
933 fold |
|
934 (fn clsmem => |
|
935 Symtab.default (clsmem, []) |
|
936 #> Symtab.map_entry clsmem |
|
937 (cons (Sign.the_const_type thy clsmem, idf_of_name thy nsp_mem clsmem)) |
|
938 ) clsmems |
|
939 ) classtab, |
|
940 overl_rev |
|
941 |> Symtab.fold |
|
942 (fn (class, (clsmems, _)) => |
|
943 fold |
|
944 (fn clsmem => |
|
945 Symtab.update_new |
|
946 (idf_of_name thy nsp_mem clsmem, (clsmem, Sign.the_const_type thy clsmem)) |
|
947 ) clsmems |
|
948 ) classtab), |
|
949 defs, |
915 (clstab |
950 (clstab |
916 |> Symtab.fold |
951 |> Symtab.fold |
917 (fn (cls, (_, clsinsts)) => fold |
952 (fn (cls, (_, clsinsts)) => fold |
918 (fn (tyco, thyname) => Insttab.update ((cls, tyco), mk_instname thyname (cls, tyco))) clsinsts) |
953 (fn (tyco, thyname) => Insttab.update ((cls, tyco), mk_instname thyname (cls, tyco))) clsinsts) |
919 classtab, |
954 classtab, |
923 (fn (tyco, thyname) => Symtab.update (mk_instname thyname (cls, tyco), (cls, tyco))) clsinsts) |
958 (fn (tyco, thyname) => Symtab.update (mk_instname thyname (cls, tyco), (cls, tyco))) clsinsts) |
924 classtab, |
959 classtab, |
925 clsmems |
960 clsmems |
926 |> Symtab.fold |
961 |> Symtab.fold |
927 (fn (class, (clsmems, _)) => fold |
962 (fn (class, (clsmems, _)) => fold |
928 (fn clsmem => Symtab.update (idf_of_name thy nsp_mem clsmem, (class, (clsmem, Sign.the_const_constraint thy clsmem)))) clsmems) |
963 (fn clsmem => Symtab.update (clsmem, class)) clsmems) |
929 classtab)) |
964 classtab)) |
930 in |
965 in |
931 ((Symtab.empty, Symtab.empty), Symtab.empty, (Insttab.empty, Symtab.empty, Symtab.empty)) |
966 ((Symtab.empty, Symtab.empty), Symtab.empty, (Insttab.empty, Symtab.empty, Symtab.empty)) |
932 |> fold add_def (Codegen.mk_deftab thy |> Symtab.dest) |
967 |> fold add_def (Codegen.mk_deftab thy |> Symtab.dest) |
933 |> add_clsmems (ClassPackage.get_classtab thy) |
968 |> add_clsmems (ClassPackage.get_classtab thy) |
934 end; |
969 end; |
935 |
970 |
936 fun expand_module gen thy = |
971 fun expand_module defs gen thy = |
937 let |
972 let |
938 val defs = mk_deftab thy; |
|
939 fun put_module modl = |
973 fun put_module modl = |
940 map_codegen_data (fn (_, gens, lookups, serialize_data, logic_data) => |
974 map_codegen_data (fn (_, gens, lookups, serialize_data, logic_data) => |
941 (modl, gens, lookups, serialize_data, logic_data)); |
975 (modl, gens, lookups, serialize_data, logic_data)); |
942 val _ = put_module : module -> theory -> theory; |
976 val _ = put_module : module -> theory -> theory; |
943 in |
977 in |
962 thy |
996 thy |
963 |> prep_mfx raw_mfx |
997 |> prep_mfx raw_mfx |
964 |-> (fn mfx => map_codegen_data |
998 |-> (fn mfx => map_codegen_data |
965 (fn (modl, gens, lookups, serialize_data, logic_data) => |
999 (fn (modl, gens, lookups, serialize_data, logic_data) => |
966 (modl, gens, lookups, |
1000 (modl, gens, lookups, |
967 serialize_data |> Symtab.map_entry serializer |
1001 serialize_data |> Symtab.map_entry serial_name |
968 (map_serialize_data |
1002 (map_serialize_data |
969 (fn (primitives, syntax_tyco, syntax_const) => |
1003 (fn (primitives, syntax_tyco, syntax_const) => |
970 (primitives |> add_primdef primdef, |
1004 (primitives |> add_primdef primdef, |
971 syntax_tyco |> Symtab.update_new (tyco, mfx), |
1005 syntax_tyco |> Symtab.update_new (tyco, mfx), |
972 syntax_const))), |
1006 syntax_const))), |
1014 thy |
1048 thy |
1015 |> prep_mfx raw_mfx |
1049 |> prep_mfx raw_mfx |
1016 |-> (fn mfx => map_codegen_data |
1050 |-> (fn mfx => map_codegen_data |
1017 (fn (modl, gens, lookups, serialize_data, logic_data) => |
1051 (fn (modl, gens, lookups, serialize_data, logic_data) => |
1018 (modl, gens, lookups, |
1052 (modl, gens, lookups, |
1019 serialize_data |> Symtab.map_entry serializer |
1053 serialize_data |> Symtab.map_entry serial_name |
1020 (map_serialize_data |
1054 (map_serialize_data |
1021 (fn (primitives, syntax_tyco, syntax_const) => |
1055 (fn (primitives, syntax_tyco, syntax_const) => |
1022 (primitives |> add_primdef primdef, |
1056 (primitives |> add_primdef primdef, |
1023 syntax_tyco, |
1057 syntax_tyco, |
1024 syntax_const |> Symtab.update_new (f, mfx)))), |
1058 syntax_const |> Symtab.update_new (f, mfx)))), |
1052 (term_of o read_cterm thy o rpair TypeInfer.logicT) mfx; |
1086 (term_of o read_cterm thy o rpair TypeInfer.logicT) mfx; |
1053 fun generate thy defs = fold_map (invoke_cg_expr thy defs) |
1087 fun generate thy defs = fold_map (invoke_cg_expr thy defs) |
1054 (Codegen.quotes_of proto_mfx); |
1088 (Codegen.quotes_of proto_mfx); |
1055 in |
1089 in |
1056 thy |
1090 thy |
1057 |> expand_module generate |
1091 |> expand_module (mk_deftab thy) generate |
1058 |-> (fn es => pair (Codegen.replace_quotes es proto_mfx)) |
1092 |-> (fn es => pair (Codegen.replace_quotes es proto_mfx)) |
1059 end; |
1093 end; |
1060 in |
1094 in |
1061 gen_add_syntax_const prep_const prep_mfx mk_name |
1095 gen_add_syntax_const prep_const prep_mfx mk_name |
1062 end; |
1096 end; |
1063 |
1097 |
1064 |
1098 |
1065 (* code generation *) |
1099 (* code generation *) |
1066 |
1100 |
1067 fun generate_code consts thy = |
1101 fun get_serializer thy serial_name = |
1068 let |
1102 (#serializer o (fn data => (the oo Symtab.lookup) data serial_name) |
1069 fun generate thy defs = fold_map (ensure_def_const thy defs) consts |
1103 o #serialize_data o CodegenData.get) thy; |
|
1104 |
|
1105 fun mk_const thy f = |
|
1106 let |
|
1107 val f' = Sign.intern_const thy f; |
|
1108 in (f', Sign.the_const_constraint thy f') end; |
|
1109 |
|
1110 fun gen_generate_code consts thy = |
|
1111 let |
|
1112 val defs = mk_deftab thy; |
|
1113 val consts' = map (idf_of_cname thy defs) consts; |
|
1114 fun generate thy defs = fold_map (ensure_def_const thy defs) consts' |
1070 in |
1115 in |
1071 thy |
1116 thy |
1072 |> expand_module generate |
1117 |> expand_module defs generate |
1073 |-> (fn _ => I) |
1118 |-> (fn _ => pair consts') |
1074 end; |
1119 end; |
|
1120 |
|
1121 fun generate_code consts thy = |
|
1122 gen_generate_code (map (mk_const thy) consts) thy; |
1075 |
1123 |
1076 fun serialize_code serial_name filename consts thy = |
1124 fun serialize_code serial_name filename consts thy = |
1077 let |
1125 let |
1078 fun mk_sfun tab name args f = |
1126 fun mk_sfun tab name args f = |
1079 Symtab.lookup tab name |
1127 Symtab.lookup tab name |
1081 val serialize_data = |
1129 val serialize_data = |
1082 thy |
1130 thy |
1083 |> CodegenData.get |
1131 |> CodegenData.get |
1084 |> #serialize_data |
1132 |> #serialize_data |
1085 |> (fn data => (the oo Symtab.lookup) data serial_name) |
1133 |> (fn data => (the oo Symtab.lookup) data serial_name) |
1086 val serializer = #serializer serialize_data |
1134 val serializer' = (get_serializer thy serial_name) |
1087 ((mk_sfun o #syntax_tyco) serialize_data) |
1135 ((mk_sfun o #syntax_tyco) serialize_data) |
1088 ((mk_sfun o #syntax_const) serialize_data) |
1136 ((mk_sfun o #syntax_const) serialize_data) |
1089 (#primitives serialize_data) |
1137 (#primitives serialize_data); |
|
1138 val _ = serializer' : string list option -> module -> Pretty.T; |
1090 val compile_it = serial_name = "ml" andalso filename = "-"; |
1139 val compile_it = serial_name = "ml" andalso filename = "-"; |
1091 fun use_code code = |
1140 fun use_code code = |
1092 if compile_it |
1141 if compile_it |
1093 then use_text Context.ml_output false code |
1142 then use_text Context.ml_output false code |
1094 else File.write (Path.unpack filename) (code ^ "\n"); |
1143 else File.write (Path.unpack filename) (code ^ "\n"); |
|
1144 val consts' = Option.map (map (mk_const thy)) consts; |
1095 in |
1145 in |
1096 thy |
1146 thy |
1097 |> (if is_some consts then generate_code (the consts) else I) |
1147 |> (if is_some consts then gen_generate_code (the consts') else pair []) |
1098 |> `(serializer consts o #modl o CodegenData.get) |
1148 |-> (fn [] => `(serializer' NONE o #modl o CodegenData.get) |
|
1149 | consts => `(serializer' (SOME consts) o #modl o CodegenData.get)) |
1099 |-> (fn code => ((use_code o Pretty.output) code; I)) |
1150 |-> (fn code => ((use_code o Pretty.output) code; I)) |
1100 end; |
1151 end; |
1101 |
1152 |
1102 |
1153 |
1103 (* toplevel interface *) |
1154 (* toplevel interface *) |
1164 P.$$$ definedK |
1215 P.$$$ definedK |
1165 |-- Scan.option (P.$$$ "(" |-- P.string --| P.$$$ ")") |
1216 |-- Scan.option (P.$$$ "(" |-- P.string --| P.$$$ ")") |
1166 -- (P.string -- Scan.optional (P.$$$ dependingK |-- P.list1 P.string) []) |
1217 -- (P.string -- Scan.optional (P.$$$ dependingK |-- P.list1 P.string) []) |
1167 ) |
1218 ) |
1168 ) |
1219 ) |
1169 >> (fn (serializer, xs) => |
1220 >> (fn (serial_name, xs) => |
1170 (Toplevel.theory oo fold) |
1221 (Toplevel.theory oo fold) |
1171 (fn ((f, raw_mfx), raw_def) => |
1222 (fn ((f, raw_mfx), raw_def) => |
1172 add_syntax_const serializer ((f, raw_mfx), raw_def)) xs) |
1223 add_syntax_const serial_name ((f, raw_mfx), raw_def)) xs) |
1173 ); |
1224 ); |
1174 |
1225 |
1175 val _ = OuterSyntax.add_parsers [generateP, serializeP, aliasP, syntax_tycoP, syntax_constP]; |
1226 val _ = OuterSyntax.add_parsers [generateP, serializeP, aliasP, syntax_tycoP, syntax_constP]; |
1176 val _ = OuterSyntax.add_keywords [extractingK, definedK, dependingK]; |
1227 val _ = OuterSyntax.add_keywords [extractingK, definedK, dependingK]; |
1177 |
1228 |
1186 fun pair t1 t2 = Type ("*", [t1, t2]); |
1237 fun pair t1 t2 = Type ("*", [t1, t2]); |
1187 val A = TVar (("'a", 0), []); |
1238 val A = TVar (("'a", 0), []); |
1188 val B = TVar (("'b", 0), []); |
1239 val B = TVar (("'b", 0), []); |
1189 in Context.add_setup [ |
1240 in Context.add_setup [ |
1190 CodegenData.init, |
1241 CodegenData.init, |
1191 add_codegen_class ("default", codegen_class_default), |
1242 add_codegen_sort ("default", codegen_sort_default), |
1192 add_codegen_type ("default", codegen_type_default), |
1243 add_codegen_type ("default", codegen_type_default), |
1193 add_codegen_expr ("default", codegen_expr_default), |
1244 add_codegen_expr ("default", codegen_expr_default), |
1194 (* add_codegen_expr ("eq", codegen_eq), *) |
1245 (* add_codegen_expr ("eq", codegen_eq), *) |
1195 add_codegen_expr ("neg", codegen_neg), |
1246 add_codegen_expr ("neg", codegen_neg), |
1196 add_defgen ("clsdecl", defgen_clsdecl), |
1247 add_defgen ("clsdecl", defgen_clsdecl), |
1197 add_defgen ("fallback_tyco", defgen_fallback_tyco), |
1248 add_defgen ("tyco_fallback", defgen_tyco_fallback), |
1198 add_defgen ("fallback_const", defgen_fallback_const), |
1249 add_defgen ("const_fallback", defgen_const_fallback), |
1199 add_defgen ("defs", defgen_defs), |
1250 add_defgen ("defs", defgen_defs), |
1200 add_defgen ("clsmem", defgen_clsmem), |
1251 add_defgen ("clsmem", defgen_clsmem), |
1201 add_defgen ("clsinst", defgen_clsinst), |
1252 add_defgen ("clsinst", defgen_clsinst), |
1202 add_alias ("op <>", "neq"), |
1253 add_alias ("op <>", "neq"), |
1203 add_alias ("op >=", "ge"), |
1254 add_alias ("op >=", "ge"), |
1206 add_alias ("op @", "append"), |
1257 add_alias ("op @", "append"), |
1207 add_lookup_tyco ("bool", type_bool), |
1258 add_lookup_tyco ("bool", type_bool), |
1208 add_lookup_tyco ("IntDef.int", type_integer), |
1259 add_lookup_tyco ("IntDef.int", type_integer), |
1209 add_lookup_tyco ("List.list", type_list), |
1260 add_lookup_tyco ("List.list", type_list), |
1210 add_lookup_tyco ("*", type_pair), |
1261 add_lookup_tyco ("*", type_pair), |
1211 add_lookup_const (("True", bool),Cons_true), |
1262 add_lookup_const (("True", bool), Cons_true), |
1212 add_lookup_const (("False", bool), Cons_false), |
1263 add_lookup_const (("False", bool), Cons_false), |
1213 add_lookup_const (("Not", bool --> bool), Fun_not), |
1264 add_lookup_const (("Not", bool --> bool), Fun_not), |
1214 add_lookup_const (("op &", bool --> bool --> bool), Fun_and), |
1265 add_lookup_const (("op &", bool --> bool --> bool), Fun_and), |
1215 add_lookup_const (("op |", bool --> bool --> bool), Fun_or), |
1266 add_lookup_const (("op |", bool --> bool --> bool), Fun_or), |
1216 add_lookup_const (("HOL.If", bool --> A --> A --> A), Fun_if), |
1267 add_lookup_const (("HOL.If", bool --> A --> A --> A), Fun_if), |
1217 add_lookup_const (("List.list.Cons", A --> list A --> list A), Cons_cons), |
1268 add_lookup_const (("List.list.Cons", A --> list A --> list A), Cons_cons), |
1218 add_lookup_const (("List.list.Nil", list A), Cons_nil), |
1269 add_lookup_const (("List.list.Nil", list A), Cons_nil), |
1219 add_lookup_const (("Pair", A --> B --> pair A B), Cons_pair), |
1270 add_lookup_const (("Pair", A --> B --> pair A B), Cons_pair), |
1220 add_lookup_const (("fst", pair A B --> A), Fun_fst), |
1271 add_lookup_const (("fst", pair A B --> A), Fun_fst), |
1221 add_lookup_const (("snd", pair A B --> B), Fun_snd), |
1272 add_lookup_const (("snd", pair A B --> B), Fun_snd), |
1222 add_lookup_const (("1", nat), |
1273 add_lookup_const (("1", nat), |