comparison src/elaborate.sml @ 174:7ee424760d2f

Elaborating module constructor patterns; parsing record patterns
author Adam Chlipala <adamc@hcoop.net>
date Thu, 31 Jul 2008 11:28:55 -0400
parents 8221b95cc24c
children b2d752455182
comparison
equal deleted inserted replaced
173:8221b95cc24c 174:7ee424760d2f
810 | Unif of string * L'.con 810 | Unif of string * L'.con
811 | WrongForm of string * L'.exp * L'.con 811 | WrongForm of string * L'.exp * L'.con
812 | IncompatibleCons of L'.con * L'.con 812 | IncompatibleCons of L'.con * L'.con
813 | DuplicatePatternVariable of ErrorMsg.span * string 813 | DuplicatePatternVariable of ErrorMsg.span * string
814 | PatUnify of L'.pat * L'.con * L'.con * cunify_error 814 | PatUnify of L'.pat * L'.con * L'.con * cunify_error
815 | UnboundConstructor of ErrorMsg.span * string 815 | UnboundConstructor of ErrorMsg.span * string list * string
816 | PatHasArg of ErrorMsg.span 816 | PatHasArg of ErrorMsg.span
817 | PatHasNoArg of ErrorMsg.span 817 | PatHasNoArg of ErrorMsg.span
818 | Inexhaustive of ErrorMsg.span 818 | Inexhaustive of ErrorMsg.span
819 819
820 fun expError env err = 820 fun expError env err =
846 (ErrorMsg.errorAt (#2 p) "Unification failure for pattern"; 846 (ErrorMsg.errorAt (#2 p) "Unification failure for pattern";
847 eprefaces' [("Pattern", p_pat env p), 847 eprefaces' [("Pattern", p_pat env p),
848 ("Have con", p_con env c1), 848 ("Have con", p_con env c1),
849 ("Need con", p_con env c2)]; 849 ("Need con", p_con env c2)];
850 cunifyError env uerr) 850 cunifyError env uerr)
851 | UnboundConstructor (loc, s) => 851 | UnboundConstructor (loc, ms, s) =>
852 ErrorMsg.errorAt loc ("Unbound constructor " ^ s ^ " in pattern") 852 ErrorMsg.errorAt loc ("Unbound constructor " ^ String.concatWith "." (ms @ [s]) ^ " in pattern")
853 | PatHasArg loc => 853 | PatHasArg loc =>
854 ErrorMsg.errorAt loc "Constructor expects no argument but is used with argument" 854 ErrorMsg.errorAt loc "Constructor expects no argument but is used with argument"
855 | PatHasNoArg loc => 855 | PatHasNoArg loc =>
856 ErrorMsg.errorAt loc "Constructor expects argument but is used with no argument" 856 ErrorMsg.errorAt loc "Constructor expects argument but is used with no argument"
857 | Inexhaustive loc => 857 | Inexhaustive loc =>
956 end 956 end
957 in 957 in
958 unravel (t, e) 958 unravel (t, e)
959 end 959 end
960 960
961 fun elabPat (pAll as (p, loc), (env, bound)) = 961 fun elabPat (pAll as (p, loc), (env, denv, bound)) =
962 let 962 let
963 val perror = (L'.PWild, loc) 963 val perror = (L'.PWild, loc)
964 val terror = (L'.CError, loc) 964 val terror = (L'.CError, loc)
965 val pterror = (perror, terror) 965 val pterror = (perror, terror)
966 val rerror = (pterror, (env, bound)) 966 val rerror = (pterror, (env, bound))
970 case (po, to) of 970 case (po, to) of
971 (NONE, SOME _) => (expError env (PatHasNoArg loc); 971 (NONE, SOME _) => (expError env (PatHasNoArg loc);
972 rerror) 972 rerror)
973 | (SOME _, NONE) => (expError env (PatHasArg loc); 973 | (SOME _, NONE) => (expError env (PatHasArg loc);
974 rerror) 974 rerror)
975 | (NONE, NONE) => (((L'.PCon (pc, NONE), loc), (L'.CNamed dn, loc)), 975 | (NONE, NONE) => (((L'.PCon (pc, NONE), loc), dn),
976 (env, bound)) 976 (env, bound))
977 | (SOME p, SOME t) => 977 | (SOME p, SOME t) =>
978 let 978 let
979 val ((p', pt), (env, bound)) = elabPat (p, (env, bound)) 979 val ((p', pt), (env, bound)) = elabPat (p, (env, denv, bound))
980 in 980 in
981 (((L'.PCon (pc, SOME p'), loc), (L'.CNamed dn, loc)), 981 (((L'.PCon (pc, SOME p'), loc), dn),
982 (env, bound)) 982 (env, bound))
983 end 983 end
984 in 984 in
985 case p of 985 case p of
986 L.PWild => (((L'.PWild, loc), cunif (loc, (L'.KType, loc))), 986 L.PWild => (((L'.PWild, loc), cunif (loc, (L'.KType, loc))),
998 end 998 end
999 | L.PPrim p => (((L'.PPrim p, loc), primType env p), 999 | L.PPrim p => (((L'.PPrim p, loc), primType env p),
1000 (env, bound)) 1000 (env, bound))
1001 | L.PCon ([], x, po) => 1001 | L.PCon ([], x, po) =>
1002 (case E.lookupConstructor env x of 1002 (case E.lookupConstructor env x of
1003 NONE => (expError env (UnboundConstructor (loc, x)); 1003 NONE => (expError env (UnboundConstructor (loc, [], x));
1004 rerror) 1004 rerror)
1005 | SOME (n, to, dn) => pcon (L'.PConVar n, po, to, dn)) 1005 | SOME (n, to, dn) => pcon (L'.PConVar n, po, to, (L'.CNamed dn, loc)))
1006 | L.PCon _ => raise Fail "uhoh" 1006 | L.PCon (m1 :: ms, x, po) =>
1007 (case E.lookupStr env m1 of
1008 NONE => (expError env (UnboundStrInExp (loc, m1));
1009 rerror)
1010 | SOME (n, sgn) =>
1011 let
1012 val (str, sgn) = foldl (fn (m, (str, sgn)) =>
1013 case E.projectStr env {sgn = sgn, str = str, field = m} of
1014 NONE => raise Fail "typeof: Unknown substructure"
1015 | SOME sgn => ((L'.StrProj (str, m), loc), sgn))
1016 ((L'.StrVar n, loc), sgn) ms
1017 in
1018 case E.projectConstructor env {str = str, sgn = sgn, field = x} of
1019 NONE => (expError env (UnboundConstructor (loc, m1 :: ms, x));
1020 rerror)
1021 | SOME (_, to, dn) => pcon (L'.PConProj (n, ms, x), po, to, dn)
1022 end)
1023
1024 | L.PRecord _ => raise Fail "Elaborate PRecord"
1007 end 1025 end
1008 1026
1009 datatype coverage = 1027 datatype coverage =
1010 Wild 1028 Wild
1011 | None 1029 | None
1014 fun exhaustive (env, denv, t, ps) = 1032 fun exhaustive (env, denv, t, ps) =
1015 let 1033 let
1016 fun pcCoverage pc = 1034 fun pcCoverage pc =
1017 case pc of 1035 case pc of
1018 L'.PConVar n => n 1036 L'.PConVar n => n
1019 | _ => raise Fail "uh oh^2" 1037 | L'.PConProj (m1, ms, x) =>
1038 let
1039 val (str, sgn) = E.chaseMpath env (m1, ms)
1040 in
1041 case E.projectConstructor env {str = str, sgn = sgn, field = x} of
1042 NONE => raise Fail "exhaustive: Can't project constructor"
1043 | SOME (n, _, _) => n
1044 end
1020 1045
1021 fun coverage (p, _) = 1046 fun coverage (p, _) =
1022 case p of 1047 case p of
1023 L'.PWild => Wild 1048 L'.PWild => Wild
1024 | L'.PVar _ => Wild 1049 | L'.PVar _ => Wild
1047 None => (false, []) 1072 None => (false, [])
1048 | Wild => (true, []) 1073 | Wild => (true, [])
1049 | Datatype cm => 1074 | Datatype cm =>
1050 let 1075 let
1051 val ((t, _), gs) = hnormCon (env, denv) t 1076 val ((t, _), gs) = hnormCon (env, denv) t
1077
1078 fun dtype cons =
1079 foldl (fn ((_, n, to), (total, gs)) =>
1080 case IM.find (cm, n) of
1081 NONE => (false, gs)
1082 | SOME c' =>
1083 case to of
1084 NONE => (total, gs)
1085 | SOME t' =>
1086 let
1087 val (total, gs') = isTotal (c', t')
1088 in
1089 (total, gs' @ gs)
1090 end)
1091 (true, gs) cons
1052 in 1092 in
1053 case t of 1093 case t of
1054 L'.CNamed n => 1094 L'.CNamed n =>
1055 let 1095 let
1056 val dt = E.lookupDatatype env n 1096 val dt = E.lookupDatatype env n
1057 val cons = E.constructors dt 1097 val cons = E.constructors dt
1058 in 1098 in
1059 foldl (fn ((_, n, to), (total, gs)) => 1099 dtype cons
1060 case IM.find (cm, n) of 1100 end
1061 NONE => (false, gs) 1101 | L'.CModProj (m1, ms, x) =>
1062 | SOME c' => 1102 let
1063 case to of 1103 val (str, sgn) = E.chaseMpath env (m1, ms)
1064 NONE => (total, gs) 1104 in
1065 | SOME t' => 1105 case E.projectDatatype env {str = str, sgn = sgn, field = x} of
1066 let 1106 NONE => raise Fail "isTotal: Can't project datatype"
1067 val (total, gs') = isTotal (c', t') 1107 | SOME cons => dtype cons
1068 in
1069 (total, gs' @ gs)
1070 end)
1071 (true, gs) cons
1072 end 1108 end
1073 | L'.CError => (true, gs) 1109 | L'.CError => (true, gs)
1074 | _ => raise Fail "isTotal: Not a datatype" 1110 | _ => raise Fail "isTotal: Not a datatype"
1075 end 1111 end
1076 in 1112 in
1293 val (e', et, gs1) = elabExp (env, denv) e 1329 val (e', et, gs1) = elabExp (env, denv) e
1294 val result = cunif (loc, (L'.KType, loc)) 1330 val result = cunif (loc, (L'.KType, loc))
1295 val (pes', gs) = ListUtil.foldlMap 1331 val (pes', gs) = ListUtil.foldlMap
1296 (fn ((p, e), gs) => 1332 (fn ((p, e), gs) =>
1297 let 1333 let
1298 val ((p', pt), (env, _)) = elabPat (p, (env, SS.empty)) 1334 val ((p', pt), (env, _)) = elabPat (p, (env, denv, SS.empty))
1299 1335
1300 val gs1 = checkPatCon (env, denv) p' pt et 1336 val gs1 = checkPatCon (env, denv) p' pt et
1301 val (e', et, gs2) = elabExp (env, denv) e 1337 val (e', et, gs2) = elabExp (env, denv) e
1302 val gs3 = checkCon (env, denv) e' et result 1338 val gs3 = checkCon (env, denv) e' et result
1303 in 1339 in