comparison src/elaborate.sml @ 147:eb16f2aadbe9

Meta-programming forms
author Adam Chlipala <adamc@hcoop.net>
date Tue, 22 Jul 2008 18:46:04 -0400
parents 80ac94b54e41
children 7420fa18d657
comparison
equal deleted inserted replaced
146:80ac94b54e41 147:eb16f2aadbe9
467 | CExplicitness (c1, c2) => 467 | CExplicitness (c1, c2) =>
468 eprefaces "Differing constructor function explicitness" 468 eprefaces "Differing constructor function explicitness"
469 [("Con 1", p_con env c1), 469 [("Con 1", p_con env c1),
470 ("Con 2", p_con env c2)] 470 ("Con 2", p_con env c2)]
471 | CKindof (k, c) => 471 | CKindof (k, c) =>
472 eprefaces "Kind unification variable blocks kindof calculation" 472 eprefaces "Unexpected kind for kindof calculation"
473 [("Kind", p_kind k), 473 [("Kind", p_kind k),
474 ("Con", p_con env c)] 474 ("Con", p_con env c)]
475 | CRecordFailure => 475 | CRecordFailure =>
476 eprefaces "Can't unify record constructors" [] 476 eprefaces "Can't unify record constructors" []
477 477
548 val hnormCon = D.hnormCon 548 val hnormCon = D.hnormCon
549 549
550 fun unifyRecordCons (env, denv) (c1, c2) = 550 fun unifyRecordCons (env, denv) (c1, c2) =
551 let 551 let
552 fun rkindof c = 552 fun rkindof c =
553 case kindof env c of 553 case hnormKind (kindof env c) of
554 (L'.KRecord k, _) => k 554 (L'.KRecord k, _) => k
555 | (L'.KError, _) => kerror 555 | (L'.KError, _) => kerror
556 | k => raise CUnify' (CKindof (k, c)) 556 | k => raise CUnify' (CKindof (k, c))
557 557
558 val k1 = rkindof c1 558 val k1 = rkindof c1
871 | L'.EModProj (n, ms, x) => 871 | L'.EModProj (n, ms, x) =>
872 let 872 let
873 val (_, sgn) = E.lookupStrNamed env n 873 val (_, sgn) = E.lookupStrNamed env n
874 val (str, sgn) = foldl (fn (m, (str, sgn)) => 874 val (str, sgn) = foldl (fn (m, (str, sgn)) =>
875 case E.projectStr env {sgn = sgn, str = str, field = m} of 875 case E.projectStr env {sgn = sgn, str = str, field = m} of
876 NONE => raise Fail "kindof: Unknown substructure" 876 NONE => raise Fail "typeof: Unknown substructure"
877 | SOME sgn => ((L'.StrProj (str, m), loc), sgn)) 877 | SOME sgn => ((L'.StrProj (str, m), loc), sgn))
878 ((L'.StrVar n, loc), sgn) ms 878 ((L'.StrVar n, loc), sgn) ms
879 in 879 in
880 case E.projectVal env {sgn = sgn, str = str, field = x} of 880 case E.projectVal env {sgn = sgn, str = str, field = x} of
881 NONE => raise Fail "typeof: Unknown val in structure" 881 NONE => raise Fail "typeof: Unknown val in structure"
963 cerror) 963 cerror)
964 | SOME t => t 964 | SOME t => t
965 in 965 in
966 ((L'.EModProj (n, ms, s), loc), t, []) 966 ((L'.EModProj (n, ms, s), loc), t, [])
967 end) 967 end)
968
969 (*| L.EApp (arg as ((L.EApp ((L.ECApp ((L.EVar (["Basis"], "join"), _), (L.CWild _, _)), _), xml1), _), xml2)) =>
970 let
971 val (xml1', t1, gs1) = elabExp (env, denv) xml1
972 val (xml2', t2, gs2) = elabExp (env, denv) xml2
973
974 val kunit = (L'.KUnit, loc)
975 val k = (L'.KRecord kunit, loc)
976 val kt = (L'.KRecord (L'.KType, loc), loc)
977
978 val basis =
979 case E.lookupStr env "Basis" of
980 NONE => raise Fail "elabExp: Unbound Basis"
981 | SOME (n, _) => n
982
983 fun xml () =
984 let
985 val ns = cunif (loc, k)
986 val use = cunif (loc, kt)
987 val bind = cunif (loc, kt)
988
989 val t = (L'.CModProj (basis, [], "xml"), loc)
990 val t = (L'.CApp (t, ns), loc)
991 val t = (L'.CApp (t, use), loc)
992 val t = (L'.CApp (t, bind), loc)
993 in
994 (ns, use, bind, t)
995 end
996
997 val (ns1, use1, bind1, c1) = xml ()
998 val (ns2, use2, bind2, c2) = xml ()
999
1000 val gs3 = checkCon (env, denv) xml1' t1 c1
1001 val gs4 = checkCon (env, denv) xml2' t2 c2
1002
1003 val (ns1, gs5) = hnormCon (env, denv) ns1
1004 val (ns2, gs6) = hnormCon (env, denv) ns2
1005
1006 val cemp = (L'.CRecord (kunit, []), loc)
1007
1008 val (shared, ctx1, ctx2) =
1009 case (#1 ns1, #1 ns2) of
1010 (L'.CRecord (_, ns1), L'.CRecord (_, ns2)) =>
1011 let
1012 val ns = List.filter (fn ((nm, _), _) =>
1013 case nm of
1014 L'.CName s =>
1015 List.exists (fn ((L'.CName s', _), _) => s' = s
1016 | _ => false) ns2
1017 | _ => false) ns1
1018 in
1019 ((L'.CRecord (kunit, ns), loc), cunif (loc, k), cunif (loc, k))
1020 end
1021 | (_, L'.CRecord _) => (ns2, cemp, cemp)
1022 | _ => (ns1, cemp, cemp)
1023
1024 val ns1' = (L'.CConcat (shared, ctx1), loc)
1025 val ns2' = (L'.CConcat (shared, ctx2), loc)
1026
1027 val e = (L'.EModProj (basis, [], "join"), loc)
1028 val e = (L'.ECApp (e, shared), loc)
1029 val e = (L'.ECApp (e, ctx1), loc)
1030 val e = (L'.ECApp (e, ctx2), loc)
1031 val e = (L'.ECApp (e, use1), loc)
1032 val e = (L'.ECApp (e, use2), loc)
1033 val e = (L'.ECApp (e, bind1), loc)
1034 val e = (L'.ECApp (e, bind2), loc)
1035 val e = (L'.EApp (e, xml1'), loc)
1036 val e = (L'.EApp (e, xml2'), loc)
1037
1038 val t = (L'.CModProj (basis, [], "xml"), loc)
1039 val t = (L'.CApp (t, shared), loc)
1040 val t = (L'.CApp (t, (L'.CConcat (use1, use2), loc)), loc)
1041 val t = (L'.CApp (t, (L'.CConcat (bind1, bind2), loc)), loc)
1042
1043 fun doUnify (ns, ns') =
1044 let
1045 fun setEmpty c =
1046 let
1047 val ((c, _), gs) = hnormCon (env, denv) c
1048 in
1049 case c of
1050 L'.CUnif (_, _, _, r) =>
1051 (r := SOME cemp;
1052 gs)
1053 | L'.CConcat (_, c') => setEmpty c' @ gs
1054 | _ => gs
1055 end
1056
1057 val gs1 = unifyCons (env, denv) ns ns'
1058 val gs2 = setEmpty ns'
1059 val gs3 = unifyCons (env, denv) ns ns'
1060 in
1061 gs1 @ gs2 @ gs3
1062 end handle CUnify _ => (expError env (IncompatibleCons (ns, ns'));
1063 [])
1064
1065 val gs7 = doUnify (ns1, ns1')
1066 val gs8 = doUnify (ns2, ns2')
1067 in
1068 (e, t, (loc, env, denv, shared, ctx1)
1069 :: (loc, env, denv, shared, ctx2)
1070 :: (loc, env, denv, use1, use2)
1071 :: (loc, env, denv, bind1, bind2)
1072 :: gs1 @ gs2 @ gs3 @ gs4 @ gs5 @ gs6 @ gs7 @ gs8)
1073 end*)
1074 968
1075 | L.EApp (e1, e2) => 969 | L.EApp (e1, e2) =>
1076 let 970 let
1077 val (e1', t1, gs1) = elabExp (env, denv) e1 971 val (e1', t1, gs1) = elabExp (env, denv) e1
1078 val (e1', t1, gs2) = elabHead (env, denv) e1' t1 972 val (e1', t1, gs2) = elabHead (env, denv) e1' t1