Mercurial > urweb
comparison src/especialize.sml @ 453:787d4931fb07
Almost have that nested save function compiling
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Sat, 01 Nov 2008 21:19:43 -0400 |
parents | f45f23ae20ed |
children | b393c2fc80f8 |
comparison
equal
deleted
inserted
replaced
452:222cbc1da232 | 453:787d4931fb07 |
---|---|
30 open Core | 30 open Core |
31 | 31 |
32 structure E = CoreEnv | 32 structure E = CoreEnv |
33 structure U = CoreUtil | 33 structure U = CoreUtil |
34 | 34 |
35 structure ILK = struct | 35 datatype skey = |
36 type ord_key = int list | 36 Named of int |
37 val compare = Order.joinL Int.compare | 37 | App of skey * skey |
38 | |
39 structure K = struct | |
40 type ord_key = skey list | |
41 fun compare' (k1, k2) = | |
42 case (k1, k2) of | |
43 (Named n1, Named n2) => Int.compare (n1, n2) | |
44 | (Named _, _) => LESS | |
45 | (_, Named _) => GREATER | |
46 | |
47 | (App (x1, y1), App (x2, y2)) => Order.join (compare' (x1, x2), fn () => compare' (y1, y2)) | |
48 | |
49 val compare = Order.joinL compare' | |
38 end | 50 end |
39 | 51 |
40 structure ILM = BinaryMapFn(ILK) | 52 structure KM = BinaryMapFn(K) |
41 structure IM = IntBinaryMap | 53 structure IM = IntBinaryMap |
54 | |
55 fun skeyIn (e, _) = | |
56 case e of | |
57 ENamed n => SOME (Named n) | |
58 | EApp (e1, e2) => | |
59 (case (skeyIn e1, skeyIn e2) of | |
60 (SOME k1, SOME k2) => SOME (App (k1, k2)) | |
61 | _ => NONE) | |
62 | _ => NONE | |
63 | |
64 fun skeyOut (k, loc) = | |
65 case k of | |
66 Named n => (ENamed n, loc) | |
67 | App (k1, k2) => (EApp (skeyOut (k1, loc), skeyOut (k2, loc)), loc) | |
42 | 68 |
43 type func = { | 69 type func = { |
44 name : string, | 70 name : string, |
45 args : int ILM.map, | 71 args : int KM.map, |
46 body : exp, | 72 body : exp, |
47 typ : con, | 73 typ : con, |
48 tag : string | 74 tag : string |
49 } | 75 } |
50 | 76 |
60 fun exp (e, st : state) = | 86 fun exp (e, st : state) = |
61 let | 87 let |
62 fun getApp e = | 88 fun getApp e = |
63 case e of | 89 case e of |
64 ENamed f => SOME (f, [], []) | 90 ENamed f => SOME (f, [], []) |
65 | EApp (e1, (ENamed x, _)) => | |
66 (case getApp (#1 e1) of | |
67 NONE => NONE | |
68 | SOME (f, xs, xs') => SOME (f, xs @ [x], xs')) | |
69 | EApp (e1, e2) => | 91 | EApp (e1, e2) => |
70 (case getApp (#1 e1) of | 92 (case getApp (#1 e1) of |
71 NONE => NONE | 93 NONE => NONE |
72 | SOME (f, xs, xs') => SOME (f, xs, xs' @ [e2])) | 94 | SOME (f, xs, xs') => |
95 let | |
96 val k = | |
97 if List.null xs' then | |
98 skeyIn e2 | |
99 else | |
100 NONE | |
101 in | |
102 case k of | |
103 NONE => SOME (f, xs, xs' @ [e2]) | |
104 | SOME k => SOME (f, xs @ [k], xs') | |
105 end) | |
73 | _ => NONE | 106 | _ => NONE |
74 in | 107 in |
75 case getApp e of | 108 case getApp e of |
76 NONE => (e, st) | 109 NONE => (e, st) |
77 | SOME (_, [], _) => (e, st) | 110 | SOME (_, [], _) => (e, st) |
78 | SOME (f, xs, xs') => | 111 | SOME (f, xs, xs') => |
79 case IM.find (#funcs st, f) of | 112 case IM.find (#funcs st, f) of |
80 NONE => (e, st) | 113 NONE => ((*print "SHOT DOWN!\n";*) (e, st)) |
81 | SOME {name, args, body, typ, tag} => | 114 | SOME {name, args, body, typ, tag} => |
82 case ILM.find (args, xs) of | 115 case KM.find (args, xs) of |
83 SOME f' => (#1 (foldl (fn (e, arg) => (EApp (e, arg), ErrorMsg.dummySpan)) | 116 SOME f' => ((*Print.prefaces "Pre-existing" [("e", CorePrint.p_exp CoreEnv.empty (e, ErrorMsg.dummySpan))];*) |
84 (ENamed f', ErrorMsg.dummySpan) xs'), | 117 (#1 (foldl (fn (e, arg) => (EApp (e, arg), ErrorMsg.dummySpan)) |
85 st) | 118 (ENamed f', ErrorMsg.dummySpan) xs'), |
119 st)) | |
86 | NONE => | 120 | NONE => |
87 let | 121 let |
122 (*val () = Print.prefaces "New" [("e", CorePrint.p_exp CoreEnv.empty (e, ErrorMsg.dummySpan))]*) | |
123 | |
88 fun subBody (body, typ, xs) = | 124 fun subBody (body, typ, xs) = |
89 case (#1 body, #1 typ, xs) of | 125 case (#1 body, #1 typ, xs) of |
90 (_, _, []) => SOME (body, typ) | 126 (_, _, []) => SOME (body, typ) |
91 | (EAbs (_, _, _, body'), TFun (_, typ'), x :: xs) => | 127 | (EAbs (_, _, _, body'), TFun (_, typ'), x :: xs) => |
92 subBody (E.subExpInExp (0, (ENamed x, ErrorMsg.dummySpan)) body', | 128 let |
93 typ', | 129 val body'' = E.subExpInExp (0, skeyOut (x, #2 body)) body' |
94 xs) | 130 in |
131 (*Print.prefaces "espec" [("body'", CorePrint.p_exp CoreEnv.empty body'), | |
132 ("body''", CorePrint.p_exp CoreEnv.empty body'')];*) | |
133 subBody (body'', | |
134 typ', | |
135 xs) | |
136 end | |
95 | _ => NONE | 137 | _ => NONE |
96 in | 138 in |
97 case subBody (body, typ, xs) of | 139 case subBody (body, typ, xs) of |
98 NONE => (e, st) | 140 NONE => (e, st) |
99 | SOME (body', typ') => | 141 | SOME (body', typ') => |
100 let | 142 let |
101 val f' = #maxName st | 143 val f' = #maxName st |
144 (*val () = print ("f' = " ^ Int.toString f' ^ "\n")*) | |
102 val funcs = IM.insert (#funcs st, f, {name = name, | 145 val funcs = IM.insert (#funcs st, f, {name = name, |
103 args = ILM.insert (args, xs, f'), | 146 args = KM.insert (args, xs, f'), |
104 body = body, | 147 body = body, |
105 typ = typ, | 148 typ = typ, |
106 tag = tag}) | 149 tag = tag}) |
107 val st = { | 150 val st = { |
108 maxName = f' + 1, | 151 maxName = f' + 1, |
126 | 169 |
127 fun decl (d, st) = (d, st) | 170 fun decl (d, st) = (d, st) |
128 | 171 |
129 val specDecl = U.Decl.foldMap {kind = kind, con = con, exp = exp, decl = decl} | 172 val specDecl = U.Decl.foldMap {kind = kind, con = con, exp = exp, decl = decl} |
130 | 173 |
131 fun specialize file = | 174 fun specialize' file = |
132 let | 175 let |
133 fun doDecl (d, st) = | 176 fun doDecl (d, (st : state, changed)) = |
134 let | 177 let |
178 val funcs = #funcs st | |
179 val funcs = | |
180 case #1 d of | |
181 DValRec vis => | |
182 foldl (fn ((x, n, c, e, tag), funcs) => | |
183 IM.insert (funcs, n, {name = x, | |
184 args = KM.empty, | |
185 body = e, | |
186 typ = c, | |
187 tag = tag})) | |
188 funcs vis | |
189 | _ => funcs | |
190 | |
191 val st = {maxName = #maxName st, | |
192 funcs = funcs, | |
193 decls = []} | |
194 | |
135 val (d', st) = specDecl st d | 195 val (d', st) = specDecl st d |
136 | 196 |
137 val funcs = #funcs st | 197 val funcs = #funcs st |
138 val funcs = | 198 val funcs = |
139 case #1 d of | 199 case #1 d of |
140 DVal (x, n, c, e as (EAbs _, _), tag) => | 200 DVal (x, n, c, e as (EAbs _, _), tag) => |
141 IM.insert (funcs, n, {name = x, | 201 IM.insert (funcs, n, {name = x, |
142 args = ILM.empty, | 202 args = KM.empty, |
143 body = e, | 203 body = e, |
144 typ = c, | 204 typ = c, |
145 tag = tag}) | 205 tag = tag}) |
146 | DValRec vis => | |
147 foldl (fn ((x, n, c, e, tag), funcs) => | |
148 IM.insert (funcs, n, {name = x, | |
149 args = ILM.empty, | |
150 body = e, | |
151 typ = c, | |
152 tag = tag})) | |
153 funcs vis | |
154 | _ => funcs | 206 | _ => funcs |
155 | 207 |
156 val ds = | 208 val (changed, ds) = |
157 case #decls st of | 209 case #decls st of |
158 [] => [d'] | 210 [] => (changed, [d']) |
159 | vis => [(DValRec vis, ErrorMsg.dummySpan), d'] | 211 | vis => |
212 (true, case d' of | |
213 (DValRec vis', _) => [(DValRec (vis @ vis'), ErrorMsg.dummySpan)] | |
214 | _ => [(DValRec vis, ErrorMsg.dummySpan), d']) | |
160 in | 215 in |
161 (ds, {maxName = #maxName st, | 216 (ds, ({maxName = #maxName st, |
162 funcs = funcs, | 217 funcs = funcs, |
163 decls = []}) | 218 decls = []}, changed)) |
164 end | 219 end |
165 | 220 |
166 val (ds, _) = ListUtil.foldlMapConcat doDecl | 221 val (ds, (_, changed)) = ListUtil.foldlMapConcat doDecl |
167 {maxName = U.File.maxName file + 1, | 222 ({maxName = U.File.maxName file + 1, |
168 funcs = IM.empty, | 223 funcs = IM.empty, |
169 decls = []} | 224 decls = []}, false) |
170 file | 225 file |
171 in | 226 in |
172 ds | 227 (changed, ds) |
173 end | 228 end |
174 | 229 |
230 fun specialize file = | |
231 let | |
232 val (changed, file) = specialize' file | |
233 in | |
234 if changed then | |
235 specialize file | |
236 else | |
237 file | |
238 end | |
239 | |
175 | 240 |
176 end | 241 end |