|
|
1.1 ! root 1: (* Copyright 1989 by AT&T Bell Laboratories *) ! 2: (* equal.sml *) ! 3: signature EQUAL = ! 4: sig ! 5: structure Basics : BASICS ! 6: structure Lambda : LAMBDA ! 7: val equal : Basics.ty -> Lambda.lexp ! 8: end ! 9: ! 10: structure Equal : EQUAL = ! 11: struct ! 12: ! 13: structure Basics : BASICS = Basics ! 14: structure Lambda : LAMBDA = Lambda ! 15: ! 16: open ErrorMsg Basics Lambda Access BasicTypes TypesUtil ! 17: ! 18: fun translatepath [v] = VAR v ! 19: | translatepath (x::p) = SELECT(x,translatepath p) ! 20: | translatepath nil = ErrorMsg.impossible "equal.translatepath nil" ! 21: ! 22: fun argType(POLYty{tyfun=TYFUN{arity,body=CONty(_,[domain,_])},...}, args) = ! 23: applyTyfun(TYFUN{arity=arity,body=domain},args) ! 24: | argType(CONty(_,[argty,_]), []) = argty ! 25: | argType _ = impossible "Equal.argType" ! 26: ! 27: ! 28: exception Poly ! 29: ! 30: fun atomeq tyc = ! 31: if eqTycon(tyc,!intTycon) ! 32: orelse eqTycon(tyc,!boolTycon) ! 33: orelse eqTycon(tyc,!refTycon) ! 34: orelse eqTycon(tyc,!arrayTycon) then PRIM P.ieql ! 35: else if eqTycon(tyc,!realTycon) then PRIM P.feql ! 36: else if eqTycon(tyc,!stringTycon) then ! 37: translatepath(!CoreInfo.stringequalPath) ! 38: else raise Poly ! 39: ! 40: exception Notfound ! 41: ! 42: val trueLexp = CON(trueDcon,RECORD[]) ! 43: val falseLexp = CON(falseDcon,RECORD[]) ! 44: ! 45: fun equal (concreteType : ty) : lexp = ! 46: let val cache : (ty * lexp * lexp ref) list ref = ref nil ! 47: fun enter ty = ! 48: let val v = VAR(mkLvar()) ! 49: val r = ref v ! 50: in if !System.Control.debugging ! 51: then (print "enter: "; PrintType.printType ty; print "\n") ! 52: else (); ! 53: cache := (ty, v, r) :: !cache; (v,r) ! 54: end ! 55: fun find ty = ! 56: let fun f ((t,v,e)::r) = if equalType(ty,t) then v else f r ! 57: | f nil = (if !System.Control.debugging ! 58: then print "find-notfound\n" ! 59: else (); ! 60: raise Notfound) ! 61: in if !System.Control.debugging ! 62: then (print "find: "; PrintType.printType ty; print "\n") ! 63: else (); ! 64: f (!cache) ! 65: end ! 66: ! 67: fun test(ty) = ! 68: (if !System.Control.debugging ! 69: then (print "test: "; PrintType.printType ty; print "\n") ! 70: else (); ! 71: case ty ! 72: of VARty(ref(INSTANTIATED t)) => test t ! 73: | FLEXRECORDty(ref(CLOSED t)) => test t ! 74: | CONty(ref(tyc as TYCON{kind=ABStyc,eq=ref YES,...}),tyl) => atomeq tyc ! 75: | CONty(ref(tyc as TYCON{kind=ABStyc,eq=ref NO,...}),tyl) => ! 76: impossible("Attempt to test opaque type for equality: " ! 77: ^ Symbol.name(tycName tyc)) ! 78: | CONty(ref(TYCON{kind=DEFtyc _,...}),tyl) => test(reduceType ty) ! 79: | CONty(ref(tyc as ! 80: TYCON{kind=DATAtyc([DATACON{const=false,rep,typ,...}]), ! 81: ...}), ! 82: tyl) => ! 83: (case rep ! 84: of TRANSPARENT => ! 85: (find ty handle Notfound => ! 86: let val (eqv,patch) = enter ty ! 87: val v = mkLvar() ! 88: val ty' = argType(!typ,tyl) ! 89: in patch := FN(v,APP(test ty', VAR v)); ! 90: eqv ! 91: end) ! 92: | REF => atomeq tyc ! 93: | _ => impossible "Equal #498") ! 94: | CONty(ref(TYCON{kind,...}), tyl) => ! 95: (find ty ! 96: handle Notfound => ! 97: let val v = mkLvar() and x=mkLvar() and y=mkLvar() ! 98: val (eqv, patch) = enter ty ! 99: fun inside (DATACON{const=true,...}) = trueLexp ! 100: | inside (c as DATACON{typ, const=false,...}) = ! 101: APP(test(argType(!typ,tyl)), ! 102: RECORD[DECON(c, VAR x), ! 103: DECON(c, VAR y)]) ! 104: val body = ! 105: case kind ! 106: of DATAtyc([dcon]) => ! 107: inside dcon ! 108: | DATAtyc(dcons) => ! 109: let fun concase dcon = ! 110: (DATAcon(dcon), ! 111: SWITCH(VAR y,[(DATAcon(dcon), inside dcon)], ! 112: SOME(falseLexp))) ! 113: in SWITCH(VAR x,map concase dcons,NONE) ! 114: end ! 115: | RECORDtyc _ => ! 116: let fun loop(n,[ty]) = ! 117: APP(test(ty), RECORD[SELECT(n, VAR x), ! 118: SELECT(n, VAR y)]) ! 119: | loop(n,ty::r) = ! 120: SWITCH(loop(n,[ty]), ! 121: [(DATAcon(trueDcon), loop(n+1,r)), ! 122: (DATAcon(falseDcon), falseLexp)], ! 123: NONE) ! 124: | loop(_,nil) = trueLexp ! 125: in loop(0,tyl) ! 126: end ! 127: | _ => raise Poly ! 128: in patch := FN(v,APP(FN(x,APP(FN(y,body), ! 129: SELECT(1,VAR v))), ! 130: SELECT(0,VAR v))); ! 131: eqv ! 132: end) ! 133: | _ => raise Poly) ! 134: ! 135: val body = test(concreteType) ! 136: ! 137: in FIX(map (fn (_,VAR v,_) => v | _ => impossible "Equal #324") (!cache), ! 138: map (fn (_,_,e) => !e) (!cache), ! 139: body) ! 140: end ! 141: handle Poly => translatepath(!CoreInfo.polyequalPath) ! 142: | Syntax => ! 143: (print "equal: type = "; ! 144: PrintType.resetPrintType(); ! 145: PrintType.printType concreteType; print"\n"; ! 146: RECORD[]) ! 147: ! 148: end (* struct *) ! 149:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.