a primitive scala serializer
authorhaftmann
Fri Jan 08 12:25:15 2010 +0100 (2010-01-08)
changeset 3429419c1fd52d6c9
parent 34275 8f105e6a2b88
child 34295 6cd289eca3e4
a primitive scala serializer
src/HOL/HOL.thy
src/Tools/Code/code_scala.ML
src/Tools/Code_Generator.thy
     1.1 --- a/src/HOL/HOL.thy	Tue Jan 05 16:55:00 2010 +0100
     1.2 +++ b/src/HOL/HOL.thy	Fri Jan 08 12:25:15 2010 +0100
     1.3 @@ -1913,6 +1913,7 @@
     1.4    (SML "bool")
     1.5    (OCaml "bool")
     1.6    (Haskell "Bool")
     1.7 +  (Scala "Boolean")
     1.8  
     1.9  code_const True and False and Not and "op &" and "op |" and If
    1.10    (SML "true" and "false" and "not"
    1.11 @@ -1925,12 +1926,18 @@
    1.12      and infixl 3 "&&" and infixl 2 "||"
    1.13      and "!(if (_)/ then (_)/ else (_))")
    1.14  
    1.15 +code_const True and False
    1.16 +  (Scala "true" and "false")
    1.17 +
    1.18  code_reserved SML
    1.19    bool true false not
    1.20  
    1.21  code_reserved OCaml
    1.22    bool not
    1.23  
    1.24 +code_reserved Scala
    1.25 +  Boolean
    1.26 +
    1.27  text {* using built-in Haskell equality *}
    1.28  
    1.29  code_class eq
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/Tools/Code/code_scala.ML	Fri Jan 08 12:25:15 2010 +0100
     2.3 @@ -0,0 +1,442 @@
     2.4 +(*  Author:     Florian Haftmann, TU Muenchen
     2.5 +
     2.6 +Serializer for Scala.
     2.7 +*)
     2.8 +
     2.9 +signature CODE_SCALA =
    2.10 +sig
    2.11 +  val setup: theory -> theory
    2.12 +end;
    2.13 +
    2.14 +structure Code_Scala : CODE_SCALA =
    2.15 +struct
    2.16 +
    2.17 +val target = "Scala";
    2.18 +
    2.19 +open Basic_Code_Thingol;
    2.20 +open Code_Printer;
    2.21 +
    2.22 +infixr 5 @@;
    2.23 +infixr 5 @|;
    2.24 +
    2.25 +
    2.26 +(** Scala serializer **)
    2.27 +
    2.28 +fun print_scala_stmt labelled_name syntax_tyco syntax_const reserved args_num is_singleton deresolve =
    2.29 +  let
    2.30 +    val deresolve_base = Long_Name.base_name o deresolve;
    2.31 +    fun print_typ tyvars fxy (tycoexpr as tyco `%% tys) = (case syntax_tyco tyco
    2.32 +         of NONE => applify "[" "]" fxy
    2.33 +              ((str o deresolve) tyco) (map (print_typ tyvars NOBR) tys)
    2.34 +          | SOME (i, print) => print (print_typ tyvars) fxy tys)
    2.35 +      | print_typ tyvars fxy (ITyVar v) = (str o lookup_var tyvars) v;
    2.36 +    fun print_typed tyvars p ty =
    2.37 +      Pretty.block [p, str ":", Pretty.brk 1, print_typ tyvars NOBR ty]
    2.38 +    fun print_var vars NONE = str "_"
    2.39 +      | print_var vars (SOME v) = (str o lookup_var vars) v
    2.40 +    fun print_term tyvars is_pat thm vars fxy (IConst c) =
    2.41 +          print_app tyvars is_pat thm vars fxy (c, [])
    2.42 +      | print_term tyvars is_pat thm vars fxy (t as (t1 `$ t2)) =
    2.43 +          (case Code_Thingol.unfold_const_app t
    2.44 +           of SOME app => print_app tyvars is_pat thm vars fxy app
    2.45 +            | _ => applify "(" ")" fxy
    2.46 +                (print_term tyvars is_pat thm vars BR t1)
    2.47 +                [print_term tyvars is_pat thm vars NOBR t2])
    2.48 +      | print_term tyvars is_pat thm vars fxy (IVar v) =
    2.49 +          print_var vars v
    2.50 +      | print_term tyvars is_pat thm vars fxy ((v, ty) `|=> t) =
    2.51 +          let
    2.52 +            val vars' = intro_vars (the_list v) vars;
    2.53 +          in
    2.54 +            concat [
    2.55 +              Pretty.block [str "(", print_typed tyvars (print_var vars' v) ty, str ")"],
    2.56 +              str "=>",
    2.57 +              print_term tyvars false thm vars' NOBR t
    2.58 +            ]
    2.59 +          end 
    2.60 +      | print_term tyvars is_pat thm vars fxy (ICase (cases as (_, t0))) =
    2.61 +          (case Code_Thingol.unfold_const_app t0
    2.62 +           of SOME (c_ts as ((c, _), _)) => if is_none (syntax_const c)
    2.63 +                then print_case tyvars thm vars fxy cases
    2.64 +                else print_app tyvars is_pat thm vars fxy c_ts
    2.65 +            | NONE => print_case tyvars thm vars fxy cases)
    2.66 +    and print_app tyvars is_pat thm vars fxy (app as ((c, ((tys, _), _)), ts)) =
    2.67 +      let
    2.68 +        val k = length ts;
    2.69 +        val l = case syntax_const c of NONE => args_num c | SOME (l, _) => l;
    2.70 +        val tys' = if is_pat orelse
    2.71 +          (is_none (syntax_const c) andalso is_singleton c) then [] else tys;
    2.72 +        val (no_syntax, print') = case syntax_const c
    2.73 +         of NONE => (true, fn ts => applify "(" ")" fxy
    2.74 +              (applify "[" "]" NOBR ((str o deresolve) c) (map (print_typ tyvars NOBR) tys'))
    2.75 +                (map (print_term tyvars is_pat thm vars NOBR) ts))
    2.76 +          | SOME (_, print) => (false, fn ts =>
    2.77 +              print (print_term tyvars is_pat thm) thm vars fxy (ts ~~ take k tys));
    2.78 +      in if k = l then print' ts
    2.79 +      else if k < l then
    2.80 +        print_term tyvars is_pat thm vars fxy (Code_Thingol.eta_expand l app)
    2.81 +      else let
    2.82 +        val (ts1, ts23) = chop l ts;
    2.83 +      in
    2.84 +        Pretty.block (print' ts1 :: map (fn t => Pretty.block
    2.85 +          [str ".apply(", print_term tyvars is_pat thm vars NOBR t, str ")"]) ts23)
    2.86 +      end end
    2.87 +    and print_bind tyvars thm fxy p = gen_print_bind (print_term tyvars true) thm fxy p
    2.88 +    and print_case tyvars thm vars fxy (cases as ((_, [_]), _)) =
    2.89 +          let
    2.90 +            val (binds, body) = Code_Thingol.unfold_let (ICase cases);
    2.91 +            fun print_match ((pat, ty), t) vars =
    2.92 +              vars
    2.93 +              |> print_bind tyvars thm BR pat
    2.94 +              |>> (fn p => semicolon [Pretty.block [str "val", Pretty.brk 1, p,
    2.95 +                str ":", Pretty.brk 1, print_typ tyvars NOBR ty],
    2.96 +                  str "=", print_term tyvars false thm vars NOBR t])
    2.97 +            val (ps, vars') = fold_map print_match binds vars;
    2.98 +          in
    2.99 +            brackify_block fxy
   2.100 +              (str "{")
   2.101 +              (ps @| print_term tyvars false thm vars' NOBR body)
   2.102 +              (str "}")
   2.103 +          end
   2.104 +      | print_case tyvars thm vars fxy (((t, ty), clauses as _ :: _), _) =
   2.105 +          let
   2.106 +            fun print_select (pat, body) =
   2.107 +              let
   2.108 +                val (p, vars') = print_bind tyvars thm NOBR pat vars;
   2.109 +              in concat [str "case", p, str "=>", print_term tyvars false thm vars' NOBR body] end;
   2.110 +          in brackify_block fxy
   2.111 +            (concat [print_term tyvars false thm vars NOBR t, str "match", str "{"])
   2.112 +            (map print_select clauses)
   2.113 +            (str "}") 
   2.114 +          end
   2.115 +      | print_case tyvars thm vars fxy ((_, []), _) =
   2.116 +          (brackify fxy o Pretty.breaks o map str) ["error(\"empty case\")"];
   2.117 +    fun implicit_arguments tyvars vs vars =
   2.118 +      let
   2.119 +        val implicit_typ_ps = maps (fn (v, sort) => map (fn class => Pretty.block
   2.120 +          [(str o deresolve) class, str "[", (str o lookup_var tyvars) v, str "]"]) sort) vs;
   2.121 +        val implicit_names = Name.invents (snd vars) "a" (length implicit_typ_ps);
   2.122 +        val vars' = intro_vars implicit_names vars;
   2.123 +        val implicit_ps = map2 (fn v => fn p => concat [str (v ^ ":"), p])
   2.124 +          implicit_names implicit_typ_ps;
   2.125 +      in ((implicit_names, implicit_ps), vars') end;
   2.126 +    fun print_defhead tyvars vars p vs params tys implicits ty =
   2.127 +      concat [str "def", print_typed tyvars (applify "(implicit " ")" NOBR
   2.128 +        (applify "(" ")" NOBR
   2.129 +          (applify "[" "]" NOBR p (map (str o lookup_var tyvars o fst) vs))
   2.130 +            (map2 (fn param => fn ty => print_typed tyvars
   2.131 +                ((str o lookup_var vars) param) ty)
   2.132 +              params tys)) implicits) ty, str "="]
   2.133 +    fun print_stmt (name, Code_Thingol.Fun (_, ((vs, ty), raw_eqs))) = (case filter (snd o snd) raw_eqs
   2.134 +         of [] =>
   2.135 +              let
   2.136 +                val (tys, ty') = Code_Thingol.unfold_fun ty;
   2.137 +                val params = Name.invents (snd reserved) "a" (length tys);
   2.138 +                val tyvars = intro_vars (map fst vs) reserved;
   2.139 +                val vars = intro_vars params reserved;
   2.140 +              in
   2.141 +                concat [print_defhead tyvars vars ((str o deresolve) name) vs params tys [] ty',
   2.142 +                  str ("error(\"" ^ name ^ "\")")]
   2.143 +              end
   2.144 +          | eqs =>
   2.145 +              let
   2.146 +                val tycos = fold (fn ((ts, t), (thm, _)) =>
   2.147 +                  fold Code_Thingol.add_tyconames (t :: ts)) eqs [];
   2.148 +                val tyvars = reserved
   2.149 +                  |> intro_base_names
   2.150 +                       (is_none o syntax_tyco) deresolve tycos
   2.151 +                  |> intro_vars (map fst vs);
   2.152 +                val simple = case eqs
   2.153 +                 of [((ts, _), _)] => forall Code_Thingol.is_IVar ts
   2.154 +                  | _ => false;
   2.155 +                val consts = fold Code_Thingol.add_constnames
   2.156 +                  (map (snd o fst) eqs) [];
   2.157 +                val vars1 = reserved
   2.158 +                  |> intro_base_names
   2.159 +                       (is_none o syntax_const) deresolve consts
   2.160 +                val ((_, implicit_ps), vars2) = implicit_arguments tyvars vs vars1;
   2.161 +                val params = if simple then (map (fn IVar (SOME x) => x) o fst o fst o hd) eqs
   2.162 +                  else aux_params vars2 (map (fst o fst) eqs);
   2.163 +                val vars3 = intro_vars params vars2;
   2.164 +                val (tys, ty1) = Code_Thingol.unfold_fun ty;
   2.165 +                val (tys1, tys2) = chop (length params) tys;
   2.166 +                val ty2 = Library.foldr
   2.167 +                  (fn (ty1, ty2) => Code_Thingol.fun_tyco `%% [ty1, ty2]) (tys2, ty1);
   2.168 +                fun print_tuple [p] = p
   2.169 +                  | print_tuple ps = enum "," "(" ")" ps;
   2.170 +                fun print_rhs vars' ((_, t), (thm, _)) = print_term tyvars false thm vars' NOBR t;
   2.171 +                fun print_clause (eq as ((ts, _), (thm, _))) =
   2.172 +                  let
   2.173 +                    val vars' = intro_vars ((fold o Code_Thingol.fold_varnames) (insert (op =)) ts []) vars2;
   2.174 +                  in
   2.175 +                    concat [str "case", print_tuple (map (print_term tyvars true thm vars' NOBR) ts),
   2.176 +                      str "=>", print_rhs vars' eq]
   2.177 +                  end;
   2.178 +                val head = print_defhead tyvars vars3 ((str o deresolve) name) vs params tys1 implicit_ps ty2;
   2.179 +              in if simple then
   2.180 +                concat [head, print_rhs vars3 (hd eqs)]
   2.181 +              else
   2.182 +                Pretty.block_enclose
   2.183 +                  (concat [head, print_tuple (map (str o lookup_var vars3) params),
   2.184 +                    str "match", str "{"], str "}")
   2.185 +                  (map print_clause eqs)
   2.186 +              end)
   2.187 +      | print_stmt (name, Code_Thingol.Datatype (_, (vs, cos))) =
   2.188 +          let
   2.189 +            val tyvars = intro_vars (map fst vs) reserved;
   2.190 +            fun print_co (co, []) =
   2.191 +                  concat [str "final", str "case", str "object", (str o deresolve_base) co,
   2.192 +                    str "extends", applify "[" "]" NOBR ((str o deresolve_base) name)
   2.193 +                      (replicate (length vs) (str "Nothing"))]
   2.194 +              | print_co (co, tys) =
   2.195 +                  let
   2.196 +                    val fields = Name.names (snd reserved) "a" tys;
   2.197 +                    val vars = intro_vars (map fst fields) reserved;
   2.198 +                    fun add_typargs p = applify "[" "]" NOBR p
   2.199 +                      (map (str o lookup_var tyvars o fst) vs);
   2.200 +                  in
   2.201 +                    concat [
   2.202 +                      applify "(" ")" NOBR
   2.203 +                        (add_typargs ((concat o map str) ["final", "case", "class", deresolve_base co]))
   2.204 +                        (map (uncurry (print_typed tyvars) o apfst str) fields),
   2.205 +                      str "extends",
   2.206 +                      add_typargs ((str o deresolve_base) name)
   2.207 +                    ]
   2.208 +                  end
   2.209 +          in
   2.210 +            Pretty.chunks (
   2.211 +              applify "[" "]" NOBR ((concat o map str) ["sealed", "class", deresolve_base name])
   2.212 +                (map (str o prefix "+" o lookup_var tyvars o fst) vs)
   2.213 +              :: map print_co cos
   2.214 +            )
   2.215 +          end
   2.216 +      | print_stmt (name, Code_Thingol.Class (_, (v, (superclasses, classparams)))) =
   2.217 +          let
   2.218 +            val tyvars = intro_vars [v] reserved;
   2.219 +            val vs = [(v, [name])];
   2.220 +            fun add_typarg p = applify "[" "]" NOBR p [(str o lookup_var tyvars) v];
   2.221 +            fun print_superclasses [] = NONE
   2.222 +              | print_superclasses classes = SOME (concat (str "extends"
   2.223 +                  :: separate (str "with") (map (add_typarg o str o deresolve o fst) classes)));
   2.224 +            fun print_tupled_typ ([], ty) =
   2.225 +                  print_typ tyvars NOBR ty
   2.226 +              | print_tupled_typ ([ty1], ty2) =
   2.227 +                  concat [print_typ tyvars BR ty1, str "=>", print_typ tyvars NOBR ty2]
   2.228 +              | print_tupled_typ (tys, ty) =
   2.229 +                  concat [enum "," "(" ")" (map (print_typ tyvars NOBR) tys),
   2.230 +                    str "=>", print_typ tyvars NOBR ty];
   2.231 +            fun print_classparam_val (classparam, ty) =
   2.232 +              concat [str "val", (str o suffix "$:" o deresolve_base) classparam,
   2.233 +                (print_tupled_typ o Code_Thingol.unfold_fun) ty]
   2.234 +            fun print_classparam_def (classparam, ty) =
   2.235 +              let
   2.236 +                val (tys, ty) = Code_Thingol.unfold_fun ty;
   2.237 +                val params = Name.invents (snd reserved) "a" (length tys);
   2.238 +                val vars = intro_vars params reserved;
   2.239 +                val (([implicit], [p_implicit]), vars') = implicit_arguments tyvars vs vars;
   2.240 +                val head = print_defhead tyvars vars' ((str o deresolve) classparam) vs params tys [p_implicit] ty;
   2.241 +              in
   2.242 +                concat [head, applify "(" ")" NOBR
   2.243 +                  (Pretty.block [str implicit, str ".", (str o suffix "$" o deresolve_base) classparam])
   2.244 +                  (map (str o lookup_var vars') params)]
   2.245 +              end;
   2.246 +          in
   2.247 +            Pretty.chunks (
   2.248 +              (Pretty.block_enclose
   2.249 +                (concat ([str "trait", add_typarg ((str o deresolve_base) name)]
   2.250 +                  @ the_list (print_superclasses superclasses) @ [str "{"]), str "}")
   2.251 +                (map print_classparam_val classparams))
   2.252 +              :: map print_classparam_def classparams
   2.253 +            )
   2.254 +          end
   2.255 +      | print_stmt (name, Code_Thingol.Classinst ((class, (tyco, vs)),
   2.256 +            (super_instances, classparam_insts))) =
   2.257 +          let
   2.258 +            val tyvars = intro_vars (map fst vs) reserved;
   2.259 +            val insttyp = tyco `%% map (ITyVar o fst) vs;
   2.260 +            val p_inst_typ = print_typ tyvars NOBR insttyp;
   2.261 +            fun add_typ_params p = applify "[" "]" NOBR p (map (str o lookup_var tyvars o fst) vs);
   2.262 +            fun add_inst_typ p = Pretty.block [p, str "[", p_inst_typ, str "]"];
   2.263 +            val ((implicit_names, implicit_ps), vars) = implicit_arguments tyvars vs reserved;
   2.264 +            fun print_classparam_inst ((classparam, const as (_, (_, tys))), (thm, _)) =
   2.265 +              let
   2.266 +                val auxs = Name.invents (snd reserved) "a" (length tys);
   2.267 +                val vars = intro_vars auxs reserved;
   2.268 +                val args = if null auxs then [] else
   2.269 +                  [concat [enum "," "(" ")" (map2 (fn aux => fn ty => print_typed tyvars ((str o lookup_var vars) aux) ty)
   2.270 +                    auxs tys), str "=>"]];
   2.271 +              in 
   2.272 +                concat ([str "val", (str o suffix "$" o deresolve_base) classparam,
   2.273 +                  str "="] @ args @ [print_app tyvars false thm vars NOBR (const, map (IVar o SOME) auxs)])
   2.274 +              end;
   2.275 +          in
   2.276 +            Pretty.chunks [
   2.277 +              Pretty.block_enclose
   2.278 +                (concat ([str "trait",
   2.279 +                    add_typ_params ((str o deresolve_base) name),
   2.280 +                    str "extends",
   2.281 +                    Pretty.block [(str o deresolve) class, str "[", p_inst_typ, str "]"]]
   2.282 +                    @ map (fn (_, (_, (superinst, _))) => add_typ_params (str ("with " ^ deresolve superinst)))
   2.283 +                      super_instances @| str "{"), str "}")
   2.284 +                (map (fn p => Pretty.block [str "implicit val arg$", p]) implicit_ps
   2.285 +                  @ map print_classparam_inst classparam_insts),
   2.286 +              concat [str "implicit", str (if null vs then "val" else "def"),
   2.287 +                applify "(implicit " ")" NOBR (applify "[" "]" NOBR
   2.288 +                  ((str o deresolve_base) name) (map (str o lookup_var tyvars o fst) vs))
   2.289 +                    implicit_ps,
   2.290 +                  str "=", str "new", applify "[" "]" NOBR ((str o deresolve_base) name)
   2.291 +                      (map (str o lookup_var tyvars o fst) vs),
   2.292 +                    Pretty.enum ";" "{ " " }" (map (str o (fn v => "val arg$" ^ v ^ " = " ^ v) o lookup_var vars)
   2.293 +                      implicit_names)]
   2.294 +            ]
   2.295 +          end;
   2.296 +  in print_stmt end;
   2.297 +
   2.298 +fun scala_program_of_program labelled_name module_name reserved raw_module_alias program =
   2.299 +  let
   2.300 +    val the_module_name = the_default "Program" module_name;
   2.301 +    val module_alias = K (SOME the_module_name);
   2.302 +    val reserved = Name.make_context reserved;
   2.303 +    fun prepare_stmt (name, stmt) (nsps, stmts) =
   2.304 +      let
   2.305 +        val (_, base) = Code_Printer.dest_name name;
   2.306 +        val mk_name_stmt = yield_singleton Name.variants;
   2.307 +        fun add_class ((nsp_class, nsp_object), nsp_common) =
   2.308 +          let
   2.309 +            val (base', nsp_class') = mk_name_stmt base nsp_class
   2.310 +          in (base', ((nsp_class', nsp_object), Name.declare base' nsp_common)) end;
   2.311 +        fun add_object ((nsp_class, nsp_object), nsp_common) =
   2.312 +          let
   2.313 +            val (base', nsp_object') = mk_name_stmt base nsp_object
   2.314 +          in (base', ((nsp_class, nsp_object'), Name.declare base' nsp_common)) end;
   2.315 +        fun add_common upper ((nsp_class, nsp_object), nsp_common) =
   2.316 +          let
   2.317 +            val (base', nsp_common') =
   2.318 +              mk_name_stmt (if upper then first_upper base else base) nsp_common
   2.319 +          in (base', ((Name.declare base' nsp_class, Name.declare base' nsp_object), nsp_common')) end;
   2.320 +        val add_name = case stmt
   2.321 +         of Code_Thingol.Fun _ => add_object
   2.322 +          | Code_Thingol.Datatype _ => add_class
   2.323 +          | Code_Thingol.Datatypecons _ => add_common true
   2.324 +          | Code_Thingol.Class _ => add_class
   2.325 +          | Code_Thingol.Classrel _ => add_object
   2.326 +          | Code_Thingol.Classparam _ => add_object
   2.327 +          | Code_Thingol.Classinst _ => add_common false;
   2.328 +        fun add_stmt base' = case stmt
   2.329 +         of Code_Thingol.Datatypecons _ => cons (name, (base', NONE))
   2.330 +          | Code_Thingol.Classrel _ => cons (name, (base', NONE))
   2.331 +          | Code_Thingol.Classparam _ => cons (name, (base', NONE))
   2.332 +          | _ => cons (name, (base', SOME stmt));
   2.333 +      in
   2.334 +        nsps
   2.335 +        |> add_name
   2.336 +        |-> (fn base' => rpair (add_stmt base' stmts))
   2.337 +      end;
   2.338 +    val (_, sca_program) = fold prepare_stmt (AList.make (fn name => Graph.get_node program name)
   2.339 +      (Graph.strong_conn program |> flat)) (((reserved, reserved), reserved), []);
   2.340 +    fun deresolver name = (fst o the o AList.lookup (op =) sca_program) name
   2.341 +      handle Option => error ("Unknown statement name: " ^ labelled_name name);
   2.342 +  in (deresolver, (the_module_name, sca_program)) end;
   2.343 +
   2.344 +fun serialize_scala raw_module_name labelled_name
   2.345 +    raw_reserved includes raw_module_alias
   2.346 +    _ syntax_tyco syntax_const (code_of_pretty, code_writeln) program cs destination =
   2.347 +  let
   2.348 +    val stmt_names = Code_Target.stmt_names_of_destination destination;
   2.349 +    val module_name = if null stmt_names then raw_module_name else SOME "Code";
   2.350 +    val reserved = fold (insert (op =) o fst) includes raw_reserved;
   2.351 +    val (deresolver, (the_module_name, sca_program)) = scala_program_of_program labelled_name
   2.352 +      module_name reserved raw_module_alias program;
   2.353 +    val reserved = make_vars reserved;
   2.354 +    fun args_num c = case Graph.get_node program c
   2.355 +     of Code_Thingol.Fun (_, ((_, ty), [])) => (length o fst o Code_Thingol.unfold_fun) ty
   2.356 +      | Code_Thingol.Fun (_, (_, ((ts, _), _) :: _)) => length ts
   2.357 +      | Code_Thingol.Datatypecons (_, tyco) =>
   2.358 +          let val Code_Thingol.Datatype (_, (_, dtcos)) = Graph.get_node program tyco
   2.359 +          in (length o the o AList.lookup (op =) dtcos) c end
   2.360 +      | Code_Thingol.Classparam (_, class) =>
   2.361 +          let val Code_Thingol.Class (_, (_, (_, classparams))) = Graph.get_node program class
   2.362 +          in (length o fst o Code_Thingol.unfold_fun o the o AList.lookup (op =) classparams) c end;
   2.363 +    fun is_singleton c = case Graph.get_node program c
   2.364 +     of Code_Thingol.Datatypecons (_, tyco) =>
   2.365 +          let val Code_Thingol.Datatype (_, (_, dtcos)) = Graph.get_node program tyco
   2.366 +          in (null o the o AList.lookup (op =) dtcos) c end
   2.367 +      | _ => false;
   2.368 +    val print_stmt = print_scala_stmt labelled_name syntax_tyco syntax_const
   2.369 +      reserved args_num is_singleton deresolver;
   2.370 +    fun print_module name content =
   2.371 +      (name, Pretty.chunks [
   2.372 +        str ("object " ^ name ^ " {"),
   2.373 +        str "",
   2.374 +        content,
   2.375 +        str "",
   2.376 +        str "}"
   2.377 +      ]);
   2.378 +    fun serialize_module the_module_name sca_program =
   2.379 +      let
   2.380 +        val content = Pretty.chunks2 (map_filter
   2.381 +          (fn (name, (_, SOME stmt)) => SOME (print_stmt (name, stmt))
   2.382 +            | (_, (_, NONE)) => NONE) sca_program);
   2.383 +      in print_module the_module_name content end;
   2.384 +    fun check_destination destination =
   2.385 +      (File.check destination; destination);
   2.386 +    fun write_module destination (modlname, content) =
   2.387 +      let
   2.388 +        val filename = case modlname
   2.389 +         of "" => Path.explode "Main.scala"
   2.390 +          | _ => (Path.ext "scala" o Path.explode o implode o separate "/"
   2.391 +                o Long_Name.explode) modlname;
   2.392 +        val pathname = Path.append destination filename;
   2.393 +        val _ = File.mkdir (Path.dir pathname);
   2.394 +      in File.write pathname (code_of_pretty content) end
   2.395 +  in
   2.396 +    Code_Target.mk_serialization target NONE
   2.397 +      (fn NONE => K () o map (code_writeln o snd) | SOME file => K () o map
   2.398 +        (write_module (check_destination file)))
   2.399 +      (rpair [] o cat_lines o map (code_of_pretty o snd))
   2.400 +      (map (uncurry print_module) includes
   2.401 +        @| serialize_module the_module_name sca_program)
   2.402 +      destination
   2.403 +  end;
   2.404 +
   2.405 +val literals = let
   2.406 +  fun char_scala c =
   2.407 +    let
   2.408 +      val s = ML_Syntax.print_char c;
   2.409 +    in if s = "'" then "\\'" else s end;
   2.410 +in Literals {
   2.411 +  literal_char = Library.enclose "'" "'" o char_scala,
   2.412 +  literal_string = quote o translate_string char_scala,
   2.413 +  literal_numeral = fn unbounded => fn k => if k >= 0 then string_of_int k
   2.414 +    else Library.enclose "(" ")" (signed_string_of_int k),
   2.415 +  literal_list = fn ps => Pretty.block [str "List", enum "," "(" ")" ps],
   2.416 +  infix_cons = (6, "::")
   2.417 +} end;
   2.418 +
   2.419 +
   2.420 +(** Isar setup **)
   2.421 +
   2.422 +fun isar_seri_scala module_name =
   2.423 +  Code_Target.parse_args (Scan.succeed ())
   2.424 +  #> (fn () => serialize_scala module_name);
   2.425 +
   2.426 +val setup =
   2.427 +  Code_Target.add_target (target, (isar_seri_scala, literals))
   2.428 +  #> Code_Target.add_syntax_tyco target "fun" (SOME (2, fn print_typ => fn fxy => fn [ty1, ty2] =>
   2.429 +      brackify_infix (1, R) fxy [
   2.430 +        print_typ (INFX (1, X)) ty1,
   2.431 +        str "=>",
   2.432 +        print_typ (INFX (1, R)) ty2
   2.433 +      ]))
   2.434 +  #> fold (Code_Target.add_reserved target) [
   2.435 +      "abstract", "case", "catch", "class", "def", "do", "else", "extends", "false",
   2.436 +      "final", "finally", "for", "forSome", "if", "implicit", "import", "lazy",
   2.437 +      "match", "new", "null", "object", "override", "package", "private", "protected",
   2.438 +      "requires", "return", "sealed", "super", "this", "throw", "trait", "try",
   2.439 +      "true", "type", "val", "var", "while", "with"
   2.440 +    ]
   2.441 +  #> fold (Code_Target.add_reserved target) [
   2.442 +      "error", "apply", "List"
   2.443 +    ];
   2.444 +
   2.445 +end; (*struct*)
     3.1 --- a/src/Tools/Code_Generator.thy	Tue Jan 05 16:55:00 2010 +0100
     3.2 +++ b/src/Tools/Code_Generator.thy	Fri Jan 08 12:25:15 2010 +0100
     3.3 @@ -18,6 +18,7 @@
     3.4    "~~/src/Tools/Code/code_ml.ML"
     3.5    "~~/src/Tools/Code/code_eval.ML"
     3.6    "~~/src/Tools/Code/code_haskell.ML"
     3.7 +  "~~/src/Tools/Code/code_scala.ML"
     3.8    "~~/src/Tools/nbe.ML"
     3.9  begin
    3.10  
    3.11 @@ -26,6 +27,7 @@
    3.12    #> Code_ML.setup
    3.13    #> Code_Eval.setup
    3.14    #> Code_Haskell.setup
    3.15 +  #> Code_Scala.setup
    3.16    #> Nbe.setup
    3.17  *}
    3.18