Major Section: OTHER
Examples: (LD "foo.lisp") ; read and evaluate each form in file ; "foo.lisp", in order (LD "foo.lisp" :ld-pre-eval-print t) ; as above, but print each form to standard ; character output just before it is evaluated General Form: (LD standard-oi ; open obj in channel, stringp file name ; to open and close, or list of formsSome Related Topics
ld
in inappropriate contexts
Ld
is the top-level ACL2 read-eval-print loop. (When you call lp
,
a little initialization is done in raw Common Lisp and then ld
is
called.) Ld
is also a general-purpose ACL2 file loader and a
command interpreter. Ld
is actually a macro that expands to a
function call involving state
. Ld
returns an ``error triple''
(mv erp val state)
as explained below. (For much more on error triples,
see programming-with-state.)
See rebuild for a variant of ld
that skips proofs. See output-to-file
for examples showing how to redirect output to a file.
The arguments to ld
, except for :dir
, all happen to be global
variables in state
(see state and see programming-with-state). For
example, '
current-package
and '
ld-verbose
are global
variables, which may be accessed via (@ current-package)
and
(@ ld-verbose)
. When ld
is called, it ``binds'' these variables. By
``binds'' we actually mean the variables are globally set but restored to
their old values on exit. Because ld
provides the illusion of state
global variables being bound, they are called ``ld
specials'' (after the
Lisp convention of calling a variable ``special'' if it is referenced freely
after having been bound).
Note that all arguments but the first are passed via keyword. Any variable
not explicitly given a value in a call retains its pre-call value, with the
exception of :
ld-error-action
, which defaults to :return!
if
not explicitly specified.
Just as an example to drive the point home: If current-package
is
"ACL2"
and you typed
(ld *standard-oi* :current-package "MY-PKG")you would find yourself in (an inner) read-eval-print loop in which the current-package was
"MY-PKG"
. You could operate there as long as
you wished, changing the current package at will. But when you typed
:
q
you would return to the outer read-eval-print loop where the
current package would still be "ACL2"
.Roughly speaking, ld
repeatedly reads a form from standard-oi
,
evaluates it, and prints its result to standard-co
. It does this until
the form is :
q
or evaluates to an error triple whose value
component is :
q
, or until the input channel or list is emptied.
However, ld
has many bells and whistles controlled by the ld
specials. Each such special is documented individually. For example, see
the documentation for standard-oi
, current-package
,
ld-pre-eval-print
, etc.
A more precise description of ld
is as follows. In the description below
we use the ld
specials as variables, e.g., we say ``a form is read from
standard-oi
.'' By this usage we refer to the current value of the
named state global variable, e.g., we mean ``a form is read from the
current value of '
standard-oi
.'' This technicality has an important
implication: If while interacting with ld
you change the value of one of
the ld
specials, e.g., '
standard-oi
, you will change the
behavior of ld
, e.g., subsequent input will be taken from the new value.
Three ld
specials are treated as channels: standard-oi
is treated
as an object input channel and is the source of forms evaluated by ld
;
standard-co
and proofs-co
are treated as character output
channels and various flavors of output are printed to them. However, the
supplied values of these specials need not actually be channels; several
special cases are recognized.
If the supplied value of one of these is in fact an open channel of the
appropriate type, that channel is used and is not closed by ld
. If the
supplied value of one of these specials is a string, the string is treated as
a file name in (essentially) Unix syntax (see pathname) and a channel of the
appropriate type is opened to/from that file. Any channel opened by ld
during the binding of the ld
specials is automatically closed by ld
upon termination. If standard-co
and proofs-co
are equal
strings, only one channel to that file is opened and is used for both.
As a special convenience, when standard-oi
is a string and the :dir
argument provided and not nil
, we look up :dir
in the table of
directories maintained by add-include-book-dir
, and prepend this
directory to standard-oi
to create the filename. (In this case,
however, we require that standard-oi
is a relative pathname, not an
absolute pathname.) For example, one can write
(ld "arithmetic/top-with-meta.lisp" :dir :system)
to ld
that
particular community books library. (Of course, you should almost always
load books like arithmetic/top-with-meta
using include-book
instead
of ld
.) If :dir
is not specified, then a relative pathname is
resolved using the connected book directory; see cbd.
Several other alternatives are allowed for standard-oi
. If
standard-oi
is a true list then it is taken as the list of forms to be
processed. If standard-oi
is a list ending in an open channel, then
ld
processes the forms in the list and then reads and processes the forms
from the channel. Analogously, if standard-oi
is a list ending a
string, an object channel from the named file is opened and ld
processes
the forms in the list followed by the forms in the file. That channel is
closed upon termination of ld
.
The remaining ld
specials are handled more simply and generally have to
be bound to one of a finite number of tokens described in the :
doc
entries for each ld
special. Should any ld
special be supplied an
inappropriate value, an error message is printed.
Next, if ld-verbose
is t
, ld
prints the message ``ACL2 loading
name'' where name
names the file or channel from which forms are being
read. At the conclusion of ld
, it will print ``Finished loading name''
if ld-verbose
is t
.
Finally, ld
repeatedly executes the ACL2 read-eval-print step, which may
be described as follows. A prompt is printed to standard-co
if
ld-prompt
is non-nil
. The format of the prompt is determined
by ld-prompt
. If it is t
, the default ACL2 prompt is used.
If it is any other non-nil
value then it is treated as an ACL2 function
that will print the desired prompt. See ld-prompt. In the exceptional
case where ld
's input is coming from the terminal (*standard-oi*)
but
its output is going to a different sink (i.e., standard-co
is not
*standard-co*
), we also print the prompt to the terminal.
Ld
then reads a form from standard-oi
. If the object read is a
keyword, ld
constructs a ``keyword command form'' by possibly reading
several more objects. See keyword-commands. This construction process is
sensitive to the value of ld-keyword-aliases
. See ld-keyword-aliases.
Otherwise, the object read is treated as the command form.
Ld
next decides whether to evaluate or skip this form, depending on
ld-pre-eval-filter
. Initially, the filter must be either :all
,
:query
, or a new name. If it is :all
, it means all forms are
evaluated. If it is :query
, it means each form that is read is displayed
and the user is queried. Otherwise, the filter is a name and each form that
is read is evaluated as long as the name remains new, but if the name is ever
introduced then no more forms are read and ld
terminates.
See ld-pre-eval-filter.
If the form is to be evaluated, then ld
first prints the form to
standard-co
, if ld-pre-eval-print
is t
. With this feature,
ld
can process an input file or form list and construct a script of the
session that appears as though each form was typed in.
See ld-pre-eval-print.
Ld
then evaluates the form, with state
bound to the current
state. The result is some list of (multiple) values. If a state
is among the values, then ld
uses that state as the subsequent
current state.
Depending on ld-error-triples
, ld
may interpret the result as an
``error.'' See ld-error-triples. We first discuss ld
's behavior if no
error signal is detected (either because none was sent or because ld
is
ignoring them because ld-error-triples
is nil
).
In the case of a non-erroneous result, ld
does two things: First, if the
logical world in the now current state is different than the
world before execution of the form, ld
adds to the world a
``command landmark'' containing the form evaluated.
See command-descriptor. Second, ld
prints the result to
standard-co
, but only if ld-post-eval-print
is not nil
. The
result is printed as a list of (multiple) values unless
ld-post-eval-print
is :command-conventions
,
ld-error-triples
is t
, and the result is an ``error triple'', i.e.,
of the form (mv * * state)
(see error-triples). In that case, only the
non-erroneous ``value'' component of the result is printed.
See ld-post-eval-print.
Whenever ld
prints anything (whether the input form, a query, or
some results) it ``eviscerates'' it if ld-evisc-tuple
is non-nil
.
Essentially, evisceration is a generalization of Common Lisp's use
of *print-level*
and *print-length*
to hide large substructures.
See evisc-tuple and also see set-iprint.
We now return to the case of a form whose evaluation signals an error. In
this case, ld
first restores the ACL2 logical world to what it was
just before the erroneous form was evaluated. Thus, a form that partially
changes the world (i.e., begins to store properties) and then signals an
error, has no effect on the world. You may see this happen on
commands that execute several events (e.g., an encapsulate
or
a progn
of several defuns
): even though the output makes it
appear that the initial events were executed, if an error is signalled
by a later event the entire block of events is discarded.
After rolling back, ld
takes an action determined by
ld-error-action
. If the action is :continue
, ld
merely
iterates the read-eval-print step. Note that nothing suggestive of the value
of the ``erroneous'' form is printed. If the action is :return
, ld
terminates normally; similarly if the action is :return!
, but a special
value is returned that can cause superior ld
commands to terminate;
see ld-error-action for details. If the action is :error
, ld
terminates signalling an error to its caller. If its caller is in fact
another instance of ld
and that instance is watching out for error
signals, the entire world created by the inner ld
will be discarded
by the outer ld
if the inner ld
terminates with an error.
Ld
returns an error triple, (mv erp val state)
. Erp
is t
or
nil
indicating whether an error is being signalled. If no error is
signalled, val
is the ``reason'' ld
terminated and is one of
:exit
(meaning :
q
was read), :eof
(meaning the input source
was exhausted), :error
(meaning an error occurred but has been supressed),
:filter
(meaning the ld-pre-eval-filter
terminated ld
), or a
cons pair whose first component is the symbol :STOP-LD
, which typically
indicates that an error occurred while the value of variable
'
ld-error-action
was :RETURN!
. See ld-error-action for
details of this last case.