src/Tools/code/code_target.ML
changeset 25621 97ebdbdb0299
parent 25538 58e8ba3b792b
child 25771 a81c0ad97133
equal deleted inserted replaced
25620:a6cb8f60cff7 25621:97ebdbdb0299
  1128 val pr_bind_haskell = gen_pr_bind pr_bind';
  1128 val pr_bind_haskell = gen_pr_bind pr_bind';
  1129 
  1129 
  1130 in
  1130 in
  1131 
  1131 
  1132 fun pr_haskell class_syntax tyco_syntax const_syntax labelled_name
  1132 fun pr_haskell class_syntax tyco_syntax const_syntax labelled_name
  1133     init_syms deresolv_here deresolv is_cons deriving_show def =
  1133     init_syms deresolv_here deresolv is_cons contr_classparam_typs deriving_show def =
  1134   let
  1134   let
  1135     fun class_name class = case class_syntax class
  1135     fun class_name class = case class_syntax class
  1136      of NONE => deresolv class
  1136      of NONE => deresolv class
  1137       | SOME (class, _) => class;
  1137       | SOME (class, _) => class;
  1138     fun classparam_name class classparam = case class_syntax class
  1138     fun classparam_name class classparam = case class_syntax class
  1139      of NONE => deresolv_here classparam
  1139      of NONE => deresolv_here classparam
  1140       | SOME (_, classparam_syntax) => case classparam_syntax classparam
  1140       | SOME (_, classparam_syntax) => case classparam_syntax classparam
  1141          of NONE => (snd o dest_name) classparam
  1141          of NONE => (snd o dest_name) classparam
  1142           | SOME classparam => classparam
  1142           | SOME classparam => classparam;
  1143     fun pr_typparms tyvars vs =
  1143     fun pr_typcontext tyvars vs = case maps (fn (v, sort) => map (pair v) sort) vs
  1144       case maps (fn (v, sort) => map (pair v) sort) vs
  1144      of [] => []
  1145        of [] => str ""
  1145       | classbinds => Pretty.enum "," "(" ")" (
  1146         | xs => Pretty.block [
  1146           map (fn (v, class) =>
  1147             Pretty.enum "," "(" ")" (
  1147             str (class_name class ^ " " ^ CodeName.lookup_var tyvars v)) classbinds)
  1148               map (fn (v, class) => str
  1148           @@ str " => ";
  1149                 (class_name class ^ " " ^ CodeName.lookup_var tyvars v)) xs
  1149     fun pr_typforall tyvars vs = case map fst vs
  1150             ),
  1150      of [] => []
  1151             str " => "
  1151       | vnames => str "forall " :: Pretty.breaks
  1152           ];
  1152           (map (str o CodeName.lookup_var tyvars) vnames) @ str "." @@ Pretty.brk 1;
  1153     fun pr_tycoexpr tyvars fxy (tyco, tys) =
  1153     fun pr_tycoexpr tyvars fxy (tyco, tys) =
  1154       brackify fxy (str tyco :: map (pr_typ tyvars BR) tys)
  1154       brackify fxy (str tyco :: map (pr_typ tyvars BR) tys)
  1155     and pr_typ tyvars fxy (tycoexpr as tyco `%% tys) =
  1155     and pr_typ tyvars fxy (tycoexpr as tyco `%% tys) =
  1156           (case tyco_syntax tyco
  1156           (case tyco_syntax tyco
  1157            of NONE =>
  1157            of NONE =>
  1162                   ^ (string_of_int o length) tys ^ " given, "
  1162                   ^ (string_of_int o length) tys ^ " given, "
  1163                   ^ string_of_int i ^ " expected")
  1163                   ^ string_of_int i ^ " expected")
  1164                 else pr (pr_typ tyvars) fxy tys)
  1164                 else pr (pr_typ tyvars) fxy tys)
  1165       | pr_typ tyvars fxy (ITyVar v) =
  1165       | pr_typ tyvars fxy (ITyVar v) =
  1166           (str o CodeName.lookup_var tyvars) v;
  1166           (str o CodeName.lookup_var tyvars) v;
  1167     fun pr_typscheme_expr tyvars (vs, tycoexpr) =
  1167     fun pr_typdecl tyvars (vs, tycoexpr) =
  1168       Pretty.block (pr_typparms tyvars vs @@ pr_tycoexpr tyvars NOBR tycoexpr);
  1168       Pretty.block (pr_typcontext tyvars vs @| pr_tycoexpr tyvars NOBR tycoexpr);
  1169     fun pr_typscheme tyvars (vs, ty) =
  1169     fun pr_typscheme tyvars (vs, ty) =
  1170       Pretty.block (pr_typparms tyvars vs @@ pr_typ tyvars NOBR ty);
  1170       Pretty.block (pr_typforall tyvars vs @ pr_typcontext tyvars vs @| pr_typ tyvars NOBR ty);
  1171     fun pr_term lhs vars fxy (IConst c) =
  1171     fun pr_term tyvars lhs vars fxy (IConst c) =
  1172           pr_app lhs vars fxy (c, [])
  1172           pr_app tyvars lhs vars fxy (c, [])
  1173       | pr_term lhs vars fxy (t as (t1 `$ t2)) =
  1173       | pr_term tyvars lhs vars fxy (t as (t1 `$ t2)) =
  1174           (case CodeThingol.unfold_const_app t
  1174           (case CodeThingol.unfold_const_app t
  1175            of SOME app => pr_app lhs vars fxy app
  1175            of SOME app => pr_app tyvars lhs vars fxy app
  1176             | _ =>
  1176             | _ =>
  1177                 brackify fxy [
  1177                 brackify fxy [
  1178                   pr_term lhs vars NOBR t1,
  1178                   pr_term tyvars lhs vars NOBR t1,
  1179                   pr_term lhs vars BR t2
  1179                   pr_term tyvars lhs vars BR t2
  1180                 ])
  1180                 ])
  1181       | pr_term lhs vars fxy (IVar v) =
  1181       | pr_term tyvars lhs vars fxy (IVar v) =
  1182           (str o CodeName.lookup_var vars) v
  1182           (str o CodeName.lookup_var vars) v
  1183       | pr_term lhs vars fxy (t as _ `|-> _) =
  1183       | pr_term tyvars lhs vars fxy (t as _ `|-> _) =
  1184           let
  1184           let
  1185             val (binds, t') = CodeThingol.unfold_abs t;
  1185             val (binds, t') = CodeThingol.unfold_abs t;
  1186             fun pr ((v, pat), ty) = pr_bind BR ((SOME v, pat), ty);
  1186             fun pr ((v, pat), ty) = pr_bind tyvars BR ((SOME v, pat), ty);
  1187             val (ps, vars') = fold_map pr binds vars;
  1187             val (ps, vars') = fold_map pr binds vars;
  1188           in brackets (str "\\" :: ps @ str "->" @@ pr_term lhs vars' NOBR t') end
  1188           in brackets (str "\\" :: ps @ str "->" @@ pr_term tyvars lhs vars' NOBR t') end
  1189       | pr_term lhs vars fxy (ICase (cases as (_, t0))) =
  1189       | pr_term tyvars lhs vars fxy (ICase (cases as (_, t0))) =
  1190           (case CodeThingol.unfold_const_app t0
  1190           (case CodeThingol.unfold_const_app t0
  1191            of SOME (c_ts as ((c, _), _)) => if is_none (const_syntax c)
  1191            of SOME (c_ts as ((c, _), _)) => if is_none (const_syntax c)
  1192                 then pr_case vars fxy cases
  1192                 then pr_case tyvars vars fxy cases
  1193                 else pr_app lhs vars fxy c_ts
  1193                 else pr_app tyvars lhs vars fxy c_ts
  1194             | NONE => pr_case vars fxy cases)
  1194             | NONE => pr_case tyvars vars fxy cases)
  1195     and pr_app' lhs vars ((c, _), ts) =
  1195     and pr_app' tyvars lhs vars ((c, (_, tys)), ts) = case contr_classparam_typs c
  1196       (str o deresolv) c :: map (pr_term lhs vars BR) ts
  1196      of [] => (str o deresolv) c :: map (pr_term tyvars lhs vars BR) ts
  1197     and pr_app lhs vars = gen_pr_app pr_app' pr_term const_syntax
  1197       | fingerprint => let
       
  1198           val ts_fingerprint = ts ~~ curry Library.take (length ts) fingerprint;
       
  1199           val needs_annotation = forall (fn (_, NONE) => true | (t, SOME _) =>
       
  1200             (not o CodeThingol.locally_monomorphic) t) ts_fingerprint;
       
  1201           fun pr_term_anno (t, NONE) _ = pr_term tyvars lhs vars BR t
       
  1202             | pr_term_anno (t, SOME _) ty =
       
  1203                 brackets [pr_term tyvars lhs vars NOBR t, str "::", pr_typ tyvars NOBR ty];
       
  1204         in
       
  1205           if needs_annotation then
       
  1206             (str o deresolv) c :: map2 pr_term_anno ts_fingerprint (curry Library.take (length ts) tys)
       
  1207           else (str o deresolv) c :: map (pr_term tyvars lhs vars BR) ts
       
  1208         end
       
  1209     and pr_app tyvars lhs vars  = gen_pr_app (pr_app' tyvars) (pr_term tyvars) const_syntax
  1198       labelled_name is_cons lhs vars
  1210       labelled_name is_cons lhs vars
  1199     and pr_bind fxy = pr_bind_haskell pr_term fxy
  1211     and pr_bind tyvars = pr_bind_haskell (pr_term tyvars)
  1200     and pr_case vars fxy (cases as ((_, [_]), _)) =
  1212     and pr_case tyvars vars fxy (cases as ((_, [_]), _)) =
  1201           let
  1213           let
  1202             val (binds, t) = CodeThingol.unfold_let (ICase cases);
  1214             val (binds, t) = CodeThingol.unfold_let (ICase cases);
  1203             fun pr ((pat, ty), t) vars =
  1215             fun pr ((pat, ty), t) vars =
  1204               vars
  1216               vars
  1205               |> pr_bind BR ((NONE, SOME pat), ty)
  1217               |> pr_bind tyvars BR ((NONE, SOME pat), ty)
  1206               |>> (fn p => semicolon [p, str "=", pr_term false vars NOBR t])
  1218               |>> (fn p => semicolon [p, str "=", pr_term tyvars false vars NOBR t])
  1207             val (ps, vars') = fold_map pr binds vars;
  1219             val (ps, vars') = fold_map pr binds vars;
  1208           in
  1220           in
  1209             Pretty.block_enclose (
  1221             Pretty.block_enclose (
  1210               str "let {",
  1222               str "let {",
  1211               concat [str "}", str "in", pr_term false vars' NOBR t]
  1223               concat [str "}", str "in", pr_term tyvars false vars' NOBR t]
  1212             ) ps
  1224             ) ps
  1213           end
  1225           end
  1214       | pr_case vars fxy (((td, ty), bs as _ :: _), _) =
  1226       | pr_case tyvars vars fxy (((td, ty), bs as _ :: _), _) =
  1215           let
  1227           let
  1216             fun pr (pat, t) =
  1228             fun pr (pat, t) =
  1217               let
  1229               let
  1218                 val (p, vars') = pr_bind NOBR ((NONE, SOME pat), ty) vars;
  1230                 val (p, vars') = pr_bind tyvars NOBR ((NONE, SOME pat), ty) vars;
  1219               in semicolon [p, str "->", pr_term false vars' NOBR t] end;
  1231               in semicolon [p, str "->", pr_term tyvars false vars' NOBR t] end;
  1220           in
  1232           in
  1221             Pretty.block_enclose (
  1233             Pretty.block_enclose (
  1222               concat [str "(case", pr_term false vars NOBR td, str "of", str "{"],
  1234               concat [str "(case", pr_term tyvars false vars NOBR td, str "of", str "{"],
  1223               str "})"
  1235               str "})"
  1224             ) (map pr bs)
  1236             ) (map pr bs)
  1225           end
  1237           end
  1226       | pr_case vars fxy ((_, []), _) = str "error \"empty case\"";
  1238       | pr_case tyvars vars fxy ((_, []), _) = str "error \"empty case\"";
  1227     fun pr_def (name, CodeThingol.Fun ((vs, ty), [])) =
  1239     fun pr_def (name, CodeThingol.Fun ((vs, ty), [])) =
  1228           let
  1240           let
  1229             val tyvars = CodeName.intro_vars (map fst vs) init_syms;
  1241             val tyvars = CodeName.intro_vars (map fst vs) init_syms;
  1230             val n = (length o fst o CodeThingol.unfold_fun) ty;
  1242             val n = (length o fst o CodeThingol.unfold_fun) ty;
  1231           in
  1243           in
  1260                   |> CodeName.intro_vars ((fold o CodeThingol.fold_unbound_varnames)
  1272                   |> CodeName.intro_vars ((fold o CodeThingol.fold_unbound_varnames)
  1261                        (insert (op =)) ts []);
  1273                        (insert (op =)) ts []);
  1262               in
  1274               in
  1263                 semicolon (
  1275                 semicolon (
  1264                   (str o deresolv_here) name
  1276                   (str o deresolv_here) name
  1265                   :: map (pr_term true vars BR) ts
  1277                   :: map (pr_term tyvars true vars BR) ts
  1266                   @ str "="
  1278                   @ str "="
  1267                   @@ pr_term false vars NOBR t
  1279                   @@ pr_term tyvars false vars NOBR t
  1268                 )
  1280                 )
  1269               end;
  1281               end;
  1270           in
  1282           in
  1271             Pretty.chunks (
  1283             Pretty.chunks (
  1272               Pretty.block [
  1284               Pretty.block [
  1282           let
  1294           let
  1283             val tyvars = CodeName.intro_vars (map fst vs) init_syms;
  1295             val tyvars = CodeName.intro_vars (map fst vs) init_syms;
  1284           in
  1296           in
  1285             semicolon [
  1297             semicolon [
  1286               str "data",
  1298               str "data",
  1287               pr_typscheme_expr tyvars (vs, (deresolv_here name, map (ITyVar o fst) vs))
  1299               pr_typdecl tyvars (vs, (deresolv_here name, map (ITyVar o fst) vs))
  1288             ]
  1300             ]
  1289           end
  1301           end
  1290       | pr_def (name, CodeThingol.Datatype (vs, [(co, [ty])])) =
  1302       | pr_def (name, CodeThingol.Datatype (vs, [(co, [ty])])) =
  1291           let
  1303           let
  1292             val tyvars = CodeName.intro_vars (map fst vs) init_syms;
  1304             val tyvars = CodeName.intro_vars (map fst vs) init_syms;
  1293           in
  1305           in
  1294             semicolon (
  1306             semicolon (
  1295               str "newtype"
  1307               str "newtype"
  1296               :: pr_typscheme_expr tyvars (vs, (deresolv_here name, map (ITyVar o fst) vs))
  1308               :: pr_typdecl tyvars (vs, (deresolv_here name, map (ITyVar o fst) vs))
  1297               :: str "="
  1309               :: str "="
  1298               :: (str o deresolv_here) co
  1310               :: (str o deresolv_here) co
  1299               :: pr_typ tyvars BR ty
  1311               :: pr_typ tyvars BR ty
  1300               :: (if deriving_show name then [str "deriving (Read, Show)"] else [])
  1312               :: (if deriving_show name then [str "deriving (Read, Show)"] else [])
  1301             )
  1313             )
  1309                 :: map (pr_typ tyvars BR) tys
  1321                 :: map (pr_typ tyvars BR) tys
  1310               )
  1322               )
  1311           in
  1323           in
  1312             semicolon (
  1324             semicolon (
  1313               str "data"
  1325               str "data"
  1314               :: pr_typscheme_expr tyvars (vs, (deresolv_here name, map (ITyVar o fst) vs))
  1326               :: pr_typdecl tyvars (vs, (deresolv_here name, map (ITyVar o fst) vs))
  1315               :: str "="
  1327               :: str "="
  1316               :: pr_co co
  1328               :: pr_co co
  1317               :: map ((fn p => Pretty.block [str "| ", p]) o pr_co) cos
  1329               :: map ((fn p => Pretty.block [str "| ", p]) o pr_co) cos
  1318               @ (if deriving_show name then [str "deriving (Read, Show)"] else [])
  1330               @ (if deriving_show name then [str "deriving (Read, Show)"] else [])
  1319             )
  1331             )
  1329               ]
  1341               ]
  1330           in
  1342           in
  1331             Pretty.block_enclose (
  1343             Pretty.block_enclose (
  1332               Pretty.block [
  1344               Pretty.block [
  1333                 str "class ",
  1345                 str "class ",
  1334                 pr_typparms tyvars [(v, map fst superclasses)],
  1346                 Pretty.block (pr_typcontext tyvars [(v, map fst superclasses)]),
  1335                 str (deresolv_here name ^ " " ^ CodeName.lookup_var tyvars v),
  1347                 str (deresolv_here name ^ " " ^ CodeName.lookup_var tyvars v),
  1336                 str " where {"
  1348                 str " where {"
  1337               ],
  1349               ],
  1338               str "};"
  1350               str "};"
  1339             ) (map pr_classparam classparams)
  1351             ) (map pr_classparam classparams)
  1343             val tyvars = CodeName.intro_vars (map fst vs) init_syms;
  1355             val tyvars = CodeName.intro_vars (map fst vs) init_syms;
  1344             fun pr_instdef ((classparam, c_inst), _) =
  1356             fun pr_instdef ((classparam, c_inst), _) =
  1345               semicolon [
  1357               semicolon [
  1346                 (str o classparam_name class) classparam,
  1358                 (str o classparam_name class) classparam,
  1347                 str "=",
  1359                 str "=",
  1348                 pr_app false init_syms NOBR (c_inst, [])
  1360                 pr_app tyvars false init_syms NOBR (c_inst, [])
  1349               ];
  1361               ];
  1350           in
  1362           in
  1351             Pretty.block_enclose (
  1363             Pretty.block_enclose (
  1352               Pretty.block [
  1364               Pretty.block [
  1353                 str "instance ",
  1365                 str "instance ",
  1354                 pr_typparms tyvars vs,
  1366                 Pretty.block (pr_typcontext tyvars vs),
  1355                 str (class_name class ^ " "),
  1367                 str (class_name class ^ " "),
  1356                 pr_typ tyvars BR (tyco `%% map (ITyVar o fst) vs),
  1368                 pr_typ tyvars BR (tyco `%% map (ITyVar o fst) vs),
  1357                 str " where {"
  1369                 str " where {"
  1358               ],
  1370               ],
  1359               str "};"
  1371               str "};"
  1386     reserved_syms includes raw_module_alias
  1398     reserved_syms includes raw_module_alias
  1387     class_syntax tyco_syntax const_syntax code =
  1399     class_syntax tyco_syntax const_syntax code =
  1388   let
  1400   let
  1389     val _ = Option.map File.check destination;
  1401     val _ = Option.map File.check destination;
  1390     val is_cons = CodeThingol.is_cons code;
  1402     val is_cons = CodeThingol.is_cons code;
       
  1403     val contr_classparam_typs = CodeThingol.contr_classparam_typs code;
  1391     val module_alias = if is_some module then K module else raw_module_alias;
  1404     val module_alias = if is_some module then K module else raw_module_alias;
  1392     val init_names = Name.make_context reserved_syms;
  1405     val init_names = Name.make_context reserved_syms;
  1393     val name_modl = mk_modl_name_tab init_names module_prefix module_alias code;
  1406     val name_modl = mk_modl_name_tab init_names module_prefix module_alias code;
  1394     fun add_def (name, (def, deps)) =
  1407     fun add_def (name, (def, deps)) =
  1395       let
  1408       let
  1458           | deriv' _ (ITyVar _) = true
  1471           | deriv' _ (ITyVar _) = true
  1459       in deriv [] tyco end;
  1472       in deriv [] tyco end;
  1460     fun seri_def qualified = pr_haskell class_syntax tyco_syntax
  1473     fun seri_def qualified = pr_haskell class_syntax tyco_syntax
  1461       const_syntax labelled_name init_syms
  1474       const_syntax labelled_name init_syms
  1462       deresolv_here (if qualified then deresolv else deresolv_here) is_cons
  1475       deresolv_here (if qualified then deresolv else deresolv_here) is_cons
       
  1476       contr_classparam_typs
  1463       (if string_classes then deriving_show else K false);
  1477       (if string_classes then deriving_show else K false);
  1464     fun write_modulefile (SOME destination) modlname =
  1478     fun write_modulefile (SOME destination) modlname =
  1465           let
  1479           let
  1466             val filename = case modlname
  1480             val filename = case modlname
  1467              of "" => Path.explode "Main.hs"
  1481              of "" => Path.explode "Main.hs"
  1539             str "->",
  1553             str "->",
  1540             pr_typ (INFX (1, R)) ty2
  1554             pr_typ (INFX (1, R)) ty2
  1541           ])
  1555           ])
  1542       | pr_fun _ = NONE
  1556       | pr_fun _ = NONE
  1543     val pr = pr_haskell (K NONE) pr_fun (K NONE) labelled_name init_names
  1557     val pr = pr_haskell (K NONE) pr_fun (K NONE) labelled_name init_names
  1544       I I (K false) (K false);
  1558       I I (K false) (K []) (K false);
  1545   in
  1559   in
  1546     []
  1560     []
  1547     |> Graph.fold (fn (name, (def, _)) =>
  1561     |> Graph.fold (fn (name, (def, _)) =>
  1548           case try pr (name, def) of SOME p => cons p | NONE => I) code
  1562           case try pr (name, def) of SOME p => cons p | NONE => I) code
  1549     |> Pretty.chunks2
  1563     |> Pretty.chunks2