356 fun pr ((v, pat), ty) = |
356 fun pr ((v, pat), ty) = |
357 pr_bind NOBR ((SOME v, pat), ty) |
357 pr_bind NOBR ((SOME v, pat), ty) |
358 #>> (fn p => concat [str "fn", p, str "=>"]); |
358 #>> (fn p => concat [str "fn", p, str "=>"]); |
359 val (ps, vars') = fold_map pr binds vars; |
359 val (ps, vars') = fold_map pr binds vars; |
360 in brackets (ps @ [pr_term vars' NOBR t']) end |
360 in brackets (ps @ [pr_term vars' NOBR t']) end |
361 | pr_term vars fxy (t as ICase (_, [_])) = |
361 | pr_term vars fxy (ICase (cases as (_, t0))) = (case CodegenThingol.unfold_const_app t0 |
362 let |
362 of SOME (c_ts as ((c, _), _)) => if is_none (const_syntax c) |
363 val (binds, t') = CodegenThingol.unfold_let t; |
363 then pr_case vars fxy cases |
364 fun pr ((pat, ty), t) vars = |
364 else pr_app vars fxy c_ts |
365 vars |
365 | NONE => pr_case vars fxy cases) |
366 |> pr_bind NOBR ((NONE, SOME pat), ty) |
|
367 |>> (fn p => semicolon [str "val", p, str "=", pr_term vars NOBR t]) |
|
368 val (ps, vars') = fold_map pr binds vars; |
|
369 in |
|
370 Pretty.chunks [ |
|
371 [str ("let"), Pretty.fbrk, Pretty.chunks ps] |> Pretty.block, |
|
372 [str ("in"), Pretty.fbrk, pr_term vars' NOBR t'] |> Pretty.block, |
|
373 str ("end") |
|
374 ] |
|
375 end |
|
376 | pr_term vars fxy (ICase ((td, ty), b::bs)) = |
|
377 let |
|
378 fun pr delim (pat, t) = |
|
379 let |
|
380 val (p, vars') = pr_bind NOBR ((NONE, SOME pat), ty) vars; |
|
381 in |
|
382 concat [str delim, p, str "=>", pr_term vars' NOBR t] |
|
383 end; |
|
384 in |
|
385 (Pretty.enclose "(" ")" o single o brackify fxy) ( |
|
386 str "case" |
|
387 :: pr_term vars NOBR td |
|
388 :: pr "of" b |
|
389 :: map (pr "|") bs |
|
390 ) |
|
391 end |
|
392 | pr_term vars fxy (t as ICase (_, [])) = str "raise Fail \"empty case\"" |
|
393 and pr_app' vars (app as ((c, (iss, tys)), ts)) = |
366 and pr_app' vars (app as ((c, (iss, tys)), ts)) = |
394 if is_cons c then let |
367 if is_cons c then let |
395 val k = length tys |
368 val k = length tys |
396 in if k < 2 then |
369 in if k < 2 then |
397 (str o deresolv) c :: map (pr_term vars BR) ts |
370 (str o deresolv) c :: map (pr_term vars BR) ts |
403 and pr_app vars = gen_pr_app pr_app' pr_term const_syntax vars |
376 and pr_app vars = gen_pr_app pr_app' pr_term const_syntax vars |
404 and pr_bind' ((NONE, NONE), _) = str "_" |
377 and pr_bind' ((NONE, NONE), _) = str "_" |
405 | pr_bind' ((SOME v, NONE), _) = str v |
378 | pr_bind' ((SOME v, NONE), _) = str v |
406 | pr_bind' ((NONE, SOME p), _) = p |
379 | pr_bind' ((NONE, SOME p), _) = p |
407 | pr_bind' ((SOME v, SOME p), _) = concat [str v, str "as", p] |
380 | pr_bind' ((SOME v, SOME p), _) = concat [str v, str "as", p] |
408 and pr_bind fxy = gen_pr_bind pr_bind' pr_term fxy; |
381 and pr_bind fxy = gen_pr_bind pr_bind' pr_term fxy |
|
382 and pr_case vars fxy (cases as ((_, [_]), _)) = |
|
383 let |
|
384 val (binds, t') = CodegenThingol.unfold_let (ICase cases); |
|
385 fun pr ((pat, ty), t) vars = |
|
386 vars |
|
387 |> pr_bind NOBR ((NONE, SOME pat), ty) |
|
388 |>> (fn p => semicolon [str "val", p, str "=", pr_term vars NOBR t]) |
|
389 val (ps, vars') = fold_map pr binds vars; |
|
390 in |
|
391 Pretty.chunks [ |
|
392 [str ("let"), Pretty.fbrk, Pretty.chunks ps] |> Pretty.block, |
|
393 [str ("in"), Pretty.fbrk, pr_term vars' NOBR t'] |> Pretty.block, |
|
394 str ("end") |
|
395 ] |
|
396 end |
|
397 | pr_case vars fxy (((td, ty), b::bs), _) = |
|
398 let |
|
399 fun pr delim (pat, t) = |
|
400 let |
|
401 val (p, vars') = pr_bind NOBR ((NONE, SOME pat), ty) vars; |
|
402 in |
|
403 concat [str delim, p, str "=>", pr_term vars' NOBR t] |
|
404 end; |
|
405 in |
|
406 (Pretty.enclose "(" ")" o single o brackify fxy) ( |
|
407 str "case" |
|
408 :: pr_term vars NOBR td |
|
409 :: pr "of" b |
|
410 :: map (pr "|") bs |
|
411 ) |
|
412 end |
|
413 | pr_case vars fxy ((_, []), _) = str "raise Fail \"empty case\"" |
409 fun pr_def (MLFuns (funns as (funn :: funns'))) = |
414 fun pr_def (MLFuns (funns as (funn :: funns'))) = |
410 let |
415 let |
411 val definer = |
416 val definer = |
412 let |
417 let |
413 fun mk [] [] = "val" |
418 fun mk [] [] = "val" |
621 let |
626 let |
622 val (binds, t') = CodegenThingol.unfold_abs t; |
627 val (binds, t') = CodegenThingol.unfold_abs t; |
623 fun pr ((v, pat), ty) = pr_bind BR ((SOME v, pat), ty); |
628 fun pr ((v, pat), ty) = pr_bind BR ((SOME v, pat), ty); |
624 val (ps, vars') = fold_map pr binds vars; |
629 val (ps, vars') = fold_map pr binds vars; |
625 in brackets (str "fun" :: ps @ str "->" @@ pr_term vars' NOBR t') end |
630 in brackets (str "fun" :: ps @ str "->" @@ pr_term vars' NOBR t') end |
626 | pr_term vars fxy (t as ICase (_, [_])) = |
631 | pr_term vars fxy (ICase (cases as (_, t0))) = (case CodegenThingol.unfold_const_app t0 |
627 let |
632 of SOME (c_ts as ((c, _), _)) => if is_none (const_syntax c) |
628 val (binds, t') = CodegenThingol.unfold_let t; |
633 then pr_case vars fxy cases |
629 fun pr ((pat, ty), t) vars = |
634 else pr_app vars fxy c_ts |
630 vars |
635 | NONE => pr_case vars fxy cases) |
631 |> pr_bind NOBR ((NONE, SOME pat), ty) |
|
632 |>> (fn p => concat [str "let", p, str "=", pr_term vars NOBR t, str "in"]) |
|
633 val (ps, vars') = fold_map pr binds vars; |
|
634 in Pretty.chunks (ps @| pr_term vars' NOBR t') end |
|
635 | pr_term vars fxy (ICase ((td, ty), b::bs)) = |
|
636 let |
|
637 fun pr delim (pat, t) = |
|
638 let |
|
639 val (p, vars') = pr_bind NOBR ((NONE, SOME pat), ty) vars; |
|
640 in concat [str delim, p, str "->", pr_term vars' NOBR t] end; |
|
641 in |
|
642 (Pretty.enclose "(" ")" o single o brackify fxy) ( |
|
643 str "match" |
|
644 :: pr_term vars NOBR td |
|
645 :: pr "with" b |
|
646 :: map (pr "|") bs |
|
647 ) |
|
648 end |
|
649 | pr_term vars fxy (t as ICase (_, [])) = str "failwith \"empty case\"" |
|
650 and pr_app' vars (app as ((c, (iss, tys)), ts)) = |
636 and pr_app' vars (app as ((c, (iss, tys)), ts)) = |
651 if is_cons c then |
637 if is_cons c then |
652 if length tys = length ts |
638 if length tys = length ts |
653 then case ts |
639 then case ts |
654 of [] => [(str o deresolv) c] |
640 of [] => [(str o deresolv) c] |
660 and pr_app vars = gen_pr_app pr_app' pr_term const_syntax vars |
646 and pr_app vars = gen_pr_app pr_app' pr_term const_syntax vars |
661 and pr_bind' ((NONE, NONE), _) = str "_" |
647 and pr_bind' ((NONE, NONE), _) = str "_" |
662 | pr_bind' ((SOME v, NONE), _) = str v |
648 | pr_bind' ((SOME v, NONE), _) = str v |
663 | pr_bind' ((NONE, SOME p), _) = p |
649 | pr_bind' ((NONE, SOME p), _) = p |
664 | pr_bind' ((SOME v, SOME p), _) = brackets [p, str "as", str v] |
650 | pr_bind' ((SOME v, SOME p), _) = brackets [p, str "as", str v] |
665 and pr_bind fxy = gen_pr_bind pr_bind' pr_term fxy; |
651 and pr_bind fxy = gen_pr_bind pr_bind' pr_term fxy |
|
652 and pr_case vars fxy (cases as ((_, [_]), _)) = |
|
653 let |
|
654 val (binds, t') = CodegenThingol.unfold_let (ICase cases); |
|
655 fun pr ((pat, ty), t) vars = |
|
656 vars |
|
657 |> pr_bind NOBR ((NONE, SOME pat), ty) |
|
658 |>> (fn p => concat [str "let", p, str "=", pr_term vars NOBR t, str "in"]) |
|
659 val (ps, vars') = fold_map pr binds vars; |
|
660 in Pretty.chunks (ps @| pr_term vars' NOBR t') end |
|
661 | pr_case vars fxy (((td, ty), b::bs), _) = |
|
662 let |
|
663 fun pr delim (pat, t) = |
|
664 let |
|
665 val (p, vars') = pr_bind NOBR ((NONE, SOME pat), ty) vars; |
|
666 in concat [str delim, p, str "->", pr_term vars' NOBR t] end; |
|
667 in |
|
668 (Pretty.enclose "(" ")" o single o brackify fxy) ( |
|
669 str "match" |
|
670 :: pr_term vars NOBR td |
|
671 :: pr "with" b |
|
672 :: map (pr "|") bs |
|
673 ) |
|
674 end |
|
675 | pr_case vars fxy ((_, []), _) = str "failwith \"empty case\""; |
666 fun pr_def (MLFuns (funns as funn :: funns')) = |
676 fun pr_def (MLFuns (funns as funn :: funns')) = |
667 let |
677 let |
668 fun fish_parm _ (w as SOME _) = w |
678 fun fish_parm _ (w as SOME _) = w |
669 | fish_parm (IVar v) NONE = SOME v |
679 | fish_parm (IVar v) NONE = SOME v |
670 | fish_parm _ NONE = NONE; |
680 | fish_parm _ NONE = NONE; |
1121 let |
1131 let |
1122 val (binds, t') = CodegenThingol.unfold_abs t; |
1132 val (binds, t') = CodegenThingol.unfold_abs t; |
1123 fun pr ((v, pat), ty) = pr_bind BR ((SOME v, pat), ty); |
1133 fun pr ((v, pat), ty) = pr_bind BR ((SOME v, pat), ty); |
1124 val (ps, vars') = fold_map pr binds vars; |
1134 val (ps, vars') = fold_map pr binds vars; |
1125 in brackets (str "\\" :: ps @ str "->" @@ pr_term vars' NOBR t') end |
1135 in brackets (str "\\" :: ps @ str "->" @@ pr_term vars' NOBR t') end |
1126 | pr_term vars fxy (t as ICase (_, [_])) = |
1136 | pr_term vars fxy (ICase (cases as (_, t0))) = (case CodegenThingol.unfold_const_app t0 |
1127 let |
1137 of SOME (c_ts as ((c, _), _)) => if is_none (const_syntax c) |
1128 val (binds, t) = CodegenThingol.unfold_let t; |
1138 then pr_case vars fxy cases |
|
1139 else pr_app vars fxy c_ts |
|
1140 | NONE => pr_case vars fxy cases) |
|
1141 and pr_app' vars ((c, _), ts) = |
|
1142 (str o deresolv) c :: map (pr_term vars BR) ts |
|
1143 and pr_app vars = gen_pr_app pr_app' pr_term const_syntax vars |
|
1144 and pr_bind fxy = pr_bind_haskell pr_term fxy |
|
1145 and pr_case vars fxy (cases as ((_, [_]), _)) = |
|
1146 let |
|
1147 val (binds, t) = CodegenThingol.unfold_let (ICase cases); |
1129 fun pr ((pat, ty), t) vars = |
1148 fun pr ((pat, ty), t) vars = |
1130 vars |
1149 vars |
1131 |> pr_bind BR ((NONE, SOME pat), ty) |
1150 |> pr_bind BR ((NONE, SOME pat), ty) |
1132 |>> (fn p => semicolon [p, str "=", pr_term vars NOBR t]) |
1151 |>> (fn p => semicolon [p, str "=", pr_term vars NOBR t]) |
1133 val (ps, vars') = fold_map pr binds vars; |
1152 val (ps, vars') = fold_map pr binds vars; |
1147 Pretty.block_enclose ( |
1166 Pretty.block_enclose ( |
1148 concat [str "(case", pr_term vars NOBR td, str "of", str "{"], |
1167 concat [str "(case", pr_term vars NOBR td, str "of", str "{"], |
1149 str "})" |
1168 str "})" |
1150 ) (map pr bs) |
1169 ) (map pr bs) |
1151 end |
1170 end |
1152 | pr_term vars fxy (t as ICase (_, [])) = str "error \"empty case\"" |
1171 | pr_case vars fxy ((_, []), _) = str "error \"empty case\""; |
1153 and pr_app' vars ((c, _), ts) = |
|
1154 (str o deresolv) c :: map (pr_term vars BR) ts |
|
1155 and pr_app vars = gen_pr_app pr_app' pr_term const_syntax vars |
|
1156 and pr_bind fxy = pr_bind_haskell pr_term fxy; |
|
1157 fun pr_def (name, CodegenThingol.Fun (eqs, (vs, ty))) = |
1172 fun pr_def (name, CodegenThingol.Fun (eqs, (vs, ty))) = |
1158 let |
1173 let |
1159 val tyvars = CodegenNames.intro_vars (map fst vs) init_syms; |
1174 val tyvars = CodegenNames.intro_vars (map fst vs) init_syms; |
1160 fun pr_eq (ts, t) = |
1175 fun pr_eq (ts, t) = |
1161 let |
1176 let |
1749 |
1764 |
1750 val pretty_imperative_monad_bind = |
1765 val pretty_imperative_monad_bind = |
1751 let |
1766 let |
1752 fun pretty (pr : CodegenNames.var_ctxt -> fixity -> iterm -> Pretty.T) |
1767 fun pretty (pr : CodegenNames.var_ctxt -> fixity -> iterm -> Pretty.T) |
1753 vars fxy [(t1, _), ((v, ty) `|-> t2, _)] = |
1768 vars fxy [(t1, _), ((v, ty) `|-> t2, _)] = |
1754 pr vars fxy (ICase ((t1, ty), ([(IVar v, t2)]))) |
1769 pr vars fxy (ICase (((t1, ty), ([(IVar v, t2)])), IVar "")) |
1755 | pretty pr vars fxy [(t1, _), (t2, ty2)] = |
1770 | pretty pr vars fxy [(t1, _), (t2, ty2)] = |
1756 let |
1771 let |
1757 (*this code suffers from the lack of a proper concept for bindings*) |
1772 (*this code suffers from the lack of a proper concept for bindings*) |
1758 val vs = CodegenThingol.fold_varnames cons t2 []; |
1773 val vs = CodegenThingol.fold_varnames cons t2 []; |
1759 val v = Name.variant vs "x"; |
1774 val v = Name.variant vs "x"; |
1760 val vars' = CodegenNames.intro_vars [v] vars; |
1775 val vars' = CodegenNames.intro_vars [v] vars; |
1761 val var = IVar v; |
1776 val var = IVar v; |
1762 val ty = (hd o fst o CodegenThingol.unfold_fun) ty2; |
1777 val ty = (hd o fst o CodegenThingol.unfold_fun) ty2; |
1763 in pr vars' fxy (ICase ((t1, ty), ([(var, t2 `$ var)]))) end; |
1778 in pr vars' fxy (ICase (((t1, ty), ([(var, t2 `$ var)])), IVar "")) end; |
1764 in (2, pretty) end; |
1779 in (2, pretty) end; |
1765 |
1780 |
1766 end; (*local*) |
1781 end; (*local*) |
1767 |
1782 |
1768 (** ML and Isar interface **) |
1783 (** ML and Isar interface **) |
2120 str "->", |
2135 str "->", |
2121 pr_typ (INFX (1, R)) ty2 |
2136 pr_typ (INFX (1, R)) ty2 |
2122 ])) |
2137 ])) |
2123 #> fold (add_reserved "SML") ML_Syntax.reserved_names |
2138 #> fold (add_reserved "SML") ML_Syntax.reserved_names |
2124 #> fold (add_reserved "SML") |
2139 #> fold (add_reserved "SML") |
2125 ["o" (*dictionary projections use it already*), "div", "mod" (*standard infixes*)] |
2140 ["o" (*dictionary projections use it already*), "Fail", "div", "mod" (*standard infixes*)] |
2126 #> fold (add_reserved "OCaml") [ |
2141 #> fold (add_reserved "OCaml") [ |
2127 "and", "as", "assert", "begin", "class", |
2142 "and", "as", "assert", "begin", "class", |
2128 "constraint", "do", "done", "downto", "else", "end", "exception", |
2143 "constraint", "do", "done", "downto", "else", "end", "exception", |
2129 "external", "false", "for", "fun", "function", "functor", "if", |
2144 "external", "false", "for", "fun", "function", "functor", "if", |
2130 "in", "include", "inherit", "initializer", "lazy", "let", "match", "method", |
2145 "in", "include", "inherit", "initializer", "lazy", "let", "match", "method", |
2131 "module", "mutable", "new", "object", "of", "open", "or", "private", "rec", |
2146 "module", "mutable", "new", "object", "of", "open", "or", "private", "rec", |
2132 "sig", "struct", "then", "to", "true", "try", "type", "val", |
2147 "sig", "struct", "then", "to", "true", "try", "type", "val", |
2133 "virtual", "when", "while", "with", "mod" |
2148 "virtual", "when", "while", "with" |
2134 ] |
2149 ] |
|
2150 #> fold (add_reserved "OCaml") ["failwith", "mod"] |
2135 #> fold (add_reserved "Haskell") [ |
2151 #> fold (add_reserved "Haskell") [ |
2136 "hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr", |
2152 "hiding", "deriving", "where", "case", "of", "infix", "infixl", "infixr", |
2137 "import", "default", "forall", "let", "in", "class", "qualified", "data", |
2153 "import", "default", "forall", "let", "in", "class", "qualified", "data", |
2138 "newtype", "instance", "if", "then", "else", "type", "as", "do", "module" |
2154 "newtype", "instance", "if", "then", "else", "type", "as", "do", "module" |
2139 ] |
2155 ] |