comparison src/monoize.sml @ 1288:fc7ecf8883b1

Some post-type-checking support for polymorphic variants
author Adam Chlipala <adam@chlipala.net>
date Sat, 21 Aug 2010 10:58:13 -0400
parents 5137b0537c92
children 6791454653c5
comparison
equal deleted inserted replaced
1287:5137b0537c92 1288:fc7ecf8883b1
51 end) 51 end)
52 52
53 val nextPvar = ref 0 53 val nextPvar = ref 0
54 val pvars = ref (RM.empty : (int * (string * int * L'.typ) list) RM.map) 54 val pvars = ref (RM.empty : (int * (string * int * L'.typ) list) RM.map)
55 val pvarDefs = ref ([] : L'.decl list) 55 val pvarDefs = ref ([] : L'.decl list)
56 val pvarOldDefs = ref ([] : (int * (string * int * L.con option) list) list)
56 57
57 fun choosePvar () = 58 fun choosePvar () =
58 let 59 let
59 val n = !nextPvar 60 val n = !nextPvar
60 in 61 in
61 nextPvar := n + 1; 62 nextPvar := n + 1;
62 n 63 n
63 end 64 end
64 65
65 fun pvar (r, loc) = 66 fun pvar (r, r', loc) =
66 case RM.find (!pvars, r) of 67 case RM.find (!pvars, r') of
67 NONE => 68 NONE =>
68 let 69 let
69 val n = choosePvar () 70 val n = choosePvar ()
70 val fs = map (fn (x, t) => (x, choosePvar (), t)) r 71 val fs = map (fn (x, t) => (x, choosePvar (), t)) r'
71 val fs' = foldl (fn ((x, n, _), fs') => SM.insert (fs', x, n)) SM.empty fs 72 val (r, fs') = ListPair.foldr (fn ((_, t), (x, n, _), (r, fs')) =>
73 ((x, n, SOME t) :: r,
74 SM.insert (fs', x, n))) ([], SM.empty) (r, fs)
72 in 75 in
73 pvars := RM.insert (!pvars, r, (n, fs)); 76 pvars := RM.insert (!pvars, r', (n, fs));
74 pvarDefs := (L'.DDatatype [("$poly" ^ Int.toString n, n, map (fn (x, n, t) => (x, n, SOME t)) fs)], loc) 77 pvarDefs := (L'.DDatatype [("$poly" ^ Int.toString n, n, map (fn (x, n, t) => (x, n, SOME t)) fs)], loc)
75 :: !pvarDefs; 78 :: !pvarDefs;
79 pvarOldDefs := (n, r) :: !pvarOldDefs;
76 (n, fs) 80 (n, fs)
77 end 81 end
78 | SOME v => v 82 | SOME v => v
79 83
80 val singletons = SS.addList (SS.empty, 84 val singletons = SS.addList (SS.empty,
156 | L.CApp ((L.CFfi ("Basis", "list"), _), t) => 160 | L.CApp ((L.CFfi ("Basis", "list"), _), t) =>
157 (L'.TList (mt env dtmap t), loc) 161 (L'.TList (mt env dtmap t), loc)
158 162
159 | L.CApp ((L.CFfi ("Basis", "variant"), _), (L.CRecord ((L.KType, _), xts), _)) => 163 | L.CApp ((L.CFfi ("Basis", "variant"), _), (L.CRecord ((L.KType, _), xts), _)) =>
160 let 164 let
161 val xts = map (fn (x, t) => (monoName env x, mt env dtmap t)) xts 165 val xts' = map (fn (x, t) => (monoName env x, mt env dtmap t)) xts
162 val xts = ListMergeSort.sort (fn ((x, _), (y, _)) => String.compare (x, y) = GREATER) xts 166 val xts' = ListMergeSort.sort (fn ((x, _), (y, _)) => String.compare (x, y) = GREATER) xts'
163 val (n, cs) = pvar (xts, loc) 167 val (n, cs) = pvar (xts, xts', loc)
164 val cs = map (fn (x, n, t) => (x, n, SOME t)) cs 168 val cs = map (fn (x, n, t) => (x, n, SOME t)) cs
165 in 169 in
166 (L'.TDatatype (n, ref (ElabUtil.classifyDatatype cs, cs)), loc) 170 (L'.TDatatype (n, ref (ElabUtil.classifyDatatype cs, cs)), loc)
167 end 171 end
168 172
814 end 818 end
815 | L.ECon _ => poly () 819 | L.ECon _ => poly ()
816 820
817 | L.ECApp ( 821 | L.ECApp (
818 (L.ECApp ( 822 (L.ECApp (
819 (L.ECApp ((L.EFfi ("Basis", "make"), _), (L.CName nm, _)), _), 823 (L.ECApp ((L.EFfi ("Basis", "make"), _), nmC as (L.CName nm, _)), _),
820 t), _), 824 t), _),
821 (L.CRecord (_, xts), _)) => 825 (L.CRecord (_, xts), _)) =>
822 let 826 let
823 val t = monoType env t 827 val t' = monoType env t
824 val xts = map (fn (x, t) => (monoName env x, monoType env t)) xts 828 val xts' = map (fn (x, t) => (monoName env x, monoType env t)) xts
825 val xts = (nm, t) :: xts 829 val xts' = (nm, t') :: xts'
826 val xts = ListMergeSort.sort (fn ((x, _), (y, _)) => String.compare (x, y) = GREATER) xts 830 val xts' = ListMergeSort.sort (fn ((x, _), (y, _)) => String.compare (x, y) = GREATER) xts'
827 val (n, cs) = pvar (xts, loc) 831 val (n, cs) = pvar ((nmC, t) :: xts, xts', loc)
828 val cs' = map (fn (x, n, t) => (x, n, SOME t)) cs 832 val cs' = map (fn (x, n, t) => (x, n, SOME t)) cs
829 val cl = ElabUtil.classifyDatatype cs' 833 val cl = ElabUtil.classifyDatatype cs'
830 in 834 in
831 case List.find (fn (nm', _, _) => nm' = nm) cs of 835 case List.find (fn (nm', _, _) => nm' = nm) cs of
832 NONE => raise Fail "Monoize: Polymorphic variant tag mismatch for 'make'" 836 NONE => raise Fail "Monoize: Polymorphic variant tag mismatch for 'make'"
833 | SOME (_, n', _) => ((L'.EAbs ("x", t, (L'.TDatatype (n, ref (cl, cs')), loc), 837 | SOME (_, n', _) => ((L'.EAbs ("x", t', (L'.TDatatype (n, ref (cl, cs')), loc),
834 (L'.ECon (cl, L'.PConVar n', SOME (L'.ERel 0, loc)), loc)), loc), 838 (L'.ECon (cl, L'.PConVar n', SOME (L'.ERel 0, loc)), loc)), loc),
835 fm) 839 fm)
836 end 840 end
837 841
838 | L.ECApp ( 842 | L.ECApp (
839 (L.ECApp ((L.EFfi ("Basis", "match"), _), (L.CRecord (_, xts), _)), _), 843 (L.ECApp ((L.EFfi ("Basis", "match"), _), (L.CRecord (_, xts), _)), _),
840 t) => 844 t) =>
841 let 845 let
842 val t = monoType env t 846 val t = monoType env t
843 val xts = map (fn (x, t) => (monoName env x, monoType env t)) xts 847 val xts' = map (fn (x, t) => (monoName env x, monoType env t)) xts
844 val xts = ListMergeSort.sort (fn ((x, _), (y, _)) => String.compare (x, y) = GREATER) xts 848 val xts' = ListMergeSort.sort (fn ((x, _), (y, _)) => String.compare (x, y) = GREATER) xts'
845 val (n, cs) = pvar (xts, loc) 849 val (n, cs) = pvar (xts, xts', loc)
846 val cs' = map (fn (x, n, t) => (x, n, SOME t)) cs 850 val cs' = map (fn (x, n, t) => (x, n, SOME t)) cs
847 val cl = ElabUtil.classifyDatatype cs' 851 val cl = ElabUtil.classifyDatatype cs'
848 val fs = (L'.TRecord (map (fn (x, t') => (x, (L'.TFun (t', t), loc))) xts), loc) 852 val fs = (L'.TRecord (map (fn (x, t') => (x, (L'.TFun (t', t), loc))) xts'), loc)
849 val dt = (L'.TDatatype (n, ref (cl, cs')), loc) 853 val dt = (L'.TDatatype (n, ref (cl, cs')), loc)
850 in 854 in
851 ((L'.EAbs ("v", 855 ((L'.EAbs ("v",
852 dt, 856 dt,
853 (L'.TFun (fs, t), loc), 857 (L'.TFun (fs, t), loc),
4097 :: (dIni, loc) 4101 :: (dIni, loc)
4098 :: ds) 4102 :: ds)
4099 end 4103 end
4100 | _ => 4104 | _ =>
4101 (pvarDefs := []; 4105 (pvarDefs := [];
4106 pvarOldDefs := [];
4102 case monoDecl (env, fm) d of 4107 case monoDecl (env, fm) d of
4103 NONE => (env, fm, ds) 4108 NONE => (env, fm, ds)
4104 | SOME (env, fm, ds') => 4109 | SOME (env, fm, ds') =>
4105 (env, 4110 (foldr (fn ((n, cs), env) =>
4111 Env.declBinds env (L.DDatatype [("$poly" ^ Int.toString n,
4112 n,
4113 [],
4114 cs)], loc))
4115 env (!pvarOldDefs),
4106 Fm.enter fm, 4116 Fm.enter fm,
4107 ds' @ Fm.decls fm @ !pvarDefs @ ds))) 4117 ds' @ Fm.decls fm @ !pvarDefs @ ds)))
4108 (env, Fm.empty mname, []) file 4118 (env, Fm.empty mname, []) file
4109 in 4119 in
4110 pvars := RM.empty; 4120 pvars := RM.empty;
4111 pvarDefs := []; 4121 pvarDefs := [];
4122 pvarOldDefs := [];
4112 rev ds 4123 rev ds
4113 end 4124 end
4114 4125
4115 end 4126 end