40 | SOME class => class; |
40 | SOME class => class; |
41 fun pr_typcontext tyvars vs = case maps (fn (v, sort) => map (pair v) sort) vs |
41 fun pr_typcontext tyvars vs = case maps (fn (v, sort) => map (pair v) sort) vs |
42 of [] => [] |
42 of [] => [] |
43 | classbinds => Pretty.enum "," "(" ")" ( |
43 | classbinds => Pretty.enum "," "(" ")" ( |
44 map (fn (v, class) => |
44 map (fn (v, class) => |
45 str (class_name class ^ " " ^ Code_Name.lookup_var tyvars v)) classbinds) |
45 str (class_name class ^ " " ^ Code_Printer.lookup_var tyvars v)) classbinds) |
46 @@ str " => "; |
46 @@ str " => "; |
47 fun pr_typforall tyvars vs = case map fst vs |
47 fun pr_typforall tyvars vs = case map fst vs |
48 of [] => [] |
48 of [] => [] |
49 | vnames => str "forall " :: Pretty.breaks |
49 | vnames => str "forall " :: Pretty.breaks |
50 (map (str o Code_Name.lookup_var tyvars) vnames) @ str "." @@ Pretty.brk 1; |
50 (map (str o Code_Printer.lookup_var tyvars) vnames) @ str "." @@ Pretty.brk 1; |
51 fun pr_tycoexpr tyvars fxy (tyco, tys) = |
51 fun pr_tycoexpr tyvars fxy (tyco, tys) = |
52 brackify fxy (str tyco :: map (pr_typ tyvars BR) tys) |
52 brackify fxy (str tyco :: map (pr_typ tyvars BR) tys) |
53 and pr_typ tyvars fxy (tycoexpr as tyco `%% tys) = (case syntax_tyco tyco |
53 and pr_typ tyvars fxy (tycoexpr as tyco `%% tys) = (case syntax_tyco tyco |
54 of NONE => pr_tycoexpr tyvars fxy (deresolve tyco, tys) |
54 of NONE => pr_tycoexpr tyvars fxy (deresolve tyco, tys) |
55 | SOME (i, pr) => pr (pr_typ tyvars) fxy tys) |
55 | SOME (i, pr) => pr (pr_typ tyvars) fxy tys) |
56 | pr_typ tyvars fxy (ITyVar v) = (str o Code_Name.lookup_var tyvars) v; |
56 | pr_typ tyvars fxy (ITyVar v) = (str o Code_Printer.lookup_var tyvars) v; |
57 fun pr_typdecl tyvars (vs, tycoexpr) = |
57 fun pr_typdecl tyvars (vs, tycoexpr) = |
58 Pretty.block (pr_typcontext tyvars vs @| pr_tycoexpr tyvars NOBR tycoexpr); |
58 Pretty.block (pr_typcontext tyvars vs @| pr_tycoexpr tyvars NOBR tycoexpr); |
59 fun pr_typscheme tyvars (vs, ty) = |
59 fun pr_typscheme tyvars (vs, ty) = |
60 Pretty.block (pr_typforall tyvars vs @ pr_typcontext tyvars vs @| pr_typ tyvars NOBR ty); |
60 Pretty.block (pr_typforall tyvars vs @ pr_typcontext tyvars vs @| pr_typ tyvars NOBR ty); |
61 fun pr_term tyvars thm vars fxy (IConst c) = |
61 fun pr_term tyvars thm vars fxy (IConst c) = |
67 brackify fxy [ |
67 brackify fxy [ |
68 pr_term tyvars thm vars NOBR t1, |
68 pr_term tyvars thm vars NOBR t1, |
69 pr_term tyvars thm vars BR t2 |
69 pr_term tyvars thm vars BR t2 |
70 ]) |
70 ]) |
71 | pr_term tyvars thm vars fxy (IVar v) = |
71 | pr_term tyvars thm vars fxy (IVar v) = |
72 (str o Code_Name.lookup_var vars) v |
72 (str o Code_Printer.lookup_var vars) v |
73 | pr_term tyvars thm vars fxy (t as _ `|-> _) = |
73 | pr_term tyvars thm vars fxy (t as _ `|-> _) = |
74 let |
74 let |
75 val (binds, t') = Code_Thingol.unfold_abs t; |
75 val (binds, t') = Code_Thingol.unfold_abs t; |
76 fun pr ((v, pat), ty) = pr_bind tyvars thm BR ((SOME v, pat), ty); |
76 fun pr ((v, pat), ty) = pr_bind tyvars thm BR ((SOME v, pat), ty); |
77 val (ps, vars') = fold_map pr binds vars; |
77 val (ps, vars') = fold_map pr binds vars; |
125 ) (map pr clauses) |
125 ) (map pr clauses) |
126 end |
126 end |
127 | pr_case tyvars thm vars fxy ((_, []), _) = str "error \"empty case\""; |
127 | pr_case tyvars thm vars fxy ((_, []), _) = str "error \"empty case\""; |
128 fun pr_stmt (name, Code_Thingol.Fun (_, ((vs, ty), []))) = |
128 fun pr_stmt (name, Code_Thingol.Fun (_, ((vs, ty), []))) = |
129 let |
129 let |
130 val tyvars = Code_Name.intro_vars (map fst vs) init_syms; |
130 val tyvars = Code_Printer.intro_vars (map fst vs) init_syms; |
131 val n = (length o fst o Code_Thingol.unfold_fun) ty; |
131 val n = (length o fst o Code_Thingol.unfold_fun) ty; |
132 in |
132 in |
133 Pretty.chunks [ |
133 Pretty.chunks [ |
134 Pretty.block [ |
134 Pretty.block [ |
135 (str o suffix " ::" o deresolve_base) name, |
135 (str o suffix " ::" o deresolve_base) name, |
148 ] |
148 ] |
149 end |
149 end |
150 | pr_stmt (name, Code_Thingol.Fun (_, ((vs, ty), raw_eqs))) = |
150 | pr_stmt (name, Code_Thingol.Fun (_, ((vs, ty), raw_eqs))) = |
151 let |
151 let |
152 val eqs = filter (snd o snd) raw_eqs; |
152 val eqs = filter (snd o snd) raw_eqs; |
153 val tyvars = Code_Name.intro_vars (map fst vs) init_syms; |
153 val tyvars = Code_Printer.intro_vars (map fst vs) init_syms; |
154 fun pr_eq ((ts, t), (thm, _)) = |
154 fun pr_eq ((ts, t), (thm, _)) = |
155 let |
155 let |
156 val consts = map_filter |
156 val consts = map_filter |
157 (fn c => if (is_some o syntax_const) c |
157 (fn c => if (is_some o syntax_const) c |
158 then NONE else (SOME o Long_Name.base_name o deresolve) c) |
158 then NONE else (SOME o Long_Name.base_name o deresolve) c) |
159 ((fold o Code_Thingol.fold_constnames) (insert (op =)) (t :: ts) []); |
159 ((fold o Code_Thingol.fold_constnames) (insert (op =)) (t :: ts) []); |
160 val vars = init_syms |
160 val vars = init_syms |
161 |> Code_Name.intro_vars consts |
161 |> Code_Printer.intro_vars consts |
162 |> Code_Name.intro_vars ((fold o Code_Thingol.fold_unbound_varnames) |
162 |> Code_Printer.intro_vars ((fold o Code_Thingol.fold_unbound_varnames) |
163 (insert (op =)) ts []); |
163 (insert (op =)) ts []); |
164 in |
164 in |
165 semicolon ( |
165 semicolon ( |
166 (str o deresolve_base) name |
166 (str o deresolve_base) name |
167 :: map (pr_term tyvars thm vars BR) ts |
167 :: map (pr_term tyvars thm vars BR) ts |
180 :: map pr_eq eqs |
180 :: map pr_eq eqs |
181 ) |
181 ) |
182 end |
182 end |
183 | pr_stmt (name, Code_Thingol.Datatype (_, (vs, []))) = |
183 | pr_stmt (name, Code_Thingol.Datatype (_, (vs, []))) = |
184 let |
184 let |
185 val tyvars = Code_Name.intro_vars (map fst vs) init_syms; |
185 val tyvars = Code_Printer.intro_vars (map fst vs) init_syms; |
186 in |
186 in |
187 semicolon [ |
187 semicolon [ |
188 str "data", |
188 str "data", |
189 pr_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs)) |
189 pr_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs)) |
190 ] |
190 ] |
191 end |
191 end |
192 | pr_stmt (name, Code_Thingol.Datatype (_, (vs, [(co, [ty])]))) = |
192 | pr_stmt (name, Code_Thingol.Datatype (_, (vs, [(co, [ty])]))) = |
193 let |
193 let |
194 val tyvars = Code_Name.intro_vars (map fst vs) init_syms; |
194 val tyvars = Code_Printer.intro_vars (map fst vs) init_syms; |
195 in |
195 in |
196 semicolon ( |
196 semicolon ( |
197 str "newtype" |
197 str "newtype" |
198 :: pr_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs)) |
198 :: pr_typdecl tyvars (vs, (deresolve_base name, map (ITyVar o fst) vs)) |
199 :: str "=" |
199 :: str "=" |
202 :: (if deriving_show name then [str "deriving (Read, Show)"] else []) |
202 :: (if deriving_show name then [str "deriving (Read, Show)"] else []) |
203 ) |
203 ) |
204 end |
204 end |
205 | pr_stmt (name, Code_Thingol.Datatype (_, (vs, co :: cos))) = |
205 | pr_stmt (name, Code_Thingol.Datatype (_, (vs, co :: cos))) = |
206 let |
206 let |
207 val tyvars = Code_Name.intro_vars (map fst vs) init_syms; |
207 val tyvars = Code_Printer.intro_vars (map fst vs) init_syms; |
208 fun pr_co (co, tys) = |
208 fun pr_co (co, tys) = |
209 concat ( |
209 concat ( |
210 (str o deresolve_base) co |
210 (str o deresolve_base) co |
211 :: map (pr_typ tyvars BR) tys |
211 :: map (pr_typ tyvars BR) tys |
212 ) |
212 ) |
220 @ (if deriving_show name then [str "deriving (Read, Show)"] else []) |
220 @ (if deriving_show name then [str "deriving (Read, Show)"] else []) |
221 ) |
221 ) |
222 end |
222 end |
223 | pr_stmt (name, Code_Thingol.Class (_, (v, (superclasses, classparams)))) = |
223 | pr_stmt (name, Code_Thingol.Class (_, (v, (superclasses, classparams)))) = |
224 let |
224 let |
225 val tyvars = Code_Name.intro_vars [v] init_syms; |
225 val tyvars = Code_Printer.intro_vars [v] init_syms; |
226 fun pr_classparam (classparam, ty) = |
226 fun pr_classparam (classparam, ty) = |
227 semicolon [ |
227 semicolon [ |
228 (str o deresolve_base) classparam, |
228 (str o deresolve_base) classparam, |
229 str "::", |
229 str "::", |
230 pr_typ tyvars NOBR ty |
230 pr_typ tyvars NOBR ty |
232 in |
232 in |
233 Pretty.block_enclose ( |
233 Pretty.block_enclose ( |
234 Pretty.block [ |
234 Pretty.block [ |
235 str "class ", |
235 str "class ", |
236 Pretty.block (pr_typcontext tyvars [(v, map fst superclasses)]), |
236 Pretty.block (pr_typcontext tyvars [(v, map fst superclasses)]), |
237 str (deresolve_base name ^ " " ^ Code_Name.lookup_var tyvars v), |
237 str (deresolve_base name ^ " " ^ Code_Printer.lookup_var tyvars v), |
238 str " where {" |
238 str " where {" |
239 ], |
239 ], |
240 str "};" |
240 str "};" |
241 ) (map pr_classparam classparams) |
241 ) (map pr_classparam classparams) |
242 end |
242 end |
243 | pr_stmt (_, Code_Thingol.Classinst ((class, (tyco, vs)), (_, classparam_insts))) = |
243 | pr_stmt (_, Code_Thingol.Classinst ((class, (tyco, vs)), (_, classparam_insts))) = |
244 let |
244 let |
245 val split_abs_pure = (fn (v, _) `|-> t => SOME (v, t) | _ => NONE); |
245 val split_abs_pure = (fn (v, _) `|-> t => SOME (v, t) | _ => NONE); |
246 val unfold_abs_pure = Code_Thingol.unfoldr split_abs_pure; |
246 val unfold_abs_pure = Code_Thingol.unfoldr split_abs_pure; |
247 val tyvars = Code_Name.intro_vars (map fst vs) init_syms; |
247 val tyvars = Code_Printer.intro_vars (map fst vs) init_syms; |
248 fun pr_instdef ((classparam, c_inst), (thm, _)) = case syntax_const classparam |
248 fun pr_instdef ((classparam, c_inst), (thm, _)) = case syntax_const classparam |
249 of NONE => semicolon [ |
249 of NONE => semicolon [ |
250 (str o deresolve_base) classparam, |
250 (str o deresolve_base) classparam, |
251 str "=", |
251 str "=", |
252 pr_app tyvars thm init_syms NOBR (c_inst, []) |
252 pr_app tyvars thm init_syms NOBR (c_inst, []) |
257 val const = if (is_some o syntax_const) c_inst_name |
257 val const = if (is_some o syntax_const) c_inst_name |
258 then NONE else (SOME o Long_Name.base_name o deresolve) c_inst_name; |
258 then NONE else (SOME o Long_Name.base_name o deresolve) c_inst_name; |
259 val proto_rhs = Code_Thingol.eta_expand k (c_inst, []); |
259 val proto_rhs = Code_Thingol.eta_expand k (c_inst, []); |
260 val (vs, rhs) = unfold_abs_pure proto_rhs; |
260 val (vs, rhs) = unfold_abs_pure proto_rhs; |
261 val vars = init_syms |
261 val vars = init_syms |
262 |> Code_Name.intro_vars (the_list const) |
262 |> Code_Printer.intro_vars (the_list const) |
263 |> Code_Name.intro_vars vs; |
263 |> Code_Printer.intro_vars vs; |
264 val lhs = IConst (classparam, ([], tys)) `$$ map IVar vs; |
264 val lhs = IConst (classparam, ([], tys)) `$$ map IVar vs; |
265 (*dictionaries are not relevant at this late stage*) |
265 (*dictionaries are not relevant at this late stage*) |
266 in |
266 in |
267 semicolon [ |
267 semicolon [ |
268 pr_term tyvars thm vars NOBR lhs, |
268 pr_term tyvars thm vars NOBR lhs, |
286 |
286 |
287 fun haskell_program_of_program labelled_name module_name module_prefix reserved_names raw_module_alias program = |
287 fun haskell_program_of_program labelled_name module_name module_prefix reserved_names raw_module_alias program = |
288 let |
288 let |
289 val module_alias = if is_some module_name then K module_name else raw_module_alias; |
289 val module_alias = if is_some module_name then K module_name else raw_module_alias; |
290 val reserved_names = Name.make_context reserved_names; |
290 val reserved_names = Name.make_context reserved_names; |
291 val mk_name_module = Code_Name.mk_name_module reserved_names module_prefix module_alias program; |
291 val mk_name_module = Code_Printer.mk_name_module reserved_names module_prefix module_alias program; |
292 fun add_stmt (name, (stmt, deps)) = |
292 fun add_stmt (name, (stmt, deps)) = |
293 let |
293 let |
294 val (module_name, base) = Code_Name.dest_name name; |
294 val (module_name, base) = Code_Printer.dest_name name; |
295 val module_name' = mk_name_module module_name; |
295 val module_name' = mk_name_module module_name; |
296 val mk_name_stmt = yield_singleton Name.variants; |
296 val mk_name_stmt = yield_singleton Name.variants; |
297 fun add_fun upper (nsp_fun, nsp_typ) = |
297 fun add_fun upper (nsp_fun, nsp_typ) = |
298 let |
298 let |
299 val (base', nsp_fun') = |
299 val (base', nsp_fun') = |
300 mk_name_stmt (if upper then Code_Name.first_upper base else base) nsp_fun |
300 mk_name_stmt (if upper then Code_Printer.first_upper base else base) nsp_fun |
301 in (base', (nsp_fun', nsp_typ)) end; |
301 in (base', (nsp_fun', nsp_typ)) end; |
302 fun add_typ (nsp_fun, nsp_typ) = |
302 fun add_typ (nsp_fun, nsp_typ) = |
303 let |
303 let |
304 val (base', nsp_typ') = mk_name_stmt (Code_Name.first_upper base) nsp_typ |
304 val (base', nsp_typ') = mk_name_stmt (Code_Printer.first_upper base) nsp_typ |
305 in (base', (nsp_fun, nsp_typ')) end; |
305 in (base', (nsp_fun, nsp_typ')) end; |
306 val add_name = case stmt |
306 val add_name = case stmt |
307 of Code_Thingol.Fun _ => add_fun false |
307 of Code_Thingol.Fun _ => add_fun false |
308 | Code_Thingol.Datatype _ => add_typ |
308 | Code_Thingol.Datatype _ => add_typ |
309 | Code_Thingol.Datatypecons _ => add_fun true |
309 | Code_Thingol.Datatypecons _ => add_fun true |
328 end; |
328 end; |
329 val hs_program = fold add_stmt (AList.make (fn name => |
329 val hs_program = fold add_stmt (AList.make (fn name => |
330 (Graph.get_node program name, Graph.imm_succs program name)) |
330 (Graph.get_node program name, Graph.imm_succs program name)) |
331 (Graph.strong_conn program |> flat)) Symtab.empty; |
331 (Graph.strong_conn program |> flat)) Symtab.empty; |
332 fun deresolver name = (fst o the o AList.lookup (op =) ((fst o snd o the |
332 fun deresolver name = (fst o the o AList.lookup (op =) ((fst o snd o the |
333 o Symtab.lookup hs_program) ((mk_name_module o fst o Code_Name.dest_name) name))) name |
333 o Symtab.lookup hs_program) ((mk_name_module o fst o Code_Printer.dest_name) name))) name |
334 handle Option => error ("Unknown statement name: " ^ labelled_name name); |
334 handle Option => error ("Unknown statement name: " ^ labelled_name name); |
335 in (deresolver, hs_program) end; |
335 in (deresolver, hs_program) end; |
336 |
336 |
337 fun serialize_haskell module_prefix raw_module_name string_classes labelled_name |
337 fun serialize_haskell module_prefix raw_module_name string_classes labelled_name |
338 raw_reserved_names includes raw_module_alias |
338 raw_reserved_names includes raw_module_alias |
355 | NONE => true |
355 | NONE => true |
356 and deriv' tycos (tyco `%% tys) = deriv tycos tyco |
356 and deriv' tycos (tyco `%% tys) = deriv tycos tyco |
357 andalso forall (deriv' tycos) tys |
357 andalso forall (deriv' tycos) tys |
358 | deriv' _ (ITyVar _) = true |
358 | deriv' _ (ITyVar _) = true |
359 in deriv [] tyco end; |
359 in deriv [] tyco end; |
360 val reserved_names = Code_Name.make_vars reserved_names; |
360 val reserved_names = Code_Printer.make_vars reserved_names; |
361 fun pr_stmt qualified = pr_haskell_stmt naming labelled_name |
361 fun pr_stmt qualified = pr_haskell_stmt naming labelled_name |
362 syntax_class syntax_tyco syntax_const reserved_names |
362 syntax_class syntax_tyco syntax_const reserved_names |
363 (if qualified then deresolver else Long_Name.base_name o deresolver) |
363 (if qualified then deresolver else Long_Name.base_name o deresolver) |
364 is_cons contr_classparam_typs |
364 is_cons contr_classparam_typs |
365 (if string_classes then deriving_show else K false); |
365 (if string_classes then deriving_show else K false); |