40 | stmt_names_of (MLClassinst (i, _)) = [i]; |
40 | stmt_names_of (MLClassinst (i, _)) = [i]; |
41 |
41 |
42 |
42 |
43 (** SML serailizer **) |
43 (** SML serailizer **) |
44 |
44 |
45 fun pr_sml_stmt syntax_tyco syntax_const labelled_name reserved_names deresolve is_cons = |
45 fun pr_sml_stmt naming labelled_name syntax_tyco syntax_const reserved_names deresolve is_cons = |
46 let |
46 let |
47 val pr_label_classrel = translate_string (fn "." => "__" | c => c) |
47 val pr_label_classrel = translate_string (fn "." => "__" | c => c) |
48 o NameSpace.qualifier; |
48 o NameSpace.qualifier; |
49 val pr_label_classparam = NameSpace.base o NameSpace.qualifier; |
49 val pr_label_classparam = NameSpace.base o NameSpace.qualifier; |
50 fun pr_dicts fxy ds = |
50 fun pr_dicts fxy ds = |
51 let |
51 let |
52 fun pr_dictvar (v, (_, 1)) = first_upper v ^ "_" |
52 fun pr_dictvar (v, (_, 1)) = Code_Name.first_upper v ^ "_" |
53 | pr_dictvar (v, (i, _)) = first_upper v ^ string_of_int (i+1) ^ "_"; |
53 | pr_dictvar (v, (i, _)) = Code_Name.first_upper v ^ string_of_int (i+1) ^ "_"; |
54 fun pr_proj [] p = |
54 fun pr_proj [] p = |
55 p |
55 p |
56 | pr_proj [p'] p = |
56 | pr_proj [p'] p = |
57 brackets [p', p] |
57 brackets [p', p] |
58 | pr_proj (ps as _ :: _) p = |
58 | pr_proj (ps as _ :: _) p = |
84 | SOME (i, pr) => pr pr_typ fxy tys) |
84 | SOME (i, pr) => pr pr_typ fxy tys) |
85 | pr_typ fxy (ITyVar v) = str ("'" ^ v); |
85 | pr_typ fxy (ITyVar v) = str ("'" ^ v); |
86 fun pr_term thm pat vars fxy (IConst c) = |
86 fun pr_term thm pat vars fxy (IConst c) = |
87 pr_app thm pat vars fxy (c, []) |
87 pr_app thm pat vars fxy (c, []) |
88 | pr_term thm pat vars fxy (IVar v) = |
88 | pr_term thm pat vars fxy (IVar v) = |
89 str (lookup_var vars v) |
89 str (Code_Name.lookup_var vars v) |
90 | pr_term thm pat vars fxy (t as t1 `$ t2) = |
90 | pr_term thm pat vars fxy (t as t1 `$ t2) = |
91 (case Code_Thingol.unfold_const_app t |
91 (case Code_Thingol.unfold_const_app t |
92 of SOME c_ts => pr_app thm pat vars fxy c_ts |
92 of SOME c_ts => pr_app thm pat vars fxy c_ts |
93 | NONE => |
93 | NONE => |
94 brackify fxy [pr_term thm pat vars NOBR t1, pr_term thm pat vars BR t2]) |
94 brackify fxy [pr_term thm pat vars NOBR t1, pr_term thm pat vars BR t2]) |
114 else if k = length ts then |
114 else if k = length ts then |
115 [(str o deresolve) c, Pretty.enum "," "(" ")" (map (pr_term thm pat vars NOBR) ts)] |
115 [(str o deresolve) c, Pretty.enum "," "(" ")" (map (pr_term thm pat vars NOBR) ts)] |
116 else [pr_term thm pat vars BR (Code_Thingol.eta_expand k app)] end else |
116 else [pr_term thm pat vars BR (Code_Thingol.eta_expand k app)] end else |
117 (str o deresolve) c |
117 (str o deresolve) c |
118 :: (map (pr_dicts BR) o filter_out null) iss @ map (pr_term thm pat vars BR) ts |
118 :: (map (pr_dicts BR) o filter_out null) iss @ map (pr_term thm pat vars BR) ts |
119 and pr_app thm pat vars = gen_pr_app pr_app' pr_term syntax_const is_cons thm pat vars |
119 and pr_app thm pat vars = gen_pr_app pr_app' pr_term syntax_const is_cons naming thm pat vars |
120 and pr_bind' ((NONE, NONE), _) = str "_" |
120 and pr_bind' ((NONE, NONE), _) = str "_" |
121 | pr_bind' ((SOME v, NONE), _) = str v |
121 | pr_bind' ((SOME v, NONE), _) = str v |
122 | pr_bind' ((NONE, SOME p), _) = p |
122 | pr_bind' ((NONE, SOME p), _) = p |
123 | pr_bind' ((SOME v, SOME p), _) = concat [str v, str "as", p] |
123 | pr_bind' ((SOME v, SOME p), _) = concat [str v, str "as", p] |
124 and pr_bind thm = gen_pr_bind pr_bind' pr_term thm |
124 and pr_bind thm = gen_pr_bind pr_bind' pr_term thm |
197 val consts = map_filter |
197 val consts = map_filter |
198 (fn c => if (is_some o syntax_const) c |
198 (fn c => if (is_some o syntax_const) c |
199 then NONE else (SOME o NameSpace.base o deresolve) c) |
199 then NONE else (SOME o NameSpace.base o deresolve) c) |
200 ((fold o Code_Thingol.fold_constnames) (insert (op =)) (t :: ts) []); |
200 ((fold o Code_Thingol.fold_constnames) (insert (op =)) (t :: ts) []); |
201 val vars = reserved_names |
201 val vars = reserved_names |
202 |> intro_vars consts |
202 |> Code_Name.intro_vars consts |
203 |> intro_vars ((fold o Code_Thingol.fold_unbound_varnames) |
203 |> Code_Name.intro_vars ((fold o Code_Thingol.fold_unbound_varnames) |
204 (insert (op =)) ts []); |
204 (insert (op =)) ts []); |
205 in |
205 in |
206 concat ( |
206 concat ( |
207 [str definer, (str o deresolve) name] |
207 [str definer, (str o deresolve) name] |
208 @ (if null ts andalso null vs_dict |
208 @ (if null ts andalso null vs_dict |
248 val (ps, p) = split_last |
248 val (ps, p) = split_last |
249 (pr_data "datatype" data :: map (pr_data "and") datas'); |
249 (pr_data "datatype" data :: map (pr_data "and") datas'); |
250 in Pretty.chunks (ps @ [Pretty.block ([p, str ";"])]) end |
250 in Pretty.chunks (ps @ [Pretty.block ([p, str ";"])]) end |
251 | pr_stmt (MLClass (class, (v, (superclasses, classparams)))) = |
251 | pr_stmt (MLClass (class, (v, (superclasses, classparams)))) = |
252 let |
252 let |
253 val w = first_upper v ^ "_"; |
253 val w = Code_Name.first_upper v ^ "_"; |
254 fun pr_superclass_field (class, classrel) = |
254 fun pr_superclass_field (class, classrel) = |
255 (concat o map str) [ |
255 (concat o map str) [ |
256 pr_label_classrel classrel, ":", "'" ^ v, deresolve class |
256 pr_label_classrel classrel, ":", "'" ^ v, deresolve class |
257 ]; |
257 ]; |
258 fun pr_classparam_field (classparam, ty) = |
258 fun pr_classparam_field (classparam, ty) = |
340 }; |
340 }; |
341 |
341 |
342 |
342 |
343 (** OCaml serializer **) |
343 (** OCaml serializer **) |
344 |
344 |
345 fun pr_ocaml_stmt syntax_tyco syntax_const labelled_name reserved_names deresolve is_cons = |
345 fun pr_ocaml_stmt naming labelled_name syntax_tyco syntax_const reserved_names deresolve is_cons = |
346 let |
346 let |
347 fun pr_dicts fxy ds = |
347 fun pr_dicts fxy ds = |
348 let |
348 let |
349 fun pr_dictvar (v, (_, 1)) = "_" ^ first_upper v |
349 fun pr_dictvar (v, (_, 1)) = "_" ^ Code_Name.first_upper v |
350 | pr_dictvar (v, (i, _)) = "_" ^ first_upper v ^ string_of_int (i+1); |
350 | pr_dictvar (v, (i, _)) = "_" ^ Code_Name.first_upper v ^ string_of_int (i+1); |
351 fun pr_proj ps p = |
351 fun pr_proj ps p = |
352 fold_rev (fn p2 => fn p1 => Pretty.block [p1, str ".", str p2]) ps p |
352 fold_rev (fn p2 => fn p1 => Pretty.block [p1, str ".", str p2]) ps p |
353 fun pr_dict fxy (DictConst (inst, dss)) = |
353 fun pr_dict fxy (DictConst (inst, dss)) = |
354 brackify fxy ((str o deresolve) inst :: map (pr_dicts BR) dss) |
354 brackify fxy ((str o deresolve) inst :: map (pr_dicts BR) dss) |
355 | pr_dict fxy (DictVar (classrels, v)) = |
355 | pr_dict fxy (DictVar (classrels, v)) = |
377 | SOME (i, pr) => pr pr_typ fxy tys) |
377 | SOME (i, pr) => pr pr_typ fxy tys) |
378 | pr_typ fxy (ITyVar v) = str ("'" ^ v); |
378 | pr_typ fxy (ITyVar v) = str ("'" ^ v); |
379 fun pr_term thm pat vars fxy (IConst c) = |
379 fun pr_term thm pat vars fxy (IConst c) = |
380 pr_app thm pat vars fxy (c, []) |
380 pr_app thm pat vars fxy (c, []) |
381 | pr_term thm pat vars fxy (IVar v) = |
381 | pr_term thm pat vars fxy (IVar v) = |
382 str (lookup_var vars v) |
382 str (Code_Name.lookup_var vars v) |
383 | pr_term thm pat vars fxy (t as t1 `$ t2) = |
383 | pr_term thm pat vars fxy (t as t1 `$ t2) = |
384 (case Code_Thingol.unfold_const_app t |
384 (case Code_Thingol.unfold_const_app t |
385 of SOME c_ts => pr_app thm pat vars fxy c_ts |
385 of SOME c_ts => pr_app thm pat vars fxy c_ts |
386 | NONE => |
386 | NONE => |
387 brackify fxy [pr_term thm pat vars NOBR t1, pr_term thm pat vars BR t2]) |
387 brackify fxy [pr_term thm pat vars NOBR t1, pr_term thm pat vars BR t2]) |
405 | _ => [(str o deresolve) c, Pretty.enum "," "(" ")" |
405 | _ => [(str o deresolve) c, Pretty.enum "," "(" ")" |
406 (map (pr_term thm pat vars NOBR) ts)] |
406 (map (pr_term thm pat vars NOBR) ts)] |
407 else [pr_term thm pat vars BR (Code_Thingol.eta_expand (length tys) app)] |
407 else [pr_term thm pat vars BR (Code_Thingol.eta_expand (length tys) app)] |
408 else (str o deresolve) c |
408 else (str o deresolve) c |
409 :: ((map (pr_dicts BR) o filter_out null) iss @ map (pr_term thm pat vars BR) ts) |
409 :: ((map (pr_dicts BR) o filter_out null) iss @ map (pr_term thm pat vars BR) ts) |
410 and pr_app thm pat vars = gen_pr_app pr_app' pr_term syntax_const is_cons thm pat vars |
410 and pr_app thm pat vars = gen_pr_app pr_app' pr_term syntax_const is_cons naming thm pat vars |
411 and pr_bind' ((NONE, NONE), _) = str "_" |
411 and pr_bind' ((NONE, NONE), _) = str "_" |
412 | pr_bind' ((SOME v, NONE), _) = str v |
412 | pr_bind' ((SOME v, NONE), _) = str v |
413 | pr_bind' ((NONE, SOME p), _) = p |
413 | pr_bind' ((NONE, SOME p), _) = p |
414 | pr_bind' ((SOME v, SOME p), _) = brackets [p, str "as", str v] |
414 | pr_bind' ((SOME v, SOME p), _) = brackets [p, str "as", str v] |
415 and pr_bind thm = gen_pr_bind pr_bind' pr_term thm |
415 and pr_bind thm = gen_pr_bind pr_bind' pr_term thm |
447 | fillup_param x (i, NONE) = x ^ string_of_int i; |
447 | fillup_param x (i, NONE) = x ^ string_of_int i; |
448 val fished1 = fold (map2 fish_param) eqs (replicate (length (hd eqs)) NONE); |
448 val fished1 = fold (map2 fish_param) eqs (replicate (length (hd eqs)) NONE); |
449 val x = Name.variant (map_filter I fished1) "x"; |
449 val x = Name.variant (map_filter I fished1) "x"; |
450 val fished2 = map_index (fillup_param x) fished1; |
450 val fished2 = map_index (fillup_param x) fished1; |
451 val (fished3, _) = Name.variants fished2 Name.context; |
451 val (fished3, _) = Name.variants fished2 Name.context; |
452 val vars' = intro_vars fished3 vars; |
452 val vars' = Code_Name.intro_vars fished3 vars; |
453 in map (lookup_var vars') fished3 end; |
453 in map (Code_Name.lookup_var vars') fished3 end; |
454 fun pr_stmt (MLFuns (funns as funn :: funns')) = |
454 fun pr_stmt (MLFuns (funns as funn :: funns')) = |
455 let |
455 let |
456 fun pr_eq ((ts, t), (thm, _)) = |
456 fun pr_eq ((ts, t), (thm, _)) = |
457 let |
457 let |
458 val consts = map_filter |
458 val consts = map_filter |
459 (fn c => if (is_some o syntax_const) c |
459 (fn c => if (is_some o syntax_const) c |
460 then NONE else (SOME o NameSpace.base o deresolve) c) |
460 then NONE else (SOME o NameSpace.base o deresolve) c) |
461 ((fold o Code_Thingol.fold_constnames) (insert (op =)) (t :: ts) []); |
461 ((fold o Code_Thingol.fold_constnames) (insert (op =)) (t :: ts) []); |
462 val vars = reserved_names |
462 val vars = reserved_names |
463 |> intro_vars consts |
463 |> Code_Name.intro_vars consts |
464 |> intro_vars ((fold o Code_Thingol.fold_unbound_varnames) |
464 |> Code_Name.intro_vars ((fold o Code_Thingol.fold_unbound_varnames) |
465 (insert (op =)) ts []); |
465 (insert (op =)) ts []); |
466 in concat [ |
466 in concat [ |
467 (Pretty.block o Pretty.commas) (map (pr_term thm true vars NOBR) ts), |
467 (Pretty.block o Pretty.commas) (map (pr_term thm true vars NOBR) ts), |
468 str "->", |
468 str "->", |
469 pr_term thm false vars NOBR t |
469 pr_term thm false vars NOBR t |
486 val consts = map_filter |
486 val consts = map_filter |
487 (fn c => if (is_some o syntax_const) c |
487 (fn c => if (is_some o syntax_const) c |
488 then NONE else (SOME o NameSpace.base o deresolve) c) |
488 then NONE else (SOME o NameSpace.base o deresolve) c) |
489 ((fold o Code_Thingol.fold_constnames) (insert (op =)) (t :: ts) []); |
489 ((fold o Code_Thingol.fold_constnames) (insert (op =)) (t :: ts) []); |
490 val vars = reserved_names |
490 val vars = reserved_names |
491 |> intro_vars consts |
491 |> Code_Name.intro_vars consts |
492 |> intro_vars ((fold o Code_Thingol.fold_unbound_varnames) |
492 |> Code_Name.intro_vars ((fold o Code_Thingol.fold_unbound_varnames) |
493 (insert (op =)) ts []); |
493 (insert (op =)) ts []); |
494 in |
494 in |
495 concat ( |
495 concat ( |
496 map (pr_term thm true vars BR) ts |
496 map (pr_term thm true vars BR) ts |
497 @ str "=" |
497 @ str "=" |
514 (fn c => if (is_some o syntax_const) c |
514 (fn c => if (is_some o syntax_const) c |
515 then NONE else (SOME o NameSpace.base o deresolve) c) |
515 then NONE else (SOME o NameSpace.base o deresolve) c) |
516 ((fold o Code_Thingol.fold_constnames) |
516 ((fold o Code_Thingol.fold_constnames) |
517 (insert (op =)) (map (snd o fst) eqs) []); |
517 (insert (op =)) (map (snd o fst) eqs) []); |
518 val vars = reserved_names |
518 val vars = reserved_names |
519 |> intro_vars consts; |
519 |> Code_Name.intro_vars consts; |
520 val dummy_parms = (map str o fish_params vars o map (fst o fst)) eqs; |
520 val dummy_parms = (map str o fish_params vars o map (fst o fst)) eqs; |
521 in |
521 in |
522 Pretty.block ( |
522 Pretty.block ( |
523 Pretty.breaks dummy_parms |
523 Pretty.breaks dummy_parms |
524 @ Pretty.brk 1 |
524 @ Pretty.brk 1 |
572 val (ps, p) = split_last |
572 val (ps, p) = split_last |
573 (pr_data "type" data :: map (pr_data "and") datas'); |
573 (pr_data "type" data :: map (pr_data "and") datas'); |
574 in Pretty.chunks (ps @ [Pretty.block ([p, str ";;"])]) end |
574 in Pretty.chunks (ps @ [Pretty.block ([p, str ";;"])]) end |
575 | pr_stmt (MLClass (class, (v, (superclasses, classparams)))) = |
575 | pr_stmt (MLClass (class, (v, (superclasses, classparams)))) = |
576 let |
576 let |
577 val w = "_" ^ first_upper v; |
577 val w = "_" ^ Code_Name.first_upper v; |
578 fun pr_superclass_field (class, classrel) = |
578 fun pr_superclass_field (class, classrel) = |
579 (concat o map str) [ |
579 (concat o map str) [ |
580 deresolve classrel, ":", "'" ^ v, deresolve class |
580 deresolve classrel, ":", "'" ^ v, deresolve class |
581 ]; |
581 ]; |
582 fun pr_classparam_field (classparam, ty) = |
582 fun pr_classparam_field (classparam, ty) = |
714 in (x, (nsp_fun', nsp_typ)) end; |
714 in (x, (nsp_fun', nsp_typ)) end; |
715 fun map_nsp_typ_yield f (nsp_fun, nsp_typ) = |
715 fun map_nsp_typ_yield f (nsp_fun, nsp_typ) = |
716 let |
716 let |
717 val (x, nsp_typ') = f nsp_typ |
717 val (x, nsp_typ') = f nsp_typ |
718 in (x, (nsp_fun, nsp_typ')) end; |
718 in (x, (nsp_fun, nsp_typ')) end; |
719 val mk_name_module = mk_name_module reserved_names NONE module_alias program; |
719 val mk_name_module = Code_Name.mk_name_module reserved_names NONE module_alias program; |
720 fun mk_name_stmt upper name nsp = |
720 fun mk_name_stmt upper name nsp = |
721 let |
721 let |
722 val (_, base) = dest_name name; |
722 val (_, base) = Code_Name.dest_name name; |
723 val base' = if upper then first_upper base else base; |
723 val base' = if upper then Code_Name.first_upper base else base; |
724 val ([base''], nsp') = Name.variants [base'] nsp; |
724 val ([base''], nsp') = Name.variants [base'] nsp; |
725 in (base'', nsp') end; |
725 in (base'', nsp') end; |
726 fun add_funs stmts = |
726 fun add_funs stmts = |
727 fold_map |
727 fold_map |
728 (fn (name, Code_Thingol.Fun stmt) => |
728 (fn (name, Code_Thingol.Fun (_, stmt)) => |
729 map_nsp_fun_yield (mk_name_stmt false name) #>> |
729 map_nsp_fun_yield (mk_name_stmt false name) #>> |
730 rpair (name, stmt |> apsnd (filter (snd o snd))) |
730 rpair (name, stmt |> apsnd (filter (snd o snd))) |
731 | (name, _) => |
731 | (name, _) => |
732 error ("Function block containing illegal statement: " ^ labelled_name name) |
732 error ("Function block containing illegal statement: " ^ labelled_name name) |
733 ) stmts |
733 ) stmts |
734 #>> (split_list #> apsnd MLFuns); |
734 #>> (split_list #> apsnd MLFuns); |
735 fun add_datatypes stmts = |
735 fun add_datatypes stmts = |
736 fold_map |
736 fold_map |
737 (fn (name, Code_Thingol.Datatype stmt) => |
737 (fn (name, Code_Thingol.Datatype (_, stmt)) => |
738 map_nsp_typ_yield (mk_name_stmt false name) #>> rpair (SOME (name, stmt)) |
738 map_nsp_typ_yield (mk_name_stmt false name) #>> rpair (SOME (name, stmt)) |
739 | (name, Code_Thingol.Datatypecons _) => |
739 | (name, Code_Thingol.Datatypecons _) => |
740 map_nsp_fun_yield (mk_name_stmt true name) #>> rpair NONE |
740 map_nsp_fun_yield (mk_name_stmt true name) #>> rpair NONE |
741 | (name, _) => |
741 | (name, _) => |
742 error ("Datatype block containing illegal statement: " ^ labelled_name name) |
742 error ("Datatype block containing illegal statement: " ^ labelled_name name) |
745 #> (fn [] => error ("Datatype block without data statement: " |
745 #> (fn [] => error ("Datatype block without data statement: " |
746 ^ (commas o map (labelled_name o fst)) stmts) |
746 ^ (commas o map (labelled_name o fst)) stmts) |
747 | stmts => MLDatas stmts))); |
747 | stmts => MLDatas stmts))); |
748 fun add_class stmts = |
748 fun add_class stmts = |
749 fold_map |
749 fold_map |
750 (fn (name, Code_Thingol.Class info) => |
750 (fn (name, Code_Thingol.Class (_, stmt)) => |
751 map_nsp_typ_yield (mk_name_stmt false name) #>> rpair (SOME (name, info)) |
751 map_nsp_typ_yield (mk_name_stmt false name) #>> rpair (SOME (name, stmt)) |
752 | (name, Code_Thingol.Classrel _) => |
752 | (name, Code_Thingol.Classrel _) => |
753 map_nsp_fun_yield (mk_name_stmt false name) #>> rpair NONE |
753 map_nsp_fun_yield (mk_name_stmt false name) #>> rpair NONE |
754 | (name, Code_Thingol.Classparam _) => |
754 | (name, Code_Thingol.Classparam _) => |
755 map_nsp_fun_yield (mk_name_stmt false name) #>> rpair NONE |
755 map_nsp_fun_yield (mk_name_stmt false name) #>> rpair NONE |
756 | (name, _) => |
756 | (name, _) => |
784 val names as (name :: names') = map fst stmts; |
784 val names as (name :: names') = map fst stmts; |
785 val deps = |
785 val deps = |
786 [] |
786 [] |
787 |> fold (fold (insert (op =)) o Graph.imm_succs program) names |
787 |> fold (fold (insert (op =)) o Graph.imm_succs program) names |
788 |> subtract (op =) names; |
788 |> subtract (op =) names; |
789 val (module_names, _) = (split_list o map dest_name) names; |
789 val (module_names, _) = (split_list o map Code_Name.dest_name) names; |
790 val module_name = (the_single o distinct (op =) o map mk_name_module) module_names |
790 val module_name = (the_single o distinct (op =) o map mk_name_module) module_names |
791 handle Empty => |
791 handle Empty => |
792 error ("Different namespace prefixes for mutual dependencies:\n" |
792 error ("Different namespace prefixes for mutual dependencies:\n" |
793 ^ commas (map labelled_name names) |
793 ^ commas (map labelled_name names) |
794 ^ "\n" |
794 ^ "\n" |
795 ^ commas module_names); |
795 ^ commas module_names); |
796 val module_name_path = NameSpace.explode module_name; |
796 val module_name_path = NameSpace.explode module_name; |
797 fun add_dep name name' = |
797 fun add_dep name name' = |
798 let |
798 let |
799 val module_name' = (mk_name_module o fst o dest_name) name'; |
799 val module_name' = (mk_name_module o fst o Code_Name.dest_name) name'; |
800 in if module_name = module_name' then |
800 in if module_name = module_name' then |
801 map_node module_name_path (Graph.add_edge (name, name')) |
801 map_node module_name_path (Graph.add_edge (name, name')) |
802 else let |
802 else let |
803 val (common, (diff1::_, diff2::_)) = chop_prefix (op =) |
803 val (common, (diff1::_, diff2::_)) = chop_prefix (op =) |
804 (module_name_path, NameSpace.explode module_name'); |
804 (module_name_path, NameSpace.explode module_name'); |
822 val (_, nodes) = empty_module |
822 val (_, nodes) = empty_module |
823 |> fold add_stmts' (map (AList.make (Graph.get_node program)) |
823 |> fold add_stmts' (map (AList.make (Graph.get_node program)) |
824 (rev (Graph.strong_conn program))); |
824 (rev (Graph.strong_conn program))); |
825 fun deresolver prefix name = |
825 fun deresolver prefix name = |
826 let |
826 let |
827 val module_name = (fst o dest_name) name; |
827 val module_name = (fst o Code_Name.dest_name) name; |
828 val module_name' = (NameSpace.explode o mk_name_module) module_name; |
828 val module_name' = (NameSpace.explode o mk_name_module) module_name; |
829 val (_, (_, remainder)) = chop_prefix (op =) (prefix, module_name'); |
829 val (_, (_, remainder)) = chop_prefix (op =) (prefix, module_name'); |
830 val stmt_name = |
830 val stmt_name = |
831 nodes |
831 nodes |
832 |> fold (fn name => fn node => case Graph.get_node node name |
832 |> fold (fn name => fn node => case Graph.get_node node name |
838 end handle Graph.UNDEF _ => |
838 end handle Graph.UNDEF _ => |
839 error ("Unknown statement name: " ^ labelled_name name); |
839 error ("Unknown statement name: " ^ labelled_name name); |
840 in (deresolver, nodes) end; |
840 in (deresolver, nodes) end; |
841 |
841 |
842 fun serialize_ml target compile pr_module pr_stmt raw_module_name labelled_name reserved_names includes raw_module_alias |
842 fun serialize_ml target compile pr_module pr_stmt raw_module_name labelled_name reserved_names includes raw_module_alias |
843 _ syntax_tyco syntax_const program cs destination = |
843 _ syntax_tyco syntax_const naming program cs destination = |
844 let |
844 let |
845 val is_cons = Code_Thingol.is_cons program; |
845 val is_cons = Code_Thingol.is_cons program; |
846 val stmt_names = Code_Target.stmt_names_of_destination destination; |
846 val stmt_names = Code_Target.stmt_names_of_destination destination; |
847 val module_name = if null stmt_names then raw_module_name else SOME "Code"; |
847 val module_name = if null stmt_names then raw_module_name else SOME "Code"; |
848 val (deresolver, nodes) = ml_node_of_program labelled_name module_name |
848 val (deresolver, nodes) = ml_node_of_program labelled_name module_name |
849 reserved_names raw_module_alias program; |
849 reserved_names raw_module_alias program; |
850 val reserved_names = make_vars reserved_names; |
850 val reserved_names = Code_Name.make_vars reserved_names; |
851 fun pr_node prefix (Dummy _) = |
851 fun pr_node prefix (Dummy _) = |
852 NONE |
852 NONE |
853 | pr_node prefix (Stmt (_, stmt)) = if null stmt_names orelse |
853 | pr_node prefix (Stmt (_, stmt)) = if null stmt_names orelse |
854 (not o null o filter (member (op =) stmt_names) o stmt_names_of) stmt then SOME |
854 (not o null o filter (member (op =) stmt_names) o stmt_names_of) stmt then SOME |
855 (pr_stmt syntax_tyco syntax_const labelled_name reserved_names |
855 (pr_stmt naming labelled_name syntax_tyco syntax_const reserved_names |
856 (deresolver prefix) is_cons stmt) |
856 (deresolver prefix) is_cons stmt) |
857 else NONE |
857 else NONE |
858 | pr_node prefix (Module (module_name, (_, nodes))) = |
858 | pr_node prefix (Module (module_name, (_, nodes))) = |
859 separate (str "") |
859 separate (str "") |
860 ((map_filter (pr_node (prefix @ [module_name]) o Graph.get_node nodes) |
860 ((map_filter (pr_node (prefix @ [module_name]) o Graph.get_node nodes) |
861 o rev o flat o Graph.strong_conn) nodes) |
861 o rev o flat o Graph.strong_conn) nodes) |
862 |> (if null stmt_names then pr_module module_name else Pretty.chunks) |
862 |> (if null stmt_names then pr_module module_name else Pretty.chunks) |
863 |> SOME; |
863 |> SOME; |
864 val cs' = map_filter (try (deresolver (if is_some module_name then the_list module_name else []))) |
864 val cs' = (map o try) |
865 cs; |
865 (deresolver (if is_some module_name then the_list module_name else [])) cs; |
866 val p = Pretty.chunks (separate (str "") (map snd includes @ (map_filter |
866 val p = Pretty.chunks (separate (str "") (map snd includes @ (map_filter |
867 (pr_node [] o Graph.get_node nodes) o rev o flat o Graph.strong_conn) nodes)); |
867 (pr_node [] o Graph.get_node nodes) o rev o flat o Graph.strong_conn) nodes)); |
868 in |
868 in |
869 Code_Target.mk_serialization target |
869 Code_Target.mk_serialization target |
870 (case compile of SOME compile => SOME (compile o Code_Target.code_of_pretty) | NONE => NONE) |
870 (case compile of SOME compile => SOME (compile o Code_Target.code_of_pretty) | NONE => NONE) |
888 let |
888 let |
889 val ctxt = ProofContext.init thy; |
889 val ctxt = ProofContext.init thy; |
890 val _ = if null (term_frees (term_of ct)) then () else error ("Term " |
890 val _ = if null (term_frees (term_of ct)) then () else error ("Term " |
891 ^ quote (Syntax.string_of_term_global thy (term_of ct)) |
891 ^ quote (Syntax.string_of_term_global thy (term_of ct)) |
892 ^ " to be evaluated contains free variables"); |
892 ^ " to be evaluated contains free variables"); |
893 fun eval' program ((vs, ty), t) deps = |
893 fun eval' naming program ((vs, ty), t) deps = |
894 let |
894 let |
895 val _ = if Code_Thingol.contains_dictvar t then |
895 val _ = if Code_Thingol.contains_dictvar t then |
896 error "Term to be evaluated constains free dictionaries" else (); |
896 error "Term to be evaluated constains free dictionaries" else (); |
|
897 val value_name = "Value.VALUE.value" |
897 val program' = program |
898 val program' = program |
898 |> Graph.new_node (Code_Name.value_name, |
899 |> Graph.new_node (value_name, |
899 Code_Thingol.Fun (([], ty), [(([], t), (Drule.dummy_thm, true))])) |
900 Code_Thingol.Fun (Term.dummy_patternN, (([], ty), [(([], t), (Drule.dummy_thm, true))]))) |
900 |> fold (curry Graph.add_edge Code_Name.value_name) deps; |
901 |> fold (curry Graph.add_edge value_name) deps; |
901 val (value_code, [value_name']) = ml_code_of thy program' [Code_Name.value_name]; |
902 val (value_code, [SOME value_name']) = ml_code_of thy naming program' [value_name]; |
902 val sml_code = "let\n" ^ value_code ^ "\nin " ^ value_name' |
903 val sml_code = "let\n" ^ value_code ^ "\nin " ^ value_name' |
903 ^ space_implode " " (map (enclose "(" ")") args) ^ " end"; |
904 ^ space_implode " " (map (enclose "(" ")") args) ^ " end"; |
904 in ML_Context.evaluate ctxt Output.ml_output false reff sml_code end; |
905 in ML_Context.evaluate ctxt Output.ml_output false reff sml_code end; |
905 in eval'' thy (fn t => (t, eval')) ct end; |
906 in eval'' thy (fn t => (t, eval')) ct end; |
906 |
907 |
920 |
921 |
921 val is_first_occ = fst o snd o CodeAntiqData.get; |
922 val is_first_occ = fst o snd o CodeAntiqData.get; |
922 |
923 |
923 fun delayed_code thy consts () = |
924 fun delayed_code thy consts () = |
924 let |
925 let |
925 val (consts', program) = Code_Thingol.consts_program thy consts; |
926 val (consts', (naming, program)) = Code_Thingol.consts_program thy consts; |
926 val (ml_code, consts'') = ml_code_of thy program consts'; |
927 val (ml_code, consts'') = ml_code_of thy naming program consts'; |
927 val _ = if length consts <> length consts'' then |
928 val const_tab = map2 (fn const => fn NONE => |
928 error ("One of the constants " ^ commas (map (quote o Code_Unit.string_of_const thy) consts) |
929 error ("Constant " ^ (quote o Code_Unit.string_of_const thy) const |
929 ^ "\nhas a user-defined serialization") else (); |
930 ^ "\nhas a user-defined serialization") |
930 in (ml_code, consts ~~ consts'') end; |
931 | SOME const' => (const, const')) consts consts'' |
|
932 in (ml_code, const_tab) end; |
931 |
933 |
932 fun register_const const ctxt = |
934 fun register_const const ctxt = |
933 let |
935 let |
934 val (consts, (_, (struct_name, _))) = CodeAntiqData.get ctxt; |
936 val (consts, (_, (struct_name, _))) = CodeAntiqData.get ctxt; |
935 val consts' = insert (op =) const consts; |
937 val consts' = insert (op =) const consts; |