23 |
23 |
24 (** Haskell serializer **) |
24 (** Haskell serializer **) |
25 |
25 |
26 fun pr_haskell_bind pr_term = |
26 fun pr_haskell_bind pr_term = |
27 let |
27 let |
28 fun pr_bind ((NONE, NONE), _) = str "_" |
28 fun pr_bind (NONE, _) = str "_" |
29 | pr_bind ((SOME v, NONE), _) = str v |
29 | pr_bind (SOME p, _) = p; |
30 | pr_bind ((NONE, SOME p), _) = p |
|
31 | pr_bind ((SOME v, SOME p), _) = brackets [str v, str "@", p]; |
|
32 in gen_pr_bind pr_bind pr_term end; |
30 in gen_pr_bind pr_bind pr_term end; |
33 |
31 |
34 fun pr_haskell_stmt labelled_name syntax_class syntax_tyco syntax_const |
32 fun pr_haskell_stmt labelled_name syntax_class syntax_tyco syntax_const |
35 init_syms deresolve is_cons contr_classparam_typs deriving_show = |
33 init_syms deresolve is_cons contr_classparam_typs deriving_show = |
36 let |
34 let |
70 ]) |
68 ]) |
71 | pr_term tyvars thm vars fxy (IVar v) = |
69 | pr_term tyvars thm vars fxy (IVar v) = |
72 (str o Code_Printer.lookup_var vars) v |
70 (str o Code_Printer.lookup_var vars) v |
73 | pr_term tyvars thm vars fxy (t as _ `|=> _) = |
71 | pr_term tyvars thm vars fxy (t as _ `|=> _) = |
74 let |
72 let |
75 val (binds, t') = Code_Thingol.unfold_abs t; |
73 val (binds, t') = Code_Thingol.unfold_pat_abs t; |
76 fun pr ((v, pat), ty) = pr_bind tyvars thm BR ((SOME v, pat), ty); |
74 val (ps, vars') = fold_map (pr_bind tyvars thm BR) binds vars; |
77 val (ps, vars') = fold_map pr binds vars; |
|
78 in brackets (str "\\" :: ps @ str "->" @@ pr_term tyvars thm vars' NOBR t') end |
75 in brackets (str "\\" :: ps @ str "->" @@ pr_term tyvars thm vars' NOBR t') end |
79 | pr_term tyvars thm vars fxy (ICase (cases as (_, t0))) = |
76 | pr_term tyvars thm vars fxy (ICase (cases as (_, t0))) = |
80 (case Code_Thingol.unfold_const_app t0 |
77 (case Code_Thingol.unfold_const_app t0 |
81 of SOME (c_ts as ((c, _), _)) => if is_none (syntax_const c) |
78 of SOME (c_ts as ((c, _), _)) => if is_none (syntax_const c) |
82 then pr_case tyvars thm vars fxy cases |
79 then pr_case tyvars thm vars fxy cases |
101 and pr_case tyvars thm vars fxy (cases as ((_, [_]), _)) = |
98 and pr_case tyvars thm vars fxy (cases as ((_, [_]), _)) = |
102 let |
99 let |
103 val (binds, body) = Code_Thingol.unfold_let (ICase cases); |
100 val (binds, body) = Code_Thingol.unfold_let (ICase cases); |
104 fun pr ((pat, ty), t) vars = |
101 fun pr ((pat, ty), t) vars = |
105 vars |
102 vars |
106 |> pr_bind tyvars thm BR ((NONE, SOME pat), ty) |
103 |> pr_bind tyvars thm BR (SOME pat, ty) |
107 |>> (fn p => semicolon [p, str "=", pr_term tyvars thm vars NOBR t]) |
104 |>> (fn p => semicolon [p, str "=", pr_term tyvars thm vars NOBR t]) |
108 val (ps, vars') = fold_map pr binds vars; |
105 val (ps, vars') = fold_map pr binds vars; |
109 in brackify_block fxy (str "let {") |
106 in brackify_block fxy (str "let {") |
110 ps |
107 ps |
111 (concat [str "}", str "in", pr_term tyvars thm vars' NOBR body]) |
108 (concat [str "}", str "in", pr_term tyvars thm vars' NOBR body]) |
112 end |
109 end |
113 | pr_case tyvars thm vars fxy (((t, ty), clauses as _ :: _), _) = |
110 | pr_case tyvars thm vars fxy (((t, ty), clauses as _ :: _), _) = |
114 let |
111 let |
115 fun pr (pat, body) = |
112 fun pr (pat, body) = |
116 let |
113 let |
117 val (p, vars') = pr_bind tyvars thm NOBR ((NONE, SOME pat), ty) vars; |
114 val (p, vars') = pr_bind tyvars thm NOBR (SOME pat, ty) vars; |
118 in semicolon [p, str "->", pr_term tyvars thm vars' NOBR body] end; |
115 in semicolon [p, str "->", pr_term tyvars thm vars' NOBR body] end; |
119 in brackify_block fxy |
116 in brackify_block fxy |
120 (concat [str "case", pr_term tyvars thm vars NOBR t, str "of", str "{"]) |
117 (concat [str "case", pr_term tyvars thm vars NOBR t, str "of", str "{"]) |
121 (map pr clauses) |
118 (map pr clauses) |
122 (str "}") |
119 (str "}") |
238 str "};" |
235 str "};" |
239 ) (map pr_classparam classparams) |
236 ) (map pr_classparam classparams) |
240 end |
237 end |
241 | pr_stmt (_, Code_Thingol.Classinst ((class, (tyco, vs)), (_, classparam_insts))) = |
238 | pr_stmt (_, Code_Thingol.Classinst ((class, (tyco, vs)), (_, classparam_insts))) = |
242 let |
239 let |
243 val split_abs_pure = (fn (v, _) `|=> t => SOME (v, t) | _ => NONE); |
|
244 val unfold_abs_pure = Code_Thingol.unfoldr split_abs_pure; |
|
245 val tyvars = Code_Printer.intro_vars (map fst vs) init_syms; |
240 val tyvars = Code_Printer.intro_vars (map fst vs) init_syms; |
246 fun pr_instdef ((classparam, c_inst), (thm, _)) = case syntax_const classparam |
241 fun pr_instdef ((classparam, c_inst), (thm, _)) = case syntax_const classparam |
247 of NONE => semicolon [ |
242 of NONE => semicolon [ |
248 (str o deresolve_base) classparam, |
243 (str o deresolve_base) classparam, |
249 str "=", |
244 str "=", |
253 let |
248 let |
254 val (c_inst_name, (_, tys)) = c_inst; |
249 val (c_inst_name, (_, tys)) = c_inst; |
255 val const = if (is_some o syntax_const) c_inst_name |
250 val const = if (is_some o syntax_const) c_inst_name |
256 then NONE else (SOME o Long_Name.base_name o deresolve) c_inst_name; |
251 then NONE else (SOME o Long_Name.base_name o deresolve) c_inst_name; |
257 val proto_rhs = Code_Thingol.eta_expand k (c_inst, []); |
252 val proto_rhs = Code_Thingol.eta_expand k (c_inst, []); |
258 val (vs, rhs) = unfold_abs_pure proto_rhs; |
253 val (vs, rhs) = (apfst o map) fst (Code_Thingol.unfold_abs proto_rhs); |
259 val vars = init_syms |
254 val vars = init_syms |
260 |> Code_Printer.intro_vars (the_list const) |
255 |> Code_Printer.intro_vars (the_list const) |
261 |> Code_Printer.intro_vars vs; |
256 |> Code_Printer.intro_vars vs; |
262 val lhs = IConst (classparam, (([], []), tys)) `$$ map IVar vs; |
257 val lhs = IConst (classparam, (([], []), tys)) `$$ map IVar vs; |
263 (*dictionaries are not relevant at this late stage*) |
258 (*dictionaries are not relevant at this late stage*) |
445 |
440 |
446 (** optional monad syntax **) |
441 (** optional monad syntax **) |
447 |
442 |
448 fun pretty_haskell_monad c_bind = |
443 fun pretty_haskell_monad c_bind = |
449 let |
444 let |
450 fun dest_bind t1 t2 = case Code_Thingol.split_abs t2 |
445 fun dest_bind t1 t2 = case Code_Thingol.split_pat_abs t2 |
451 of SOME (((v, pat), ty), t') => |
446 of SOME ((some_pat, ty), t') => |
452 SOME ((SOME (((SOME v, pat), ty), true), t1), t') |
447 SOME ((SOME ((some_pat, ty), true), t1), t') |
453 | NONE => NONE; |
448 | NONE => NONE; |
454 fun dest_monad c_bind_name (IConst (c, _) `$ t1 `$ t2) = |
449 fun dest_monad c_bind_name (IConst (c, _) `$ t1 `$ t2) = |
455 if c = c_bind_name then dest_bind t1 t2 |
450 if c = c_bind_name then dest_bind t1 t2 |
456 else NONE |
451 else NONE |
457 | dest_monad _ t = case Code_Thingol.split_let t |
452 | dest_monad _ t = case Code_Thingol.split_let t |
458 of SOME (((pat, ty), tbind), t') => |
453 of SOME (((pat, ty), tbind), t') => |
459 SOME ((SOME (((NONE, SOME pat), ty), false), tbind), t') |
454 SOME ((SOME ((SOME pat, ty), false), tbind), t') |
460 | NONE => NONE; |
455 | NONE => NONE; |
461 fun implode_monad c_bind_name = Code_Thingol.unfoldr (dest_monad c_bind_name); |
456 fun implode_monad c_bind_name = Code_Thingol.unfoldr (dest_monad c_bind_name); |
462 fun pr_monad pr_bind pr (NONE, t) vars = |
457 fun pr_monad pr_bind pr (NONE, t) vars = |
463 (semicolon [pr vars NOBR t], vars) |
458 (semicolon [pr vars NOBR t], vars) |
464 | pr_monad pr_bind pr (SOME (bind, true), t) vars = vars |
459 | pr_monad pr_bind pr (SOME (bind, true), t) vars = vars |