Mercurial > urweb
comparison src/core_util.sml @ 16:bc7b76ca57e0
Conversion to Core
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Sun, 08 Jun 2008 13:59:29 -0400 |
parents | |
children | 1ab48e37d0ef |
comparison
equal
deleted
inserted
replaced
15:1e645beb3f3b | 16:bc7b76ca57e0 |
---|---|
1 (* Copyright (c) 2008, 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 CoreUtil :> CORE_UTIL = struct | |
29 | |
30 open Core | |
31 | |
32 structure S = Search | |
33 | |
34 structure Kind = struct | |
35 | |
36 fun mapfold f = | |
37 let | |
38 fun mfk k acc = | |
39 S.bindP (mfk' k acc, f) | |
40 | |
41 and mfk' (kAll as (k, loc)) = | |
42 case k of | |
43 KType => S.return2 kAll | |
44 | |
45 | KArrow (k1, k2) => | |
46 S.bind2 (mfk k1, | |
47 fn k1' => | |
48 S.map2 (mfk k2, | |
49 fn k2' => | |
50 (KArrow (k1', k2'), loc))) | |
51 | |
52 | KName => S.return2 kAll | |
53 | |
54 | KRecord k => | |
55 S.map2 (mfk k, | |
56 fn k' => | |
57 (KRecord k', loc)) | |
58 in | |
59 mfk | |
60 end | |
61 | |
62 fun map f k = | |
63 case mapfold (fn k => fn () => S.Continue (f k, ())) k () of | |
64 S.Return () => raise Fail "Core_util.Kind.map" | |
65 | S.Continue (k, ()) => k | |
66 | |
67 fun exists f k = | |
68 case mapfold (fn k => fn () => | |
69 if f k then | |
70 S.Return () | |
71 else | |
72 S.Continue (k, ())) k () of | |
73 S.Return _ => true | |
74 | S.Continue _ => false | |
75 | |
76 end | |
77 | |
78 structure Con = struct | |
79 | |
80 datatype binder = | |
81 Rel of string * kind | |
82 | Named of string * kind | |
83 | |
84 fun mapfoldB {kind = fk, con = fc, bind} = | |
85 let | |
86 val mfk = Kind.mapfold fk | |
87 | |
88 fun mfc ctx c acc = | |
89 S.bindP (mfc' ctx c acc, fc ctx) | |
90 | |
91 and mfc' ctx (cAll as (c, loc)) = | |
92 case c of | |
93 TFun (c1, c2) => | |
94 S.bind2 (mfc ctx c1, | |
95 fn c1' => | |
96 S.map2 (mfc ctx c2, | |
97 fn c2' => | |
98 (TFun (c1', c2'), loc))) | |
99 | TCFun (x, k, c) => | |
100 S.bind2 (mfk k, | |
101 fn k' => | |
102 S.map2 (mfc (bind (ctx, Rel (x, k))) c, | |
103 fn c' => | |
104 (TCFun (x, k', c'), loc))) | |
105 | TRecord c => | |
106 S.map2 (mfc ctx c, | |
107 fn c' => | |
108 (TRecord c', loc)) | |
109 | |
110 | CRel _ => S.return2 cAll | |
111 | CNamed _ => S.return2 cAll | |
112 | CApp (c1, c2) => | |
113 S.bind2 (mfc ctx c1, | |
114 fn c1' => | |
115 S.map2 (mfc ctx c2, | |
116 fn c2' => | |
117 (CApp (c1', c2'), loc))) | |
118 | CAbs (x, k, c) => | |
119 S.bind2 (mfk k, | |
120 fn k' => | |
121 S.map2 (mfc (bind (ctx, Rel (x, k))) c, | |
122 fn c' => | |
123 (CAbs (x, k', c'), loc))) | |
124 | |
125 | CName _ => S.return2 cAll | |
126 | |
127 | CRecord (k, xcs) => | |
128 S.bind2 (mfk k, | |
129 fn k' => | |
130 S.map2 (ListUtil.mapfold (fn (x, c) => | |
131 S.bind2 (mfc ctx x, | |
132 fn x' => | |
133 S.map2 (mfc ctx c, | |
134 fn c' => | |
135 (x', c')))) | |
136 xcs, | |
137 fn xcs' => | |
138 (CRecord (k', xcs'), loc))) | |
139 | CConcat (c1, c2) => | |
140 S.bind2 (mfc ctx c1, | |
141 fn c1' => | |
142 S.map2 (mfc ctx c2, | |
143 fn c2' => | |
144 (CConcat (c1', c2'), loc))) | |
145 in | |
146 mfc | |
147 end | |
148 | |
149 fun mapfold {kind = fk, con = fc} = | |
150 mapfoldB {kind = fk, | |
151 con = fn () => fc, | |
152 bind = fn ((), _) => ()} () | |
153 | |
154 fun map {kind, con} c = | |
155 case mapfold {kind = fn k => fn () => S.Continue (kind k, ()), | |
156 con = fn c => fn () => S.Continue (con c, ())} c () of | |
157 S.Return () => raise Fail "Core_util.Con.map" | |
158 | S.Continue (c, ()) => c | |
159 | |
160 fun mapB {kind, con, bind} ctx c = | |
161 case mapfoldB {kind = fn k => fn () => S.Continue (kind k, ()), | |
162 con = fn ctx => fn c => fn () => S.Continue (con ctx c, ()), | |
163 bind = bind} ctx c () of | |
164 S.Continue (c, ()) => c | |
165 | S.Return _ => raise Fail "Con.mapB: Impossible" | |
166 | |
167 fun exists {kind, con} k = | |
168 case mapfold {kind = fn k => fn () => | |
169 if kind k then | |
170 S.Return () | |
171 else | |
172 S.Continue (k, ()), | |
173 con = fn c => fn () => | |
174 if con c then | |
175 S.Return () | |
176 else | |
177 S.Continue (c, ())} k () of | |
178 S.Return _ => true | |
179 | S.Continue _ => false | |
180 | |
181 end | |
182 | |
183 structure Exp = struct | |
184 | |
185 datatype binder = | |
186 RelC of string * kind | |
187 | NamedC of string * kind | |
188 | RelE of string * con | |
189 | NamedE of string * con | |
190 | |
191 fun mapfoldB {kind = fk, con = fc, exp = fe, bind} = | |
192 let | |
193 val mfk = Kind.mapfold fk | |
194 | |
195 fun bind' (ctx, b) = | |
196 let | |
197 val b' = case b of | |
198 Con.Rel x => RelC x | |
199 | Con.Named x => NamedC x | |
200 in | |
201 bind (ctx, b') | |
202 end | |
203 val mfc = Con.mapfoldB {kind = fk, con = fc, bind = bind'} | |
204 | |
205 fun mfe ctx e acc = | |
206 S.bindP (mfe' ctx e acc, fe ctx) | |
207 | |
208 and mfe' ctx (eAll as (e, loc)) = | |
209 case e of | |
210 EPrim _ => S.return2 eAll | |
211 | ERel _ => S.return2 eAll | |
212 | ENamed _ => S.return2 eAll | |
213 | EApp (e1, e2) => | |
214 S.bind2 (mfe ctx e1, | |
215 fn e1' => | |
216 S.map2 (mfe ctx e2, | |
217 fn e2' => | |
218 (EApp (e1', e2'), loc))) | |
219 | EAbs (x, t, e) => | |
220 S.bind2 (mfc ctx t, | |
221 fn t' => | |
222 S.map2 (mfe (bind (ctx, RelE (x, t))) e, | |
223 fn e' => | |
224 (EAbs (x, t', e'), loc))) | |
225 | |
226 | ECApp (e, c) => | |
227 S.bind2 (mfe ctx e, | |
228 fn e' => | |
229 S.map2 (mfc ctx c, | |
230 fn c' => | |
231 (ECApp (e', c'), loc))) | |
232 | ECAbs (x, k, e) => | |
233 S.bind2 (mfk k, | |
234 fn k' => | |
235 S.map2 (mfe (bind (ctx, RelC (x, k))) e, | |
236 fn e' => | |
237 (ECAbs (x, k', e'), loc))) | |
238 | |
239 | ERecord xes => | |
240 S.map2 (ListUtil.mapfold (fn (x, e) => | |
241 S.bind2 (mfc ctx x, | |
242 fn x' => | |
243 S.map2 (mfe ctx e, | |
244 fn e' => | |
245 (x', e')))) | |
246 xes, | |
247 fn xes' => | |
248 (ERecord xes', loc)) | |
249 | EField (e, c, {field, rest}) => | |
250 S.bind2 (mfe ctx e, | |
251 fn e' => | |
252 S.bind2 (mfc ctx c, | |
253 fn c' => | |
254 S.bind2 (mfc ctx field, | |
255 fn field' => | |
256 S.map2 (mfc ctx rest, | |
257 fn rest' => | |
258 (EField (e', c', {field = field', rest = rest'}), loc))))) | |
259 in | |
260 mfe | |
261 end | |
262 | |
263 fun mapfold {kind = fk, con = fc, exp = fe} = | |
264 mapfoldB {kind = fk, | |
265 con = fn () => fc, | |
266 exp = fn () => fe, | |
267 bind = fn ((), _) => ()} () | |
268 | |
269 fun map {kind, con, exp} e = | |
270 case mapfold {kind = fn k => fn () => S.Continue (kind k, ()), | |
271 con = fn c => fn () => S.Continue (con c, ()), | |
272 exp = fn e => fn () => S.Continue (exp e, ())} e () of | |
273 S.Return () => raise Fail "Core_util.Exp.map" | |
274 | S.Continue (e, ()) => e | |
275 | |
276 fun exists {kind, con, exp} k = | |
277 case mapfold {kind = fn k => fn () => | |
278 if kind k then | |
279 S.Return () | |
280 else | |
281 S.Continue (k, ()), | |
282 con = fn c => fn () => | |
283 if con c then | |
284 S.Return () | |
285 else | |
286 S.Continue (c, ()), | |
287 exp = fn e => fn () => | |
288 if exp e then | |
289 S.Return () | |
290 else | |
291 S.Continue (e, ())} k () of | |
292 S.Return _ => true | |
293 | S.Continue _ => false | |
294 | |
295 end | |
296 | |
297 end |