src/Tools/code/code_haskell.ML
changeset 30648 17365ef082f3
parent 30364 577edc39b501
child 31049 396d4d6a1594
equal deleted inserted replaced
30647:ef8f46c3158a 30648:17365ef082f3
    40       | SOME class => class;
    40       | SOME class => class;
    41     fun pr_typcontext tyvars vs = case maps (fn (v, sort) => map (pair v) sort) vs
    41     fun pr_typcontext tyvars vs = case maps (fn (v, sort) => map (pair v) sort) vs
    42      of [] => []
    42      of [] => []
    43       | classbinds => Pretty.enum "," "(" ")" (
    43       | classbinds => Pretty.enum "," "(" ")" (
    44           map (fn (v, class) =>
    44           map (fn (v, class) =>
    45             str (class_name class ^ " " ^ Code_Name.lookup_var tyvars v)) classbinds)
    45             str (class_name class ^ " " ^ Code_Printer.lookup_var tyvars v)) classbinds)
    46           @@ str " => ";
    46           @@ str " => ";
    47     fun pr_typforall tyvars vs = case map fst vs
    47     fun pr_typforall tyvars vs = case map fst vs
    48      of [] => []
    48      of [] => []
    49       | vnames => str "forall " :: Pretty.breaks
    49       | vnames => str "forall " :: Pretty.breaks
    50           (map (str o Code_Name.lookup_var tyvars) vnames) @ str "." @@ Pretty.brk 1;
    50           (map (str o Code_Printer.lookup_var tyvars) vnames) @ str "." @@ Pretty.brk 1;
    51     fun pr_tycoexpr tyvars fxy (tyco, tys) =
    51     fun pr_tycoexpr tyvars fxy (tyco, tys) =
    52       brackify fxy (str tyco :: map (pr_typ tyvars BR) tys)
    52       brackify fxy (str tyco :: map (pr_typ tyvars BR) tys)
    53     and pr_typ tyvars fxy (tycoexpr as tyco `%% tys) = (case syntax_tyco tyco
    53     and pr_typ tyvars fxy (tycoexpr as tyco `%% tys) = (case syntax_tyco tyco
    54          of NONE => pr_tycoexpr tyvars fxy (deresolve tyco, tys)
    54          of NONE => pr_tycoexpr tyvars fxy (deresolve tyco, tys)
    55           | SOME (i, pr) => pr (pr_typ tyvars) fxy tys)
    55           | SOME (i, pr) => pr (pr_typ tyvars) fxy tys)
    56       | pr_typ tyvars fxy (ITyVar v) = (str o Code_Name.lookup_var tyvars) v;
    56       | pr_typ tyvars fxy (ITyVar v) = (str o Code_Printer.lookup_var tyvars) v;
    57     fun pr_typdecl tyvars (vs, tycoexpr) =
    57     fun pr_typdecl tyvars (vs, tycoexpr) =
    58       Pretty.block (pr_typcontext tyvars vs @| pr_tycoexpr tyvars NOBR tycoexpr);
    58       Pretty.block (pr_typcontext tyvars vs @| pr_tycoexpr tyvars NOBR tycoexpr);
    59     fun pr_typscheme tyvars (vs, ty) =
    59     fun pr_typscheme tyvars (vs, ty) =
    60       Pretty.block (pr_typforall tyvars vs @ pr_typcontext tyvars vs @| pr_typ tyvars NOBR ty);
    60       Pretty.block (pr_typforall tyvars vs @ pr_typcontext tyvars vs @| pr_typ tyvars NOBR ty);
    61     fun pr_term tyvars thm vars fxy (IConst c) =
    61     fun pr_term tyvars thm vars fxy (IConst c) =
    67                 brackify fxy [
    67                 brackify fxy [
    68                   pr_term tyvars thm vars NOBR t1,
    68                   pr_term tyvars thm vars NOBR t1,
    69                   pr_term tyvars thm vars BR t2
    69                   pr_term tyvars thm vars BR t2
    70                 ])
    70                 ])
    71       | pr_term tyvars thm vars fxy (IVar v) =
    71       | pr_term tyvars thm vars fxy (IVar v) =
    72           (str o Code_Name.lookup_var vars) v
    72           (str o Code_Printer.lookup_var vars) v
    73       | pr_term tyvars thm vars fxy (t as _ `|-> _) =
    73       | pr_term tyvars thm vars fxy (t as _ `|-> _) =
    74           let
    74           let
    75             val (binds, t') = Code_Thingol.unfold_abs t;
    75             val (binds, t') = Code_Thingol.unfold_abs t;
    76             fun pr ((v, pat), ty) = pr_bind tyvars thm BR ((SOME v, pat), ty);
    76             fun pr ((v, pat), ty) = pr_bind tyvars thm BR ((SOME v, pat), ty);
    77             val (ps, vars') = fold_map pr binds vars;
    77             val (ps, vars') = fold_map pr binds vars;
   125             ) (map pr clauses)
   125             ) (map pr clauses)
   126           end
   126           end
   127       | pr_case tyvars thm vars fxy ((_, []), _) = str "error \"empty case\"";
   127       | pr_case tyvars thm vars fxy ((_, []), _) = str "error \"empty case\"";
   128     fun pr_stmt (name, Code_Thingol.Fun (_, ((vs, ty), []))) =
   128     fun pr_stmt (name, Code_Thingol.Fun (_, ((vs, ty), []))) =
   129           let
   129           let
   130             val tyvars = Code_Name.intro_vars (map fst vs) init_syms;
   130             val tyvars = Code_Printer.intro_vars (map fst vs) init_syms;
   131             val n = (length o fst o Code_Thingol.unfold_fun) ty;
   131             val n = (length o fst o Code_Thingol.unfold_fun) ty;
   132           in
   132           in
   133             Pretty.chunks [
   133             Pretty.chunks [
   134               Pretty.block [
   134               Pretty.block [
   135                 (str o suffix " ::" o deresolve_base) name,
   135                 (str o suffix " ::" o deresolve_base) name,
   148             ]
   148             ]
   149           end
   149           end
   150       | pr_stmt (name, Code_Thingol.Fun (_, ((vs, ty), raw_eqs))) =
   150       | pr_stmt (name, Code_Thingol.Fun (_, ((vs, ty), raw_eqs))) =
   151           let
   151           let
   152             val eqs = filter (snd o snd) raw_eqs;
   152             val eqs = filter (snd o snd) raw_eqs;
   153             val tyvars = Code_Name.intro_vars (map fst vs) init_syms;
   153             val tyvars = Code_Printer.intro_vars (map fst vs) init_syms;
   154             fun pr_eq ((ts, t), (thm, _)) =
   154             fun pr_eq ((ts, t), (thm, _)) =
   155               let
   155               let
   156                 val consts = map_filter
   156                 val consts = map_filter
   157                   (fn c => if (is_some o syntax_const) c
   157                   (fn c => if (is_some o syntax_const) c
   158                     then NONE else (SOME o Long_Name.base_name o deresolve) c)
   158                     then NONE else (SOME o Long_Name.base_name o deresolve) c)
   159                     ((fold o Code_Thingol.fold_constnames) (insert (op =)) (t :: ts) []);
   159                     ((fold o Code_Thingol.fold_constnames) (insert (op =)) (t :: ts) []);
   160                 val vars = init_syms
   160                 val vars = init_syms
   161                   |> Code_Name.intro_vars consts
   161                   |> Code_Printer.intro_vars consts
   162                   |> Code_Name.intro_vars ((fold o Code_Thingol.fold_unbound_varnames)
   162                   |> Code_Printer.intro_vars ((fold o Code_Thingol.fold_unbound_varnames)
   163                        (insert (op =)) ts []);
   163                        (insert (op =)) ts []);
   164               in
   164               in
   165                 semicolon (
   165                 semicolon (
   166                   (str o deresolve_base) name
   166                   (str o deresolve_base) name
   167                   :: map (pr_term tyvars thm vars BR) ts
   167                   :: map (pr_term tyvars thm vars BR) ts
   180               :: map pr_eq eqs
   180               :: map pr_eq eqs
   181             )
   181             )
   182           end
   182           end
   183       | pr_stmt (name, Code_Thingol.Datatype (_, (vs, []))) =
   183       | pr_stmt (name, Code_Thingol.Datatype (_, (vs, []))) =
   184           let
   184           let
   185             val tyvars = Code_Name.intro_vars (map fst vs) init_syms;
   185             val tyvars = Code_Printer.intro_vars (map fst vs) init_syms;
   186           in
   186           in
   187             semicolon [
   187             semicolon [
   188               str "data",
   188               str "data",
   189               pr_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs))
   189               pr_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs))
   190             ]
   190             ]
   191           end
   191           end
   192       | pr_stmt (name, Code_Thingol.Datatype (_, (vs, [(co, [ty])]))) =
   192       | pr_stmt (name, Code_Thingol.Datatype (_, (vs, [(co, [ty])]))) =
   193           let
   193           let
   194             val tyvars = Code_Name.intro_vars (map fst vs) init_syms;
   194             val tyvars = Code_Printer.intro_vars (map fst vs) init_syms;
   195           in
   195           in
   196             semicolon (
   196             semicolon (
   197               str "newtype"
   197               str "newtype"
   198               :: pr_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs))
   198               :: pr_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs))
   199               :: str "="
   199               :: str "="
   202               :: (if deriving_show name then [str "deriving (Read, Show)"] else [])
   202               :: (if deriving_show name then [str "deriving (Read, Show)"] else [])
   203             )
   203             )
   204           end
   204           end
   205       | pr_stmt (name, Code_Thingol.Datatype (_, (vs, co :: cos))) =
   205       | pr_stmt (name, Code_Thingol.Datatype (_, (vs, co :: cos))) =
   206           let
   206           let
   207             val tyvars = Code_Name.intro_vars (map fst vs) init_syms;
   207             val tyvars = Code_Printer.intro_vars (map fst vs) init_syms;
   208             fun pr_co (co, tys) =
   208             fun pr_co (co, tys) =
   209               concat (
   209               concat (
   210                 (str o deresolve_base) co
   210                 (str o deresolve_base) co
   211                 :: map (pr_typ tyvars BR) tys
   211                 :: map (pr_typ tyvars BR) tys
   212               )
   212               )
   220               @ (if deriving_show name then [str "deriving (Read, Show)"] else [])
   220               @ (if deriving_show name then [str "deriving (Read, Show)"] else [])
   221             )
   221             )
   222           end
   222           end
   223       | pr_stmt (name, Code_Thingol.Class (_, (v, (superclasses, classparams)))) =
   223       | pr_stmt (name, Code_Thingol.Class (_, (v, (superclasses, classparams)))) =
   224           let
   224           let
   225             val tyvars = Code_Name.intro_vars [v] init_syms;
   225             val tyvars = Code_Printer.intro_vars [v] init_syms;
   226             fun pr_classparam (classparam, ty) =
   226             fun pr_classparam (classparam, ty) =
   227               semicolon [
   227               semicolon [
   228                 (str o deresolve_base) classparam,
   228                 (str o deresolve_base) classparam,
   229                 str "::",
   229                 str "::",
   230                 pr_typ tyvars NOBR ty
   230                 pr_typ tyvars NOBR ty
   232           in
   232           in
   233             Pretty.block_enclose (
   233             Pretty.block_enclose (
   234               Pretty.block [
   234               Pretty.block [
   235                 str "class ",
   235                 str "class ",
   236                 Pretty.block (pr_typcontext tyvars [(v, map fst superclasses)]),
   236                 Pretty.block (pr_typcontext tyvars [(v, map fst superclasses)]),
   237                 str (deresolve_base name ^ " " ^ Code_Name.lookup_var tyvars v),
   237                 str (deresolve_base name ^ " " ^ Code_Printer.lookup_var tyvars v),
   238                 str " where {"
   238                 str " where {"
   239               ],
   239               ],
   240               str "};"
   240               str "};"
   241             ) (map pr_classparam classparams)
   241             ) (map pr_classparam classparams)
   242           end
   242           end
   243       | pr_stmt (_, Code_Thingol.Classinst ((class, (tyco, vs)), (_, classparam_insts))) =
   243       | pr_stmt (_, Code_Thingol.Classinst ((class, (tyco, vs)), (_, classparam_insts))) =
   244           let
   244           let
   245             val split_abs_pure = (fn (v, _) `|-> t => SOME (v, t) | _ => NONE);
   245             val split_abs_pure = (fn (v, _) `|-> t => SOME (v, t) | _ => NONE);
   246             val unfold_abs_pure = Code_Thingol.unfoldr split_abs_pure;
   246             val unfold_abs_pure = Code_Thingol.unfoldr split_abs_pure;
   247             val tyvars = Code_Name.intro_vars (map fst vs) init_syms;
   247             val tyvars = Code_Printer.intro_vars (map fst vs) init_syms;
   248             fun pr_instdef ((classparam, c_inst), (thm, _)) = case syntax_const classparam
   248             fun pr_instdef ((classparam, c_inst), (thm, _)) = case syntax_const classparam
   249              of NONE => semicolon [
   249              of NONE => semicolon [
   250                     (str o deresolve_base) classparam,
   250                     (str o deresolve_base) classparam,
   251                     str "=",
   251                     str "=",
   252                     pr_app tyvars thm init_syms NOBR (c_inst, [])
   252                     pr_app tyvars thm init_syms NOBR (c_inst, [])
   257                     val const = if (is_some o syntax_const) c_inst_name
   257                     val const = if (is_some o syntax_const) c_inst_name
   258                       then NONE else (SOME o Long_Name.base_name o deresolve) c_inst_name;
   258                       then NONE else (SOME o Long_Name.base_name o deresolve) c_inst_name;
   259                     val proto_rhs = Code_Thingol.eta_expand k (c_inst, []);
   259                     val proto_rhs = Code_Thingol.eta_expand k (c_inst, []);
   260                     val (vs, rhs) = unfold_abs_pure proto_rhs;
   260                     val (vs, rhs) = unfold_abs_pure proto_rhs;
   261                     val vars = init_syms
   261                     val vars = init_syms
   262                       |> Code_Name.intro_vars (the_list const)
   262                       |> Code_Printer.intro_vars (the_list const)
   263                       |> Code_Name.intro_vars vs;
   263                       |> Code_Printer.intro_vars vs;
   264                     val lhs = IConst (classparam, ([], tys)) `$$ map IVar vs;
   264                     val lhs = IConst (classparam, ([], tys)) `$$ map IVar vs;
   265                       (*dictionaries are not relevant at this late stage*)
   265                       (*dictionaries are not relevant at this late stage*)
   266                   in
   266                   in
   267                     semicolon [
   267                     semicolon [
   268                       pr_term tyvars thm vars NOBR lhs,
   268                       pr_term tyvars thm vars NOBR lhs,
   286 
   286 
   287 fun haskell_program_of_program labelled_name module_name module_prefix reserved_names raw_module_alias program =
   287 fun haskell_program_of_program labelled_name module_name module_prefix reserved_names raw_module_alias program =
   288   let
   288   let
   289     val module_alias = if is_some module_name then K module_name else raw_module_alias;
   289     val module_alias = if is_some module_name then K module_name else raw_module_alias;
   290     val reserved_names = Name.make_context reserved_names;
   290     val reserved_names = Name.make_context reserved_names;
   291     val mk_name_module = Code_Name.mk_name_module reserved_names module_prefix module_alias program;
   291     val mk_name_module = Code_Printer.mk_name_module reserved_names module_prefix module_alias program;
   292     fun add_stmt (name, (stmt, deps)) =
   292     fun add_stmt (name, (stmt, deps)) =
   293       let
   293       let
   294         val (module_name, base) = Code_Name.dest_name name;
   294         val (module_name, base) = Code_Printer.dest_name name;
   295         val module_name' = mk_name_module module_name;
   295         val module_name' = mk_name_module module_name;
   296         val mk_name_stmt = yield_singleton Name.variants;
   296         val mk_name_stmt = yield_singleton Name.variants;
   297         fun add_fun upper (nsp_fun, nsp_typ) =
   297         fun add_fun upper (nsp_fun, nsp_typ) =
   298           let
   298           let
   299             val (base', nsp_fun') =
   299             val (base', nsp_fun') =
   300               mk_name_stmt (if upper then Code_Name.first_upper base else base) nsp_fun
   300               mk_name_stmt (if upper then Code_Printer.first_upper base else base) nsp_fun
   301           in (base', (nsp_fun', nsp_typ)) end;
   301           in (base', (nsp_fun', nsp_typ)) end;
   302         fun add_typ (nsp_fun, nsp_typ) =
   302         fun add_typ (nsp_fun, nsp_typ) =
   303           let
   303           let
   304             val (base', nsp_typ') = mk_name_stmt (Code_Name.first_upper base) nsp_typ
   304             val (base', nsp_typ') = mk_name_stmt (Code_Printer.first_upper base) nsp_typ
   305           in (base', (nsp_fun, nsp_typ')) end;
   305           in (base', (nsp_fun, nsp_typ')) end;
   306         val add_name = case stmt
   306         val add_name = case stmt
   307          of Code_Thingol.Fun _ => add_fun false
   307          of Code_Thingol.Fun _ => add_fun false
   308           | Code_Thingol.Datatype _ => add_typ
   308           | Code_Thingol.Datatype _ => add_typ
   309           | Code_Thingol.Datatypecons _ => add_fun true
   309           | Code_Thingol.Datatypecons _ => add_fun true
   328       end;
   328       end;
   329     val hs_program = fold add_stmt (AList.make (fn name =>
   329     val hs_program = fold add_stmt (AList.make (fn name =>
   330       (Graph.get_node program name, Graph.imm_succs program name))
   330       (Graph.get_node program name, Graph.imm_succs program name))
   331       (Graph.strong_conn program |> flat)) Symtab.empty;
   331       (Graph.strong_conn program |> flat)) Symtab.empty;
   332     fun deresolver name = (fst o the o AList.lookup (op =) ((fst o snd o the
   332     fun deresolver name = (fst o the o AList.lookup (op =) ((fst o snd o the
   333       o Symtab.lookup hs_program) ((mk_name_module o fst o Code_Name.dest_name) name))) name
   333       o Symtab.lookup hs_program) ((mk_name_module o fst o Code_Printer.dest_name) name))) name
   334       handle Option => error ("Unknown statement name: " ^ labelled_name name);
   334       handle Option => error ("Unknown statement name: " ^ labelled_name name);
   335   in (deresolver, hs_program) end;
   335   in (deresolver, hs_program) end;
   336 
   336 
   337 fun serialize_haskell module_prefix raw_module_name string_classes labelled_name
   337 fun serialize_haskell module_prefix raw_module_name string_classes labelled_name
   338     raw_reserved_names includes raw_module_alias
   338     raw_reserved_names includes raw_module_alias
   355                  | NONE => true
   355                  | NONE => true
   356         and deriv' tycos (tyco `%% tys) = deriv tycos tyco
   356         and deriv' tycos (tyco `%% tys) = deriv tycos tyco
   357               andalso forall (deriv' tycos) tys
   357               andalso forall (deriv' tycos) tys
   358           | deriv' _ (ITyVar _) = true
   358           | deriv' _ (ITyVar _) = true
   359       in deriv [] tyco end;
   359       in deriv [] tyco end;
   360     val reserved_names = Code_Name.make_vars reserved_names;
   360     val reserved_names = Code_Printer.make_vars reserved_names;
   361     fun pr_stmt qualified = pr_haskell_stmt naming labelled_name
   361     fun pr_stmt qualified = pr_haskell_stmt naming labelled_name
   362       syntax_class syntax_tyco syntax_const reserved_names
   362       syntax_class syntax_tyco syntax_const reserved_names
   363       (if qualified then deresolver else Long_Name.base_name o deresolver)
   363       (if qualified then deresolver else Long_Name.base_name o deresolver)
   364       is_cons contr_classparam_typs
   364       is_cons contr_classparam_typs
   365       (if string_classes then deriving_show else K false);
   365       (if string_classes then deriving_show else K false);