Mercurial > urweb
comparison src/elab_env.sml @ 191:aa54250f58ac
Parametrized datatypes through explify
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Fri, 08 Aug 2008 10:28:32 -0400 |
parents | 8e9f97508f0d |
children | dd82457fda82 |
comparison
equal
deleted
inserted
replaced
190:3eb53c957d10 | 191:aa54250f58ac |
---|---|
71 datatype 'a var = | 71 datatype 'a var = |
72 NotBound | 72 NotBound |
73 | Rel of int * 'a | 73 | Rel of int * 'a |
74 | Named of int * 'a | 74 | Named of int * 'a |
75 | 75 |
76 type datatyp = (string * con option) IM.map | 76 type datatyp = string list * (string * con option) IM.map |
77 | 77 |
78 type env = { | 78 type env = { |
79 renameC : kind var' SM.map, | 79 renameC : kind var' SM.map, |
80 relC : (string * kind) list, | 80 relC : (string * kind) list, |
81 namedC : (string * kind * con option) IM.map, | 81 namedC : (string * kind * con option) IM.map, |
82 | 82 |
83 datatypes : datatyp IM.map, | 83 datatypes : datatyp IM.map, |
84 constructors : (datatype_kind * int * con option * int) SM.map, | 84 constructors : (datatype_kind * int * string list * con option * int) SM.map, |
85 | 85 |
86 renameE : con var' SM.map, | 86 renameE : con var' SM.map, |
87 relE : (string * con) list, | 87 relE : (string * con) list, |
88 namedE : (string * con) IM.map, | 88 namedE : (string * con) IM.map, |
89 | 89 |
186 case SM.find (#renameC env, x) of | 186 case SM.find (#renameC env, x) of |
187 NONE => NotBound | 187 NONE => NotBound |
188 | SOME (Rel' x) => Rel x | 188 | SOME (Rel' x) => Rel x |
189 | SOME (Named' x) => Named x | 189 | SOME (Named' x) => Named x |
190 | 190 |
191 fun pushDatatype (env : env) n xncs = | 191 fun pushDatatype (env : env) n xs xncs = |
192 let | 192 let |
193 val dk = U.classifyDatatype xncs | 193 val dk = U.classifyDatatype xncs |
194 in | 194 in |
195 {renameC = #renameC env, | 195 {renameC = #renameC env, |
196 relC = #relC env, | 196 relC = #relC env, |
197 namedC = #namedC env, | 197 namedC = #namedC env, |
198 | 198 |
199 datatypes = IM.insert (#datatypes env, n, | 199 datatypes = IM.insert (#datatypes env, n, |
200 foldl (fn ((x, n, to), cons) => | 200 (xs, foldl (fn ((x, n, to), cons) => |
201 IM.insert (cons, n, (x, to))) IM.empty xncs), | 201 IM.insert (cons, n, (x, to))) IM.empty xncs)), |
202 constructors = foldl (fn ((x, n', to), cmap) => | 202 constructors = foldl (fn ((x, n', to), cmap) => |
203 SM.insert (cmap, x, (dk, n', to, n))) | 203 SM.insert (cmap, x, (dk, n', xs, to, n))) |
204 (#constructors env) xncs, | 204 (#constructors env) xncs, |
205 | 205 |
206 renameE = #renameE env, | 206 renameE = #renameE env, |
207 relE = #relE env, | 207 relE = #relE env, |
208 namedE = #namedE env, | 208 namedE = #namedE env, |
217 fun lookupDatatype (env : env) n = | 217 fun lookupDatatype (env : env) n = |
218 case IM.find (#datatypes env, n) of | 218 case IM.find (#datatypes env, n) of |
219 NONE => raise UnboundNamed n | 219 NONE => raise UnboundNamed n |
220 | SOME x => x | 220 | SOME x => x |
221 | 221 |
222 fun lookupDatatypeConstructor dt n = | 222 fun lookupDatatypeConstructor (_, dt) n = |
223 case IM.find (dt, n) of | 223 case IM.find (dt, n) of |
224 NONE => raise UnboundNamed n | 224 NONE => raise UnboundNamed n |
225 | SOME x => x | 225 | SOME x => x |
226 | 226 |
227 fun lookupConstructor (env : env) s = SM.find (#constructors env, s) | 227 fun lookupConstructor (env : env) s = SM.find (#constructors env, s) |
228 | 228 |
229 fun constructors dt = IM.foldri (fn (n, (x, to), ls) => (x, n, to) :: ls) [] dt | 229 fun datatypeArgs (xs, _) = xs |
230 fun constructors (_, dt) = IM.foldri (fn (n, (x, to), ls) => (x, n, to) :: ls) [] dt | |
230 | 231 |
231 fun pushERel (env : env) x t = | 232 fun pushERel (env : env) x t = |
232 let | 233 let |
233 val renameE = SM.map (fn Rel' (n, t) => Rel' (n+1, t) | 234 val renameE = SM.map (fn Rel' (n, t) => Rel' (n+1, t) |
234 | x => x) (#renameE env) | 235 | x => x) (#renameE env) |
360 | 361 |
361 fun sgiBinds env (sgi, loc) = | 362 fun sgiBinds env (sgi, loc) = |
362 case sgi of | 363 case sgi of |
363 SgiConAbs (x, n, k) => pushCNamedAs env x n k NONE | 364 SgiConAbs (x, n, k) => pushCNamedAs env x n k NONE |
364 | SgiCon (x, n, k, c) => pushCNamedAs env x n k (SOME c) | 365 | SgiCon (x, n, k, c) => pushCNamedAs env x n k (SOME c) |
365 | SgiDatatype (x, n, xncs) => | 366 | SgiDatatype (x, n, xs, xncs) => |
366 let | 367 let |
367 val env = pushCNamedAs env x n (KType, loc) NONE | 368 val env = pushCNamedAs env x n (KType, loc) NONE |
368 in | 369 in |
369 foldl (fn ((x', n', NONE), env) => pushENamedAs env x' n' (CNamed n, loc) | 370 foldl (fn ((x', n', to), env) => |
370 | ((x', n', SOME t), env) => pushENamedAs env x' n' (TFun (t, (CNamed n, loc)), loc)) | 371 let |
372 val t = | |
373 case to of | |
374 NONE => (CNamed n, loc) | |
375 | SOME t => (TFun (t, (CNamed n, loc)), loc) | |
376 | |
377 val k = (KType, loc) | |
378 val t = foldr (fn (x, t) => (TCFun (Explicit, x, k, t), loc)) t xs | |
379 in | |
380 pushENamedAs env x' n' t | |
381 end) | |
371 env xncs | 382 env xncs |
372 end | 383 end |
373 | SgiDatatypeImp (x, n, m1, ms, x', xncs) => | 384 | SgiDatatypeImp (x, n, m1, ms, x', xs, xncs) => |
374 let | 385 let |
375 val env = pushCNamedAs env x n (KType, loc) (SOME (CModProj (m1, ms, x'), loc)) | 386 val env = pushCNamedAs env x n (KType, loc) (SOME (CModProj (m1, ms, x'), loc)) |
376 in | 387 in |
377 foldl (fn ((x', n', NONE), env) => pushENamedAs env x' n' (CNamed n, loc) | 388 foldl (fn ((x', n', to), env) => |
378 | ((x', n', SOME t), env) => pushENamedAs env x' n' (TFun (t, (CNamed n, loc)), loc)) | 389 let |
390 val t = | |
391 case to of | |
392 NONE => (CNamed n, loc) | |
393 | SOME t => (TFun (t, (CNamed n, loc)), loc) | |
394 | |
395 val k = (KType, loc) | |
396 val t = foldr (fn (x, t) => (TCFun (Explicit, x, k, t), loc)) t xs | |
397 in | |
398 pushENamedAs env x' n' t | |
399 end) | |
379 env xncs | 400 env xncs |
380 end | 401 end |
381 | SgiVal (x, n, t) => pushENamedAs env x n t | 402 | SgiVal (x, n, t) => pushENamedAs env x n t |
382 | SgiStr (x, n, sgn) => pushStrNamedAs env x n sgn | 403 | SgiStr (x, n, sgn) => pushStrNamedAs env x n sgn |
383 | SgiSgn (x, n, sgn) => pushSgnNamedAs env x n sgn | 404 | SgiSgn (x, n, sgn) => pushSgnNamedAs env x n sgn |
392 case f sgi of | 413 case f sgi of |
393 SOME v => | 414 SOME v => |
394 let | 415 let |
395 val cons = | 416 val cons = |
396 case sgi of | 417 case sgi of |
397 SgiDatatype (x, n, _) => IM.insert (cons, n, x) | 418 SgiDatatype (x, n, _, _) => IM.insert (cons, n, x) |
398 | SgiDatatypeImp (x, n, _, _, _, _) => IM.insert (cons, n, x) | 419 | SgiDatatypeImp (x, n, _, _, _, _, _) => IM.insert (cons, n, x) |
399 | _ => cons | 420 | _ => cons |
400 in | 421 in |
401 SOME (v, (sgns, strs, cons)) | 422 SOME (v, (sgns, strs, cons)) |
402 end | 423 end |
403 | NONE => | 424 | NONE => |
404 case sgi of | 425 case sgi of |
405 SgiConAbs (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x)) | 426 SgiConAbs (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x)) |
406 | SgiCon (x, n, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x)) | 427 | SgiCon (x, n, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x)) |
407 | SgiDatatype (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x)) | 428 | SgiDatatype (x, n, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x)) |
408 | SgiDatatypeImp (x, n, _, _, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x)) | 429 | SgiDatatypeImp (x, n, _, _, _, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x)) |
409 | SgiVal _ => seek (sgis, sgns, strs, cons) | 430 | SgiVal _ => seek (sgis, sgns, strs, cons) |
410 | SgiSgn (x, n, _) => seek (sgis, IM.insert (sgns, n, x), strs, cons) | 431 | SgiSgn (x, n, _) => seek (sgis, IM.insert (sgns, n, x), strs, cons) |
411 | SgiStr (x, n, _) => seek (sgis, sgns, IM.insert (strs, n, x), cons) | 432 | SgiStr (x, n, _) => seek (sgis, sgns, IM.insert (strs, n, x), cons) |
412 | SgiConstraint _ => seek (sgis, sgns, strs, cons) | 433 | SgiConstraint _ => seek (sgis, sgns, strs, cons) |
413 in | 434 in |
550 fun projectCon env {sgn, str, field} = | 571 fun projectCon env {sgn, str, field} = |
551 case #1 (hnormSgn env sgn) of | 572 case #1 (hnormSgn env sgn) of |
552 SgnConst sgis => | 573 SgnConst sgis => |
553 (case sgnSeek (fn SgiConAbs (x, _, k) => if x = field then SOME (k, NONE) else NONE | 574 (case sgnSeek (fn SgiConAbs (x, _, k) => if x = field then SOME (k, NONE) else NONE |
554 | SgiCon (x, _, k, c) => if x = field then SOME (k, SOME c) else NONE | 575 | SgiCon (x, _, k, c) => if x = field then SOME (k, SOME c) else NONE |
555 | SgiDatatype (x, _, _) => if x = field then SOME ((KType, #2 sgn), NONE) else NONE | 576 | SgiDatatype (x, _, _, _) => if x = field then SOME ((KType, #2 sgn), NONE) else NONE |
556 | SgiDatatypeImp (x, _, m1, ms, x', _) => | 577 | SgiDatatypeImp (x, _, m1, ms, x', _, _) => |
557 if x = field then | 578 if x = field then |
558 SOME ((KType, #2 sgn), SOME (CModProj (m1, ms, x'), #2 sgn)) | 579 SOME ((KType, #2 sgn), SOME (CModProj (m1, ms, x'), #2 sgn)) |
559 else | 580 else |
560 NONE | 581 NONE |
561 | _ => NONE) sgis of | 582 | _ => NONE) sgis of |
565 | _ => NONE | 586 | _ => NONE |
566 | 587 |
567 fun projectDatatype env {sgn, str, field} = | 588 fun projectDatatype env {sgn, str, field} = |
568 case #1 (hnormSgn env sgn) of | 589 case #1 (hnormSgn env sgn) of |
569 SgnConst sgis => | 590 SgnConst sgis => |
570 (case sgnSeek (fn SgiDatatype (x, _, xncs) => if x = field then SOME xncs else NONE | 591 (case sgnSeek (fn SgiDatatype (x, _, xs, xncs) => if x = field then SOME (xs, xncs) else NONE |
571 | SgiDatatypeImp (x, _, _, _, _, xncs) => if x = field then SOME xncs else NONE | 592 | SgiDatatypeImp (x, _, _, _, _, xs, xncs) => if x = field then SOME (xs, xncs) else NONE |
572 | _ => NONE) sgis of | 593 | _ => NONE) sgis of |
573 NONE => NONE | 594 NONE => NONE |
574 | SOME (xncs, subs) => SOME (map (fn (x, n, to) => (x, n, Option.map (sgnSubCon (str, subs)) to)) xncs)) | 595 | SOME ((xs, xncs), subs) => SOME (xs, |
596 map (fn (x, n, to) => (x, n, Option.map (sgnSubCon (str, subs)) to)) xncs)) | |
575 | _ => NONE | 597 | _ => NONE |
576 | 598 |
577 fun projectConstructor env {sgn, str, field} = | 599 fun projectConstructor env {sgn, str, field} = |
578 case #1 (hnormSgn env sgn) of | 600 case #1 (hnormSgn env sgn) of |
579 SgnConst sgis => | 601 SgnConst sgis => |
580 let | 602 let |
581 fun consider (n, xncs) = | 603 fun consider (n, xs, xncs) = |
582 ListUtil.search (fn (x, n', to) => | 604 ListUtil.search (fn (x, n', to) => |
583 if x <> field then | 605 if x <> field then |
584 NONE | 606 NONE |
585 else | 607 else |
586 SOME (U.classifyDatatype xncs, n', to, (CNamed n, #2 str))) xncs | 608 SOME (U.classifyDatatype xncs, n', xs, to, (CNamed n, #2 str))) xncs |
587 in | 609 in |
588 case sgnSeek (fn SgiDatatype (_, n, xncs) => consider (n, xncs) | 610 case sgnSeek (fn SgiDatatype (_, n, xs, xncs) => consider (n, xs, xncs) |
589 | SgiDatatypeImp (_, n, _, _, _, xncs) => consider (n, xncs) | 611 | SgiDatatypeImp (_, n, _, _, _, xs, xncs) => consider (n, xs, xncs) |
590 | _ => NONE) sgis of | 612 | _ => NONE) sgis of |
591 NONE => NONE | 613 NONE => NONE |
592 | SOME ((dk, n, to, t), subs) => SOME (dk, n, Option.map (sgnSubCon (str, subs)) to, | 614 | SOME ((dk, n, xs, to, t), subs) => SOME (dk, n, xs, Option.map (sgnSubCon (str, subs)) to, |
593 sgnSubCon (str, subs) t) | 615 sgnSubCon (str, subs) t) |
594 end | 616 end |
595 | _ => NONE | 617 | _ => NONE |
596 | 618 |
597 fun projectVal env {sgn, str, field} = | 619 fun projectVal env {sgn, str, field} = |
598 case #1 (hnormSgn env sgn) of | 620 case #1 (hnormSgn env sgn) of |
599 SgnConst sgis => | 621 SgnConst sgis => |
600 let | 622 let |
601 fun seek (n, xncs) = | 623 fun seek (n, xs, xncs) = |
602 ListUtil.search (fn (x, _, to) => | 624 ListUtil.search (fn (x, _, to) => |
603 if x = field then | 625 if x = field then |
604 SOME (case to of | 626 SOME (let |
605 NONE => (CNamed n, #2 sgn) | 627 val t = |
606 | SOME t => (TFun (t, (CNamed n, #2 sgn)), #2 sgn)) | 628 case to of |
629 NONE => (CNamed n, #2 sgn) | |
630 | SOME t => (TFun (t, (CNamed n, #2 sgn)), #2 sgn) | |
631 val k = (KType, #2 sgn) | |
632 in | |
633 foldr (fn (x, t) => (TCFun (Explicit, x, k, t), #2 sgn)) | |
634 t xs | |
635 end) | |
607 else | 636 else |
608 NONE) xncs | 637 NONE) xncs |
609 in | 638 in |
610 case sgnSeek (fn SgiVal (x, _, c) => if x = field then SOME c else NONE | 639 case sgnSeek (fn SgiVal (x, _, c) => if x = field then SOME c else NONE |
611 | SgiDatatype (_, n, xncs) => seek (n, xncs) | 640 | SgiDatatype (_, n, xs, xncs) => seek (n, xs, xncs) |
612 | SgiDatatypeImp (_, n, _, _, _, xncs) => seek (n, xncs) | 641 | SgiDatatypeImp (_, n, _, _, _, xs, xncs) => seek (n, xs, xncs) |
613 | _ => NONE) sgis of | 642 | _ => NONE) sgis of |
614 NONE => NONE | 643 NONE => NONE |
615 | SOME (c, subs) => SOME (sgnSubCon (str, subs) c) | 644 | SOME (c, subs) => SOME (sgnSubCon (str, subs) c) |
616 end | 645 end |
617 | SgnError => SOME (CError, ErrorMsg.dummySpan) | 646 | SgnError => SOME (CError, ErrorMsg.dummySpan) |
630 in | 659 in |
631 seek (sgis, sgns, strs, cons, (sub c1, sub c2) :: acc) | 660 seek (sgis, sgns, strs, cons, (sub c1, sub c2) :: acc) |
632 end | 661 end |
633 | SgiConAbs (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) | 662 | SgiConAbs (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) |
634 | SgiCon (x, n, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) | 663 | SgiCon (x, n, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) |
635 | SgiDatatype (x, n, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) | 664 | SgiDatatype (x, n, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) |
636 | SgiDatatypeImp (x, n, _, _, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) | 665 | SgiDatatypeImp (x, n, _, _, _, _, _) => seek (sgis, sgns, strs, IM.insert (cons, n, x), acc) |
637 | SgiVal _ => seek (sgis, sgns, strs, cons, acc) | 666 | SgiVal _ => seek (sgis, sgns, strs, cons, acc) |
638 | SgiSgn (x, n, _) => seek (sgis, IM.insert (sgns, n, x), strs, cons, acc) | 667 | SgiSgn (x, n, _) => seek (sgis, IM.insert (sgns, n, x), strs, cons, acc) |
639 | SgiStr (x, n, _) => seek (sgis, sgns, IM.insert (strs, n, x), cons, acc) | 668 | SgiStr (x, n, _) => seek (sgis, sgns, IM.insert (strs, n, x), cons, acc) |
640 in | 669 in |
641 seek (sgis, IM.empty, IM.empty, IM.empty, []) | 670 seek (sgis, IM.empty, IM.empty, IM.empty, []) |
648 | _ => NONE | 677 | _ => NONE |
649 | 678 |
650 fun declBinds env (d, loc) = | 679 fun declBinds env (d, loc) = |
651 case d of | 680 case d of |
652 DCon (x, n, k, c) => pushCNamedAs env x n k (SOME c) | 681 DCon (x, n, k, c) => pushCNamedAs env x n k (SOME c) |
653 | DDatatype (x, n, xncs) => | 682 | DDatatype (x, n, xs, xncs) => |
654 let | 683 let |
655 val env = pushCNamedAs env x n (KType, loc) NONE | 684 val env = pushCNamedAs env x n (KType, loc) NONE |
656 val env = pushDatatype env n xncs | 685 val env = pushDatatype env n xs xncs |
657 in | 686 in |
658 foldl (fn ((x', n', NONE), env) => pushENamedAs env x' n' (CNamed n, loc) | 687 foldl (fn ((x', n', to), env) => |
659 | ((x', n', SOME t), env) => pushENamedAs env x' n' (TFun (t, (CNamed n, loc)), loc)) | 688 let |
660 env xncs | 689 val t = |
690 case to of | |
691 NONE => (CNamed n, loc) | |
692 | SOME t => (TFun (t, (CNamed n, loc)), loc) | |
693 val k = (KType, loc) | |
694 val t = foldr (fn (x, t) => (TCFun (Explicit, x, k, t), loc)) t xs | |
695 in | |
696 pushENamedAs env x' n' t | |
697 end) | |
698 env xncs | |
661 end | 699 end |
662 | DDatatypeImp (x, n, m, ms, x', xncs) => | 700 | DDatatypeImp (x, n, m, ms, x', xs, xncs) => |
663 let | 701 let |
664 val t = (CModProj (m, ms, x'), loc) | 702 val t = (CModProj (m, ms, x'), loc) |
665 val env = pushCNamedAs env x n (KType, loc) (SOME t) | 703 val env = pushCNamedAs env x n (KType, loc) (SOME t) |
666 val env = pushDatatype env n xncs | 704 val env = pushDatatype env n xs xncs |
667 | 705 |
668 val t = (CNamed n, loc) | 706 val t = (CNamed n, loc) |
669 in | 707 in |
670 foldl (fn ((x', n', NONE), env) => pushENamedAs env x' n' t | 708 foldl (fn ((x', n', to), env) => |
671 | ((x', n', SOME t'), env) => pushENamedAs env x' n' (TFun (t', t), loc)) | 709 let |
672 env xncs | 710 val t = |
711 case to of | |
712 NONE => (CNamed n, loc) | |
713 | SOME t => (TFun (t, (CNamed n, loc)), loc) | |
714 val k = (KType, loc) | |
715 val t = foldr (fn (x, t) => (TCFun (Explicit, x, k, t), loc)) t xs | |
716 in | |
717 pushENamedAs env x' n' t | |
718 end) | |
719 env xncs | |
673 end | 720 end |
674 | DVal (x, n, t, _) => pushENamedAs env x n t | 721 | DVal (x, n, t, _) => pushENamedAs env x n t |
675 | DValRec vis => foldl (fn ((x, n, t, _), env) => pushENamedAs env x n t) env vis | 722 | DValRec vis => foldl (fn ((x, n, t, _), env) => pushENamedAs env x n t) env vis |
676 | DSgn (x, n, sgn) => pushSgnNamedAs env x n sgn | 723 | DSgn (x, n, sgn) => pushSgnNamedAs env x n sgn |
677 | DStr (x, n, sgn, _) => pushStrNamedAs env x n sgn | 724 | DStr (x, n, sgn, _) => pushStrNamedAs env x n sgn |