The basic logic is:
writeObject(x, out, table) {
Info info = table.get(x);
if (info == null) {
info = newInfo(out, table);
table.put(info);
// The tricky part is here, because you might need to emit a #N=
// but you don't know that yet. So you might have to back-patch
// in the output stream - which may change pretty-printer re-flow.
out.writePositionMarker(info);
out.writeObjectRecursive(x);
} else {
out.writeBackReference(info);
}
}
Some implementations
basically solve the problem by essentially printing twice: The first time
just to a dummy output which makes a note of shared structures. I'm
not really keen on that - it seems inefficient. Worse: inconsistencies
seem possible, either the data structure is mutated while it is being
printed, or if there are side-effects in the formatting routines.