.\" Copyright (c) 1980 Regents of the University of California.
.\" All rights reserved. The Berkeley software License Agreement
.\" specifies the terms and conditions for redistribution.
.\" @(#)ch13.n 6.2 (Berkeley) 5/14/86
." $Header: /na/franz/doc/RCS/ch13.n,v 1.1 83/01/31 07:08:37 jkf Exp $
.Lc The\ CMU\ User\ Toplevel\ and\ the\ File\ Package 13
This documentation was written by Don Cohen, and the functions described below
were imported from PDP-10 CMULisp.
\fINon CMU users note:\fP this is not the default top level for your Lisp
system. In order to start up this top level, you should type
.sh 2 User\ Command\ Input\ Top\ Level \n(ch 1
The top-level is the function that reads what you type, evaluates it
and prints the result. The \fInewlisp\fP top-level was inspired by the
CMULisp top-level (which was inspired by interlisp) but is much
simpler. The top-level is a function (of zero arguments) that can be
called by your program. If you prefer another top-level, just redefine
the top-level function and type "(reset)" to start running it. The
current top-level simply calls the functions tlread, tleval and tlprint
to read, evaluate and print. These are supposed to be replaceable by
the user. The only one that would make sense to replace is tlprint,
which currently uses a function that refuses to go below a certain
level and prints "...]" when it finds itself printing a circular list.
One might want to prettyprint the results instead. The current
top-level numbers the lines that you type to it, and remembers the last
n "events" (where n can be set but is defaulted to 25). One can refer
to these events in the following "top-level commands":
\fITOPLEVEL COMMAND SUMMARY\fP
?? prints events - both the input and the result. If you just type
"??" you will see all of the recorded events. "?? 3" will show
only event 3, and "?? 3 6" will show events 3 through 6.
redo pretends that you typed the same thing that was typed before. If
you type "redo 3" event number 3 is redone. "redo -3" redoes the
thing 3 events ago. "redo" is the same as "redo -1".
ed calls the editor and then does whatever the editor returns. Thus
if you want to do event 5 again except for some small change, you
can type "ed 5", make the change and leave the editor. "ed -3"
and "ed" are analogous to redo.
Finally, you can get the value of event 7 with the function (valueof 7).
The other interesting feature of the top-level is that it makes outermost
parentheses superfluous for the most part. This works the same way as in
CMULisp, so you can use the help for an explanation. If you're not sure
and don't want to risk it you can always just include the parentheses.
is the LISP top level function. As well
as being the top level function with which the user
interacts, it can be called recursively by the user or
any function. Thus, the top level can be invoked from
inside the editor, break package, or a user function to
make its commands available to the user.
The difference will not usually be noticeable. The principal thing to be
careful about is that input to the function or system being called
cannot appear on the same line as the top-level call. For example,
typing \fI(editf foo)fP on one line will edit
and execute the p command in the editor.
specially recognizes the following commands:
.Lf valueof "'g_eventspec"
the value(s) of the event(s) specified by g_eventspec. If a single
event is specified, its value will be returned. If more than one event
is specified, or an event has more than one subevent (as for
etc), a list of vlaues will be returned.
Users typically define functions in lisp and then want to save them for
the next session. If you do \fI(changes)\fP, a list of the functions that are
newly defined or changed will be printed. When you type \fI(dskouts)\fP, the
functions associated with files will be saved in the new versions of
those files. In order to associate functions with files you can either
add them to the \fIfilefns\fP list of an existing file or create a new file to
hold them. This is done with the
function. If you type \fI(file new)\fP
the system will create a variable called
You may add the names of the functions to go into that file to
After you do \fI(changes)\fP,
the functions which are in no other file are stored in the value of the
To put these all in the new file, \fI(setq newfns (append newfns changes))\fP.
Now if you do \fI(changes)\fP, all of the changed functions
should be associated with files. In order to save the changes on the
files, do \fI(dskouts)\fP. All of the changed files (such as NEW) will be
written. To recover the new functions the next time you run
Script started on Sat Mar 14 11:50:32 1981
1.(defun square (x) (* x x)) ; define a new function
2.(changes) ; See, this function is associated
3.(file 'new) ; So let's declare file NEW.
4.newfns ; It doesn't have anything on it yet.
5.(setq newfns '(square)) ; Add the function associated
(square) ; with no file to file NEW.
6.(changes) ; CHANGES magically notices this fact.
7.(dskouts) ; We write the file.
8.(dskin new) ; We read it in!
script done on Sat Mar 14 11:51:48 1981
Changes computes a list containing an entry for each file which
defines atoms that have been marked changed. The entry contains the
file name and the changed atoms defined therein. There is also a
special entry for changes to atoms which are not defined in any known
file. The global variable
contains the list of "known" files. If no flag is passed this result
is printed in human readable form and the value returned is t if there
were any changes and nil if not. Otherwise nothing is printed and the
computer list is returned. The global variable
contains the atoms which are marked changed but not yet associated
function attempts to associate these names with files, and any that are not
found are considered to belong to no file. The
property is the means by which changed functions are associated with
files. When a file is read in or written out its
.Lf dc "s_word s_id [ g_descriptor1 ... ] <text> <esc>"
defines comments. It is exceptional in that its behavior is very
fact that the comment exists. It is expected that in interactive mode
comments will be found via
comments which do not take up space in your core image. When
is executed from the terminal it expects you to type a comment.
will write out the comments that you define and also copy the comments on the
old version of the file, so that the new version will keep the old comments
even though they were never actually brought into core.
The optional id is a mechanism for distinguishing among several
comments associated with the same word. It defaults to nil. However
if you define two comments with the same id, the second is considered
to be a replacement for the first.
is determined by the value of the global variable
contains the name of a function that is run.
Its arguments are the word, id and attribute list.
Other functions rebind it to
The comment property of an atom is a list of entries, each representing
one comment. Atomic entries are assumed to be identifiers of comments on
a file but not in core. In-core comments are represented by a list of the
id, the attribute list and the comment text. The comment text is an
uninterned atom. Comments may be deleted or reordered by editing the
READ-EVAL-PRINTs the contents of the given files. This
is the function to use to read files created by
also declares the files that it reads (if a
list is defined and the file is otherwise declarable by
), so that changes to it can be recorded.
filenameFNS (i.e., the file name, excluding extension,
) contains a list of function
names, etc., to be loaded
Any previous version of the file will be renamed to have extension
.Lf dskouts "s_file1 ..."
to and prints the name of each
s_filei (with no additional arguments, assuming
filenameFNS to be a list to be loaded) for which s_file\fIi\fP
is either not in \fIfilelst\fP (meaning it is a new file not
previously declared by \fIfile\fP or given as an argument to
\fIdskin\fP, \fIdskouts\fP, or \fIdskouts\fP) or is in \fIfilelst\fP and has some
recorded changes to definitions of atoms in filenameFNS,
as recorded by \fImark!changed\fP and noted by changes.
If \fIfile\fPi is not specified, \fIfilelst\fP will be
used. This is the most common way of using dskouts.
Typing \fI(dskouts)\fP will save every file reported by
\fI(changes)\fP to have changed definitions.
\fI(setq atom 'value)\fP.
declares its argument to be a file to be used for reporting and saving
changes to functions by adding the file name to a list of files,
is called for each file argument of
the name of the fileFNS list for its file argument s_file.
.Lf getdef "'s_file ['s_i1 ...]"
selectively executes definitions for atoms s_i1 ... from the
specified file. Any of the words to be defined which end with "@"
will be treated as patterns in which the @ matchs any suffix
(and thus may be programmed). It looks for lines in the file that start
with a word in the table. The first character must be a "(" or "["
followed by the word, followed by a space, return or something else that will
not be considered as part of the identifier by
e.g., "(" is unacceptable. When one is found the next word is read. If
it matches one of the identifiers in the call to
then the table entry is executed. The table entry is a function of the
expression starting in this line. Output from
is in acceptable format for
a list of the words which match the ones it looked for, for which it found
(but, depending on the table, perhaps did not execute) in the file.
It is in the form of an association list. Each element is a dotted pair
consisting of the name of a function for which
searches and a function of one argument to be executed when it is found.
records the fact that the definition of s_f has been changed. It is
and the editor when a definition is altered.