comparison src/corify.sml @ 177:5d030ee143e2

Case through corify
author Adam Chlipala <adamc@hcoop.net>
date Sat, 02 Aug 2008 11:15:32 -0400
parents 33d4a8eea484
children d11754ffe252
comparison
equal deleted inserted replaced
176:33d4a8eea484 177:5d030ee143e2
69 | CFfi of string 69 | CFfi of string
70 val bindCon : t -> string -> int -> t * int 70 val bindCon : t -> string -> int -> t * int
71 val lookupConById : t -> int -> int option 71 val lookupConById : t -> int -> int option
72 val lookupConByName : t -> string -> core_con 72 val lookupConByName : t -> string -> core_con
73 73
74 val bindConstructor : t -> string -> int -> L'.patCon -> t
75 val lookupConstructorByName : t -> string -> L'.patCon
76 val lookupConstructorById : t -> int -> L'.patCon
77
74 datatype core_val = 78 datatype core_val =
75 ENormal of int 79 ENormal of int
76 | EFfi of string * L'.con 80 | EFfi of string * L'.con
77 val bindVal : t -> string -> int -> t * int 81 val bindVal : t -> string -> int -> t * int
78 val bindConstructor : t -> string -> int -> t 82 val bindConstructorVal : t -> string -> int -> t
79 val lookupValById : t -> int -> int option 83 val lookupValById : t -> int -> int option
80 val lookupValByName : t -> string -> core_val 84 val lookupValByName : t -> string -> core_val
81 85
82 val bindStr : t -> string -> int -> t -> t 86 val bindStr : t -> string -> int -> t -> t
83 val lookupStrById : t -> int -> t 87 val lookupStrById : t -> int -> t
88 val lookupFunctorByName : string * t -> string * int * L.str 92 val lookupFunctorByName : string * t -> string * int * L.str
89 end = struct 93 end = struct
90 94
91 datatype flattening = 95 datatype flattening =
92 FNormal of {cons : int SM.map, 96 FNormal of {cons : int SM.map,
97 constructors : L'.patCon SM.map,
93 vals : int SM.map, 98 vals : int SM.map,
94 strs : flattening SM.map, 99 strs : flattening SM.map,
95 funs : (string * int * L.str) SM.map} 100 funs : (string * int * L.str) SM.map}
96 | FFfi of {mod : string, 101 | FFfi of {mod : string,
97 vals : L'.con SM.map} 102 vals : L'.con SM.map}
98 103
99 type t = { 104 type t = {
100 cons : int IM.map, 105 cons : int IM.map,
106 constructors : L'.patCon IM.map,
101 vals : int IM.map, 107 vals : int IM.map,
102 strs : flattening IM.map, 108 strs : flattening IM.map,
103 funs : (string * int * L.str) IM.map, 109 funs : (string * int * L.str) IM.map,
104 current : flattening, 110 current : flattening,
105 nested : flattening list 111 nested : flattening list
106 } 112 }
107 113
108 val empty = { 114 val empty = {
109 cons = IM.empty, 115 cons = IM.empty,
116 constructors = IM.empty,
110 vals = IM.empty, 117 vals = IM.empty,
111 strs = IM.empty, 118 strs = IM.empty,
112 funs = IM.empty, 119 funs = IM.empty,
113 current = FNormal { cons = SM.empty, vals = SM.empty, strs = SM.empty, funs = SM.empty }, 120 current = FNormal { cons = SM.empty, constructors = SM.empty, vals = SM.empty, strs = SM.empty, funs = SM.empty },
114 nested = [] 121 nested = []
115 } 122 }
116 123
117 fun debug ({current = FNormal {cons, vals, strs, funs}, ...} : t) = 124 fun debug ({current = FNormal {cons, constructors, vals, strs, funs}, ...} : t) =
118 print ("cons: " ^ Int.toString (SM.numItems cons) ^ "; " 125 print ("cons: " ^ Int.toString (SM.numItems cons) ^ "; "
126 ^ "constructors: " ^ Int.toString (SM.numItems constructors) ^ "; "
119 ^ "vals: " ^ Int.toString (SM.numItems vals) ^ "; " 127 ^ "vals: " ^ Int.toString (SM.numItems vals) ^ "; "
120 ^ "strs: " ^ Int.toString (SM.numItems strs) ^ "; " 128 ^ "strs: " ^ Int.toString (SM.numItems strs) ^ "; "
121 ^ "funs: " ^ Int.toString (SM.numItems funs) ^ "\n") 129 ^ "funs: " ^ Int.toString (SM.numItems funs) ^ "\n")
122 | debug _ = print "Not normal!\n" 130 | debug _ = print "Not normal!\n"
123 131
127 135
128 datatype core_val = 136 datatype core_val =
129 ENormal of int 137 ENormal of int
130 | EFfi of string * L'.con 138 | EFfi of string * L'.con
131 139
132 fun bindCon {cons, vals, strs, funs, current, nested} s n = 140 fun bindCon {cons, constructors, vals, strs, funs, current, nested} s n =
133 let 141 let
134 val n' = alloc () 142 val n' = alloc ()
135 143
136 val current = 144 val current =
137 case current of 145 case current of
138 FFfi _ => raise Fail "Binding inside FFfi" 146 FFfi _ => raise Fail "Binding inside FFfi"
139 | FNormal {cons, vals, strs, funs} => 147 | FNormal {cons, constructors, vals, strs, funs} =>
140 FNormal {cons = SM.insert (cons, s, n'), 148 FNormal {cons = SM.insert (cons, s, n'),
149 constructors = constructors,
141 vals = vals, 150 vals = vals,
142 strs = strs, 151 strs = strs,
143 funs = funs} 152 funs = funs}
144 in 153 in
145 ({cons = IM.insert (cons, n, n'), 154 ({cons = IM.insert (cons, n, n'),
155 constructors = constructors,
146 vals = vals, 156 vals = vals,
147 strs = strs, 157 strs = strs,
148 funs = funs, 158 funs = funs,
149 current = current, 159 current = current,
150 nested = nested}, 160 nested = nested},
159 | FNormal {cons, ...} => 169 | FNormal {cons, ...} =>
160 case SM.find (cons, x) of 170 case SM.find (cons, x) of
161 NONE => raise Fail "Corify.St.lookupConByName" 171 NONE => raise Fail "Corify.St.lookupConByName"
162 | SOME n => CNormal n 172 | SOME n => CNormal n
163 173
164 fun bindVal {cons, vals, strs, funs, current, nested} s n = 174 fun bindVal {cons, constructors, vals, strs, funs, current, nested} s n =
165 let 175 let
166 val n' = alloc () 176 val n' = alloc ()
167 177
168 val current = 178 val current =
169 case current of 179 case current of
170 FFfi _ => raise Fail "Binding inside FFfi" 180 FFfi _ => raise Fail "Binding inside FFfi"
171 | FNormal {cons, vals, strs, funs} => 181 | FNormal {cons, constructors, vals, strs, funs} =>
172 FNormal {cons = cons, 182 FNormal {cons = cons,
183 constructors = constructors,
173 vals = SM.insert (vals, s, n'), 184 vals = SM.insert (vals, s, n'),
174 strs = strs, 185 strs = strs,
175 funs = funs} 186 funs = funs}
176 in 187 in
177 ({cons = cons, 188 ({cons = cons,
189 constructors = constructors,
178 vals = IM.insert (vals, n, n'), 190 vals = IM.insert (vals, n, n'),
179 strs = strs, 191 strs = strs,
180 funs = funs, 192 funs = funs,
181 current = current, 193 current = current,
182 nested = nested}, 194 nested = nested},
183 n') 195 n')
184 end 196 end
185 197
186 fun bindConstructor {cons, vals, strs, funs, current, nested} s n = 198 fun bindConstructorVal {cons, constructors, vals, strs, funs, current, nested} s n =
187 let 199 let
188 val current = 200 val current =
189 case current of 201 case current of
190 FFfi _ => raise Fail "Binding inside FFfi" 202 FFfi _ => raise Fail "Binding inside FFfi"
191 | FNormal {cons, vals, strs, funs} => 203 | FNormal {cons, constructors, vals, strs, funs} =>
192 FNormal {cons = cons, 204 FNormal {cons = cons,
205 constructors = constructors,
193 vals = SM.insert (vals, s, n), 206 vals = SM.insert (vals, s, n),
194 strs = strs, 207 strs = strs,
195 funs = funs} 208 funs = funs}
196 in 209 in
197 {cons = cons, 210 {cons = cons,
211 constructors = constructors,
198 vals = IM.insert (vals, n, n), 212 vals = IM.insert (vals, n, n),
199 strs = strs, 213 strs = strs,
200 funs = funs, 214 funs = funs,
201 current = current, 215 current = current,
202 nested = nested} 216 nested = nested}
203 end 217 end
218
204 219
205 fun lookupValById ({vals, ...} : t) n = IM.find (vals, n) 220 fun lookupValById ({vals, ...} : t) n = IM.find (vals, n)
206 221
207 fun lookupValByName ({current, ...} : t) x = 222 fun lookupValByName ({current, ...} : t) x =
208 case current of 223 case current of
213 | FNormal {vals, ...} => 228 | FNormal {vals, ...} =>
214 case SM.find (vals, x) of 229 case SM.find (vals, x) of
215 NONE => raise Fail "Corify.St.lookupValByName" 230 NONE => raise Fail "Corify.St.lookupValByName"
216 | SOME n => ENormal n 231 | SOME n => ENormal n
217 232
218 fun enter {cons, vals, strs, funs, current, nested} = 233 fun bindConstructor {cons, constructors, vals, strs, funs, current, nested} s n n' =
234 let
235 val current =
236 case current of
237 FFfi _ => raise Fail "Binding inside FFfi"
238 | FNormal {cons, constructors, vals, strs, funs} =>
239 FNormal {cons = cons,
240 constructors = SM.insert (constructors, s, n'),
241 vals = vals,
242 strs = strs,
243 funs = funs}
244 in
245 {cons = cons,
246 constructors = IM.insert (constructors, n, n'),
247 vals = vals,
248 strs = strs,
249 funs = funs,
250 current = current,
251 nested = nested}
252 end
253
254 fun lookupConstructorById ({constructors, ...} : t) n =
255 case IM.find (constructors, n) of
256 NONE => raise Fail "Corify.St.lookupConstructorById"
257 | SOME x => x
258
259 fun lookupConstructorByName ({current, ...} : t) x =
260 case current of
261 FFfi {mod = m, ...} => L'.PConFfi (m, x)
262 | FNormal {constructors, ...} =>
263 case SM.find (constructors, x) of
264 NONE => raise Fail "Corify.St.lookupConstructorByName"
265 | SOME n => n
266
267 fun enter {cons, constructors, vals, strs, funs, current, nested} =
219 {cons = cons, 268 {cons = cons,
269 constructors = constructors,
220 vals = vals, 270 vals = vals,
221 strs = strs, 271 strs = strs,
222 funs = funs, 272 funs = funs,
223 current = FNormal {cons = SM.empty, 273 current = FNormal {cons = SM.empty,
274 constructors = SM.empty,
224 vals = SM.empty, 275 vals = SM.empty,
225 strs = SM.empty, 276 strs = SM.empty,
226 funs = SM.empty}, 277 funs = SM.empty},
227 nested = current :: nested} 278 nested = current :: nested}
228 279
229 fun dummy f = {cons = IM.empty, 280 fun dummy f = {cons = IM.empty,
281 constructors = IM.empty,
230 vals = IM.empty, 282 vals = IM.empty,
231 strs = IM.empty, 283 strs = IM.empty,
232 funs = IM.empty, 284 funs = IM.empty,
233 current = f, 285 current = f,
234 nested = []} 286 nested = []}
235 287
236 fun leave {cons, vals, strs, funs, current, nested = m1 :: rest} = 288 fun leave {cons, constructors, vals, strs, funs, current, nested = m1 :: rest} =
237 {outer = {cons = cons, 289 {outer = {cons = cons,
290 constructors = constructors,
238 vals = vals, 291 vals = vals,
239 strs = strs, 292 strs = strs,
240 funs = funs, 293 funs = funs,
241 current = m1, 294 current = m1,
242 nested = rest}, 295 nested = rest},
243 inner = dummy current} 296 inner = dummy current}
244 | leave _ = raise Fail "Corify.St.leave" 297 | leave _ = raise Fail "Corify.St.leave"
245 298
246 fun ffi m vals = dummy (FFfi {mod = m, vals = vals}) 299 fun ffi m vals = dummy (FFfi {mod = m, vals = vals})
247 300
248 fun bindStr ({cons, vals, strs, funs, 301 fun bindStr ({cons, constructors, vals, strs, funs,
249 current = FNormal {cons = mcons, vals = mvals, strs = mstrs, funs = mfuns}, nested} : t) 302 current = FNormal {cons = mcons, constructors = mconstructors,
303 vals = mvals, strs = mstrs, funs = mfuns}, nested} : t)
250 x n ({current = f, ...} : t) = 304 x n ({current = f, ...} : t) =
251 {cons = cons, 305 {cons = cons,
306 constructors = constructors,
252 vals = vals, 307 vals = vals,
253 strs = IM.insert (strs, n, f), 308 strs = IM.insert (strs, n, f),
254 funs = funs, 309 funs = funs,
255 current = FNormal {cons = mcons, 310 current = FNormal {cons = mcons,
311 constructors = mconstructors,
256 vals = mvals, 312 vals = mvals,
257 strs = SM.insert (mstrs, x, f), 313 strs = SM.insert (mstrs, x, f),
258 funs = mfuns}, 314 funs = mfuns},
259 nested = nested} 315 nested = nested}
260 | bindStr _ _ _ _ = raise Fail "Corify.St.bindStr" 316 | bindStr _ _ _ _ = raise Fail "Corify.St.bindStr"
268 (case SM.find (strs, m) of 324 (case SM.find (strs, m) of
269 NONE => raise Fail "Corify.St.lookupStrByName" 325 NONE => raise Fail "Corify.St.lookupStrByName"
270 | SOME f => dummy f) 326 | SOME f => dummy f)
271 | lookupStrByName _ = raise Fail "Corify.St.lookupStrByName" 327 | lookupStrByName _ = raise Fail "Corify.St.lookupStrByName"
272 328
273 fun bindFunctor ({cons, vals, strs, funs, 329 fun bindFunctor ({cons, constructors, vals, strs, funs,
274 current = FNormal {cons = mcons, vals = mvals, strs = mstrs, funs = mfuns}, nested} : t) 330 current = FNormal {cons = mcons, constructors = mconstructors,
331 vals = mvals, strs = mstrs, funs = mfuns}, nested} : t)
275 x n xa na str = 332 x n xa na str =
276 {cons = cons, 333 {cons = cons,
334 constructors = constructors,
277 vals = vals, 335 vals = vals,
278 strs = strs, 336 strs = strs,
279 funs = IM.insert (funs, n, (xa, na, str)), 337 funs = IM.insert (funs, n, (xa, na, str)),
280 current = FNormal {cons = mcons, 338 current = FNormal {cons = mcons,
339 constructors = mconstructors,
281 vals = mvals, 340 vals = mvals,
282 strs = mstrs, 341 strs = mstrs,
283 funs = SM.insert (mfuns, x, (xa, na, str))}, 342 funs = SM.insert (mfuns, x, (xa, na, str))},
284 nested = nested} 343 nested = nested}
285 | bindFunctor _ _ _ _ _ _ = raise Fail "Corify.St.bindFunctor" 344 | bindFunctor _ _ _ _ _ _ = raise Fail "Corify.St.bindFunctor"
335 | L.CRecord (k, xcs) => 394 | L.CRecord (k, xcs) =>
336 (L'.CRecord (corifyKind k, map (fn (c1, c2) => (corifyCon st c1, corifyCon st c2)) xcs), loc) 395 (L'.CRecord (corifyKind k, map (fn (c1, c2) => (corifyCon st c1, corifyCon st c2)) xcs), loc)
337 | L.CConcat (c1, c2) => (L'.CConcat (corifyCon st c1, corifyCon st c2), loc) 396 | L.CConcat (c1, c2) => (L'.CConcat (corifyCon st c1, corifyCon st c2), loc)
338 | L.CFold (k1, k2) => (L'.CFold (corifyKind k1, corifyKind k2), loc) 397 | L.CFold (k1, k2) => (L'.CFold (corifyKind k1, corifyKind k2), loc)
339 | L.CUnit => (L'.CUnit, loc) 398 | L.CUnit => (L'.CUnit, loc)
399
400 fun corifyPatCon st pc =
401 case pc of
402 L.PConVar n => St.lookupConstructorById st n
403 | L.PConProj (m1, ms, x) =>
404 let
405 val st = St.lookupStrById st m1
406 val st = foldl St.lookupStrByName st ms
407 in
408 St.lookupConstructorByName st x
409 end
410
411 fun corifyPat st (p, loc) =
412 case p of
413 L.PWild => (L'.PWild, loc)
414 | L.PVar x => (L'.PVar x, loc)
415 | L.PPrim p => (L'.PPrim p, loc)
416 | L.PCon (pc, po) => (L'.PCon (corifyPatCon st pc, Option.map (corifyPat st) po), loc)
417 | L.PRecord xps => (L'.PRecord (map (fn (x, p) => (x, corifyPat st p)) xps), loc)
340 418
341 fun corifyExp st (e, loc) = 419 fun corifyExp st (e, loc) =
342 case e of 420 case e of
343 L.EPrim p => (L'.EPrim p, loc) 421 L.EPrim p => (L'.EPrim p, loc)
344 | L.ERel n => (L'.ERel n, loc) 422 | L.ERel n => (L'.ERel n, loc)
392 | L.EField (e1, c, {field, rest}) => (L'.EField (corifyExp st e1, corifyCon st c, 470 | L.EField (e1, c, {field, rest}) => (L'.EField (corifyExp st e1, corifyCon st c,
393 {field = corifyCon st field, rest = corifyCon st rest}), loc) 471 {field = corifyCon st field, rest = corifyCon st rest}), loc)
394 | L.ECut (e1, c, {field, rest}) => (L'.ECut (corifyExp st e1, corifyCon st c, 472 | L.ECut (e1, c, {field, rest}) => (L'.ECut (corifyExp st e1, corifyCon st c,
395 {field = corifyCon st field, rest = corifyCon st rest}), loc) 473 {field = corifyCon st field, rest = corifyCon st rest}), loc)
396 | L.EFold k => (L'.EFold (corifyKind k), loc) 474 | L.EFold k => (L'.EFold (corifyKind k), loc)
397 | L.ECase _ => raise Fail "Corify ECase" 475
476 | L.ECase (e, pes, t) => (L'.ECase (corifyExp st e,
477 map (fn (p, e) => (corifyPat st p, corifyExp st e)) pes,
478 corifyCon st t),
479 loc)
480
398 | L.EWrite e => (L'.EWrite (corifyExp st e), loc) 481 | L.EWrite e => (L'.EWrite (corifyExp st e), loc)
399 482
400 fun corifyDecl ((d, loc : EM.span), st) = 483 fun corifyDecl ((d, loc : EM.span), st) =
401 case d of 484 case d of
402 L.DCon (x, n, k, c) => 485 L.DCon (x, n, k, c) =>
408 | L.DDatatype (x, n, xncs) => 491 | L.DDatatype (x, n, xncs) =>
409 let 492 let
410 val (st, n) = St.bindCon st x n 493 val (st, n) = St.bindCon st x n
411 val (xncs, st) = ListUtil.foldlMap (fn ((x, n, co), st) => 494 val (xncs, st) = ListUtil.foldlMap (fn ((x, n, co), st) =>
412 let 495 let
413 val st = St.bindConstructor st x n 496 val st = St.bindConstructor st x n (L'.PConVar n)
497 val st = St.bindConstructorVal st x n
414 val co = Option.map (corifyCon st) co 498 val co = Option.map (corifyCon st) co
415 in 499 in
416 ((x, n, co), st) 500 ((x, n, co), st)
417 end) st xncs 501 end) st xncs
418 in 502
419 ([(L'.DDatatype (x, n, xncs), loc)], st) 503 val t = (L'.CNamed n, loc)
504 val dcons = map (fn (x, n, to) =>
505 let
506 val (e, t) =
507 case to of
508 NONE => ((L'.ECon (n, NONE), loc), t)
509 | SOME t' => ((L'.EAbs ("x", t', t,
510 (L'.ECon (n, SOME (L'.ERel 0, loc)), loc)),
511 loc),
512 (L'.TFun (t', t), loc))
513 in
514 (L'.DVal (x, n, t, e, ""), loc)
515 end) xncs
516 in
517 ((L'.DDatatype (x, n, xncs), loc) :: dcons, st)
420 end 518 end
421 | L.DDatatypeImp (x, n, m1, ms, s, xncs) => 519 | L.DDatatypeImp (x, n, m1, ms, s, xncs) =>
422 let 520 let
423 val (st, n) = St.bindCon st x n 521 val (st, n) = St.bindCon st x n
424 val c = corifyCon st (L.CModProj (m1, ms, s), loc) 522 val c = corifyCon st (L.CModProj (m1, ms, s), loc)
425 523
524 val m = foldl (fn (x, m) => (L.StrProj (m, x), loc)) (L.StrVar m1, loc) ms
525 val (_, {inner, ...}) = corifyStr (m, st)
526
426 val (xncs, st) = ListUtil.foldlMap (fn ((x, n, co), st) => 527 val (xncs, st) = ListUtil.foldlMap (fn ((x, n, co), st) =>
427 let 528 let
529 val n' = St.lookupConstructorByName inner x
530 val st = St.bindConstructor st x n n'
428 val (st, n) = St.bindVal st x n 531 val (st, n) = St.bindVal st x n
429 val co = Option.map (corifyCon st) co 532 val co = Option.map (corifyCon st) co
430 in 533 in
431 ((x, n, co), st) 534 ((x, n, co), st)
432 end) st xncs 535 end) st xncs
433 536
434 val cds = map (fn (x, n, co) => 537 val cds = map (fn (x, n, co) =>
435 let 538 let
436 val t = case co of 539 val t = case co of
437 NONE => c 540 NONE => c
438 | SOME t' => (L'.TFun (t', c), loc) 541 | SOME t' => (L'.TFun (t', c), loc)