Trailing-Edge
-
PDP-10 Archives
-
decus_20tap1_198111
-
decus/20-0004/20lisp.doc
There are no other files named 20lisp.doc in the archive.
SECTION 20
PRINTSTRUCTURE, INTERSCOPE, AND HELPSYS
1
20.1 Printstructure
In trying to work with large programs, a user can lose track of the
hierarchy which defines his program structure; it is often convenient to
have a map to show which functions are called by each of the functions
in a system. If fn is the name of the top level function called in your
system, then typing in printstructure[fn] will cause a tree printout of
the function-call structure of fn. To illustrate this in more detail,
we use the printstructure program itself as an example.
------------------------------------------------------------------------
1
A preliminary version of printstructure was written by D. G. Bobrow.
The current form of printstructure was written by W. Teitelman.
20.1
PRINTSTRUCTURE PRGETD
PROGSTRUC PRGETD
PRGSTRC NOTFN PRGETD
PROGSTRUC
PRGSTRC1 PRNCONC
PRGSTRC1
PRGSTRC
PRNCONC
PRGSTRC
CALLS1 MAKELIST
NOTFN
CALLS2 CALLS1
PRGETD
TREEPRINT TREEPRINT1
TREEPRINT
VARPRINT VARPRINT1 TREEPRINT1
VARPRINT2 ALLCALLS ALLCALLS1 ALLCALLS1
TREEPRINT1
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PRINTSTRUCTURE [X,FILE: DONELST,N,TREELST,TREEFNS,LSTEM,X,Y,Z,
FN,TREE;PRDEPTH,LAST-PRINTSTRUCTURE]
CALLED BY:
PRGETD [X,FLG; ; ]
CALLED BY: PRINTSTRUCTURE,PROGSTRUC,NOTFN,CALLS2
PROGSTRUC [FN,DEF; N,Y,Z,CALLSFLG,VARSFLG,VARS1,VARS2,D,X; N,DONELST]
CALLED BY: PRINSTRUCTURE,PRGSTRC
PRGSTRC [X,HEAD,FLG; Y,TEM,X; VARSFLG,D,NOFNS,CALLSFLG,N,DONELST,
TREEFNS,NOTRACEFNS,FN,VARS1,QUOTEFNS]
CALLED BY: PROGSTRUC,PRGSTRC1,PRGSTRC
NOTFN [FN; DEF; NOFNS,YESFNS,FIRSTLOC,LASTLOC]
CALLED BY: PRGSTRC,CALLS1
PRGSTRC1 [L,HEAD,FLG; A,B; VARS1,VARS2]
CALLED BY: PRGSTRC,PRGSTRC1
PRNCONC [X,Y; ; CALLSFLG]
CALLED BY: PRGSTRC1,PRGSTRC
CALLS1 [ADR,GENFLG,D; LIT,END,V1,V2,LEFT,OPD,X,X; VARS1,VARS2,
VARSFLG]
CALLED BY: PROGSTRUC,CALLS2
MAKELIST [N,ADR; L; ]
CALLED BY: CALLS1
Figure 20-1
20.2
The upper portion of this printout is the usual horizontal version of a
tree. This tree is straighforwardly derived from the definitions of the
functions: printstructure calls prgetd, progstruc, treeprint, and
varprint. progstruc in turn calls prgetd, prgstrc and calls1. prgstrc
calls notfn, progstruc, prgstrc1, prnconc, and itself. prgstrc1 calls
prnconc, itself, and prgstrc. Note that a function whose substructure
has already been shown is not expanded in its second occurrence in the
tree.
The lower portion of the printout contains, for each function,
information about the variables it uses, and a list of the functions
that call it. For example, printstructure is a function of two
arguments, x and file. It binds eleven variables internally: donelst,
2
n, ... tree, and uses prdepth and last-printstructure as free
variables. It is not called by any of the functions in the tree.
prgetd is a function of two arguments, x and flg, binds no variables
internally, uses no free variables, and is called by printstructure,
progstruc, notfn and calls2.
printstructure calls many other low-level functions such as getd, car,
list, nconc, etc. in addition to the four functions appearing in the
above output. The reason these do not appear in the output is that they
were defined "uninteresting" by the user for the purposes of his
analysis. Two functions, firstfn and lastfn, and two variables, yesfns
and nofns are used for this purpose. Any function that appears on the
list nofns is not of interest, any function appearing on yesfns is of
interest.
yesfns=T effectively puts all functions on yesfns. As for functions
appearing on neither nofns or yesfns, all interpreted functions are
deemed interesting, but only those compiled functions whose code lies in
that portion of bpspace between the two limits established by firstfn
and lastfn. For example, the above analysis was performed following
firstfn[PRINTSTRUCTURE] and lastfn[ALLCALLS1].
Two other variables, notracefns and prdepth, also affect the action of
printstructure. Functions that appear on the list notracefns will
appear in the tree, assuming they are "interesting" functions as defined
above, but their definitions will not be analyzed. prdepth is a cutoff
depth for analysis. It is initially set to 7.
printstructure assumes that all functions whose argtypes are 1 or 3,
i.e. all NLAMBDAs, do not evaluate their arguments. For example, if the
function prinq were defined as (NLAMBDA (X) (MAPC X (FUNCTION PRIN1))),
and the form (PRINQ (NOW IS THE TIME)) appeared in a function being
analyzed, IS, THE, and TIME would not be reported as free variables, and
NOW as an undefined function. The user can inform printstructure (and
other system packages which require this information) that an nlambda
function does evaluate its arguments by putting on its property list the
property INFO value EVAL. For example, the functions and, ersetq, progn,
etc., are all initialized in this fashion.
------------------------------------------------------------------------
2
Variables are bound internally by either PROGs LAMBDA-expressions.
20.3
If printstructure encounters a form beginning with two left parentheses
in the course of analyzing an interpreted function (other than a COND
clause or open lambda expression) it notes the presence of a possible
parentheses error by the abbreviation P.P.E., followed by the function
in which the form appears, and the form itself, as in the example below.
Note also that since printstructure detects functions that are not
defined, (i.e., atoms appearing as CAR of a form), printstructure is a
useful tool for debugging.
20.4
_PP FOO
(FOO
[LAMBDA (X)
(COND
((CAR X) (FOO1 X))
(T ((CONS X (CAR X])
FOO
_PRINTSTRUCTURE(FOO)
FOO FOO1
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
FOO [X; ; ]
CALLED BY:
FOO1 IS NOT DEFINED.
P.P.E. IN FOO - ((CONS X (CAR X)))
Figure 20-2
OTHER OPTIONS
printstructure is a function of three arguments, x, exprflg, and file.
printstructure analyzes x, sets the free variable last-printstructure to
the results of its analysis, prints the result (in the format shown
earlier) to file (which is opened if necessary and closed afterwards),
and returns x as its value. Thus if the user did not want to see any
3
output, he could call printstructure with file=NIL:, and then process
the result himself by using last-printstructure.
printstructure always checks for EXPR properties on the property list of
functions that are not defined. However, if exprflg=T, printstructure
will prefer to analyze EXPR definitions whenever possible, i.e. if the
function definition call contains a compiled definition, and there is
also an EXPR property, the latter will be analyzed.
x can be NIL, a list, a function, or an atom that evaluates to a list.
If x is NIL, printstructure does not perform any analysis, but simply
prints the result of the last analysis, i.e., that stored on
last-printstructure. Thus the user can effectively redirect the output
that is going to the terminal to a disc file by aborting the printout,
and then performing printstructure[NIL;file].
------------------------------------------------------------------------
3
NIL: is a TENEX output device that acts like a 'bottomless pit'.
Note that file=NIL (not NIL:) means print the tree to primary output
file.
20.5
If x is a list, printstructure analyzes the first function on x, and
then analyzes the second function, unless it was already analyzed, then
the third, etc., producing however many trees required. Thus, if the
user wishes to analyze a collection of functions, e.g., breakfns, he can
simply perform (PRINTSTRUCTURE BREAKFNS).
If x is not a list, but is the name of a function, printstructure[x] is
the same as printstructure[(x)]. Finally, if the value of x is a list
of functions, printstructure will process that list as described above.
Note that in the case that x is a list, or evaluates to a list,
subsequent functions are not separately analyzed if they have been
encountered in the analysis of a function appearing earlier on the list.
Thus, the ordering of x can be important. For example, if both FOO and
FIE call FUM, printstructure[(FOO FIE FUM)], will produce a tree for FOO
containing embedded in it the tree for FUM. FUM will not be expanded in
the tree for FIE, nor will it have a tree of its own. (Of course, if
FOO also calls FIE, then FIE will not have a tree either.) The
convention of listing FUM can be used to force printstructure to give
FUM a tree of its own. Thus printstructure[(FOO FIE (FUM))] will
produce three trees, and neither of the calls to FUM from FOO or FIE
will be expanded in their respective trees. Of course, in this example,
the same effect could have been achieved by reordering, i.e.,
printstructure[(FUM FOO FIE)]. However, if FOO, FIE, and FUM, all
called each other, and yet the user wanted to see three separate trees,
no ordering would suffice. Instead, the user would have to do
printstructure[((FOO) (FIE) (FUM))].
The result of the analysis of printstructure is in two parts: donelst, a
list summarizing the argument/variable information for each function
appearing in the tree(s), and treelst, a list of the trees.
last-printstructure is set to cons[donelst;treelst].
donelst is a list consisting, in alternation, of the functions appearing
in any tree, and a variable list for that function. car of the variable
list is a list of variables bound in the function, and cdr is a list of
those variables used freely in the function. Thus the form of donelst
for the earlier example would be:
(PRINTSTRUCTURE ((X FILE DONELST N TREELST TREEFNS L TEM X Y Z
FN TREE) PRDEPTH LAST-PRINTSTRUCTURE) PRGETD ((X FLG))
PROGSTRUC (( FN DEF N Y Z CALLSFLG VARSFLG VARS1 VARS2 D X)
N DONELST) ... ALLCALLS1 ((FN TR A B)))
Possible parentheses errors are indicated on donelst by a non-atomic
form appearing where a function would normally occur, i.e., in an odd
position. The non-atomic form is followed by the name of the function
in which the P.P.E. occurred.
PRINTSTRUCTURE FUNCTIONS
printstructure[x;exprflg;file]
analyzes x, saves result on
last-printstructure, outputs trees and
variable information to file, and returns x
as its value.
20.6
If exprflg=T, printstructure will prefer to
analyze expr's. See page 20.5.
treeprint[x;n] prints a tree in the horizontal fashion
shown in the examples above. i.e.,
printstructure performs
(MAPC TREELST (FUNCTION TREEPRINT)).
varprint[donelst;treelst] prints the "lower half" of the
printstructure output.
allcalls[fn;treelst] uses treelst to produce a list of the
functions that call fn.
firstfn[fn] If fn=T, lower boundary is set to 0, i.e.,
all subrs and all compiled functions will
pass this test. If fn=NIL, lower boundary
set at end of bpspace, i.e., no compiled
functions will pass this test. Otherwise
fn is the name of a compiled function and
the boundary is set at fn, i.e., all
compiled functions defined earlier than fn
are rejected.
lastfn[fn] if fn=NIL, upper boundary set at end of
bpspace, i.e., all compiled functions will
pass this test. Otherwise boundary set at
fn, i.e., all compiled functions defined
later than fn are rejected.
Thus to accept all compiled functions, perform firstfn[T] and
lastfn[NIL]: to reject all compiled functions, perform firstfn[].
calls[fn;exprflg;varsflg] is a fast 'one-level' printstructure, i.e.,
it indicates what functions fn calls, but
does not go further and analyze any of
them. calls does not print a tree, but
reports its findings by returning as its
value a list of three elements: a list of
all functions called by fn, a list of
variables bound in fn, and a list of
variables used freely in fn, e.g.,
calls[progstruc] =
((PRGETD EXPRP PRGSTRC CCODEP
CALLS1 ATTACH) (FN DEF N Y Z CALLSFLG
VARSFLG VARS1 VARS2 D X) (N DONELST))
fn can be a function name, a definition, or
a form. Calls first does firstfn(T),
lastfn() so that all subrs and compiled
20.7
functions appear, except those on nofns.
If varsflg is T, calls ignores functions
and only looks at the variables (and
therefore runs much faster).
vars[fn;exprflg] cdr[calls[fn;exprflg;T]]
freevars[fn;exprflg] cadr[vars[fn;exprflg]]
4
20.2 Interscope
While printstructure is a convenient tool for giving the user an
overview of the structure of his programs, it is not well suited for
determining the answer to particular questions the user may have about
his programs. For example, if FOO uses X freely, and the user wants to
know where X is bound 'above' FOO, he has to visually trace back up the
tree that is output by printstructure, and, at each point, look down at
the lower portion of the printout and find whether the corresponding
function binds X. For large systems, such a procedure can be quite
tedious. Furthermore, printstructure does not even compute certain
certain important types of information. For example, printstructure does
not distinguish between functions that use a variable freely and those
that set it (or smash it).
Interscope is an extension of printstructure designed to resolve these
shortcomings. Like printstructure, interscope analyses programs
(functions), although it extracts considerably more information and
relationships than does printstructure. However, instead of presenting
the information it obtains in a predetermined format, interscope allows
the user to ask it questions about the programs it has analysed, i.e. to
interrogate its data base. These questions can be input in English, and
contain conjunctions, disjunctions, and negations of the many
relationships between functions and variables that interscope knows
about. The questions can be closed questions, e.g.
"DOES FOO CALL FIE?", or open questions, "WHAT FUNCTIONS CALL FIE?".
The answers to some questions are obtainable directly from the data
base, e.g. "WHAT VARIABLES DOES FOO SET?" Other questions cause
interscope to search its data base, e.g.
"WHAT FUNCTIONS BIND VARIABLES THAT FOO SETS?". Figure 20-3 contains a
sample session with interscope.
------------------------------------------------------------------------
4
Interscope was originally written by P. C. Jackson, and
substantially revised and improved by L. M. Masinter.
20.8
_INTERSCOPE]
Hello, shall I analyze a system? [1]
&_WTFIXFNS AND CLISPFNS.
This may take a few minutes.
GC: 8
1233, 10431 FREE WORDS
Shall I analyze another system?
&_NO [2]
Ok, what would you like to know?
&WHO CALLS RETDWIM?
(WTFIX FIX89TYPEIN FIXAPPLY FIXATOM FIXCONTINUE CLISPATOM FIXT)
&HOW IS CLISPATOM CALLED?
I didn't understand that. [3]
&WHAT FUNCTIONS CALL CLISPATOM? [4]
(WTFIX FIXAPPLY FIXATOM)
&WHAT FREE VARIABLES DOES CLISPATOM USE?
(ONLYSPELLFLG CLISPCHANGES CLISPFLG TYPE-IN? CLISPSTATS INFIXSTATS LST
FAULTXX CHCONLST FAULTX DWIMIFYFLG 89CHANGE FAULTPOS)
&WHO BINDS TAIL?
(WTFIX RETDWIM1 RETDWIM2 RETDWIM3 CLISPFUNCTION? CLISPATOM0 CLISPATOM1
CLISPATOM1A CLISPATOM2A DWIMIFY1A DWIMIFY2 DWIMIFY2A CLISPRESPELL)
&WHO BINDS TAIL AND CALLS CLISPATOM SOMEHOW?
(WTFIX DWIMIFY2)
&WHAT VARS DOES HELPFIX CHANGE?
(FORM LASTPOS NOCHANGEFLG HELPFIXTAIL FN TEM BRKEXP)
&WHAT FUNCTIONS CHANGE THE VARIABLE TENTATIVE?
(CLISPATOM1 CLISPATOM2 CLISPATOM2C CLISPATOM2A CLISPATOM1A)
&WHO CHANGES TAIL?
(FIXATOM HELPFIX1 CLISPATOM1 CLISPATOM2 DWIMIFY2)
&WHAT FNS USE TEM AS AN INTERANL VAR AND
...ARE CALLED BY CLISPATOM INDIRECTLY?
INTERANL=INTERNAL ? Yes
(RETDWIM RETDWIM1 FIX89TYPEIN)
&HOW DOES CLIAPTOM CALL LISTP?
CLIAPTOM=CLISPATOM ? Yes
((CLISPATOM LISTP) (CLISPATOM *** RETDWIM *** LISTP) (CLISPATOM [5]
FIX89 FIX89A LISTP))
&SHOW ME THE PATHS FROM CLISPATOM TO LISTP.
CLISPATOM LISTP
RETDWIM LISTP [6]
RETDWIM1 LISTP
FIX89TYPEIN RETDWIM ...
FIX89 FIX89A LISTP
&DOES GETVARS SMASH ANY VARIABLES?
(L)
&SHOW ME HOW GETVARS SMASHES L.
(NCONC L (AND (LISTP X) (MAPCAR & &)))
&GOODBYE.
Goodbye.
Figure 20-3
20.9
In order to answer questions about programs, interscope must analyze
them and build its data-base. When interscope is first called, it will
ask the user what functions he wants analyzed. The user can respond to
this question by giving interscope either: 1) the name of the top level
function called in his system, or 2) the name of a variable that
evaluates to a list of top level functions, or 3) the list itself. All
of the functions below each top level function will be analyzed, except
those which are declared to be "uninteresting," as described below.
5
Note that after interscope goes into question-answering mode, the user
can instruct interscope to analyze additional functions, either in
English input, e.g. "ANALYZE FOOFNS." or by calling the function lookat
directly (page 20.13).
The structure of interscope may be divided into three major subsystems:
a top-level monitor function, an English preprocessor, and the functions
which build and search the data base. The monitor function is
implemented via userexec (see Section 22), so that the features of the
6
programmer's assistant are available from within interscope. For
example, the user can REDO or FIX interscope questions, interrogate the
7
history list for his session, or run programs from within interscope.
------------------------------------------------------------------------
5
When interscope is first called, and it has not previously analyzed
any functions, it is in analysis mode, as indicated by its greeting
and prompt character (&_ instead of &) (see [1] in Figure 20-3).
Interscope goes into question-answering mode when the user answers
NO to the question "Shall I analyse a (another) system?" ([2] in
Figure 20-3). The only difference between analysis mode and
question-answering mode is that in analysis mode, interscope treats
forms as indicating a list of functions to be analysed, whereas in
question-answering mode, interscope simply passes forms back to
lispx for evaluation.
6
interscope assumes that any input line terminated by a punctuation
mark is intended for it to process. interscope will also attempt to
process other input lines, i.e. those not ending in punctuation.
However, if it is not able to make sense of the input, interscope
will assume that it was intended to be handled by lispx, and pass it
back for evaluation. For example, if the user types
"HAS THOU SLAIN THE JABBERWOCK?", interscope will respond "I didn't
understand that", but if the user omits the '?', the line will be
given to lispx for evaluation and (probably) cause a U.D.F. HAS
error.
7
Since the data base that interscope constructs is global (stored on
property lists), the user can also exit from interscope, either by
typing OK or GOODBYE, or via control-D, and then reenter interscope
at some later point and continue asking questions, without having to
reanalyze his functions.
20.10
8
The English preprocessor translates English questions, statements, and
commands into INTERLISP forms appropriate for searching and building the
interscope data base. Although this preprocessor is fairly flexible and
robust (e.g. includes spelling correction), it translates only a limited
subset of English sentences, and replies "I didn't understand that." to
9
anything outside this subset ([3] in Figure 20-3). When this happens,
usually a simple rephrasing of the question will suffice to allow
interscope to handle it ([4] in Figure 20-3).
The interscope data-base can be accessed directly by the user via the
functions described below. It should be noted that interscope actually
creates two data bases, the first containing information about the
elementary relations between the functions and variables in the user's
system, and the second containing information derived from the first,
i.e. the paths by which one function calls another. The first data base
is created when interscope analyzes a system (via the function lookat).
The second data base is developed incrementally (by the function paths),
depending on the questions asked by the user. Both data bases are stored
on the property lists of the functions and variables which are analyzed.
Interscope "understands" a wide variety of the elementary relations that
exist between functions and variables, e.g. which functions bind, use,
change, test, or smash a given variable, which functions may cause a
10
given function to be called, either directly or indirectly, which
variables are used as global or local free variables, either by a given
function or by a group of functions, etc.
Information about the function-call paths from one program to another is
"generalized" when it is stored; e.g. at [5] in Figure 20-3, one of the
paths by which CLISPATOM calls LISTP is given as (CLISPATOM *** RETDWIM
*** LISTP), which means that there is more than one path from CLISPATOM
to RETDWIM, and more than one path from RETDWIM to LISTP.
The conventions used by interscope for recognizing functions that are
"uninteresting" are the same as those used by printstructure (page
20.3), i.e. yesfns, nofns firstfn, and lastfn all have the same effect
as for printstructure.
------------------------------------------------------------------------
8
The translation of the most recent input is always stored in the
function definition cell of the atom MEANING.
9
Where possible, interscope will try to inform the user what part of
the sentence it did not understand.
10
e.g. if FOO calls FIE, and FIE calls FUM, then FOO calls FUM
indirectly. 'SOMEHOW' means directly or indirectly, e.g.
"WHAT FUNCTIONS CALL FOO SOMEHOW?"
20.11
INTERSCOPE FUNCTIONS
paths[x;y;type;must;avoid;only]
Value is a list of paths from x to y, where
each path is an ordered list of functions.
*** is used to indicate multiple paths. For
example, if FOO calls FIE, and FIE calls
FUM directly as well as calling FIE1 which
calls FUM, then paths[FOO;FUM] returns
((FOO FIE *** FUM)).
type, must, avoid, and only are optional.
type can be either CALLS or CALLEDBY (NIL
is equivalent to CALLS), e.g. in the above
example, paths[FUM;FOO;CALLEDBY] would
return the same set of paths as
paths[FOO;FUM], except each path would be
in the reverse order.
must, avoid, and only are used to select
out certain types of paths. Each can be
specified by an atom which evaluates to a
list of functions, or a form which
evaluates to such a list. If (the value
of) must is non-NIL, each path is required
to go through at least one of the members
of must. If avoid is non-NIL, no path can
go through any member of avoid. If only is
non-NIL, no path can go through any
function which is not a member of only,
i.e. each path can only go through
11
functions on only.
treepaths[x;y;type;must;avoid;only]
Like paths, except prints paths as a tree
structure, as shown at [6] in Figure 20-3.
type, must, avoid, and only have the same
12
meaning as with paths.
------------------------------------------------------------------------
11
paths is called for English inputs of the form:
"WHAT ARE THE PATHS FROM x TO y?". Such questions can be modified
with subordinate clauses to indicate values for must, avoid, and/or
only, e.g. "WHAT ARE THE PATHS FROM FOO TO FIE WHICH ONLY GO
THROUGH FOOFNS AND AVOID FIEFNS?"
12
treepaths is called for English inputs of the form "SHOW ME HOW x
CALLS y", "DISPLAY THE PATHS FROM x TO y", etc.
20.12
lookat[x] Builds the initial data base describing the
system x, where x is either the name of a
function, the name of a variable which
evaluates to a list of functions, or the
list of functions itself.
clumpget[object;relation;universe] Value is a list of objects
(functions or variables) which have the
indicated relation with respect to object,
e.g. clumpget[FOO;CALLERS] returns a list
of functions that call FOO,
clumpget[X;SMASHERS] a list of functions
that smash the variable X, etc. A complete
list of the possible values for relation is
13
given below.
object can be a list of objects (or a
variable which evaluates to a list of
objects), in which case the value returned
by clumpget is the list of all objects
which have the indicated relation to any of
the members of object.
Similarly, universe can be a list of
objects (or a variable which evaluates to a
list of objects), in which case the value
returned by clumpget is the list of all
objects in universe which have the
indicated relation to object (or any of the
members of object), e.g.
clumpget[X;SMASHERS;FOOFNS].
Finally,, universe can be a relation, which
is equivalent to supplying
clumpget[object;universe] in place of
object, i.e. the value returned is the list
of all objects which have the indicated
relation to any of the members of the {set
of all objects which bear the relationship
universe to object}. For example,
clumpget[FOO;CALLERS;CALLEDFNS] is a list
of all functions that call any of the
functions (CALLERS) that are directly
called by FOO (CALLEDFNS).
clumpget[FOO;FREEUSERS;LOCALVARS] is a list
of functions that use freely any of the
variables that are bound locally by FOO.
------------------------------------------------------------------------
13
If clumpget is given a value for relation that it does not
recognize, it will attempt spelling correction, and if that fails,
generate an error. If given a value for object that it has not seen
before, it will type "I don't know anything about object, shall I
analyse a system?" and go into analysis mode.
20.13
Currently, the following relations are implemented:
CALLERS list of functions that directly call object.
CALLEDFNS list of functions directly called by object.
CALLCAUSERS list of functions that call object, perhaps
indirectly. In English: "WHO CALLS FOO
SOMEHOW?".
CALLSCAUSED list of functions called by object, perhaps
indirectly. In English: "WHO DOES FOO CALL
SOMEHOW?"
ABOVE union of object with CALLCAUSERS.
BELOW union of object with CALLSCAUSED.
ARGS arguments of object.
ARGBINDERS list of functions that have object as an
argument.
LOCALVARS list of variables that are locally bound in
object, e.g. PROG vars.
LOCALBINDERS list of functions that bind object as a local
variable.
FREEVARS list of variables used freely by object.
FREEUSERS list of functions that use object freely.
LOCALFREEVARS list of variables that are used freely in
object, but are bound in object before they are
used, e.g. clumpget[FOO;LOCALFREEVARS;BELOW]
gives a list of those variables used freely
below FOO, but are bound above the place that
20.14
14
they are used. In English: "WHAT ARE THE LOCAL
FREE VARS (VARIABLES) BELOW FOO?"
GLOBALFREEVARS list of variables used freely in object without
previously being bound in object.
ENTRYFNS list of each function in object which is not
called by any function in object other than
itself, e.g. clumpget[FOOFNS;ENTRYFNS].
SELFRECURSIVE list of functions in object which call
themselves directly.
CAUSESELFCALL list of functions in object which could call
themselves, perhaps indirectly.
CAUSERECURSION list of functions in object which cause some
function to call itself, perhaps indirectly.
CHANGEVARS list of variables that are changed by object,
where 'changed' means any flavor of assignment,
i.e. via SETQ, SETQQ, RPAQ, SETN, or even an
expression of the form
(RPLACA (QUOTE atom) value) (or FRPLACA,
15
/RPLACA, SAVESET, etc.)
CHANGERS list of functions that change object.
Note: 'set' in English input means any flavor of assignment, and
translates the same as 'change'.
SMASHVARS list of variables whose value are smashed by
object, where 'smash' means the variable appears
------------------------------------------------------------------------
14
Note that if object is the name of a function and universe is NIL,
LOCALFREEVARS will always be NIL, and GLOBALFREEVARS the same as
FREEVARS. It is only in connection with collections of functions
that LOCALFREEVARS and GLOBALFREEVARS become interesting.
15
clumpget will accept as relations SETQVARS, SETQERS, SETVARS,
SETTERS, SETQQERS, SETQQVARS, etc., in case the user wants to
distinguish between the various flavors of assignments. In English,
"WHAT ARE THE SETQERS OF X?", etc.
20.15
as the first argument to one of the list of
16
functions on smasherslst.
SMASHERS list of functions that smash object.
TESTVARS list of variables that are tested by object,
where 'tested' means they appear as the first
argument to one of the list of functions on
testerslst, initially (ATOM LISTP NUMBERP NLISTP
STRINGP EQ EQP EQUAL NULL), or anywhere in an
AND or OR, or as the predicate in a COND clause,
or as the first argument to SELECTQ, etc.
TESTERS list of functions that test object.
USEVARS list of variables that are used in object, where
'used' means actually appear in the body of the
function, i.e. if a variable is simply bound,
but not actually used anywhere, it will not be
included in the value of USEVARS. CHANGEVARS
and TESTVARS are subsets of USEVARS.
USERS list of functions that use object.
------------------------------------------------------------------------
16
Initially (RPLACA RPLACD FRPLACA FRPLACD /RPLACA /RPLACD NCONC
NCONC1 /NCONC /NCONC1 ATTACH /ATTACH RPLNODE /RPLNODE RPLNODE2
/RPLNODE2). As with assignments, clumpget will accept as relations
RPLACAERS, RPLACAVARS, RPLACDERS, RPLACDVARS, etc., in case the user
wants to distinguish the different types of smashing.
20.16
17
20.3 Helpsys
Helpsys provides yet another form of on-line assistance to the user,
namely in the area of documentation of INTERLISP. Helpsys uses the
INTERLISP Reference Manual as a data base, and answers simple questions
about INTERLISP by presenting the appropriate passages from the manual.
Inquiries are made in the form of simple sentences, void of punctuation,
terminated with a carriage-return. The following sample session
illustrates the use of Helpsys. User inputs are underlined.
_HELPSYS]
Type ??? <CR> for assistance
!TELL ME ABOUT WHILE
... WHILE as a CLISP iterative statement operator from section 23
WHILE pred
provides a way of terminating the i.s. WHILE pred evaluates
pred before each iteration, and if the value is NIL, exits.
!TELL ME ABOUT EVAL
Do you want to see the function ? No
Do you want to see the break command ? Yes
EVAL
Same as GO or OK except that the break is maintained after the
evaluation. The user can then interrogate the value of the break
which is bound on the variable !value, and continue with the break.
More? Yes
Typing GO or OK following EVAL will not cause reevaluation but
another EVAL will. EVAL is a useful command when the user is not
sure whether or not the break will produce the correct value and
wishes to be able to do something about it if it is wrong.
!TELL ME ABOUT UB
... UB as a break command from section 15
UB
unbreaks brkfn, e.g.
(FOO BROKEN)
:UB
FOO
:
and FOO is now unbroken
!REDO EVAL
Do you want to see the function ? ...yes
eval[x]
eval evaluates the expression x and returns this value i.e.
eval provides a way of calling the interpreter.
Footnote [7] now? Yes
----------
{*7*} eval is a subr so that the 'name' x does not actually appear
------------------------------------------------------------------------
17
Helpsys was written by R. L. Walker II.
20.17
on the stack.
----------
Note that eval is itself a lambda type function, so its argument
18
is the first evaluated, e.g., {user aborts output by typing control-E}
!WHAT ARE THE ARGS FOR BREAK1
Valid arguments for BREAK1 are: [BRKEXP;BRKWHEN;BRKFN;BRKCOMS;BRKTYPE]
!TELL ME AOUT THE THIRD ARG FOR BREAK1
=ABOUT
... BREAK1 as a function from section 15
break1[brkexp;brkwhen;brkfn;brkcoms;brktype]
is an nlambda. brktype is NIL for user breaks, INTERRUPT for
control-H breaks, and ERRORX for error breaks.
!TELL ME ABOUT ERROR IN ARRAYSIZE
... ARRAYSIZE as a function from section 10
Generates an error, ARG NOT ARRAY, if a is not an array.
!TELL ME ABOUT THE LAST ARUGNEMT OF CHANGEPROP
=ARGUMENT
... CHANGEPROP as a function from section 7
changeprop[x;prop1;prop2]
Changes name of property prop1 to prop2 on property list of x,
(but does not affect the value of the property).
!USE 2ND FOR LAST
... CHANGEPROP as a function from section 7
changeprop[x;prop1;prop2]
Changes name of property prop1 to prop2 on property list of x,
(but does not affect the value of the property). Value is x,
(but does not affect the value of the property).
!WHAT IS THE VALUE OF MAPC
... MAPC as a function from section 11
The value of mapc is NIL.
!OK
NIL
------------------------------------------------------------------------
18
The user could also interrupt the output by striking the 'del' key,
which simply causes helpsys to skip over what it was currently
typing, e.g. footnote, paragraph, etc., and continue with the same
subject further on.
20.18