.chapter "Pretty-Printing Lisp Code"

The lan{ppcode} module of the 3pretty-print* lan{lsb} system
utilizes the interfaces provided by the 3pretty-print-definition*
system to provide some default interfaces and formats for
prettyprinting Lisp code.  It provides a large number of default
formats for common lan{lisp} functions, reader macros, and special
forms.
.defun pretty-prin1 object 1(Optional*stream1)*
This is the basic entry for prettyprinting Lisp code.  It is similar
to 3pretty-prin1-datum* ((pretty-prin1-datum-fun)), but sets up
the environment so that lan{lisp} code and special constructs will
be recognized and formatted accordingly.
.end_defun
.defun pretty-print x 1(Optional*stream1)*
Like 3pretty-prin1*, but performs a 3terpri* first.  2It
does not print a trailing space.  Should it?*
.end_defun
.section "Anaphora"

The printing environment established by 3pretty-prin1* provides
some defaults for how term_i{anaphora} (circular references) may be
handled.  The things described in this section might be needed if one
wants to customize the handling of anaphora, or make use of the things
provided here in defining other customized printing environments.
.defvar *pretty-print-anaphora?
This variable controls how 3pretty-prin1* (and hence
3pretty-print* also) treat circularities.  It may be 3nil*,
meaning to ignore circularities (but see below), 3t* meaning to do
a fairly dumb default, or a 3cons* of the function to handle the
writing of anaphora, and a
function to 2wrap* anaphoric references;  either or both of these
may be 3nil*.  If the value is atomic, it is assumed to be the
function to 2write* anaphora.  3pretty-prin1* will only perform a
circularity-checking pre-pass if at least one of these functions is
supplied.  In some implementations, the pretty-printer may still
detect some circularities, in particular those which are 2not*
circular through data handled tail-recursively (the way lists are
printed).  Whether or not it does cannot be depended on, as it depends
on whether it is easier for the particular implementation to 2not*
do so when it is not supposed to.

The default for this is 3nil*, except in lan{nil} where it
defaults to a cons of functions which will provide lan{common
lisp}-compatible circular list printing.
.end_defvar
.defun ppcode-default-anaphor-hacker object count total-depth
If it is desired that the 3pretty-prin1* 2always* check for
circularities, then 3*pretty-print-anaphora?* may be set to
3ppcode-default-anaphor-hacker*.  This writes all anaphora as
3##*.
.end_defun
.defun ppcode-common-lisp-anaphor-hacker object count total-depth
This is the routine which performs lan{common lisp} anaphora output.
It outputs 3#2n*#*, where 2n* is an integer matching a
label generated by the following routine.
.end_defun
.defun ppcode-common-lisp-anaphor-wrapper object format-description?
This is the function which provides lan{common lisp} anaphora
wrapping.  If the object has not been output previously (within the
given 3pp-environment*), then it is output, prefixed with
3#2n*=*, where 2n* is a non-negative decimal integer
unique to that 3pp-environment*.  If the object has been output
previously ("previously" means "to the left", essentially), then it is
as if output is being performed for a circular reference:  the label
is referred to, with 3#2n*#*.
.end_defun
.section "Reader Macro Inversion"

