src/Pure/Tools/codegen_serializer.ML
changeset 21082 82460fa3340d
parent 21067 2a5dba84986a
child 21093 7ad7a12c0712
equal deleted inserted replaced
21081:837b535137a9 21082:82460fa3340d
    17    -> (string -> string) -> (string -> string) -> string -> theory -> theory;
    17    -> (string -> string) -> (string -> string) -> string -> theory -> theory;
    18   val add_undefined: string -> string -> string -> theory -> theory;
    18   val add_undefined: string -> string -> string -> theory -> theory;
    19 
    19 
    20   type serializer;
    20   type serializer;
    21   val add_serializer : string * serializer -> theory -> theory;
    21   val add_serializer : string * serializer -> theory -> theory;
    22   val ml_from_thingol: serializer;
       
    23   val hs_from_thingol: serializer;
       
    24   val get_serializer: theory -> string -> Args.T list
    22   val get_serializer: theory -> string -> Args.T list
    25     -> string list option -> CodegenThingol.code -> unit;
    23     -> string list option -> CodegenThingol.code -> unit;
       
    24   val assert_serializer: theory -> string -> string;
    26 
    25 
    27   val const_has_serialization: theory -> string list -> string -> bool;
    26   val const_has_serialization: theory -> string list -> string -> bool;
    28   val tyco_has_serialization: theory -> string list -> string -> bool;
    27   val tyco_has_serialization: theory -> string list -> string -> bool;
    29 
    28 
    30   val eval_verbose: bool ref;
    29   val eval_verbose: bool ref;
   170       ) -- OuterParse.string >> (fn ((p, fxy), s) => (p s, fxy));
   169       ) -- OuterParse.string >> (fn ((p, fxy), s) => (p s, fxy));
   171   in
   170   in
   172     (parse >> (fn (mfx, fixity) => mk fixity mfx)) tokens
   171     (parse >> (fn (mfx, fixity) => mk fixity mfx)) tokens
   173   end;
   172   end;
   174 
   173 
       
   174 fun parse_args f args =
       
   175   case f args
       
   176    of (x, []) => x
       
   177     | (_, _) => error "bad serializer arguments";
       
   178 
   175 
   179 
   176 (* list and string serializer *)
   180 (* list and string serializer *)
   177 
   181 
   178 fun implode_list c_nil c_cons e =
   182 fun implode_list c_nil c_cons e =
   179   let
   183   let
   222               | NONE => mk_list (map (pr NOBR) es))
   226               | NONE => mk_list (map (pr NOBR) es))
   223         | NONE => default fxy pr e1 e2;
   227         | NONE => default fxy pr e1 e2;
   224   in (2, pretty) end;
   228   in (2, pretty) end;
   225 
   229 
   226 
   230 
   227 (* variable name contexts *)
   231 (* misc *)
   228 
       
   229 fun make_vars names = (fold (fn name => Symtab.update_new (name, name)) names Symtab.empty,
       
   230   Name.make_context names);
       
   231 
       
   232 fun intro_vars names (namemap, namectxt) =
       
   233   let
       
   234     val (names', namectxt') = Name.variants names namectxt;
       
   235     val namemap' = fold2 (curry Symtab.update) names names' namemap;
       
   236   in (namemap', namectxt') end;
       
   237 
       
   238 fun lookup_var (namemap, _) name = case Symtab.lookup namemap name
       
   239  of SOME name' => name'
       
   240   | NONE => error ("invalid name in context: " ^ quote name);
       
   241 
   232 
   242 fun constructive_fun (name, (eqs, ty)) =
   233 fun constructive_fun (name, (eqs, ty)) =
   243   let
   234   let
   244     val is_cons = CodegenNames.has_nsp CodegenNames.nsp_dtco;
   235     val is_cons = CodegenNames.has_nsp CodegenNames.nsp_dtco;
   245     fun is_pat (IConst (c, _)) = is_cons c
   236     fun is_pat (IConst (c, _)) = is_cons c
   257   in case map_filter check_eq eqs
   248   in case map_filter check_eq eqs
   258    of [] => error ("In function " ^ quote name ^ ", no "
   249    of [] => error ("In function " ^ quote name ^ ", no "
   259         ^ "executable function clauses found")
   250         ^ "executable function clauses found")
   260     | eqs => (name, (eqs, ty))
   251     | eqs => (name, (eqs, ty))
   261   end;
   252   end;
       
   253 
       
   254 fun dest_name name =
       
   255   let
       
   256     val (names, name_base) = (split_last o NameSpace.unpack) name;
       
   257     val (names_mod, name_shallow) = split_last names;
       
   258   in (names_mod, (name_shallow, name_base)) end;
   262 
   259 
   263 
   260 
   264 
   261 
   265 (** SML serializer **)
   262 (** SML serializer **)
   266 
   263 
   346       | pr_typ fxy (ITyVar v) =
   343       | pr_typ fxy (ITyVar v) =
   347           str ("'" ^ v);
   344           str ("'" ^ v);
   348     fun pr_term vars fxy (IConst c) =
   345     fun pr_term vars fxy (IConst c) =
   349           pr_app vars fxy (c, [])
   346           pr_app vars fxy (c, [])
   350       | pr_term vars fxy (IVar v) =
   347       | pr_term vars fxy (IVar v) =
   351           str (lookup_var vars v)
   348           str (CodegenThingol.lookup_var vars v)
   352       | pr_term vars fxy (t as t1 `$ t2) =
   349       | pr_term vars fxy (t as t1 `$ t2) =
   353           (case CodegenThingol.unfold_const_app t
   350           (case CodegenThingol.unfold_const_app t
   354            of SOME c_ts => pr_app vars fxy c_ts
   351            of SOME c_ts => pr_app vars fxy c_ts
   355             | NONE =>
   352             | NONE =>
   356                 brackify fxy [pr_term vars NOBR t1, pr_term vars BR t2])
   353                 brackify fxy [pr_term vars NOBR t1, pr_term vars BR t2])
   357       | pr_term vars fxy (t as _ `|-> _) =
   354       | pr_term vars fxy (t as _ `|-> _) =
   358           let
   355           let
   359             val (ps, t') = CodegenThingol.unfold_abs t;
   356             val (ps, t') = CodegenThingol.unfold_abs t;
   360             fun pr ((v, NONE), _) vars =
   357             fun pr ((v, NONE), _) vars =
   361                   let
   358                   let
   362                     val vars' = intro_vars [v] vars;
   359                     val vars' = CodegenThingol.intro_vars [v] vars;
   363                   in
   360                   in
   364                     ((Pretty.block o Pretty.breaks) [str "fn", str (lookup_var vars' v), str "=>"], vars')
   361                     ((Pretty.block o Pretty.breaks) [str "fn", str (CodegenThingol.lookup_var vars' v), str "=>"], vars')
   365                   end
   362                   end
   366               | pr ((v, SOME p), _) vars =
   363               | pr ((v, SOME p), _) vars =
   367                   let
   364                   let
   368                     val vs = CodegenThingol.fold_varnames (insert (op =)) p [v];
   365                     val vs = CodegenThingol.fold_varnames (insert (op =)) p [v];
   369                     val vars' = intro_vars vs vars;
   366                     val vars' = CodegenThingol.intro_vars vs vars;
   370                   in
   367                   in
   371                     ((Pretty.block o Pretty.breaks) [str "fn", str (lookup_var vars' v), str "as",
   368                     ((Pretty.block o Pretty.breaks) [str "fn", str (CodegenThingol.lookup_var vars' v), str "as",
   372                       pr_term vars' NOBR p, str "=>"], vars')
   369                       pr_term vars' NOBR p, str "=>"], vars')
   373                   end;
   370                   end;
   374             val (ps', vars') = fold_map pr ps vars;
   371             val (ps', vars') = fold_map pr ps vars;
   375           in brackify BR (ps' @ [pr_term vars' NOBR t']) end
   372           in brackify BR (ps' @ [pr_term vars' NOBR t']) end
   376       | pr_term vars fxy (INum n) =
   373       | pr_term vars fxy (INum n) =
   386           let
   383           let
   387             val (ts, t') = CodegenThingol.unfold_let t;
   384             val (ts, t') = CodegenThingol.unfold_let t;
   388             fun mk ((p, _), t'') vars =
   385             fun mk ((p, _), t'') vars =
   389               let
   386               let
   390                 val vs = CodegenThingol.fold_varnames (insert (op =)) p [];
   387                 val vs = CodegenThingol.fold_varnames (insert (op =)) p [];
   391                 val vars' = intro_vars vs vars;
   388                 val vars' = CodegenThingol.intro_vars vs vars;
   392               in
   389               in
   393                 (Pretty.block [
   390                 (Pretty.block [
   394                   (Pretty.block o Pretty.breaks) [
   391                   (Pretty.block o Pretty.breaks) [
   395                     str "val",
   392                     str "val",
   396                     pr_term vars' NOBR p,
   393                     pr_term vars' NOBR p,
   410       | pr_term vars fxy (ICase ((td, ty), b::bs)) =
   407       | pr_term vars fxy (ICase ((td, ty), b::bs)) =
   411           let
   408           let
   412             fun pr definer (p, t) =
   409             fun pr definer (p, t) =
   413               let
   410               let
   414                 val vs = CodegenThingol.fold_varnames (insert (op =)) p [];
   411                 val vs = CodegenThingol.fold_varnames (insert (op =)) p [];
   415                 val vars' = intro_vars vs vars;
   412                 val vars' = CodegenThingol.intro_vars vs vars;
   416               in
   413               in
   417                 (Pretty.block o Pretty.breaks) [
   414                 (Pretty.block o Pretty.breaks) [
   418                   str definer,
   415                   str definer,
   419                   pr_term vars' NOBR p,
   416                   pr_term vars' NOBR p,
   420                   str "=>",
   417                   str "=>",
   483                     val consts = map_filter
   480                     val consts = map_filter
   484                       (fn c => if (is_some o const_syntax) c
   481                       (fn c => if (is_some o const_syntax) c
   485                         then NONE else (SOME o NameSpace.base o deresolv) c)
   482                         then NONE else (SOME o NameSpace.base o deresolv) c)
   486                         ((fold o CodegenThingol.fold_constnames) (insert (op =)) (t :: ts) []);
   483                         ((fold o CodegenThingol.fold_constnames) (insert (op =)) (t :: ts) []);
   487                     val vars = keyword_vars
   484                     val vars = keyword_vars
   488                       |> intro_vars consts
   485                       |> CodegenThingol.intro_vars consts
   489                       |> intro_vars ((fold o CodegenThingol.fold_unbound_varnames) (insert (op =)) (t :: ts) []);
   486                       |> CodegenThingol.intro_vars ((fold o CodegenThingol.fold_unbound_varnames) (insert (op =)) (t :: ts) []);
   490                   in
   487                   in
   491                     (Pretty.block o Pretty.breaks) (
   488                     (Pretty.block o Pretty.breaks) (
   492                       [str definer, (str o deresolv) name]
   489                       [str definer, (str o deresolv) name]
   493                       @ (if null ts andalso null vs
   490                       @ (if null ts andalso null vs
   494                            andalso not (ty = ITyVar "_")(*for evaluation*)
   491                            andalso not (ty = ITyVar "_")(*for evaluation*)
   572                 val consts = map_filter
   569                 val consts = map_filter
   573                   (fn c => if (is_some o const_syntax) c
   570                   (fn c => if (is_some o const_syntax) c
   574                     then NONE else (SOME o NameSpace.base o deresolv) c)
   571                     then NONE else (SOME o NameSpace.base o deresolv) c)
   575                     (CodegenThingol.fold_constnames (insert (op =)) t []);
   572                     (CodegenThingol.fold_constnames (insert (op =)) t []);
   576                 val vars = keyword_vars
   573                 val vars = keyword_vars
   577                   |> intro_vars consts;
   574                   |> CodegenThingol.intro_vars consts;
   578               in
   575               in
   579                 (Pretty.block o Pretty.breaks) [
   576                 (Pretty.block o Pretty.breaks) [
   580                   (str o suffix "_" o NameSpace.base) classop,
   577                   (str o suffix "_" o NameSpace.base) classop,
   581                   str "=",
   578                   str "=",
   582                   pr_term vars NOBR t
   579                   pr_term vars NOBR t
   597 
   594 
   598 
   595 
   599 
   596 
   600 (** Haskell serializer **)
   597 (** Haskell serializer **)
   601 
   598 
   602 fun pr_haskell class_syntax tyco_syntax const_syntax keyword_vars deresolv_here deresolv def =
   599 fun pr_haskell class_syntax tyco_syntax const_syntax keyword_vars deresolv_here deresolv deriving_show def =
   603   let
   600   let
   604     val is_cons = CodegenNames.has_nsp CodegenNames.nsp_dtco;
   601     val is_cons = CodegenNames.has_nsp CodegenNames.nsp_dtco;
   605     fun class_name class = case class_syntax class
   602     fun class_name class = case class_syntax class
   606      of NONE => deresolv class
   603      of NONE => deresolv class
   607       | SOME (class, _) => class;
   604       | SOME (class, _) => class;
   614       case maps (fn (v, sort) => map (pair v) sort) vs
   611       case maps (fn (v, sort) => map (pair v) sort) vs
   615        of [] => str ""
   612        of [] => str ""
   616         | xs => Pretty.block [
   613         | xs => Pretty.block [
   617             Pretty.enum "," "(" ")" (
   614             Pretty.enum "," "(" ")" (
   618               map (fn (v, class) => str
   615               map (fn (v, class) => str
   619                 (class_name class ^ " " ^ lookup_var tyvars v)) xs
   616                 (class_name class ^ " " ^ CodegenThingol.lookup_var tyvars v)) xs
   620             ),
   617             ),
   621             str " => "
   618             str " => "
   622           ];
   619           ];
   623     fun pr_tycoexpr tyvars fxy (tyco, tys) =
   620     fun pr_tycoexpr tyvars fxy (tyco, tys) =
   624       brackify fxy (str tyco :: map (pr_typ tyvars BR) tys)
   621       brackify fxy (str tyco :: map (pr_typ tyvars BR) tys)
   637             pr_typ tyvars (INFX (1, X)) t1,
   634             pr_typ tyvars (INFX (1, X)) t1,
   638             str "->",
   635             str "->",
   639             pr_typ tyvars (INFX (1, R)) t2
   636             pr_typ tyvars (INFX (1, R)) t2
   640           ]
   637           ]
   641       | pr_typ tyvars fxy (ITyVar v) =
   638       | pr_typ tyvars fxy (ITyVar v) =
   642           (str o lookup_var tyvars) v;
   639           (str o CodegenThingol.lookup_var tyvars) v;
   643     fun pr_typscheme_expr tyvars (vs, tycoexpr) =
   640     fun pr_typscheme_expr tyvars (vs, tycoexpr) =
   644       Pretty.block [pr_typparms tyvars vs, pr_tycoexpr tyvars NOBR tycoexpr];
   641       Pretty.block [pr_typparms tyvars vs, pr_tycoexpr tyvars NOBR tycoexpr];
   645     fun pr_typscheme tyvars (vs, ty) =
   642     fun pr_typscheme tyvars (vs, ty) =
   646       Pretty.block [pr_typparms tyvars vs, pr_typ tyvars NOBR ty];
   643       Pretty.block [pr_typparms tyvars vs, pr_typ tyvars NOBR ty];
   647     fun pr_term vars fxy (IConst c) =
   644     fun pr_term vars fxy (IConst c) =
   653                 brackify fxy [
   650                 brackify fxy [
   654                   pr_term vars NOBR t1,
   651                   pr_term vars NOBR t1,
   655                   pr_term vars BR t2
   652                   pr_term vars BR t2
   656                 ])
   653                 ])
   657       | pr_term vars fxy (IVar v) =
   654       | pr_term vars fxy (IVar v) =
   658           (str o lookup_var vars) v
   655           (str o CodegenThingol.lookup_var vars) v
   659       | pr_term vars fxy (t as _ `|-> _) =
   656       | pr_term vars fxy (t as _ `|-> _) =
   660           let
   657           let
   661             val (ps, t') = CodegenThingol.unfold_abs t;
   658             val (ps, t') = CodegenThingol.unfold_abs t;
   662             fun pr ((v, SOME p), _) vars =
   659             fun pr ((v, SOME p), _) vars =
   663                   let
   660                   let
   664                     val vs = CodegenThingol.fold_varnames (insert (op =)) p [v];
   661                     val vs = CodegenThingol.fold_varnames (insert (op =)) p [v];
   665                     val vars' = intro_vars vs vars;
   662                     val vars' = CodegenThingol.intro_vars vs vars;
   666                   in ((Pretty.block o Pretty.breaks) [str (lookup_var vars' v), str "@", pr_term vars' BR p], vars') end
   663                   in ((Pretty.block o Pretty.breaks) [str (CodegenThingol.lookup_var vars' v), str "@", pr_term vars' BR p], vars') end
   667               | pr ((v, NONE), _) vars =
   664               | pr ((v, NONE), _) vars =
   668                   let
   665                   let
   669                     val vars' = intro_vars [v] vars;
   666                     val vars' = CodegenThingol.intro_vars [v] vars;
   670                   in (str (lookup_var vars' v), vars') end;
   667                   in (str (CodegenThingol.lookup_var vars' v), vars') end;
   671             val (ps', vars') = fold_map pr ps vars;
   668             val (ps', vars') = fold_map pr ps vars;
   672           in
   669           in
   673             brackify BR (
   670             brackify BR (
   674               str "\\"
   671               str "\\"
   675               :: ps' @ [
   672               :: ps' @ [
   693           let
   690           let
   694             val (ts, t) = CodegenThingol.unfold_let t;
   691             val (ts, t) = CodegenThingol.unfold_let t;
   695             fun pr ((p, _), t) vars =
   692             fun pr ((p, _), t) vars =
   696               let
   693               let
   697                 val vs = CodegenThingol.fold_varnames (insert (op =)) p [];
   694                 val vs = CodegenThingol.fold_varnames (insert (op =)) p [];
   698                 val vars' = intro_vars vs vars;
   695                 val vars' = CodegenThingol.intro_vars vs vars;
   699               in
   696               in
   700                 ((Pretty.block o Pretty.breaks) [
   697                 ((Pretty.block o Pretty.breaks) [
   701                   pr_term vars' BR p,
   698                   pr_term vars' BR p,
   702                   str "=",
   699                   str "=",
   703                   pr_term vars NOBR t
   700                   pr_term vars NOBR t
   711       | pr_term vars fxy (ICase ((td, _), bs)) =
   708       | pr_term vars fxy (ICase ((td, _), bs)) =
   712           let
   709           let
   713             fun pr (p, t) =
   710             fun pr (p, t) =
   714               let
   711               let
   715                 val vs = CodegenThingol.fold_varnames (insert (op =)) p [];
   712                 val vs = CodegenThingol.fold_varnames (insert (op =)) p [];
   716                 val vars' = intro_vars vs vars;
   713                 val vars' = CodegenThingol.intro_vars vs vars;
   717               in
   714               in
   718                 (Pretty.block o Pretty.breaks) [
   715                 (Pretty.block o Pretty.breaks) [
   719                   pr_term vars' NOBR p,
   716                   pr_term vars' NOBR p,
   720                   str "->",
   717                   str "->",
   721                   pr_term vars' NOBR t
   718                   pr_term vars' NOBR t
   733       (str o deresolv) c :: map (pr_term vars BR) ts
   730       (str o deresolv) c :: map (pr_term vars BR) ts
   734     and pr_app vars fxy =
   731     and pr_app vars fxy =
   735       mk_app (pr_app' vars) (pr_term vars) const_syntax fxy;
   732       mk_app (pr_app' vars) (pr_term vars) const_syntax fxy;
   736     fun pr_def (name, CodegenThingol.Fun (funn as (eqs, (vs, ty)))) =
   733     fun pr_def (name, CodegenThingol.Fun (funn as (eqs, (vs, ty)))) =
   737           let
   734           let
   738             val tyvars = intro_vars (map fst vs) keyword_vars;
   735             val tyvars = CodegenThingol.intro_vars (map fst vs) keyword_vars;
   739             fun pr_eq (ts, t) =
   736             fun pr_eq (ts, t) =
   740               let
   737               let
   741                 val consts = map_filter
   738                 val consts = map_filter
   742                   (fn c => if (is_some o const_syntax) c
   739                   (fn c => if (is_some o const_syntax) c
   743                     then NONE else (SOME o NameSpace.base o deresolv) c)
   740                     then NONE else (SOME o NameSpace.base o deresolv) c)
   744                     ((fold o CodegenThingol.fold_constnames) (insert (op =)) (t :: ts) []);
   741                     ((fold o CodegenThingol.fold_constnames) (insert (op =)) (t :: ts) []);
   745                 val vars = keyword_vars
   742                 val vars = keyword_vars
   746                   |> intro_vars consts
   743                   |> CodegenThingol.intro_vars consts
   747                   |> intro_vars ((fold o CodegenThingol.fold_unbound_varnames) (insert (op =)) (t :: ts) []);
   744                   |> CodegenThingol.intro_vars ((fold o CodegenThingol.fold_unbound_varnames) (insert (op =)) (t :: ts) []);
   748               in
   745               in
   749                 (Pretty.block o Pretty.breaks) (
   746                 (Pretty.block o Pretty.breaks) (
   750                   (str o deresolv_here) name
   747                   (str o deresolv_here) name
   751                   :: map (pr_term vars BR) ts
   748                   :: map (pr_term vars BR) ts
   752                   @ [str "=", pr_term vars NOBR t]
   749                   @ [str "=", pr_term vars NOBR t]
   759                 Pretty.brk 1,
   756                 Pretty.brk 1,
   760                 pr_typscheme tyvars (vs, ty)
   757                 pr_typscheme tyvars (vs, ty)
   761               ]
   758               ]
   762               :: (map pr_eq o fst o snd o constructive_fun) (name, funn)
   759               :: (map pr_eq o fst o snd o constructive_fun) (name, funn)
   763             )
   760             )
   764           end |> SOME
   761           end
   765       | pr_def (name, CodegenThingol.Datatype (vs, [(co, [ty])])) =
   762       | pr_def (name, CodegenThingol.Datatype (vs, [(co, [ty])])) =
   766           let
   763           let
   767             val tyvars = intro_vars (map fst vs) keyword_vars;
   764             val tyvars = CodegenThingol.intro_vars (map fst vs) keyword_vars;
   768           in
   765           in
   769             (Pretty.block o Pretty.breaks) [
   766             (Pretty.block o Pretty.breaks) ([
   770               str "newtype",
   767               str "newtype",
   771               pr_typscheme_expr tyvars (vs, (deresolv_here name, map (ITyVar o fst) vs)),
   768               pr_typscheme_expr tyvars (vs, (deresolv_here name, map (ITyVar o fst) vs)),
   772               str "=",
   769               str "=",
   773               (str o deresolv_here) co,
   770               (str o deresolv_here) co,
   774               pr_typ tyvars BR ty
   771               pr_typ tyvars BR ty
   775             ]
   772             ] @ (if deriving_show name then [str "deriving Read, Show"] else []))
   776           end |> SOME
   773           end
   777       | pr_def (name, CodegenThingol.Datatype (vs, co :: cos)) =
   774       | pr_def (name, CodegenThingol.Datatype (vs, co :: cos)) =
   778           let
   775           let
   779             val tyvars = intro_vars (map fst vs) keyword_vars;
   776             val tyvars = CodegenThingol.intro_vars (map fst vs) keyword_vars;
   780             fun pr_co (co, tys) =
   777             fun pr_co (co, tys) =
   781               (Pretty.block o Pretty.breaks) (
   778               (Pretty.block o Pretty.breaks) (
   782                 (str o deresolv_here) co
   779                 (str o deresolv_here) co
   783                 :: map (pr_typ tyvars BR) tys
   780                 :: map (pr_typ tyvars BR) tys
   784               )
   781               )
   785           in
   782           in
   786             (Pretty.block o Pretty.breaks) (
   783             (Pretty.block o Pretty.breaks) ((
   787               str "data"
   784               str "data"
   788               :: pr_typscheme_expr tyvars (vs, (deresolv_here name, map (ITyVar o fst) vs))
   785               :: pr_typscheme_expr tyvars (vs, (deresolv_here name, map (ITyVar o fst) vs))
   789               :: str "="
   786               :: str "="
   790               :: pr_co co
   787               :: pr_co co
   791               :: map ((fn p => Pretty.block [str "| ", p]) o pr_co) cos
   788               :: map ((fn p => Pretty.block [str "| ", p]) o pr_co) cos
   792             )
   789             ) @ (if deriving_show name then [str "deriving Read, Show"] else []))
   793           end |> SOME
   790           end
   794       | pr_def (_, CodegenThingol.Datatypecons _) =
       
   795           NONE
       
   796       | pr_def (name, CodegenThingol.Class (superclasss, (v, classops))) =
   791       | pr_def (name, CodegenThingol.Class (superclasss, (v, classops))) =
   797           let
   792           let
   798             val tyvars = intro_vars [v] keyword_vars;
   793             val tyvars = CodegenThingol.intro_vars [v] keyword_vars;
   799             fun pr_classop (classop, ty) =
   794             fun pr_classop (classop, ty) =
   800               Pretty.block [
   795               Pretty.block [
   801                 str (deresolv_here classop ^ " ::"),
   796                 str (deresolv_here classop ^ " ::"),
   802                 Pretty.brk 1,
   797                 Pretty.brk 1,
   803                 pr_typ tyvars NOBR ty
   798                 pr_typ tyvars NOBR ty
   804               ]
   799               ]
   805           in
   800           in
   806             Pretty.block [
   801             Pretty.block [
   807               str "class ",
   802               str "class ",
   808               pr_typparms tyvars [(v, superclasss)],
   803               pr_typparms tyvars [(v, superclasss)],
   809               str (deresolv_here name ^ " " ^ v),
   804               str (deresolv_here name ^ " " ^ CodegenThingol.lookup_var tyvars v),
   810               str " where",
   805               str " where",
   811               Pretty.fbrk,
   806               Pretty.fbrk,
   812               Pretty.chunks (map pr_classop classops)
   807               Pretty.chunks (map pr_classop classops)
   813             ]
   808             ]
   814           end |> SOME
   809           end
   815       | pr_def (_, CodegenThingol.Classmember _) =
       
   816           NONE
       
   817       | pr_def (_, CodegenThingol.Classinst ((class, (tyco, vs)), (_, classop_defs))) =
   810       | pr_def (_, CodegenThingol.Classinst ((class, (tyco, vs)), (_, classop_defs))) =
   818           let
   811           let
   819             val tyvars = intro_vars (map fst vs) keyword_vars;
   812             val tyvars = CodegenThingol.intro_vars (map fst vs) keyword_vars;
   820           in
   813           in
   821             Pretty.block [
   814             Pretty.block [
   822               str "instance ",
   815               str "instance ",
   823               pr_typparms tyvars vs,
   816               pr_typparms tyvars vs,
   824               str (class_name class ^ " "),
   817               str (class_name class ^ " "),
   830                   val consts = map_filter
   823                   val consts = map_filter
   831                     (fn c => if (is_some o const_syntax) c
   824                     (fn c => if (is_some o const_syntax) c
   832                       then NONE else (SOME o NameSpace.base o deresolv) c)
   825                       then NONE else (SOME o NameSpace.base o deresolv) c)
   833                       (CodegenThingol.fold_constnames (insert (op =)) t []);
   826                       (CodegenThingol.fold_constnames (insert (op =)) t []);
   834                   val vars = keyword_vars
   827                   val vars = keyword_vars
   835                     |> intro_vars consts;
   828                     |> CodegenThingol.intro_vars consts;
   836                 in
   829                 in
   837                   (Pretty.block o Pretty.breaks) [
   830                   (Pretty.block o Pretty.breaks) [
   838                     (str o classop_name class) classop,
   831                     (str o classop_name class) classop,
   839                     str "=",
   832                     str "=",
   840                     pr_term vars NOBR t
   833                     pr_term vars NOBR t
   841                   ]
   834                   ]
   842                 end
   835                 end
   843               ) classop_defs)
   836               ) classop_defs)
   844             ]
   837             ]
   845           end |> SOME
   838           end;
   846       | pr_def (_, CodegenThingol.Bot) =
       
   847           NONE;
       
   848   in pr_def def end;
   839   in pr_def def end;
   849 
   840 
   850 val reserved_haskell = [
   841 val reserved_haskell = [
   851   "hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr",
   842   "hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr",
   852   "import", "default", "forall", "let", "in", "class", "qualified", "data",
   843   "import", "default", "forall", "let", "in", "class", "qualified", "data",
   853   "newtype", "instance", "if", "then", "else", "type", "as", "do", "module"
   844   "newtype", "instance", "if", "then", "else", "type", "as", "do", "module"
   854 ];
   845 ];
   855 
   846 
   856 fun seri_haskell module_prefix destination reserved_user module_alias module_prolog
   847 fun seri_haskell module_prefix destination string_classes reserved_user module_alias module_prolog
   857   class_syntax tyco_syntax const_syntax code =
   848   class_syntax tyco_syntax const_syntax code =
   858   let
   849   let
   859     val init_vars = make_vars (reserved_haskell @ reserved_user);
   850     val _ = Option.map File.assert destination;
   860   in () end;
   851     val empty_names = Name.make_context (reserved_haskell @ reserved_user);
   861 
   852     fun prefix_modlname modlname = case module_prefix
       
   853      of NONE => modlname
       
   854       | SOME module_prefix => NameSpace.append module_prefix modlname;
       
   855     fun add_def (name, (def, deps)) =
       
   856       let
       
   857         val (modl, (shallow, base)) = dest_name name;
       
   858         val base' = if member (op =)
       
   859           [CodegenNames.nsp_class, CodegenNames.nsp_tyco, CodegenNames.nsp_dtco] shallow
       
   860           then first_upper base else base;
       
   861         fun mk name = (the_single o fst) (Name.variants [name] empty_names);
       
   862         fun mk' name names = names |> Name.variants [name] |>> the_single;
       
   863         val modlname = NameSpace.pack modl;
       
   864         val modlname' = case module_alias modlname
       
   865          of SOME modlname' => prefix_modlname modlname'
       
   866           | NONE => NameSpace.pack (map_filter I (module_prefix :: map (SOME o mk) modl));
       
   867         val deps' = remove (op =) modlname (map (NameSpace.qualifier o NameSpace.qualifier) deps);
       
   868         fun add_def base' =
       
   869           case def
       
   870            of CodegenThingol.Datatypecons _ => I
       
   871                 cons (name, ((NameSpace.append modlname' base', base'), NONE))
       
   872             | CodegenThingol.Classop _ =>
       
   873                 cons (name, ((NameSpace.append modlname' base', base'), NONE))
       
   874             | CodegenThingol.Bot => I
       
   875             | _ => cons (name, ((NameSpace.append modlname' base', base'), SOME def));
       
   876       in
       
   877         Symtab.map_default (modlname, (modlname', ([], ([], empty_names))))
       
   878             ((apsnd o apfst) (fold (insert (op =)) deps'))
       
   879         #> `(fn code => mk' base' ((snd o snd o snd o the o Symtab.lookup code) modlname))
       
   880         #-> (fn (base', names) =>
       
   881               Symtab.map_entry modlname ((apsnd o apsnd) (fn (defs, _) =>
       
   882               (add_def base' defs, names))))
       
   883       end;
       
   884     val code' =
       
   885       fold add_def (AList.make (fn name => (Graph.get_node code name, Graph.imm_succs code name))
       
   886         (Graph.strong_conn code |> flat)) Symtab.empty;
       
   887     val init_vars = CodegenThingol.make_vars (reserved_haskell @ reserved_user);
       
   888     fun deresolv name =
       
   889       (fst o fst o the o AList.lookup (op =) ((fst o snd o snd o the
       
   890         o Symtab.lookup code') ((NameSpace.qualifier o NameSpace.qualifier) name))) name;
       
   891     fun deresolv_here name =
       
   892       (snd o fst o the o AList.lookup (op =) ((fst o snd o snd o the
       
   893         o Symtab.lookup code') ((NameSpace.qualifier o NameSpace.qualifier) name))) name;
       
   894     val deresolv_module = fst o the o Symtab.lookup code';
       
   895     fun deriving_show tyco =
       
   896       let
       
   897         fun deriv tycos tyco = member (op =) tycos tyco orelse
       
   898           case Graph.get_node code tyco
       
   899            of CodegenThingol.Bot => true
       
   900             | CodegenThingol.Datatype (_, cs) => forall (deriv' (tyco :: tycos))
       
   901                 (maps snd cs)
       
   902         and deriv' tycos (tyco `%% tys) = deriv tycos tyco
       
   903               andalso forall (deriv' tycos) tys
       
   904           | deriv' _ (_ `-> _) = false
       
   905           | deriv' _ (ITyVar _) = true
       
   906       in deriv [] tyco end;
       
   907     val seri_def = pr_haskell class_syntax tyco_syntax const_syntax init_vars
       
   908       deresolv_here deresolv (if string_classes then deriving_show else K false);
       
   909     fun write_module (SOME destination) modlname p =
       
   910           let
       
   911             val filename = case modlname
       
   912              of "" => Path.unpack "Main.hs"
       
   913               | _ => (Path.ext "hs" o Path.unpack o implode o separate "/" o NameSpace.unpack) modlname;
       
   914             val pathname = Path.append destination filename;
       
   915             val _ = File.mkdir (Path.dir pathname);
       
   916           in File.write pathname (Pretty.setmp_margin 999999 Pretty.output p ^ "\n") end
       
   917       | write_module NONE _ p =
       
   918           writeln (Pretty.setmp_margin 999999 Pretty.output p ^ "\n");
       
   919     fun seri_module (modlname, (modlname', (imports, (defs, _)))) =
       
   920       Pretty.chunks (
       
   921         str ("module " ^ modlname' ^ " where")
       
   922         :: map str (distinct (op =) (map (prefix "import qualified " o deresolv_module) imports)) @ (
       
   923         (case module_prolog modlname
       
   924          of SOME prolog => [str "", prolog, str ""]
       
   925           | NONE => [str ""])
       
   926         @ separate (str "") (map_filter
       
   927           (fn (name, (_, SOME def)) => SOME (seri_def (name, def))
       
   928             | (_, (_, NONE)) => NONE) defs))
       
   929       ) |> write_module destination modlname';
       
   930   in Symtab.fold (fn modl => fn () => seri_module modl) code' () end;
       
   931 
       
   932 val isar_seri_haskell =
       
   933   parse_args (Scan.option (Args.$$$ "root" -- Args.colon |-- Args.name)
       
   934     -- Scan.optional (Args.$$$ "string_classes" >> K true) false
       
   935     -- (Args.$$$ "-" >> K NONE || Args.name >> SOME)
       
   936     >> (fn ((module_prefix, string_classes), destination) =>
       
   937       seri_haskell module_prefix (Option.map Path.unpack destination) string_classes));
   862 
   938 
   863 
   939 
   864 (** diagnosis serializer **)
   940 (** diagnosis serializer **)
   865 
   941 
   866 fun seri_diagnosis _ _ _ _ _ code =
   942 fun seri_diagnosis _ _ _ _ _ code =
   867   let
   943   let
   868     val init_vars = make_vars reserved_haskell;
   944     val init_vars = CodegenThingol.make_vars reserved_haskell;
   869     val pr = pr_haskell (K NONE) (K NONE) (K NONE) init_vars I I;
   945     val pr = pr_haskell (K NONE) (K NONE) (K NONE) init_vars I I (K false);
   870   in
   946   in
   871     []
   947     []
   872     |> Graph.fold (fn (name, (def, _)) =>
   948     |> Graph.fold (fn (name, (def, _)) => cons (pr (name, def))) code
   873         case pr (name, def) of SOME p => cons p | NONE => I) code
       
   874     |> separate (Pretty.str "")
   949     |> separate (Pretty.str "")
   875     |> Pretty.chunks
   950     |> Pretty.chunks
   876     |> Pretty.writeln
   951     |> Pretty.writeln
   877   end;
   952   end;
   878 
   953 
   879 
   954 
   880 
   955 
   881 (** generic abstract serializer **)
   956 (** ML abstract serializer -- FIXME to be refactored **)
   882 
   957 
   883 structure NameMangler = NameManglerFun (
   958 structure NameMangler = NameManglerFun (
   884   type ctxt = (string * string -> string) * (string -> string option);
   959   type ctxt = (string * string -> string) * (string -> string option);
   885   type src = string * string;
   960   type src = string * string;
   886   val ord = prod_ord string_ord string_ord;
   961   val ord = prod_ord string_ord string_ord;
   972             val (common, (_, rem)) = chop_prefix (op =) (prefix, NameSpace.unpack name);
  1047             val (common, (_, rem)) = chop_prefix (op =) (prefix, NameSpace.unpack name);
   973             val (_, SOME tab') = get_path_name common tab;
  1048             val (_, SOME tab') = get_path_name common tab;
   974             val (name', _) = get_path_name rem tab';
  1049             val (name', _) = get_path_name rem tab';
   975           in NameSpace.pack name' end handle BIND => (error ("Missing name: " ^ quote name ^ ", in " ^ quote (NameSpace.pack prefix)));
  1050           in NameSpace.pack name' end handle BIND => (error ("Missing name: " ^ quote name ^ ", in " ^ quote (NameSpace.pack prefix)));
   976       in deresolv (mk module (AList.make (K NameMangler.empty) nsp_conn) Symtab.empty) end;
  1051       in deresolv (mk module (AList.make (K NameMangler.empty) nsp_conn) Symtab.empty) end;
   977     fun allimports_of modl =
       
   978       let
       
   979         fun imps_of prfx (Module modl) imps tab =
       
   980               let
       
   981                 val this = NameSpace.pack prfx;
       
   982                 val name_con = (rev o Graph.strong_conn) modl;
       
   983               in
       
   984                 tab
       
   985                 |> pair []
       
   986                 |> fold (fn names => fn (imps', tab) =>
       
   987                     tab
       
   988                     |> fold_map (fn name =>
       
   989                          imps_of (prfx @ [name]) (Graph.get_node modl name) (imps' @ imps)) names
       
   990                     |-> (fn imps'' => pair (flat imps'' @ imps'))) name_con
       
   991                 |-> (fn imps' =>
       
   992                    Symtab.update_new (this, imps' @ imps)
       
   993                 #> pair (this :: imps'))
       
   994               end
       
   995           | imps_of prfx (Def _) imps tab =
       
   996               ([], tab);
       
   997       in snd (imps_of [] (Module modl) [] Symtab.empty) end;
       
   998     fun add_def ((names_mod, name_id), def) =
  1052     fun add_def ((names_mod, name_id), def) =
   999       let
  1053       let
  1000         fun add [] =
  1054         fun add [] =
  1001               Graph.new_node (name_id, Def def)
  1055               Graph.new_node (name_id, Def def)
  1002           | add (m::ms) =
  1056           | add (m::ms) =
  1029       Graph.empty
  1083       Graph.empty
  1030       |> Graph.fold (fn (name, (def, _)) => add_def (dest_name name, def)) code
  1084       |> Graph.fold (fn (name, (def, _)) => add_def (dest_name name, def)) code
  1031       |> Graph.fold (fn (name, (_, (_, deps))) =>
  1085       |> Graph.fold (fn (name, (_, (_, deps))) =>
  1032           fold (curry add_dep name) deps) code;
  1086           fold (curry add_dep name) deps) code;
  1033     val names = map fst (Graph.dest root_module);
  1087     val names = map fst (Graph.dest root_module);
  1034     val imptab = allimports_of root_module;
       
  1035     val resolver = mk_deresolver root_module nsp_conn postprocess validate;
  1088     val resolver = mk_deresolver root_module nsp_conn postprocess validate;
  1036     fun sresolver s = (resolver o NameSpace.unpack) s
  1089     fun sresolver s = (resolver o NameSpace.unpack) s
  1037     fun mk_name prfx name =
  1090     fun mk_name prfx name =
  1038       let
  1091       let
  1039         val name_qual = NameSpace.pack (prfx @ [name])
  1092         val name_qual = NameSpace.pack (prfx @ [name])
  1040       in (name_qual, resolver prfx name_qual) end;
  1093       in (name_qual, resolver prfx name_qual) end;
  1041     fun is_bot (_, (Def Bot)) = true
       
  1042       | is_bot _ = false;
       
  1043     fun mk_contents prfx module =
  1094     fun mk_contents prfx module =
  1044       map_filter (seri prfx)
  1095       map_filter (seri prfx)
  1045         ((map (AList.make (Graph.get_node module)) o rev o Graph.strong_conn) module)
  1096         ((map (AList.make (Graph.get_node module)) o rev o Graph.strong_conn) module)
  1046     and seri prfx [(name, Module modl)] =
  1097     and seri prfx [(name, Module modl)] =
  1047           seri_module (resolver []) (map (resolver []) ((the o Symtab.lookup imptab) (NameSpace.pack (prfx @ [name]))))
  1098           seri_module (resolver []) (mk_name prfx name, mk_contents (prfx @ [name]) modl)
  1048             (mk_name prfx name, mk_contents (prfx @ [name]) modl)
       
  1049       | seri prfx ds =
  1099       | seri prfx ds =
  1050           seri_defs sresolver (NameSpace.pack prfx)
  1100           seri_defs sresolver (NameSpace.pack prfx)
  1051             (map (fn (name, Def def) => (fst (mk_name prfx name), def)) ds)
  1101             (map (fn (name, Def def) => (fst (mk_name prfx name), def)) ds)
  1052   in
  1102   in
  1053     seri_module (resolver []) (map (resolver []) ((the o Symtab.lookup imptab) ""))
  1103     seri_module (resolver [])
  1054       (("", name_root), (mk_contents [] root_module))
  1104       (("", name_root), (mk_contents [] root_module))
  1055   end;
  1105   end;
  1056 
  1106 
  1057 fun abstract_serializer nspgrp name_root (from_defs, from_module, validator, postproc)
  1107 fun abstract_serializer nspgrp name_root (from_defs, from_module, validator, postproc)
  1058     postprocess
  1108     postprocess
  1059     reserved_user module_alias module_prolog class_syntax tyco_syntax const_syntax
  1109     reserved_user module_alias module_prolog class_syntax tyco_syntax const_syntax
  1060     code =
  1110     code =
  1061   let
  1111   let
  1062     fun from_module' resolv imps ((name_qual, name), defs) =
  1112     fun from_module' resolv ((name_qual, name), defs) =
  1063       from_module resolv imps ((name_qual, name), defs)
  1113       from_module resolv ((name_qual, name), defs)
  1064       |> postprocess (resolv name_qual);
  1114       |> postprocess (resolv name_qual);
  1065   in
  1115   in
  1066     code_serialize (from_defs (class_syntax, tyco_syntax, const_syntax))
  1116     code_serialize (from_defs (class_syntax, tyco_syntax, const_syntax))
  1067       from_module' validator postproc nspgrp name_root code
  1117       from_module' validator postproc nspgrp name_root code
  1068     |> K ()
  1118     |> K ()
  1084     |> translate_string replace_invalid
  1134     |> translate_string replace_invalid
  1085     |> suffix_it
  1135     |> suffix_it
  1086     |> (fn name' => if name = name' then NONE else SOME name')
  1136     |> (fn name' => if name = name' then NONE else SOME name')
  1087   end;
  1137   end;
  1088 
  1138 
  1089 fun write_file mkdir path p = (
  1139 fun write_file path p = (File.write path (Pretty.output p ^ "\n"); p);
  1090     if mkdir
       
  1091       then
       
  1092         File.mkdir (Path.dir path)
       
  1093       else ();
       
  1094       File.write path (Pretty.output p ^ "\n");
       
  1095       p
       
  1096   );
       
  1097 
       
  1098 fun mk_module_file postprocess_module ext path name p =
       
  1099   let
       
  1100     val prfx = Path.dir path;
       
  1101     val name' = case name
       
  1102      of "" => Path.base path
       
  1103       | _ => (Path.ext ext o Path.unpack o implode o separate "/" o NameSpace.unpack) name;
       
  1104   in
       
  1105     p
       
  1106     |> Pretty.setmp_margin 999999 (write_file true (Path.append prfx name'))
       
  1107     |> postprocess_module name
       
  1108   end;
       
  1109 
       
  1110 fun parse_args f args =
       
  1111   case f args
       
  1112    of (x, []) => x
       
  1113     | (_, _) => error "bad serializer arguments";
       
  1114 
  1140 
  1115 val sml_code_width = ref 80;
  1141 val sml_code_width = ref 80;
  1116 
  1142 
  1117 fun parse_single_file serializer =
  1143 fun parse_single_file serializer =
  1118   parse_args (Args.name
  1144   parse_args (Args.name
  1119   >> (fn path => serializer
  1145   >> (fn path => serializer
  1120         (fn "" => Pretty.setmp_margin (!sml_code_width) (write_file false (Path.unpack path)) #> K NONE
  1146         (fn "" => Pretty.setmp_margin (!sml_code_width) (write_file (Path.unpack path)) #> K NONE
  1121           | _ => SOME)));
  1147           | _ => SOME)));
  1122 
       
  1123 fun parse_multi_file postprocess_module ext serializer =
       
  1124   parse_args (Args.name
       
  1125   >> (fn path => (serializer o mk_module_file postprocess_module ext) (Path.unpack path)));
       
  1126 
  1148 
  1127 fun parse_internal serializer =
  1149 fun parse_internal serializer =
  1128   parse_args (Args.name
  1150   parse_args (Args.name
  1129   >> (fn "-" => serializer
  1151   >> (fn "-" => serializer
  1130         (fn "" => (fn p => (use_text Output.ml_output false (Pretty.output p); NONE))
  1152         (fn "" => (fn p => (use_text Output.ml_output false (Pretty.output p); NONE))
  1141 val nsp_module = CodegenNames.nsp_module;
  1163 val nsp_module = CodegenNames.nsp_module;
  1142 val nsp_class = CodegenNames.nsp_class;
  1164 val nsp_class = CodegenNames.nsp_class;
  1143 val nsp_tyco = CodegenNames.nsp_tyco;
  1165 val nsp_tyco = CodegenNames.nsp_tyco;
  1144 val nsp_inst = CodegenNames.nsp_inst;
  1166 val nsp_inst = CodegenNames.nsp_inst;
  1145 val nsp_fun = CodegenNames.nsp_fun;
  1167 val nsp_fun = CodegenNames.nsp_fun;
  1146 val nsp_classop = CodegenNames.nsp_classop;
       
  1147 val nsp_dtco = CodegenNames.nsp_dtco;
  1168 val nsp_dtco = CodegenNames.nsp_dtco;
  1148 val nsp_eval = CodegenNames.nsp_eval;
  1169 val nsp_eval = CodegenNames.nsp_eval;
  1149 
  1170 
  1150 
  1171 
  1151 (** ML serializer **)
  1172 (** ML serializer **)
  1158 ];
  1179 ];
  1159 
  1180 
  1160 fun ml_from_defs (_, tyco_syntax, const_syntax) deresolver prefx defs =
  1181 fun ml_from_defs (_, tyco_syntax, const_syntax) deresolver prefx defs =
  1161   let
  1182   let
  1162     val seri = pr_sml_def tyco_syntax const_syntax
  1183     val seri = pr_sml_def tyco_syntax const_syntax
  1163       (make_vars (ThmDatabase.ml_reserved @ reserved_ml'))
  1184       (CodegenThingol.make_vars (ThmDatabase.ml_reserved @ reserved_ml'))
  1164       (deresolver prefx) #> SOME;
  1185       (deresolver prefx) #> SOME;
  1165     val filter_funs =
  1186     val filter_funs =
  1166       map
  1187       map
  1167         (fn (name, CodegenThingol.Fun info) => (name, info)
  1188         (fn (name, CodegenThingol.Fun info) => (name, info)
  1168           | (name, def) => error ("Function block containing illegal def: " ^ quote name)
  1189           | (name, def) => error ("Function block containing illegal def: " ^ quote name)
  1176         )
  1197         )
  1177       #> MLDatas;
  1198       #> MLDatas;
  1178     fun filter_class defs =
  1199     fun filter_class defs =
  1179       case map_filter
  1200       case map_filter
  1180         (fn (name, CodegenThingol.Class info) => SOME (name, info)
  1201         (fn (name, CodegenThingol.Class info) => SOME (name, info)
  1181           | (name, CodegenThingol.Classmember _) => NONE
  1202           | (name, CodegenThingol.Classop _) => NONE
  1182           | (name, def) => error ("Class block containing illegal def: " ^ quote name)
  1203           | (name, def) => error ("Class block containing illegal def: " ^ quote name)
  1183         ) defs
  1204         ) defs
  1184        of [class] => MLClass class
  1205        of [class] => MLClass class
  1185         | _ => error ("Class block without class: " ^ (commas o map (quote o fst)) defs)
  1206         | _ => error ("Class block without class: " ^ (commas o map (quote o fst)) defs)
  1186   in case defs
  1207   in case defs
  1187    of (_, CodegenThingol.Fun _)::_ => (seri o filter_funs) defs
  1208    of (_, CodegenThingol.Fun _)::_ => (seri o filter_funs) defs
  1188     | (_, CodegenThingol.Datatypecons _)::_ => (seri o filter_datatype) defs
  1209     | (_, CodegenThingol.Datatypecons _)::_ => (seri o filter_datatype) defs
  1189     | (_, CodegenThingol.Datatype _)::_ => (seri o filter_datatype) defs
  1210     | (_, CodegenThingol.Datatype _)::_ => (seri o filter_datatype) defs
  1190     | (_, CodegenThingol.Class _)::_ => (seri o filter_class) defs
  1211     | (_, CodegenThingol.Class _)::_ => (seri o filter_class) defs
  1191     | (_, CodegenThingol.Classmember _)::_ => (seri o filter_class) defs
  1212     | (_, CodegenThingol.Classop _)::_ => (seri o filter_class) defs
  1192     | [(inst, CodegenThingol.Classinst info)] => seri (MLClassinst (inst, info))
  1213     | [(inst, CodegenThingol.Classinst info)] => seri (MLClassinst (inst, info))
  1193     | defs => error ("Illegal mutual dependencies: " ^ (commas o map fst) defs)
  1214     | defs => error ("Illegal mutual dependencies: " ^ (commas o map fst) defs)
  1194   end;
  1215   end;
  1195 
  1216 
  1196 fun ml_serializer root_name nspgrp =
  1217 fun ml_serializer root_name nspgrp =
  1197   let
  1218   let
  1198     fun ml_from_module resolv _ ((_, name), ps) =
  1219     fun ml_from_module resolv ((_, name), ps) =
  1199       Pretty.chunks ([
  1220       Pretty.chunks ([
  1200         str ("structure " ^ name ^ " = "),
  1221         str ("structure " ^ name ^ " = "),
  1201         str "struct",
  1222         str "struct",
  1202         str ""
  1223         str ""
  1203       ] @ separate (str "") ps @ [
  1224       ] @ separate (str "") ps @ [
  1204         str "",
  1225         str "",
  1205         str ("end; (* struct " ^ name ^ " *)")
  1226         str ("end; (* struct " ^ name ^ " *)")
  1206       ]);
  1227       ]);
  1207     fun postproc (shallow, n) =
  1228     fun postproc (shallow, n) =
  1208       let
  1229       if shallow = CodegenNames.nsp_dtco
  1209         fun ch_first f = String.implode o nth_map 0 f o String.explode;
  1230         then first_upper n
  1210       in if shallow = CodegenNames.nsp_dtco
  1231         else n;
  1211         then ch_first Char.toUpper n
       
  1212         else n
       
  1213       end;
       
  1214   in abstract_serializer nspgrp
  1232   in abstract_serializer nspgrp
  1215     root_name (ml_from_defs, ml_from_module,
  1233     root_name (ml_from_defs, ml_from_module,
  1216      abstract_validator (ThmDatabase.ml_reserved @ reserved_ml'), postproc) end;
  1234      abstract_validator (ThmDatabase.ml_reserved @ reserved_ml'), postproc) end;
  1217 
  1235 
  1218 in
  1236 in
  1219 
  1237 
  1220 fun ml_from_thingol args =
  1238 fun ml_from_thingol args =
  1221   let
  1239   let
  1222     val serializer = ml_serializer "ROOT" [[nsp_module], [nsp_class, nsp_tyco],
  1240     val serializer = ml_serializer "ROOT" [[nsp_module], [nsp_class, nsp_tyco],
  1223       [nsp_fun, nsp_dtco, nsp_class, nsp_classop, nsp_inst]]
  1241       [nsp_fun, nsp_dtco, nsp_class, nsp_inst]]
  1224     val parse_multi =
  1242   in
  1225       Args.name
  1243     (parse_internal serializer
  1226       #-> (fn "dir" =>
       
  1227                parse_multi_file
       
  1228                  (K o SOME o str o suffix ";" o prefix "val _ = use "
       
  1229                   o quote o suffix ".ML" o translate_string (fn "." => "/" | s => s)) "ML" serializer
       
  1230             | _ => Scan.fail ());
       
  1231   in
       
  1232     (parse_multi
       
  1233     || parse_internal serializer
       
  1234     || parse_stdout serializer
  1244     || parse_stdout serializer
  1235     || parse_single_file serializer) args
  1245     || parse_single_file serializer) args
  1236   end;
  1246   end;
  1237 
  1247 
  1238 val eval_verbose = ref false;
  1248 val eval_verbose = ref false;
  1243     val code'' = CodegenThingol.project_code hidden (SOME [NameSpace.pack [nsp_eval, val_name]]) code';
  1253     val code'' = CodegenThingol.project_code hidden (SOME [NameSpace.pack [nsp_eval, val_name]]) code';
  1244     val struct_name = "EVAL";
  1254     val struct_name = "EVAL";
  1245     fun output p = if !eval_verbose then (Pretty.writeln p; Pretty.output p)
  1255     fun output p = if !eval_verbose then (Pretty.writeln p; Pretty.output p)
  1246       else Pretty.output p;
  1256       else Pretty.output p;
  1247     val serializer = ml_serializer struct_name [[nsp_module], [nsp_class, nsp_tyco],
  1257     val serializer = ml_serializer struct_name [[nsp_module], [nsp_class, nsp_tyco],
  1248       [nsp_fun, nsp_dtco, nsp_class, nsp_classop, nsp_inst], [nsp_eval]]
  1258       [nsp_fun, nsp_dtco, nsp_class, nsp_inst], [nsp_eval]]
  1249       (fn "" => (fn p => (use_text Output.ml_output (!eval_verbose) (output p); NONE))
  1259       (fn "" => (fn p => (use_text Output.ml_output (!eval_verbose) (output p); NONE))
  1250         | _ => SOME) data1 data2 data3 data4 data5 data6;
  1260         | _ => SOME) data1 data2 data3 data4 data5 data6;
  1251     val _ = serializer code'';
  1261     val _ = serializer code'';
  1252     val val_name_struct = NameSpace.append struct_name val_name;
  1262     val val_name_struct = NameSpace.append struct_name val_name;
  1253     val _ = reff := NONE;
  1263     val _ = reff := NONE;
  1256    of NONE => error ("Could not retrieve value of ML reference " ^ quote ref_name
  1266    of NONE => error ("Could not retrieve value of ML reference " ^ quote ref_name
  1257         ^ " (reference probably has been shadowed)")
  1267         ^ " (reference probably has been shadowed)")
  1258     | SOME value => value
  1268     | SOME value => value
  1259   end;
  1269   end;
  1260 
  1270 
  1261 structure NameMangler = NameManglerFun (
       
  1262   type ctxt = string list;
       
  1263   type src = string;
       
  1264   val ord = string_ord;
       
  1265   fun mk reserved_ml (name, i) =
       
  1266     (Symbol.alphanum o NameSpace.base) name ^ replicate_string i "'";
       
  1267   fun is_valid (reserved_ml : string list) = not o member (op =) reserved_ml;
       
  1268   fun maybe_unique _ _ = NONE;
       
  1269   fun re_mangle _ dst = error ("No such definition name: " ^ quote dst);
       
  1270 );
       
  1271 
       
  1272 fun mk_flat_ml_resolver names =
       
  1273   let
       
  1274     val mangler =
       
  1275       NameMangler.empty
       
  1276       |> fold_map (NameMangler.declare (ThmDatabase.ml_reserved @ reserved_ml')) names
       
  1277       |-> (fn _ => I)
       
  1278   in NameMangler.get (ThmDatabase.ml_reserved @ reserved_ml') mangler end;
       
  1279 
       
  1280 end; (* local *)
  1271 end; (* local *)
  1281 
       
  1282 
       
  1283 (** haskell serializer **)
       
  1284 
       
  1285 fun hs_from_thingol args =
       
  1286   let
       
  1287     fun hs_from_defs keyword_vars (class_syntax, tyco_syntax, const_syntax) deresolver prefix defs =
       
  1288       let
       
  1289         val deresolv = deresolver "";
       
  1290         val deresolv_here = deresolver prefix;
       
  1291         val hs_from_def = pr_haskell class_syntax tyco_syntax const_syntax
       
  1292           keyword_vars deresolv_here deresolv;
       
  1293       in case map_filter hs_from_def defs
       
  1294        of [] => NONE
       
  1295         | ps => (SOME o Pretty.chunks o separate (str "")) ps
       
  1296       end;
       
  1297     val reserved_hs = [
       
  1298       "hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr",
       
  1299       "import", "default", "forall", "let", "in", "class", "qualified", "data",
       
  1300       "newtype", "instance", "if", "then", "else", "type", "as", "do", "module"
       
  1301     ] @ [
       
  1302       "Bool", "Integer", "Maybe", "True", "False", "Nothing", "Just", "not", "negate",
       
  1303       "String", "Char"
       
  1304     ];
       
  1305     fun hs_from_module resolv imps ((_, name), ps) =
       
  1306       (Pretty.chunks) (
       
  1307         str ("module " ^ name ^ " where")
       
  1308         :: map (str o prefix "import qualified ") imps @ (
       
  1309           str ""
       
  1310           :: separate (str "") ps
       
  1311       ));
       
  1312     fun postproc (shallow, n) =
       
  1313       let
       
  1314         fun ch_first f = String.implode o nth_map 0 f o String.explode;
       
  1315       in if member (op =) [nsp_module, nsp_class, nsp_tyco, nsp_dtco] shallow
       
  1316         then ch_first Char.toUpper n
       
  1317         else ch_first Char.toLower n
       
  1318       end;
       
  1319     val serializer = abstract_serializer [[nsp_module],
       
  1320       [nsp_class], [nsp_tyco], [nsp_fun, nsp_classop], [nsp_dtco], [nsp_inst]]
       
  1321       "Main" (hs_from_defs (make_vars reserved_hs), hs_from_module, abstract_validator reserved_hs, postproc);
       
  1322   in
       
  1323     (parse_multi_file ((K o K) NONE) "hs" serializer) args
       
  1324   end;
       
  1325 
  1272 
  1326 
  1273 
  1327 
  1274 
  1328 (** theory data **)
  1275 (** theory data **)
  1329 
  1276 
  1439 val target_diag = "diag";
  1386 val target_diag = "diag";
  1440 
  1387 
  1441 val _ = Context.add_setup (
  1388 val _ = Context.add_setup (
  1442   CodegenSerializerData.init
  1389   CodegenSerializerData.init
  1443   #> add_serializer ("SML", ml_from_thingol)
  1390   #> add_serializer ("SML", ml_from_thingol)
  1444   #> add_serializer ("Haskell", hs_from_thingol)
  1391   #> add_serializer ("Haskell", isar_seri_haskell)
  1445   #> add_serializer (target_diag, (fn _ => fn _ => seri_diagnosis))
  1392   #> add_serializer (target_diag, (fn _ => fn _ => seri_diagnosis))
  1446 );
  1393 );
  1447 
  1394 
  1448 fun get_serializer thy target args cs =
  1395 fun get_serializer thy target args cs =
  1449   let
  1396   let
  1461   in
  1408   in
  1462     project #> seri args reserved (Symtab.lookup alias) (Symtab.lookup prolog)
  1409     project #> seri args reserved (Symtab.lookup alias) (Symtab.lookup prolog)
  1463       (fun_of class) (fun_of tyco) (fun_of const)
  1410       (fun_of class) (fun_of tyco) (fun_of const)
  1464   end;
  1411   end;
  1465 
  1412 
       
  1413 fun assert_serializer thy target =
       
  1414   case Symtab.lookup (CodegenSerializerData.get thy) target
       
  1415    of SOME data => target
       
  1416     | NONE => error ("Unknown code target language: " ^ quote target);
       
  1417 
  1466 fun has_serialization f thy targets name =
  1418 fun has_serialization f thy targets name =
  1467   forall (
  1419   forall (
  1468     is_some o (fn tab => Symtab.lookup tab name) o f o the_syntax_expr o the
  1420     is_some o (fn tab => Symtab.lookup tab name) o f o the_syntax_expr o the
  1469       o (Symtab.lookup ((CodegenSerializerData.get) thy))
  1421       o (Symtab.lookup ((CodegenSerializerData.get) thy))
  1470   ) targets;
  1422   ) targets;
  1665     P.name -- Scan.repeat1 P.name
  1617     P.name -- Scan.repeat1 P.name
  1666     >> (fn (target, reserveds) => (Toplevel.theory o fold (add_reserved target)) reserveds)
  1618     >> (fn (target, reserveds) => (Toplevel.theory o fold (add_reserved target)) reserveds)
  1667   )
  1619   )
  1668 
  1620 
  1669 val code_modulenameP =
  1621 val code_modulenameP =
  1670   OuterSyntax.command code_reservedK "alias module to other name" K.thy_decl (
  1622   OuterSyntax.command code_modulenameK "alias module to other name" K.thy_decl (
  1671     P.name -- Scan.repeat1 (P.name -- P.name)
  1623     P.name -- Scan.repeat1 (P.name -- P.name)
  1672     >> (fn (target, modlnames) => (Toplevel.theory o fold (add_modl_alias target)) modlnames)
  1624     >> (fn (target, modlnames) => (Toplevel.theory o fold (add_modl_alias target)) modlnames)
  1673   )
  1625   )
  1674 
  1626 
  1675 val code_moduleprologP =
  1627 val code_moduleprologP =
  1676   OuterSyntax.command code_reservedK "add prolog to module" K.thy_decl (
  1628   OuterSyntax.command code_moduleprologK "add prolog to module" K.thy_decl (
  1677     P.name -- Scan.repeat1 (P.name -- (P.string >> (fn "-" => NONE | s => SOME s)))
  1629     P.name -- Scan.repeat1 (P.name -- (P.string >> (fn "-" => NONE | s => SOME s)))
  1678     >> (fn (target, prologs) => (Toplevel.theory o fold (add_modl_prolog target)) prologs)
  1630     >> (fn (target, prologs) => (Toplevel.theory o fold (add_modl_prolog target)) prologs)
  1679   )
  1631   )
  1680 
  1632 
  1681 val _ = OuterSyntax.add_parsers [code_classP, code_instanceP, code_typeP, code_constP,
  1633 val _ = OuterSyntax.add_parsers [code_classP, code_instanceP, code_typeP, code_constP,
  1682   code_reservedP, code_modulenameP, code_moduleprologP];
  1634   code_reservedP, code_modulenameP, code_moduleprologP];
  1683 
  1635 
       
  1636 val _ = Context.add_setup (add_reserved "Haskell" "Show" #> add_reserved "Haskell" "Read")
       
  1637 
  1684 end; (*local*)
  1638 end; (*local*)
  1685 
  1639 
  1686 end; (* struct *)
  1640 end; (* struct *)