|
|
1.1 root 1: (* Copyright 1989 by AT&T Bell Laboratories *)
2: (* overload.sml *)
3:
4: structure Overload : OVERLOAD = struct
5:
6: structure Basics = Basics
7:
8: local open Basics TypesUtil PrintUtil ErrorMsg BasicTypes
9: PrintType
10: in
11:
12: type subst = (tyvar * tvkind) list
13:
14: exception SoftUnify
15:
16: fun copyScheme (tyfun as TYFUN{arity,...}) : ty * ty =
17: let val tvs = typeArgs arity
18: in (applyTyfun(tyfun,tvs),
19: if arity>1 then tupleTy tvs else hd tvs)
20: end
21:
22: fun rollBack subst =
23: let fun loop (nil,trace) = trace
24: | loop (((tv as ref kind),oldkind)::subst,trace) =
25: (tv := oldkind;
26: loop(subst,(tv,kind)::trace))
27: in loop(subst,nil)
28: end
29:
30: fun redoSubst nil = ()
31: | redoSubst ((tv,INSTANTIATED ty)::rest) =
32: (instantiate(tv, ty); redoSubst rest)
33: | redoSubst (_) = impossible "Overload--redoSubst"
34:
35: fun softUnify(ty1: ty, ty2: ty): subst =
36: let val subst: subst ref = ref nil
37: fun softInst(tv as ref kind: tyvar, ty: ty) : unit =
38: let fun scan(ty: ty) : unit = (* simple occurrence check *)
39: case ty
40: of VARty(tv') =>
41: if eqTyvar(tv, tv') then raise SoftUnify else ()
42: | CONty(_, args) => app scan args
43: | FLEXRECORDty(ref(OPEN fields)) =>
44: app (fn (_,ty') => scan ty') fields
45: | ty => () (* propagate error *)
46: in case kind
47: of META _ => ()
48: | _ => raise SoftUnify;
49: scan ty;
50: subst := (tv, kind)::(!subst);
51: tv := INSTANTIATED ty
52: end
53:
54: fun unify(ty1: ty, ty2: ty): unit =
55: let val ty1 = prune ty1
56: and ty2 = prune ty2
57: in case (ty1,ty2)
58: of (VARty(tv1),VARty(tv2)) =>
59: if eqTyvar(tv1,tv2) then () else softInst(tv1,ty2)
60: | (VARty(tv1),_) => softInst(tv1,ty2)
61: | (_,VARty(tv2)) => softInst(tv2,ty1)
62: | (CONty(ref tycon1, args1), CONty(ref tycon2, args2)) =>
63: if eqTycon(tycon1, tycon2)
64: then unifyLists(args1, args2)
65: else (unify(reduceType ty1, ty2)
66: handle ReduceType =>
67: unify(ty1, reduceType ty2)
68: handle ReduceType => raise SoftUnify)
69: | (ERRORty, _) => () (* propagate error *)
70: | (_, ERRORty) => () (* propagate error *)
71: | _ => raise SoftUnify
72: end
73:
74: and unifyLists([],[]) = ()
75: | unifyLists(ty1::rest1, ty2::rest2) =
76: (unify(ty1,ty2); unifyLists(rest1,rest2))
77: | unifyLists(_) = raise SoftUnify
78:
79: in unify(ty1,ty2)
80: handle SoftUnify => (rollBack(!subst); raise SoftUnify);
81: !subst
82: end
83:
84:
85: exception Overld
86:
87: datatype stack
88: = EMPTY
89: | PUSH of var ref * ty * stack
90: | MARK of stack
91:
92: val overloaded = ref EMPTY (* stack of currently unresolved overloaded vars *)
93:
94: fun resetOverloaded () = overloaded := EMPTY
95:
96: fun markOverloaded () = overloaded := MARK(!overloaded)
97:
98: fun pushOverloaded (refvar as ref(OVLDvar{options,scheme,...}) : var ref) =
99: let val (scheme',ty) = copyScheme(scheme)
100: in overloaded := PUSH(refvar,ty,!overloaded);
101: scheme'
102: end
103: | pushOverloaded _ = impossible "overload.1"
104:
105: fun resolveOVLDvar(rv as ref(OVLDvar{name,options,...}),context) =
106: (let fun findFirst({indicator, variant}::rest) =
107: ((softUnify(applyPoly(indicator,0,infinity), context), variant, rest)
108: handle SoftUnify => findFirst(rest))
109: | findFirst(nil) =
110: (complain("overloaded variable \"" ^ Symbol.name(name) ^
111: "\" not defined at type:");
112: print " ";
113: resetPrintType(); printType(context); newline();
114: raise Overld)
115: fun findSecond({indicator, variant}::rest) =
116: ((rollBack(softUnify(applyPoly(indicator,0,infinity), context));
117: complain("overloaded variable \"" ^ Symbol.name(name) ^
118: "\" cannot be resolved");
119: raise Overld)
120: handle SoftUnify => findSecond(rest))
121: | findSecond(nil) = ()
122: val (subst,var,restOptions) = findFirst(!options)
123: val subst = rollBack subst
124: in findSecond(restOptions);
125: redoSubst subst;
126: rv := var
127: end handle Overld => ())
128: | resolveOVLDvar _ = impossible "overload.2"
129:
130: fun resolveOverloaded () =
131: let fun loop EMPTY = ()
132: | loop(MARK(s)) = (overloaded := s)
133: | loop(PUSH(refvar,context,s)) =
134: (resolveOVLDvar(refvar,context); loop(s))
135: in loop(!overloaded)
136: end
137:
138: end (* local *)
139:
140: end (* structure Overload *)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.