comparison src/elab_env.sml @ 158:b4b70de488e9

More datatype module stuff
author Adam Chlipala <adamc@hcoop.net>
date Thu, 24 Jul 2008 16:36:41 -0400
parents adc4e42e3adc
children 06a98129b23f
comparison
equal deleted inserted replaced
157:adc4e42e3adc 158:b4b70de488e9
364 fun seek (sgis, sgns, strs, cons) = 364 fun seek (sgis, sgns, strs, cons) =
365 case sgis of 365 case sgis of
366 [] => NONE 366 [] => NONE
367 | (sgi, _) :: sgis => 367 | (sgi, _) :: sgis =>
368 case f sgi of 368 case f sgi of
369 SOME v => SOME (v, (sgns, strs, cons)) 369 SOME v =>
370 let
371 val cons =
372 case sgi of
373 SgiDatatype (x, n, _) => IM.insert (cons, n, x)
374 | SgiDatatypeImp (x, n, _, _, _) => IM.insert (cons, n, x)
375 | _ => cons
376 in
377 SOME (v, (sgns, strs, cons))
378 end
370 | NONE => 379 | NONE =>
371 case sgi of 380 case sgi of
372 SgiConAbs (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x)) 381 SgiConAbs (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x))
373 | SgiCon (x, n, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x)) 382 | SgiCon (x, n, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x))
374 | SgiDatatype (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x)) 383 | SgiDatatype (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x))
501 NONE => NONE 510 NONE => NONE
502 | SOME (sgn, subs) => SOME (sgnSubSgn (str, subs) sgn)) 511 | SOME (sgn, subs) => SOME (sgnSubSgn (str, subs) sgn))
503 | SgnError => SOME (SgnError, ErrorMsg.dummySpan) 512 | SgnError => SOME (SgnError, ErrorMsg.dummySpan)
504 | _ => NONE 513 | _ => NONE
505 514
515 fun chaseMpath env (n, ms) =
516 let
517 val (_, sgn) = lookupStrNamed env n
518 in
519 foldl (fn (m, (str, sgn)) =>
520 case projectStr env {sgn = sgn, str = str, field = m} of
521 NONE => raise Fail "kindof: Unknown substructure"
522 | SOME sgn => ((StrProj (str, m), #2 sgn), sgn))
523 ((StrVar n, #2 sgn), sgn) ms
524 end
525
506 fun projectCon env {sgn, str, field} = 526 fun projectCon env {sgn, str, field} =
507 case #1 (hnormSgn env sgn) of 527 case #1 (hnormSgn env sgn) of
508 SgnConst sgis => 528 SgnConst sgis =>
509 (case sgnSeek (fn SgiConAbs (x, _, k) => if x = field then SOME (k, NONE) else NONE 529 (case sgnSeek (fn SgiConAbs (x, _, k) => if x = field then SOME (k, NONE) else NONE
510 | SgiCon (x, _, k, c) => if x = field then SOME (k, SOME c) else NONE 530 | SgiCon (x, _, k, c) => if x = field then SOME (k, SOME c) else NONE
511 | SgiDatatype (x, _, _) => if x = field then SOME ((KType, #2 sgn), NONE) else NONE 531 | SgiDatatype (x, _, _) => if x = field then SOME ((KType, #2 sgn), NONE) else NONE
532 | SgiDatatypeImp (x, _, m1, ms, x') =>
533 if x = field then
534 SOME ((KType, #2 sgn), SOME (CModProj (m1, ms, x'), #2 sgn))
535 else
536 NONE
512 | _ => NONE) sgis of 537 | _ => NONE) sgis of
513 NONE => NONE 538 NONE => NONE
514 | SOME ((k, co), subs) => SOME (k, Option.map (sgnSubCon (str, subs)) co)) 539 | SOME ((k, co), subs) => SOME (k, Option.map (sgnSubCon (str, subs)) co))
515 | SgnError => SOME ((KError, ErrorMsg.dummySpan), SOME (CError, ErrorMsg.dummySpan)) 540 | SgnError => SOME ((KError, ErrorMsg.dummySpan), SOME (CError, ErrorMsg.dummySpan))
516 | _ => NONE 541 | _ => NONE
517 542
518 fun projectDatatype env {sgn, str, field} = 543 fun projectDatatype env {sgn, str, field} =
519 case #1 (hnormSgn env sgn) of 544 case #1 (hnormSgn env sgn) of
520 SgnConst sgis => 545 SgnConst sgis =>
521 (case sgnSeek (fn SgiDatatype (x, _, xncs) => if x = field then SOME xncs else NONE 546 (case sgnSeek (fn SgiDatatype (x, _, xncs) => if x = field then SOME xncs else NONE
547 | SgiDatatypeImp (x, _, m1, ms, x') =>
548 if x = field then
549 let
550 val (str, sgn) = chaseMpath env (m1, ms)
551 in
552 projectDatatype env {sgn = sgn, str = str, field = x'}
553 end
554 else
555 NONE
522 | _ => NONE) sgis of 556 | _ => NONE) sgis of
523 NONE => NONE 557 NONE => NONE
524 | SOME (xncs, subs) => SOME (map (fn (x, n, to) => (x, n, Option.map (sgnSubCon (str, subs)) to)) xncs)) 558 | SOME (xncs, subs) => SOME (map (fn (x, n, to) => (x, n, Option.map (sgnSubCon (str, subs)) to)) xncs))
525 | _ => NONE 559 | _ => NONE
526 560
527 fun projectVal env {sgn, str, field} = 561 fun projectVal env {sgn, str, field} =
528 case #1 (hnormSgn env sgn) of 562 case #1 (hnormSgn env sgn) of
529 SgnConst sgis => 563 SgnConst sgis =>
530 (case sgnSeek (fn SgiVal (x, _, c) => if x = field then SOME c else NONE | _ => NONE) sgis of 564 (case sgnSeek (fn SgiVal (x, _, c) => if x = field then SOME c else NONE
565 | SgiDatatype (_, n, xncs) =>
566 ListUtil.search (fn (x, _, to) =>
567 if x = field then
568 SOME (case to of
569 NONE => (CNamed n, #2 sgn)
570 | SOME t => (TFun (t, (CNamed n, #2 sgn)), #2 sgn))
571 else
572 NONE) xncs
573 | SgiDatatypeImp (_, n, m1, ms, x') =>
574 let
575 val (str, sgn) = chaseMpath env (m1, ms)
576 in
577 case projectDatatype env {sgn = sgn, str = str, field = x'} of
578 NONE => NONE
579 | SOME xncs =>
580 ListUtil.search (fn (x, _, to) =>
581 if x = field then
582 SOME (case to of
583 NONE => (CNamed n, #2 sgn)
584 | SOME t => (TFun (t, (CNamed n, #2 sgn)), #2 sgn))
585 else
586 NONE) xncs
587 end
588 | _ => NONE) sgis of
531 NONE => NONE 589 NONE => NONE
532 | SOME (c, subs) => SOME (sgnSubCon (str, subs) c)) 590 | SOME (c, subs) => SOME (sgnSubCon (str, subs) c))
533 | SgnError => SOME (CError, ErrorMsg.dummySpan) 591 | SgnError => SOME (CError, ErrorMsg.dummySpan)
534 | _ => NONE 592 | _ => NONE
535 593