1 (* Title: Tools/Code/code_ml.ML
2 Author: Florian Haftmann, TU Muenchen
4 Serializer for SML and OCaml.
10 val target_OCaml: string
11 val setup: theory -> theory
14 structure Code_ML : CODE_ML =
17 open Basic_Code_Thingol;
26 val target_SML = "SML";
27 val target_OCaml = "OCaml";
30 ML_Function of string * (typscheme * ((iterm list * iterm) * (thm option * bool)) list)
31 | ML_Instance of string * ((class * (string * (vname * sort) list))
32 * ((class * (string * (string * dict list list))) list
33 * (((string * const) * (thm * bool)) list * ((string * const) * (thm * bool)) list)));
36 ML_Exc of string * (typscheme * int)
37 | ML_Val of ml_binding
38 | ML_Funs of ml_binding list * string list
39 | ML_Datas of (string * (vname list * ((string * vname list) * itype list) list)) list
40 | ML_Class of string * (vname * ((class * string) list * (string * itype) list));
42 fun print_product _ [] = NONE
43 | print_product print [x] = SOME (print x)
44 | print_product print xs = (SOME o enum " *" "" "") (map print xs);
46 fun tuplify _ _ [] = NONE
47 | tuplify print fxy [x] = SOME (print fxy x)
48 | tuplify print _ xs = SOME (enum "," "(" ")" (map (print NOBR) xs));
51 (** SML serializer **)
53 fun print_sml_stmt tyco_syntax const_syntax reserved is_cons deresolve =
55 fun print_tyco_expr (tyco, []) = (str o deresolve) tyco
56 | print_tyco_expr (tyco, [ty]) =
57 concat [print_typ BR ty, (str o deresolve) tyco]
58 | print_tyco_expr (tyco, tys) =
59 concat [enum "," "(" ")" (map (print_typ BR) tys), (str o deresolve) tyco]
60 and print_typ fxy (tyco `%% tys) = (case tyco_syntax tyco
61 of NONE => print_tyco_expr (tyco, tys)
62 | SOME (_, print) => print print_typ fxy tys)
63 | print_typ fxy (ITyVar v) = str ("'" ^ v);
64 fun print_dicttyp (class, ty) = print_tyco_expr (class, [ty]);
65 fun print_typscheme_prefix (vs, p) = enum " ->" "" ""
66 (map_filter (fn (v, sort) =>
67 (print_product (fn class => print_dicttyp (class, ITyVar v)) sort)) vs @| p);
68 fun print_typscheme (vs, ty) = print_typscheme_prefix (vs, print_typ NOBR ty);
69 fun print_dicttypscheme (vs, class_ty) = print_typscheme_prefix (vs, print_dicttyp class_ty);
70 fun print_classrels fxy [] ps = brackify fxy ps
71 | print_classrels fxy [classrel] ps = brackify fxy [(str o deresolve) classrel, brackify BR ps]
72 | print_classrels fxy classrels ps =
73 brackify fxy [enum " o" "(" ")" (map (str o deresolve) classrels), brackify BR ps]
74 fun print_dict is_pseudo_fun fxy (Dict (classrels, x)) =
75 print_classrels fxy classrels (print_plain_dict is_pseudo_fun fxy x)
76 and print_plain_dict is_pseudo_fun fxy (Dict_Const (inst, dss)) =
77 ((str o deresolve) inst ::
78 (if is_pseudo_fun inst then [str "()"]
79 else map_filter (print_dicts is_pseudo_fun BR) dss))
80 | print_plain_dict is_pseudo_fun fxy (Dict_Var (v, (i, k))) =
81 [str (if k = 1 then first_upper v ^ "_"
82 else first_upper v ^ string_of_int (i+1) ^ "_")]
83 and print_dicts is_pseudo_fun = tuplify (print_dict is_pseudo_fun);
84 val print_dict_args = map_filter (fn (v, sort) => print_dicts (K false) BR
85 (map_index (fn (i, _) => Dict ([], Dict_Var (v, (i, length sort)))) sort));
86 fun print_term is_pseudo_fun some_thm vars fxy (IConst c) =
87 print_app is_pseudo_fun some_thm vars fxy (c, [])
88 | print_term is_pseudo_fun some_thm vars fxy (IVar NONE) =
90 | print_term is_pseudo_fun some_thm vars fxy (IVar (SOME v)) =
91 str (lookup_var vars v)
92 | print_term is_pseudo_fun some_thm vars fxy (t as t1 `$ t2) =
93 (case Code_Thingol.unfold_const_app t
94 of SOME c_ts => print_app is_pseudo_fun some_thm vars fxy c_ts
95 | NONE => brackify fxy [print_term is_pseudo_fun some_thm vars NOBR t1,
96 print_term is_pseudo_fun some_thm vars BR t2])
97 | print_term is_pseudo_fun some_thm vars fxy (t as _ `|=> _) =
99 val (binds, t') = Code_Thingol.unfold_pat_abs t;
100 fun print_abs (pat, ty) =
101 print_bind is_pseudo_fun some_thm NOBR pat
102 #>> (fn p => concat [str "fn", p, str "=>"]);
103 val (ps, vars') = fold_map print_abs binds vars;
104 in brackets (ps @ [print_term is_pseudo_fun some_thm vars' NOBR t']) end
105 | print_term is_pseudo_fun some_thm vars fxy (ICase (cases as (_, t0))) =
106 (case Code_Thingol.unfold_const_app t0
107 of SOME (c_ts as ((c, _), _)) => if is_none (const_syntax c)
108 then print_case is_pseudo_fun some_thm vars fxy cases
109 else print_app is_pseudo_fun some_thm vars fxy c_ts
110 | NONE => print_case is_pseudo_fun some_thm vars fxy cases)
111 and print_app_expr is_pseudo_fun some_thm vars (app as ((c, (((_, iss), (arg_tys, _)), _)), ts)) =
113 let val k = length arg_tys in
114 if k < 2 orelse length ts = k
115 then (str o deresolve) c
116 :: the_list (tuplify (print_term is_pseudo_fun some_thm vars) BR ts)
117 else [print_term is_pseudo_fun some_thm vars BR (Code_Thingol.eta_expand k app)]
119 else if is_pseudo_fun c
120 then (str o deresolve) c @@ str "()"
121 else (str o deresolve) c :: map_filter (print_dicts is_pseudo_fun BR) iss
122 @ map (print_term is_pseudo_fun some_thm vars BR) ts
123 and print_app is_pseudo_fun some_thm vars = gen_print_app (print_app_expr is_pseudo_fun)
124 (print_term is_pseudo_fun) const_syntax some_thm vars
125 and print_bind is_pseudo_fun = gen_print_bind (print_term is_pseudo_fun)
126 and print_case is_pseudo_fun some_thm vars fxy (cases as ((_, [_]), _)) =
128 val (binds, body) = Code_Thingol.unfold_let (ICase cases);
129 fun print_match ((pat, _), t) vars =
131 |> print_bind is_pseudo_fun some_thm NOBR pat
132 |>> (fn p => semicolon [str "val", p, str "=",
133 print_term is_pseudo_fun some_thm vars NOBR t])
134 val (ps, vars') = fold_map print_match binds vars;
137 Pretty.block [str "let", Pretty.fbrk, Pretty.chunks ps],
138 Pretty.block [str "in", Pretty.fbrk, print_term is_pseudo_fun some_thm vars' NOBR body],
142 | print_case is_pseudo_fun some_thm vars fxy (((t, ty), clause :: clauses), _) =
144 fun print_select delim (pat, body) =
146 val (p, vars') = print_bind is_pseudo_fun some_thm NOBR pat vars;
148 concat [str delim, p, str "=>", print_term is_pseudo_fun some_thm vars' NOBR body]
153 :: print_term is_pseudo_fun some_thm vars NOBR t
154 :: print_select "of" clause
155 :: map (print_select "|") clauses
158 | print_case is_pseudo_fun some_thm vars fxy ((_, []), _) =
159 (concat o map str) ["raise", "Fail", "\"empty case\""];
160 fun print_val_decl print_typscheme (name, typscheme) = concat
161 [str "val", str (deresolve name), str ":", print_typscheme typscheme];
162 fun print_datatype_decl definer (tyco, (vs, cos)) =
164 fun print_co ((co, _), []) = str (deresolve co)
165 | print_co ((co, _), tys) = concat [str (deresolve co), str "of",
166 enum " *" "" "" (map (print_typ (INFX (2, X))) tys)];
170 :: print_tyco_expr (tyco, map ITyVar vs)
172 :: separate (str "|") (map print_co cos)
175 fun print_def is_pseudo_fun needs_typ definer
176 (ML_Function (name, (vs_ty as (vs, ty), eq :: eqs))) =
178 fun print_eqn definer ((ts, t), (some_thm, _)) =
180 val consts = fold Code_Thingol.add_constnames (t :: ts) [];
183 (is_none o const_syntax) deresolve consts
184 |> intro_vars ((fold o Code_Thingol.fold_varnames)
185 (insert (op =)) ts []);
186 val prolog = if needs_typ then
187 concat [str definer, (str o deresolve) name, str ":", print_typ NOBR ty]
188 else (concat o map str) [definer, deresolve name];
192 :: (if is_pseudo_fun name then [str "()"]
193 else print_dict_args vs
194 @ map (print_term is_pseudo_fun some_thm vars BR) ts)
196 @@ print_term is_pseudo_fun some_thm vars NOBR t
199 val shift = if null eqs then I else
200 map (Pretty.block o single o Pretty.block o single);
202 (print_val_decl print_typscheme (name, vs_ty))
203 ((Pretty.block o Pretty.fbreaks o shift) (
205 :: map (print_eqn "|") eqs
208 | print_def is_pseudo_fun _ definer
209 (ML_Instance (inst, ((class, (tyco, vs)), (super_instances, (classparam_instances, _))))) =
211 fun print_super_instance (_, (classrel, x)) =
213 (str o Long_Name.base_name o deresolve) classrel,
215 print_dict is_pseudo_fun NOBR (Dict ([], Dict_Const x))
217 fun print_classparam_instance ((classparam, const), (thm, _)) =
219 (str o Long_Name.base_name o deresolve) classparam,
221 print_app (K false) (SOME thm) reserved NOBR (const, [])
224 (print_val_decl print_dicttypscheme
225 (inst, (vs, (class, tyco `%% map (ITyVar o fst) vs))))
228 :: (str o deresolve) inst
229 :: (if is_pseudo_fun inst then [str "()"]
230 else print_dict_args vs)
233 (map print_super_instance super_instances
234 @ map print_classparam_instance classparam_instances)
236 @@ print_tyco_expr (class, [tyco `%% map (ITyVar o fst) vs])
239 fun print_stmt (ML_Exc (name, (vs_ty, n))) = pair
240 [print_val_decl print_typscheme (name, vs_ty)]
241 ((semicolon o map str) (
242 (if n = 0 then "val" else "fun")
248 @@ (ML_Syntax.print_string o Long_Name.base_name o Long_Name.qualifier) name
250 | print_stmt (ML_Val binding) =
252 val (sig_p, p) = print_def (K false) true "val" binding
257 | print_stmt (ML_Funs (binding :: bindings, pseudo_funs)) =
259 val print_def' = print_def (member (op =) pseudo_funs) false;
260 fun print_pseudo_fun name = concat [
262 (str o deresolve) name,
264 (str o deresolve) name,
267 val (sig_ps, (ps, p)) = (apsnd split_last o split_list)
268 (print_def' "fun" binding :: map (print_def' "and") bindings);
269 val pseudo_ps = map print_pseudo_fun pseudo_funs;
272 (Pretty.chunks (ps @ semicolon [p] :: pseudo_ps))
274 | print_stmt (ML_Datas [(tyco, (vs, []))]) =
276 val ty_p = print_tyco_expr (tyco, map ITyVar vs);
279 [concat [str "type", ty_p]]
280 (concat [str "datatype", ty_p, str "=", str "EMPTY__"])
282 | print_stmt (ML_Datas (data :: datas)) =
284 val sig_ps = print_datatype_decl "datatype" data
285 :: map (print_datatype_decl "and") datas;
286 val (ps, p) = split_last sig_ps;
289 (Pretty.chunks (ps @| semicolon [p]))
291 | print_stmt (ML_Class (class, (v, (super_classes, classparams)))) =
293 fun print_field s p = concat [str s, str ":", p];
294 fun print_proj s p = semicolon
295 (map str ["val", s, "=", "#" ^ s, ":"] @| p);
296 fun print_super_class_decl (super_class, classrel) =
297 print_val_decl print_dicttypscheme
298 (classrel, ([(v, [class])], (super_class, ITyVar v)));
299 fun print_super_class_field (super_class, classrel) =
300 print_field (deresolve classrel) (print_dicttyp (super_class, ITyVar v));
301 fun print_super_class_proj (super_class, classrel) =
302 print_proj (deresolve classrel)
303 (print_dicttypscheme ([(v, [class])], (super_class, ITyVar v)));
304 fun print_classparam_decl (classparam, ty) =
305 print_val_decl print_typscheme
306 (classparam, ([(v, [class])], ty));
307 fun print_classparam_field (classparam, ty) =
308 print_field (deresolve classparam) (print_typ NOBR ty);
309 fun print_classparam_proj (classparam, ty) =
310 print_proj (deresolve classparam)
311 (print_typscheme ([(v, [class])], ty));
313 (concat [str "type", print_dicttyp (class, ITyVar v)]
314 :: map print_super_class_decl super_classes
315 @ map print_classparam_decl classparams)
319 (str o deresolve) class,
322 map print_super_class_field super_classes
323 @ map print_classparam_field classparams
326 :: map print_super_class_proj super_classes
327 @ map print_classparam_proj classparams
332 fun print_sml_module name some_decls body =
335 str ("structure " ^ name ^ (if is_some some_decls then " : sig" else " ="))
336 :: (the_list o Option.map (indent 2 o Pretty.chunks)) some_decls
337 @| (if is_some some_decls then str "end = struct" else str "struct")
340 @| str ("end; (*struct " ^ name ^ "*)")
343 val literals_sml = Literals {
344 literal_char = prefix "#" o quote o ML_Syntax.print_char,
345 literal_string = quote o translate_string ML_Syntax.print_char,
346 literal_numeral = fn k => "(" ^ string_of_int k ^ " : IntInf.int)",
347 literal_positive_numeral = fn k => "(" ^ string_of_int k ^ " : IntInf.int)",
348 literal_alternative_numeral = fn k => "(" ^ string_of_int k ^ " : IntInf.int)",
349 literal_naive_numeral = string_of_int,
350 literal_list = enum "," "[" "]",
351 infix_cons = (7, "::")
355 (** OCaml serializer **)
357 fun print_ocaml_stmt tyco_syntax const_syntax reserved is_cons deresolve =
359 fun print_tyco_expr (tyco, []) = (str o deresolve) tyco
360 | print_tyco_expr (tyco, [ty]) =
361 concat [print_typ BR ty, (str o deresolve) tyco]
362 | print_tyco_expr (tyco, tys) =
363 concat [enum "," "(" ")" (map (print_typ BR) tys), (str o deresolve) tyco]
364 and print_typ fxy (tyco `%% tys) = (case tyco_syntax tyco
365 of NONE => print_tyco_expr (tyco, tys)
366 | SOME (_, print) => print print_typ fxy tys)
367 | print_typ fxy (ITyVar v) = str ("'" ^ v);
368 fun print_dicttyp (class, ty) = print_tyco_expr (class, [ty]);
369 fun print_typscheme_prefix (vs, p) = enum " ->" "" ""
370 (map_filter (fn (v, sort) =>
371 (print_product (fn class => print_dicttyp (class, ITyVar v)) sort)) vs @| p);
372 fun print_typscheme (vs, ty) = print_typscheme_prefix (vs, print_typ NOBR ty);
373 fun print_dicttypscheme (vs, class_ty) = print_typscheme_prefix (vs, print_dicttyp class_ty);
374 val print_classrels =
375 fold_rev (fn classrel => fn p => Pretty.block [p, str ".", (str o deresolve) classrel])
376 fun print_dict is_pseudo_fun fxy (Dict (classrels, x)) =
377 print_plain_dict is_pseudo_fun fxy x
378 |> print_classrels classrels
379 and print_plain_dict is_pseudo_fun fxy (Dict_Const (inst, dss)) =
380 brackify BR ((str o deresolve) inst ::
381 (if is_pseudo_fun inst then [str "()"]
382 else map_filter (print_dicts is_pseudo_fun BR) dss))
383 | print_plain_dict is_pseudo_fun fxy (Dict_Var (v, (i, k))) =
384 str (if k = 1 then "_" ^ first_upper v
385 else "_" ^ first_upper v ^ string_of_int (i+1))
386 and print_dicts is_pseudo_fun = tuplify (print_dict is_pseudo_fun);
387 val print_dict_args = map_filter (fn (v, sort) => print_dicts (K false) BR
388 (map_index (fn (i, _) => Dict ([], Dict_Var (v, (i, length sort)))) sort));
389 fun print_term is_pseudo_fun some_thm vars fxy (IConst c) =
390 print_app is_pseudo_fun some_thm vars fxy (c, [])
391 | print_term is_pseudo_fun some_thm vars fxy (IVar NONE) =
393 | print_term is_pseudo_fun some_thm vars fxy (IVar (SOME v)) =
394 str (lookup_var vars v)
395 | print_term is_pseudo_fun some_thm vars fxy (t as t1 `$ t2) =
396 (case Code_Thingol.unfold_const_app t
397 of SOME c_ts => print_app is_pseudo_fun some_thm vars fxy c_ts
398 | NONE => brackify fxy [print_term is_pseudo_fun some_thm vars NOBR t1,
399 print_term is_pseudo_fun some_thm vars BR t2])
400 | print_term is_pseudo_fun some_thm vars fxy (t as _ `|=> _) =
402 val (binds, t') = Code_Thingol.unfold_pat_abs t;
403 val (ps, vars') = fold_map (print_bind is_pseudo_fun some_thm BR o fst) binds vars;
404 in brackets (str "fun" :: ps @ str "->" @@ print_term is_pseudo_fun some_thm vars' NOBR t') end
405 | print_term is_pseudo_fun some_thm vars fxy (ICase (cases as (_, t0))) =
406 (case Code_Thingol.unfold_const_app t0
407 of SOME (c_ts as ((c, _), _)) => if is_none (const_syntax c)
408 then print_case is_pseudo_fun some_thm vars fxy cases
409 else print_app is_pseudo_fun some_thm vars fxy c_ts
410 | NONE => print_case is_pseudo_fun some_thm vars fxy cases)
411 and print_app_expr is_pseudo_fun some_thm vars (app as ((c, (((_, iss), (tys, _)), _)), ts)) =
413 let val k = length tys in
415 then (str o deresolve) c
416 :: the_list (tuplify (print_term is_pseudo_fun some_thm vars) BR ts)
417 else [print_term is_pseudo_fun some_thm vars BR (Code_Thingol.eta_expand k app)]
419 else if is_pseudo_fun c
420 then (str o deresolve) c @@ str "()"
421 else (str o deresolve) c :: map_filter (print_dicts is_pseudo_fun BR) iss
422 @ map (print_term is_pseudo_fun some_thm vars BR) ts
423 and print_app is_pseudo_fun some_thm vars = gen_print_app (print_app_expr is_pseudo_fun)
424 (print_term is_pseudo_fun) const_syntax some_thm vars
425 and print_bind is_pseudo_fun = gen_print_bind (print_term is_pseudo_fun)
426 and print_case is_pseudo_fun some_thm vars fxy (cases as ((_, [_]), _)) =
428 val (binds, body) = Code_Thingol.unfold_let (ICase cases);
429 fun print_let ((pat, _), t) vars =
431 |> print_bind is_pseudo_fun some_thm NOBR pat
433 [str "let", p, str "=", print_term is_pseudo_fun some_thm vars NOBR t, str "in"])
434 val (ps, vars') = fold_map print_let binds vars;
436 brackify_block fxy (Pretty.chunks ps) []
437 (print_term is_pseudo_fun some_thm vars' NOBR body)
439 | print_case is_pseudo_fun some_thm vars fxy (((t, ty), clause :: clauses), _) =
441 fun print_select delim (pat, body) =
443 val (p, vars') = print_bind is_pseudo_fun some_thm NOBR pat vars;
444 in concat [str delim, p, str "->", print_term is_pseudo_fun some_thm vars' NOBR body] end;
448 :: print_term is_pseudo_fun some_thm vars NOBR t
449 :: print_select "with" clause
450 :: map (print_select "|") clauses
453 | print_case is_pseudo_fun some_thm vars fxy ((_, []), _) =
454 (concat o map str) ["failwith", "\"empty case\""];
455 fun print_val_decl print_typscheme (name, typscheme) = concat
456 [str "val", str (deresolve name), str ":", print_typscheme typscheme];
457 fun print_datatype_decl definer (tyco, (vs, cos)) =
459 fun print_co ((co, _), []) = str (deresolve co)
460 | print_co ((co, _), tys) = concat [str (deresolve co), str "of",
461 enum " *" "" "" (map (print_typ (INFX (2, X))) tys)];
465 :: print_tyco_expr (tyco, map ITyVar vs)
467 :: separate (str "|") (map print_co cos)
470 fun print_def is_pseudo_fun needs_typ definer
471 (ML_Function (name, (vs_ty as (vs, ty), eqs))) =
473 fun print_eqn ((ts, t), (some_thm, _)) =
475 val consts = fold Code_Thingol.add_constnames (t :: ts) [];
478 (is_none o const_syntax) deresolve consts
479 |> intro_vars ((fold o Code_Thingol.fold_varnames)
480 (insert (op =)) ts []);
482 (Pretty.block o commas)
483 (map (print_term is_pseudo_fun some_thm vars NOBR) ts),
485 print_term is_pseudo_fun some_thm vars NOBR t
487 fun print_eqns is_pseudo [((ts, t), (some_thm, _))] =
489 val consts = fold Code_Thingol.add_constnames (t :: ts) [];
492 (is_none o const_syntax) deresolve consts
493 |> intro_vars ((fold o Code_Thingol.fold_varnames)
494 (insert (op =)) ts []);
497 (if is_pseudo then [str "()"]
498 else map (print_term is_pseudo_fun some_thm vars BR) ts)
500 @@ print_term is_pseudo_fun some_thm vars NOBR t
503 | print_eqns _ ((eq as (([_], _), _)) :: eqs) =
510 :: maps (append [Pretty.fbrk, str "|", Pretty.brk 1]
511 o single o print_eqn) eqs
513 | print_eqns _ (eqs as eq :: eqs') =
515 val consts = fold Code_Thingol.add_constnames (map (snd o fst) eqs) [];
518 (is_none o const_syntax) deresolve consts;
519 val dummy_parms = (map str o aux_params vars o map (fst o fst)) eqs;
522 Pretty.breaks dummy_parms
528 :: (Pretty.block o commas) dummy_parms
533 :: maps (append [Pretty.fbrk, str "|", Pretty.brk 1]
534 o single o print_eqn) eqs'
537 val prolog = if needs_typ then
538 concat [str definer, (str o deresolve) name, str ":", print_typ NOBR ty]
539 else (concat o map str) [definer, deresolve name];
541 (print_val_decl print_typscheme (name, vs_ty))
544 :: print_dict_args vs
545 @| print_eqns (is_pseudo_fun name) eqs
548 | print_def is_pseudo_fun _ definer
549 (ML_Instance (inst, ((class, (tyco, vs)), (super_instances, (classparam_instances, _))))) =
551 fun print_super_instance (_, (classrel, x)) =
553 (str o deresolve) classrel,
555 print_dict is_pseudo_fun NOBR (Dict ([], Dict_Const x))
557 fun print_classparam_instance ((classparam, const), (thm, _)) =
559 (str o deresolve) classparam,
561 print_app (K false) (SOME thm) reserved NOBR (const, [])
564 (print_val_decl print_dicttypscheme
565 (inst, (vs, (class, tyco `%% map (ITyVar o fst) vs))))
568 :: (str o deresolve) inst
569 :: (if is_pseudo_fun inst then [str "()"]
570 else print_dict_args vs)
573 enum_default "()" ";" "{" "}" (map print_super_instance super_instances
574 @ map print_classparam_instance classparam_instances),
576 print_tyco_expr (class, [tyco `%% map (ITyVar o fst) vs])
580 fun print_stmt (ML_Exc (name, (vs_ty, n))) = pair
581 [print_val_decl print_typscheme (name, vs_ty)]
582 ((doublesemicolon o map str) (
588 @@ (ML_Syntax.print_string o Long_Name.base_name o Long_Name.qualifier) name
590 | print_stmt (ML_Val binding) =
592 val (sig_p, p) = print_def (K false) true "let" binding
595 (doublesemicolon [p])
597 | print_stmt (ML_Funs (binding :: bindings, pseudo_funs)) =
599 val print_def' = print_def (member (op =) pseudo_funs) false;
600 fun print_pseudo_fun name = concat [
602 (str o deresolve) name,
604 (str o deresolve) name,
607 val (sig_ps, (ps, p)) = (apsnd split_last o split_list)
608 (print_def' "let rec" binding :: map (print_def' "and") bindings);
609 val pseudo_ps = map print_pseudo_fun pseudo_funs;
612 (Pretty.chunks (ps @ doublesemicolon [p] :: pseudo_ps))
614 | print_stmt (ML_Datas [(tyco, (vs, []))]) =
616 val ty_p = print_tyco_expr (tyco, map ITyVar vs);
619 [concat [str "type", ty_p]]
620 (concat [str "type", ty_p, str "=", str "EMPTY__"])
622 | print_stmt (ML_Datas (data :: datas)) =
624 val sig_ps = print_datatype_decl "type" data
625 :: map (print_datatype_decl "and") datas;
626 val (ps, p) = split_last sig_ps;
629 (Pretty.chunks (ps @| doublesemicolon [p]))
631 | print_stmt (ML_Class (class, (v, (super_classes, classparams)))) =
633 fun print_field s p = concat [str s, str ":", p];
634 fun print_super_class_field (super_class, classrel) =
635 print_field (deresolve classrel) (print_dicttyp (super_class, ITyVar v));
636 fun print_classparam_decl (classparam, ty) =
637 print_val_decl print_typscheme
638 (classparam, ([(v, [class])], ty));
639 fun print_classparam_field (classparam, ty) =
640 print_field (deresolve classparam) (print_typ NOBR ty);
641 val w = "_" ^ first_upper v;
642 fun print_classparam_proj (classparam, _) =
643 (concat o map str) ["let", deresolve classparam, w, "=",
644 w ^ "." ^ deresolve classparam ^ ";;"];
645 val type_decl_p = concat [
647 (str o deresolve) class,
649 enum_default "unit" ";" "{" "}" (
650 map print_super_class_field super_classes
651 @ map print_classparam_field classparams
655 (type_decl_p :: map print_classparam_decl classparams)
657 doublesemicolon [type_decl_p]
658 :: map print_classparam_proj classparams
663 fun print_ocaml_module name some_decls body =
666 str ("module " ^ name ^ (if is_some some_decls then " : sig" else " ="))
667 :: (the_list o Option.map (indent 2 o Pretty.chunks)) some_decls
668 @| (if is_some some_decls then str "end = struct" else str "struct")
671 @| str ("end;; (*struct " ^ name ^ "*)")
674 val literals_ocaml = let
677 val xs = string_of_int i;
678 val ys = replicate_string (3 - length (raw_explode xs)) "0";
679 in "\\" ^ ys ^ xs end;
683 val s = if i < 32 orelse i = 34 orelse i = 39 orelse i = 92 orelse i > 126
686 fun numeral_ocaml k = if k < 0
687 then "(Big_int.minus_big_int " ^ numeral_ocaml (~ k) ^ ")"
688 else if k <= 1073741823
689 then "(Big_int.big_int_of_int " ^ string_of_int k ^ ")"
690 else "(Big_int.big_int_of_string " ^ quote (string_of_int k) ^ ")"
692 literal_char = Library.enclose "'" "'" o char_ocaml,
693 literal_string = quote o translate_string char_ocaml,
694 literal_numeral = numeral_ocaml,
695 literal_positive_numeral = numeral_ocaml,
696 literal_alternative_numeral = numeral_ocaml,
697 literal_naive_numeral = numeral_ocaml,
698 literal_list = enum ";" "[" "]",
699 infix_cons = (6, "::")
704 (** SML/OCaml generic part **)
706 fun ml_program_of_program labelled_name reserved module_alias program =
708 fun namify_const upper base (nsp_const, nsp_type) =
710 val (base', nsp_const') =
711 Name.variant (if upper then first_upper base else base) nsp_const
712 in (base', (nsp_const', nsp_type)) end;
713 fun namify_type base (nsp_const, nsp_type) =
715 val (base', nsp_type') = Name.variant base nsp_type
716 in (base', (nsp_const, nsp_type')) end;
717 fun namify_stmt (Code_Thingol.Fun _) = namify_const false
718 | namify_stmt (Code_Thingol.Datatype _) = namify_type
719 | namify_stmt (Code_Thingol.Datatypecons _) = namify_const true
720 | namify_stmt (Code_Thingol.Class _) = namify_type
721 | namify_stmt (Code_Thingol.Classrel _) = namify_const false
722 | namify_stmt (Code_Thingol.Classparam _) = namify_const false
723 | namify_stmt (Code_Thingol.Classinst _) = namify_const false;
724 fun ml_binding_of_stmt (name, Code_Thingol.Fun (_, ((tysm as (vs, ty), raw_eqs), _))) =
726 val eqs = filter (snd o snd) raw_eqs;
727 val (eqs', some_value_name) = if null (filter_out (null o snd) vs) then case eqs
728 of [(([], t), some_thm)] => if (not o null o fst o Code_Thingol.unfold_fun) ty
729 then ([(([IVar (SOME "x")], t `$ IVar (SOME "x")), some_thm)], NONE)
730 else (eqs, SOME (name, member (op =) (Code_Thingol.add_constnames t []) name))
733 in (ML_Function (name, (tysm, eqs')), some_value_name) end
734 | ml_binding_of_stmt (name, Code_Thingol.Classinst (stmt as ((_, (_, vs)), _))) =
735 (ML_Instance (name, stmt), if forall (null o snd) vs then SOME (name, false) else NONE)
736 | ml_binding_of_stmt (name, _) =
737 error ("Binding block containing illegal statement: " ^ labelled_name name)
738 fun modify_fun (name, stmt) =
740 val (binding, some_value_name) = ml_binding_of_stmt (name, stmt);
741 val ml_stmt = case binding
742 of ML_Function (name, ((vs, ty), [])) =>
743 ML_Exc (name, ((vs, ty),
744 (length o filter_out (null o snd)) vs + (length o fst o Code_Thingol.unfold_fun) ty))
745 | _ => case some_value_name
746 of NONE => ML_Funs ([binding], [])
747 | SOME (name, true) => ML_Funs ([binding], [name])
748 | SOME (name, false) => ML_Val binding
750 fun modify_funs stmts = single (SOME
751 (ML_Funs (map_split ml_binding_of_stmt stmts |> (apsnd o map_filter o Option.map) fst)))
752 fun modify_datatypes stmts = single (SOME
753 (ML_Datas (map_filter
754 (fn (name, Code_Thingol.Datatype (_, stmt)) => SOME (name, stmt) | _ => NONE) stmts)))
755 fun modify_class stmts = single (SOME
756 (ML_Class (the_single (map_filter
757 (fn (name, Code_Thingol.Class (_, stmt)) => SOME (name, stmt) | _ => NONE) stmts))))
758 fun modify_stmts ([stmt as (_, stmt' as Code_Thingol.Fun _)]) =
759 if Code_Thingol.is_case stmt' then [] else [modify_fun stmt]
760 | modify_stmts ((stmts as (_, Code_Thingol.Fun _)::_)) =
761 modify_funs (filter_out (Code_Thingol.is_case o snd) stmts)
762 | modify_stmts ((stmts as (_, Code_Thingol.Datatypecons _)::_)) =
763 modify_datatypes stmts
764 | modify_stmts ((stmts as (_, Code_Thingol.Datatype _)::_)) =
765 modify_datatypes stmts
766 | modify_stmts ((stmts as (_, Code_Thingol.Class _)::_)) =
768 | modify_stmts ((stmts as (_, Code_Thingol.Classrel _)::_)) =
770 | modify_stmts ((stmts as (_, Code_Thingol.Classparam _)::_)) =
772 | modify_stmts ([stmt as (_, Code_Thingol.Classinst _)]) =
774 | modify_stmts ((stmts as (_, Code_Thingol.Classinst _)::_)) =
776 | modify_stmts stmts = error ("Illegal mutual dependencies: " ^
777 (Library.commas o map (labelled_name o fst)) stmts);
779 Code_Namespace.hierarchical_program labelled_name { module_alias = module_alias, reserved = reserved,
780 empty_nsp = (reserved, reserved), namify_module = pair, namify_stmt = namify_stmt,
781 cyclic_modules = false, empty_data = (), memorize_data = K I, modify_stmts = modify_stmts } program
784 fun serialize_ml print_ml_module print_ml_stmt with_signatures
785 { labelled_name, reserved_syms, includes, module_alias,
786 class_syntax, tyco_syntax, const_syntax } program =
790 val { deresolver, hierarchical_program = ml_program } =
791 ml_program_of_program labelled_name (Name.make_context reserved_syms) module_alias program;
793 (* print statements *)
794 fun print_stmt prefix_fragments (_, stmt) = print_ml_stmt
795 tyco_syntax const_syntax (make_vars reserved_syms)
796 (Code_Thingol.is_cons program) (deresolver prefix_fragments) stmt
800 fun print_module _ base _ xs =
802 val (raw_decls, body) = split_list xs;
803 val decls = if with_signatures then SOME (maps these raw_decls) else NONE
804 in (NONE, print_ml_module base decls body) end;
807 val p = Pretty.chunks2 (map snd includes
808 @ map snd (Code_Namespace.print_hierarchical {
809 print_module = print_module, print_stmt = print_stmt,
810 lift_markup = apsnd } ml_program));
811 fun write width NONE = writeln o format [] width
812 | write width (SOME p) = File.write p o format [] width;
814 Code_Target.serialization write (rpair (try (deresolver [])) ooo format) p
817 val serializer_sml : Code_Target.serializer =
818 Code_Target.parse_args (Scan.optional (Args.$$$ "no_signatures" >> K false) true
819 >> (fn with_signatures => serialize_ml print_sml_module print_sml_stmt with_signatures));
821 val serializer_ocaml : Code_Target.serializer =
822 Code_Target.parse_args (Scan.optional (Args.$$$ "no_signatures" >> K false) true
823 >> (fn with_signatures => serialize_ml print_ocaml_module print_ocaml_stmt with_signatures));
829 Code_Target.add_target
830 (target_SML, { serializer = serializer_sml, literals = literals_sml,
831 check = { env_var = "ISABELLE_PROCESS",
832 make_destination = fn p => Path.append p (Path.explode "ROOT.ML"),
833 make_command = fn _ => "\"$ISABELLE_PROCESS\" -r -q -u Pure" } })
834 #> Code_Target.add_target
835 (target_OCaml, { serializer = serializer_ocaml, literals = literals_ocaml,
836 check = { env_var = "ISABELLE_OCAML",
837 make_destination = fn p => Path.append p (Path.explode "ROOT.ocaml"),
838 make_command = fn _ => "\"$ISABELLE_OCAML\" -w pu nums.cma ROOT.ocaml" } })
839 #> Code_Target.add_tyco_syntax target_SML "fun" (SOME (2, fn print_typ => fn fxy => fn [ty1, ty2] =>
840 brackify_infix (1, R) fxy (
841 print_typ (INFX (1, X)) ty1,
843 print_typ (INFX (1, R)) ty2
845 #> Code_Target.add_tyco_syntax target_OCaml "fun" (SOME (2, fn print_typ => fn fxy => fn [ty1, ty2] =>
846 brackify_infix (1, R) fxy (
847 print_typ (INFX (1, X)) ty1,
849 print_typ (INFX (1, R)) ty2
851 #> fold (Code_Target.add_reserved target_SML) ML_Syntax.reserved_names
852 #> fold (Code_Target.add_reserved target_SML)
853 ["ref" (*rebinding is illegal*), "o" (*dictionary projections use it already*),
854 "Fail", "div", "mod" (*standard infixes*), "IntInf"]
855 #> fold (Code_Target.add_reserved target_OCaml) [
856 "and", "as", "assert", "begin", "class",
857 "constraint", "do", "done", "downto", "else", "end", "exception",
858 "external", "false", "for", "fun", "function", "functor", "if",
859 "in", "include", "inherit", "initializer", "lazy", "let", "match", "method",
860 "module", "mutable", "new", "object", "of", "open", "or", "private", "rec",
861 "sig", "struct", "then", "to", "true", "try", "type", "val",
862 "virtual", "when", "while", "with"
864 #> fold (Code_Target.add_reserved target_OCaml) ["failwith", "mod", "Big_int"];