1 /* -*- mode: hugs-c; -*- */
2 /* --------------------------------------------------------------------------
3 * Part of type checker dealing with kind inference
5 * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
6 * All rights reserved. See NOTICE for details and conditions of use etc...
7 * Hugs version 1.4, December 1997
11 * $Date: 1998/12/02 13:22:16 $
12 * ------------------------------------------------------------------------*/
14 #define newKindvars(n) newTyvars(n) /* to highlight uses of type vars */
15 /* as kind variables */
17 Bool kindExpert = FALSE; /* TRUE => display kind errors in */
20 /* --------------------------------------------------------------------------
22 * ------------------------------------------------------------------------*/
24 static Void local kindError(l,c,in,wh,k,o)
25 Int l; /* line number near constuctor exp */
26 Constr c; /* constructor */
27 Constr in; /* context (if any) */
28 String wh; /* place in which error occurs */
29 Kind k; /* expected kind (k,o) */
30 Int o; { /* inferred kind (typeIs,typeOff) */
33 if (!kindExpert) { /* for those with a fear of kinds */
34 ERRMSG(l) "Illegal type" ETHEN
36 ERRTEXT " \"" ETHEN ERRTYPE(in);
39 ERRTEXT " in %s\n", wh
43 ERRMSG(l) "Kind error in %s", wh ETHEN
45 ERRTEXT "\n*** expression : " ETHEN ERRTYPE(in);
47 ERRTEXT "\n*** constructor : " ETHEN ERRTYPE(c);
48 ERRTEXT "\n*** kind : " ETHEN ERRKIND(copyType(typeIs,typeOff));
49 ERRTEXT "\n*** does not match : " ETHEN ERRKIND(copyType(k,o));
51 ERRTEXT "\n*** because : %s", unifyFails ETHEN
57 #define shouldKind(l,c,in,wh,k,o) if (!kunify(typeIs,typeOff,k,o)) \
58 kindError(l,c,in,wh,k,o)
59 #define checkKind(l,c,in,wh,k,o) kindConstr(l,c); shouldKind(l,c,in,wh,k,o)
60 #define inferKind(k,o) typeIs=k; typeOff=o
62 static Int locCVars; /* offset to local variable kinds */
63 static List unkindTypes; /* types in need of kind annotation*/
65 static Kind extKind; /* Kind of extension, *->row->row */
68 static Void local kindConstr(l,c) /* Determine kind of constructor */
74 if (isSynonym(h) && n<tycon(h).arity) {
75 ERRMSG(l) "Not enough arguments for type synonym \"%s\"",
76 textToStr(tycon(h).text)
81 if (isExt(h) && n!=2) {
82 ERRMSG(l) "Illegal use of row in " ETHEN ERRTYPE(c);
88 if (n==0) /* trivial case, no arguments */
90 else { /* non-trivial application */
91 static String app = "constructor application";
101 typeIs = kindAtom(h); /* h :: v1 -> ... -> vn -> w */
102 shouldKind(l,h,c,app,k,beta);
104 for (i=n; i>0; --i) { /* ci :: vi for each 1 <- 1..n */
105 checkKind(l,arg(a),c,app,var,beta+i-1);
108 tyvarType(beta+n); /* inferred kind is w */
112 static Kind local kindAtom(c) /* Find kind of atomic constructor */
115 case TUPLE : return simpleKind(tupleOf(c)); /* (,) :: * -> * -> * */
116 case OFFSET : return mkInt(locCVars+offsetOf(c));
117 case TYCON : return tycon(c).kind;
119 case EXT : return extKind;
122 internal("kindAtom");
123 return STAR;/* not reached */
126 static Void local kindPred(line,pred) /* Check kinds of arguments in pred*/
129 static String predicate = "class constraint";
131 if (isExt(fun(pred))) {
132 checkKind(line,arg(pred),NIL,predicate,ROW,0);
136 checkKind(line,arg(pred),NIL,predicate,cclass(fun(pred)).sig,0);
139 static Void local kindType(line,wh,type)/* check that (poss qualified) type*/
140 Int line; /* is well-kinded */
144 if (isPolyType(type)) { /* local constructor vars reqd? */
145 Kind k = polySigOf(type);
147 for (; isPair(k); k=snd(k))
149 locCVars = newKindvars(n);
150 unkindTypes = cons(pair(mkInt(locCVars),snd(type)),unkindTypes);
151 type = monoTypeOf(type);
153 if (whatIs(type)==QUAL) { /* examine context (if any) */
154 map1Proc(kindPred,line,fst(snd(type)));
155 type = snd(snd(type));
157 checkKind(line,type,NIL,wh,STAR,0); /* finally, check type part */
160 static Void local fixKinds() { /* add kind annotations to types */
161 for (; nonNull(unkindTypes); unkindTypes=tl(unkindTypes)) {
162 Pair pr = hd(unkindTypes);
163 Int beta = intOf(fst(pr));
164 Cell qts = fst(snd(pr));
167 hd(qts) = copyKindvar(beta++);
169 hd(qts) = ap(hd(qts),copyKindvar(beta++));
170 if (nonNull(tl(qts)))
178 Printf("Type expression: ");
179 printType(stdout,snd(snd(pr)));
181 printKind(stdout,fst(snd(pr)));
187 /* --------------------------------------------------------------------------
188 * Kind checking of groups of type constructors and classes:
189 * ------------------------------------------------------------------------*/
191 Void kindTCGroup(tcs) /* find kinds for mutually rec. gp */
192 List tcs; { /* of tycons and classes */
194 mapProc(initTCKind,tcs);
201 static Void local initTCKind(c) /* build initial kind/arity for c */
203 if (isTycon(c)) { /* Initial kind of tycon is: */
204 Int beta = newKindvars(1); /* v1 -> ... -> vn -> vn+1 */
205 varKind(tycon(c).arity); /* where n is the arity of c. */
206 bindTv(beta,typeIs,typeOff); /* For data definitions, vn+1 == * */
207 switch (whatIs(tycon(c).what)) {
209 case DATATYPE : bindTv(typeOff+tycon(c).arity,STAR,0);
211 tycon(c).kind = mkInt(beta);
214 cclass(c).sig = mkInt(newKindvars(1));
217 static Void local kindTC(c) /* check each part of a tycon/class*/
218 Cell c; { /* is well-kinded */
220 static String cfun = "constructor function";
221 static String tsyn = "synonym definition";
222 Int line = tycon(c).line;
224 locCVars = tyvar(intOf(tycon(c).kind))->offs;
225 switch (whatIs(tycon(c).what)) {
227 case DATATYPE : { List cs = tycon(c).defn;
228 if (whatIs(cs)==QUAL) {
229 map1Proc(kindPred,line,fst(snd(cs)));
230 tycon(c).defn = cs = snd(snd(cs));
232 for (; hasCfun(cs); cs=tl(cs))
233 kindType(line,cfun,name(hd(cs)).type);
237 default : checkKind(line,tycon(c).defn,NIL,
238 tsyn,var,locCVars+tycon(c).arity);
241 else { /* scan type exprs in class defn to*/
242 List ms = cclass(c).members; /* determine the class signature */
243 List scs = cclass(c).supers;
245 for (; nonNull(scs); scs=tl(scs))
246 if (!kunify(cclass(hd(scs)).sig,0,cclass(c).sig,0)) {
247 ERRMSG(cclass(c).line)
248 "Kind of class \"%s\" does not match superclass \"%s\"",
249 textToStr(cclass(c).text), textToStr(cclass(hd(scs)).text)
253 for (; nonNull(ms); ms=tl(ms)) {
254 Int line = intOf(fst3(hd(ms)));
255 Type type = thd3(hd(ms));
256 kindType(line,"member function type signature",type);
261 static Void local genTC(c) /* generalise kind inferred for */
262 Cell c; { /* given tycon/class */
264 tycon(c).kind = copyKindvar(intOf(tycon(c).kind));
266 Printf("%s :: ",textToStr(tycon(c).text));
267 printKind(stdout,tycon(c).kind);
272 cclass(c).sig = copyKindvar(intOf(cclass(c).sig));
274 Printf("%s :: ",textToStr(cclass(c).text));
275 printKind(stdout,cclass(c).sig);
281 static Kind local copyKindvar(vn) /* build kind attatched to variable*/
283 Tyvar *tyv = tyvar(vn);
285 return copyKind(tyv->bound,tyv->offs);
286 return STAR; /* any unbound variable defaults to*/
287 } /* the kind of all types */
289 static Kind local copyKind(k,o) /* build kind expression from */
290 Kind k; /* given skeleton */
293 case AP : { Kind l = copyKind(fst(k),o); /* ensure correct */
294 Kind r = copyKind(snd(k),o); /* eval. order */
297 case OFFSET : return copyKindvar(o+offsetOf(k));
298 case INTCELL : return copyKindvar(intOf(k));
303 /* --------------------------------------------------------------------------
304 * Kind checking of instance declaration headers:
305 * ------------------------------------------------------------------------*/
307 Void kindInst(in,h) /* check predicates in instance */
311 locCVars = newKindvars(inst(in).arity);
312 kindPred(inst(in).line,h);
313 map1Proc(kindPred,inst(in).line,inst(in).specifics);
317 /* --------------------------------------------------------------------------
318 * Kind checking of individual type signatures:
319 * ------------------------------------------------------------------------*/
321 Void kindSigType(line,type) /* check that type is well-kinded */
325 kindType(line,"type expression",type);
330 /* --------------------------------------------------------------------------
331 * Kind checking of default types:
332 * ------------------------------------------------------------------------*/
334 Void kindDefaults(line,ts) /* check that list of types are */
335 Int line; /* well-kinded */
338 map2Proc(kindType,line,"default type",ts);
343 /* --------------------------------------------------------------------------
344 * Support for `kind preserving substitutions' from unification:
345 * ------------------------------------------------------------------------*/
347 static Bool local eqKind(k1,k2) /* check that two (mono)kinds are */
348 Kind k1, k2; { /* equal */
350 || (isPair(k1) && isPair(k2)
351 && eqKind(fst(k1),fst(k2))
352 && eqKind(snd(k1),snd(k2)));
355 static Kind local getKind(c,o) /* Find kind of constr during type */
356 Cell c; /* checking process */
358 if (isAp(c)) /* application */
359 return snd(getKind(fst(c),o));
361 case TUPLE : return simpleKind(tupleOf(c)); /* (,) :: * -> * -> * */
362 case OFFSET : return tyvar(o+offsetOf(c))->kind;
363 case INTCELL: return tyvar(intOf(c))->kind;
364 case TYCON : return tycon(c).kind;
366 case EXT : return extKind;
370 Printf("getKind c = %d, whatIs=%d\n",c,whatIs(c));
373 return STAR;/* not reached */
376 /* --------------------------------------------------------------------------
377 * Two forms of kind expression are used quite frequently:
378 * * -> * -> ... -> * -> * for kinds of ->, [], ->, (,) etc...
379 * v1 -> v2 -> ... -> vn -> vn+1 skeletons for constructor kinds
380 * Expressions of these forms are produced by the following functions which
381 * use a cache to avoid repeated construction of commonly used values.
382 * A similar approach is used to store the types of tuple constructors in the
384 * ------------------------------------------------------------------------*/
386 #define MAXKINDFUN 10
387 static Kind simpleKindCache[MAXKINDFUN];
388 static Kind varKindCache[MAXKINDFUN];
390 static Kind local makeSimpleKind(n) /* construct * -> ... -> * (n args)*/
398 static Kind local simpleKind(n) /* return (possibly cached) simple */
399 Int n; { /* function kind */
401 return makeSimpleKind(n);
402 else if (nonNull(simpleKindCache[n]))
403 return simpleKindCache[n];
405 return simpleKindCache[0] = STAR;
407 return simpleKindCache[n] = ap(STAR,simpleKind(n-1));
410 static Kind local makeVarKind(n) /* construct v0 -> .. -> vn */
412 Kind k = mkOffset(n);
414 k = ap(mkOffset(n),k);
418 static Void local varKind(n) /* return (possibly cached) var */
419 Int n; { /* function kind */
420 typeOff = newKindvars(n+1);
422 typeIs = makeVarKind(n);
423 else if (nonNull(varKindCache[n]))
424 typeIs = varKindCache[n];
426 typeIs = varKindCache[n] = makeVarKind(n);
429 /*-------------------------------------------------------------------------*/