structure Types = struct type unique = unit ref datatype ty = RECORD of (Symbol.symbol * ty) list * unique | NIL | INT | STRING | ARRAY of ty * unique | NAME of Symbol.symbol * ty option ref | UNIT fun joinstrs sep [] = "" | joinstrs sep l = foldr (fn (e, s) => s ^ sep ^ e) (hd l) (tl l) fun name t = let fun namex (RECORD(bindings, unique), seen) = (case List.find (fn x => x = RECORD(bindings,unique)) seen of SOME x => "#1" | NONE => "RECORD(" ^ (joinstrs "," (map (fn (name, ty) => (Symbol.name name) ^ ": " ^ (namex (ty, [RECORD(bindings,unique)]))) bindings)) ^ ")") | namex (NIL, seen) = "NIL" | namex (INT, seen) = "INT" | namex (STRING, seen) = "STRING" | namex (ARRAY(ty, unique), seen) = ("ARRAY of " ^ (namex (ty, seen))) | namex (NAME(sym, ref tyo), seen) = (case tyo of (SOME x) => "NAME(" ^ (Symbol.name sym) ^ ") of " ^ (namex (x, x::seen)) | NONE => "NAME(" ^ (Symbol.name sym) ^ ") of NONE") | namex (UNIT, seen) = "UNIT" in namex(t,[]) end fun print t = let fun spc 0 = () | spc n = (TextIO.print " "; spc (n-1)) fun print_n (RECORD(bindings, unique), n) = (spc n; TextIO.print "RECORD(\n"; app (fn (name, binding) => (spc (n); TextIO.print ((Symbol.name name) ^ " ->\n"); print_n(binding,n+1))) bindings; spc n; TextIO.print ")\n") | print_n (NIL, n) = (spc n; TextIO.print "NIL\n") | print_n (INT, n) = (spc n; TextIO.print "INT\n") | print_n (STRING,n) = (spc n; TextIO.print "STRING\n") | print_n (ARRAY(ty,unique), n) = (spc n; TextIO.print "ARRAY of\n"; print_n(ty,n+1)) | print_n (NAME(sym,oref), n) = (spc n; TextIO.print ("NAME = " ^ (Symbol.name sym) ^ " ->\n"); case oref of (ref (SOME x)) => (spc (n+1); TextIO.print "SOME\n") | (ref NONE) => (spc (n+1); TextIO.print "NONE\n")) | print_n (UNIT, n) = (spc n; TextIO.print "UNIT\n") in print_n(t,0) end end