|
|
1.1 ! root 1: (* Copyright 1989 by AT&T Bell Laboratories *) ! 2: structure EnvAccess : ENVACCESS = struct ! 3: (* lookup and binding functions *) ! 4: ! 5: structure Access = Access ! 6: structure Basics = Basics ! 7: structure Env = Env ! 8: ! 9: open ErrorMsg PrintUtil Access Basics Basics.Symbol BasicTypes TypesUtil Env ! 10: NameSpace ! 11: ! 12: val debugBind = System.Control.debugBind ! 13: ! 14: fun openStructureVar(STRvar{access=PATH p,binding,...}) = ! 15: (case binding ! 16: of STRstr{table,env,...} => openOld({path=p,strenv=env},table) ! 17: | INDstr _ => impossible "EnvAccess.openStructureVar -- INDstr arg" ! 18: | SHRstr _ => impossible "EnvAccess.openStructureVar -- SHRstr arg" ! 19: | NULLstr => impossible "EnvAccess.openStructureVar -- NULLstr arg") ! 20: | openStructureVar _ = impossible "EnvAccess.openStructureVar -- bad access value" ! 21: ! 22: val bogusID = Symbol.symbol "bogus" ! 23: ! 24: val bogusStrStamp = Stampset.newStamp(Stampset.fixedStrStamps) ! 25: ! 26: local val b = STRstr{stamp=bogusStrStamp, sign=0, table=newTable(), env=DIR, ! 27: kind=STRkind{path=[bogusID]}} ! 28: in val bogusSTR = STRvar{name=[bogusID], access=PATH[0], binding=b} ! 29: val bogusSTR' = STRvar{name=[bogusID], access=SLOT 0, binding=b} ! 30: end ! 31: ! 32: (* type constructors *) ! 33: ! 34: val bogusTyc = mkDEFtyc([bogusID],TYFUN{arity=0,body=ERRORty},YES,Stampset.globalStamps) ! 35: ! 36: fun lookTYCinTable(table,id) = ! 37: let val TYCbind tycref = IntStrMap.map table (tycKey id) ! 38: in tycref ! 39: end ! 40: ! 41: fun lookTYCinStr(STRstr{table,env,stamp,...}: Structure, id: symbol) : tycon ref = ! 42: ((case lookTYCinTable(table,id) ! 43: of ref(INDtyc i) => ! 44: (case env ! 45: of REL{s,t} => ref(t sub i) ! 46: | DIR => impossible "EnvAccess.lookTYCinStr 1") ! 47: | ref(SHRtyc p) => ref(getEpathTyc(p,env)) ! 48: | tyc => tyc) ! 49: handle UnboundTable => ! 50: (if stamp=bogusStrStamp then () ! 51: else complain("unbound type in structure: " ^ Symbol.name id); ! 52: ref bogusTyc)) ! 53: | lookTYCinStr _ = impossible "EnvAccess.lookTYCinStr 2" ! 54: ! 55: fun lookTYC' look (id:symbol) = ! 56: case look(tycKey(id)) ! 57: of (TYCbind(tycref as ref(INDtyc i)), {strenv=REL{s,t},path}) => ! 58: (ref(t sub i) ! 59: handle Subscript => ! 60: impossible "EnvAccess.lookTYC' 1") ! 61: | (TYCbind(tycref as ref(SHRtyc p)), {strenv,path}) => ! 62: (ref(getEpathTyc(p,strenv)) ! 63: handle Subscript => ! 64: impossible "EnvAccess.lookTYC' 2") ! 65: | (TYCbind tycref, _) => tycref ! 66: | _ => impossible "EnvAccess.lookTYC' 3" ! 67: ! 68: val lookTYC = lookTYC' look ! 69: val lookTYClocal = lookTYC' lookStrLocal ! 70: ! 71: (* addzeros also defined in Parse *) ! 72: fun addzeros(0,l) = l ! 73: | addzeros(n,l) = addzeros(n-1,0::l) ! 74: ! 75: fun bindTYC(id: symbol, tc: tycon ref) = ! 76: let val binding = TYCbind tc ! 77: in add(tycIndex id, name id, binding); binding ! 78: end ! 79: ! 80: ! 81: (* tycon lookup with arity checking *) ! 82: ! 83: fun checkArity(tycon, arity) = ! 84: if tyconArity(tycon) <> arity ! 85: then complain("type constructor "^(Symbol.name(tycName(tycon)))^ ! 86: " has wrong number of arguments: "^makestring arity) ! 87: else () ! 88: ! 89: fun lookArTYC0(id,arity) = ! 90: let val tycref as ref tyc = lookTYC id ! 91: in checkArity(tyc,arity); ! 92: tycref ! 93: end ! 94: handle Unbound => ! 95: (complain("unbound type constructor: " ^ Symbol.name id); ! 96: ref bogusTyc) ! 97: ! 98: fun lookArTYCinSig (depth: int) (id: symbol, arity: int) = ! 99: (case look(tycKey id) ! 100: of (TYCbind(tycref as ref(INDtyc i)), {strenv=REL{s,t},path=h::r}) => ! 101: if h >= 0 ! 102: then let val tyc = t sub i ! 103: in checkArity(tyc,arity); ! 104: ref tyc ! 105: end ! 106: else (checkArity(t sub i, arity); ! 107: ref(RELtyc(addzeros(depth+h,r@[i])))) ! 108: | (TYCbind(tycref as ref(SHRtyc p)), {strenv,path}) => ! 109: let val tyc = getEpathTyc(p,strenv) ! 110: in checkArity(tyc,arity); ! 111: ref tyc ! 112: end ! 113: | (TYCbind tycref, _) => (checkArity(!tycref,arity); tycref) ! 114: | _ => impossible "EnvAccess.lookTYCinSig") ! 115: handle Unbound => ! 116: (complain("unbound type constructor in signature: " ^ Symbol.name id); ! 117: ref bogusTyc) ! 118: ! 119: val lookArTYC : (symbol * int -> tycon ref) ref = ref lookArTYC0 ! 120: ! 121: ! 122: (* patching type constructor references in datatype declarations *) ! 123: ! 124: fun protectDb () = ! 125: let val patchList : tycon ref list ref = ref [] ! 126: val savedLook = !lookArTYC ! 127: fun localLook(id,ary) = ! 128: let val tycref = ref (mkUNDEFtyc(id,ary)) ! 129: in patchList := tycref :: !patchList; ! 130: tycref ! 131: end ! 132: fun patch (tc::l) = ! 133: let val ref(TYCON{path=id::_,arity,kind=UNDEFtyc newpath,...}) = tc ! 134: in let val ref tycon = !lookArTYC(id,arity) ! 135: in tc := case newpath ! 136: of NONE => tycon ! 137: | SOME path => setTycPath(path,tycon) ! 138: end ! 139: handle Unbound => ! 140: complain("unbound type constructor (in datatype): " ^ ! 141: Symbol.name id); ! 142: patch l ! 143: end ! 144: | patch nil = () ! 145: in ((fn () => lookArTYC := localLook), ! 146: (fn () => (lookArTYC := savedLook; patch(!patchList)))) ! 147: end ! 148: ! 149: (* constructors *) ! 150: ! 151: fun dconApplied(DATACON{name,const,typ,rep,sign},{path,strenv}:info) : datacon = ! 152: DATACON{name = name, const = const, sign=sign, ! 153: rep = (case rep ! 154: of VARIABLE(SLOT n) => VARIABLE(PATH(n::path)) ! 155: | VARIABLE(LVAR v) => VARIABLE(PATH [v]) ! 156: | _ => rep), (* nonexception datacon *) ! 157: typ = ref(typeInContext(!typ,strenv))} ! 158: ! 159: fun lookCONinTable(table,id) = ! 160: case IntStrMap.map table (varKey(id)) ! 161: of CONbind c => c ! 162: | _ => raise UnboundTable ! 163: ! 164: fun lookCON' lookfn id = ! 165: case lookfn(varKey(id)) ! 166: of (CONbind c,info) => dconApplied(c,info) ! 167: | _ => raise Unbound ! 168: ! 169: val lookCON = lookCON' look ! 170: val lookCONlocal = lookCON' lookStrLocal ! 171: ! 172: val bogusCON = DATACON{name=bogusID,const=true,typ=ref ERRORty, ! 173: rep=UNDECIDED,sign=[]} ! 174: ! 175: fun lookCONinStr(STRstr{table,env,stamp,...},id,ap,qid): datacon = ! 176: (dconApplied(lookCONinTable(table,id),{path=ap,strenv=env}) ! 177: handle UnboundTable => ! 178: (if stamp=bogusStrStamp then () ! 179: else complain("unbound constructor in structure: " ^ Symbol.name id); ! 180: bogusCON)) ! 181: | lookCONinStr _ = impossible "EnvAccess.lookCONinStr" ! 182: ! 183: fun bindCON (id: symbol, c: datacon) = ! 184: let val binding = CONbind c ! 185: in add(conIndex id, name id, binding); binding ! 186: end ! 187: ! 188: (* variables *) ! 189: ! 190: fun unboundVAR id = (complain ("unbound variable " ^ name id); ! 191: VARbind(mkVALvar(id, ref(VARty(mkTyvar defaultMETA))))) ! 192: ! 193: fun varApplied(v: var, {path, strenv}: info, qid) : var = ! 194: case v ! 195: of VALvar{access,name,typ} => ! 196: VALvar{access = ! 197: (case access ! 198: of SLOT(n) => PATH(n::path) ! 199: | LVAR(n) => PATH([n]) ! 200: | INLINE _ => access ! 201: | PATH _ => impossible "varApplied: access = PATH"), ! 202: typ = ! 203: if Prim.special(access) ! 204: then ref(!typ) ! 205: else (case path ! 206: of [] => typ ! 207: | _ => ref(typeInContext(!typ,strenv))), ! 208: name = qid} ! 209: | _ => v ! 210: ! 211: fun lookVARinTable(table, id) = ! 212: case IntStrMap.map table (varKey id) ! 213: of VARbind v => v ! 214: | _ => raise UnboundTable ! 215: ! 216: fun lookVARCONinTable(table,id) = IntStrMap.map table (varKey id) ! 217: ! 218: fun lookVARCONinStr(STRstr{table,env,stamp,...},id,ap,qid): binding = ! 219: ((case lookVARCONinTable(table,id) ! 220: of VARbind(var) => VARbind(varApplied(var,{path=ap,strenv=env},qid)) ! 221: | CONbind(dcon) => CONbind(dconApplied(dcon,{path=ap,strenv=env})) ! 222: | _ => impossible "EnvAccess.lookVARCONinStr 1") ! 223: handle UnboundTable => ! 224: (if stamp=bogusStrStamp then () ! 225: else complain("unbound variable or constructor in structure: " ! 226: ^ Symbol.name id); ! 227: CONbind bogusCON)) ! 228: | lookVARCONinStr(NULLstr,id,_,_) = ! 229: (printSym id; print "\n"; impossible "EnvAccess.lookVARCONinStr 2") ! 230: | lookVARCONinStr(_,id,_,_) = ! 231: (printSym id; print "\n"; impossible "EnvAccess.lookVARCONinStr 3") ! 232: ! 233: fun lookVARCON id = ! 234: case lookRec(varKey id) ! 235: of LOCAL(VARbind v, info) => VARbind(varApplied(v,info,[id])) ! 236: | LOCAL(CONbind d, info) => CONbind(dconApplied(d,info)) ! 237: | GLOBAL(CONbind d, info) => CONbind(dconApplied(d,info)) ! 238: | GLOBAL(VARbind _, _) => raise Unboundrec ! 239: | _ => impossible "EnvAccess.lookVARCON" ! 240: ! 241: fun lookVARCONlocal id = ! 242: case lookStrLocal(varKey id) ! 243: of (VARbind v, info) => VARbind(varApplied(v,info,[id])) ! 244: | (CONbind d, info) => CONbind(dconApplied(d,info)) ! 245: | _ => impossible "EnvAccess.lookVARCON" ! 246: ! 247: fun lookVARRecLocal id = ! 248: case lookRecLocal(varKey id) ! 249: of (VARbind v, info) => varApplied(v,info,[id]) ! 250: | _ => impossible "EnvAccess.lookVARRecLocal" ! 251: ! 252: (* patching deferred variables *) ! 253: ! 254: val varPatchList : var ref list ref = ref nil ! 255: ! 256: fun getPatchVar id = ! 257: let val v = ref (UNKNOWNvar id) ! 258: in varPatchList := v :: !varPatchList; ! 259: v ! 260: end ! 261: ! 262: exception Patched ! 263: ! 264: fun patchVars (pl as (varRef as ref(UNKNOWNvar id))::pl', tl) = ! 265: ((varRef := lookVARRecLocal id; raise Patched) ! 266: handle Unboundrec => ! 267: patchVars(pl',varRef::tl) (* not yet bound; try later *) ! 268: | Unbound => (* no more rec layers *) ! 269: let val VARbind v = unboundVAR id ! 270: in varRef := v; patchVars(pl',tl) ! 271: end ! 272: | Patched => patchVars(pl', tl)) ! 273: | patchVars (nil, tl) = tl ! 274: | patchVars _ = impossible "EnvAccess.patchVars" ! 275: ! 276: val protectPatchList = ! 277: ((fn () => !varPatchList before (varPatchList := nil)), ! 278: (fn (vpl) => varPatchList := patchVars(!varPatchList,vpl))) ! 279: (* bug -- exit function only works right for normal exit from protect *) ! 280: ! 281: fun capitalized string = ! 282: (* string starts with a capital letter *) ! 283: let val firstchar = ordof(string,0) ! 284: in firstchar >= Ascii.uc_a andalso firstchar <= Ascii.uc_z ! 285: end ! 286: ! 287: (* Could be used to enforce the Capitalization convention, but isn't *) ! 288: fun checkBinding(id: symbol,_) = ! 289: if capitalized(Symbol.name id) ! 290: then warn("Capitalized variable in rule: "^ Symbol.name id) ! 291: else () ! 292: ! 293: ! 294: fun newVAR(bl: (symbol * var) list ref, id: symbol) : var = ! 295: let fun checkid ((i,b)::bl) = ! 296: if Symbol.eq(i,id) ! 297: then complain "repeated var in pattern" ! 298: else checkid bl ! 299: | checkid nil = () ! 300: in checkid(!bl); ! 301: let val v = mkVALvar(id,ref UNDEFty) ! 302: in bl := (id, v) :: !bl; ! 303: v ! 304: end ! 305: end ! 306: ! 307: fun bindVAR(id: symbol, v: var) = ! 308: let val binding = VARbind v ! 309: in add(varIndex id, name id, binding); binding ! 310: end ! 311: ! 312: fun bindVARs(binders: (symbol * var) list) = ! 313: app (fn b as (id,bind) => ! 314: (if !debugBind ! 315: then (print "bindVARs: "; printSym id; newline()) ! 316: else (); ! 317: bindVAR b)) ! 318: binders ! 319: ! 320: ! 321: (* type variables *) ! 322: ! 323: datatype mode = EXP | TYPEDEC ! 324: ! 325: val tyvarsMode = ref(EXP) ! 326: val boundTyvars = ref([]:tyvar list) ! 327: ! 328: fun protectTyvars NONE = ! 329: ((fn () => (!boundTyvars before (boundTyvars := []))), ! 330: (fn btv => boundTyvars := btv)) ! 331: | protectTyvars (SOME tvs) = ! 332: ((fn () => (!boundTyvars before (boundTyvars := tvs; tyvarsMode := TYPEDEC))), ! 333: (fn btv => (boundTyvars := btv; tyvarsMode := EXP))) ! 334: ! 335: fun currentTyvars () = !boundTyvars ! 336: ! 337: fun lookTYV id = ! 338: let val (TYVbind tyv, _) = lookStrLocal(tyvKey id) in tyv end ! 339: ! 340: fun lookTyvar (id: symbol) = ! 341: case !tyvarsMode ! 342: of TYPEDEC => ! 343: let fun find ((tv as ref(UBOUND{name=id',...}))::resttvs) = ! 344: if Symbol.eq(id,id') ! 345: then tv ! 346: else find(resttvs) ! 347: | find([]) = ! 348: (complain "lookTyvar -- unbound tyvar in closed scope"; ! 349: mkTyvar(INSTANTIATED UNDEFty)) ! 350: | find _ = impossible "EnvAccess.lookTyvar.find" ! 351: in find(!boundTyvars) ! 352: end ! 353: | EXP => ! 354: lookTYV id ! 355: handle Unbound => (* here we could check for weakness > 0 *) ! 356: let val tyv = mkTyvar(mkUBOUND id) ! 357: in add(tyvIndex id, name id, TYVbind tyv); ! 358: boundTyvars := tyv :: !boundTyvars; ! 359: tyv ! 360: end; ! 361: ! 362: ! 363: (* exceptions *) ! 364: ! 365: fun notInitialLowerCase string = ! 366: (* string does NOT start with lower-case alpha *) ! 367: let val firstchar = ordof(string,0) ! 368: in firstchar < Ascii.lc_a orelse firstchar > Ascii.lc_z ! 369: end ! 370: ! 371: (* Could be used to enforce the Capitalization convention *) ! 372: fun looksLikeExn sym = notInitialLowerCase(Symbol.name sym) ! 373: ! 374: fun unboundEXN id = ! 375: (complain("unbound exn: " ^ name id); bogusCON) ! 376: ! 377: fun lookEXNinStr(STRstr{table,env,stamp,...},id,ap,qid) = ! 378: (dconApplied(lookCONinTable(table,id),{path=ap,strenv=env}) ! 379: handle UnboundTable => ! 380: (if stamp=bogusStrStamp then () ! 381: else complain("unbound exception in path: " ^ Symbol.name id); ! 382: bogusCON)) ! 383: | lookEXNinStr _ = impossible "EnvAccess.lookEXNinStr" ! 384: ! 385: ! 386: (* signatures *) ! 387: ! 388: val bogusSIGStampsets = Stampset.newStampsets() ! 389: val bogusSIGbody = ! 390: STRstr{stamp=Stampset.newStamp(#strStamps bogusSIGStampsets), ! 391: sign=Stampset.newStamp(Stampset.sigStamps), ! 392: table=newTable(), ! 393: env=DIR, ! 394: kind=SIGkind{share={s=nil,t=nil}, ! 395: bindings=nil,stamps=bogusSIGStampsets}} ! 396: val bogusSIG=SIGvar{name=bogusID,binding=bogusSIGbody} ! 397: ! 398: fun lookSIG id = ! 399: let val (SIGbind sign,_) = look(sigKey id) ! 400: in sign ! 401: end ! 402: handle Unbound => (complain("unbound signature: " ^ name id); bogusSIG) ! 403: ! 404: fun bindSIG(id: symbol, s: signatureVar) = add(sigIndex id, name id, SIGbind s) ! 405: ! 406: ! 407: (* structures *) ! 408: ! 409: fun strApplied(STRvar{name,access,binding},{path=ap,strenv},qid) = ! 410: STRvar{name=qid, ! 411: binding=(case (binding,strenv) ! 412: of (INDstr i,REL{s,...}) => s sub i ! 413: | (SHRstr(i::r),REL{s,...}) => getEpath(r,s sub i) ! 414: | (STRstr _, _) => binding ! 415: | _ => impossible "strApplied: bad binding/env"), ! 416: access=(case access ! 417: of SLOT(n) => PATH(n::ap) ! 418: | LVAR(n) => PATH [n] ! 419: | _ => impossible "strApplied: access = PATH or INLINE")} ! 420: ! 421: fun lookSTRinTable(table, id) = ! 422: let val STRbind strvar = IntStrMap.map table (strKey id) in strvar end ! 423: ! 424: fun lookSTR0 id = ! 425: let val (STRbind str, info) = look(strKey id) ! 426: in (str,info) ! 427: end ! 428: ! 429: fun lookSTR' look id = ! 430: let val (STRbind str, info) = look(strKey id) ! 431: in strApplied(str,info,[id]) ! 432: end ! 433: val lookSTR = lookSTR' look ! 434: val lookSTRlocal = lookSTR' lookStrLocal ! 435: ! 436: fun lookSTRinStr(STRstr{table,env,stamp,...},id,ap,qid) = ! 437: (strApplied(lookSTRinTable(table,id),{path=ap,strenv=env},qid) ! 438: handle UnboundTable => ! 439: (if stamp=bogusStrStamp then () ! 440: else complain("unbound structure in path: " ^ Symbol.name id); ! 441: bogusSTR)) ! 442: | lookSTRinStr _ = impossible "EnvAccess.lookSTRinStr" ! 443: ! 444: fun bindSTR(id: symbol, strvar: structureVar) = ! 445: let val binding = STRbind strvar ! 446: in add(strIndex id, name id, binding); ! 447: binding ! 448: end ! 449: ! 450: ! 451: (* functors *) ! 452: ! 453: val bogusFCT = FCTvar{name=bogusID, access=PATH[0], ! 454: binding=FUNCTOR{paramName=bogusID, ! 455: param=bogusSIGbody, ! 456: body=bogusSIGbody, ! 457: paramVis=false, ! 458: stamps=Stampset.newStampsets()}} ! 459: ! 460: fun lookFCT id = ! 461: let val (FCTbind fv,_) = look(fctKey id) in fv end ! 462: handle Unbound => ! 463: (complain("unbound functor identifier: " ^ Symbol.name id); ! 464: bogusFCT) ! 465: ! 466: fun bindFCT(id: symbol, f: functorVar) = add(fctIndex id, name id, FCTbind f) ! 467: ! 468: (* fixity bindings *) ! 469: ! 470: fun lookFIX id = ! 471: if true (* !(Symbol.infixed id) *) ! 472: then let val (FIXbind(FIXvar{binding,...}),_) = look(fixKey id) ! 473: in binding ! 474: end ! 475: handle Unbound => ((* Symbol.infixed id := false; *) NONfix) ! 476: else NONfix ! 477: ! 478: fun bindFIX(id: symbol, f: fixityVar) = ! 479: let val binding = FIXbind f ! 480: in add(fixIndex id, name id, binding); binding ! 481: end ! 482: ! 483: (* lookup using symbolic path *) ! 484: fun lookPathinStr ! 485: (str: Structure, ap: Access.path, spath as _::rest : symbol list, ! 486: lookLast: Structure * symbol * Access.path * symbol list -> 'a) : 'a = ! 487: let fun getStr([id],str,ap) = lookLast(str,id,ap,spath) ! 488: | getStr(id::rest,STRstr{table,stamp,env,...},ap) = ! 489: let val STRvar{access=SLOT n,binding,...} = ! 490: lookSTRinTable(table,id) ! 491: handle UnboundTable => ! 492: (if stamp=bogusStrStamp then () ! 493: else (complain("unbound intermediate structure: " ! 494: ^ name id); ! 495: print " in path: "; ! 496: printSequence "." printSym spath; ! 497: newline()); ! 498: bogusSTR') ! 499: in getStr(rest, ! 500: (case binding ! 501: of INDstr i => ! 502: (case env ! 503: of REL{s,...} => s sub i ! 504: | DIR => impossible "lookPathinStr.getStr 1") ! 505: | SHRstr(i::r) => ! 506: (case env ! 507: of REL{s,...} => getEpath(r,s sub i) ! 508: | DIR => impossible "lookPathinStr.getStr 2") ! 509: | _ => binding), ! 510: n::ap) ! 511: end ! 512: | getStr _ = impossible "EnvAccess.lookPathinStr.getStr" ! 513: in getStr(rest,str,ap) ! 514: end ! 515: | lookPathinStr _ = impossible "EnvAccess.lookPathinStr" ! 516: ! 517: fun lookPath(spath as first::rest, ! 518: lookLast: Structure * symbol * Access.path * symbol list -> 'a) : 'a = ! 519: let val STRvar{access=PATH(ap),binding,...} = ! 520: lookSTR first ! 521: handle Unbound => ! 522: (complain("unbound head structure: " ^ name first); ! 523: print " in path: "; printSequence "." printSym spath; ! 524: newline(); ! 525: bogusSTR) ! 526: in lookPathinStr(binding,ap,spath,lookLast) ! 527: end ! 528: | lookPath _ = impossible "EnvAccess.lookPath" ! 529: ! 530: ! 531: fun lookPathArTYC0 (path: symbol list, arity: int) = ! 532: let val tycref as ref tyc = lookPath(path, fn(str,id,_,_) => lookTYCinStr(str,id)) ! 533: in checkArity(tyc,arity); ! 534: tycref ! 535: end ! 536: ! 537: (* debug print functions *) ! 538: val prIntPath = printClosedSequence ("[",",","]") (print:int->unit) ! 539: fun prSymPath spath = printSequence "." printSym (rev spath) ! 540: ! 541: fun lookPathArTYCinSig (depth: int) (spath as first::rest, arity) : tycon ref = ! 542: let fun complainUnbound() = ! 543: (complain "unbound type constructor in signature"; ! 544: print " name: "; printSequence "." printSym spath; ! 545: newline(); ! 546: raise Syntax) ! 547: (* second arg of get is expected to be a signature *) ! 548: fun get([id],STRstr{table,env as REL{t,...},...}) = ! 549: (case lookTYCinTable(table,id) ! 550: handle UnboundTable => complainUnbound() ! 551: of ref(INDtyc i) => (checkArity(t sub i, arity); [i]) ! 552: | ref(SHRtyc p) => (checkArity(getEpathTyc(p,env), arity); p) ! 553: | _ => impossible "lookPathArTYCinSig.get") ! 554: | get(id::rest,STRstr{table,env=REL{s,...},...}) = ! 555: let val STRvar{binding=INDstr k,...} = ! 556: lookSTRinTable(table,id) ! 557: handle UnboundTable => complainUnbound() ! 558: in k::get(rest, s sub k) ! 559: end ! 560: | get([],_) = impossible "EnvAccess.lookPathArTYCinSig.get - empty path" ! 561: | get(p,NULLstr) = ! 562: (prSymPath p; print "\n"; ! 563: impossible "EnvAccess.lookPathArTYCinSig.get - NULLstr") ! 564: | get(p,INDstr _) = ! 565: (prSymPath p; print "\n"; ! 566: impossible "EnvAccess.lookPathArTYCinSig.get - INDstr") ! 567: | get(p,SHRstr _) = ! 568: (prSymPath p; print "\n"; ! 569: impossible "EnvAccess.lookPathArTYCinSig.get - SHRstr") ! 570: | get _ = impossible "EnvAccess.lookPathArTYCinSig.get - bad args" ! 571: fun lookInStr(str) = ! 572: let val tycref = ! 573: lookPathinStr(str, [], spath, ! 574: (fn(str,id,_,_) => lookTYCinStr(str,id))) ! 575: in checkArity(!tycref,arity); ! 576: tycref ! 577: end ! 578: val leadStr = lookSTR0 first ! 579: handle Unbound => complainUnbound() ! 580: in case leadStr ! 581: of (STRvar{binding=INDstr i,...},{path=h::r,strenv=REL{s,...}}) => ! 582: if h < 0 (* indicates signature component *) ! 583: then ref(RELtyc(addzeros(depth+h,r@(i::get(rest, s sub i))))) ! 584: else lookInStr(s sub i) ! 585: | (STRvar{binding=SHRstr(i::r),...},{strenv=REL{s,...},...}) => ! 586: lookInStr(getEpath(r, s sub i)) ! 587: | (STRvar{binding as STRstr _,...},_) => lookInStr binding ! 588: | _ => impossible "EnvAccess.lookPathArTYCinSig - leadStr" ! 589: end ! 590: | lookPathArTYCinSig _ _ = impossible "lookPathArTYCinSig - bad arg" ! 591: ! 592: val lookPathArTYC = ref lookPathArTYC0 ! 593: ! 594: ! 595: (* functions to collect stale lvars for unbinding *) ! 596: exception LOOKLVAR ! 597: ! 598: fun lookLvar (env: env) (key: int * string) = ! 599: case lookEnv(env,key) ! 600: of (VARbind(VALvar{access=LVAR v,...}),_) => v ! 601: | (STRbind(STRvar{access=LVAR v,...}),_) => v ! 602: | (FCTbind(FCTvar{access=LVAR v,...}),_) => v ! 603: | _ => raise LOOKLVAR ! 604: ! 605: fun runbound index = ! 606: case index mod namespaces ! 607: of 0 => true (* var *) ! 608: | 4 => true (* structure *) ! 609: | 5 => true (* functor *) ! 610: | _ => false ! 611: ! 612: fun staleLvars(newenv,oldenv) : int list = ! 613: let val lvarset = ref([] : int list) ! 614: val get = lookLvar oldenv ! 615: fun collect (i,s,_) = ! 616: if runbound i ! 617: then (lvarset := get(i,s) :: !lvarset) ! 618: handle LOOKLVAR => () ! 619: | Unbound => () ! 620: else () ! 621: in appenv collect (newenv,oldenv); ! 622: !lvarset ! 623: end ! 624: ! 625: (* reset state of EnvAccess *) ! 626: fun reset() = ! 627: (varPatchList := nil; ! 628: boundTyvars := []; ! 629: tyvarsMode := EXP) ! 630: ! 631: end (* structure EnvAccess *)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.