|
|
1.1 ! root 1: (* Copyright 1989 by AT&T Bell Laboratories *) ! 2: (* sharing.sml *) ! 3: ! 4: structure Sharing : SHARING = ! 5: struct ! 6: ! 7: structure Basics = Basics ! 8: ! 9: open ErrorMsg PrintUtil Basics EnvAccess TypesUtil ! 10: ! 11: (* a couple of useful iterators *) ! 12: ! 13: fun for a b = app b a ! 14: ! 15: fun upto (start,finish) f = ! 16: let fun loop i = if i>=finish then () else (f i; loop(i+1)) ! 17: in loop start ! 18: end ! 19: ! 20: fun getStr([],str) = str ! 21: | getStr(id::rest,STRstr{table,env,...}) = ! 22: let val STRvar{binding,...} = lookSTRinTable(table,id) ! 23: val str = case (binding,env) ! 24: of (INDstr i,REL{s,...}) => s sub i ! 25: | (SHRstr(i::r),REL{s,...}) => getEpath(r, s sub i) ! 26: | (STRstr _, _) => binding ! 27: | _ => impossible "Sharing.getStr" ! 28: in getStr(rest,str) ! 29: end ! 30: handle Env.UnboundTable => ! 31: condemn("unbound structure id in sharing specification: " ! 32: ^ Symbol.name id) ! 33: ! 34: fun findStr(id::rest,table,env) : Structure = ! 35: (let val STRvar{binding,...} = lookSTRinTable(table,id) ! 36: val str = case (binding,env) ! 37: of (INDstr i,REL{s,...}) => s sub i ! 38: | (SHRstr(i::r),REL{s,...}) => getEpath(r,s sub i) ! 39: | (STRstr _, _) => binding ! 40: | _ => impossible "Sharing.findStr" ! 41: in getStr(rest,str) ! 42: end ! 43: handle Env.UnboundTable => (* look for global structure *) ! 44: let val STRvar{binding,...} = ! 45: lookSTR(id) handle Env.Unbound => ! 46: condemn("unbound structure id in sharing specification: " ! 47: ^ Symbol.name id) ! 48: in getStr(rest,binding) ! 49: end) ! 50: | findStr([],_,_) = impossible "Sharing.findStr with empty path" ! 51: ! 52: fun findTycon(path,table,env) : tycon = ! 53: let val (id::rpath) = rev path ! 54: in case rev rpath ! 55: of [] => ((case !(lookTYCinTable(table,id)) ! 56: of INDtyc i => ! 57: (case env ! 58: of REL{t,...} => t sub i ! 59: | DIR => impossible "Sharing.findTycon") ! 60: | SHRtyc p => getEpathTyc(p,env) ! 61: | tyc => tyc) ! 62: handle Env.UnboundTable => ! 63: !(lookTYC id) ! 64: handle Env.Unbound => ! 65: condemn("unbound type in sharing spec: "^ Symbol.name id)) ! 66: | path' => !(lookTYCinStr(findStr(path',table,env),id)) ! 67: end ! 68: (* ! 69: fun sameStructure(STRstr{env,...}, STRstr{env=env',...}) = (env = env') ! 70: | sameStructure _ = false ! 71: ! 72: (* similar to ModUtil.resetParent except for sameStructure test -- ! 73: would ModUtil.resetParent suffice? *) ! 74: fun resetParent (newparent: Structure, oldparent: Structure) = ! 75: fn (STRstr{env=REL{s,...},...}) => ! 76: ((case s sub 0 ! 77: of NULLstr => update(s,0,newparent) ! 78: | _ => if sameStructure(s sub 0, oldparent) ! 79: then update(s,0,newparent) ! 80: else ()) ! 81: handle Subscript => ()) ! 82: | NULLstr => () ! 83: | _ => impossible "Sharing.resetParent" ! 84: *) ! 85: fun doSharing(table,env as REL{s=senv,t=tenv},{strStamps,tycStamps}, ! 86: {s=strShare,t=typeShare}) = ! 87: let fun freeStrStamp s = not(Stampset.member(s,strStamps)) ! 88: fun freeTycStamp s = not(Stampset.member(s,tycStamps)) ! 89: val {assoc,getassoc,union,find} = Siblings.new(freeStrStamp) ! 90: : Structure Siblings.siblingClass ! 91: val {union=tunion,find=tfind} = Unionfind.new(freeTycStamp) ! 92: ! 93: fun strMerge(p' as STRstr{stamp=p,...}, q' as STRstr{stamp=q,...}) = ! 94: if (assoc(p,p'); find p) = (assoc(q,q'); find q) ! 95: then () ! 96: else let val pclass = getassoc p ! 97: and qclass = getassoc q ! 98: in union(p,q); ! 99: for pclass (fn x => ! 100: for qclass (fn y => ! 101: sMerge(x,y))) ! 102: end ! 103: ! 104: and sMerge(str1 as STRstr{stamp=s1,kind=k1,env=REL{s=senv1,t=tenv1,...},...}, ! 105: str2 as STRstr{stamp=s2,kind=k2, ! 106: env=env2 as REL{s=senv2,t=tenv2,...}, ! 107: table,...}) = ! 108: case (k1,k2) ! 109: of (STRkind _, STRkind _) => ! 110: if s1 = s2 ! 111: then () ! 112: else condemn "sharing constraint - \ ! 113: \incompatible fixed structures" ! 114: | (STRkind _, SIGkind _) => sMerge(str2,str1) ! 115: | (SIGkind{bindings,...}, _) => ! 116: for bindings ! 117: (fn STRbind(STRvar{name=[id],binding,...}) => ! 118: (let val STRvar{binding=target,...} = ! 119: lookSTRinTable(table,id) ! 120: in strMerge((case binding ! 121: of INDstr i => senv1 sub i ! 122: | _ => binding), ! 123: (case target ! 124: of INDstr i => senv2 sub i ! 125: | SHRstr(i::r) => getEpath(r,senv2 sub i) ! 126: | _ => target)) ! 127: end ! 128: handle Env.UnboundTable => ()) ! 129: | TYCbind(ref tycon) => ! 130: (let val tyc1 = case tycon ! 131: of INDtyc i => tenv1 sub i ! 132: | _ => tycon ! 133: val tyc2 = ! 134: case !(lookTYCinTable(table,tycName tyc1)) ! 135: of INDtyc i => tenv2 sub i ! 136: | SHRtyc p => getEpathTyc(p,env2) ! 137: | tyc => tyc ! 138: in tunion(tycStamp tyc1,tycStamp tyc2); ! 139: () ! 140: end ! 141: handle Env.UnboundTable => ()) ! 142: | _ => ()) ! 143: ! 144: fun shareSig(REL{s,t}) = ! 145: (upto (2, Array.length s) (fn i => ! 146: let val str as STRstr{stamp,sign,table,env as REL{s=s',...},kind} = ! 147: s sub i ! 148: in case kind ! 149: of SIGkind _ => ! 150: let val stamp' = find stamp ! 151: in if stamp' = stamp ! 152: then () ! 153: else let val new = ! 154: STRstr{stamp=stamp',sign=sign, ! 155: table=table, ! 156: env=env,kind=kind} ! 157: in update(s,i,new); ! 158: ArrayExt.app(ModUtil.resetParent new,s',1) ! 159: end; ! 160: shareSig env ! 161: end ! 162: | STRkind _ => impossible "Sharing.doSharing.shareSig" ! 163: end); ! 164: upto (0,Array.length t) (fn i => ! 165: let val tycon = t sub i ! 166: val stamp = tycStamp tycon ! 167: val stamp' = tfind stamp ! 168: in if stamp = stamp' ! 169: then () ! 170: else update(t,i,setTycStamp(stamp',tycon)) ! 171: end)) ! 172: ! 173: val strPathPairs = ref [] : (spath*spath) list ref ! 174: val typePathPairs = ref [] : (spath*spath) list ref ! 175: ! 176: in for strShare (fn p as (p1,p2) => ! 177: let val str1 as STRstr{stamp=s1,...} = findStr(p1,table,env) ! 178: and str2 as STRstr{stamp=s2,...} = findStr(p2,table,env) ! 179: in if freeStrStamp s1 orelse freeStrStamp s2 then () ! 180: else strPathPairs := p :: !strPathPairs; ! 181: strMerge(str1,str2) ! 182: end); ! 183: for typeShare (fn p as (p1,p2) => ! 184: let val s1 = tycStamp(findTycon(p1,table,env)) ! 185: and s2 = tycStamp(findTycon(p2,table,env)) ! 186: in if freeTycStamp(s1) orelse freeTycStamp(s2) ! 187: then () ! 188: else typePathPairs := p :: !typePathPairs; ! 189: tunion(s1,s2) ! 190: end); ! 191: shareSig env; ! 192: {s= !strPathPairs, t= !typePathPairs} ! 193: end (* doSharing *) ! 194: ! 195: fun checkSharing(table,env,{s=strShare,t=typeShare}) = ! 196: (for strShare (fn p as (p1,p2) => ! 197: let val STRstr{stamp=s1,...} = findStr(p1,table,env) ! 198: and STRstr{stamp=s2,...} = findStr(p2,table,env) ! 199: in if s1 <> s2 ! 200: then condemn "structure sharing violation" ! 201: else () ! 202: end); ! 203: for typeShare (fn (p1,p2) => ! 204: let val tyc1 = findTycon(p1,table,env) ! 205: and tyc2 = findTycon(p2,table,env) ! 206: in if equalTycon(tyc1,tyc2) ! 207: then () ! 208: else (PrintType.printTycon tyc1; print "\n"; (* DEBUGGING *) ! 209: PrintType.printTycon tyc2; print "\n"; (* DEBUGGING *) ! 210: condemn "type sharing violation") ! 211: end)) ! 212: ! 213: end (* structure Sharing *)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.