src/Tools/Code/code_scala.ML
changeset 37639 5b6733e6e033
parent 37464 9250ad1b98e0
child 37651 62fc16341922
equal deleted inserted replaced
37638:82f9ce5a8274 37639:5b6733e6e033
    21 
    21 
    22 
    22 
    23 (** Scala serializer **)
    23 (** Scala serializer **)
    24 
    24 
    25 fun print_scala_stmt labelled_name syntax_tyco syntax_const reserved
    25 fun print_scala_stmt labelled_name syntax_tyco syntax_const reserved
    26     args_num is_singleton deresolve =
    26     args_num is_singleton_constr deresolve =
    27   let
    27   let
    28     val deresolve_base = Long_Name.base_name o deresolve;
    28     val deresolve_base = Long_Name.base_name o deresolve;
    29     val lookup_tyvar = first_upper oo lookup_var;
    29     fun lookup_tyvar tyvars = lookup_var tyvars o first_upper;
    30     fun print_typ tyvars fxy (tycoexpr as tyco `%% tys) = (case syntax_tyco tyco
    30     fun intro_tyvars vs = intro_vars (map (first_upper o fst) vs);
    31          of NONE => applify "[" "]" fxy
    31     fun print_tyco_expr tyvars fxy (tyco, tys) = applify "[" "]"
    32               ((str o deresolve) tyco) (map (print_typ tyvars NOBR) tys)
    32           (print_typ tyvars NOBR) fxy ((str o deresolve) tyco) tys
       
    33     and print_typ tyvars fxy (tyco `%% tys) = (case syntax_tyco tyco
       
    34          of NONE => print_tyco_expr tyvars fxy (tyco, tys)
    33           | SOME (i, print) => print (print_typ tyvars) fxy tys)
    35           | SOME (i, print) => print (print_typ tyvars) fxy tys)
    34       | print_typ tyvars fxy (ITyVar v) = (str o lookup_tyvar tyvars) v;
    36       | print_typ tyvars fxy (ITyVar v) = (str o lookup_tyvar tyvars) v;
    35     fun print_typed tyvars p ty =
    37     fun print_dicttyp tyvars (class, ty) = print_tyco_expr tyvars NOBR (class, [ty]);
    36       Pretty.block [p, str ":", Pretty.brk 1, print_typ tyvars NOBR ty]
    38     fun print_tupled_typ tyvars ([], ty) =
       
    39           print_typ tyvars NOBR ty
       
    40       | print_tupled_typ tyvars ([ty1], ty2) =
       
    41           concat [print_typ tyvars BR ty1, str "=>", print_typ tyvars NOBR ty2]
       
    42       | print_tupled_typ tyvars (tys, ty) =
       
    43           concat [enum "," "(" ")" (map (print_typ tyvars NOBR) tys),
       
    44             str "=>", print_typ tyvars NOBR ty];
       
    45     fun constraint p1 p2 = Pretty.block [p1, str ":", Pretty.brk 1, p2];
    37     fun print_var vars NONE = str "_"
    46     fun print_var vars NONE = str "_"
    38       | print_var vars (SOME v) = (str o lookup_var vars) v
    47       | print_var vars (SOME v) = (str o lookup_var vars) v
    39     fun print_term tyvars is_pat some_thm vars fxy (IConst c) =
    48     fun print_term tyvars is_pat some_thm vars fxy (IConst c) =
    40           print_app tyvars is_pat some_thm vars fxy (c, [])
    49           print_app tyvars is_pat some_thm vars fxy (c, [])
    41       | print_term tyvars is_pat some_thm vars fxy (t as (t1 `$ t2)) =
    50       | print_term tyvars is_pat some_thm vars fxy (t as (t1 `$ t2)) =
    42           (case Code_Thingol.unfold_const_app t
    51           (case Code_Thingol.unfold_const_app t
    43            of SOME app => print_app tyvars is_pat some_thm vars fxy app
    52            of SOME app => print_app tyvars is_pat some_thm vars fxy app
    44             | _ => applify "(" ")" fxy
    53             | _ => applify "(" ")" (print_term tyvars is_pat some_thm vars NOBR) fxy
    45                 (print_term tyvars is_pat some_thm vars BR t1)
    54                 (print_term tyvars is_pat some_thm vars BR t1) [t2])
    46                 [print_term tyvars is_pat some_thm vars NOBR t2])
       
    47       | print_term tyvars is_pat some_thm vars fxy (IVar v) =
    55       | print_term tyvars is_pat some_thm vars fxy (IVar v) =
    48           print_var vars v
    56           print_var vars v
    49       | print_term tyvars is_pat some_thm vars fxy ((v, ty) `|=> t) =
    57       | print_term tyvars is_pat some_thm vars fxy ((v, ty) `|=> t) =
    50           let
    58           let
    51             val vars' = intro_vars (the_list v) vars;
    59             val vars' = intro_vars (the_list v) vars;
    52           in
    60           in
    53             concat [
    61             concat [
    54               Pretty.block [str "(", print_typed tyvars (print_var vars' v) ty, str ")"],
    62               enclose "(" ")" [constraint (print_var vars' v) (print_typ tyvars NOBR ty)],
    55               str "=>",
    63               str "=>",
    56               print_term tyvars false some_thm vars' NOBR t
    64               print_term tyvars false some_thm vars' NOBR t
    57             ]
    65             ]
    58           end 
    66           end 
    59       | print_term tyvars is_pat some_thm vars fxy (ICase (cases as (_, t0))) =
    67       | print_term tyvars is_pat some_thm vars fxy (ICase (cases as (_, t0))) =
    66         (app as ((c, ((arg_typs, _), function_typs)), ts)) =
    74         (app as ((c, ((arg_typs, _), function_typs)), ts)) =
    67       let
    75       let
    68         val k = length ts;
    76         val k = length ts;
    69         val l = case syntax_const c of NONE => args_num c | SOME (l, _) => l;
    77         val l = case syntax_const c of NONE => args_num c | SOME (l, _) => l;
    70         val arg_typs' = if is_pat orelse
    78         val arg_typs' = if is_pat orelse
    71           (is_none (syntax_const c) andalso is_singleton c) then [] else arg_typs;
    79           (is_none (syntax_const c) andalso is_singleton_constr c) then [] else arg_typs;
    72         val (no_syntax, print') = case syntax_const c
    80         val (no_syntax, print') = case syntax_const c
    73          of NONE => (true, fn ts => applify "(" ")" fxy
    81          of NONE => (true, fn ts => applify "(" ")"
    74               (applify "[" "]" NOBR ((str o deresolve) c)
    82               (print_term tyvars is_pat some_thm vars NOBR) fxy
    75                 (map (print_typ tyvars NOBR) arg_typs'))
    83                 (applify "[" "]" (print_typ tyvars NOBR)
    76                   (map (print_term tyvars is_pat some_thm vars NOBR) ts))
    84                   NOBR ((str o deresolve) c) arg_typs') ts)
    77           | SOME (_, print) => (false, fn ts =>
    85           | SOME (_, print) => (false, fn ts =>
    78               print (print_term tyvars is_pat some_thm) some_thm vars fxy
    86               print (print_term tyvars is_pat some_thm) some_thm vars fxy
    79                 (ts ~~ take l function_typs));
    87                 (ts ~~ take l function_typs));
    80       in if k = l then print' ts
    88       in if k = l then print' ts
    81       else if k < l then
    89       else if k < l then
    92           let
   100           let
    93             val (binds, body) = Code_Thingol.unfold_let (ICase cases);
   101             val (binds, body) = Code_Thingol.unfold_let (ICase cases);
    94             fun print_match ((pat, ty), t) vars =
   102             fun print_match ((pat, ty), t) vars =
    95               vars
   103               vars
    96               |> print_bind tyvars some_thm BR pat
   104               |> print_bind tyvars some_thm BR pat
    97               |>> (fn p => semicolon [Pretty.block [str "val", Pretty.brk 1, p,
   105               |>> (fn p => concat [str "val", constraint p (print_typ tyvars NOBR ty),
    98                 str ":", Pretty.brk 1, print_typ tyvars NOBR ty],
       
    99                   str "=", print_term tyvars false some_thm vars NOBR t])
   106                   str "=", print_term tyvars false some_thm vars NOBR t])
   100             val (ps, vars') = fold_map print_match binds vars;
   107             val (all_ps, vars') = fold_map print_match binds vars;
   101           in
   108             val (ps, p) = split_last all_ps;
   102             brackify_block fxy
   109           in brackify_block fxy
   103               (str "{")
   110             (str "{")
   104               (ps @| print_term tyvars false some_thm vars' NOBR body)
   111             (ps @ Pretty.block [p, str ";"] @@ print_term tyvars false some_thm vars' NOBR body)
   105               (str "}")
   112             (str "}")
   106           end
   113           end
   107       | print_case tyvars some_thm vars fxy (((t, ty), clauses as _ :: _), _) =
   114       | print_case tyvars some_thm vars fxy (((t, ty), clauses as _ :: _), _) =
   108           let
   115           let
   109             fun print_select (pat, body) =
   116             fun print_select (pat, body) =
   110               let
   117               let
   116             (map print_select clauses)
   123             (map print_select clauses)
   117             (str "}") 
   124             (str "}") 
   118           end
   125           end
   119       | print_case tyvars some_thm vars fxy ((_, []), _) =
   126       | print_case tyvars some_thm vars fxy ((_, []), _) =
   120           (brackify fxy o Pretty.breaks o map str) ["error(\"empty case\")"];
   127           (brackify fxy o Pretty.breaks o map str) ["error(\"empty case\")"];
   121     fun print_defhead tyvars vars p vs params tys implicits (*FIXME simplify*) ty =
   128     fun print_context tyvars vs name = applify "[" "]"
   122       Pretty.block [str "def ", print_typed tyvars (applify "(implicit " ")" NOBR
   129       (fn (v, sort) => (Pretty.block o map str)
   123         (applify "(" ")" NOBR
   130         (lookup_tyvar tyvars v :: maps (fn sort => [": ", deresolve sort]) sort))
   124           (applify "[" "]" NOBR p (map (fn (v, sort) =>
   131           NOBR ((str o deresolve) name) vs;
   125               (str o implode)
   132     fun print_defhead tyvars vars name vs params tys ty =
   126                 (lookup_tyvar tyvars v :: map (prefix ": " o deresolve) sort)) vs))
   133       Pretty.block [str "def ", constraint (applify "(" ")" (fn (param, ty) =>
   127             (map2 (fn param => fn ty => print_typed tyvars
   134         constraint ((str o lookup_var vars) param) (print_typ tyvars NOBR ty))
   128                 ((str o lookup_var vars) param) ty)
   135           NOBR (print_context tyvars vs name) (params ~~ tys)) (print_typ tyvars NOBR ty),
   129               params tys)) implicits) ty, str " ="]
   136             str " ="];
       
   137     fun print_def name (vs, ty) [] =
       
   138           let
       
   139             val (tys, ty') = Code_Thingol.unfold_fun ty;
       
   140             val params = Name.invents (snd reserved) "a" (length tys);
       
   141             val tyvars = intro_tyvars vs reserved;
       
   142             val vars = intro_vars params reserved;
       
   143           in
       
   144             concat [print_defhead tyvars vars name vs params tys ty',
       
   145               str ("error(\"" ^ name ^ "\")")]
       
   146           end
       
   147       | print_def name (vs, ty) eqs =
       
   148           let
       
   149             val tycos = fold (fn ((ts, t), _) =>
       
   150               fold Code_Thingol.add_tyconames (t :: ts)) eqs [];
       
   151             val tyvars = reserved
       
   152               |> intro_base_names
       
   153                    (is_none o syntax_tyco) deresolve tycos
       
   154               |> intro_tyvars vs;
       
   155             val simple = case eqs
       
   156              of [((ts, _), _)] => forall Code_Thingol.is_IVar ts
       
   157               | _ => false;
       
   158             val consts = fold Code_Thingol.add_constnames
       
   159               (map (snd o fst) eqs) [];
       
   160             val vars1 = reserved
       
   161               |> intro_base_names
       
   162                    (is_none o syntax_const) deresolve consts
       
   163             val params = if simple
       
   164               then (map (fn IVar (SOME x) => x) o fst o fst o hd) eqs
       
   165               else aux_params vars1 (map (fst o fst) eqs);
       
   166             val vars2 = intro_vars params vars1;
       
   167             val (tys', ty') = Code_Thingol.unfold_fun_n (length params) ty;
       
   168             fun print_tuple [p] = p
       
   169               | print_tuple ps = enum "," "(" ")" ps;
       
   170             fun print_rhs vars' ((_, t), (some_thm, _)) =
       
   171               print_term tyvars false some_thm vars' NOBR t;
       
   172             fun print_clause (eq as ((ts, _), (some_thm, _))) =
       
   173               let
       
   174                 val vars' = intro_vars ((fold o Code_Thingol.fold_varnames)
       
   175                   (insert (op =)) ts []) vars1;
       
   176               in
       
   177                 concat [str "case",
       
   178                   print_tuple (map (print_term tyvars true some_thm vars' NOBR) ts),
       
   179                   str "=>", print_rhs vars' eq]
       
   180               end;
       
   181             val head = print_defhead tyvars vars2 name vs params tys' ty';
       
   182           in if simple then
       
   183             concat [head, print_rhs vars2 (hd eqs)]
       
   184           else
       
   185             Pretty.block_enclose
       
   186               (concat [head, print_tuple (map (str o lookup_var vars2) params),
       
   187                 str "match", str "{"], str "}")
       
   188               (map print_clause eqs)
       
   189           end;
       
   190     val print_method = (str o Library.enclose "`" "+`" o deresolve_base);
   130     fun print_stmt (name, Code_Thingol.Fun (_, (((vs, ty), raw_eqs), _))) =
   191     fun print_stmt (name, Code_Thingol.Fun (_, (((vs, ty), raw_eqs), _))) =
   131         (case filter (snd o snd) raw_eqs
   192           print_def name (vs, ty) (filter (snd o snd) raw_eqs)
   132          of [] =>
       
   133               let
       
   134                 val (tys, ty') = Code_Thingol.unfold_fun ty;
       
   135                 val params = Name.invents (snd reserved) "a" (length tys);
       
   136                 val tyvars = intro_vars (map fst vs) reserved;
       
   137                 val vars = intro_vars params reserved;
       
   138               in
       
   139                 concat [print_defhead tyvars vars ((str o deresolve) name) vs params tys [] ty',
       
   140                   str ("error(\"" ^ name ^ "\")")]
       
   141               end
       
   142           | eqs =>
       
   143               let
       
   144                 val tycos = fold (fn ((ts, t), _) =>
       
   145                   fold Code_Thingol.add_tyconames (t :: ts)) eqs [];
       
   146                 val tyvars = reserved
       
   147                   |> intro_base_names
       
   148                        (is_none o syntax_tyco) deresolve tycos
       
   149                   |> intro_vars (map fst vs);
       
   150                 val simple = case eqs
       
   151                  of [((ts, _), _)] => forall Code_Thingol.is_IVar ts
       
   152                   | _ => false;
       
   153                 val consts = fold Code_Thingol.add_constnames
       
   154                   (map (snd o fst) eqs) [];
       
   155                 val vars1 = reserved
       
   156                   |> intro_base_names
       
   157                        (is_none o syntax_const) deresolve consts
       
   158                 val params = if simple
       
   159                   then (map (fn IVar (SOME x) => x) o fst o fst o hd) eqs
       
   160                   else aux_params vars1 (map (fst o fst) eqs);
       
   161                 val vars2 = intro_vars params vars1;
       
   162                 val (tys, ty1) = Code_Thingol.unfold_fun ty;
       
   163                 val (tys1, tys2) = chop (length params) tys;
       
   164                 val ty2 = Library.foldr
       
   165                   (fn (ty1, ty2) => Code_Thingol.fun_tyco `%% [ty1, ty2]) (tys2, ty1);
       
   166                 fun print_tuple [p] = p
       
   167                   | print_tuple ps = enum "," "(" ")" ps;
       
   168                 fun print_rhs vars' ((_, t), (some_thm, _)) =
       
   169                   print_term tyvars false some_thm vars' NOBR t;
       
   170                 fun print_clause (eq as ((ts, _), (some_thm, _))) =
       
   171                   let
       
   172                     val vars' = intro_vars ((fold o Code_Thingol.fold_varnames)
       
   173                       (insert (op =)) ts []) vars1;
       
   174                   in
       
   175                     concat [str "case",
       
   176                       print_tuple (map (print_term tyvars true some_thm vars' NOBR) ts),
       
   177                       str "=>", print_rhs vars' eq]
       
   178                   end;
       
   179                 val head = print_defhead tyvars vars2 ((str o deresolve) name) vs params tys1 [] ty2;
       
   180               in if simple then
       
   181                 concat [head, print_rhs vars2 (hd eqs)]
       
   182               else
       
   183                 Pretty.block_enclose
       
   184                   (concat [head, print_tuple (map (str o lookup_var vars2) params),
       
   185                     str "match", str "{"], str "}")
       
   186                   (map print_clause eqs)
       
   187               end)
       
   188       | print_stmt (name, Code_Thingol.Datatype (_, (vs, cos))) =
   193       | print_stmt (name, Code_Thingol.Datatype (_, (vs, cos))) =
   189           let
   194           let
   190             val tyvars = intro_vars (map fst vs) reserved;
   195             val tyvars = intro_tyvars vs reserved;
   191             fun print_co ((co, _), []) =
   196             fun print_co ((co, _), []) =
   192                   concat [str "final", str "case", str "object", (str o deresolve_base) co,
   197                   concat [str "final", str "case", str "object", (str o deresolve_base) co,
   193                     str "extends", applify "[" "]" NOBR ((str o deresolve_base) name)
   198                     str "extends", applify "[" "]" I NOBR ((str o deresolve_base) name)
   194                       (replicate (length vs) (str "Nothing"))]
   199                       (replicate (length vs) (str "Nothing"))]
   195               | print_co ((co, vs_args), tys) =
   200               | print_co ((co, vs_args), tys) =
   196                   let
   201                   concat [applify "(" ")"
   197                     val fields = Name.names (snd reserved) "a" tys;
   202                     (fn (v, arg) => constraint (str v) (print_typ tyvars NOBR arg)) NOBR
   198                     val vars = intro_vars (map fst fields) reserved;
   203                     (applify "[" "]" (str o lookup_tyvar tyvars) NOBR ((concat o map str)
   199                     fun add_typargs1 p = applify "[" "]" NOBR p
   204                       ["final", "case", "class", deresolve_base co]) vs_args)
   200                       (map (str o lookup_tyvar tyvars o fst) vs); (*FIXME*)
   205                     (Name.names (snd reserved) "a" tys),
   201                     fun add_typargs2 p = applify "[" "]" NOBR p
   206                     str "extends",
   202                       (map (str o lookup_tyvar tyvars) vs_args); (*FIXME*)
   207                     applify "[" "]" (str o lookup_tyvar tyvars o fst) NOBR
   203                   in
   208                       ((str o deresolve_base) name) vs
   204                     concat [
   209                   ];
   205                       applify "(" ")" NOBR
   210           in
   206                         (add_typargs2 ((concat o map str)
   211             Pretty.chunks (applify "[" "]" (str o prefix "+" o lookup_tyvar tyvars o fst)
   207                           ["final", "case", "class", deresolve_base co]))
   212               NOBR ((concat o map str) ["sealed", "class", deresolve_base name]) vs
   208                         (map (uncurry (print_typed tyvars) o apfst str) fields),
   213                 :: map print_co cos)
   209                       str "extends",
       
   210                       add_typargs1 ((str o deresolve_base) name)
       
   211                     ]
       
   212                   end
       
   213           in
       
   214             Pretty.chunks (
       
   215               applify "[" "]" NOBR ((concat o map str)
       
   216                   ["sealed", "class", deresolve_base name])
       
   217                 (map (str o prefix "+" o lookup_tyvar tyvars o fst) vs)
       
   218               :: map print_co cos
       
   219             )
       
   220           end
   214           end
   221       | print_stmt (name, Code_Thingol.Class (_, (v, (super_classes, classparams)))) =
   215       | print_stmt (name, Code_Thingol.Class (_, (v, (super_classes, classparams)))) =
   222           let
   216           let
   223             val tyvars = intro_vars [v] reserved;
   217             val tyvars = intro_tyvars [(v, [name])] reserved;
   224             val vs = [(v, [name])];
   218             fun add_typarg s = Pretty.block
   225             fun add_typarg p = applify "[" "]" NOBR p [(str o lookup_tyvar tyvars) v];
   219               [str s, str "[", (str o lookup_tyvar tyvars) v, str "]"];
   226             fun print_super_classes [] = NONE
   220             fun print_super_classes [] = NONE
   227               | print_super_classes classes = SOME (concat (str "extends"
   221               | print_super_classes classes = SOME (concat (str "extends"
   228                   :: separate (str "with")
   222                   :: separate (str "with") (map (add_typarg o deresolve o fst) classes)));
   229                     (map (add_typarg o str o deresolve o fst) classes)));
       
   230             fun print_tupled_typ ([], ty) =
       
   231                   print_typ tyvars NOBR ty
       
   232               | print_tupled_typ ([ty1], ty2) =
       
   233                   concat [print_typ tyvars BR ty1, str "=>", print_typ tyvars NOBR ty2]
       
   234               | print_tupled_typ (tys, ty) =
       
   235                   concat [enum "," "(" ")" (map (print_typ tyvars NOBR) tys),
       
   236                     str "=>", print_typ tyvars NOBR ty];
       
   237             fun print_classparam_val (classparam, ty) =
   223             fun print_classparam_val (classparam, ty) =
   238               concat [str "val", (str o Library.enclose "`" "+`:" o deresolve_base)
   224               concat [str "val", constraint (print_method classparam)
   239                   classparam,
   225                 ((print_tupled_typ tyvars o Code_Thingol.unfold_fun) ty)];
   240                 (print_tupled_typ o Code_Thingol.unfold_fun) ty]
       
   241             fun implicit_arguments tyvars vs vars = (*FIXME simplifiy*)
       
   242               let
       
   243                 val implicit_typ_ps = maps (fn (v, sort) => map (fn class => Pretty.block
       
   244                   [(str o deresolve) class, str "[",
       
   245                     (str o lookup_tyvar tyvars) v, str "]"]) sort) vs;
       
   246                 val implicit_names = Name.variant_list [] (maps (fn (v, sort) =>
       
   247                   map (fn class => lookup_tyvar tyvars v ^ "_" ^
       
   248                     (Long_Name.base_name o deresolve) class) sort) vs);
       
   249                 val vars' = intro_vars implicit_names vars;
       
   250                 val implicit_ps = map2 (fn v => fn p => concat [str (v ^ ":"), p])
       
   251                   implicit_names implicit_typ_ps;
       
   252               in ((implicit_names, implicit_ps), vars') end;
       
   253             fun print_classparam_def (classparam, ty) =
   226             fun print_classparam_def (classparam, ty) =
   254               let
   227               let
   255                 val (tys, ty) = Code_Thingol.unfold_fun ty;
   228                 val (tys, ty) = Code_Thingol.unfold_fun ty;
   256                 val params = Name.invents (snd reserved) "a" (length tys);
   229                 val [implicit_name] = Name.invents (snd reserved) (lookup_tyvar tyvars v) 1;
   257                 val vars = intro_vars params reserved;
   230                 val proto_vars = intro_vars [implicit_name] reserved;
   258                 val (([implicit], [p_implicit]), vars') = implicit_arguments tyvars vs vars;
   231                 val auxs = Name.invents (snd proto_vars) "a" (length tys);
   259                 val head = print_defhead tyvars vars' ((str o deresolve) classparam)
   232                 val vars = intro_vars auxs proto_vars;
   260                   ((map o apsnd) (K []) vs) params tys [p_implicit] ty;
       
   261               in
   233               in
   262                 concat [head, applify "(" ")" NOBR
   234                 concat [str "def", constraint (Pretty.block [applify "(" ")"
   263                   (Pretty.block [str implicit, str ".",
   235                   (fn (aux, ty) => constraint ((str o lookup_var vars) aux)
   264                     (str o Library.enclose "`" "+`" o deresolve_base) classparam])
   236                   (print_typ tyvars NOBR ty)) NOBR (add_typarg (deresolve classparam))
   265                   (map (str o lookup_var vars') params)]
   237                   (auxs ~~ tys), str "(implicit ", str implicit_name, str ": ",
       
   238                   add_typarg (deresolve name), str ")"]) (print_typ tyvars NOBR ty), str "=",
       
   239                   applify "(" ")" (str o lookup_var vars) NOBR
       
   240                   (Pretty.block [str implicit_name, str ".", print_method classparam]) auxs]
   266               end;
   241               end;
   267           in
   242           in
   268             Pretty.chunks (
   243             Pretty.chunks (
   269               (Pretty.block_enclose
   244               (Pretty.block_enclose
   270                 (concat ([str "trait", add_typarg ((str o deresolve_base) name)]
   245                 (concat ([str "trait", (add_typarg o deresolve_base) name]
   271                   @ the_list (print_super_classes super_classes) @ [str "{"]), str "}")
   246                   @ the_list (print_super_classes super_classes) @ [str "{"]), str "}")
   272                 (map print_classparam_val classparams))
   247                 (map print_classparam_val classparams))
   273               :: map print_classparam_def classparams
   248               :: map print_classparam_def classparams
   274             )
   249             )
   275           end
   250           end
   276       | print_stmt (name, Code_Thingol.Classinst ((class, (tyco, vs)),
   251       | print_stmt (name, Code_Thingol.Classinst ((class, (tyco, vs)),
   277             (super_instances, (classparam_instances, further_classparam_instances)))) =
   252             (super_instances, (classparam_instances, further_classparam_instances)))) =
   278           let
   253           let
   279             val tyvars = intro_vars (map fst vs) reserved;
   254             val tyvars = intro_tyvars vs reserved;
   280             val classtyp = (class, (tyco, map fst vs));
   255             val classtyp = (class, tyco `%% map (ITyVar o fst) vs);
   281             fun print_classtyp' (class, (tyco, vs)) = (*FIXME already exists?*)
       
   282               applify "[" "]" NOBR(*? FIXME*) ((str o deresolve) class)
       
   283                 [print_typ tyvars NOBR (tyco `%% map ITyVar vs)]; (*FIXME a mess...*)
       
   284             fun print_typed' tyvars p classtyp = (*FIXME unify with existing print_typed*)
       
   285               Pretty.block [p, str ":", Pretty.brk 1, print_classtyp' classtyp];
       
   286             fun print_defhead' tyvars vars p vs params tys classtyp = (*FIXME unify with existing def_head*)
       
   287               Pretty.block [str "def ", print_typed' tyvars
       
   288                 (applify "(" ")" NOBR
       
   289                   (applify "[" "]" NOBR p (map (fn (v, sort) =>
       
   290                       (str o implode) (lookup_tyvar tyvars v :: map (prefix ": " o deresolve) sort)) vs))
       
   291                     (map2 (fn param => fn ty => print_typed tyvars ((str o lookup_var vars) param) ty)
       
   292                       params tys)) classtyp, str " ="];
       
   293             fun print_classparam_instance ((classparam, const as (_, (_, tys))), (thm, _)) =
   256             fun print_classparam_instance ((classparam, const as (_, (_, tys))), (thm, _)) =
   294               let
   257               let
   295                 val auxs = Name.invents (snd reserved) "a" (length tys);
   258                 val aux_tys = Name.names (snd reserved) "a" tys;
       
   259                 val auxs = map fst aux_tys;
   296                 val vars = intro_vars auxs reserved;
   260                 val vars = intro_vars auxs reserved;
   297                 val args = if null auxs then [] else
   261                 val aux_abstr = if null auxs then [] else [enum "," "(" ")"
   298                   [concat [enum "," "(" ")" (map2 (fn aux => fn ty => print_typed tyvars ((str o lookup_var vars) aux) ty)
   262                   (map (fn (aux, ty) => constraint ((str o lookup_var vars) aux)
   299                     auxs tys), str "=>"]];
   263                   (print_typ tyvars NOBR ty)) aux_tys), str "=>"];
   300               in 
   264               in 
   301                 concat ([str "val", (str o Library.enclose "`" "+`" o deresolve_base) classparam,
   265                 concat ([str "val", print_method classparam, str "="]
   302                   str "="] @ args @ [print_app tyvars false (SOME thm) vars NOBR (const, map (IVar o SOME) auxs)])
   266                   @ aux_abstr @| print_app tyvars false (SOME thm) vars NOBR
       
   267                     (const, map (IVar o SOME) auxs))
   303               end;
   268               end;
   304             val head = print_defhead' tyvars reserved ((str o deresolve) name) vs [] [] classtyp;
   269           in
   305             val body = [str "new", print_classtyp' classtyp,
   270             Pretty.block_enclose (concat [str "implicit def",
   306               Pretty.enum ";" "{ " " }" (map print_classparam_instance (classparam_instances @ further_classparam_instances))];
   271               constraint (print_context tyvars vs name) (print_dicttyp tyvars classtyp),
   307           in concat (str "implicit" :: head :: body) end;
   272               str "=", str "new", print_dicttyp tyvars classtyp, str "{"], str "}")
       
   273                 (map print_classparam_instance (classparam_instances @ further_classparam_instances))
       
   274           end;
   308   in print_stmt end;
   275   in print_stmt end;
   309 
   276 
   310 fun scala_program_of_program labelled_name module_name reserved raw_module_alias program =
   277 fun scala_program_of_program labelled_name module_name reserved raw_module_alias program =
   311   let
   278   let
   312     val the_module_name = the_default "Program" module_name;
   279     val the_module_name = the_default "Program" module_name;
   366     val module_name = if null presentation_stmt_names then raw_module_name else SOME "Code";
   333     val module_name = if null presentation_stmt_names then raw_module_name else SOME "Code";
   367     val reserved = fold (insert (op =) o fst) includes raw_reserved;
   334     val reserved = fold (insert (op =) o fst) includes raw_reserved;
   368     val (deresolver, (the_module_name, sca_program)) = scala_program_of_program labelled_name
   335     val (deresolver, (the_module_name, sca_program)) = scala_program_of_program labelled_name
   369       module_name reserved raw_module_alias program;
   336       module_name reserved raw_module_alias program;
   370     val reserved = make_vars reserved;
   337     val reserved = make_vars reserved;
       
   338     fun lookup_constr tyco constr = case Graph.get_node program tyco
       
   339      of Code_Thingol.Datatype (_, (_, constrs)) =>
       
   340           the (AList.lookup (op = o apsnd fst) constrs constr);
       
   341     fun classparams_of_class class = case Graph.get_node program class
       
   342      of Code_Thingol.Class (_, (_, (_, classparams))) => classparams;
   371     fun args_num c = case Graph.get_node program c
   343     fun args_num c = case Graph.get_node program c
   372      of Code_Thingol.Fun (_, (((_, ty), []), _)) =>
   344      of Code_Thingol.Fun (_, (((_, ty), []), _)) =>
   373           (length o fst o Code_Thingol.unfold_fun) ty
   345           (length o fst o Code_Thingol.unfold_fun) ty
   374       | Code_Thingol.Fun (_, ((_, ((ts, _), _) :: _), _)) => length ts
   346       | Code_Thingol.Fun (_, ((_, ((ts, _), _) :: _), _)) => length ts
   375       | Code_Thingol.Datatypecons (_, tyco) =>
   347       | Code_Thingol.Datatypecons (_, tyco) => length (lookup_constr tyco c)
   376           let val Code_Thingol.Datatype (_, (_, constrs)) = Graph.get_node program tyco
       
   377           in (length o the o AList.lookup (eq_fst op =) constrs) (c, []) end (*FIXME simplify lookup*)
       
   378       | Code_Thingol.Classparam (_, class) =>
   348       | Code_Thingol.Classparam (_, class) =>
   379           let
   349           (length o fst o Code_Thingol.unfold_fun o the o AList.lookup (op =)
   380             val Code_Thingol.Class (_, (_, (_, classparams))) =
   350             (classparams_of_class class)) c;
   381               Graph.get_node program class
   351     fun is_singleton_constr c = case Graph.get_node program c
   382           in (length o fst o Code_Thingol.unfold_fun o the o AList.lookup (op =) classparams) c end;
   352      of Code_Thingol.Datatypecons (_, tyco) => null (lookup_constr tyco c)
   383     fun is_singleton c = case Graph.get_node program c
       
   384      of Code_Thingol.Datatypecons (_, tyco) =>
       
   385           let val Code_Thingol.Datatype (_, (_, constrs)) = Graph.get_node program tyco
       
   386           in (null o the o AList.lookup (eq_fst op =) constrs) (c, []) end (*FIXME simplify lookup*)
       
   387       | _ => false;
   353       | _ => false;
   388     val print_stmt = print_scala_stmt labelled_name syntax_tyco syntax_const
   354     val print_stmt = print_scala_stmt labelled_name syntax_tyco syntax_const
   389       reserved args_num is_singleton deresolver;
   355       reserved args_num is_singleton_constr deresolver;
   390     fun print_module name content =
   356     fun print_module name content =
   391       (name, Pretty.chunks [
   357       (name, Pretty.chunks [
   392         str ("object " ^ name ^ " {"),
   358         str ("object " ^ name ^ " {"),
   393         str "",
   359         str "",
   394         content,
   360         content,
   466       "match", "new", "null", "object", "override", "package", "private", "protected",
   432       "match", "new", "null", "object", "override", "package", "private", "protected",
   467       "requires", "return", "sealed", "super", "this", "throw", "trait", "try",
   433       "requires", "return", "sealed", "super", "this", "throw", "trait", "try",
   468       "true", "type", "val", "var", "while", "with", "yield"
   434       "true", "type", "val", "var", "while", "with", "yield"
   469     ]
   435     ]
   470   #> fold (Code_Target.add_reserved target) [
   436   #> fold (Code_Target.add_reserved target) [
   471       "error", "apply", "List", "Nil", "BigInt"
   437       "apply", "error", "BigInt", "Nil", "List"
   472     ];
   438     ];
   473 
   439 
   474 end; (*struct*)
   440 end; (*struct*)