comparison src/elaborate.sml @ 171:c7a6e6dbc318

Elaborating some basic pattern matching
author Adam Chlipala <adamc@hcoop.net>
date Thu, 31 Jul 2008 10:06:27 -0400
parents a158f8c5aa55
children 021f5beb6f8d
comparison
equal deleted inserted replaced
170:a158f8c5aa55 171:c7a6e6dbc318
807 | UnboundStrInExp of ErrorMsg.span * string 807 | UnboundStrInExp of ErrorMsg.span * string
808 | Unify of L'.exp * L'.con * L'.con * cunify_error 808 | Unify of L'.exp * L'.con * L'.con * cunify_error
809 | Unif of string * L'.con 809 | Unif of string * L'.con
810 | WrongForm of string * L'.exp * L'.con 810 | WrongForm of string * L'.exp * L'.con
811 | IncompatibleCons of L'.con * L'.con 811 | IncompatibleCons of L'.con * L'.con
812 | DuplicatePatternVariable of ErrorMsg.span * string
813 | PatUnify of L'.pat * L'.con * L'.con * cunify_error
814 | UnboundConstructor of ErrorMsg.span * string
815 | PatHasArg of ErrorMsg.span
816 | PatHasNoArg of ErrorMsg.span
812 817
813 fun expError env err = 818 fun expError env err =
814 case err of 819 case err of
815 UnboundExp (loc, s) => 820 UnboundExp (loc, s) =>
816 ErrorMsg.errorAt loc ("Unbound expression variable " ^ s) 821 ErrorMsg.errorAt loc ("Unbound expression variable " ^ s)
831 ("Type", p_con env t)]) 836 ("Type", p_con env t)])
832 | IncompatibleCons (c1, c2) => 837 | IncompatibleCons (c1, c2) =>
833 (ErrorMsg.errorAt (#2 c1) "Incompatible constructors"; 838 (ErrorMsg.errorAt (#2 c1) "Incompatible constructors";
834 eprefaces' [("Con 1", p_con env c1), 839 eprefaces' [("Con 1", p_con env c1),
835 ("Con 2", p_con env c2)]) 840 ("Con 2", p_con env c2)])
841 | DuplicatePatternVariable (loc, s) =>
842 ErrorMsg.errorAt loc ("Duplicate pattern variable " ^ s)
843 | PatUnify (p, c1, c2, uerr) =>
844 (ErrorMsg.errorAt (#2 p) "Unification failure for pattern";
845 eprefaces' [("Pattern", p_pat env p),
846 ("Have con", p_con env c1),
847 ("Need con", p_con env c2)];
848 cunifyError env uerr)
849 | UnboundConstructor (loc, s) =>
850 ErrorMsg.errorAt loc ("Unbound constructor " ^ s ^ " in pattern")
851 | PatHasArg loc =>
852 ErrorMsg.errorAt loc "Constructor expects no argument but is used with argument"
853 | PatHasNoArg loc =>
854 ErrorMsg.errorAt loc "Constructor expects argument but is used with no argument"
836 855
837 fun checkCon (env, denv) e c1 c2 = 856 fun checkCon (env, denv) e c1 c2 =
838 unifyCons (env, denv) c1 c2 857 unifyCons (env, denv) c1 c2
839 handle CUnify (c1, c2, err) => 858 handle CUnify (c1, c2, err) =>
840 (expError env (Unify (e, c1, c2, err)); 859 (expError env (Unify (e, c1, c2, err));
860 [])
861
862 fun checkPatCon (env, denv) p c1 c2 =
863 unifyCons (env, denv) c1 c2
864 handle CUnify (c1, c2, err) =>
865 (expError env (PatUnify (p, c1, c2, err));
841 []) 866 [])
842 867
843 fun primType env p = 868 fun primType env p =
844 case p of 869 case p of
845 P.Int _ => !int 870 P.Int _ => !int
901 | L'.ERecord xes => (L'.TRecord (L'.CRecord (ktype, map (fn (x, _, t) => (x, t)) xes), loc), loc) 926 | L'.ERecord xes => (L'.TRecord (L'.CRecord (ktype, map (fn (x, _, t) => (x, t)) xes), loc), loc)
902 | L'.EField (_, _, {field, ...}) => field 927 | L'.EField (_, _, {field, ...}) => field
903 | L'.ECut (_, _, {rest, ...}) => (L'.TRecord rest, loc) 928 | L'.ECut (_, _, {rest, ...}) => (L'.TRecord rest, loc)
904 | L'.EFold dom => foldType (dom, loc) 929 | L'.EFold dom => foldType (dom, loc)
905 930
931 | L'.ECase (_, _, t) => t
932
906 | L'.EError => cerror 933 | L'.EError => cerror
907 934
908 fun elabHead (env, denv) (e as (_, loc)) t = 935 fun elabHead (env, denv) (e as (_, loc)) t =
909 let 936 let
910 fun unravel (t, e) = 937 fun unravel (t, e) =
923 end 950 end
924 | _ => (e, t, gs) 951 | _ => (e, t, gs)
925 end 952 end
926 in 953 in
927 unravel (t, e) 954 unravel (t, e)
955 end
956
957 fun elabPat (pAll as (p, loc), (env, bound)) =
958 let
959 val perror = (L'.PWild, loc)
960 val terror = (L'.CError, loc)
961 val pterror = (perror, terror)
962 val rerror = (pterror, (env, bound))
963
964 fun pcon (pc, po, to, dn) =
965
966 case (po, to) of
967 (NONE, SOME _) => (expError env (PatHasNoArg loc);
968 rerror)
969 | (SOME _, NONE) => (expError env (PatHasArg loc);
970 rerror)
971 | (NONE, NONE) => (((L'.PCon (pc, NONE), loc), (L'.CNamed dn, loc)),
972 (env, bound))
973 | (SOME p, SOME t) =>
974 let
975 val ((p', pt), (env, bound)) = elabPat (p, (env, bound))
976 in
977 (((L'.PCon (pc, SOME p'), loc), (L'.CNamed dn, loc)),
978 (env, bound))
979 end
980 in
981 case p of
982 L.PWild => (((L'.PWild, loc), cunif (loc, (L'.KType, loc))),
983 (env, bound))
984 | L.PVar x =>
985 let
986 val t = if SS.member (bound, x) then
987 (expError env (DuplicatePatternVariable (loc, x));
988 terror)
989 else
990 cunif (loc, (L'.KType, loc))
991 in
992 (((L'.PVar x, loc), t),
993 (E.pushERel env x t, SS.add (bound, x)))
994 end
995 | L.PCon ([], x, po) =>
996 (case E.lookupConstructor env x of
997 NONE => (expError env (UnboundConstructor (loc, x));
998 rerror)
999 | SOME (n, to, dn) => pcon (L'.PConVar n, po, to, dn))
1000 | L.PCon _ => raise Fail "uhoh"
928 end 1001 end
929 1002
930 fun elabExp (env, denv) (eAll as (e, loc)) = 1003 fun elabExp (env, denv) (eAll as (e, loc)) =
931 let 1004 let
932 1005
1136 val dom = kunif loc 1209 val dom = kunif loc
1137 in 1210 in
1138 ((L'.EFold dom, loc), foldType (dom, loc), []) 1211 ((L'.EFold dom, loc), foldType (dom, loc), [])
1139 end 1212 end
1140 1213
1141 | L.ECase _ => raise Fail "Elaborate ECase" 1214 | L.ECase (e, pes) =>
1215 let
1216 val (e', et, gs1) = elabExp (env, denv) e
1217 val result = cunif (loc, (L'.KType, loc))
1218 val (pes', gs) = ListUtil.foldlMap
1219 (fn ((p, e), gs) =>
1220 let
1221 val ((p', pt), (env, _)) = elabPat (p, (env, SS.empty))
1222
1223 val gs1 = checkPatCon (env, denv) p' pt et
1224 val (e', et, gs2) = elabExp (env, denv) e
1225 val gs3 = checkCon (env, denv) e' et result
1226 in
1227 ((p', e'), gs1 @ gs2 @ gs3 @ gs)
1228 end)
1229 gs1 pes
1230 in
1231 ((L'.ECase (e', pes', result), loc), result, gs)
1232 end
1142 end 1233 end
1143 1234
1144 1235
1145 datatype decl_error = 1236 datatype decl_error =
1146 KunifsRemain of L'.decl list 1237 KunifsRemain of L'.decl list
1959 else 2050 else
1960 (); 2051 ();
1961 ((x, n', to), (SS.add (used, x), env, gs')) 2052 ((x, n', to), (SS.add (used, x), env, gs'))
1962 end) 2053 end)
1963 (SS.empty, env, []) xcs 2054 (SS.empty, env, []) xcs
2055
2056 val env = E.pushDatatype env n xcs
1964 in 2057 in
1965 ([(L'.DDatatype (x, n, xcs), loc)], (env, denv, gs)) 2058 ([(L'.DDatatype (x, n, xcs), loc)], (env, denv, gs))
1966 end 2059 end
1967 2060
1968 | L.DDatatypeImp (_, [], _) => raise Fail "Empty DDatatypeImp" 2061 | L.DDatatypeImp (_, [], _) => raise Fail "Empty DDatatypeImp"