|
|
1.1 ! root 1: (* Copyright 1989 by AT&T Bell Laboratories *) ! 2: (* printval.sml *) ! 3: ! 4: structure PrintVal: PRINTVAL = ! 5: struct ! 6: ! 7: structure Basics = Basics ! 8: ! 9: open System System.Unsafe Basics BasicTypes TypesUtil ErrorMsg PrintUtil ! 10: ! 11: fun gettag obj = int (tuple obj sub 1) ! 12: ! 13: exception Switch ! 14: ! 15: fun switch(obj, TYCON{kind=DATAtyc dcons,...}) = ! 16: let fun try ((d as DATACON{rep,...})::r) = ! 17: (case rep ! 18: of TAGGED i => if (gettag obj = i handle Boxity => false) ! 19: then d else try r ! 20: | CONSTANT i => if (int obj = i handle Boxity => false) ! 21: then d else try r ! 22: | TRANSPARENT => ! 23: if ((tuple obj; true) handle Boxity => false) ! 24: then d else (try r handle Switch => d) ! 25: | TRANSB => if ((tuple obj; true) handle Boxity => false) ! 26: then d else try r ! 27: | TRANSU => if ((int obj; true) handle Boxity => false) ! 28: then d else try r ! 29: | REF => d ! 30: | _ => ErrorMsg.impossible "PrintVal.switch: funny datacon") ! 31: | try nil = raise Switch ! 32: in try dcons ! 33: handle Switch => ! 34: ErrorMsg.impossible "PrintVal.switch: none of the datacons matched" ! 35: end ! 36: ! 37: fun decon(obj, DATACON{rep,...}) = ! 38: case rep ! 39: of UNDECIDED => ErrorMsg.impossible "undecided datacon in decon" ! 40: | TAGGED _ => tuple obj sub 0 ! 41: | CONSTANT _ => ErrorMsg.impossible "constant datacon in decon" ! 42: | TRANSPARENT => obj ! 43: | TRANSU => obj ! 44: | TRANSB => obj ! 45: | REF => tuple obj sub 0 ! 46: | VARIABLE _ => tuple obj sub 0 ! 47: ! 48: val noparen = INfix(0,0) ! 49: ! 50: fun printVal(obj: object, ty: ty, depth: int) : unit = ! 51: printVal'(obj, ty, depth, noparen, noparen) ! 52: ! 53: and printVal'(_,_,0,_,_) = print "#" ! 54: | printVal'(obj: object, ty: ty, depth: int, l: fixity, r: fixity) : unit = ! 55: case ty ! 56: of VARty(ref(INSTANTIATED t)) => printVal'(obj,t,depth,r,l) ! 57: | FLEXRECORDty(ref(CLOSED t)) => printVal'(obj,t,depth,r,l) ! 58: | CONty(ref(tyc as TYCON{kind,...}), argtys) => (* wrong!? *) ! 59: (case kind ! 60: of ABStyc => ! 61: if eqTycon(tyc,!intTycon) then print(makestring(int obj)) ! 62: else if eqTycon(tyc,!realTycon) then print(makestring(real obj)) ! 63: else if eqTycon(tyc,!stringTycon) then pr_mlstr(string obj) ! 64: else if eqTycon(tyc,!arrowTycon) then print "fn" ! 65: else print "-" ! 66: | DEFtyc _ => ! 67: printVal'(obj, reduceType ty, depth, l, r) ! 68: | DATAtyc _ => ! 69: if eqTycon(tyc,!listTycon) ! 70: then printList(obj, hd argtys, depth) ! 71: else printDcon(obj, tyc, argtys, depth, l, r) ! 72: | RECORDtyc [] => print "()" ! 73: | RECORDtyc labels => ! 74: if Tuples.isTUPLEtyc tyc ! 75: then printTuple(tuple(obj), argtys, depth) ! 76: else printRecord(tuple(obj), labels, argtys, depth)) ! 77: | POLYty{tyfun=TYFUN{body,...},...} => printVal'(obj,body,depth,l,r) ! 78: | _ => print "-" ! 79: ! 80: and printDcon(_,_,_,0,_,_) = print "#" ! 81: | printDcon(obj:object, tyc as TYCON{arity,...}, argtys, ! 82: depth:int, l:fixity, r:fixity) = ! 83: let val dcon as DATACON{name,const,typ,...} = switch(obj,tyc) ! 84: val dname = Symbol.name name ! 85: in if const ! 86: then print dname ! 87: else ! 88: let val fixity = EnvAccess.lookFIX name (* may be inaccurate *) ! 89: val dom = case !typ ! 90: of CONty(_,dom::_) => dom ! 91: | POLYty{tyfun=TYFUN{body=CONty(_,dom::_),...},...} => ! 92: applyTyfun(TYFUN{arity=arity,body=dom},argtys) ! 93: val dom = headReduceType(dom) ! 94: fun prdcon() = ! 95: case (fixity,dom) ! 96: of (INfix _,CONty(ref(domTyc as TYCON{kind=RECORDtyc _,...}), ! 97: [tyL,tyR])) => ! 98: let val twoTuple = tuple(decon(obj,dcon)) ! 99: in if Tuples.isTUPLEtyc domTyc ! 100: then ( ! 101: printVal'(twoTuple sub 0,tyL,depth-1,NONfix,fixity); ! 102: print " "; print dname; print " "; ! 103: printVal'(twoTuple sub 1,tyR,depth-1,fixity,NONfix)) ! 104: else ( ! 105: print dname; print " "; ! 106: printVal'(decon(obj,dcon),dom,depth-1,NONfix,NONfix)) ! 107: end ! 108: | _ => ! 109: (print dname; print " "; ! 110: printVal'(decon(obj,dcon),dom,depth-1,NONfix,NONfix)) ! 111: fun prpardcon() = (print "("; prdcon(); print ")") ! 112: in case(l,r,fixity) ! 113: of (NONfix,NONfix,_) => prpardcon() ! 114: | (INfix _,INfix _,_) => prdcon() ! 115: (* special case: only on first iteration, for no parens *) ! 116: | (_,_,NONfix) => prdcon() ! 117: | (INfix(_,p1),_,INfix(p2,_)) => ! 118: if p1 >= p2 then prpardcon() ! 119: else prdcon() ! 120: | (_,INfix(p1,_),INfix(_,p2)) => ! 121: if p1 > p2 then prpardcon() ! 122: else prdcon() ! 123: end ! 124: end ! 125: ! 126: and printList(obj:object, ty:ty, depth:int) : unit = ! 127: let fun printTail(separator, p) = ! 128: let val dcon as DATACON{name,...} = switch(p, !listTycon) ! 129: in case (Symbol.name name) ! 130: of "nil" => print "]" ! 131: | "::" => ! 132: let val pair = tuple(decon(p, dcon)) ! 133: in print separator; ! 134: printVal(pair sub 0, ty, depth-1); ! 135: printTail (",", pair sub 1) ! 136: end ! 137: end ! 138: in print "["; printTail("",obj) ! 139: end ! 140: ! 141: and printTuple(objs: object array, tys: ty list, depth:int) : unit = ! 142: let fun printFields(nf,[ty]) = printVal(objs sub nf,ty,depth-1) ! 143: | printFields(nf, ty::restty) = ! 144: (printVal(objs sub nf,ty,depth-1); print(","); ! 145: printFields(nf+1,restty)) ! 146: | printFields(nf,[]) = () ! 147: in print("("); printFields(0,tys); print(")") ! 148: end ! 149: ! 150: and printRecord(objs: object array, labels: label list, tys: ty list, depth:int) = ! 151: let fun printFields(nf,[l],[ty]) = ! 152: (print(Symbol.name l); print("="); printVal(objs sub nf,ty,depth-1)) ! 153: | printFields(nf, l::restl, ty::restty) = ! 154: (print(Symbol.name l); print("="); printVal(objs sub nf,ty,depth-1); ! 155: print(","); printFields(nf+1,restl,restty)) ! 156: | printFields(nf,[],[]) = () ! 157: in print("{"); printFields(0,labels,tys); print("}") ! 158: end ! 159: ! 160: end (* structure PrintVal *)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.