comparison src/elab_env.sml @ 59:abb2b32c19fb

Subsignatures
author Adam Chlipala <adamc@hcoop.net>
date Sun, 22 Jun 2008 19:10:38 -0400
parents d3cc191cb25f
children 7bab29834cd6
comparison
equal deleted inserted replaced
58:fd8a81ecd598 59:abb2b32c19fb
296 case sgi of 296 case sgi of
297 SgiConAbs (x, n, k) => pushCNamedAs env x n k NONE 297 SgiConAbs (x, n, k) => pushCNamedAs env x n k NONE
298 | SgiCon (x, n, k, c) => pushCNamedAs env x n k (SOME c) 298 | SgiCon (x, n, k, c) => pushCNamedAs env x n k (SOME c)
299 | SgiVal (x, n, t) => pushENamedAs env x n t 299 | SgiVal (x, n, t) => pushENamedAs env x n t
300 | SgiStr (x, n, sgn) => pushStrNamedAs env x n sgn 300 | SgiStr (x, n, sgn) => pushStrNamedAs env x n sgn
301 | SgiSgn (x, n, sgn) => pushSgnNamedAs env x n sgn
301 302
302 fun sgnSeek f sgis = 303 fun sgnSeek f sgis =
303 let 304 let
304 fun seek (sgis, strs, cons) = 305 fun seek (sgis, sgns, strs, cons) =
305 case sgis of 306 case sgis of
306 [] => NONE 307 [] => NONE
307 | (sgi, _) :: sgis => 308 | (sgi, _) :: sgis =>
308 case f sgi of 309 case f sgi of
309 SOME v => SOME (v, (strs, cons)) 310 SOME v => SOME (v, (sgns, strs, cons))
310 | NONE => 311 | NONE =>
311 case sgi of 312 case sgi of
312 SgiConAbs (x, n, _) => seek (sgis, strs, IM.insert (cons, n, x)) 313 SgiConAbs (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x))
313 | SgiCon (x, n, _, _) => seek (sgis, strs, IM.insert (cons, n, x)) 314 | SgiCon (x, n, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x))
314 | SgiVal _ => seek (sgis, strs, cons) 315 | SgiVal _ => seek (sgis, sgns, strs, cons)
315 | SgiStr (x, n, _) => seek (sgis, IM.insert (strs, n, x), cons) 316 | SgiSgn (x, n, _) => seek (sgis, IM.insert (sgns, n, x), strs, cons)
316 in 317 | SgiStr (x, n, _) => seek (sgis, sgns, IM.insert (strs, n, x), cons)
317 seek (sgis, IM.empty, IM.empty) 318 in
319 seek (sgis, IM.empty, IM.empty, IM.empty)
318 end 320 end
319 321
320 fun id x = x 322 fun id x = x
321 323
322 fun unravelStr (str, _) = 324 fun unravelStr (str, _) =
328 in 330 in
329 (x, ms @ [m]) 331 (x, ms @ [m])
330 end 332 end
331 | _ => raise Fail "unravelStr" 333 | _ => raise Fail "unravelStr"
332 334
333 fun sgnS_con (str, (strs, cons)) c = 335 fun sgnS_con (str, (sgns, strs, cons)) c =
334 case c of 336 case c of
335 CModProj (m1, ms, x) => 337 CModProj (m1, ms, x) =>
336 (case IM.find (strs, m1) of 338 (case IM.find (strs, m1) of
337 NONE => c 339 NONE => c
338 | SOME m1x => 340 | SOME m1x =>
350 in 352 in
351 CModProj (m1, ms, nx) 353 CModProj (m1, ms, nx)
352 end) 354 end)
353 | _ => c 355 | _ => c
354 356
355 fun sgnSubCon (str, (strs, cons)) = 357 fun sgnS_sgn (str, (sgns, strs, cons)) sgn =
358 case sgn of
359 SgnProj (m1, ms, x) =>
360 (case IM.find (strs, m1) of
361 NONE => sgn
362 | SOME m1x =>
363 let
364 val (m1, ms') = unravelStr str
365 in
366 SgnProj (m1, ms' @ m1x :: ms, x)
367 end)
368 | SgnVar n =>
369 (case IM.find (sgns, n) of
370 NONE => sgn
371 | SOME nx =>
372 let
373 val (m1, ms) = unravelStr str
374 in
375 SgnProj (m1, ms, nx)
376 end)
377 | _ => sgn
378
379 fun sgnSubCon x =
356 ElabUtil.Con.map {kind = id, 380 ElabUtil.Con.map {kind = id,
357 con = sgnS_con (str, (strs, cons))} 381 con = sgnS_con x}
358 382
359 fun sgnSubSgn (str, (strs, cons)) = 383 fun sgnSubSgn x =
360 ElabUtil.Sgn.map {kind = id, 384 ElabUtil.Sgn.map {kind = id,
361 con = sgnS_con (str, (strs, cons)), 385 con = sgnS_con x,
362 sgn_item = id, 386 sgn_item = id,
363 sgn = id} 387 sgn = sgnS_sgn x}
364 388
365 fun hnormSgn env (all as (sgn, loc)) = 389 fun hnormSgn env (all as (sgn, loc)) =
366 case sgn of 390 case sgn of
367 SgnError => all 391 SgnError => all
368 | SgnVar n => hnormSgn env (#2 (lookupSgnNamed env n)) 392 | SgnVar n => hnormSgn env (#2 (lookupSgnNamed env n))
369 | SgnConst _ => all 393 | SgnConst _ => all
370 | SgnFun _ => all 394 | SgnFun _ => all
395 | SgnProj (m, ms, x) =>
396 let
397 val (_, sgn) = lookupStrNamed env m
398 in
399 case projectSgn env {str = foldl (fn (m, str) => (StrProj (str, m), loc)) (StrVar m, loc) ms,
400 sgn = sgn,
401 field = x} of
402 NONE => raise Fail "ElabEnv.hnormSgn: projectSgn failed"
403 | SOME sgn => sgn
404 end
371 | SgnWhere (sgn, x, c) => 405 | SgnWhere (sgn, x, c) =>
372 case #1 (hnormSgn env sgn) of 406 case #1 (hnormSgn env sgn) of
373 SgnError => (SgnError, loc) 407 SgnError => (SgnError, loc)
374 | SgnConst sgis => 408 | SgnConst sgis =>
375 let 409 let
387 in 421 in
388 (SgnConst sgis, loc) 422 (SgnConst sgis, loc)
389 end 423 end
390 | _ => raise Fail "ElabEnv.hnormSgn: Can't reduce 'where' [2]" 424 | _ => raise Fail "ElabEnv.hnormSgn: Can't reduce 'where' [2]"
391 425
426 and projectSgn env {sgn, str, field} =
427 case #1 (hnormSgn env sgn) of
428 SgnConst sgis =>
429 (case sgnSeek (fn SgiSgn (x, _, sgn) => if x = field then SOME sgn else NONE | _ => NONE) sgis of
430 NONE => NONE
431 | SOME (sgn, subs) => SOME (sgnSubSgn (str, subs) sgn))
432 | SgnError => SOME (SgnError, ErrorMsg.dummySpan)
433 | _ => NONE
434
435 fun projectStr env {sgn, str, field} =
436 case #1 (hnormSgn env sgn) of
437 SgnConst sgis =>
438 (case sgnSeek (fn SgiStr (x, _, sgn) => if x = field then SOME sgn else NONE | _ => NONE) sgis of
439 NONE => NONE
440 | SOME (sgn, subs) => SOME (sgnSubSgn (str, subs) sgn))
441 | SgnError => SOME (SgnError, ErrorMsg.dummySpan)
442 | _ => NONE
443
392 fun projectCon env {sgn, str, field} = 444 fun projectCon env {sgn, str, field} =
393 case #1 (hnormSgn env sgn) of 445 case #1 (hnormSgn env sgn) of
394 SgnConst sgis => 446 SgnConst sgis =>
395 (case sgnSeek (fn SgiConAbs (x, _, k) => if x = field then SOME (k, NONE) else NONE 447 (case sgnSeek (fn SgiConAbs (x, _, k) => if x = field then SOME (k, NONE) else NONE
396 | SgiCon (x, _, k, c) => if x = field then SOME (k, SOME c) else NONE 448 | SgiCon (x, _, k, c) => if x = field then SOME (k, SOME c) else NONE
407 NONE => NONE 459 NONE => NONE
408 | SOME (c, subs) => SOME (sgnSubCon (str, subs) c)) 460 | SOME (c, subs) => SOME (sgnSubCon (str, subs) c))
409 | SgnError => SOME (CError, ErrorMsg.dummySpan) 461 | SgnError => SOME (CError, ErrorMsg.dummySpan)
410 | _ => NONE 462 | _ => NONE
411 463
412 fun projectStr env {sgn, str, field} =
413 case #1 (hnormSgn env sgn) of
414 SgnConst sgis =>
415 (case sgnSeek (fn SgiStr (x, _, sgn) => if x = field then SOME sgn else NONE | _ => NONE) sgis of
416 NONE => NONE
417 | SOME (sgn, subs) => SOME (sgnSubSgn (str, subs) sgn))
418 | SgnError => SOME (SgnError, ErrorMsg.dummySpan)
419 | _ => NONE
420 464
421 end 465 end