The lan{ppcode}-provided printing environment utilizes the
term_i{list wrapper} hook provided by lan{ppdef} to do reader
macro inversion.  A list whose 3car* is a symbol with one of the
following properties will be handled specially:
.table 3 250 250 0 0 0
.item ppcode-cadr-readmacroinverse
This is the type of inversion which turns 3(quote foo)* into
3'foo* and 3(function foo)* into 3#'foo*.  The
property is a symbol or string to write as a prefix of the 3cadr*
of the form.  This does not "match" if the form is not a list exactly
two elements long.
.item ppcode-cdr-readmacroinverse
The property is a symbol or string to write as a prefix of the
3cdr* of the form.  This readmacro-inversion format is often used
internally by things (such as backquote), and the triggering symbol
(the 3car* of the form) is usually something fairly obscure, so
that it won't be normally encountered.
.item ppcode-wrapper-format
This is the general hook which lan{ppcode} provides.  The property
is a function which receives two arguments:  the entire (original)
form, and the (possibly null) format description.  If the function
returns 3nil*, then it did 2not* wish to handle the writing of
the form, and the form will be handled by more conventional means
(treated like an ordinary function, perhaps).  Otherwise, the function
is assumed to have performed the necessary writing.
.end_table
.section "Symbol Formats"
.cindex nil, special formatting of
.cindex :list format description special check
.cindex :series format description special check
The dispatch which lan{ppcode} provides for symbols in the
3pretty-prin1* printing environment checks specially for the
3:list* and 3:series* format descriptions being passed in;  if
it is given the symbol 3nil* and one of these format descriptions,
it writes 3()* rather than 3nil*.
.section "Function and Special Form Formats"

The lan{ppcode}-provided printing environment finally provides a
special dispatch for lists with 3car* which is a symbol.  This is
how most of the special formats for lan{lisp} functions and special
forms are handled.  In this printing environment, the 3car* of the
list is checked for one of the following properties:
.table 3 250 250
.item ppcode-format-description
The value of the property should be a format description.  The form is
printed according to that format description, 2except* that a
format description passed in overrides this property.  This is because
a passed-in format description supposedly has more knowledge of the
context.
.item ppcode-function-format
The value of the property is a function which is called to do the
writing of the form in the proper format.  Often, such a function
simply needs to some non-trivial examination of the form to figure out
the format, and then calls 3pp-from-format-description*
((pp-from-format-description-fun)) on a format description;  this is
how "new style" and "old style" 3do* are differentiated.  This
property, like the 3ppcode-format-description* property, is
overridden by a passed-in format description.  The function receives
two arguments;  the form, and a format description which will always
be 3nil* (why is it given this argument???  probably for
consistency with the next one so that they can share functions).
.item ppcode-format
This is interpreted like the 3ppcode-function-format* property,
2except* that it is 2not* overridden by a passed-in format
description.  The function can, of course, decide to defer to a
passed-in format description, since it receives the form and the
format description as arguments.
.end_table

The 3:function* symbolic format description is defined by
lan{ppcode};  this causes interpretation of the form as a function
(or macro) call.  When such a call is to be printed, attempts will be
made to determine how it should be formatted based on what can be
found out about its arguments.  If nothing can be determined, then the
default format description for "function calls" will be used.
.defvar *ppcode-default-function-format-description
The value of this, which is initially
.lisp
((:elements-in-head 1) (:hanging-indentation 1))
.end_lisp
is used as the default format description by the 3:function*
format description.
.end_defvar
.section "Macroexpansion Inversion"

Most lan{lisp} implementations 2cache* macro expansions
somehow;  that is, they store an association between the original
macro form and its expansion, so that subsequent evaluations will not
have to evaluate the macro code over again.  Many do this by modifying
the original form in some way;  one mechanism used in both
lan{maclisp} and lan{lispm} is to bash the original call with a
2new* macro call, which has among its "arguments" both the original
form (somewhat copied), and the expansion.  If the pretty-printer can
detect such a form, it can choose to show either the original form (as
it was written), the expanded form, or the bashed form which has both.

The lan{ppcode} module arranges for this intermediate macro,
whatever it is in the given lan{lisp} implementation, to perform the
appropriate action based on the value of a user-modifiable variable.
Only lan{pdp-10 maclisp} and lan{lispm} do it this way;  in
lan{nil}, setting this variable has no effect--the original form is
always left unmodified.
.defvar *ppcode-show-macro-expansions
This controls the pretty-printing of macro displacement forms which
contain pointers to both the original macro form and the expanded
form.  It may take on the following values:
.table 3 250 500
.item nil
Don't perform any transformations - show exactly what is there.  This
will probably be much too verbose since the form contains both the
original form and the expansion.
.item :original
Show the original form.
.item :expanded
Show the expansion.
.end_table
.end_defvar

