comparison src/elaborate.sml @ 31:1c91c5e6840f

Simple signature matching
author Adam Chlipala <adamc@hcoop.net>
date Thu, 12 Jun 2008 17:16:20 -0400
parents e6ccf961d8a3
children 0ff8c2728634
comparison
equal deleted inserted replaced
30:e6ccf961d8a3 31:1c91c5e6840f
133 val ktype_record = (L'.KRecord ktype, dummy) 133 val ktype_record = (L'.KRecord ktype, dummy)
134 134
135 val cerror = (L'.CError, dummy) 135 val cerror = (L'.CError, dummy)
136 val kerror = (L'.KError, dummy) 136 val kerror = (L'.KError, dummy)
137 val eerror = (L'.EError, dummy) 137 val eerror = (L'.EError, dummy)
138 val sgnerror = (L'.SgnError, dummy)
139 val strerror = (L'.StrError, dummy)
138 140
139 local 141 local
140 val count = ref 0 142 val count = ref 0
141 in 143 in
142 144
862 eprefaces' [("Constructor", p_con env c)]) 864 eprefaces' [("Constructor", p_con env c)])
863 | CunifsRemainExp (loc, e) => 865 | CunifsRemainExp (loc, e) =>
864 (ErrorMsg.errorAt loc "Some constructor unification variables are undetermined in expression"; 866 (ErrorMsg.errorAt loc "Some constructor unification variables are undetermined in expression";
865 eprefaces' [("Expression", p_exp env e)]) 867 eprefaces' [("Expression", p_exp env e)])
866 868
867 fun elabDecl env (d, loc) = 869 datatype sgn_error =
870 UnboundSgn of ErrorMsg.span * string
871 | UnmatchedSgi of L'.sgn_item
872 | SgiWrongKind of L'.sgn_item * L'.kind * L'.sgn_item * L'.kind * kunify_error
873 | SgiWrongCon of L'.sgn_item * L'.con * L'.sgn_item * L'.con * cunify_error
874
875 fun sgnError env err =
876 case err of
877 UnboundSgn (loc, s) =>
878 ErrorMsg.errorAt loc ("Unbound signature variable " ^ s)
879 | UnmatchedSgi (sgi as (_, loc)) =>
880 (ErrorMsg.errorAt loc "Unmatched signature item";
881 eprefaces' [("Item", p_sgn_item env sgi)])
882 | SgiWrongKind (sgi1, k1, sgi2, k2, kerr) =>
883 (ErrorMsg.errorAt (#2 sgi1) "Kind unification failure in signature matching:";
884 eprefaces' [("Item 1", p_sgn_item env sgi1),
885 ("Item 2", p_sgn_item env sgi2),
886 ("Kind 1", p_kind k1),
887 ("Kind 2", p_kind k2)];
888 kunifyError kerr)
889 | SgiWrongCon (sgi1, c1, sgi2, c2, cerr) =>
890 (ErrorMsg.errorAt (#2 sgi1) "Constructor unification failure in signature matching:";
891 eprefaces' [("Item 1", p_sgn_item env sgi1),
892 ("Item 2", p_sgn_item env sgi2),
893 ("Con 1", p_con env c1),
894 ("Con 2", p_con env c2)];
895 cunifyError env cerr)
896
897 datatype str_error =
898 UnboundStr of ErrorMsg.span * string
899
900 fun strError env err =
901 case err of
902 UnboundStr (loc, s) =>
903 ErrorMsg.errorAt loc ("Unbound structure variable " ^ s)
904
905
906 fun elabSgn_item ((sgi, loc), env) =
907 let
908
909 in
910 resetKunif ();
911 resetCunif ();
912 case sgi of
913 L.SgiConAbs (x, k) =>
914 let
915 val k' = elabKind k
916
917 val (env', n) = E.pushCNamed env x k' NONE
918 in
919 if ErrorMsg.anyErrors () then
920 ()
921 else (
922 if kunifsInKind k' then
923 declError env (KunifsRemainKind (loc, k'))
924 else
925 ()
926 );
927
928 ((L'.SgiConAbs (x, n, k'), loc), env')
929 end
930
931 | L.SgiCon (x, ko, c) =>
932 let
933 val k' = case ko of
934 NONE => kunif ()
935 | SOME k => elabKind k
936
937 val (c', ck) = elabCon env c
938 val (env', n) = E.pushCNamed env x k' (SOME c')
939 in
940 checkKind env c' ck k';
941
942 if ErrorMsg.anyErrors () then
943 ()
944 else (
945 if kunifsInKind k' then
946 declError env (KunifsRemainKind (loc, k'))
947 else
948 ();
949
950 if kunifsInCon c' then
951 declError env (KunifsRemainCon (loc, c'))
952 else
953 ()
954 );
955
956 ((L'.SgiCon (x, n, k', c'), loc), env')
957 end
958
959 | L.SgiVal (x, c) =>
960 let
961 val (c', ck) = elabCon env c
962
963 val (env', n) = E.pushENamed env x c'
964 in
965 unifyKinds ck ktype;
966
967 if ErrorMsg.anyErrors () then
968 ()
969 else (
970 if kunifsInCon c' then
971 declError env (KunifsRemainCon (loc, c'))
972 else
973 ()
974 );
975
976 ((L'.SgiVal (x, n, c'), loc), env')
977 end
978
979 | L.SgiStr (x, sgn) =>
980 let
981 val sgn' = elabSgn env sgn
982 val (env', n) = E.pushStrNamed env x sgn'
983 in
984 ((L'.SgiStr (x, n, sgn'), loc), env')
985 end
986
987 end
988
989 and elabSgn env (sgn, loc) =
990 case sgn of
991 L.SgnConst sgis =>
992 let
993 val (sgis', _) = ListUtil.foldlMap elabSgn_item env sgis
994 in
995 (L'.SgnConst sgis', loc)
996 end
997 | L.SgnVar x =>
998 (case E.lookupSgn env x of
999 NONE =>
1000 (sgnError env (UnboundSgn (loc, x));
1001 (L'.SgnError, loc))
1002 | SOME (n, sgis) => (L'.SgnVar n, loc))
1003
1004 fun sgiOfDecl (d, loc) =
1005 case d of
1006 L'.DCon (x, n, k, c) => SOME (L'.SgiCon (x, n, k, c), loc)
1007 | L'.DVal (x, n, t, _) => SOME (L'.SgiVal (x, n, t), loc)
1008 | L'.DSgn _ => NONE
1009 | L'.DStr (x, n, sgn, _) => SOME (L'.SgiStr (x, n, sgn), loc)
1010
1011 fun subSgn env (all1 as (sgn1, _)) (all2 as (sgn2, loc2)) =
1012 case (sgn1, sgn2) of
1013 (L'.SgnError, _) => ()
1014 | (_, L'.SgnError) => ()
1015
1016 | (L'.SgnVar n, _) =>
1017 subSgn env (#2 (E.lookupSgnNamed env n)) all2
1018 | (_, L'.SgnVar n) =>
1019 subSgn env all1 (#2 (E.lookupSgnNamed env n))
1020
1021 | (L'.SgnConst sgis1, L'.SgnConst sgis2) =>
1022 let
1023 fun folder (sgi2All as (sgi, _), env) =
1024 let
1025 fun seek p =
1026 let
1027 fun seek env ls =
1028 case ls of
1029 [] => (sgnError env (UnmatchedSgi sgi2All);
1030 env)
1031 | h :: t =>
1032 case p h of
1033 NONE => seek (E.sgiBinds env h) t
1034 | SOME env => env
1035 in
1036 seek env sgis1
1037 end
1038 in
1039 case sgi of
1040 L'.SgiConAbs (x, n2, k2) =>
1041 seek (fn sgi1All as (sgi1, _) =>
1042 let
1043 fun found (x, n1, k1, co1) =
1044 let
1045 val () = unifyKinds k1 k2
1046 handle KUnify (k1, k2, err) =>
1047 sgnError env (SgiWrongKind (sgi1All, k1, sgi2All, k2, err))
1048 val env = E.pushCNamedAs env x n1 k1 co1
1049 in
1050 SOME (if n1 = n2 then
1051 env
1052 else
1053 E.pushCNamedAs env x n2 k2 (SOME (L'.CNamed n1, loc2)))
1054 end
1055 in
1056 case sgi1 of
1057 L'.SgiConAbs (x, n1, k1) => found (x, n1, k1, NONE)
1058 | L'.SgiCon (x, n1, k1, c1) => found (x, n1, k1, SOME c1)
1059 | _ => NONE
1060 end)
1061
1062 | L'.SgiCon (x, n2, k2, c2) =>
1063 seek (fn sgi1All as (sgi1, _) =>
1064 case sgi1 of
1065 L'.SgiCon (x, n1, k1, c1) =>
1066 let
1067 val () = unifyCons env c1 c2
1068 handle CUnify (c1, c2, err) =>
1069 sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err))
1070 in
1071 SOME (E.pushCNamedAs env x n2 k2 (SOME c2))
1072 end
1073 | _ => NONE)
1074
1075 | _ => raise Fail "Not ready for more sig matching"
1076 end
1077 in
1078 ignore (foldl folder env sgis2)
1079 end
1080
1081
1082 fun elabDecl ((d, loc), env) =
868 let 1083 let
869 1084
870 in 1085 in
871 resetKunif (); 1086 resetKunif ();
872 resetCunif (); 1087 resetCunif ();
894 declError env (KunifsRemainCon (loc, c')) 1109 declError env (KunifsRemainCon (loc, c'))
895 else 1110 else
896 () 1111 ()
897 ); 1112 );
898 1113
899 (env', 1114 ((L'.DCon (x, n, k', c'), loc), env')
900 (L'.DCon (x, n, k', c'), loc))
901 end 1115 end
902 | L.DVal (x, co, e) => 1116 | L.DVal (x, co, e) =>
903 let 1117 let
904 val (c', ck) = case co of 1118 val (c', ck) = case co of
905 NONE => (cunif ktype, ktype) 1119 NONE => (cunif ktype, ktype)
931 if cunifsInExp e' then 1145 if cunifsInExp e' then
932 declError env (CunifsRemainExp (loc, e')) 1146 declError env (CunifsRemainExp (loc, e'))
933 else 1147 else
934 ()); 1148 ());
935 1149
936 (env', 1150 ((L'.DVal (x, n, c', e'), loc), env')
937 (L'.DVal (x, n, c', e'), loc))
938 end 1151 end
939 1152
940 | L.DSgn _ => raise Fail "Not ready to elaborate signature" 1153 | L.DSgn (x, sgn) =>
941 | L.DStr _ => raise Fail "Not ready to elaborate structure" 1154 let
1155 val sgn' = elabSgn env sgn
1156 val (env', n) = E.pushSgnNamed env x sgn'
1157 in
1158 ((L'.DSgn (x, n, sgn'), loc), env')
1159 end
1160
1161 | L.DStr (x, sgno, str) =>
1162 let
1163 val formal = Option.map (elabSgn env) sgno
1164 val (str', actual) = elabStr env str
1165
1166 val sgn' = case formal of
1167 NONE => actual
1168 | SOME formal =>
1169 (subSgn env actual formal;
1170 formal)
1171
1172 val (env', n) = E.pushStrNamed env x sgn'
1173 in
1174 ((L'.DStr (x, n, sgn', str'), loc), env')
1175 end
942 end 1176 end
943 1177
944 fun elabFile env ds = 1178 and elabStr env (str, loc) =
945 ListUtil.mapfoldl (fn (d, env) => elabDecl env d) env ds 1179 case str of
1180 L.StrConst ds =>
1181 let
1182 val (ds', env') = ListUtil.foldlMap elabDecl env ds
1183 val sgis = List.mapPartial sgiOfDecl ds'
1184 in
1185 ((L'.StrConst ds', loc), (L'.SgnConst sgis, loc))
1186 end
1187 | L.StrVar x =>
1188 (case E.lookupStr env x of
1189 NONE =>
1190 (strError env (UnboundStr (loc, x));
1191 (strerror, sgnerror))
1192 | SOME (n, sgn) => ((L'.StrVar n, loc), sgn))
1193
1194 val elabFile = ListUtil.foldlMap elabDecl
946 1195
947 end 1196 end