Mercurial > urweb
comparison src/expl_rename.sml @ 1989:210fb3dfc483
Some more nested functor bug-fixing, including generating fresh internal names at applications; still need to debug issues with datatype constructors
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Thu, 20 Feb 2014 10:27:15 -0500 |
parents | |
children | 7bd2ecf96bb0 |
comparison
equal
deleted
inserted
replaced
1988:abb6981a2c4c | 1989:210fb3dfc483 |
---|---|
1 (* Copyright (c) 2014, Adam Chlipala | |
2 * All rights reserved. | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions are met: | |
6 * | |
7 * - Redistributions of source code must retain the above copyright notice, | |
8 * this list of conditions and the following disclaimer. | |
9 * - Redistributions in binary form must reproduce the above copyright notice, | |
10 * this list of conditions and the following disclaimer in the documentation | |
11 * and/or other materials provided with the distribution. | |
12 * - The names of contributors may not be used to endorse or promote products | |
13 * derived from this software without specific prior written permission. | |
14 * | |
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
25 * POSSIBILITY OF SUCH DAMAGE. | |
26 *) | |
27 | |
28 structure ExplRename :> EXPL_RENAME = struct | |
29 | |
30 open Expl | |
31 structure E = ExplEnv | |
32 | |
33 structure IM = IntBinaryMap | |
34 | |
35 structure St :> sig | |
36 type t | |
37 | |
38 val create : int -> t | |
39 val next : t -> int | |
40 | |
41 val bind : t * int -> t * int | |
42 val lookup: t * int -> int option | |
43 end = struct | |
44 | |
45 type t = {next : int, | |
46 renaming : int IM.map} | |
47 | |
48 fun create next = {next = next, | |
49 renaming = IM.empty} | |
50 | |
51 fun next (t : t) = #next t | |
52 | |
53 fun bind ({next, renaming}, n) = | |
54 ({next = next + 1, | |
55 renaming = IM.insert (renaming, n, next)}, next) | |
56 | |
57 fun lookup ({next, renaming}, n) = | |
58 IM.find (renaming, n) | |
59 | |
60 end | |
61 | |
62 fun renameCon st (all as (c, loc)) = | |
63 case c of | |
64 TFun (c1, c2) => (TFun (renameCon st c1, renameCon st c2), loc) | |
65 | TCFun (x, k, c) => (TCFun (x, k, renameCon st c), loc) | |
66 | TRecord c => (TRecord (renameCon st c), loc) | |
67 | CRel _ => all | |
68 | CNamed n => | |
69 (case St.lookup (st, n) of | |
70 NONE => all | |
71 | SOME n' => (CNamed n', loc)) | |
72 | CModProj (n, ms, x) => | |
73 (case St.lookup (st, n) of | |
74 NONE => all | |
75 | SOME n' => (CModProj (n', ms, x), loc)) | |
76 | CApp (c1, c2) => (CApp (renameCon st c1, renameCon st c2), loc) | |
77 | CAbs (x, k, c) => (CAbs (x, k, renameCon st c), loc) | |
78 | CKAbs (x, c) => (CKAbs (x, renameCon st c), loc) | |
79 | CKApp (c, k) => (CKApp (renameCon st c, k), loc) | |
80 | TKFun (x, c) => (TKFun (x, renameCon st c), loc) | |
81 | CName _ => all | |
82 | CRecord (k, xcs) => (CRecord (k, map (fn (x, c) => (renameCon st x, renameCon st c)) xcs), loc) | |
83 | CConcat (c1, c2) => (CConcat (renameCon st c1, renameCon st c2), loc) | |
84 | CMap _ => all | |
85 | CUnit => all | |
86 | CTuple cs => (CTuple (map (renameCon st) cs), loc) | |
87 | CProj (c, n) => (CProj (renameCon st c, n), loc) | |
88 | |
89 fun renamePatCon st pc = | |
90 case pc of | |
91 PConVar n => | |
92 (case St.lookup (st, n) of | |
93 NONE => pc | |
94 | SOME n' => PConVar n') | |
95 | PConProj (n, ms, x) => | |
96 (case St.lookup (st, n) of | |
97 NONE => pc | |
98 | SOME n' => PConProj (n', ms, x)) | |
99 | |
100 fun renamePat st (all as (p, loc)) = | |
101 case p of | |
102 PWild => all | |
103 | PVar (x, c) => (PVar (x, renameCon st c), loc) | |
104 | PPrim _ => all | |
105 | PCon (dk, pc, cs, po) => (PCon (dk, renamePatCon st pc, | |
106 map (renameCon st) cs, | |
107 Option.map (renamePat st) po), loc) | |
108 | PRecord xpcs => (PRecord (map (fn (x, p, c) => | |
109 (x, renamePat st p, renameCon st c)) xpcs), loc) | |
110 | |
111 fun renameExp st (all as (e, loc)) = | |
112 case e of | |
113 EPrim _ => all | |
114 | ERel _ => all | |
115 | ENamed n => | |
116 (case St.lookup (st, n) of | |
117 NONE => all | |
118 | SOME n' => (ENamed n', loc)) | |
119 | EModProj (n, ms, x) => | |
120 (case St.lookup (st, n) of | |
121 NONE => all | |
122 | SOME n' => (EModProj (n', ms, x), loc)) | |
123 | EApp (e1, e2) => (EApp (renameExp st e1, renameExp st e2), loc) | |
124 | EAbs (x, dom, ran, e) => (EAbs (x, renameCon st dom, renameCon st ran, renameExp st e), loc) | |
125 | ECApp (e, c) => (ECApp (renameExp st e, renameCon st c), loc) | |
126 | ECAbs (x, k, e) => (ECAbs (x, k, renameExp st e), loc) | |
127 | EKAbs (x, e) => (EKAbs (x, renameExp st e), loc) | |
128 | EKApp (e, k) => (EKApp (renameExp st e, k), loc) | |
129 | ERecord xecs => (ERecord (map (fn (x, e, c) => (renameCon st x, | |
130 renameExp st e, | |
131 renameCon st c)) xecs), loc) | |
132 | EField (e, c, {field, rest}) => (EField (renameExp st e, | |
133 renameCon st c, | |
134 {field = renameCon st field, | |
135 rest = renameCon st rest}), loc) | |
136 | EConcat (e1, c1, e2, c2) => (EConcat (renameExp st e1, | |
137 renameCon st c1, | |
138 renameExp st e2, | |
139 renameCon st c2), loc) | |
140 | ECut (e, c, {field, rest}) => (ECut (renameExp st e, | |
141 renameCon st c, | |
142 {field = renameCon st field, | |
143 rest = renameCon st rest}), loc) | |
144 | ECutMulti (e, c, {rest}) => (ECutMulti (renameExp st e, | |
145 renameCon st c, | |
146 {rest = renameCon st rest}), loc) | |
147 | ECase (e, pes, {disc, result}) => (ECase (renameExp st e, | |
148 map (fn (p, e) => (renamePat st p, renameExp st e)) pes, | |
149 {disc = renameCon st disc, | |
150 result = renameCon st result}), loc) | |
151 | EWrite e => (EWrite (renameExp st e), loc) | |
152 | ELet (x, c1, e1, e2) => (ELet (x, renameCon st c1, | |
153 renameExp st e1, | |
154 renameExp st e2), loc) | |
155 | |
156 fun renameSitem st (all as (si, loc)) = | |
157 case si of | |
158 SgiConAbs _ => all | |
159 | SgiCon (x, n, k, c) => (SgiCon (x, n, k, renameCon st c), loc) | |
160 | SgiDatatype dts => (SgiDatatype (map (fn (x, n, xs, cns) => | |
161 (x, n, xs, | |
162 map (fn (x, n, co) => | |
163 (x, n, Option.map (renameCon st) co)) cns)) dts), | |
164 loc) | |
165 | SgiDatatypeImp (x, n, n', xs, x', xs', cns) => | |
166 (SgiDatatypeImp (x, n, n', xs, x', xs', | |
167 map (fn (x, n, co) => | |
168 (x, n, Option.map (renameCon st) co)) cns), loc) | |
169 | SgiVal (x, n, c) => (SgiVal (x, n, renameCon st c), loc) | |
170 | SgiSgn (x, n, sg) => (SgiSgn (x, n, renameSgn st sg), loc) | |
171 | SgiStr (x, n, sg) => (SgiStr (x, n, renameSgn st sg), loc) | |
172 | |
173 and renameSgn st (all as (sg, loc)) = | |
174 case sg of | |
175 SgnConst sis => (SgnConst (map (renameSitem st) sis), loc) | |
176 | SgnVar n => | |
177 (case St.lookup (st, n) of | |
178 NONE => all | |
179 | SOME n' => (SgnVar n', loc)) | |
180 | SgnFun (x, n, dom, ran) => (SgnFun (x, n, renameSgn st dom, renameSgn st ran), loc) | |
181 | SgnWhere (sg, xs, s, c) => (SgnWhere (renameSgn st sg, xs, s, renameCon st c), loc) | |
182 | SgnProj (n, ms, x) => | |
183 (case St.lookup (st, n) of | |
184 NONE => all | |
185 | SOME n' => (SgnProj (n', ms, x), loc)) | |
186 | |
187 fun renameDecl st (all as (d, loc)) = | |
188 case d of | |
189 DCon (x, n, k, c) => (DCon (x, n, k, renameCon st c), loc) | |
190 | DDatatype dts => (DDatatype (map (fn (x, n, xs, cns) => | |
191 (x, n, xs, | |
192 map (fn (x, n, co) => | |
193 (x, n, Option.map (renameCon st) co)) cns)) dts), | |
194 loc) | |
195 | DDatatypeImp (x, n, n', xs, x', xs', cns) => | |
196 (DDatatypeImp (x, n, n', xs, x', xs', | |
197 map (fn (x, n, co) => | |
198 (x, n, Option.map (renameCon st) co)) cns), loc) | |
199 | DVal (x, n, c, e) => (DVal (x, n, renameCon st c, renameExp st e), loc) | |
200 | DValRec vis => (DValRec (map (fn (x, n, c, e) => (x, n, renameCon st c, renameExp st e)) vis), loc) | |
201 | DSgn (x, n, sg) => (DSgn (x, n, renameSgn st sg), loc) | |
202 | DStr (x, n, sg, str) => (DStr (x, n, renameSgn st sg, renameStr st str), loc) | |
203 | DFfiStr (x, n, sg) => (DFfiStr (x, n, renameSgn st sg), loc) | |
204 | DExport (n, sg, str) => | |
205 (case St.lookup (st, n) of | |
206 NONE => all | |
207 | SOME n' => (DExport (n', renameSgn st sg, renameStr st str), loc)) | |
208 | DTable (n, x, m, c1, e1, c2, e2, c3) => | |
209 (DTable (n, x, m, renameCon st c1, renameExp st e1, renameCon st c2, | |
210 renameExp st e2, renameCon st c3), loc) | |
211 | DSequence _ => all | |
212 | DView (n, x, n', e, c) => (DView (n, x, n', renameExp st e, renameCon st c), loc) | |
213 | DDatabase _ => all | |
214 | DCookie (n, x, n', c) => (DCookie (n, x, n', renameCon st c), loc) | |
215 | DStyle _ => all | |
216 | DTask (e1, e2) => (DTask (renameExp st e1, renameExp st e2), loc) | |
217 | DPolicy e => (DPolicy (renameExp st e), loc) | |
218 | DOnError (n, xs, x) => | |
219 (case St.lookup (st, n) of | |
220 NONE => all | |
221 | SOME n' => (DOnError (n', xs, x), loc)) | |
222 | |
223 and renameStr st (all as (str, loc)) = | |
224 case str of | |
225 StrConst ds => (StrConst (map (renameDecl st) ds), loc) | |
226 | StrVar n => | |
227 (case St.lookup (st, n) of | |
228 NONE => all | |
229 | SOME n' => (StrVar n', loc)) | |
230 | StrProj (str, x) => (StrProj (renameStr st str, x), loc) | |
231 | StrFun (x, n, dom, ran, str) => (StrFun (x, n, renameSgn st dom, | |
232 renameSgn st ran, | |
233 renameStr st str), loc) | |
234 | StrApp (str1, str2) => (StrApp (renameStr st str1, renameStr st str2), loc) | |
235 | |
236 | |
237 | |
238 fun fromArity (n, loc) = | |
239 case n of | |
240 0 => (KType, loc) | |
241 | _ => (KArrow ((KType, loc), fromArity (n - 1, loc)), loc) | |
242 | |
243 fun dupDecl (all as (d, loc), st) = | |
244 case d of | |
245 DCon (x, n, k, c) => | |
246 let | |
247 val (st, n') = St.bind (st, n) | |
248 in | |
249 ([(DCon (x, n, k, renameCon st c), loc), | |
250 (DCon (x, n', k, (CNamed n, loc)), loc)], | |
251 st) | |
252 end | |
253 | DDatatype dts => | |
254 let | |
255 val (dts', st) = ListUtil.foldlMap (fn ((x, n, xs, cns), st) => | |
256 let | |
257 val (st, n') = St.bind (st, n) | |
258 | |
259 val (cns', st) = ListUtil.foldlMap | |
260 (fn ((x, n, _), st) => | |
261 let | |
262 val (st, n') = | |
263 St.bind (st, n) | |
264 in | |
265 ((x, n, n'), st) | |
266 end) st cns | |
267 in | |
268 ((x, n, length xs, n', cns'), st) | |
269 end) st dts | |
270 | |
271 val d = (DDatatype (map (fn (x, n, xs, cns) => | |
272 (x, n, xs, | |
273 map (fn (x, n, co) => | |
274 (x, n, Option.map (renameCon st) co)) cns)) dts), | |
275 loc) | |
276 | |
277 val env = E.declBinds E.empty d | |
278 in | |
279 (d | |
280 :: map (fn (x, n, arity, n', _) => | |
281 (DCon (x, n', fromArity (arity, loc), (CNamed n, loc)), loc)) dts' | |
282 @ ListUtil.mapConcat (fn (_, _, _, _, cns') => | |
283 map (fn (x, n, n') => | |
284 (DVal (x, n', #2 (E.lookupENamed env n), (ENamed n, loc)), | |
285 loc)) cns') dts', | |
286 st) | |
287 end | |
288 | DDatatypeImp (x, n, n', xs, x', xs', cns) => | |
289 let | |
290 val (cns', st) = ListUtil.foldlMap | |
291 (fn ((x, n, _), st) => | |
292 let | |
293 val (st, n') = | |
294 St.bind (st, n) | |
295 in | |
296 ((x, n, n'), st) | |
297 end) st cns | |
298 | |
299 val (st, n') = St.bind (st, n) | |
300 | |
301 val d = (DDatatypeImp (x, n, n', xs, x', xs', | |
302 map (fn (x, n, co) => | |
303 (x, n, Option.map (renameCon st) co)) cns), loc) | |
304 | |
305 val env = E.declBinds E.empty d | |
306 in | |
307 (d | |
308 :: (DCon (x, n', fromArity (length xs, loc), (CNamed n, loc)), loc) | |
309 :: map (fn (x, n, n') => | |
310 (DVal (x, n', #2 (E.lookupENamed env n), (ENamed n, loc)), | |
311 loc)) cns', | |
312 st) | |
313 end | |
314 | DVal (x, n, c, e) => | |
315 let | |
316 val (st, n') = St.bind (st, n) | |
317 val c' = renameCon st c | |
318 in | |
319 ([(DVal (x, n, c', renameExp st e), loc), | |
320 (DVal (x, n', c', (ENamed n, loc)), loc)], | |
321 st) | |
322 end | |
323 | DValRec vis => | |
324 let | |
325 val d = (DValRec (map (fn (x, n, c, e) => (x, n, renameCon st c, renameExp st e)) vis), loc) | |
326 | |
327 val (vis', st) = ListUtil.foldlMap (fn ((x, n, _, _), st) => | |
328 let | |
329 val (st, n') = St.bind (st, n) | |
330 in | |
331 ((x, n, n'), st) | |
332 end) st vis | |
333 | |
334 val env = E.declBinds E.empty d | |
335 in | |
336 (d | |
337 :: map (fn (x, n, n') => (DVal (x, n', #2 (E.lookupENamed env n), (ENamed n, loc)), loc)) vis', | |
338 st) | |
339 end | |
340 | DSgn (x, n, sg) => | |
341 let | |
342 val (st, n') = St.bind (st, n) | |
343 in | |
344 ([(DSgn (x, n, renameSgn st sg), loc), | |
345 (DSgn (x, n', (SgnVar n, loc)), loc)], | |
346 st) | |
347 end | |
348 | DStr (x, n, sg, str) => | |
349 let | |
350 val (st, n') = St.bind (st, n) | |
351 val sg' = renameSgn st sg | |
352 in | |
353 ([(DStr (x, n, sg', renameStr st str), loc), | |
354 (DStr (x, n', sg', (StrVar n, loc)), loc)], | |
355 st) | |
356 end | |
357 | DFfiStr (x, n, sg) => ([(DFfiStr (x, n, renameSgn st sg), loc)], st) | |
358 | DExport (n, sg, str) => | |
359 (case St.lookup (st, n) of | |
360 NONE => ([all], st) | |
361 | SOME n' => ([(DExport (n', renameSgn st sg, renameStr st str), loc)], st)) | |
362 | DTable (n, x, m, c1, e1, c2, e2, c3) => | |
363 let | |
364 val (st, m') = St.bind (st, m) | |
365 | |
366 val d = (DTable (n, x, m, renameCon st c1, renameExp st e1, renameCon st c2, | |
367 renameExp st e2, renameCon st c3), loc) | |
368 | |
369 val env = E.declBinds E.empty d | |
370 in | |
371 ([d, (DVal (x, m', #2 (E.lookupENamed env m), (ENamed m, loc)), loc)], st) | |
372 end | |
373 | DSequence (n, x, m) => | |
374 let | |
375 val (st, m') = St.bind (st, m) | |
376 | |
377 val env = E.declBinds E.empty all | |
378 in | |
379 ([all, (DVal (x, m', #2 (E.lookupENamed env m), (ENamed m, loc)), loc)], st) | |
380 end | |
381 | DView (n, x, m, e, c) => | |
382 let | |
383 val (st, m') = St.bind (st, m) | |
384 | |
385 val d = (DView (n, x, m, renameExp st e, renameCon st c), loc) | |
386 | |
387 val env = E.declBinds E.empty d | |
388 in | |
389 ([d, (DVal (x, m', #2 (E.lookupENamed env m), (ENamed m, loc)), loc)], st) | |
390 end | |
391 | DDatabase _ => ([all], st) | |
392 | DCookie (n, x, m, c) => | |
393 let | |
394 val (st, m') = St.bind (st, m) | |
395 | |
396 val d = (DCookie (n, x, m, renameCon st c), loc) | |
397 | |
398 val env = E.declBinds E.empty d | |
399 in | |
400 ([d, (DVal (x, m', #2 (E.lookupENamed env m), (ENamed m, loc)), loc)], st) | |
401 end | |
402 | DStyle (n, x, m) => | |
403 let | |
404 val (st, m') = St.bind (st, m) | |
405 | |
406 val env = E.declBinds E.empty all | |
407 in | |
408 ([all, (DVal (x, m', #2 (E.lookupENamed env m), (ENamed m, loc)), loc)], st) | |
409 end | |
410 | DTask (e1, e2) => ([(DTask (renameExp st e1, renameExp st e2), loc)], st) | |
411 | DPolicy e => ([(DPolicy (renameExp st e), loc)], st) | |
412 | DOnError (n, xs, x) => | |
413 (case St.lookup (st, n) of | |
414 NONE => ([all], st) | |
415 | SOME n' => ([(DOnError (n', xs, x), loc)], st)) | |
416 | |
417 fun rename {NextId, FormalName, FormalId, Body = all as (str, loc)} = | |
418 case str of | |
419 StrConst ds => | |
420 let | |
421 val st = St.create NextId | |
422 val (st, n) = St.bind (st, FormalId) | |
423 | |
424 val (ds, st) = ListUtil.foldlMapConcat dupDecl st ds | |
425 val ds = (DStr (FormalName, n, (SgnConst [], loc), (StrVar FormalId, loc)), loc) :: ds | |
426 in | |
427 (St.next st, (StrConst ds, loc)) | |
428 end | |
429 | _ => (NextId, all) | |
430 | |
431 end |