############################################################################
#
# File: ximage.icn
#
# Subject: Procedures to produce string image of structured data
#
# Author: Robert J. Alexander
#
# Date: May 19, 1996
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# ximage(x) : s
#
# Produces a string image of x. ximage() differs from image() in that
# it outputs all elements of structured data types. The output
# resembles Icon code and is thus familiar to Icon programmers.
# Additionally, it indents successive structural levels in such a way
# that it is easy to visualize the data's structure. Note that the
# additional arguments in the ximage procedure declaration are used for
# passing data among recursive levels.
#
# xdump(x1,x2,...,xn) : xn
#
# Using ximage(), successively writes the images of x1, x2, ..., xn to
# &errout.
#
# Some Examples:
#
# The following code:
# ...
# t := table() ; t["one"] := 1 ; t["two"] := 2
# xdump("A table",t)
# xdump("A list",[3,1,3,[2,4,6],3,4,3,5])
#
# Writes the following output (note that ximage() infers the
# predominant list element value and avoids excessive output):
#
# "A table"
# T18 := table(&null)
# T18["one"] := 1
# T18["two"] := 2
# "A list"
# L25 := list(8,3)
# L25[2] := 1
# L25[4] := L24 := list(3)
# L24[1] := 2
# L24[2] := 4
# L24[3] := 6
# L25[6] := 4
# L25[8] := 5
#
procedure ximage(x,indent,done) #: string image of value
local i,s,ss,state,t,xtag,tp,sn,sz, prefix
static tr, name
initial name := proc("name", 0) # REG: in case name is a global
#
# If this is the outer invocation, do some initialization.
#
if /(state := done) then {
tr := &trace ; &trace := 0 # postpone tracing while in here
indent := ""
done := table()
}
#
# Determine the type and process accordingly.
#
indent := (if indent == "" then "\n" else "") || indent || " "
ss := ""
tp := type(x)
s := if xtag := \done[x] then xtag else case tp of {
#
# Unstructured types just return their image().
#
"integer": x
"null" | "string" | "real" | "cset" | "window" | "thread" |
"co-expression" | "file" | "procedure" | "external" | "pattern": image(x)
#
# List.
#
"list": {
image(x) ? {
tab(6)
sn := tab(find("("))
sz := tab(0)
}
done[x] := xtag := "L" || sn
#
# Figure out if there is a predominance of any object in the
# list. If so, make it the default object.
#
t := table(0)
every t[!x] +:= 1
s := [,0]
every t := !sort(t) do if s[2] < t[2] then s := t
if s[2] > *x / 3 & s[2] > 2 then {
s := s[1]
t := ximage(s,indent || " ",done)
if t ? (not any('\'"') & ss := tab(find(" :="))) then
t := "{" || t || indent || " " || ss || "}"
}
else s := t := &null
#
# Output the non-defaulted elements of the list.
#
ss := ""
every i := 1 to *x do if x[i] ~=== s then {
ss ||:= indent || xtag || "[" || i || "] := " ||
ximage(x[i],indent,done)
}
s := tp || sz
s[-1:-1] := "," || \t
xtag || " := " || s || ss
}
#
# Set.
#
"set": {
image(x) ? {
tab(5)
sn := tab(find("("))
}
done[x] := xtag := "S" || sn
every i := !sort(x) do {
t := ximage(i,indent || " ",done)
if t ? (not any('\'"') & s := tab(find(" :="))) then
t := "{" || t || indent || " " || s || "}"
ss ||:= indent || "insert(" || xtag || "," || t || ")"
}
xtag || " := " || "set()" || ss
}
#
# Table.
#
"table": {
image(x) ? {
tab(7)
sn := tab(find("("))
}
done[x] := xtag := "T" || sn
#
# Output the table elements. This is a bit tricky, since
# the subscripts might be structured, too.
#
every i := !sort(x) do {
t := ximage(i[1],indent || " ",done)
if t ? (not any('\'"') & s := tab(find(" :="))) then
t := "{" || t || indent || " " || s || "}"
ss ||:= indent || xtag || "[" ||
t || "] := " ||
ximage(i[2],indent,done)
}
#
# Output the table, including its default value (which might
# also be structured).
#
t := ximage(x[[]],indent || " ",done)
if t ? (not any('\'"') & s := tab(find(" :="))) then
t := "{" || t || indent || " " || s || "}"
xtag || " := " || "table(" || t || ")" || ss
}
#
# Record.
#
default: {
image(x) ? {
prefix := move(7) |
write(&errout, "ximage expected \"record\" in ", image(x))
t := ""
while t ||:= tab(find("_")) || move(1)
t[-1] := ""
sn := tab(find("("))
}
done[x] := xtag := (if prefix=="record " then "R_" else "") ||
t || "_" || sn
every i := 1 to *x do {
name(x[i]) ? (tab(find(".")),sn := tab(0))
ss ||:= indent || xtag || sn || " := " || ximage(\x[i],indent,done)
}
xtag || " := " || t || "()" || ss
}
}
#
# If this is the outer invocation, clean up before returning.
#
if /state then {
&trace := tr # restore &trace
}
#
# Return the result.
#
return s
end
#
# Write ximages of x1,x1,...,xn.
#
procedure xdump(x[]) #: write images of values
every write(&errout,ximage(!x))
return x[-1] | &null
end
This page produced by UniDoc on 2021/04/15 @ 23:59:43.