79 end |
79 end |
80 and pr_typ fxy (tyco `%% tys) = (case syntax_tyco tyco |
80 and pr_typ fxy (tyco `%% tys) = (case syntax_tyco tyco |
81 of NONE => pr_tycoexpr fxy (tyco, tys) |
81 of NONE => pr_tycoexpr fxy (tyco, tys) |
82 | SOME (i, pr) => pr pr_typ fxy tys) |
82 | SOME (i, pr) => pr pr_typ fxy tys) |
83 | pr_typ fxy (ITyVar v) = str ("'" ^ v); |
83 | pr_typ fxy (ITyVar v) = str ("'" ^ v); |
84 fun pr_term thm vars fxy (IConst c) = |
84 fun pr_term is_closure thm vars fxy (IConst c) = |
85 pr_app thm vars fxy (c, []) |
85 pr_app is_closure thm vars fxy (c, []) |
86 | pr_term thm vars fxy (IVar v) = |
86 | pr_term is_closure thm vars fxy (IVar v) = |
87 str (Code_Name.lookup_var vars v) |
87 str (Code_Name.lookup_var vars v) |
88 | pr_term thm vars fxy (t as t1 `$ t2) = |
88 | pr_term is_closure thm vars fxy (t as t1 `$ t2) = |
89 (case Code_Thingol.unfold_const_app t |
89 (case Code_Thingol.unfold_const_app t |
90 of SOME c_ts => pr_app thm vars fxy c_ts |
90 of SOME c_ts => pr_app is_closure thm vars fxy c_ts |
91 | NONE => |
91 | NONE => brackify fxy |
92 brackify fxy [pr_term thm vars NOBR t1, pr_term thm vars BR t2]) |
92 [pr_term is_closure thm vars NOBR t1, pr_term is_closure thm vars BR t2]) |
93 | pr_term thm vars fxy (t as _ `|-> _) = |
93 | pr_term is_closure thm vars fxy (t as _ `|-> _) = |
94 let |
94 let |
95 val (binds, t') = Code_Thingol.unfold_abs t; |
95 val (binds, t') = Code_Thingol.unfold_abs t; |
96 fun pr ((v, pat), ty) = |
96 fun pr ((v, pat), ty) = |
97 pr_bind thm NOBR ((SOME v, pat), ty) |
97 pr_bind is_closure thm NOBR ((SOME v, pat), ty) |
98 #>> (fn p => concat [str "fn", p, str "=>"]); |
98 #>> (fn p => concat [str "fn", p, str "=>"]); |
99 val (ps, vars') = fold_map pr binds vars; |
99 val (ps, vars') = fold_map pr binds vars; |
100 in brackets (ps @ [pr_term thm vars' NOBR t']) end |
100 in brackets (ps @ [pr_term is_closure thm vars' NOBR t']) end |
101 | pr_term thm vars fxy (ICase (cases as (_, t0))) = |
101 | pr_term is_closure thm vars fxy (ICase (cases as (_, t0))) = |
102 (case Code_Thingol.unfold_const_app t0 |
102 (case Code_Thingol.unfold_const_app t0 |
103 of SOME (c_ts as ((c, _), _)) => if is_none (syntax_const c) |
103 of SOME (c_ts as ((c, _), _)) => if is_none (syntax_const c) |
104 then pr_case thm vars fxy cases |
104 then pr_case is_closure thm vars fxy cases |
105 else pr_app thm vars fxy c_ts |
105 else pr_app is_closure thm vars fxy c_ts |
106 | NONE => pr_case thm vars fxy cases) |
106 | NONE => pr_case is_closure thm vars fxy cases) |
107 and pr_app' thm vars (app as ((c, (iss, tys)), ts)) = |
107 and pr_app' is_closure thm vars (app as ((c, (iss, tys)), ts)) = |
108 if is_cons c then let |
108 if is_cons c then |
109 val k = length tys |
109 let |
110 in if k < 2 then |
110 val k = length tys |
111 (str o deresolve) c :: map (pr_term thm vars BR) ts |
111 in if k < 2 then |
112 else if k = length ts then |
112 (str o deresolve) c :: map (pr_term is_closure thm vars BR) ts |
113 [(str o deresolve) c, Pretty.enum "," "(" ")" (map (pr_term thm vars NOBR) ts)] |
113 else if k = length ts then |
114 else [pr_term thm vars BR (Code_Thingol.eta_expand k app)] end else |
114 [(str o deresolve) c, Pretty.enum "," "(" ")" (map (pr_term is_closure thm vars NOBR) ts)] |
|
115 else [pr_term is_closure thm vars BR (Code_Thingol.eta_expand k app)] end |
|
116 else if is_closure c |
|
117 then (str o deresolve) c @@ str "()" |
|
118 else |
115 (str o deresolve) c |
119 (str o deresolve) c |
116 :: (map (pr_dicts BR) o filter_out null) iss @ map (pr_term thm vars BR) ts |
120 :: (map (pr_dicts BR) o filter_out null) iss @ map (pr_term is_closure thm vars BR) ts |
117 and pr_app thm vars = gen_pr_app pr_app' pr_term syntax_const naming thm vars |
121 and pr_app is_closure thm vars = gen_pr_app (pr_app' is_closure) (pr_term is_closure) |
|
122 syntax_const naming thm vars |
118 and pr_bind' ((NONE, NONE), _) = str "_" |
123 and pr_bind' ((NONE, NONE), _) = str "_" |
119 | pr_bind' ((SOME v, NONE), _) = str v |
124 | pr_bind' ((SOME v, NONE), _) = str v |
120 | pr_bind' ((NONE, SOME p), _) = p |
125 | pr_bind' ((NONE, SOME p), _) = p |
121 | pr_bind' ((SOME v, SOME p), _) = concat [str v, str "as", p] |
126 | pr_bind' ((SOME v, SOME p), _) = concat [str v, str "as", p] |
122 and pr_bind thm = gen_pr_bind pr_bind' pr_term thm |
127 and pr_bind is_closure = gen_pr_bind pr_bind' (pr_term is_closure) |
123 and pr_case thm vars fxy (cases as ((_, [_]), _)) = |
128 and pr_case is_closure thm vars fxy (cases as ((_, [_]), _)) = |
124 let |
129 let |
125 val (binds, t') = Code_Thingol.unfold_let (ICase cases); |
130 val (binds, t') = Code_Thingol.unfold_let (ICase cases); |
126 fun pr ((pat, ty), t) vars = |
131 fun pr ((pat, ty), t) vars = |
127 vars |
132 vars |
128 |> pr_bind thm NOBR ((NONE, SOME pat), ty) |
133 |> pr_bind is_closure thm NOBR ((NONE, SOME pat), ty) |
129 |>> (fn p => semicolon [str "val", p, str "=", pr_term thm vars NOBR t]) |
134 |>> (fn p => semicolon [str "val", p, str "=", pr_term is_closure thm vars NOBR t]) |
130 val (ps, vars') = fold_map pr binds vars; |
135 val (ps, vars') = fold_map pr binds vars; |
131 in |
136 in |
132 Pretty.chunks [ |
137 Pretty.chunks [ |
133 [str ("let"), Pretty.fbrk, Pretty.chunks ps] |> Pretty.block, |
138 [str ("let"), Pretty.fbrk, Pretty.chunks ps] |> Pretty.block, |
134 [str ("in"), Pretty.fbrk, pr_term thm vars' NOBR t'] |> Pretty.block, |
139 [str ("in"), Pretty.fbrk, pr_term is_closure thm vars' NOBR t'] |> Pretty.block, |
135 str ("end") |
140 str ("end") |
136 ] |
141 ] |
137 end |
142 end |
138 | pr_case thm vars fxy (((td, ty), b::bs), _) = |
143 | pr_case is_closure thm vars fxy (((td, ty), b::bs), _) = |
139 let |
144 let |
140 fun pr delim (pat, t) = |
145 fun pr delim (pat, t) = |
141 let |
146 let |
142 val (p, vars') = pr_bind thm NOBR ((NONE, SOME pat), ty) vars; |
147 val (p, vars') = pr_bind is_closure thm NOBR ((NONE, SOME pat), ty) vars; |
143 in |
148 in |
144 concat [str delim, p, str "=>", pr_term thm vars' NOBR t] |
149 concat [str delim, p, str "=>", pr_term is_closure thm vars' NOBR t] |
145 end; |
150 end; |
146 in |
151 in |
147 (Pretty.enclose "(" ")" o single o brackify fxy) ( |
152 (Pretty.enclose "(" ")" o single o brackify fxy) ( |
148 str "case" |
153 str "case" |
149 :: pr_term thm vars NOBR td |
154 :: pr_term is_closure thm vars NOBR td |
150 :: pr "of" b |
155 :: pr "of" b |
151 :: map (pr "|") bs |
156 :: map (pr "|") bs |
152 ) |
157 ) |
153 end |
158 end |
154 | pr_case thm vars fxy ((_, []), _) = str "raise Fail \"empty case\""; |
159 | pr_case is_closure thm vars fxy ((_, []), _) = str "raise Fail \"empty case\""; |
155 fun pr_stmt (MLFuns (funns as (funn :: funns'))) = |
160 fun pr_stmt (MLFuns (funns as (funn :: funns'))) = |
156 let |
161 let |
157 val definer = |
162 val definer = |
158 let |
163 let |
159 fun no_args _ (((ts, _), _) :: _) = length ts |
164 fun no_args _ (((ts, _), _) :: _) = length ts |
160 | no_args ty [] = (length o fst o Code_Thingol.unfold_fun) ty; |
165 | no_args ty [] = (length o fst o Code_Thingol.unfold_fun) ty; |
161 fun mk 0 [] = "val" |
166 fun mk 0 [] = "val" |
162 | mk 0 vs = if (null o filter_out (null o snd)) vs |
167 | mk 0 vs = if (null o filter_out (null o snd)) vs |
163 then "val" else "fun" |
168 then "val" else "fun" |
164 | mk k _ = "fun"; |
169 | mk k _ = "fun"; |
165 fun chk (_, ((vs, ty), eqs)) NONE = SOME (mk (no_args ty eqs) vs) |
170 fun chk ((_, ((vs, ty), eqs)), _) NONE = SOME (mk (no_args ty eqs) vs) |
166 | chk (_, ((vs, ty), eqs)) (SOME defi) = |
171 | chk ((_, ((vs, ty), eqs)), _) (SOME defi) = |
167 if defi = mk (no_args ty eqs) vs then SOME defi |
172 if defi = mk (no_args ty eqs) vs then SOME defi |
168 else error ("Mixing simultaneous vals and funs not implemented: " |
173 else error ("Mixing simultaneous vals and funs not implemented: " |
169 ^ commas (map (labelled_name o fst) funns)); |
174 ^ commas (map (labelled_name o fst o fst) funns)); |
170 in the (fold chk funns NONE) end; |
175 in the (fold chk funns NONE) end; |
171 fun pr_funn definer (name, ((vs, ty), [])) = |
176 fun pr_funn definer ((name, ((vs, ty), [])), _) = |
172 let |
177 let |
173 val vs_dict = filter_out (null o snd) vs; |
178 val vs_dict = filter_out (null o snd) vs; |
174 val n = length vs_dict + (length o fst o Code_Thingol.unfold_fun) ty; |
179 val n = length vs_dict + (length o fst o Code_Thingol.unfold_fun) ty; |
175 val exc_str = |
180 val exc_str = |
176 (ML_Syntax.print_string o NameSpace.base o NameSpace.qualifier) name; |
181 (ML_Syntax.print_string o NameSpace.base o NameSpace.qualifier) name; |
372 end |
377 end |
373 and pr_typ fxy (tyco `%% tys) = (case syntax_tyco tyco |
378 and pr_typ fxy (tyco `%% tys) = (case syntax_tyco tyco |
374 of NONE => pr_tycoexpr fxy (tyco, tys) |
379 of NONE => pr_tycoexpr fxy (tyco, tys) |
375 | SOME (i, pr) => pr pr_typ fxy tys) |
380 | SOME (i, pr) => pr pr_typ fxy tys) |
376 | pr_typ fxy (ITyVar v) = str ("'" ^ v); |
381 | pr_typ fxy (ITyVar v) = str ("'" ^ v); |
377 fun pr_term thm vars fxy (IConst c) = |
382 fun pr_term is_closure thm vars fxy (IConst c) = |
378 pr_app thm vars fxy (c, []) |
383 pr_app is_closure thm vars fxy (c, []) |
379 | pr_term thm vars fxy (IVar v) = |
384 | pr_term is_closure thm vars fxy (IVar v) = |
380 str (Code_Name.lookup_var vars v) |
385 str (Code_Name.lookup_var vars v) |
381 | pr_term thm vars fxy (t as t1 `$ t2) = |
386 | pr_term is_closure thm vars fxy (t as t1 `$ t2) = |
382 (case Code_Thingol.unfold_const_app t |
387 (case Code_Thingol.unfold_const_app t |
383 of SOME c_ts => pr_app thm vars fxy c_ts |
388 of SOME c_ts => pr_app is_closure thm vars fxy c_ts |
384 | NONE => |
389 | NONE => |
385 brackify fxy [pr_term thm vars NOBR t1, pr_term thm vars BR t2]) |
390 brackify fxy [pr_term is_closure thm vars NOBR t1, pr_term is_closure thm vars BR t2]) |
386 | pr_term thm vars fxy (t as _ `|-> _) = |
391 | pr_term is_closure thm vars fxy (t as _ `|-> _) = |
387 let |
392 let |
388 val (binds, t') = Code_Thingol.unfold_abs t; |
393 val (binds, t') = Code_Thingol.unfold_abs t; |
389 fun pr ((v, pat), ty) = pr_bind thm BR ((SOME v, pat), ty); |
394 fun pr ((v, pat), ty) = pr_bind is_closure thm BR ((SOME v, pat), ty); |
390 val (ps, vars') = fold_map pr binds vars; |
395 val (ps, vars') = fold_map pr binds vars; |
391 in brackets (str "fun" :: ps @ str "->" @@ pr_term thm vars' NOBR t') end |
396 in brackets (str "fun" :: ps @ str "->" @@ pr_term is_closure thm vars' NOBR t') end |
392 | pr_term thm vars fxy (ICase (cases as (_, t0))) = (case Code_Thingol.unfold_const_app t0 |
397 | pr_term is_closure thm vars fxy (ICase (cases as (_, t0))) = (case Code_Thingol.unfold_const_app t0 |
393 of SOME (c_ts as ((c, _), _)) => if is_none (syntax_const c) |
398 of SOME (c_ts as ((c, _), _)) => if is_none (syntax_const c) |
394 then pr_case thm vars fxy cases |
399 then pr_case is_closure thm vars fxy cases |
395 else pr_app thm vars fxy c_ts |
400 else pr_app is_closure thm vars fxy c_ts |
396 | NONE => pr_case thm vars fxy cases) |
401 | NONE => pr_case is_closure thm vars fxy cases) |
397 and pr_app' thm vars (app as ((c, (iss, tys)), ts)) = |
402 and pr_app' is_closure thm vars (app as ((c, (iss, tys)), ts)) = |
398 if is_cons c then |
403 if is_cons c then |
399 if length tys = length ts |
404 if length tys = length ts |
400 then case ts |
405 then case ts |
401 of [] => [(str o deresolve) c] |
406 of [] => [(str o deresolve) c] |
402 | [t] => [(str o deresolve) c, pr_term thm vars BR t] |
407 | [t] => [(str o deresolve) c, pr_term is_closure thm vars BR t] |
403 | _ => [(str o deresolve) c, Pretty.enum "," "(" ")" |
408 | _ => [(str o deresolve) c, Pretty.enum "," "(" ")" |
404 (map (pr_term thm vars NOBR) ts)] |
409 (map (pr_term is_closure thm vars NOBR) ts)] |
405 else [pr_term thm vars BR (Code_Thingol.eta_expand (length tys) app)] |
410 else [pr_term is_closure thm vars BR (Code_Thingol.eta_expand (length tys) app)] |
|
411 else if is_closure c |
|
412 then (str o deresolve) c @@ str "()" |
406 else (str o deresolve) c |
413 else (str o deresolve) c |
407 :: ((map (pr_dicts BR) o filter_out null) iss @ map (pr_term thm vars BR) ts) |
414 :: ((map (pr_dicts BR) o filter_out null) iss @ map (pr_term is_closure thm vars BR) ts) |
408 and pr_app thm vars = gen_pr_app pr_app' pr_term syntax_const naming thm vars |
415 and pr_app is_closure = gen_pr_app (pr_app' is_closure) (pr_term is_closure) |
|
416 syntax_const naming |
409 and pr_bind' ((NONE, NONE), _) = str "_" |
417 and pr_bind' ((NONE, NONE), _) = str "_" |
410 | pr_bind' ((SOME v, NONE), _) = str v |
418 | pr_bind' ((SOME v, NONE), _) = str v |
411 | pr_bind' ((NONE, SOME p), _) = p |
419 | pr_bind' ((NONE, SOME p), _) = p |
412 | pr_bind' ((SOME v, SOME p), _) = brackets [p, str "as", str v] |
420 | pr_bind' ((SOME v, SOME p), _) = brackets [p, str "as", str v] |
413 and pr_bind thm = gen_pr_bind pr_bind' pr_term thm |
421 and pr_bind is_closure = gen_pr_bind pr_bind' (pr_term is_closure) |
414 and pr_case thm vars fxy (cases as ((_, [_]), _)) = |
422 and pr_case is_closure thm vars fxy (cases as ((_, [_]), _)) = |
415 let |
423 let |
416 val (binds, t') = Code_Thingol.unfold_let (ICase cases); |
424 val (binds, t') = Code_Thingol.unfold_let (ICase cases); |
417 fun pr ((pat, ty), t) vars = |
425 fun pr ((pat, ty), t) vars = |
418 vars |
426 vars |
419 |> pr_bind thm NOBR ((NONE, SOME pat), ty) |
427 |> pr_bind is_closure thm NOBR ((NONE, SOME pat), ty) |
420 |>> (fn p => concat |
428 |>> (fn p => concat |
421 [str "let", p, str "=", pr_term thm vars NOBR t, str "in"]) |
429 [str "let", p, str "=", pr_term is_closure thm vars NOBR t, str "in"]) |
422 val (ps, vars') = fold_map pr binds vars; |
430 val (ps, vars') = fold_map pr binds vars; |
423 in Pretty.chunks (ps @| pr_term thm vars' NOBR t') end |
431 in Pretty.chunks (ps @| pr_term is_closure thm vars' NOBR t') end |
424 | pr_case thm vars fxy (((td, ty), b::bs), _) = |
432 | pr_case is_closure thm vars fxy (((td, ty), b::bs), _) = |
425 let |
433 let |
426 fun pr delim (pat, t) = |
434 fun pr delim (pat, t) = |
427 let |
435 let |
428 val (p, vars') = pr_bind thm NOBR ((NONE, SOME pat), ty) vars; |
436 val (p, vars') = pr_bind is_closure thm NOBR ((NONE, SOME pat), ty) vars; |
429 in concat [str delim, p, str "->", pr_term thm vars' NOBR t] end; |
437 in concat [str delim, p, str "->", pr_term is_closure thm vars' NOBR t] end; |
430 in |
438 in |
431 (Pretty.enclose "(" ")" o single o brackify fxy) ( |
439 (Pretty.enclose "(" ")" o single o brackify fxy) ( |
432 str "match" |
440 str "match" |
433 :: pr_term thm vars NOBR td |
441 :: pr_term is_closure thm vars NOBR td |
434 :: pr "with" b |
442 :: pr "with" b |
435 :: map (pr "|") bs |
443 :: map (pr "|") bs |
436 ) |
444 ) |
437 end |
445 end |
438 | pr_case thm vars fxy ((_, []), _) = str "failwith \"empty case\""; |
446 | pr_case is_closure thm vars fxy ((_, []), _) = str "failwith \"empty case\""; |
439 fun fish_params vars eqs = |
447 fun fish_params vars eqs = |
440 let |
448 let |
441 fun fish_param _ (w as SOME _) = w |
449 fun fish_param _ (w as SOME _) = w |
442 | fish_param (IVar v) NONE = SOME v |
450 | fish_param (IVar v) NONE = SOME v |
443 | fish_param _ NONE = NONE; |
451 | fish_param _ NONE = NONE; |