src/Pure/Tools/codegen_serializer.ML
changeset 23513 2ebb50c0db4f
parent 22846 fb79144af9a3
child 23691 cedf9610b71d
equal deleted inserted replaced
23512:770e7f9f715b 23513:2ebb50c0db4f
   264 val first_lower = implode o nth_map 0 Symbol.to_ascii_lower o explode;
   264 val first_lower = implode o nth_map 0 Symbol.to_ascii_lower o explode;
   265 
   265 
   266 val dest_name =
   266 val dest_name =
   267   apfst NameSpace.implode o split_last o fst o split_last o NameSpace.explode;
   267   apfst NameSpace.implode o split_last o fst o split_last o NameSpace.explode;
   268 
   268 
   269 fun mk_modl_name_tab empty_names prefix module_alias code =
   269 fun mk_modl_name_tab init_names prefix module_alias code =
   270   let
   270   let
   271     fun nsp_map f = NameSpace.explode #> map f #> NameSpace.implode;
   271     fun nsp_map f = NameSpace.explode #> map f #> NameSpace.implode;
   272     fun mk_alias name =
   272     fun mk_alias name =
   273      case module_alias name
   273      case module_alias name
   274       of SOME name' => name'
   274       of SOME name' => name'
   275        | NONE => nsp_map (fn name => (the_single o fst)
   275        | NONE => nsp_map (fn name => (the_single o fst)
   276             (Name.variants [name] empty_names)) name;
   276             (Name.variants [name] init_names)) name;
   277     fun mk_prefix name =
   277     fun mk_prefix name =
   278       case prefix
   278       case prefix
   279        of SOME prefix => NameSpace.append prefix name
   279        of SOME prefix => NameSpace.append prefix name
   280         | NONE => name;
   280         | NONE => name;
   281     val tab =
   281     val tab =
   295   | MLClass of string * ((class * string) list * (vname * (string * itype) list))
   295   | MLClass of string * ((class * string) list * (vname * (string * itype) list))
   296   | MLClassinst of string * ((class * (string * (vname * sort) list))
   296   | MLClassinst of string * ((class * (string * (vname * sort) list))
   297         * ((class * (string * (string * dict list list))) list
   297         * ((class * (string * (string * dict list list))) list
   298       * (string * iterm) list));
   298       * (string * iterm) list));
   299 
   299 
   300 fun pr_sml tyco_syntax const_syntax labelled_name keyword_vars deresolv is_cons ml_def =
   300 fun pr_sml tyco_syntax const_syntax labelled_name init_syms deresolv is_cons ml_def =
   301   let
   301   let
   302     val pr_label_classrel = translate_string (fn "." => "__" | c => c) o NameSpace.qualifier;
   302     val pr_label_classrel = translate_string (fn "." => "__" | c => c) o NameSpace.qualifier;
   303     val pr_label_classop = NameSpace.base o NameSpace.qualifier;
   303     val pr_label_classop = NameSpace.base o NameSpace.qualifier;
   304     fun pr_dicts fxy ds =
   304     fun pr_dicts fxy ds =
   305       let
   305       let
   430                   let
   430                   let
   431                     val consts = map_filter
   431                     val consts = map_filter
   432                       (fn c => if (is_some o const_syntax) c
   432                       (fn c => if (is_some o const_syntax) c
   433                         then NONE else (SOME o NameSpace.base o deresolv) c)
   433                         then NONE else (SOME o NameSpace.base o deresolv) c)
   434                         ((fold o CodegenThingol.fold_constnames) (insert (op =)) (t :: ts) []);
   434                         ((fold o CodegenThingol.fold_constnames) (insert (op =)) (t :: ts) []);
   435                     val vars = keyword_vars
   435                     val vars = init_syms
   436                       |> CodegenNames.intro_vars consts
   436                       |> CodegenNames.intro_vars consts
   437                       |> CodegenNames.intro_vars ((fold o CodegenThingol.fold_unbound_varnames)
   437                       |> CodegenNames.intro_vars ((fold o CodegenThingol.fold_unbound_varnames)
   438                            (insert (op =)) ts []);
   438                            (insert (op =)) ts []);
   439                   in
   439                   in
   440                     concat (
   440                     concat (
   537               let
   537               let
   538                 val consts = map_filter
   538                 val consts = map_filter
   539                   (fn c => if (is_some o const_syntax) c
   539                   (fn c => if (is_some o const_syntax) c
   540                     then NONE else (SOME o NameSpace.base o deresolv) c)
   540                     then NONE else (SOME o NameSpace.base o deresolv) c)
   541                     (CodegenThingol.fold_constnames (insert (op =)) t []);
   541                     (CodegenThingol.fold_constnames (insert (op =)) t []);
   542                 val vars = CodegenNames.intro_vars consts keyword_vars;
   542                 val vars = CodegenNames.intro_vars consts init_syms;
   543               in
   543               in
   544                 concat [
   544                 concat [
   545                   (str o pr_label_classop) classop,
   545                   (str o pr_label_classop) classop,
   546                   str "=",
   546                   str "=",
   547                   pr_term vars NOBR t
   547                   pr_term vars NOBR t
   568   ] @ content @ [
   568   ] @ content @ [
   569     str "",
   569     str "",
   570     str ("end; (*struct " ^ name ^ "*)")
   570     str ("end; (*struct " ^ name ^ "*)")
   571   ]);
   571   ]);
   572 
   572 
   573 fun pr_ocaml tyco_syntax const_syntax labelled_name keyword_vars deresolv is_cons ml_def =
   573 fun pr_ocaml tyco_syntax const_syntax labelled_name init_syms deresolv is_cons ml_def =
   574   let
   574   let
   575     fun pr_dicts fxy ds =
   575     fun pr_dicts fxy ds =
   576       let
   576       let
   577         fun pr_dictvar (v, (_, 1)) = "_" ^ first_upper v
   577         fun pr_dictvar (v, (_, 1)) = "_" ^ first_upper v
   578           | pr_dictvar (v, (i, _)) = "_" ^ first_upper v ^ string_of_int (i+1);
   578           | pr_dictvar (v, (i, _)) = "_" ^ first_upper v ^ string_of_int (i+1);
   683               let
   683               let
   684                 val consts = map_filter
   684                 val consts = map_filter
   685                   (fn c => if (is_some o const_syntax) c
   685                   (fn c => if (is_some o const_syntax) c
   686                     then NONE else (SOME o NameSpace.base o deresolv) c)
   686                     then NONE else (SOME o NameSpace.base o deresolv) c)
   687                     ((fold o CodegenThingol.fold_constnames) (insert (op =)) (t :: ts) []);
   687                     ((fold o CodegenThingol.fold_constnames) (insert (op =)) (t :: ts) []);
   688                 val vars = keyword_vars
   688                 val vars = init_syms
   689                   |> CodegenNames.intro_vars consts
   689                   |> CodegenNames.intro_vars consts
   690                   |> CodegenNames.intro_vars ((fold o CodegenThingol.fold_unbound_varnames)
   690                   |> CodegenNames.intro_vars ((fold o CodegenThingol.fold_unbound_varnames)
   691                       (insert (op =)) ts []);
   691                       (insert (op =)) ts []);
   692               in concat [
   692               in concat [
   693                 (Pretty.block o Pretty.commas) (map (pr_term vars NOBR) ts),
   693                 (Pretty.block o Pretty.commas) (map (pr_term vars NOBR) ts),
   698                   let
   698                   let
   699                     val consts = map_filter
   699                     val consts = map_filter
   700                       (fn c => if (is_some o const_syntax) c
   700                       (fn c => if (is_some o const_syntax) c
   701                         then NONE else (SOME o NameSpace.base o deresolv) c)
   701                         then NONE else (SOME o NameSpace.base o deresolv) c)
   702                         ((fold o CodegenThingol.fold_constnames) (insert (op =)) (t :: ts) []);
   702                         ((fold o CodegenThingol.fold_constnames) (insert (op =)) (t :: ts) []);
   703                     val vars = keyword_vars
   703                     val vars = init_syms
   704                       |> CodegenNames.intro_vars consts
   704                       |> CodegenNames.intro_vars consts
   705                       |> CodegenNames.intro_vars ((fold o CodegenThingol.fold_unbound_varnames)
   705                       |> CodegenNames.intro_vars ((fold o CodegenThingol.fold_unbound_varnames)
   706                           (insert (op =)) ts []);
   706                           (insert (op =)) ts []);
   707                   in
   707                   in
   708                     concat (
   708                     concat (
   724                   let
   724                   let
   725                     val consts = map_filter
   725                     val consts = map_filter
   726                       (fn c => if (is_some o const_syntax) c
   726                       (fn c => if (is_some o const_syntax) c
   727                         then NONE else (SOME o NameSpace.base o deresolv) c)
   727                         then NONE else (SOME o NameSpace.base o deresolv) c)
   728                         ((fold o CodegenThingol.fold_constnames) (insert (op =)) (map snd eqs) []);
   728                         ((fold o CodegenThingol.fold_constnames) (insert (op =)) (map snd eqs) []);
   729                     val vars = keyword_vars
   729                     val vars = init_syms
   730                       |> CodegenNames.intro_vars consts;
   730                       |> CodegenNames.intro_vars consts;
   731                     val dummy_parms = (map str o fish_parms vars o map fst) eqs;
   731                     val dummy_parms = (map str o fish_parms vars o map fst) eqs;
   732                   in
   732                   in
   733                     Pretty.block (
   733                     Pretty.block (
   734                       Pretty.breaks dummy_parms
   734                       Pretty.breaks dummy_parms
   822               let
   822               let
   823                 val consts = map_filter
   823                 val consts = map_filter
   824                   (fn c => if (is_some o const_syntax) c
   824                   (fn c => if (is_some o const_syntax) c
   825                     then NONE else (SOME o NameSpace.base o deresolv) c)
   825                     then NONE else (SOME o NameSpace.base o deresolv) c)
   826                     (CodegenThingol.fold_constnames (insert (op =)) t []);
   826                     (CodegenThingol.fold_constnames (insert (op =)) t []);
   827                 val vars = CodegenNames.intro_vars consts keyword_vars;
   827                 val vars = CodegenNames.intro_vars consts init_syms;
   828               in
   828               in
   829                 concat [
   829                 concat [
   830                   (str o deresolv) classop,
   830                   (str o deresolv) classop,
   831                   str "=",
   831                   str "=",
   832                   pr_term vars NOBR t
   832                   pr_term vars NOBR t
   858   ]);
   858   ]);
   859 
   859 
   860 val code_width = ref 80;
   860 val code_width = ref 80;
   861 fun code_output p = Pretty.setmp_margin (!code_width) Pretty.output p ^ "\n";
   861 fun code_output p = Pretty.setmp_margin (!code_width) Pretty.output p ^ "\n";
   862 
   862 
   863 fun seri_ml pr_def pr_modl reserved_ml output labelled_name reserved_user module_alias module_prolog
   863 fun seri_ml pr_def pr_modl output labelled_name reserved_syms module_alias module_prolog
   864   (_ : string -> class_syntax option) tyco_syntax const_syntax code =
   864   (_ : string -> class_syntax option) tyco_syntax const_syntax code =
   865   let
   865   let
   866     val is_cons = fn node => case CodegenThingol.get_def code node
   866     val is_cons = fn node => case CodegenThingol.get_def code node
   867      of CodegenThingol.Datatypecons _ => true
   867      of CodegenThingol.Datatypecons _ => true
   868       | _ => false;
   868       | _ => false;
   869     datatype node =
   869     datatype node =
   870         Def of string * ml_def option
   870         Def of string * ml_def option
   871       | Module of string * ((Name.context * Name.context) * node Graph.T);
   871       | Module of string * ((Name.context * Name.context) * node Graph.T);
   872     val empty_names = reserved_ml |> fold Name.declare reserved_user;
   872     val init_names = Name.make_context reserved_syms;
   873     val empty_module = ((empty_names, empty_names), Graph.empty);
   873     val init_module = ((init_names, init_names), Graph.empty);
   874     fun map_node [] f = f
   874     fun map_node [] f = f
   875       | map_node (m::ms) f =
   875       | map_node (m::ms) f =
   876           Graph.default_node (m, Module (m, empty_module))
   876           Graph.default_node (m, Module (m, init_module))
   877           #> Graph.map_node m (fn (Module (dmodlname, (nsp, nodes))) => Module (dmodlname, (nsp, map_node ms f nodes)));
   877           #> Graph.map_node m (fn (Module (dmodlname, (nsp, nodes))) => Module (dmodlname, (nsp, map_node ms f nodes)));
   878     fun map_nsp_yield [] f (nsp, nodes) =
   878     fun map_nsp_yield [] f (nsp, nodes) =
   879           let
   879           let
   880             val (x, nsp') = f nsp
   880             val (x, nsp') = f nsp
   881           in (x, (nsp', nodes)) end
   881           in (x, (nsp', nodes)) end
   882       | map_nsp_yield (m::ms) f (nsp, nodes) =
   882       | map_nsp_yield (m::ms) f (nsp, nodes) =
   883           let
   883           let
   884             val (x, nodes') =
   884             val (x, nodes') =
   885               nodes
   885               nodes
   886               |> Graph.default_node (m, Module (m, empty_module))
   886               |> Graph.default_node (m, Module (m, init_module))
   887               |> Graph.map_node_yield m (fn Module (dmodlname, nsp_nodes) => 
   887               |> Graph.map_node_yield m (fn Module (dmodlname, nsp_nodes) => 
   888                   let
   888                   let
   889                     val (x, nsp_nodes') = map_nsp_yield ms f nsp_nodes
   889                     val (x, nsp_nodes') = map_nsp_yield ms f nsp_nodes
   890                   in (x, Module (dmodlname, nsp_nodes')) end)
   890                   in (x, Module (dmodlname, nsp_nodes')) end)
   891           in (x, (nsp, nodes')) end;
   891           in (x, (nsp, nodes')) end;
   892     val init_vars = CodegenNames.make_vars (ML_Syntax.reserved_names @ reserved_user);
   892     val init_syms = CodegenNames.make_vars reserved_syms;
   893     val name_modl = mk_modl_name_tab empty_names NONE module_alias code;
   893     val name_modl = mk_modl_name_tab init_names NONE module_alias code;
   894     fun name_def upper name nsp =
   894     fun name_def upper name nsp =
   895       let
   895       let
   896         val (_, base) = dest_name name;
   896         val (_, base) = dest_name name;
   897         val base' = if upper then first_upper base else base;
   897         val base' = if upper then first_upper base else base;
   898         val ([base''], nsp') = Name.variants [base'] nsp;
   898         val ([base''], nsp') = Name.variants [base'] nsp;
   992           add_group mk_class defs
   992           add_group mk_class defs
   993       | group_defs ((defs as [(_, CodegenThingol.Classinst _)])) =
   993       | group_defs ((defs as [(_, CodegenThingol.Classinst _)])) =
   994           add_group mk_inst defs
   994           add_group mk_inst defs
   995       | group_defs defs = error ("Illegal mutual dependencies: " ^ (commas o map (labelled_name o fst)) defs)
   995       | group_defs defs = error ("Illegal mutual dependencies: " ^ (commas o map (labelled_name o fst)) defs)
   996     val (_, nodes) =
   996     val (_, nodes) =
   997       empty_module
   997       init_module
   998       |> fold group_defs (map (AList.make (Graph.get_node code))
   998       |> fold group_defs (map (AList.make (Graph.get_node code))
   999           (rev (Graph.strong_conn code)))
   999           (rev (Graph.strong_conn code)))
  1000     fun deresolver prefix name = 
  1000     fun deresolver prefix name = 
  1001       let
  1001       let
  1002         val modl = (fst o dest_name) name;
  1002         val modl = (fst o dest_name) name;
  1015      of NONE => []
  1015      of NONE => []
  1016       | SOME p => [p, str ""];
  1016       | SOME p => [p, str ""];
  1017     fun pr_node prefix (Def (_, NONE)) =
  1017     fun pr_node prefix (Def (_, NONE)) =
  1018           NONE
  1018           NONE
  1019       | pr_node prefix (Def (_, SOME def)) =
  1019       | pr_node prefix (Def (_, SOME def)) =
  1020           SOME (pr_def tyco_syntax const_syntax labelled_name init_vars (deresolver prefix) is_cons def)
  1020           SOME (pr_def tyco_syntax const_syntax labelled_name init_syms (deresolver prefix) is_cons def)
  1021       | pr_node prefix (Module (dmodlname, (_, nodes))) =
  1021       | pr_node prefix (Module (dmodlname, (_, nodes))) =
  1022           SOME (pr_modl dmodlname (the_prolog (NameSpace.implode (prefix @ [dmodlname]))
  1022           SOME (pr_modl dmodlname (the_prolog (NameSpace.implode (prefix @ [dmodlname]))
  1023             @ separate (str "") ((map_filter (pr_node (prefix @ [dmodlname]) o Graph.get_node nodes)
  1023             @ separate (str "") ((map_filter (pr_node (prefix @ [dmodlname]) o Graph.get_node nodes)
  1024                 o rev o flat o Graph.strong_conn) nodes)));
  1024                 o rev o flat o Graph.strong_conn) nodes)));
  1025     val p = pr_modl "ROOT" (the_prolog "" @ separate (str "") ((map_filter
  1025     val p = pr_modl "ROOT" (the_prolog "" @ separate (str "") ((map_filter
  1032      of NONE => use_text "generated code" Output.ml_output false o code_output
  1032      of NONE => use_text "generated code" Output.ml_output false o code_output
  1033       | SOME "-" => writeln o code_output
  1033       | SOME "-" => writeln o code_output
  1034       | SOME file => File.write (Path.explode file) o code_output;
  1034       | SOME file => File.write (Path.explode file) o code_output;
  1035   in
  1035   in
  1036     parse_args (Scan.succeed ())
  1036     parse_args (Scan.succeed ())
  1037     #> (fn () => seri_ml pr_sml pr_sml_modl ML_Syntax.reserved output)
  1037     #> (fn () => seri_ml pr_sml pr_sml_modl output)
  1038   end;
  1038   end;
  1039 
       
  1040 val reserved_ocaml = Name.make_context ["and", "as", "assert", "begin", "class",
       
  1041   "constraint", "do", "done", "downto", "else", "end", "exception",
       
  1042   "external", "false", "for", "fun", "function", "functor", "if",
       
  1043   "in", "include", "inherit", "initializer", "lazy", "let", "match", "method",
       
  1044   "module", "mutable", "new", "object", "of", "open", "or", "private", "rec",
       
  1045   "sig", "struct", "then", "to", "true", "try", "type", "val",
       
  1046   "virtual", "when", "while", "with", "mod"];
       
  1047 
  1039 
  1048 fun isar_seri_ocaml file =
  1040 fun isar_seri_ocaml file =
  1049   let
  1041   let
  1050     val output = case file
  1042     val output = case file
  1051      of NONE => error "OCaml: no internal compilation"
  1043      of NONE => error "OCaml: no internal compilation"
  1053       | SOME file => File.write (Path.explode file) o code_output;
  1045       | SOME file => File.write (Path.explode file) o code_output;
  1054     fun output_file file = File.write (Path.explode file) o code_output;
  1046     fun output_file file = File.write (Path.explode file) o code_output;
  1055     val output_diag = writeln o code_output;
  1047     val output_diag = writeln o code_output;
  1056   in
  1048   in
  1057     parse_args (Scan.succeed ())
  1049     parse_args (Scan.succeed ())
  1058     #> (fn () => seri_ml pr_ocaml pr_ocaml_modl reserved_ocaml output)
  1050     #> (fn () => seri_ml pr_ocaml pr_ocaml_modl output)
  1059   end;
  1051   end;
  1060 
  1052 
  1061 
  1053 
  1062 (** Haskell serializer **)
  1054 (** Haskell serializer **)
  1063 
  1055 
  1070 
  1062 
  1071 val pr_bind_haskell = gen_pr_bind pr_bind';
  1063 val pr_bind_haskell = gen_pr_bind pr_bind';
  1072 
  1064 
  1073 in
  1065 in
  1074 
  1066 
  1075 fun pr_haskell class_syntax tyco_syntax const_syntax labelled_name keyword_vars deresolv_here deresolv deriving_show def =
  1067 fun pr_haskell class_syntax tyco_syntax const_syntax labelled_name init_syms deresolv_here deresolv deriving_show def =
  1076   let
  1068   let
  1077     fun class_name class = case class_syntax class
  1069     fun class_name class = case class_syntax class
  1078      of NONE => deresolv class
  1070      of NONE => deresolv class
  1079       | SOME (class, _) => class;
  1071       | SOME (class, _) => class;
  1080     fun classop_name class classop = case class_syntax class
  1072     fun classop_name class classop = case class_syntax class
  1159       (str o deresolv) c :: map (pr_term vars BR) ts
  1151       (str o deresolv) c :: map (pr_term vars BR) ts
  1160     and pr_app vars = gen_pr_app pr_app' pr_term const_syntax vars
  1152     and pr_app vars = gen_pr_app pr_app' pr_term const_syntax vars
  1161     and pr_bind fxy = pr_bind_haskell pr_term fxy;
  1153     and pr_bind fxy = pr_bind_haskell pr_term fxy;
  1162     fun pr_def (name, CodegenThingol.Fun (eqs, (vs, ty))) =
  1154     fun pr_def (name, CodegenThingol.Fun (eqs, (vs, ty))) =
  1163           let
  1155           let
  1164             val tyvars = CodegenNames.intro_vars (map fst vs) keyword_vars;
  1156             val tyvars = CodegenNames.intro_vars (map fst vs) init_syms;
  1165             fun pr_eq (ts, t) =
  1157             fun pr_eq (ts, t) =
  1166               let
  1158               let
  1167                 val consts = map_filter
  1159                 val consts = map_filter
  1168                   (fn c => if (is_some o const_syntax) c
  1160                   (fn c => if (is_some o const_syntax) c
  1169                     then NONE else (SOME o NameSpace.base o deresolv) c)
  1161                     then NONE else (SOME o NameSpace.base o deresolv) c)
  1170                     ((fold o CodegenThingol.fold_constnames) (insert (op =)) (t :: ts) []);
  1162                     ((fold o CodegenThingol.fold_constnames) (insert (op =)) (t :: ts) []);
  1171                 val vars = keyword_vars
  1163                 val vars = init_syms
  1172                   |> CodegenNames.intro_vars consts
  1164                   |> CodegenNames.intro_vars consts
  1173                   |> CodegenNames.intro_vars ((fold o CodegenThingol.fold_unbound_varnames)
  1165                   |> CodegenNames.intro_vars ((fold o CodegenThingol.fold_unbound_varnames)
  1174                        (insert (op =)) ts []);
  1166                        (insert (op =)) ts []);
  1175               in
  1167               in
  1176                 semicolon (
  1168                 semicolon (
  1191               :: map pr_eq eqs
  1183               :: map pr_eq eqs
  1192             )
  1184             )
  1193           end
  1185           end
  1194       | pr_def (name, CodegenThingol.Datatype (vs, [])) =
  1186       | pr_def (name, CodegenThingol.Datatype (vs, [])) =
  1195           let
  1187           let
  1196             val tyvars = CodegenNames.intro_vars (map fst vs) keyword_vars;
  1188             val tyvars = CodegenNames.intro_vars (map fst vs) init_syms;
  1197           in
  1189           in
  1198             semicolon [
  1190             semicolon [
  1199               str "data",
  1191               str "data",
  1200               pr_typscheme_expr tyvars (vs, (deresolv_here name, map (ITyVar o fst) vs))
  1192               pr_typscheme_expr tyvars (vs, (deresolv_here name, map (ITyVar o fst) vs))
  1201             ]
  1193             ]
  1202           end
  1194           end
  1203       | pr_def (name, CodegenThingol.Datatype (vs, [(co, [ty])])) =
  1195       | pr_def (name, CodegenThingol.Datatype (vs, [(co, [ty])])) =
  1204           let
  1196           let
  1205             val tyvars = CodegenNames.intro_vars (map fst vs) keyword_vars;
  1197             val tyvars = CodegenNames.intro_vars (map fst vs) init_syms;
  1206           in
  1198           in
  1207             semicolon (
  1199             semicolon (
  1208               str "newtype"
  1200               str "newtype"
  1209               :: pr_typscheme_expr tyvars (vs, (deresolv_here name, map (ITyVar o fst) vs))
  1201               :: pr_typscheme_expr tyvars (vs, (deresolv_here name, map (ITyVar o fst) vs))
  1210               :: str "="
  1202               :: str "="
  1213               :: (if deriving_show name then [str "deriving (Read, Show)"] else [])
  1205               :: (if deriving_show name then [str "deriving (Read, Show)"] else [])
  1214             )
  1206             )
  1215           end
  1207           end
  1216       | pr_def (name, CodegenThingol.Datatype (vs, co :: cos)) =
  1208       | pr_def (name, CodegenThingol.Datatype (vs, co :: cos)) =
  1217           let
  1209           let
  1218             val tyvars = CodegenNames.intro_vars (map fst vs) keyword_vars;
  1210             val tyvars = CodegenNames.intro_vars (map fst vs) init_syms;
  1219             fun pr_co (co, tys) =
  1211             fun pr_co (co, tys) =
  1220               concat (
  1212               concat (
  1221                 (str o deresolv_here) co
  1213                 (str o deresolv_here) co
  1222                 :: map (pr_typ tyvars BR) tys
  1214                 :: map (pr_typ tyvars BR) tys
  1223               )
  1215               )
  1231               @ (if deriving_show name then [str "deriving (Read, Show)"] else [])
  1223               @ (if deriving_show name then [str "deriving (Read, Show)"] else [])
  1232             )
  1224             )
  1233           end
  1225           end
  1234       | pr_def (name, CodegenThingol.Class (superclasss, (v, classops))) =
  1226       | pr_def (name, CodegenThingol.Class (superclasss, (v, classops))) =
  1235           let
  1227           let
  1236             val tyvars = CodegenNames.intro_vars [v] keyword_vars;
  1228             val tyvars = CodegenNames.intro_vars [v] init_syms;
  1237             fun pr_classop (classop, ty) =
  1229             fun pr_classop (classop, ty) =
  1238               semicolon [
  1230               semicolon [
  1239                 (str o classop_name name) classop,
  1231                 (str o classop_name name) classop,
  1240                 str "::",
  1232                 str "::",
  1241                 pr_typ tyvars NOBR ty
  1233                 pr_typ tyvars NOBR ty
  1251               str "};"
  1243               str "};"
  1252             ) (map pr_classop classops)
  1244             ) (map pr_classop classops)
  1253           end
  1245           end
  1254       | pr_def (_, CodegenThingol.Classinst ((class, (tyco, vs)), (_, classop_defs))) =
  1246       | pr_def (_, CodegenThingol.Classinst ((class, (tyco, vs)), (_, classop_defs))) =
  1255           let
  1247           let
  1256             val tyvars = CodegenNames.intro_vars (map fst vs) keyword_vars;
  1248             val tyvars = CodegenNames.intro_vars (map fst vs) init_syms;
  1257             fun pr_instdef (classop, t) =
  1249             fun pr_instdef (classop, t) =
  1258                 let
  1250                 let
  1259                   val consts = map_filter
  1251                   val consts = map_filter
  1260                     (fn c => if (is_some o const_syntax) c
  1252                     (fn c => if (is_some o const_syntax) c
  1261                       then NONE else (SOME o NameSpace.base o deresolv) c)
  1253                       then NONE else (SOME o NameSpace.base o deresolv) c)
  1262                       (CodegenThingol.fold_constnames (insert (op =)) t []);
  1254                       (CodegenThingol.fold_constnames (insert (op =)) t []);
  1263                   val vars = keyword_vars
  1255                   val vars = init_syms
  1264                     |> CodegenNames.intro_vars consts;
  1256                     |> CodegenNames.intro_vars consts;
  1265                 in
  1257                 in
  1266                   semicolon [
  1258                   semicolon [
  1267                     (str o classop_name class) classop,
  1259                     (str o classop_name class) classop,
  1268                     str "=",
  1260                     str "=",
  1302       in (brack o Pretty.block_enclose (str "do {", str "}")) (ps @| pr vars' NOBR t) end;
  1294       in (brack o Pretty.block_enclose (str "do {", str "}")) (ps @| pr vars' NOBR t) end;
  1303   in (1, pretty) end;
  1295   in (1, pretty) end;
  1304 
  1296 
  1305 end; (*local*)
  1297 end; (*local*)
  1306 
  1298 
  1307 val reserved_haskell = [
  1299 fun seri_haskell module_prefix destination string_classes labelled_name reserved_syms module_alias module_prolog
  1308   "hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr",
       
  1309   "import", "default", "forall", "let", "in", "class", "qualified", "data",
       
  1310   "newtype", "instance", "if", "then", "else", "type", "as", "do", "module"
       
  1311 ];
       
  1312 
       
  1313 fun seri_haskell module_prefix destination string_classes labelled_name reserved_user module_alias module_prolog
       
  1314   class_syntax tyco_syntax const_syntax code =
  1300   class_syntax tyco_syntax const_syntax code =
  1315   let
  1301   let
  1316     val _ = Option.map File.check destination;
  1302     val _ = Option.map File.check destination;
  1317     val empty_names = Name.make_context (reserved_haskell @ reserved_user);
  1303     val init_names = Name.make_context reserved_syms;
  1318     val name_modl = mk_modl_name_tab empty_names module_prefix module_alias code;
  1304     val name_modl = mk_modl_name_tab init_names module_prefix module_alias code;
  1319     fun add_def (name, (def, deps)) =
  1305     fun add_def (name, (def, deps)) =
  1320       let
  1306       let
  1321         val (modl, base) = dest_name name;
  1307         val (modl, base) = dest_name name;
  1322         fun name_def base = Name.variants [base] #>> the_single;
  1308         fun name_def base = Name.variants [base] #>> the_single;
  1323         fun add_fun upper (nsp_fun, nsp_typ) =
  1309         fun add_fun upper (nsp_fun, nsp_typ) =
  1347             | CodegenThingol.Classrel _ => I
  1333             | CodegenThingol.Classrel _ => I
  1348             | CodegenThingol.Classop _ =>
  1334             | CodegenThingol.Classop _ =>
  1349                 cons (name, ((NameSpace.append modlname' base', base'), NONE))
  1335                 cons (name, ((NameSpace.append modlname' base', base'), NONE))
  1350             | _ => cons (name, ((NameSpace.append modlname' base', base'), SOME def));
  1336             | _ => cons (name, ((NameSpace.append modlname' base', base'), SOME def));
  1351       in
  1337       in
  1352         Symtab.map_default (modlname', ([], ([], (empty_names, empty_names))))
  1338         Symtab.map_default (modlname', ([], ([], (init_names, init_names))))
  1353               (apfst (fold (insert (op = : string * string -> bool)) deps))
  1339               (apfst (fold (insert (op = : string * string -> bool)) deps))
  1354         #> `(fn code => add_name ((snd o snd o the o Symtab.lookup code) modlname'))
  1340         #> `(fn code => add_name ((snd o snd o the o Symtab.lookup code) modlname'))
  1355         #-> (fn (base', names) =>
  1341         #-> (fn (base', names) =>
  1356               (Symtab.map_entry modlname' o apsnd) (fn (defs, _) =>
  1342               (Symtab.map_entry modlname' o apsnd) (fn (defs, _) =>
  1357               (add_def base' defs, names)))
  1343               (add_def base' defs, names)))
  1358       end;
  1344       end;
  1359     val code' =
  1345     val code' =
  1360       fold add_def (AList.make (fn name => (Graph.get_node code name, Graph.imm_succs code name))
  1346       fold add_def (AList.make (fn name => (Graph.get_node code name, Graph.imm_succs code name))
  1361         (Graph.strong_conn code |> flat)) Symtab.empty;
  1347         (Graph.strong_conn code |> flat)) Symtab.empty;
  1362     val init_vars = CodegenNames.make_vars (reserved_haskell @ reserved_user);
  1348     val init_syms = CodegenNames.make_vars reserved_syms;
  1363     fun deresolv name =
  1349     fun deresolv name =
  1364       (fst o fst o the o AList.lookup (op =) ((fst o snd o the
  1350       (fst o fst o the o AList.lookup (op =) ((fst o snd o the
  1365         o Symtab.lookup code') ((name_modl o fst o dest_name) name))) name
  1351         o Symtab.lookup code') ((name_modl o fst o dest_name) name))) name
  1366         handle Option => error ("Unknown definition name: " ^ labelled_name name);
  1352         handle Option => error ("Unknown definition name: " ^ labelled_name name);
  1367     fun deresolv_here name =
  1353     fun deresolv_here name =
  1378                     (maps snd cs)
  1364                     (maps snd cs)
  1379         and deriv' tycos (tyco `%% tys) = deriv tycos tyco
  1365         and deriv' tycos (tyco `%% tys) = deriv tycos tyco
  1380               andalso forall (deriv' tycos) tys
  1366               andalso forall (deriv' tycos) tys
  1381           | deriv' _ (ITyVar _) = true
  1367           | deriv' _ (ITyVar _) = true
  1382       in deriv [] tyco end;
  1368       in deriv [] tyco end;
  1383     fun seri_def qualified = pr_haskell class_syntax tyco_syntax const_syntax labelled_name init_vars
  1369     fun seri_def qualified = pr_haskell class_syntax tyco_syntax const_syntax labelled_name init_syms
  1384       deresolv_here (if qualified then deresolv else deresolv_here)
  1370       deresolv_here (if qualified then deresolv else deresolv_here)
  1385       (if string_classes then deriving_show else K false);
  1371       (if string_classes then deriving_show else K false);
  1386     fun write_module (SOME destination) modlname =
  1372     fun write_module (SOME destination) modlname =
  1387           let
  1373           let
  1388             val filename = case modlname
  1374             val filename = case modlname
  1443 
  1429 
  1444 (** diagnosis serializer **)
  1430 (** diagnosis serializer **)
  1445 
  1431 
  1446 fun seri_diagnosis labelled_name _ _ _ _ _ code =
  1432 fun seri_diagnosis labelled_name _ _ _ _ _ code =
  1447   let
  1433   let
  1448     val init_vars = CodegenNames.make_vars reserved_haskell;
  1434     val init_names = CodegenNames.make_vars [];
  1449     fun pr_fun "fun" = SOME (2, fn pr_typ => fn fxy => fn [ty1, ty2] =>
  1435     fun pr_fun "fun" = SOME (2, fn pr_typ => fn fxy => fn [ty1, ty2] =>
  1450           brackify_infix (1, R) fxy [
  1436           brackify_infix (1, R) fxy [
  1451             pr_typ (INFX (1, X)) ty1,
  1437             pr_typ (INFX (1, X)) ty1,
  1452             str "->",
  1438             str "->",
  1453             pr_typ (INFX (1, R)) ty2
  1439             pr_typ (INFX (1, R)) ty2
  1454           ])
  1440           ])
  1455       | pr_fun _ = NONE
  1441       | pr_fun _ = NONE
  1456     val pr = pr_haskell (K NONE) pr_fun (K NONE) labelled_name init_vars I I (K false);
  1442     val pr = pr_haskell (K NONE) pr_fun (K NONE) labelled_name init_names I I (K false);
  1457   in
  1443   in
  1458     []
  1444     []
  1459     |> Graph.fold (fn (name, (def, _)) => case try pr (name, def) of SOME p => cons p | NONE => I) code
  1445     |> Graph.fold (fn (name, (def, _)) => case try pr (name, def) of SOME p => cons p | NONE => I) code
  1460     |> Pretty.chunks2
  1446     |> Pretty.chunks2
  1461     |> code_output
  1447     |> code_output
  1614   let
  1600   let
  1615     val val_name = "eval.EVAL.EVAL";
  1601     val val_name = "eval.EVAL.EVAL";
  1616     val val_name' = "ROOT.eval.EVAL";
  1602     val val_name' = "ROOT.eval.EVAL";
  1617     val val_name'_args = space_implode " " (val_name' :: map (enclose "(" ")") args);
  1603     val val_name'_args = space_implode " " (val_name' :: map (enclose "(" ")") args);
  1618     val data = (the o Symtab.lookup (CodegenSerializerData.get thy)) "SML"
  1604     val data = (the o Symtab.lookup (CodegenSerializerData.get thy)) "SML"
  1619     val reserved = the_reserved data;
  1605     val reserved_syms = the_reserved data;
  1620     val { alias, prolog } = the_syntax_modl data;
  1606     val { alias, prolog } = the_syntax_modl data;
  1621     val { class, inst, tyco, const } = the_syntax_expr data;
  1607     val { class, inst, tyco, const } = the_syntax_expr data;
  1622     fun eval p = (
  1608     fun eval p = (
  1623       reff := NONE;
  1609       reff := NONE;
  1624       if !eval_verbose then Pretty.writeln p else ();
  1610       if !eval_verbose then Pretty.writeln p else ();
  1635     code
  1621     code
  1636     |> CodegenThingol.add_eval_def (val_name, t)
  1622     |> CodegenThingol.add_eval_def (val_name, t)
  1637     |> CodegenThingol.project_code
  1623     |> CodegenThingol.project_code
  1638         (Symtab.keys class @ Symtab.keys inst @ Symtab.keys tyco @ Symtab.keys const)
  1624         (Symtab.keys class @ Symtab.keys inst @ Symtab.keys tyco @ Symtab.keys const)
  1639           (SOME [val_name])
  1625           (SOME [val_name])
  1640     |> seri_ml pr_sml pr_sml_modl ML_Syntax.reserved I (labelled_name thy) reserved
  1626     |> seri_ml pr_sml pr_sml_modl I (labelled_name thy) reserved_syms
  1641         (Symtab.lookup alias) (Symtab.lookup prolog)
  1627         (Symtab.lookup alias) (Symtab.lookup prolog)
  1642         (Symtab.lookup class) (Symtab.lookup tyco) (Symtab.lookup const)
  1628         (Symtab.lookup class) (Symtab.lookup tyco) (Symtab.lookup const)
  1643     |> eval
  1629     |> eval
  1644   end;
  1630   end;
  1645 
  1631 
  1911     |> gen_add_syntax_const (K I) target_Haskell c_kbind'
  1897     |> gen_add_syntax_const (K I) target_Haskell c_kbind'
  1912           (no_bindings (SOME (parse_infix fst (L, 1) ">>")))
  1898           (no_bindings (SOME (parse_infix fst (L, 1) ">>")))
  1913   end;
  1899   end;
  1914 
  1900 
  1915 fun add_reserved target =
  1901 fun add_reserved target =
  1916   map_reserveds target o insert (op =);
  1902   let
       
  1903     fun add sym syms = if member (op =) syms sym
       
  1904       then error ("Reserved symbol " ^ quote sym ^ " already declared")
       
  1905       else insert (op =) sym syms
       
  1906   in map_reserveds target o add end;
  1917 
  1907 
  1918 fun add_modl_alias target =
  1908 fun add_modl_alias target =
  1919   map_syntax_modls target o apfst o Symtab.update o apsnd CodegenNames.check_modulename;
  1909   map_syntax_modls target o apfst o Symtab.update o apsnd CodegenNames.check_modulename;
  1920 
  1910 
  1921 fun add_modl_prolog target =
  1911 fun add_modl_prolog target =
  2108 
  2098 
  2109 val _ = OuterSyntax.add_keywords [infixK, infixlK, infixrK];
  2099 val _ = OuterSyntax.add_keywords [infixK, infixlK, infixrK];
  2110 
  2100 
  2111 val _ = OuterSyntax.add_parsers [code_classP, code_instanceP, code_typeP, code_constP,
  2101 val _ = OuterSyntax.add_parsers [code_classP, code_instanceP, code_typeP, code_constP,
  2112   code_reservedP, code_modulenameP, code_moduleprologP, code_monadP];
  2102   code_reservedP, code_modulenameP, code_moduleprologP, code_monadP];
       
  2103 
  2113 
  2104 
  2114 (*including serializer defaults*)
  2105 (*including serializer defaults*)
  2115 val _ = Context.add_setup (
  2106 val _ = Context.add_setup (
  2116   add_syntax_tyco "SML" "fun" (SOME (2, fn pr_typ => fn fxy => fn [ty1, ty2] =>
  2107   add_syntax_tyco "SML" "fun" (SOME (2, fn pr_typ => fn fxy => fn [ty1, ty2] =>
  2117       (gen_brackify (case fxy of NOBR => false | _ => eval_fxy (INFX (1, R)) fxy) o Pretty.breaks) [
  2108       (gen_brackify (case fxy of NOBR => false | _ => eval_fxy (INFX (1, R)) fxy) o Pretty.breaks) [
  2129       brackify_infix (1, R) fxy [
  2120       brackify_infix (1, R) fxy [
  2130         pr_typ (INFX (1, X)) ty1,
  2121         pr_typ (INFX (1, X)) ty1,
  2131         str "->",
  2122         str "->",
  2132         pr_typ (INFX (1, R)) ty2
  2123         pr_typ (INFX (1, R)) ty2
  2133       ]))
  2124       ]))
  2134   (*IntInt resp. Big_int are added later when code extraction for numerals is set up*)
  2125   #> fold (add_reserved "SML") ML_Syntax.reserved_names
  2135   #> fold (add_reserved "SML") ["o" (*dictionary projections use it already*),
  2126   #> fold (add_reserved "SML")
  2136       "div", "mod" (*infixes*)]
  2127       ["o" (*dictionary projections use it already*), "div", "mod" (*standard infixes*)]
       
  2128   #> fold (add_reserved "OCaml") [
       
  2129       "and", "as", "assert", "begin", "class",
       
  2130       "constraint", "do", "done", "downto", "else", "end", "exception",
       
  2131       "external", "false", "for", "fun", "function", "functor", "if",
       
  2132       "in", "include", "inherit", "initializer", "lazy", "let", "match", "method",
       
  2133       "module", "mutable", "new", "object", "of", "open", "or", "private", "rec",
       
  2134       "sig", "struct", "then", "to", "true", "try", "type", "val",
       
  2135       "virtual", "when", "while", "with", "mod"
       
  2136     ]
       
  2137   #> fold (add_reserved "Haskell") [
       
  2138       "hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr",
       
  2139       "import", "default", "forall", "let", "in", "class", "qualified", "data",
       
  2140       "newtype", "instance", "if", "then", "else", "type", "as", "do", "module"
       
  2141     ]
  2137   #> fold (add_reserved "Haskell") [
  2142   #> fold (add_reserved "Haskell") [
  2138       "Prelude", "Main", "Bool", "Maybe", "Either", "Ordering", "Char", "String", "Int",
  2143       "Prelude", "Main", "Bool", "Maybe", "Either", "Ordering", "Char", "String", "Int",
  2139       "Integer", "Float", "Double", "Rational", "IO", "Eq", "Ord", "Enum", "Bounded",
  2144       "Integer", "Float", "Double", "Rational", "IO", "Eq", "Ord", "Enum", "Bounded",
  2140       "Num", "Real", "Integral", "Fractional", "Floating", "RealFloat", "Monad", "Functor",
  2145       "Num", "Real", "Integral", "Fractional", "Floating", "RealFloat", "Monad", "Functor",
  2141       "AlreadyExists", "ArithException", "ArrayException", "AssertionFailed", "AsyncException",
  2146       "AlreadyExists", "ArithException", "ArrayException", "AssertionFailed", "AsyncException",
  2142       "BlockedOnDeadMVar", "Deadlock", "Denormal", "DivideByZero", "DotNetException", "DynException",
  2147       "BlockedOnDeadMVar", "Deadlock", "Denormal", "DivideByZero", "DotNetException", "DynException",
  2143       "Dynamic", "EOF", "EQ", "EmptyRec", "ErrorCall", "ExitException", "ExitFailure",
  2148       "Dynamic", "EOF", "EQ", "EmptyRec", "ErrorCall", "ExitException", "ExitFailure",
  2144       "ExitSuccess", "False", "GT", "HeapOverflow",
  2149       "ExitSuccess", "False", "GT", "HeapOverflow",
  2145       "IO", "IOError", "IOException", "IllegalOperation",
  2150       "IOError", "IOException", "IllegalOperation",
  2146       "IndexOutOfBounds", "Just", "Key", "LT", "Left", "LossOfPrecision", "NoMethodError",
  2151       "IndexOutOfBounds", "Just", "Key", "LT", "Left", "LossOfPrecision", "NoMethodError",
  2147       "NoSuchThing", "NonTermination", "Nothing", "Obj", "OtherError", "Overflow",
  2152       "NoSuchThing", "NonTermination", "Nothing", "Obj", "OtherError", "Overflow",
  2148       "PatternMatchFail", "PermissionDenied", "ProtocolError", "RecConError", "RecSelError",
  2153       "PatternMatchFail", "PermissionDenied", "ProtocolError", "RecConError", "RecSelError",
  2149       "RecUpdError", "ResourceBusy", "ResourceExhausted", "Right", "StackOverflow",
  2154       "RecUpdError", "ResourceBusy", "ResourceExhausted", "Right", "StackOverflow",
  2150       "ThreadKilled", "True", "TyCon", "TypeRep", "UndefinedElement", "Underflow",
  2155       "ThreadKilled", "True", "TyCon", "TypeRep", "UndefinedElement", "Underflow",