src/Pure/Tools/codegen_serializer.ML
changeset 24166 7b28dc69bdbb
parent 23931 4d82207fb251
child 24202 9e77397eba8e
equal deleted inserted replaced
24165:605f664d5115 24166:7b28dc69bdbb
   279     val tab =
   279     val tab =
   280       Symtab.empty
   280       Symtab.empty
   281       |> Graph.fold ((fn name => Symtab.default (name, (mk_alias #> mk_prefix) name))
   281       |> Graph.fold ((fn name => Symtab.default (name, (mk_alias #> mk_prefix) name))
   282            o fst o dest_name o fst)
   282            o fst o dest_name o fst)
   283              code
   283              code
   284   in (fn name => (the o Symtab.lookup tab) name) end;
   284   in fn name => (the o Symtab.lookup tab) name end;
   285 
   285 
   286 
   286 
   287 
   287 
   288 (** SML/OCaml serializer **)
   288 (** SML/OCaml serializer **)
   289 
   289 
   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;
  1135             Pretty.block_enclose (
  1154             Pretty.block_enclose (
  1136               str "let {",
  1155               str "let {",
  1137               concat [str "}", str "in", pr_term vars' NOBR t]
  1156               concat [str "}", str "in", pr_term vars' NOBR t]
  1138             ) ps
  1157             ) ps
  1139           end
  1158           end
  1140       | pr_term vars fxy (ICase ((td, ty), bs as _ :: _)) =
  1159       | pr_case vars fxy (((td, ty), bs as _ :: _), _) =
  1141           let
  1160           let
  1142             fun pr (pat, t) =
  1161             fun pr (pat, t) =
  1143               let
  1162               let
  1144                 val (p, vars') = pr_bind NOBR ((NONE, SOME pat), ty) vars;
  1163                 val (p, vars') = pr_bind NOBR ((NONE, SOME pat), ty) vars;
  1145               in semicolon [p, str "->", pr_term vars' NOBR t] end;
  1164               in semicolon [p, str "->", pr_term vars' NOBR t] end;
  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     ]