|
|
1.1 ! root 1: (* Copyright 1989 by AT&T Bell Laboratories *) ! 2: (* sigmatch.sml *) ! 3: ! 4: structure SigMatch : SIGMATCH = struct ! 5: ! 6: structure Basics = Basics ! 7: ! 8: open List2 PrintUtil ErrorMsg Access Stampset Basics BareAbsyn BasicTypes ! 9: EnvAccess EnvAccess.Env TypesUtil PrintType ModUtil ! 10: ! 11: (* debug print functions *) ! 12: val prIntPath = printClosedSequence ("[",",","]") (print:int->unit) ! 13: fun prSymPath spath = printSequence "." printSym (rev spath) ! 14: ! 15: val symName = Symbol.name ! 16: val anonName = Symbol.symbol "Anon" ! 17: fun for a b = app b a ! 18: ! 19: exception CompareTypes ! 20: exception REFtyc ! 21: val refstamp = tycStamp(!refTycon) ! 22: and arraystamp = tycStamp(!arrayTycon) ! 23: ! 24: fun compType(specty, specsign:polysign, actty, actsign:polysign, actarity): unit = ! 25: let val env = array(actarity,UNDEFty) ! 26: fun comp(ty1, VARty(ref(INSTANTIATED(ty2)))) = ! 27: comp(ty1,ty2) ! 28: | comp(ty1, FLEXRECORDty(ref(CLOSED ty2))) = comp(ty1,ty2) ! 29: | comp(ty1, VARty(ref(IBOUND i))) = ! 30: (case env sub i ! 31: of UNDEFty => ! 32: let val {weakness=aw,eq=ae} = nth(actsign,i) ! 33: in if aw < infinity ! 34: then let fun checkweak(VARty(ref(IBOUND n))) = ! 35: let val {weakness=sw,...} = nth(specsign,n) ! 36: in if sw > aw then raise CompareTypes ! 37: else () ! 38: end ! 39: | checkweak(CONty(_,args)) = app checkweak args ! 40: | checkweak _ = impossible "compType/checkweak" ! 41: in checkweak ty1 ! 42: end ! 43: else (); ! 44: if ae ! 45: then checkEqTySig(ty1,specsign) ! 46: handle CHECKEQ => raise CompareTypes ! 47: else (); ! 48: update(env,i,ty1) ! 49: end ! 50: | ty => if equalType(ty1,ty) ! 51: then () ! 52: else raise CompareTypes) ! 53: | comp(ty1 as CONty(ref tycon, args), ty2 as CONty(ref tycon', args')) = ! 54: if eqTycon(tycon,tycon') ! 55: then app2 comp (args,args') ! 56: else (comp(reduceType ty1, ty2) ! 57: handle ReduceType => ! 58: comp(ty1, reduceType ty2) ! 59: handle ReduceType => raise CompareTypes) ! 60: | comp(_, ERRORty) = () ! 61: | comp _ = raise CompareTypes ! 62: in comp(specty,actty) ! 63: end ! 64: ! 65: fun compareTypes(spec: ty, actual: ty, name) : unit = ! 66: let fun error() = ! 67: (complain "value type in structure doesn't match signature spec"; ! 68: PrintType.resetPrintType(); ! 69: print (" name: " ^ symName name ^ "\n spec: "); ! 70: PrintType.printType(spec); ! 71: print "\n actual: "; ! 72: PrintType.printType(actual); newline()) ! 73: in case spec ! 74: of POLYty{sign,tyfun=TYFUN{body,...}} => ! 75: (case actual ! 76: of POLYty{sign=sign',tyfun=TYFUN{arity,body=body'}} => ! 77: (compType(body,sign,body',sign',arity) ! 78: handle CompareTypes => error()) ! 79: | _ => error()) ! 80: | ERRORty => () ! 81: | _ => ! 82: (case actual ! 83: of POLYty{sign,tyfun=TYFUN{arity,body}} => ! 84: (compType(spec,[],body,sign,arity) ! 85: handle CompareTypes => error()) ! 86: | _ => if equalType(spec,actual) ! 87: then () ! 88: else error()) ! 89: end ! 90: ! 91: ! 92: (* making abstraction structures *) ! 93: ! 94: fun abstract(sgn as STRstr{kind=SIGkind{stamps={strStamps=sigStrStamps, ! 95: tycStamps=sigTycStamps}, ! 96: ...}, ! 97: ...}, ! 98: str, {strStamps, tycStamps}) = ! 99: let val transStrStamp = join(strStamps,sigStrStamps) ! 100: val transTycStamp = join(tycStamps,sigTycStamps) ! 101: fun abstractTyc(sigtyc,strtyc) = ! 102: case sigtyc ! 103: of TYCON{kind=DATAtyc _,...} => strtyc ! 104: | _ => let val stamp = tycStamp sigtyc ! 105: in if tycFixed(stamp) ! 106: then strtyc ! 107: else setTycStamp(transTycStamp(stamp),sigtyc) ! 108: end ! 109: fun abstractStr(STRstr{stamp,sign,table,env,...}, ! 110: str as STRstr{env=env',...}) = ! 111: if strFixed stamp ! 112: then str ! 113: else let val newenv as REL{s,t} = abstractEnv(env,env') ! 114: val newstr = STRstr{stamp=transStrStamp(stamp), ! 115: env=newenv, ! 116: sign=sign,table=table, ! 117: kind=STRkind{path=[]}} (* ??? def of kind *) ! 118: in ArrayExt.app((setParent newstr), s, 2); ! 119: newstr ! 120: end ! 121: | abstractStr (INDstr i,_) = ! 122: impossible ("3437 in sigmatch: " ^makestring i) ! 123: | abstractStr _ = impossible "9833 in sigmatch (abstractStr)" ! 124: and abstractEnv(REL{s=sSig,t=tSig}:strenv, REL{s=sStr,t=tStr}:strenv) = ! 125: let val sNew = array(Array.length sSig, NULLstr) ! 126: val tNew = array(Array.length tSig, NULLtyc) ! 127: fun foreachStr i = ! 128: (update(sNew,i,abstractStr(sSig sub i, sStr sub i)); ! 129: foreachStr(i+1)) ! 130: fun foreachTyc i = ! 131: (update(tNew,i,abstractTyc(tSig sub i, tStr sub i)); ! 132: foreachTyc(i+1)) ! 133: in foreachStr 2 (* ignoring parent and parameter slots *) ! 134: handle Subscript => ! 135: foreachTyc 0 ! 136: handle Subscript => ! 137: REL{s=sNew,t=tNew} ! 138: end ! 139: in abstractStr(sgn,str) ! 140: end ! 141: | abstract _ = impossible "8375 in sigmatch (abstract)" ! 142: ! 143: (* signature matching *) ! 144: ! 145: fun matchx (parent: Structure) ! 146: (mapfns as {mapstr,mapstr1,maptyc}) ! 147: (abs, path, stamps, ! 148: sgn as STRstr{stamp,sign,...}, ! 149: str as STRstr{stamp=stamp',sign=sign',table,env,...}, ! 150: param: Structure) ! 151: : Structure * thinning = ! 152: if strFixed(stamp) andalso stamp <> stamp' ! 153: then (print "fixed signature stamp: "; print stamp; ! 154: print "\nstructure stamp: "; print stamp'; ! 155: print "\npath: "; prSymPath path; print "\n"; ! 156: condemn "fixed signature doesn't agree with structure") ! 157: else if sign = sign' ! 158: then (mapstr(sgn,str); ! 159: (if abs then abstract(sgn,str,stamps) else str, NONE)) ! 160: else let val v = mkLvar() ! 161: val _ = (openStr(); openOld({path=[v],strenv=env},table)) ! 162: val (str',transl) = ! 163: realizex parent mapfns (abs,path,stamps,stamp',sgn,param) ! 164: in closeStr(); ! 165: (str',SOME(v,transl)) ! 166: end ! 167: | matchx _ _ _ = impossible "843 in sigmatch" ! 168: ! 169: and realizex (parent: Structure) ! 170: (mapfns as {mapstr1,maptyc,mapstr}) ! 171: (abs, path, stamps, strStamp, ! 172: sgn as STRstr{stamp = boundStamp, sign, table, ! 173: env = sigenv as REL{s=sSig,t=tSig}, ! 174: kind = SIGkind{bindings,share,...},...}, ! 175: param: Structure) ! 176: : Structure * trans list = ! 177: let val sNew = array(Array.length sSig, NULLstr) ! 178: val tNew = array(Array.length tSig, NULLtyc) ! 179: val newenv = REL{s=sNew,t=tNew} ! 180: val newstr = STRstr{stamp=strStamp,sign=sign,table=table,env=newenv, ! 181: kind=STRkind{path=path}} ! 182: fun checkSpec spec = ! 183: case spec ! 184: of STRbind(STRvar{name=[id],binding=INDstr i,...}) => ! 185: let val STRvar{access,binding=str',...} = ! 186: lookSTRlocal id ! 187: handle Unbound => ! 188: condemn("unmatched structure spec: " ^ symName id) ! 189: val (str,thin) = matchx newstr mapfns ! 190: (false, id::path, stamps, ! 191: sSig sub i, str',NULLstr) ! 192: in update(sNew,i,str); ! 193: [case thin ! 194: of NONE => VALtrans access ! 195: | SOME(v,transl) => THINtrans(access,v,transl)] ! 196: end ! 197: | TYCbind(ref(INDtyc i)) => ! 198: let val sigTycon = tSig sub i ! 199: val name = tycName sigTycon ! 200: val strTycon = !(lookTYClocal name) ! 201: handle Unbound => ! 202: condemn("unmatched type spec: "^ ! 203: symName(name)) ! 204: val s = tycStamp sigTycon ! 205: val s' = tycStamp strTycon ! 206: in update(tNew,i,strTycon); ! 207: if tycFixed s andalso s <> s' ! 208: then if equalTycon(sigTycon,strTycon) ! 209: then maptyc(s,strTycon) ! 210: else condemn("bad match for fixed type spec " ! 211: ^ symName(name)) ! 212: else (case (sigTycon, strTycon) ! 213: of (TYCON{arity,kind=DATAtyc dcons,...}, ! 214: TYCON{arity=arity',kind=DATAtyc dcons',...}) => ! 215: if arity = arity' ! 216: andalso length(dcons) = length(dcons') ! 217: then maptyc(s,strTycon) ! 218: else condemn("mismatching datatype spec: " ! 219: ^ symName(name)) ! 220: | (TYCON{kind=DATAtyc _,...}, _) => ! 221: condemn("unmatched datatype spec: "^symName(name)) ! 222: | (TYCON{arity,kind=ABStyc,eq,...}, _) => ! 223: if arity <> tyconArity(strTycon) ! 224: then condemn("mismatching tycon arities: " ! 225: ^ symName(name)) ! 226: else if (!eq=YES) andalso not(isEqTycon(strTycon)) ! 227: then condemn("mismatched eqtype spec: " ! 228: ^ symName(name)) ! 229: else maptyc(s,strTycon) ! 230: | _ => impossible "realizex/checkSpec/TYCbind"); ! 231: nil ! 232: end ! 233: | CONbind(DATACON{name,typ,rep=VARIABLE _,const,...}) => ! 234: let val DATACON{typ=typ',rep=VARIABLE(access),...} = ! 235: lookCONlocal name ! 236: handle Unbound => ! 237: condemn ("unmatched exception spec: "^symName(name)) ! 238: | Bind => ! 239: condemn ("unmatched exception spec: "^symName(name)) ! 240: in compareTypes(typeInContext(!typ,newenv),!typ',name); ! 241: [VALtrans access] ! 242: end ! 243: | CONbind(DATACON{name,typ,...}) => ! 244: let val DATACON{typ=typ',...} = ! 245: lookCONlocal name ! 246: handle Unbound => ! 247: condemn ("unmatched data constructor spec: " ! 248: ^symName(name)) ! 249: in compareTypes(typeInContext(!typ,newenv),!typ',name); ! 250: nil ! 251: end ! 252: | VARbind(VALvar{name=[id],typ,...}) => ! 253: (case (lookVARCONlocal id ! 254: handle Unbound => ! 255: condemn("unmatched val spec: "^symName(id))) ! 256: of VARbind(VALvar{access,typ=typ',...}) => ! 257: (* no propagation of INLINE access!! *) ! 258: (compareTypes(typeInContext(!typ,newenv),!typ',id); ! 259: [case access of INLINE _ => VALtrans access ! 260: | PATH _ => VALtrans access ! 261: | LVAR _ => ! 262: if !ErrorMsg.anyErrors ! 263: then VALtrans access ! 264: else impossible "sigmatch.1" ! 265: | _ => impossible "sigmatch.2"]) ! 266: | CONbind(dcon as DATACON{typ=typ',...}) => ! 267: (compareTypes(typeInContext(!typ,newenv),!typ',id); ! 268: [CONtrans dcon]) ! 269: | _ => impossible "sigmatch.476") ! 270: | _ => nil (* nonchecked binding (FIXbind) *) ! 271: fun checkList (a::rest) = ! 272: (checkSpec a handle Syntax => nil) @ checkList rest ! 273: | checkList nil = nil ! 274: ! 275: val _ = update(sNew,0,parent) (* define parent before checking specs *) ! 276: val _ = update(sNew,1,param) (* ditto for param *) ! 277: val trans = checkList bindings ! 278: val _ = Sharing.checkSharing(table,newenv,share) ! 279: val str = if abs then abstract(sgn,newstr,stamps) else newstr ! 280: in mapstr1(boundStamp,str); ! 281: linkParents str; (* should be redundant *) ! 282: (str, trans) ! 283: end ! 284: | realizex _ _ _ = impossible "783 in sigmatch" ! 285: ! 286: val defaultMapfns = ! 287: let fun ignore _ = () ! 288: in {mapstr=ignore,mapstr1=ignore,maptyc=ignore} ! 289: end ! 290: ! 291: val match0 = matchx NULLstr ! 292: val match = matchx NULLstr defaultMapfns ! 293: val realize = realizex NULLstr defaultMapfns ! 294: ! 295: end (* structure SigMatch *)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.