|
|
1.1 ! root 1: (* Copyright 1989 by AT&T Bell Laboratories *) ! 2: signature TRANSLATE = sig ! 3: val transDec : Absyn.dec -> Lambda.lexp -> Lambda.lexp ! 4: end ! 5: ! 6: structure Translate : TRANSLATE = ! 7: struct ! 8: open Access Absyn Lambda Basics BasicTypes Nonrec ErrorMsg Unboxed ! 9: ! 10: val unitLexp = RECORD [] ! 11: ! 12: fun composeNOT (x) = ! 13: let val v = mkLvar() ! 14: in FN(v,SWITCH(APP(x, VAR v), ! 15: [(DATAcon falseDcon, CON(trueDcon,unitLexp)), ! 16: (DATAcon trueDcon, CON(falseDcon,unitLexp))],NONE)) ! 17: end ! 18: ! 19: val elemgtr = (fn ((LABEL{number=x,...},_),(LABEL{number=y,...},_))=> x>y); ! 20: val sorted = Sort.sorted elemgtr ! 21: val sortrec = Sort.sort elemgtr ! 22: ! 23: val [bogusID,matchsym,bindsym] = map Symbol.symbol ["bogus","Match","Bind"] ! 24: ! 25: fun raisematch() = (WILDpat,RAISE(CON(!CoreInfo.exnMatch,unitLexp))) ! 26: ! 27: fun reraise() = ! 28: let val v = mkLvar() ! 29: in (VARpat(VALvar{name=[bogusID],access=LVAR v, typ=ref UNDEFty}), RAISE(VAR v)) ! 30: end ! 31: ! 32: val printDepth = System.Control.Print.printDepth ! 33: ! 34: fun translatepath [v] = VAR v ! 35: | translatepath (x::p) = SELECT(x,translatepath p) ! 36: | translatepath nil = impossible "translate.translatepath nil" ! 37: ! 38: fun fill (APPpat(_,p)) = fill p ! 39: | fill (CONSTRAINTpat (p,_)) = fill p ! 40: | fill (LAYEREDpat (p,q)) = (fill p; fill q) ! 41: | fill (RECORDpat {pats = ref (_::_),...}) = () ! 42: | fill (RECORDpat {fields,flex=false,pats,...}) = ! 43: pats := map (fn (_,p) => (fill p; p)) fields ! 44: | fill (pat as RECORDpat {fields,flex=true,typ,pats}) = ! 45: (app (fn (_,p) => fill p) fields; ! 46: let fun find (FLEXRECORDty(ref(CLOSED ty))) = find(ty) ! 47: | find (t as CONty(ref(TYCON{kind=RECORDtyc labels,...}),_)) = ! 48: (typ := t; labels) ! 49: | find _ = (PrintAbsyn.printPat(pat,!printDepth); ! 50: condemn "unresolved flexible record") ! 51: fun merge (a as ((id,p)::r), lab::s) = ! 52: if Symbol.eq(id,lab) then p :: merge(r,s) ! 53: else WILDpat :: merge(a,s) ! 54: | merge (nil, lab::s) = WILDpat :: merge(nil,s) ! 55: | merge (nil,nil) = nil ! 56: | merge _ = impossible "merge in translate" ! 57: in pats := (merge(fields, find(!typ)) handle Syntax => [WILDpat]) ! 58: end) ! 59: | fill _ = () ! 60: ! 61: fun polyequal() = translatepath(!CoreInfo.polyequalPath) ! 62: ! 63: fun getEqualElem (CONty(_,[CONty(_,[t,_]),_])) = t ! 64: | getEqualElem _ = VARty(ref(IBOUND 0)) ! 65: ! 66: fun thinStr(e,NONE) = e ! 67: | thinStr(e,SOME(v,locs)) = APP(FN(v,RECORD(map transLoc locs)), e) ! 68: ! 69: and transLoc trans = ! 70: case trans ! 71: of VALtrans(PATH p) => translatepath p ! 72: | VALtrans(INLINE P.eql) => polyequal() ! 73: | VALtrans(INLINE P.neq) => composeNOT(polyequal()) ! 74: | VALtrans(INLINE i) => PRIM i ! 75: | THINtrans(PATH p,v,locs) => thinStr(translatepath p, SOME(v,locs)) ! 76: | CONtrans(d as DATACON{const=true,...}) => CON(d, unitLexp) ! 77: | CONtrans(d as DATACON{const=false,...}) => ! 78: let val v = mkLvar() in FN(v,CON(d, VAR v)) end ! 79: | _ => impossible "transLoc in translate" ! 80: ! 81: ! 82: ! 83: fun transStr (VARstr(STRvar{access=PATH(path),...})) = translatepath path ! 84: | transStr (STRUCTstr{body,locations}) = ! 85: makedec (SEQdec body) (RECORD(map transLoc locations)) ! 86: | transStr (APPstr{oper=FCTvar{access=LVAR(v),...},argexp,argthin}) = ! 87: APP(VAR v, thinStr(transStr argexp, argthin)) ! 88: | transStr (LETstr(d,body)) = makedec d (transStr body) ! 89: | transStr _ = impossible "Translate.transStr" ! 90: ! 91: and makedec (VALdec vbl) = ! 92: fold (fn (VB{pat=VARpat(VALvar{access=INLINE(_),...}),...},b) => b ! 93: | (VB{pat=CONSTRAINTpat(VARpat(VALvar{access=INLINE _,...}),_), ! 94: exp=_,...},b) => b ! 95: | (VB{pat=VARpat(VALvar{access=LVAR v,...}),exp,...},b) => ! 96: APP(FN(v,b), translate exp) ! 97: | (VB{pat,exp,...},b) => ! 98: (fill pat; ! 99: APP(MC.bindCompile ! 100: [(pat,b),(WILDpat,RAISE(CON(!CoreInfo.exnBind,unitLexp)))], ! 101: translate exp))) ! 102: vbl ! 103: | makedec (a as VALRECdec rvbl) = ! 104: (makedec (nonrec a) ! 105: handle Isrec => ! 106: (fn e => FIX(fold ! 107: (fn (RVB{var=VALvar{access=LVAR(var),...},exp,...}, (vlist,llist,lexp)) ! 108: => (var::vlist, translate exp :: llist, lexp) ! 109: | _ => impossible "#73 in translate") ! 110: rvbl (nil,nil,e)))) ! 111: | makedec (LOCALdec(localdec,visibledec)) = ! 112: makedec(SEQdec[localdec,visibledec]) ! 113: ! 114: | makedec (EXCEPTIONdec ebl) = ! 115: fold(fn (EBgen{exn=DATACON{rep=VARIABLE(LVAR v),name,const,...},...},lexp)=> ! 116: APP(FN(v,lexp), ! 117: if const ! 118: then RECORD[unitLexp,CON(refDcon,STRING (Symbol.name name))] ! 119: else CON(refDcon,STRING (Symbol.name name))) ! 120: | (EBdef{exn=DATACON{rep=VARIABLE(LVAR v),...}, ! 121: edef=DATACON{rep=VARIABLE(PATH p),...}}, ! 122: lexp) => APP(FN(v,lexp),translatepath p) ! 123: | _ => impossible "in makedec EXCEPTIONdec") ! 124: ebl ! 125: ! 126: | makedec (SEQdec decl) = ! 127: (* fold (fn (dec,exp) => makedec dec exp) decl *) ! 128: let fun f(a::r) = (makedec a) o (f r) | f nil = (fn e=>e) in f decl end ! 129: ! 130: | makedec (DATATYPEdec _) = (fn e => e) ! 131: | makedec (ABSTYPEdec{body,...}) = makedec body ! 132: | makedec (TYPEdec _) = (fn e => e) ! 133: | makedec (STRdec sbl) = ! 134: fold(fn (STRB{strvar=STRvar{access=LVAR(v),...},def,thin,...},lexp) => ! 135: APP(FN(v,lexp),thinStr(transStr def, thin)) ! 136: | _ => impossible "makedec(STRdec) in translate") ! 137: sbl ! 138: | makedec (ABSdec sbl) = makedec(STRdec sbl) ! 139: | makedec (FCTdec fbl) = ! 140: fold(fn (FCTB{fctvar=FCTvar{access=LVAR(v),binding,...},def,thin, ! 141: param=STRvar{access=LVAR p,...},...}, ! 142: lexp) => ! 143: APP(FN(v,lexp),FN(p,thinStr(transStr def, thin))) ! 144: | _ => impossible "makedec(FCTdec) in translate") ! 145: fbl ! 146: | makedec (SIGdec _) = (fn e => e) ! 147: | makedec (OPENdec _) = (fn e => e) ! 148: | makedec (MARKdec(dec,a,b)) = makedec dec ! 149: ! 150: and transrules rules = map (fn (RULE(p,e)) => ((fill p; p), translate e)) rules ! 151: ! 152: and translate exp = ! 153: case exp ! 154: of INTexp i => INT i ! 155: | REALexp r => REAL r ! 156: | STRINGexp s => STRING s ! 157: | RECORDexp l => ! 158: if sorted l ! 159: then RECORD(map (fn(_,e)=>translate e) l) ! 160: else let val vars = map (fn (l,e) => (l,(e,mkLvar()))) l ! 161: fun bind ((_,(e,v)), x) = APP(FN(v, x), translate e) ! 162: in fold bind vars (RECORD(map (fn(_,(_,v))=>VAR v) (sortrec vars))) ! 163: end ! 164: | SEQexp [e] => translate e ! 165: | SEQexp (e::r) => APP(FN(mkLvar(), translate(SEQexp r)), translate e) ! 166: | APPexp(CONexp dcon, e) => CON (dcon, translate e) ! 167: | MARKexp(e,_,_) => translate e ! 168: | CONexp(dcon as DATACON{const=false,...}) => ! 169: let val v = mkLvar () in FN(v,CON (dcon, VAR v)) end ! 170: | CONexp (dcon as DATACON{const=true,...}) => CON(dcon, unitLexp) ! 171: | VARexp (ref(VALvar{access=PATH(path),...})) => translatepath path ! 172: | VARexp (ref(VALvar{access=INLINE P.eql,typ=ref ty,...})) => ! 173: Equal.equal(getEqualElem ty) ! 174: | VARexp (ref(VALvar{access=INLINE P.neq,typ=ref ty,...})) => ! 175: composeNOT(Equal.equal(getEqualElem ty)) ! 176: | VARexp (ref(VALvar{access=INLINE P.:=,typ=ref ty,...})) => ! 177: PRIM(unboxedAssign ty) ! 178: | VARexp (ref(VALvar{access=INLINE P.update,typ=ref ty,...})) => ! 179: PRIM(unboxedUpdate ty) ! 180: | VARexp (ref(VALvar{access=INLINE(n),typ=ref ty,...})) => PRIM n ! 181: | VARexp (ref(OVLDvar{name,...})) => ! 182: (complain("unresolved overloading: "^Symbol.name name); unitLexp) ! 183: | APPexp (f,a) => APP(translate f, translate a) ! 184: | CONSTRAINTexp (e,t) => translate e ! 185: | HANDLEexp (e,HANDLER(FNexp l)) => ! 186: let val rules = transrules l ! 187: fun anywild (WILDpat,_) = true ! 188: | anywild (VARpat _,_) = true ! 189: | anywild _ = false ! 190: val rules = if exists anywild rules then rules@[(WILDpat,unitLexp)] ! 191: else rules@[reraise(),(WILDpat,unitLexp)] ! 192: in HANDLE (translate e, MC.matchCompile rules) ! 193: end ! 194: | RAISEexp e => RAISE (translate e) ! 195: | FNexp l => MC.matchCompile((transrules l)@[raisematch()]) ! 196: | CASEexp (e,l) => APP(MC.matchCompile((transrules l)@[raisematch()]), ! 197: translate e) ! 198: | LETexp (d,e) => makedec d (translate e) ! 199: | x => (PrintAbsyn.printExp(x,0,!printDepth); impossible "in translate") ! 200: ! 201: val transDec = makedec ! 202: ! 203: end (* structure Translate *)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.