src/Pure/Tools/codegen_serializer.ML
changeset 18865 31aed965135c
parent 18853 afe45058241a
child 18885 ee8b5c36ba2b
equal deleted inserted replaced
18864:a87c0aeae92f 18865:31aed965135c
    10 sig
    10 sig
    11   type 'a pretty_syntax;
    11   type 'a pretty_syntax;
    12   type serializer = 
    12   type serializer = 
    13       string list list
    13       string list list
    14       -> OuterParse.token list ->
    14       -> OuterParse.token list ->
    15       ((string -> CodegenThingol.itype pretty_syntax option)
    15       ((string -> string option)
       
    16         * (string -> CodegenThingol.itype pretty_syntax option)
    16         * (string -> CodegenThingol.iexpr pretty_syntax option)
    17         * (string -> CodegenThingol.iexpr pretty_syntax option)
    17       -> string list option
    18       -> string list option
    18       -> CodegenThingol.module -> unit)
    19       -> CodegenThingol.module -> unit)
    19       * OuterParse.token list;
    20       * OuterParse.token list;
    20   val parse_syntax: (string -> 'b -> 'a * 'b) -> OuterParse.token list ->
    21   val parse_syntax: (string -> 'b -> 'a * 'b) -> OuterParse.token list ->
    21     ('b -> 'a pretty_syntax * 'b) * OuterParse.token list;
    22     ('b -> 'a pretty_syntax * 'b) * OuterParse.token list;
    22   val parse_targetdef: (string -> string) -> string -> string;
    23   val parse_targetdef: (string -> string) -> string -> string;
    23   val pretty_list: string -> string -> int * string -> CodegenThingol.iexpr pretty_syntax;
    24   val pretty_list: string -> string -> int * string -> CodegenThingol.iexpr pretty_syntax;
    24   val serializers: {
    25   val serializers: {
    25     ml: string * (string * string * string -> serializer),
    26     ml: string * (string * string * (string -> bool) -> serializer),
    26     haskell: string * (string -> serializer)
    27     haskell: string * (string -> serializer)
    27   }
    28   }
    28 end;
    29 end;
    29 
    30 
    30 structure CodegenSerializer: CODEGEN_SERIALIZER =
    31 structure CodegenSerializer: CODEGEN_SERIALIZER =
    55     Arg of fixity
    56     Arg of fixity
    56   | Ignore
    57   | Ignore
    57   | Pretty of Pretty.T
    58   | Pretty of Pretty.T
    58   | Quote of 'a;
    59   | Quote of 'a;
    59 
    60 
    60 type 'a pretty_syntax = (int * int) * (fixity -> (fixity -> 'a -> Pretty.T) -> 'a list -> Pretty.T);
    61 type 'a pretty_syntax = (int * int) * (fixity -> (fixity -> 'a -> Pretty.T)
       
    62   -> 'a list -> Pretty.T);
    61 
    63 
    62 fun eval_lrx L L = false
    64 fun eval_lrx L L = false
    63   | eval_lrx R R = false
    65   | eval_lrx R R = false
    64   | eval_lrx _ _ = true;
    66   | eval_lrx _ _ = true;
    65 
    67 
    82   gen_brackify (eval_fxy BR fxy_ctxt) (Pretty.breaks ps);
    84   gen_brackify (eval_fxy BR fxy_ctxt) (Pretty.breaks ps);
    83 
    85 
    84 fun brackify_infix infx fxy_ctxt ps =
    86 fun brackify_infix infx fxy_ctxt ps =
    85   gen_brackify (eval_fxy (INFX infx) fxy_ctxt) (Pretty.breaks ps);
    87   gen_brackify (eval_fxy (INFX infx) fxy_ctxt) (Pretty.breaks ps);
    86 
    88 
    87 fun from_app mk_app from_expr const_syntax fxy (f, es) =
    89 fun from_app mk_app from_expr const_syntax fxy (c, es) =
    88   let
    90   let
    89     fun mk NONE es =
    91     fun mk NONE es =
    90           brackify fxy (mk_app f es)
    92           brackify fxy (mk_app c es)
    91       | mk (SOME ((i, k), pr)) es =
    93       | mk (SOME ((i, k), pr)) es =
    92           let
    94           let
    93             val (es1, es2) = splitAt (i, es);
    95             val (es1, es2) = splitAt (k, es);
    94           in
    96           in
    95             brackify fxy (pr fxy from_expr es1 :: map (from_expr BR) es2)
    97             brackify fxy (pr fxy from_expr es1 :: map (from_expr BR) es2)
    96           end;
    98           end;
    97   in mk (const_syntax f) es end;
    99   in mk (const_syntax c) es end;
       
   100 
       
   101 val _ : (string -> iexpr list -> Pretty.T list)
       
   102                  -> (fixity -> iexpr -> Pretty.T)
       
   103                     -> (string
       
   104                         -> ((int * int)
       
   105                             * (fixity
       
   106                                -> (fixity -> iexpr -> Pretty.T)
       
   107                                   -> iexpr list -> Pretty.T)) option)
       
   108                        -> fixity -> string * iexpr list -> Pretty.T = from_app;
    98 
   109 
    99 fun fillin_mixfix fxy_this ms fxy_ctxt pr args =
   110 fun fillin_mixfix fxy_this ms fxy_ctxt pr args =
   100   let
   111   let
   101     fun fillin [] [] =
   112     fun fillin [] [] =
   102          []
   113          []
   153     | _ => error ("Malformed mixfix annotation: " ^ quote s)
   164     | _ => error ("Malformed mixfix annotation: " ^ quote s)
   154   end;
   165   end;
   155 
   166 
   156 fun parse_nonatomic_mixfix reader s ctxt =
   167 fun parse_nonatomic_mixfix reader s ctxt =
   157   case parse_mixfix reader s ctxt
   168   case parse_mixfix reader s ctxt
   158    of ([Pretty _], _) => error ("mixfix contains just one pretty element; either declare as " ^ quote atomK ^ " or consider adding a break")
   169    of ([Pretty _], _) =>
       
   170         error ("mixfix contains just one pretty element; either declare as "
       
   171           ^ quote atomK ^ " or consider adding a break")
   159     | x => x;
   172     | x => x;
   160 
   173 
   161 fun parse_syntax_proto reader = OuterParse.$$$ "(" |-- (
   174 fun parse_syntax_proto reader = OuterParse.$$$ "(" |-- (
   162        OuterParse.$$$ infixK  |-- OuterParse.nat >> (fn i => (parse_infix (INFX (i, X)), INFX (i, X)))
   175        OuterParse.$$$ infixK  |-- OuterParse.nat
   163     || OuterParse.$$$ infixlK |-- OuterParse.nat >> (fn i => (parse_infix (INFX (i, L)), INFX (i, L)))
   176         >> (fn i => (parse_infix (INFX (i, X)), INFX (i, X)))
   164     || OuterParse.$$$ infixrK |-- OuterParse.nat >> (fn i => (parse_infix (INFX (i, R)), INFX (i, R)))
   177     || OuterParse.$$$ infixlK |-- OuterParse.nat
       
   178         >> (fn i => (parse_infix (INFX (i, L)), INFX (i, L)))
       
   179     || OuterParse.$$$ infixrK |-- OuterParse.nat
       
   180         >> (fn i => (parse_infix (INFX (i, R)), INFX (i, R)))
   165     || OuterParse.$$$ atomK |-- pair (parse_mixfix reader, NOBR)
   181     || OuterParse.$$$ atomK |-- pair (parse_mixfix reader, NOBR)
   166     || pair (parse_nonatomic_mixfix reader, BR)
   182     || pair (parse_nonatomic_mixfix reader, BR)
   167   ) -- OuterParse.string --| OuterParse.$$$ ")" >> (fn ((p, fxy), s) => (p s, fxy));
   183   ) -- OuterParse.string --| OuterParse.$$$ ")" >> (fn ((p, fxy), s) => (p s, fxy));
   168 
   184 
   169 fun parse_syntax reader =
   185 fun parse_syntax reader =
   208 (* abstract serializer *)
   224 (* abstract serializer *)
   209 
   225 
   210 type serializer = 
   226 type serializer = 
   211     string list list
   227     string list list
   212     -> OuterParse.token list ->
   228     -> OuterParse.token list ->
   213     ((string -> CodegenThingol.itype pretty_syntax option)
   229     ((string -> string option)
       
   230       * (string -> CodegenThingol.itype pretty_syntax option)
   214       * (string -> CodegenThingol.iexpr pretty_syntax option)
   231       * (string -> CodegenThingol.iexpr pretty_syntax option)
   215     -> string list option
   232     -> string list option
   216     -> CodegenThingol.module -> unit)
   233     -> CodegenThingol.module -> unit)
   217     * OuterParse.token list;
   234     * OuterParse.token list;
   218 
   235 
   224    of NONE => error ("no primitive definition for " ^ quote name)
   241    of NONE => error ("no primitive definition for " ^ quote name)
   225     | SOME ps => (Pretty.block o map pr) ps
   242     | SOME ps => (Pretty.block o map pr) ps
   226   end;
   243   end;
   227 
   244 
   228 fun abstract_serializer (target, nspgrp) name_root (from_defs, from_module, validator)
   245 fun abstract_serializer (target, nspgrp) name_root (from_defs, from_module, validator)
   229   postprocess preprocess (tyco_syntax, const_syntax) select module =
   246     postprocess preprocess (class_syntax : string -> string option, tyco_syntax, const_syntax)
       
   247     select module =
   230   let
   248   let
   231     fun from_prim (name, prim) =
   249     fun from_prim (name, prim) =
   232       case AList.lookup (op = : string * string -> bool) prim target
   250       case AList.lookup (op = : string * string -> bool) prim target
   233        of NONE => error ("no primitive definition for " ^ quote name)
   251        of NONE => error ("no primitive definition for " ^ quote name)
   234         | SOME p => p;
   252         | SOME p => p;
   240     |> (if is_some select then (partof o the) select else I)
   258     |> (if is_some select then (partof o the) select else I)
   241     |> tap (Pretty.writeln o pretty_deps)
   259     |> tap (Pretty.writeln o pretty_deps)
   242     |> debug 3 (fn _ => "preprocessing...")
   260     |> debug 3 (fn _ => "preprocessing...")
   243     |> preprocess
   261     |> preprocess
   244     |> debug 3 (fn _ => "serializing...")
   262     |> debug 3 (fn _ => "serializing...")
   245     |> serialize (from_defs (from_prim, (tyco_syntax, const_syntax)))
   263     |> serialize (from_defs (from_prim, (class_syntax, tyco_syntax, const_syntax)))
   246          from_module' validator nspgrp name_root
   264          from_module' validator nspgrp name_root
   247     |> K ()
   265     |> K ()
   248   end;
   266   end;
   249 
   267 
   250 fun abstract_validator keywords name =
   268 fun abstract_validator keywords name =
   306 
   324 
   307 (* list serializer *)
   325 (* list serializer *)
   308 
   326 
   309 fun pretty_list thingol_nil thingol_cons (target_pred, target_cons) =
   327 fun pretty_list thingol_nil thingol_cons (target_pred, target_cons) =
   310   let
   328   let
   311     fun dest_cons (IApp (IApp (IConst (c, _), e1), e2)) =
   329     fun dest_cons (IApp (IApp (IConst ((c, _), _), e1), e2)) =
   312           if c = thingol_cons
   330           if c = thingol_cons
   313           then SOME (e1, e2)
   331           then SOME (e1, e2)
   314           else NONE
   332           else NONE
   315       | dest_cons  _ = NONE;
   333       | dest_cons  _ = NONE;
   316     fun pretty_default fxy pr e1 e2 =
   334     fun pretty_default fxy pr e1 e2 =
   319         str target_cons,
   337         str target_cons,
   320         pr (INFX (target_pred, R)) e2
   338         pr (INFX (target_pred, R)) e2
   321       ];
   339       ];
   322     fun pretty_compact fxy pr [e1, e2] =
   340     fun pretty_compact fxy pr [e1, e2] =
   323       case unfoldr dest_cons e2
   341       case unfoldr dest_cons e2
   324        of (es, IConst (c, _)) =>
   342        of (es, IConst ((c, _), _)) =>
   325             if c = thingol_nil
   343             if c = thingol_nil
   326             then Pretty.enum "," "[" "]" (map (pr NOBR) (e1::es))
   344             then Pretty.enum "," "[" "]" (map (pr NOBR) (e1::es))
   327             else pretty_default fxy pr e1 e2
   345             else pretty_default fxy pr e1 e2
   328         | _ => pretty_default fxy pr e1 e2;
   346         | _ => pretty_default fxy pr e1 e2;
   329   in ((2, 2), pretty_compact) end;
   347   in ((2, 2), pretty_compact) end;
   333 (** ML serializer **)
   351 (** ML serializer **)
   334 
   352 
   335 local
   353 local
   336 
   354 
   337 fun ml_from_defs (is_cons, needs_type)
   355 fun ml_from_defs (is_cons, needs_type)
   338   (from_prim, (tyco_syntax, const_syntax)) resolv defs =
   356     (from_prim, (_, tyco_syntax, const_syntax)) resolv defs =
   339   let
   357   let
   340     fun chunk_defs ps =
   358     fun chunk_defs ps =
   341       let
   359       let
   342         val (p_init, p_last) = split_last ps
   360         val (p_init, p_last) = split_last ps
   343       in
   361       in
   344         Pretty.chunks (p_init @ [Pretty.block ([p_last, str ";"])])
   362         Pretty.chunks (p_init @ [Pretty.block ([p_last, str ";"])])
   345     end;
       
   346     fun ml_from_label s =
       
   347       let
       
   348         val s' = NameSpace.unpack s;
       
   349       in
       
   350         NameSpace.pack (Library.drop (length s' - 2, s'))
       
   351         |> translate_string (fn "_" => "__" | "." => "_" | c => c)
       
   352       end;
   363       end;
       
   364     val ml_from_label =
       
   365       resolv
       
   366       #> NameSpace.base
       
   367       #> translate_string (fn "_" => "__" | "." => "_" | c => c)
       
   368       #> str;
   353     fun ml_from_type fxy (IType (tyco, tys)) =
   369     fun ml_from_type fxy (IType (tyco, tys)) =
   354           (case tyco_syntax tyco
   370           (case tyco_syntax tyco
   355            of NONE =>
   371            of NONE =>
   356                 let
   372                 let
   357                   val f' = (str o resolv) tyco
   373                   val f' = (str o resolv) tyco
   361                   | (ps as _::_) => Pretty.block [Pretty.list "(" ")" ps, Pretty.brk 1, f']
   377                   | (ps as _::_) => Pretty.block [Pretty.list "(" ")" ps, Pretty.brk 1, f']
   362                 end
   378                 end
   363             | SOME ((i, k), pr) =>
   379             | SOME ((i, k), pr) =>
   364                 if not (i <= length tys andalso length tys <= k)
   380                 if not (i <= length tys andalso length tys <= k)
   365                 then error ("number of argument mismatch in customary serialization: "
   381                 then error ("number of argument mismatch in customary serialization: "
   366                   ^ (string_of_int o length) tys ^ " given, " ^ string_of_int i ^ " to " ^ string_of_int k
   382                   ^ (string_of_int o length) tys ^ " given, "
       
   383                   ^ string_of_int i ^ " to " ^ string_of_int k
   367                   ^ " expected")
   384                   ^ " expected")
   368                 else pr fxy ml_from_type tys)
   385                 else pr fxy ml_from_type tys)
   369       | ml_from_type fxy (IFun (t1, t2)) =
   386       | ml_from_type fxy (IFun (t1, t2)) =
   370           let
   387           let
   371             val brackify = gen_brackify
   388             val brackify = gen_brackify
   377               ml_from_type (INFX (1, X)) t1,
   394               ml_from_type (INFX (1, X)) t1,
   378               str "->",
   395               str "->",
   379               ml_from_type (INFX (1, R)) t2
   396               ml_from_type (INFX (1, R)) t2
   380             ]
   397             ]
   381           end
   398           end
   382       | ml_from_type _ (IVarT (v, [])) =
   399       | ml_from_type _ (IVarT (v, _)) =
   383           str ("'" ^ v)
   400           str ("'" ^ v)
   384       | ml_from_type _ (IVarT (_, sort)) =
       
   385           "cannot serialize sort constrained type variable to ML: " ^ commas sort |> error
       
   386       | ml_from_type _ (IDictT fs) =
   401       | ml_from_type _ (IDictT fs) =
   387           Pretty.enum "," "{" "}" (
   402           Pretty.enum "," "{" "}" (
   388             map (fn (f, ty) =>
   403             map (fn (f, ty) =>
   389               Pretty.block [str (ml_from_label f ^ ": "), ml_from_type NOBR ty]) fs
   404               Pretty.block [ml_from_label f, str ": ", ml_from_type NOBR ty]) fs
   390           );
   405           );
   391     fun ml_from_pat fxy (ICons ((f, ps), ty)) =
   406     fun ml_from_expr sortctxt fxy (e as IApp (e1, e2)) =
   392           (case const_syntax f
   407           (case unfold_const_app e
   393            of NONE => if length ps <= 1
   408            of SOME x => ml_from_app sortctxt fxy x
   394                 then
   409             | NONE =>
   395                   ps
       
   396                   |> map (ml_from_pat BR)
       
   397                   |> cons ((str o resolv) f)
       
   398                   |> brackify fxy
       
   399                 else
       
   400                   ps
       
   401                   |> map (ml_from_pat BR)
       
   402                   |> Pretty.enum "," "(" ")"
       
   403                   |> single
       
   404                   |> cons ((str o resolv) f)
       
   405                   |> brackify fxy
       
   406             | SOME ((i, k), pr) =>
       
   407                 if not (i <= length ps andalso length ps <= k)
       
   408                 then error ("number of argument mismatch in customary serialization: "
       
   409                   ^ (string_of_int o length) ps ^ " given, " ^ string_of_int i ^ " to " ^ string_of_int k
       
   410                   ^ " expected")
       
   411                 else pr fxy ml_from_expr (map iexpr_of_ipat ps))
       
   412       | ml_from_pat fxy (IVarP (v, ty)) =
       
   413           if needs_type ty
       
   414           then
       
   415             brackify fxy [
       
   416               str v,
       
   417               str ":",
       
   418               ml_from_type NOBR ty
       
   419             ]
       
   420           else
       
   421             str v
       
   422     and ml_from_expr fxy (e as IApp (e1, e2)) =
       
   423           (case (unfold_app e)
       
   424            of (e as (IConst (f, _)), es) =>
       
   425                 ml_from_app fxy (f, es)
       
   426             | _ =>
       
   427                 brackify fxy [
   410                 brackify fxy [
   428                   ml_from_expr NOBR e1,
   411                   ml_from_expr sortctxt NOBR e1,
   429                   ml_from_expr BR e2
   412                   ml_from_expr sortctxt BR e2
   430                 ])
   413                 ])
   431       | ml_from_expr fxy (e as IConst (f, _)) =
   414       | ml_from_expr sortctxt fxy (e as IConst x) =
   432           ml_from_app fxy (f, [])
   415           ml_from_app sortctxt fxy (x, [])
   433       | ml_from_expr fxy (IVarE (v, _)) =
   416       | ml_from_expr sortctxt fxy (IVarE (v, _)) =
   434           str v
   417           str v
   435       | ml_from_expr fxy (IAbs ((v, _), e)) =
   418       | ml_from_expr sortctxt fxy (IAbs ((v, _), e)) =
   436           brackify fxy [
   419           brackify fxy [
   437             str ("fn " ^ v ^ " =>"),
   420             str ("fn " ^ v ^ " =>"),
   438             ml_from_expr NOBR e
   421             ml_from_expr sortctxt NOBR e
   439           ]
   422           ]
   440       | ml_from_expr fxy (e as ICase (_, [_])) =
   423       | ml_from_expr sortctxt fxy (e as ICase (_, [_])) =
   441           let
   424           let
   442             val (ps, e) = unfold_let e;
   425             val (ps, e) = unfold_let e;
   443             fun mk_val (p, e) = Pretty.block [
   426             fun mk_val (p, e) = Pretty.block [
   444                 str "val ",
   427                 str "val ",
   445                 ml_from_pat fxy p,
   428                 ml_from_expr sortctxt fxy p,
   446                 str " =",
   429                 str " =",
   447                 Pretty.brk 1,
   430                 Pretty.brk 1,
   448                 ml_from_expr NOBR e,
   431                 ml_from_expr sortctxt NOBR e,
   449                 str ";"
   432                 str ";"
   450               ]
   433               ]
   451           in Pretty.chunks [
   434           in Pretty.chunks [
   452             [str ("let"), Pretty.fbrk, map mk_val ps |> Pretty.chunks] |> Pretty.block,
   435             [str ("let"), Pretty.fbrk, map mk_val ps |> Pretty.chunks] |> Pretty.block,
   453             [str ("in"), Pretty.fbrk, ml_from_expr NOBR e] |> Pretty.block,
   436             [str ("in"), Pretty.fbrk, ml_from_expr sortctxt NOBR e] |> Pretty.block,
   454             str ("end")
   437             str ("end")
   455           ] end
   438           ] end
   456       | ml_from_expr fxy (ICase (e, c::cs)) =
   439       | ml_from_expr sortctxt fxy (ICase (e, c::cs)) =
   457           let
   440           let
   458             fun mk_clause definer (p, e) =
   441             fun mk_clause definer (p, e) =
   459               Pretty.block [
   442               Pretty.block [
   460                 str definer,
   443                 str definer,
   461                 ml_from_pat NOBR p,
   444                 ml_from_expr sortctxt NOBR p,
   462                 str " =>",
   445                 str " =>",
   463                 Pretty.brk 1,
   446                 Pretty.brk 1,
   464                 ml_from_expr NOBR e
   447                 ml_from_expr sortctxt NOBR e
   465               ]
   448               ]
   466           in brackify fxy (
   449           in brackify fxy (
   467             str "case"
   450             str "case"
   468             :: ml_from_expr NOBR e
   451             :: ml_from_expr sortctxt NOBR e
   469             :: mk_clause "of " c
   452             :: mk_clause "of " c
   470             :: map (mk_clause "| ") cs
   453             :: map (mk_clause "| ") cs
   471           ) end
   454           ) end
   472       | ml_from_expr fxy (IInst _) =
   455       | ml_from_expr sortctxt fxy (IDictE fs) =
   473           error "cannot serialize poly instant to ML"
       
   474       | ml_from_expr fxy (IDictE fs) =
       
   475           Pretty.enum "," "{" "}" (
   456           Pretty.enum "," "{" "}" (
   476             map (fn (f, e) =>
   457             map (fn (f, e) =>
   477               Pretty.block [str (ml_from_label f ^ " = "), ml_from_expr NOBR e]) fs
   458               Pretty.block [ml_from_label f, str " = ", ml_from_expr sortctxt NOBR e]) fs
   478           )
   459           )
   479       | ml_from_expr fxy (ILookup ([], v)) =
   460       | ml_from_expr sortctxt fxy (ILookup ([], v)) =
   480           str v
   461           str v
   481       | ml_from_expr fxy (ILookup ([l], v)) =
   462       | ml_from_expr sortctxt fxy (ILookup ([l], v)) =
   482           brackify fxy [
   463           brackify fxy [
   483             str ("#" ^ (ml_from_label l)),
   464             str "#",
       
   465             ml_from_label l,
   484             str v
   466             str v
   485           ]
   467           ]
   486       | ml_from_expr fxy (ILookup (ls, v)) =
   468       (*| ml_from_expr sortctxt fxy (ILookup (ls, v)) =
   487           brackify fxy [
   469           brackify fxy [
   488             str ("("
   470             str ("("
   489               ^ (ls |> map ((fn s => "#" ^ s) o ml_from_label) |> foldr1 (fn (l, e) => l ^ " o " ^ e))
   471               ^ (ls |> map ((fn s => "#" ^ s) o ml_from_label) |> foldr1 (fn (l, e) => l ^ " o " ^ e))
   490               ^ ")"),
   472               ^ ")"),
   491             str v
   473             str v
   492           ]
   474           ]*)
   493       | ml_from_expr _ e =
   475       | ml_from_expr _ _ e =
   494           error ("dubious expression: " ^ (Pretty.output o pretty_iexpr) e)
   476           error ("dubious expression: " ^ (Pretty.output o pretty_iexpr) e)
   495     and ml_mk_app f es =
   477     and ml_mk_app sortctxt f es =
   496       if is_cons f andalso length es > 1
   478       if is_cons f andalso length es > 1
   497       then
   479       then
   498         [(str o resolv) f, Pretty.enum " *" "(" ")" (map (ml_from_expr BR) es)]
   480         [(str o resolv) f, Pretty.enum " *" "(" ")" (map (ml_from_expr sortctxt BR) es)]
   499       else
   481       else
   500         (str o resolv) f :: map (ml_from_expr BR) es
   482         (str o resolv) f :: map (ml_from_expr sortctxt BR) es
   501     and ml_from_app fxy =
   483     and ml_from_app sortctxt fxy (((f, _), ls), es) =
   502       from_app ml_mk_app ml_from_expr const_syntax fxy;
   484       let
       
   485         val _ = ();
       
   486       in
       
   487         from_app (ml_mk_app sortctxt) (ml_from_expr sortctxt) const_syntax fxy (f, es)
       
   488       end;
   503     fun ml_from_funs (ds as d::ds_tl) =
   489     fun ml_from_funs (ds as d::ds_tl) =
   504       let
   490       let
   505         fun mk_definer [] = "val"
   491         fun mk_definer [] = "val"
   506           | mk_definer _ = "fun";
   492           | mk_definer _ = "fun";
   507         fun check_args (_, Fun ((pats, _)::_, _)) NONE =
   493         fun check_args (_, Fun ((pats, _)::_, _)) NONE =
   511               then SOME definer
   497               then SOME definer
   512               else error ("mixing simultaneous vals and funs not implemented")
   498               else error ("mixing simultaneous vals and funs not implemented")
   513           | check_args _ _ =
   499           | check_args _ _ =
   514               error ("function definition block containing other definitions than functions")
   500               error ("function definition block containing other definitions than functions")
   515         val definer = the (fold check_args ds NONE);
   501         val definer = the (fold check_args ds NONE);
   516         fun mk_eq definer f ty (pats, expr) =
   502         fun mk_eq definer sortctxt f ty (pats, expr) =
   517           let
   503           let
   518             val lhs = [str (definer ^ " " ^ f)]
   504             val lhs = [str (definer ^ " " ^ f)]
   519                        @ (if null pats
   505                        @ (if null pats
   520                           then [str ":", ml_from_type NOBR ty]
   506                           then [str ":", ml_from_type NOBR ty]
   521                           else map (ml_from_pat BR) pats)
   507                           else map (ml_from_expr sortctxt BR) pats)
   522             val rhs = [str "=", ml_from_expr NOBR expr]
   508             val rhs = [str "=", ml_from_expr sortctxt NOBR expr]
   523           in
   509           in
   524             Pretty.block (separate (Pretty.brk 1) (lhs @ rhs))
   510             Pretty.block (separate (Pretty.brk 1) (lhs @ rhs))
   525           end
   511           end
   526         fun mk_fun definer (f, Fun (eqs as eq::eq_tl, (_, ty))) =
   512         fun mk_fun definer (f, Fun (eqs as eq::eq_tl, (sortctxt , ty))) =
   527           let
   513           let
   528             val (pats_hd::pats_tl) = (fst o split_list) eqs;
   514             val (pats_hd::pats_tl) = (fst o split_list) eqs;
   529             val shift = if null eq_tl then I else map (Pretty.block o single);
   515             val shift = if null eq_tl then I else map (Pretty.block o single);
   530           in (Pretty.block o Pretty.fbreaks o shift) (
   516           in (Pretty.block o Pretty.fbreaks o shift) (
   531                mk_eq definer f ty eq
   517                mk_eq definer sortctxt f ty eq
   532                :: map (mk_eq "|" f ty) eq_tl
   518                :: map (mk_eq "|" sortctxt f ty) eq_tl
   533              )
   519              )
   534           end;
   520           end;
   535       in
   521       in
   536         chunk_defs (
   522         chunk_defs (
   537           mk_fun definer d
   523           mk_fun definer d
   541     fun ml_from_datatypes defs =
   527     fun ml_from_datatypes defs =
   542       let
   528       let
   543         val defs' = List.mapPartial
   529         val defs' = List.mapPartial
   544           (fn (name, Datatype info) => SOME (name, info)
   530           (fn (name, Datatype info) => SOME (name, info)
   545             | (name, Datatypecons _) => NONE
   531             | (name, Datatypecons _) => NONE
   546             | (name, def) => error ("datatype block containing illegal def: " ^ (Pretty.output o pretty_def) def)
   532             | (name, def) => error ("datatype block containing illegal def: "
       
   533                 ^ (Pretty.output o pretty_def) def)
   547           ) defs
   534           ) defs
   548         fun mk_cons (co, []) =
   535         fun mk_cons (co, []) =
   549               str (resolv co)
   536               str (resolv co)
   550           | mk_cons (co, tys) =
   537           | mk_cons (co, tys) =
   551               Pretty.block (
   538               Pretty.block (
   552                 str (resolv co)
   539                 str (resolv co)
   553                 :: str " of"
   540                 :: str " of"
   554                 :: Pretty.brk 1
   541                 :: Pretty.brk 1
   555                 :: separate (Pretty.block [str " *", Pretty.brk 1]) (map (ml_from_type NOBR) tys)
   542                 :: separate (Pretty.block [str " *", Pretty.brk 1])
       
   543                      (map (ml_from_type NOBR) tys)
   556               )
   544               )
   557         fun mk_datatype definer (t, ((vs, cs), _)) =
   545         fun mk_datatype definer (t, ((vs, cs), _)) =
   558           Pretty.block (
   546           Pretty.block (
   559             str definer
   547             str definer
   560             :: ml_from_type NOBR (t `%% map IVarT vs)
   548             :: ml_from_type NOBR (t `%% map IVarT vs)
   574     fun ml_from_def (name, Undef) =
   562     fun ml_from_def (name, Undef) =
   575           error ("empty definition during serialization: " ^ quote name)
   563           error ("empty definition during serialization: " ^ quote name)
   576       | ml_from_def (name, Prim prim) =
   564       | ml_from_def (name, Prim prim) =
   577           from_prim (name, prim)
   565           from_prim (name, prim)
   578       | ml_from_def (name, Typesyn (vs, ty)) =
   566       | ml_from_def (name, Typesyn (vs, ty)) =
   579         (map (fn (vname, []) => () | _ => error "can't serialize sort constrained type declaration to ML") vs;
   567         (map (fn (vname, []) => () | _ =>
       
   568             error "can't serialize sort constrained type declaration to ML") vs;
   580           Pretty.block [
   569           Pretty.block [
   581             str "type ",
   570             str "type ",
   582             ml_from_type NOBR (name `%% map IVarT vs),
   571             ml_from_type NOBR (name `%% map IVarT vs),
   583             str " =",
   572             str " =",
   584             Pretty.brk 1,
   573             Pretty.brk 1,
   585             ml_from_type NOBR ty,
   574             ml_from_type NOBR ty,
   586             str ";"
   575             str ";"
   587             ]
   576             ]
   588           ) |> SOME
   577           ) |> SOME
   589       | ml_from_def (name, Class _) =
   578       | ml_from_def (name, Class ((supclasses, (v, membrs)), _)) =
   590           error ("can't serialize class declaration " ^ quote name ^ " to ML")
   579           let
       
   580             val pv = str ("'" ^ v);
       
   581             fun from_supclass class =
       
   582               Pretty.block [
       
   583                 ml_from_label class,
       
   584                 str ":",
       
   585                 Pretty.brk 1,
       
   586                 pv,
       
   587                 Pretty.brk 1,
       
   588                 (str o resolv) class
       
   589               ]
       
   590             fun from_membr (m, (_, ty)) =
       
   591               Pretty.block [
       
   592                 ml_from_label m,
       
   593                 str ":",
       
   594                 Pretty.brk 1,
       
   595                 ml_from_type NOBR ty
       
   596               ]
       
   597           in
       
   598             Pretty.block [
       
   599               str "type",
       
   600               Pretty.brk 1,
       
   601               pv,
       
   602               Pretty.brk 1,
       
   603               (str o resolv) name,
       
   604               Pretty.brk 1,
       
   605               str "=",
       
   606               Pretty.brk 1,
       
   607               Pretty.enum "," "{" "};" (
       
   608                 map from_supclass supclasses @ map from_membr membrs
       
   609               )
       
   610             ] |> SOME
       
   611           end
   591       | ml_from_def (_, Classmember _) =
   612       | ml_from_def (_, Classmember _) =
   592           NONE
   613           NONE
   593       | ml_from_def (name, Classinst _) =
   614       | ml_from_def (name, Classinst (((class, (tyco, arity)), suparities), memdefs)) =
   594           error ("can't serialize instance declaration " ^ quote name ^ " to ML")
   615           let
       
   616             val definer = if null arity then "val" else "fun"
       
   617             fun from_supclass (supclass, (inst, ls)) = str "<DUMMY>"
       
   618             fun from_memdef (m, def) =
       
   619               ((the o ml_from_funs) [(m, Fun def)], Pretty.block [
       
   620                 (str o resolv) m,
       
   621                 Pretty.brk 1,
       
   622                 str "=",
       
   623                 Pretty.brk 1,
       
   624                 (str o resolv) m
       
   625               ])
       
   626             fun mk_memdefs supclassexprs [] =
       
   627                   Pretty.enum "," "{" "};" (
       
   628                     supclassexprs
       
   629                   )
       
   630               | mk_memdefs supclassexprs memdefs =
       
   631                   let
       
   632                     val (defs, assigns) = (split_list o map from_memdef) memdefs;
       
   633                   in
       
   634                     Pretty.chunks [
       
   635                       [str ("let"), Pretty.fbrk, defs |> Pretty.chunks]
       
   636                         |> Pretty.block,
       
   637                       [str ("in "), Pretty.enum "," "{" "};" (supclassexprs @ assigns)]
       
   638                         |> Pretty.block
       
   639                     ] 
       
   640                   end;
       
   641           in
       
   642             Pretty.block [
       
   643               (Pretty.block o Pretty.breaks) (
       
   644                 str definer
       
   645                 :: str name
       
   646                 :: map (str o fst) arity
       
   647               ),
       
   648               Pretty.brk 1,
       
   649               str "=",
       
   650               Pretty.brk 1,
       
   651               mk_memdefs (map from_supclass suparities) memdefs
       
   652             ] |> SOME
       
   653           end;
   595   in case defs
   654   in case defs
   596    of (_, Fun _)::_ => ml_from_funs defs
   655    of (_, Fun _)::_ => ml_from_funs defs
   597     | (_, Datatypecons _)::_ => ml_from_datatypes defs
   656     | (_, Datatypecons _)::_ => ml_from_datatypes defs
   598     | (_, Datatype _)::_ => ml_from_datatypes defs
   657     | (_, Datatype _)::_ => ml_from_datatypes defs
   599     | [def] => ml_from_def def
   658     | [def] => ml_from_def def
   600   end;
   659   end;
   601 
   660 
   602 in
   661 in
   603 
   662 
   604 fun ml_from_thingol target (nsp_dtcon, nsp_class, int_tyco) nspgrp =
   663 fun ml_from_thingol target (nsp_dtcon, nsp_class, is_int_tyco) nspgrp =
   605   let
   664   let
   606     val reserved_ml = ThmDatabase.ml_reserved @ [
   665     val reserved_ml = ThmDatabase.ml_reserved @ [
   607       "bool", "int", "list", "true", "false"
   666       "bool", "int", "list", "true", "false", "o"
   608     ];
   667     ];
   609     fun ml_from_module _ ((_, name), ps) =
   668     fun ml_from_module _ ((_, name), ps) =
   610       Pretty.chunks ([
   669       Pretty.chunks ([
   611         str ("structure " ^ name ^ " = "),
   670         str ("structure " ^ name ^ " = "),
   612         str "struct",
   671         str "struct",
   615         str "",
   674         str "",
   616         str ("end; (* struct " ^ name ^ " *)")
   675         str ("end; (* struct " ^ name ^ " *)")
   617       ]);
   676       ]);
   618     fun needs_type (IType (tyco, _)) =
   677     fun needs_type (IType (tyco, _)) =
   619           has_nsp tyco nsp_class
   678           has_nsp tyco nsp_class
   620           orelse tyco = int_tyco
   679           orelse is_int_tyco tyco
   621       | needs_type (IDictT _) =
   680       | needs_type (IDictT _) =
   622           true
   681           true
   623       | needs_type _ =
   682       | needs_type _ =
   624           false;
   683           false;
   625     fun is_cons c = has_nsp c nsp_dtcon;
   684     fun is_cons c = has_nsp c nsp_dtcon;
   639       module
   698       module
   640       |> tap (Pretty.writeln o pretty_deps)
   699       |> tap (Pretty.writeln o pretty_deps)
   641       |> debug 3 (fn _ => "eta-expanding...")
   700       |> debug 3 (fn _ => "eta-expanding...")
   642       |> eta_expand (eta_expander module const_syntax)
   701       |> eta_expand (eta_expander module const_syntax)
   643       |> debug 3 (fn _ => "eta-expanding polydefs...")
   702       |> debug 3 (fn _ => "eta-expanding polydefs...")
   644       |> eta_expand_poly
   703       |> eta_expand_poly;
   645       |> debug 3 (fn _ => "eliminating classes...")
       
   646       |> eliminate_classes;
       
   647     val parse_multi =
   704     val parse_multi =
   648       OuterParse.name
   705       OuterParse.name
   649       #-> (fn "dir" => 
   706       #-> (fn "dir" => 
   650                parse_multi_file
   707                parse_multi_file
   651                  (K o SOME o str o suffix ";" o prefix "val _ = use "
   708                  (K o SOME o str o suffix ";" o prefix "val _ = use "
   653             | _ => Scan.fail ());
   710             | _ => Scan.fail ());
   654   in
   711   in
   655     (parse_multi
   712     (parse_multi
   656      || parse_internal serializer
   713      || parse_internal serializer
   657      || parse_single_file serializer)
   714      || parse_single_file serializer)
   658     >> (fn seri => fn (tyco_syntax, const_syntax) => seri 
   715     >> (fn seri => fn (class_syntax, tyco_syntax, const_syntax) => seri 
   659          (preprocess const_syntax) (tyco_syntax, const_syntax))
   716          (preprocess const_syntax) (class_syntax, tyco_syntax, const_syntax))
   660   end;
   717   end;
   661 
   718 
   662 end; (* local *)
   719 end; (* local *)
   663 
   720 
   664 local
   721 local
   665 
   722 
   666 fun hs_from_defs is_cons (from_prim, (tyco_syntax, const_syntax)) resolv defs =
   723 fun hs_from_defs is_cons (from_prim, (class_syntax, tyco_syntax, const_syntax))
       
   724     resolv defs =
   667   let
   725   let
   668     fun upper_first s =
   726     fun upper_first s =
   669       let
   727       let
   670         val (pr, b) = split_last (NameSpace.unpack s);
   728         val (pr, b) = split_last (NameSpace.unpack s);
   671         val (c::cs) = String.explode b;
   729         val (c::cs) = String.explode b;
   689         else (lower_first o resolv) f
   747         else (lower_first o resolv) f
   690       else
   748       else
   691         f;
   749         f;
   692     fun hs_from_sctxt vs =
   750     fun hs_from_sctxt vs =
   693       let
   751       let
       
   752         fun from_class cls =
       
   753          case class_syntax cls
       
   754           of NONE => (upper_first o resolv) cls
       
   755            | SOME cls => cls
   694         fun from_sctxt [] = str ""
   756         fun from_sctxt [] = str ""
   695           | from_sctxt vs =
   757           | from_sctxt vs =
   696               vs
   758               vs
   697               |> map (fn (v, cls) => str ((upper_first o resolv) cls ^ " " ^ lower_first v))
   759               |> map (fn (v, cls) => str (from_class cls ^ " " ^ lower_first v))
   698               |> Pretty.enum "," "(" ")"
   760               |> Pretty.enum "," "(" ")"
   699               |> (fn p => Pretty.block [p, str " => "])
   761               |> (fn p => Pretty.block [p, str " => "])
   700       in 
   762       in 
   701         vs
   763         vs
   702         |> map (fn (v, sort) => map (pair v) sort)
   764         |> map (fn (v, sort) => map (pair v) sort)
   703         |> Library.flat
   765         |> Library.flat
   704         |> from_sctxt
   766         |> from_sctxt
   705       end;
   767       end;
   706     fun hs_from_type fxy ty =
   768     fun hs_from_type fxy (IType (tyco, tys)) =
   707       let
   769           (case tyco_syntax tyco
   708         fun from_itype fxy (IType (tyco, tys)) sctxt =
       
   709               (case tyco_syntax tyco
       
   710                of NONE =>
       
   711                     sctxt
       
   712                     |> fold_map (from_itype BR) tys
       
   713                     |-> (fn tyargs => pair (brackify fxy ((str o upper_first o resolv) tyco :: tyargs)))
       
   714                 | SOME ((i, k), pr) =>
       
   715                     if not (i <= length tys andalso length tys <= k)
       
   716                     then error ("number of argument mismatch in customary serialization: "
       
   717                       ^ (string_of_int o length) tys ^ " given, " ^ string_of_int i ^ " to " ^ string_of_int k
       
   718                       ^ " expected")
       
   719                     else (pr fxy hs_from_type tys, sctxt))
       
   720           | from_itype fxy (IFun (t1, t2)) sctxt =
       
   721               sctxt
       
   722               |> from_itype (INFX (1, X)) t1
       
   723               ||>> from_itype (INFX (1, R)) t2
       
   724               |-> (fn (p1, p2) => pair (
       
   725                     brackify_infix (1, R) fxy [
       
   726                       p1,
       
   727                       str "->",
       
   728                       p2
       
   729                     ]
       
   730                   ))
       
   731           | from_itype fxy (IVarT (v, [])) sctxt =
       
   732               sctxt
       
   733               |> pair ((str o lower_first) v)
       
   734           | from_itype fxy (IVarT (v, sort)) sctxt =
       
   735               sctxt
       
   736               |> AList.default (op =) (v, [])
       
   737               |> AList.map_entry (op =) v (fold (insert (op =)) sort)
       
   738               |> pair ((str o lower_first) v)
       
   739           | from_itype fxy (IDictT _) _ =
       
   740               error "cannot serialize dictionary type to hs"
       
   741       in
       
   742         []
       
   743         |> from_itype fxy ty
       
   744         ||> hs_from_sctxt
       
   745         |> (fn (pty, pctxt) => Pretty.block [pctxt, pty])
       
   746       end;
       
   747     fun hs_from_pat fxy (ICons ((f, ps), _)) =
       
   748           (case const_syntax f
       
   749            of NONE =>
   770            of NONE =>
   750                 ps
   771                 brackify fxy ((str o upper_first o resolv) tyco :: map (hs_from_type BR) tys)
   751                 |> map (hs_from_pat BR)
       
   752                 |> cons ((str o resolv_const) f)
       
   753                 |> brackify fxy
       
   754             | SOME ((i, k), pr) =>
   772             | SOME ((i, k), pr) =>
   755                 if not (i <= length ps andalso length ps <= k)
   773                 if not (i <= length tys andalso length tys <= k)
   756                 then error ("number of argument mismatch in customary serialization: "
   774                 then error ("number of argument mismatch in customary serialization: "
   757                   ^ (string_of_int o length) ps ^ " given, " ^ string_of_int i ^ " to " ^ string_of_int k
   775                   ^ (string_of_int o length) tys ^ " given, "
       
   776                   ^ string_of_int i ^ " to " ^ string_of_int k
   758                   ^ " expected")
   777                   ^ " expected")
   759                 else pr fxy hs_from_expr (map iexpr_of_ipat ps))
   778                 else pr fxy hs_from_type tys)
   760       | hs_from_pat fxy (IVarP (v, _)) =
   779       | hs_from_type fxy (IFun (t1, t2)) =
       
   780           brackify_infix (1, R) fxy [
       
   781             hs_from_type (INFX (1, X)) t1,
       
   782             str "->",
       
   783             hs_from_type (INFX (1, R)) t2
       
   784           ]
       
   785       | hs_from_type fxy (IVarT (v, _)) =
   761           (str o lower_first) v
   786           (str o lower_first) v
   762     and hs_from_expr fxy (e as IApp (e1, e2)) =
   787       | hs_from_type fxy (IDictT _) =
   763           (case (unfold_app e)
   788           error "can't serialize dictionary type to hs";
   764            of (e as (IConst (f, _)), es) =>
   789     fun hs_from_sctxt_type (sctxt, ty) =
   765                 hs_from_app fxy (f, es)
   790       Pretty.block [hs_from_sctxt sctxt, hs_from_type NOBR ty]
       
   791     fun hs_from_expr fxy (e as IApp (e1, e2)) =
       
   792           (case unfold_const_app e
       
   793            of SOME x => hs_from_app fxy x
   766             | _ =>
   794             | _ =>
   767                 brackify fxy [
   795                 brackify fxy [
   768                   hs_from_expr NOBR e1,
   796                   hs_from_expr NOBR e1,
   769                   hs_from_expr BR e2
   797                   hs_from_expr BR e2
   770                 ])
   798                 ])
   771       | hs_from_expr fxy (e as IConst (f, _)) =
   799       | hs_from_expr fxy (e as IConst x) =
   772           hs_from_app fxy (f, [])
   800           hs_from_app fxy (x, [])
   773       | hs_from_expr fxy (IVarE (v, _)) =
   801       | hs_from_expr fxy (IVarE (v, _)) =
   774           (str o lower_first) v
   802           (str o lower_first) v
   775       | hs_from_expr fxy (e as IAbs _) =
   803       | hs_from_expr fxy (e as IAbs _) =
   776           let
   804           let
   777             val (vs, body) = unfold_abs e
   805             val (vs, body) = unfold_abs e
   785           end
   813           end
   786       | hs_from_expr fxy (e as ICase (_, [_])) =
   814       | hs_from_expr fxy (e as ICase (_, [_])) =
   787           let
   815           let
   788             val (ps, body) = unfold_let e;
   816             val (ps, body) = unfold_let e;
   789             fun mk_bind (p, e) = Pretty.block [
   817             fun mk_bind (p, e) = Pretty.block [
   790                 hs_from_pat BR p,
   818                 hs_from_expr BR p,
   791                 str " =",
   819                 str " =",
   792                 Pretty.brk 1,
   820                 Pretty.brk 1,
   793                 hs_from_expr NOBR e
   821                 hs_from_expr NOBR e
   794               ];
   822               ];
   795           in Pretty.chunks [
   823           in Pretty.chunks [
   798           ] end
   826           ] end
   799       | hs_from_expr fxy (ICase (e, cs)) =
   827       | hs_from_expr fxy (ICase (e, cs)) =
   800           let
   828           let
   801             fun mk_clause (p, e) =
   829             fun mk_clause (p, e) =
   802               Pretty.block [
   830               Pretty.block [
   803                 hs_from_pat NOBR p,
   831                 hs_from_expr NOBR p,
   804                 str " ->",
   832                 str " ->",
   805                 Pretty.brk 1,
   833                 Pretty.brk 1,
   806                 hs_from_expr NOBR e
   834                 hs_from_expr NOBR e
   807               ]
   835               ]
   808           in Pretty.block [
   836           in Pretty.block [
   812             Pretty.brk 1,
   840             Pretty.brk 1,
   813             str "of",
   841             str "of",
   814             Pretty.fbrk,
   842             Pretty.fbrk,
   815             (Pretty.chunks o map mk_clause) cs
   843             (Pretty.chunks o map mk_clause) cs
   816           ] end
   844           ] end
   817       | hs_from_expr fxy (IInst (e, _)) =
       
   818           hs_from_expr fxy e
       
   819       | hs_from_expr fxy (IDictE _) =
   845       | hs_from_expr fxy (IDictE _) =
   820           error "cannot serialize dictionary expression to hs"
   846           error "can't serialize dictionary expression to hs"
   821       | hs_from_expr fxy (ILookup _) =
   847       | hs_from_expr fxy (ILookup _) =
   822           error "cannot serialize lookup expression to hs"
   848           error "can't serialize lookup expression to hs"
   823     and hs_mk_app f es =
   849     and hs_mk_app c es =
   824       (str o resolv_const) f :: map (hs_from_expr BR) es
   850       (str o resolv_const) c :: map (hs_from_expr BR) es
   825     and hs_from_app fxy =
   851     and hs_from_app fxy (((c, _), ls), es) =
   826       from_app hs_mk_app hs_from_expr const_syntax fxy;
   852       from_app hs_mk_app hs_from_expr const_syntax fxy (c, es);
       
   853     fun hs_from_funeqs (name, eqs) =
       
   854       let
       
   855         fun from_eq name (args, rhs) =
       
   856           Pretty.block [
       
   857             str (lower_first name),
       
   858             Pretty.block (map (fn p => Pretty.block [Pretty.brk 1, hs_from_expr BR p]) args),
       
   859             Pretty.brk 1,
       
   860             str ("="),
       
   861             Pretty.brk 1,
       
   862             hs_from_expr NOBR rhs
       
   863           ]
       
   864       in Pretty.chunks (map (from_eq name) eqs) end;
   827     fun hs_from_def (name, Undef) =
   865     fun hs_from_def (name, Undef) =
   828           error ("empty statement during serialization: " ^ quote name)
   866           error ("empty statement during serialization: " ^ quote name)
   829       | hs_from_def (name, Prim prim) =
   867       | hs_from_def (name, Prim prim) =
   830           from_prim (name, prim)
   868           from_prim (name, prim)
   831       | hs_from_def (name, Fun (eqs, (_, ty))) =
   869       | hs_from_def (name, Fun (eqs, (sctxt, ty))) =
   832           let
   870           let
   833             fun from_eq name (args, rhs) =
   871             fun from_eq name (args, rhs) =
   834               Pretty.block [
   872               Pretty.block [
   835                 str (lower_first name),
   873                 str (lower_first name),
   836                 Pretty.block (map (fn p => Pretty.block [Pretty.brk 1, hs_from_pat BR p]) args),
   874                 Pretty.block (map (fn p => Pretty.block [Pretty.brk 1, hs_from_expr BR p]) args),
   837                 Pretty.brk 1,
   875                 Pretty.brk 1,
   838                 str ("="),
   876                 str ("="),
   839                 Pretty.brk 1,
   877                 Pretty.brk 1,
   840                 hs_from_expr NOBR rhs
   878                 hs_from_expr NOBR rhs
   841               ]
   879               ]
   842           in
   880           in
   843             Pretty.chunks [
   881             Pretty.chunks [
   844               Pretty.block [
   882               Pretty.block [
   845                 str (lower_first name ^ " ::"),
   883                 str (lower_first name ^ " ::"),
   846                 Pretty.brk 1,
   884                 Pretty.brk 1,
   847                 hs_from_type NOBR ty
   885                 hs_from_sctxt_type (sctxt, ty)
   848               ],
   886               ],
   849               Pretty.chunks (map (from_eq name) eqs)
   887               hs_from_funeqs (name, eqs)
   850             ] |> SOME
   888             ] |> SOME
   851           end
   889           end
   852       | hs_from_def (name, Typesyn (vs, ty)) =
   890       | hs_from_def (name, Typesyn (vs, ty)) =
   853           Pretty.block [
   891           Pretty.block [
   854             str "type ",
   892             str "type ",
   855             hs_from_sctxt vs,
   893             hs_from_sctxt_type (vs, CodegenThingol.IType (name, map CodegenThingol.IVarT vs)),
   856             str (upper_first name),
       
   857             Pretty.block (map (fn (v, _) => str (" " ^ (lower_first) v)) vs),
       
   858             str " =",
   894             str " =",
   859             Pretty.brk 1,
   895             Pretty.brk 1,
   860             hs_from_type NOBR ty
   896             hs_from_sctxt_type ([], ty)
   861           ] |> SOME
   897           ] |> SOME
   862       | hs_from_def (name, Datatype ((vars, constrs), _)) =
   898       | hs_from_def (name, Datatype ((vs, constrs), _)) =
   863           let
   899           let
   864             fun mk_cons (co, tys) =
   900             fun mk_cons (co, tys) =
   865               (Pretty.block o Pretty.breaks) (
   901               (Pretty.block o Pretty.breaks) (
   866                 str ((upper_first o resolv) co)
   902                 str ((upper_first o resolv) co)
   867                 :: map (hs_from_type NOBR) tys
   903                 :: map (hs_from_type NOBR) tys
   868               )
   904               )
   869           in
   905           in
   870             Pretty.block (
   906             Pretty.block ((
   871               str "data "
   907               str "data "
   872               :: hs_from_sctxt vars
   908               :: hs_from_sctxt_type (vs, CodegenThingol.IType (name, map CodegenThingol.IVarT vs))
   873               :: str (upper_first name)
       
   874               :: Pretty.block (map (fn (v, _) => str (" " ^ (lower_first) v)) vars)
       
   875               :: str " ="
   909               :: str " ="
   876               :: Pretty.brk 1
   910               :: Pretty.brk 1
   877               :: separate (Pretty.block [Pretty.brk 1, str "| "]) (map mk_cons constrs)
   911               :: separate (Pretty.block [Pretty.brk 1, str "| "]) (map mk_cons constrs)
   878             )
   912             ) @ [
       
   913               Pretty.brk 1,
       
   914               str "deriving Show"
       
   915             ])
   879           end |> SOME
   916           end |> SOME
   880       | hs_from_def (_, Datatypecons _) =
   917       | hs_from_def (_, Datatypecons _) =
   881           NONE
   918           NONE
   882       | hs_from_def (name, Class ((supclasss, (v, membrs)), _)) =
   919       | hs_from_def (name, Class ((supclasss, (v, membrs)), _)) =
   883           let
   920           let
   884             fun mk_member (m, (_, ty)) =
   921             fun mk_member (m, (sctxt, ty)) =
   885               Pretty.block [
   922               Pretty.block [
   886                 str (resolv m ^ " ::"),
   923                 str (resolv m ^ " ::"),
   887                 Pretty.brk 1,
   924                 Pretty.brk 1,
   888                 hs_from_type NOBR ty
   925                 hs_from_sctxt_type (sctxt, ty)
   889               ]
   926               ]
   890           in
   927           in
   891             Pretty.block [
   928             Pretty.block [
   892               str "class ",
   929               str "class ",
   893               hs_from_sctxt (map (fn class => (v, [class])) supclasss),
   930               hs_from_sctxt (map (fn class => (v, [class])) supclasss),
   897               Pretty.chunks (map mk_member membrs)
   934               Pretty.chunks (map mk_member membrs)
   898             ] |> SOME
   935             ] |> SOME
   899           end
   936           end
   900       | hs_from_def (name, Classmember _) =
   937       | hs_from_def (name, Classmember _) =
   901           NONE
   938           NONE
   902       | hs_from_def (_, Classinst ((clsname, (tyco, arity)), memdefs)) = 
   939       | hs_from_def (_, Classinst (((clsname, (tyco, arity)), _), memdefs)) = 
   903           Pretty.block [
   940           Pretty.block [
   904             str "instance ",
   941             str "instance ",
   905             hs_from_sctxt arity,
   942             hs_from_sctxt_type (arity, IType ((upper_first o resolv) clsname, map (IVarT o rpair [] o fst) arity)),
   906             str ((upper_first o resolv) clsname),
       
   907             str " ",
   943             str " ",
   908             hs_from_type NOBR (IType (tyco, (map (IVarT o rpair [] o fst)) arity)),
   944             hs_from_sctxt_type (arity, IType (tyco, map (IVarT o rpair [] o fst) arity)),
   909             str " where",
   945             str " where",
   910             Pretty.fbrk,
   946             Pretty.fbrk,
   911             Pretty.chunks (map (fn (m, funn) => hs_from_def (m, Fun funn) |> the) memdefs)
   947             Pretty.chunks (map (fn (m, (eqs, _)) => hs_from_funeqs (resolv m, eqs)) memdefs)
   912           ] |> SOME
   948           ] |> SOME
   913   in
   949   in
   914     case List.mapPartial (fn (name, def) => hs_from_def (name, def)) defs
   950     case List.mapPartial (fn (name, def) => hs_from_def (name, def)) defs
   915      of [] => NONE
   951      of [] => NONE
   916       | l => (SOME o Pretty.chunks o separate (str "")) l
   952       | l => (SOME o Pretty.chunks o separate (str "")) l
   951       |> tap (Pretty.writeln o pretty_deps)
   987       |> tap (Pretty.writeln o pretty_deps)
   952       |> debug 3 (fn _ => "eta-expanding...")
   988       |> debug 3 (fn _ => "eta-expanding...")
   953       |> eta_expand (eta_expander const_syntax);
   989       |> eta_expand (eta_expander const_syntax);
   954   in
   990   in
   955     parse_multi_file ((K o K) NONE) "hs" serializer
   991     parse_multi_file ((K o K) NONE) "hs" serializer
   956     >> (fn seri => fn (tyco_syntax, const_syntax) => seri 
   992     >> (fn seri => fn (class_syntax, tyco_syntax, const_syntax) => seri 
   957          (preprocess const_syntax) (tyco_syntax, const_syntax))
   993          (preprocess const_syntax) (class_syntax, tyco_syntax, const_syntax))
   958   end;
   994   end;
   959 
   995 
   960 end; (* local *)
   996 end; (* local *)
   961 
   997 
   962 
   998