Implementation details of our pretty-printing support.
My implementation is very much based on ACL2's pretty printer. The
pretty printer operates in two linear passes: the first pass builds a data
structure that tells the second pass how to print. The basic algorithm dates
from about 1971 and was used in the earliest Edinburgh Pure Lisp Theorem
Prover. It is described in:
Robert S. Boyer. Pretty-Print. Memo
number 64. Department of Computational Logic, School of Artificial
Intelligence, University of Edinburgh. 1973.
Some general principles of pretty-printer are:
- Print flat whenever possible, unless argument lists of length over (say)
40; since they become hard to parse.
- Atoms and eviscerated things (which print like atoms, e.g., <world>)
may be printed on a single line.
- Parenthesized expressions should not be printed on a line with any other
argument (unless the whole form fits on the line).
(foo (bar a) b c d) | (foo (bar a) b |
c d) |
(foo a b |
c d) | ^^ we think it's too easy to
miss 'b' when reading this
(foo (bar a) |
b c d) |
- Notes about some ACL2 pretty-printer settings that are not
implemented in our printconfig-p objects.
- Options that govern various aspects of pretty-printing, e.g., the
margins, numeric base, home package for printing symbols, etc.
- Print a character list, escaping backslashes and some other character.
- How many characters are required to print an atom? (BOZO: roughly)
- Print a string, escaping backslashes and some other character.
- How many characters are required to print an object. (bounded)
- Basic merging of flat singleton objects into rows.
- Low-level routine to do both passes of pretty-printing.
- Internal "instruction" data structure used by our pretty-printing
- Does a pretty-printer instruction represent a single object, which
could plausibly be the value of a keyword parameter?
- We print the elements of x, separated by spaces. If x is a
non-nil atom, we print a dot and then x.
- Print an integer in a particular print base, with radix.
- Print any arbitrary atom with suitable escaping, obeying the print-base,
print-radix, print-lowercase, and home package settings.
- Print any arbitrary atom with no escaping, but obeying print-base,
print-radix, and (for symbols) print-lowercase.
- Print a complex rational in a particular print base, with radix.
- Print a complex rational in a particular print base, no radix.
- Print a (non-integer) rational in a particular print base, with radix.
- Print a (non-integer) rational in a particular print base, no radix.
- Print a natural number in a particular print base, no radix.
- Print an integer in a particular print base, no radix.
- How many characters are required to represent a natural number?
- Print a list of instructions in a column.
- How many characters are required to represent an integer?
- Print as directed by a printing instruction.