PSL Manual 7 February 1983 Utilities
section 17.0 page 17.1
CHAPTER 17
CHAPTER 17
CHAPTER 17
MISCELLANEOUS UTILITIES
MISCELLANEOUS UTILITIES
MISCELLANEOUS UTILITIES
17.1. Introduction . . . . . . . . . . . . . . . 17.1
17.2. RCREF - Cross Reference Generator for PSL Files . . . 17.1
17.2.1. Restrictions. . . . . . . . . . . . . 17.2
17.2.2. Usage . . . . . . . . . . . . . . . 17.3
17.2.3. Options . . . . . . . . . . . . . . 17.3
17.3. Picture RLISP. . . . . . . . . . . . . . . 17.4
17.3.1. Running PictureRLISP on HP2648A and on TEKTRONIX 17.10
4006-1 Terminals . . . . . . . . . . .
17.4. Tools for Defining Macros. . . . . . . . . . . 17.11
17.4.1. DefMacro . . . . . . . . . . . . . . 17.11
17.4.2. BackQuote. . . . . . . . . . . . . . 17.12
17.4.3. Sharp-Sign Macros . . . . . . . . . . . 17.12
17.4.4. MacroExpand . . . . . . . . . . . . . 17.13
17.4.5. DefLambda. . . . . . . . . . . . . . 17.13
17.5. Simulating a Stack . . . . . . . . . . . . . 17.14
17.6. DefStruct . . . . . . . . . . . . . . . . 17.14
17.6.1. Options . . . . . . . . . . . . . . 17.17
17.6.2. Slot Options. . . . . . . . . . . . . 17.18
17.6.3. A Simple Example . . . . . . . . . . . 17.18
17.7. DefConst . . . . . . . . . . . . . . . . 17.21
17.8. Functions for Sorting . . . . . . . . . . . . 17.22
17.9. Hashing Cons . . . . . . . . . . . . . . . 17.23
17.10. Graph-to-Tree . . . . . . . . . . . . . . 17.25
17.11. Inspect Utility. . . . . . . . . . . . . . 17.25
17.1. Introduction
17.1. Introduction
17.1. Introduction
This chapter describes an assortment of utility packages. Its purpose is
to record the existence and capabilities of a number of tools. More
information on existing packages can be found by looking at the current set
of HELP files (DIR PH:*.* on the DEC-20).
17.2. RCREF - Cross Reference Generator for PSL Files
17.2. RCREF - Cross Reference Generator for PSL Files
17.2. RCREF - Cross Reference Generator for PSL Files
RCREF is a Standard LISP program for processing a set of Standard LISP
function definitions to produce:
a. A "Summary" showing:
Utilities 7 February 1983 PSL Manual
page 17.2 section 17.2
i. A list of files processed.
ii. A list of "entry points" (functions which are not called
or are called only by themselves).
iii. A list of undefined functions (functions called but not
defined in this set of functions).
iv. A list of variables that were used non-locally but not
declared GLOBAL or FLUID before their use.
v. A list of variables that were declared GLOBAL but used as
FLUIDs (i.e. bound in a function).
vi. A list of FLUID variables that were not bound in a
function so that one might consider declaring them
GLOBALs.
vii. A list of all GLOBAL variables present.
viii. A list of all FLUID variables present.
ix. A list of all functions present.
b. A "global variable usage" table, showing for each non-local
variable:
i. Functions in which it is used as a declared FLUID or
GLOBAL.
ii. Functions in which it is used but not declared before.
iii. Functions in which it is bound.
SetQ
SetQ
iv. Functions in which it is changed by SetQ.
c. A "function usage" table showing for each function:
i. Where it is defined.
ii. Functions which call this function.
iii. Functions called by it.
iv. Non-local variables used.
The output is alphabetized on the first seven characters of each function
name.
RCREF also checks that functions are called with the correct number of
arguments.
17.2.1. Restrictions
17.2.1. Restrictions
17.2.1. Restrictions
Algebraic procedures in REDUCE are treated as if they were symbolic, so
that algebraic constructs actually appear as calls to symbolic functions,
AEval
AEval
such as AEval.
SYSLISP procedures are not correctly analyzed.
PSL Manual 7 February 1983 Utilities
section 17.2 page 17.3
17.2.2. Usage
17.2.2. Usage
17.2.2. Usage
RCREF should be used in PSL:RLISP. To make a file FILE.CRF which is a
cross reference listing for files FILE1.EX1 and FILE2.EX2 do the following
in RLISP:
@PSL:RLISP
LOAD RCREF; % RCREF is now autoloading, so this may be omitted
OUT "file.crf"; % later, CREFOUT ...
ON CREF;
IN "file1.ex1","file2.ex2";
OFF CREF;
SHUT "file.crf"; % later CREFEND
To process more files, more IN statements may be added, or the IN statement
may be changed to include more files.
17.2.3. Options
17.2.3. Options
17.2.3. Options
__________ ______
!*CREFSUMMARY [Initially: NIL] switch
If the switch CREFSUMMARY is ON then only the summary (see 1
above) is produced.
Functions with the flag NOLIST are not examined or output. Initially,
all Standard LISP functions are so flagged. (In fact, they are kept on a
list NOLIST!*, so if you wish to see references to ALL functions, then CREF
should be first loaded with the command LOAD RCREF, and this variable then
set to NIL). (RCREF is now autoloading.)
__________ ______
NOLIST!* [Initially: the following list] global
(AND COND LIST MAX MIN OR PLUS PROG PROG2 PROGN TIMES LAMB
ADD1 APPEND APPLY ASSOC ATOM CAR CDR CAAR CADR CDAR CDDR
CAADR CADAR CADDR CDAAR CDADR CDDAR CDDDR CAAAAR CAAADR
CAADDR CADAAR CADADR CADDAR CADDDR CDAAAR CDAADR CDADAR
CDDAAR CDDADR CDDDAR CDDDDR CLOSE CODEP COMPRESS CONS CO
DE DEFLIST DELETE DF DIFFERENCE DIGIT DIVIDE DM EJECT
EQUAL ERROR ERRORSET EVAL EVLIS EXPAND EXPLODE EXPT FIX FI
FLAGP FLOAT FLOATP FLUID FLUIDP FUNCTION GENSYM GET GET
GLOBAL GLOBALP GO GREATERP IDP INTERN LENGTH LESSP LIN
LITER LPOSN MAP MAPC MAPCAN MAPCAR MAPCON MAPLIST MAX2
MEMQ MINUS MINUSP MIN2 MKVECT NCONC NOT NULL NUMBERP ONE
PAGELENGTH PAIR PAIRP PLUS2 POSN PRINC PRINT PRIN1 PRIN2
PUT PUTD PUTV QUOTE QUOTIENT RDS READ READCH REMAINDE
REMFLAG REMOB REMPROP RETURN REVERSE RPLACA RPLACD SASS
SETQ STRINGP SUBLIS SUBST SUB1 TERPRI TIMES2 UNFLUID UPBV
WRS ZEROP)
Utilities 7 February 1983 PSL Manual
page 17.4 section 17.2
It should also be remembered that in RLISP any macros with the flag
EXPAND or, if FORCE is on, without the flag NOEXPAND are expanded before
the definition is seen by the cross-reference program, so this flag can
also be used to select those macros you require expanded and those you do
not. The use of ON FORCE; is highly recommended for CREF.
17.3. Picture RLISP
17.3. Picture RLISP
17.3. Picture RLISP
[??? ReWrite ???]
[??? ReWrite ???]
[??? ReWrite ???]
Picture RLISP is an ALGOL-like graphics language for Teleray, HP2648a and
Tektronix, in which graphics Model primitives are combined into complete
Models for display. PRLISP is a 3D version; PRLISP2D is a faster, smaller
2D version which also drives more terminals. Two demonstration files,
PR-DEMO.RED and PR-DEMO.Sl, are available on PU. See the help files
PH:PRLISP.HLP and PRLISP2D.HLP.
Model primitives include:
P:={x,y,z};
A point (y, and z may be omitted, default to 0).
PS:=P1_ P2_ ... Pn;
A Point Set is an ordered set of Points (Polygon).
G := PS1 & PS2 & ... PSn;
A Group of Polygons.
Point Set Modifiers
alter the interpretation of Point Sets within their scope.
BEZIER() causes the point-set to be interpreted as the specification
points for a BEZIER curve, open pointset.
BSPLINE() does the same for a Bspline curve, closed pointset.
TRANSFORMS:
Mostly return a transformation matrix.
Translation:
Move the specified amount along the specified axis.
XMOVE(deltaX); YMOVE(deltaY); ZMOVE(deltaZ);
MOVE(deltaX, deltaY, deltaZ);
Scale: Scale the Model SCALE (factor) XSCALE(factor); YSCALE(factor);
ZSCALE(factor);
SCALE1(x.scale.factor, y.scale.factor, z.scale.factor);
SCALE<Scale factor>;. Scale along all axes.
PSL Manual 7 February 1983 Utilities
section 17.3 page 17.5
Rotation: ROT(degrees); ROT(degrees, point.specifying.axis); XROT(degrees);
YROT(degrees); ZROT(degrees);
Window (z.eye,z.screen):
The WINDOW primitives assume that the viewer is located along the
z axis looking in the positive z direction, and that the viewing
window is to be centered on both the x and y axis.
Vwport(leftclip,rightclip,topclip,bottomclip):
The VWPORT, which specifies the region of the screen which is
used for display.
REPEATED (number.of.times, my.transform):
The Section of the Model which is contained within the scope of
the Repeat Specification is replicated. Note that REPEATED is
intended to duplicate a sub-image in several different places on
the screen; it was not designed for animation.
Identifiers of other Models
the Model referred to is displayed as if it were part of the
current Model for dynamic display.
Calls to PictureRLISP Procedures
This Model primitive allows procedure calls to be imbedded within
Models. When the Model interpreter reaches the procedure
identifier it calls it, passing it the portion of the Model below
the procedure as an argument. The current transformation matrix
and the current pen position are available to such procedures as
the values of the global identifiers GLOBAL!.TRANSFORM and
HEREPOINT. If normal procedure call syntax, i.e.
proc.name (parameters), is used then the procedure is called at
Model-building time, but if only the procedure's identifier is
used then the procedure is imbedded in the Model.
ERASE() Clears the screen and leaves the cursor at the origin.
SHOW(pict)
Takes a picture and displays it on the screen.
ESHOW (pict)
Erases the whole screen and display "pict".
HP!.INIT(), TEK!.INIT(), TEL!.INIT()
Initializes the operating system's view of the characteristics of
HP2648A terminal, TEKTRONIX 4006-1 (also ADM-3A with
Retrographics board, and Teleray-1061).
For example, the Model
Utilities 7 February 1983 PSL Manual
page 17.6 section 17.3
(A _ B _ C & {1,2} _ B) | XROT (30) | 'TRAN ;
%
% PictureRLISP Commands to SHOW lots of Cubes
%
% Outline is a Point Set defining the 20 by 20
% square which is part of the Cubeface
%
Outline := { 10, 10} _ {-10, 10} _
{-10,-10} _ { 10,-10} _ {10, 10};
% Cubeface also has an Arrow on it
%
Arrow := {0,-1} _ {0,2} & {-1,1} _ {0,2} _ {1,1};
% We are ready for the Cubeface
Cubeface := (Outline & Arrow) | 'Tranz;
% Note the use of static clustering to keep objects
% meaningful as well as the quoted Cluster
% to the as yet undefined transformation Tranz,
% which results in its evaluation being
% deferred until SHOW time
% and now define the Cube
Cube := Cubeface
& Cubeface | XROT (180) % 180 degrees
& Cubeface | YROT ( 90)
& Cubeface | YROT (-90)
& Cubeface | XROT ( 90)
& Cubeface | XROT (-90);
% In order to have a more pleasant look at
% the picture shown on the screen we magnify
% cube by 5 times.
BigCube := Cube | SCALE 5;
% Set up initial Z Transform for each cube face
%
Tranz := ZMOVE (10); % 10 units out
%
% GLOBAL!.TRANSFORM has been treated as a global variable.
% GLOBAL!.TRANSFORM should be initialized as a perspective
% transformation matrix so that a viewer can have a correct
% look at the picture as the viewing location changed.
% For instance, it may be set as the desired perspective
% with a perspective window centered at the origin and
% of screen size 60, and the observer at -300 on the z axis.
% Currently this has been set as default perspective transformation.
PSL Manual 7 February 1983 Utilities
section 17.3 page 17.7
% Now draw cube
%
SHOW BigCube;
%
Utilities 7 February 1983 PSL Manual
page 17.8 section 17.3
% Draw it again rotated and moved left
%
SHOW (BigCube | XROT 20 | YROT 30 | ZROT 10);
% Dynamically expand the faces out
%
Tranz := ZMOVE 12;
%
SHOW (BigCube | YROT 30 | ZROT 10);
% Now show 5 cubes, each moved further right by 80
%
Tranz := ZMOVE 10;
%
SHOW (Cube | SCALE 2.5 | XMOVE (-240) | REPEATED(5, XMOVE 80));
%
% Now try pointset modifier.
% Given a pointset (polygon) as control points either a BEZIER or a
% BSPLINE curve can be drawn.
%
Cpts := {0,0} _ {70,-60} _ {189,-69} _ {206,33} _ {145,130} _ {48,13
_ {0,84} $
%
% Now draw Bezier curve
% Show the polygon and the Bezier curve
%
SHOW (Cpts & Cpts | BEZIER());
% Now draw Bspline curve
% Show the polygon and the Bspline curve
%
SHOW (Cpts & Cpts | BSPLINE());
% Now work on the Circle
% Given a center position and a radius a circle is drawn
%
SHOW ( {10,10} | CIRCLE(50));
%
% Define a procedure which returns a model of
% a Cube when passed the face to be used
%
Symbolic Procedure Buildcube;
List 'Buildcube;
% put the name onto the property list
Put('buildcube, 'pbintrp, 'Dobuildcube);
Symbolic Procedure Dobuildcube Face$
Face & Face | XROT(180)
& Face | YROT(90)
& Face | YROT(-90)
PSL Manual 7 February 1983 Utilities
section 17.3 page 17.9
& Face | XROT(90)
& Face | XROT(-90) ;
% just return the value of the one statement
% Use this procedure to display 2 cubes, with and
% without the Arrow - first do it by calling
% Buildcube at time the Model is built
%
P := Cubeface | Buildcube() | XMOVE(-15) &
(Outline | 'Tranz) | Buildcube() | XMOVE 15;
%
SHOW (P | SCALE 5);
% Now define a procedure which returns a Model of
% a cube when passed the half size parameter
Symbolic Procedure Cubemodel;
List 'Cubemodel;
%put the name onto the property list
Put('Cubemodel,'Pbintrp, 'Docubemodel);
Symbolic Procedure Docubemodel HSize;
<< if idp HSize then HSize := eval HSize$
{ HSize, HSize, HSize} _
{-HSize, HSize, HSize} _
{-HSize, -HSize, HSize} _
{ HSize, -HSize, HSize} _
{ HSize, HSize, HSize} _
{ HSize, HSize, -HSize} _
{-HSize, HSize, -HSize} _
{-HSize, -HSize, -HSize} _
{ HSize, -HSize, -HSize} _
{ HSize, HSize, -HSize} &
{-HSize, HSize, -HSize} _
{-HSize, HSize, HSize} &
{-HSize, -HSize, -HSize} _
{-HSize, -HSize, HSize} &
{ HSize, -HSize, -HSize} _
{ HSize, -HSize, HSize} >>;
% Imbed the parameterized cube in some Models
%
His!.cube := 'His!.size | Cubemodel();
Her!.cube := 'Her!.size | Cubemodel();
R := His!.cube | XMOVE (60) &
Her!.cube | XMOVE (-60) ;
% Set up some sizes and SHOW them
His!.size := 50;
Her!.size := 30;
%
SHOW R ;
Utilities 7 February 1983 PSL Manual
page 17.10 section 17.3
%
% Set up some different sizes and SHOW them again
%
His!.size := 35;
Her!.size := 60;
%
SHOW R;
%
% Now show a triangle rotated 45 degree about the z axis.
Rotatedtriangle := {0,0} _ {50,50} _
{100,0} _ {0,0} | Zrot (45);
%
SHOW Rotatedtriangle;
%
% Define a procedure which returns a model of a Pyramid
% when passed 4 vertices of a pyramid.
% Procedure Second,Third, Fourth and Fifth are primitive procedures
% written in the source program which return the second, the third,
% the fourth and the fifth element of a list respectively.
% This procedure simply takes 4 points and connects the vertices to
% show a pyramid.
Symbolic Procedure Pyramid (Point4); %.point4 is a pointset
Point4 &
Third Point4 _
Fifth Point4 _
Second Point4 _
Fourth Point4 ;
% Now give a pointset indicating 4 vertices build a pyramid
% and show it
%
My!.vertices := {-40,0} _ {20,-40} _ {90,20} _ {70,100};
My!.pyramid := Pyramid Vertices;
%
SHOW ( My!.pyramid | XROT 30);
%
% A procedure that makes a wheel with "count"
% spokes rotated around the z axis.
% in which "count" is the number specified.
Symbolic Procedure Dowheel(spoke,count)$
begin scalar rotatedangle$
count := first count$
rotatedangle := 360.0 / count$
return (spoke | REPEATED(count, ZROT rotatedangle))
end$
%
% Now draw a wheel consisting of 8 cubes
%
PSL Manual 7 February 1983 Utilities
section 17.3 page 17.11
Cubeonspoke := (Outline | ZMOVE 10 | SCALE 2) | buildcube();
Eight!.cubes := Cubeonspoke | XMOVE 50 | WHEEL(8);
%
SHOW Eight!.cubes;
%
%Draw a cube in which each face consists of just
% a wheel of 8 Outlines
%
Flat!.Spoke := outline | XMOVE 25$
A!.Fancy!.Cube := Flat!.Spoke | WHEEL(8) | ZMOVE 50 | Buildcube()$
%
SHOW A!.Fancy!.Cube;
%
% Redraw the fancy cube, after changing perspective by
% moving the observer farther out along Z axis
%
GLOBAL!.TRANSFORM := WINDOW(-500,60);
%
SHOW A!.Fancy!.Cube;
%
% Note the flexibility resulting from the fact that
% both Buildcube and Wheel simply take or return any
% Model as their argument or value
The current version of PictureRLISP runs on HP2648A graphics terminal and
TEKTRONIX 4006-1 computer display terminal. The screen of the HP terminal
is 720 units long in the X direction, and 360 units high in the Y
direction. The coordinate system used in HP terminal places the origin in
approximately the center of the screen, and uses a domain of -360 to 360
and a range of -180 to 180. Similarly, the screen of the TEKTRONIX
terminal is 1024 units long in the X direction, and 780 units high in the Y
direction. The same origin is used but the domain is -512 to 512 in the X
direction and the range is -390 to 390 in the Y direction.
Procedures HP!.INIT and TEK!.INIT are used to set the terminals to
graphics mode and initiate the lower level procedures on HP and TEKTRONIX
terminals respectively. Basically, INIT procedures are written for
different terminals depending on their specific characteristics. Using
INIT procedures keeps terminal device dependence at the user's level to a
minimum.
17.4. Tools for Defining Macros
17.4. Tools for Defining Macros
17.4. Tools for Defining Macros
The following (and other) macro utilities are in the file PU:USEFUL.SL;
Utilities 7 February 1983 PSL Manual
page 17.12 section 17.4
1
use (LOAD USEFUL) to access. See PH:USEFUL.HLP for more information.
17.4.1. DefMacro
17.4.1. DefMacro
17.4.1. DefMacro
DefMacro
DefMacro _ __ _ ____ _ ____ __ _____
(DefMacro A:id B:form [C:form]): id macro
_____
_____
_____
DefMacro macro DefMacro
DefMacro macro DefMacro
DefMacro is a useful tool for defining macros. A DefMacro form
looks like
(DEFMACRO <NAME> <PATTERN> <S1> <S2> ... <Sn>)
____ __
The <PATTERN> is an S-expression made of pairs and ids. It is
_____
_____
_____
macro
macro
matched against the arguments of the macro much like the first
DeSetQ
DeSetQ __
argument to DeSetQ. All of the non-NIL ids in <pattern> are
local variables which may be used freely in the body (the <Si>).
_____
_____
_____
macro ProgN
macro ProgN
If the macro is called the <Si> are evaluated as in a ProgN with
the local variables in <pattern> appropriately bound, and the
DefMacro
DefMacro
value of <Sn> is returned. DefMacro is often used with
BackQuote.
17.4.2. BackQuote
17.4.2. BackQuote
17.4.2. BackQuote
Note that the special symbols described below only work in LISP syntax,
BackQuote UnQuote
BackQuote UnQuote
not RLISP. In RLISP you may simply use the functions BackQuote, UnQuote,
UnQuoteL BackQuote
UnQuoteL BackQuote
and UnQuoteL. Load USEFUL to get the BackQuote function.
_____
_____
_____
Read macro
Read macro
The backquote symbol "`" is a Read macro which introduces a quoted
expression which may contain the unquote symbols comma "," and comma-atsign
",@". An appropriate form consisting of the unquoted expression calls to
Cons
Cons
the function Cons and quoted expressions are produced so that the resulting
expression looks like the quoted one except that the values of the unquoted
expressions are substituted in the appropriate place. ",@" splices in the
value of the subsequent expression (i.e. strips off the outer layer of
parentheses). Thus
`(a (b ,x) c d ,@x e f)
is equivalent to
(cons 'a (cons (list 'b x) (append '(c d) (append x '(e f)))))
In particular, if x is bound to (1 2 3) this evaluates to
_______________
1
Useful was written by D. Morrison.
PSL Manual 7 February 1983 Utilities
section 17.4 page 17.13
(a (b (1 2 3)) c d 1 2 3 e f)
BackQuote
BackQuote _ ____ ____ _____
(BackQuote A:form): form macro
Function name for back quote `.
UnQuote
UnQuote _ ___ _________ _____
(UnQuote A:any): Undefined fexpr
Eval
Eval
Function name for comma ,. It is an error to Eval this function;
BackQuote
BackQuote
it should occur only inside a BackQuote.
UnQuoteL
UnQuoteL _ ___ _________ _____
(UnQuoteL A:any): Undefined fexpr
Eval
Eval
Function name for comma-atsign ,@. It is an error to Eval this
BackQuote
BackQuote
function; it should only occur inside a BackQuote.
17.4.3. Sharp-Sign Macros
17.4.3. Sharp-Sign Macros
17.4.3. Sharp-Sign Macros
USEFUL defines several MACLISP style sharp sign read macros. Note that
these only work with the LISP reader, not RLISP. Those currently included
are
#' : this is like the quote mark ' but is for FUNCTION instead of QUOTE.
#/ : this returns the numeric form of the following character read
without raising it. For example #/a is 97 while #/A is 65.
#\ : This is a read macro for the CHAR macro, described in the PSL
manual. Not that the argument is raised, if *RAISE is non-nil. For
Char
Char
example, #\a = #\A = 65, while #\!a = #\(lower a) = 97. Char has been
redefined in USEFUL to be slightly more table driven -- users can now add
new "prefixes" such as META or CONTROL: just hang the appropriate function
(from integers to integers) off the char-prefix-function property of the
"prefix". A LARGE number of additional alias for various characters have
been added, including all the "standard" ASCII names like NAK and DC1.
#. : this causes the following expression to be evaluated at read time.
For example, `(1 2 #.(plus 1 2) 4) reads as (1 2 3 4)
#+ : this reads two expressions, and passes them to the if_system macro.
That is, the first should be a system name, and if that is the current
system the second argument is returned by the reader. If not, the next
expression is returned.
#-: #- is similar, but causes the second arg to be returned only if it
is NOT the current system.
Utilities 7 February 1983 PSL Manual
page 17.14 section 17.4
17.4.4. MacroExpand
17.4.4. MacroExpand
17.4.4. MacroExpand
MacroExpand
MacroExpand _ ____ _ __ ____ _____
(MacroExpand A:form [B:id]): form macro
_____
_____
_____
MacroExpand macro
MacroExpand macro
MacroExpand is a useful tool for debugging macro definitions. If
MacroExpand macro
MacroExpand macro
given one argument, MacroExpand expands all the macros in that
form. Often one wishes for more control over this process. For
_____
_____
_____
macro Let
macro Let
example, if a macro expands into a Let, we may not wish to see
Let
Let
the Let itself expanded to a lambda expression. Therefore
MacroExpand
MacroExpand
additional arguments may be given to MacroExpand. If these are
_____
_____
_____
macro
macro
supplied, they should be macros, and only those specified are
expanded.
17.4.5. DefLambda
17.4.5. DefLambda
17.4.5. DefLambda
DefLambda
DefLambda _____
(DefLambda ): macro
Yet another little (two line) macro has been added to USEFUL:
DefLambda
DefLambda
DefLambda. This defines a macro much like a substitution macro
______
______
______
smacro
smacro
(smacro) except that it is a lambda expression. Thus, modulo
____
____
____
expr
expr
redefinability, it has the same semantics as the equivalent expr.
It is mostly intended as an easy way to open compile things. For
example, we would not normally want to define a substitution
macro for a constructor (NEW-FOO X) which maps into (CONS X X),
in case X is expensive to compute or, far worse, has side
effects. (DEFLAMBDA NEW-FOO (X) (CONS X X)) defines it as a
macro which maps (NEW-FOO (SETQ BAR (BAZ))) to
((LAMBDA (X) (CONS X X)) (SETQ BAR (BAZ))).
17.5. Simulating a Stack
17.5. Simulating a Stack
17.5. Simulating a Stack
The following macros are in the USEFUL package. They are convenient for
____
adding and deleting things from the head of a list.
Push
Push ___ ___ ___ ____ ___ _____
(Push ITM:any STK:list): any macro
(PUSH ITEM STACK)
is equivalent to
(SETF STACK (CONS ITEM STACK))
PSL Manual 7 February 1983 Utilities
section 17.5 page 17.15
Pop
Pop ___ ____ ___ _____
(Pop STK:list): any macro
(POP STACK)
does
(SETF STACK (CDR STACK))
_____
and returns the item popped off STACK. An additional argument
Pop
Pop
may be supplied to Pop, in which case it is a variable which is
SetQ
SetQ
SetQ'd to the popped value.
17.6. DefStruct
17.6. DefStruct
17.6. DefStruct
(LOAD DEFSTRUCT) to use the functions described below, or FAST!-DEFSTRUCT
to use those functions but with fast vector operations used. DefStruct is
similar to the Spice (Common) LISP/LISP machine/MacLISP flavor of struct
definitions, and is expected to be subsumed by the Mode package. It is
2
implemented in PSL as a function which builds access macros and fns for
"typed" vectors, including constructor and alterant macros, a type
predicate for the structure type, and individual selector/assignment fns
for the elements. DefStruct understands a keyword-option oriented
structure specification. DefStruct is now autoloading.
First a few miscellaneous functions on types, before getting into the
depths of defining DefStructs:
DefstructP
DefstructP ____ __ _____ _______ ____
(DefstructP NAME:id): extra-boolean expr
This is a predicate that returns non-NIL (the Defstruct
____
definition) if NAME is a structured type which has been defined
using Defstruct, or NIL if it is not.
DefstructType
DefstructType _ ______ __ ____
(DefstructType S:struct): id expr
This returns the type name field of an instance of a structured
_
type, or NIL if S cannot be a Defstruct type.
_______________
2
Defstruct was implemented by Russ Fish.
Utilities 7 February 1983 PSL Manual
page 17.16 section 17.6
SubTypeP
SubTypeP _____ __ _____ __ _______ ____
(SubTypeP NAME1:id NAME2:id): boolean expr
_____
This returns true if NAME1 is a structured type which has been
_____
!:Included in the definition of structured type NAME2, possibly
through intermediate structure definitions. (In other words, the
_____ _____
selectors of NAME1 can be applied to NAME2.)
Now the function which defines the beasties, in all its gory glory:
Defstruct
Defstruct ____ ___ _______ __ ____ ____ _____ __ ____ __ _____
(Defstruct NAME-AND-OPTIONS:{id,list} [SLOT-DESCS:{id,list}]): id fexpr
Defines a record-structure data type. A general call to
Defstruct
Defstruct
Defstruct looks like this: (in RLISP syntax)
defstruct( struct-name( option-1, option-2, ... ),
slot-description-1,
slot-description-2,
...
);
The name of the defined structure is returned.
Slot-descriptions are:
slot-name( default-init, slot-option-1, slot-option-2, ... )
__
Struct-name and slot-name are ids. If there are no options following a
name in a spec, it can be a bare id with no option argument list. The
default-init form is optional and may be omitted. The default-init form is
evaluated EACH TIME a structure is to be constructed and the value is used
as the initial value of the slot. Options are either a keyword id, or the
keyword followed by its argument list. Options are described below.
_____
_____
_____
macro
macro
A call to a constructor macro has the form:
MakeThing( slot-name-1( value-expr-1 ),
slot-name-2( value-expr-2 ),
... );
The slot-name:value lists override the default-init values which were part
of the structure definition. Note that the slot-names look like unary
functions of the value, so the parens can be left off. A call to MakeThing
with no arguments of course takes all of the default values. The order of
evaluation of the default-init forms and the list of assigned values is
undefined, so code should not depend upon the ordering.
____________ ____
Implementors Note: Common/LispMachine Lisps define it this way, but Is
this necessary? It wouldn't be too tough to make the order be the same as
the struct defn, or the argument order in the constructor call. Maybe they
PSL Manual 7 February 1983 Utilities
section 17.6 page 17.17
think such things should not be advertised and thus constrained in the
future. Or perhaps the theory is that constructs such as this can be
compiled more efficiently if the ordering is flexible?? Also, should the
overridden default-init forms be evaluated or not? I think not.
_____
_____
_____
macro
macro
The alterant macro calls have a similar form:
AlterThing( thing,
slot-name-1 value-expr-1,
slot-name-2 value-expr-2,
... );
The first argument evaluates to the struct to be altered. (The optional
parens were left off here.) This is just a multiple-assignment form, which
eventually goes through the slot depositors. Remember that the slot-names
are used, not the depositor names. (See !:Prefix, below.) The altered
structure instance is returned as the value of an Alterant macro.
Implementators note: Common/LispMachine Lisp defines this such that all
of the slots are altered in parallel AFTER the new value forms are
evaluated, but still with the order of evaluation of the forms undefined.
This seemed to lose more than it gained, but arguments for its worth will
be entertained.
17.6.1. Options
17.6.1. Options
17.6.1. Options
Structure options appear as an argument list to the struct-name. Many of
the options themselves take argument lists, which are sometimes optional.
Option ids all start with a colon (!:), on the theory that this
distinguishes them from other things.
By default, the names of the constructor, alterant and predicate macros
are MakeName, AlterName and NameP. "Name" is the struct-name. The
!:Constructor, !:Alterant, and !:Predicate options can be used to override
the default names. Their argument is the name to use, and a name of NIL
causes the respective macro not to be defined at all.
The !:Creator option causes a different form of constructor to be
defined, in addition to the regular "Make" constructor (which can be
suppressed.) As in the !:Constructor option above, an argument supplies
the name of the macro, but the default name in this case is CreateName. A
call to a Creator macro has the form:
CreateThing( slot-value-1, slot-value-2, ... );
___ ____ __ _______
All of the slot-values of the structure must be present, in the order they
appear in the structure definition. No checking is done, other than
assuring that the number of values is the same as the number of slots. For
___ ___ ___________
obvious reasons, constructors of this form are not recommended for
Utilities 7 February 1983 PSL Manual
page 17.18 section 17.6
structures with many fields, or which may be expanded or modified.
Slot selector macros may appear on either the left side or the right side
of an assignment. They are by default named the same as the slot-names,
but can be given a common prefix by the !:Prefix option. If !:Prefix does
not have an argument, the structure name is the prefix. If there is an
argument, it should be a string or an id whose print name is the prefix.
The !:Include option allows building a new structure definition as an
extension of an old one. The required argument is the name of a previously
defined structure type. The access functions for the slots of the source
type also works on instances of the new type. This can be used to build
hierarchies of types. The source types contain generic information in
common to the more specific subtypes which !:Include them.
The !:IncludeInit option takes an argument list of "slot-name(default-
init)" pairs, like slot-descriptors without slot-options, and files them
away to modify the default-init values for fields inherited as part of the
!:Included structure type.
17.6.2. Slot Options
17.6.2. Slot Options
17.6.2. Slot Options
Slot-options include the !:Type option, which has an argument declaring
the type of the slot as a type id or list of permissible type ids. This is
not enforced now, but anticipates the Mode system structures.
The !:UserGet and !:UserPut slot-options allow overriding the simple
vector reference and assignment semantics of the generated selector macros
with user-defined functions. The !:UserGet FNAME is a combination of the
slot-name and a !:Prefix if applicable. The !:UserPut FNAME is the same,
with "Put" prefixed. One application of this capability is building
depositors which handle the incremental maintenance of parallel data
structures as a side effect, such as automatically maintaining display file
representations of objects which are resident in a remote display processor
in parallel with modifications to the LISP structures which describe the
objects. The Make and Create macros bypass the depositors, while Alter
uses them.
17.6.3. A Simple Example
17.6.3. A Simple Example
17.6.3. A Simple Example
(Input lines have a "> " prompt at the beginning.)
PSL Manual 7 February 1983 Utilities
section 17.6 page 17.19
> % (Do definitions twice to see what functions were defined.)
> macro procedure TWICE u; list( 'PROGN, second u, second u );
TWICE
> % A definition of Complex, structure with Real and Imaginary parts
> % Redefine to see what functions were defined. Give 0 Init values
> TWICE
> Defstruct( Complex( !:Creator(Complex) ), R(0), I(0) );
*** Function `MAKECOMPLEX' has been redefined
*** Function `ALTERCOMPLEX' has been redefined
*** Function `COMPLEXP' has been redefined
*** Function `COMPLEX' has been redefined
*** Function `R' has been redefined
*** Function `PUTR' has been redefined
*** Function `I' has been redefined
*** Function `PUTI' has been redefined
*** Defstruct `COMPLEX' has been redefined
COMPLEX
> C0 := MakeComplex(); % Constructor with default inits.
[COMPLEX 0 0]
> ComplexP C0;% Predicate.
T
> C1:=MakeComplex( R 1, I 2 ); % Constructor with named values.
[COMPLEX 1 2]
> R(C1); I(C1);% Named selectors.
1
2
> C2:=Complex(3,4) % Creator with positional values.
[COMPLEX 3 4]
> AlterComplex( C1, R(2), I(3) ); % Alterant with named values.
[COMPLEX 2 3]
> C1;
[COMPLEX 2 3]
> R(C1):=5; I(C1):=6; % Named depositors.
5
6
> C1;
[COMPLEX 5 6]
> % Show use of Include Option. (Again, redef to show fns defined.)
> TWICE
Utilities 7 February 1983 PSL Manual
page 17.20 section 17.6
> Defstruct( MoreComplex( !:Include(Complex) ), Z(99) );
*** Function `MAKEMORECOMPLEX' has been redefined
*** Function `ALTERMORECOMPLEX' has been redefined
*** Function `MORECOMPLEXP' has been redefined
*** Function `Z' has been redefined
*** Function `PUTZ' has been redefined
*** Defstruct `MORECOMPLEX' has been redefined
MORECOMPLEX
> M0 := MakeMoreComplex();
[MORECOMPLEX 0 0 99]
> M1 := MakeMoreComplex( R 1, I 2, Z 3 );
[MORECOMPLEX 1 2 3]
> R C1;
5
> R M1;
1
> % A more complicated example: The structures which are used in the
> % Defstruct facility to represent defstructs. (The EX prefix has
> % been added to the names to protect the innocent...)
> TWICE% Redef to show fns generated.
> Defstruct(
> EXDefstructDescriptor( !:Prefix(EXDsDesc), !:Creator ),
>DsSize(!:Type int ), % (Upper Bound of vector.)
>Prefix(!:Type string ),
>SlotAlist( !:Type alist ), % (Cdrs are SlotDescriptors.)
>ConsName( !:Type fnId ),
>AltrName( !:Type fnId ),
>PredName( !:Type fnId ),
>CreateName( !:Type fnId ),
>Include( !:Type typeid ),
>InclInit( !:Type alist )
> );
*** Function `MAKEEXDEFSTRUCTDESCRIPTOR' has been redefined
*** Function `ALTEREXDEFSTRUCTDESCRIPTOR' has been redefined
*** Function `EXDEFSTRUCTDESCRIPTORP' has been redefined
*** Function `CREATEEXDEFSTRUCTDESCRIPTOR' has been redefined
*** Function `EXDSDESCDSSIZE' has been redefined
*** Function `PUTEXDSDESCDSSIZE' has been redefined
*** Function `EXDSDESCPREFIX' has been redefined
*** Function `PUTEXDSDESCPREFIX' has been redefined
*** Function `EXDSDESCSLOTALIST' has been redefined
*** Function `PUTEXDSDESCSLOTALIST' has been redefined
*** Function `EXDSDESCCONSNAME' has been redefined
*** Function `PUTEXDSDESCCONSNAME' has been redefined
*** Function `EXDSDESCALTRNAME' has been redefined
*** Function `PUTEXDSDESCALTRNAME' has been redefined
PSL Manual 7 February 1983 Utilities
section 17.6 page 17.21
*** Function `EXDSDESCPREDNAME' has been redefined
*** Function `PUTEXDSDESCPREDNAME' has been redefined
*** Function `EXDSDESCCREATENAME' has been redefined
*** Function `PUTEXDSDESCCREATENAME' has been redefined
*** Function `EXDSDESCINCLUDE' has been redefined
*** Function `PUTEXDSDESCINCLUDE' has been redefined
*** Function `EXDSDESCINCLINIT' has been redefined
*** Function `PUTEXDSDESCINCLINIT' has been redefined
*** Defstruct `EXDEFSTRUCTDESCRIPTOR' has been redefined
EXDEFSTRUCTDESCRIPTOR
> TWICE% Redef to show fns generated.
> Defstruct(
> EXSlotDescriptor( !:Prefix(EXSlotDesc), !:Creator ),
>SlotNum( !:Type int ),
>InitForm( !:Type form ),
>SlotFn(!:Type fnId ), % Selector/Depositor id.
>SlotType( !:Type type ), % Hm...
>UserGet( !:Type boolean ),
>UserPut( !:Type boolean )
> );
*** Function `MAKEEXSLOTDESCRIPTOR' has been redefined
*** Function `ALTEREXSLOTDESCRIPTOR' has been redefined
*** Function `EXSLOTDESCRIPTORP' has been redefined
*** Function `CREATEEXSLOTDESCRIPTOR' has been redefined
*** Function `EXSLOTDESCSLOTNUM' has been redefined
*** Function `PUTEXSLOTDESCSLOTNUM' has been redefined
*** Function `EXSLOTDESCINITFORM' has been redefined
*** Function `PUTEXSLOTDESCINITFORM' has been redefined
*** Function `EXSLOTDESCSLOTFN' has been redefined
*** Function `PUTEXSLOTDESCSLOTFN' has been redefined
*** Function `EXSLOTDESCSLOTTYPE' has been redefined
*** Function `PUTEXSLOTDESCSLOTTYPE' has been redefined
*** Function `EXSLOTDESCUSERGET' has been redefined
*** Function `PUTEXSLOTDESCUSERGET' has been redefined
*** Function `EXSLOTDESCUSERPUT' has been redefined
*** Function `PUTEXSLOTDESCUSERPUT' has been redefined
*** Defstruct `EXSLOTDESCRIPTOR' has been redefined
EXSLOTDESCRIPTOR
> END;
NIL
Utilities 7 February 1983 PSL Manual
page 17.22 section 17.7
17.7. DefConst
17.7. DefConst
17.7. DefConst
DefConst
DefConst _ __ _ ______ _________ _____
(DefConst [U:id V:number]): Undefined macro
DefConst
DefConst
DefConst is a simple means for defining and using symbolic
constants, as an alternative to the heavy-handed NEWNAM or DEFINE
facility in REDUCE/RLISP. Constants are defined thus:
DefConst(FooSize, 3); or as sequential pairs:
DEFCONST(FOOSIZE, 3,
BARSIZE, 4);
Const
Const _ __ ______ _____
(Const U:id): number macro
Const
Const
They are referred to by the macro Const, so
CONST(FOOSIZE)
would be replaced by 3.
17.8. Functions for Sorting
17.8. Functions for Sorting
17.8. Functions for Sorting
The Gsort module provides functions for sorting lists and vectors. Some
__________ ________
of the functions take a comparison function as an argument. The comparison
function takes two arguments and returns NIL if they are out of order, i.e.
if the second argument should come before the first in the sorted result.
Lambda expressions are acceptable as comparison functions.
Gsort
Gsort _____ ____ ______ ___ __ __ ________ ____ ______ ____
(Gsort TABLE:{list,vector} leq-fn:{id,function}): {list,vector} expr
____ ______ ___ __
Returns a sorted list or vector. LEQ-FN is the comparison
_____
function used to determine the sorting order. The original TABLE
Gsort
Gsort
is unchanged. Gsort uses a stable sorting algorithm. In other
_ _ _
words, if X appears before Y in the original table then X will
_ _ _
appear before Y in the final table unless X and Y are out of
_ _
order. (An unstable sort, on the other hand, might swap X and Y
_ _
even if they're in order. This could happen when X and Y have
the same "key field", so either one could come first without
making a difference to the comparison function.)
GmergeSort
GmergeSort _____ ____ ______ ___ __ __ ________ ____ ______ ____
(GmergeSort TABLE:{list,vector} leq-fn:{id,function}): {list,vector} expr
Gsort
Gsort _____
The same as Gsort, but destructively modifies the TABLE argument.
GmergeSort Gsort
GmergeSort Gsort
GmergeSort has the advantage of being somewhat faster than Gsort.
Note that you should use the value returned by the function--
PSL Manual 7 February 1983 Utilities
section 17.8 page 17.23
don't depend on the modified argument to give the right answer.
IdSort
IdSort _____ ____ ______ ____ ______ ____
(IdSort TABLE:{list,vector}): {list,vector} expr
__
Returns a table of ids sorted into alphabetical order. The
original table is unchanged. Case is not significant in
determining the alphabetical order. The table may contain
______ __
strings as well as ids.
The following example illustrates the use of Gsort.
1 lisp> (load gsort)
NIL
2 lisp> (setq X '(3 8 -7 2 1 5))
(3 8 -7 2 1 5)
3 lisp> % Sort from smallest to largest.
3 lisp> (Gsort X 'leq)
(-7 1 2 3 5 8)
4 lisp> % Sort from largest to smallest.
4 lisp> (GmergeSort X 'geq)
(8 5 3 2 1 -7)
5 lisp> % Note that X was "destroyed" by GmergeSort.
5 lisp> X
(3 2 1 -7)
6 lisp>
6 lisp> % Here's IdSort, taking a vector as its argument.
6 lisp> (IdSort '[the quick brown fox jumped over the lazy dog])
[BROWN DOG FOX JUMPED LAZY OVER QUICK THE THE]
7 lisp>
7 lisp> % Some examples of user defined comparison functions...
7 lisp> (setq X '(("Joe" . 20000) ("Moe" . 21000) ("Larry" . 7000)))
(("Joe" . 20000) ("Moe" . 21000) ("Larry" . 7000))
8 lisp>
8 lisp> % First, sort the list alphabetically according to name,
8 lisp> % using a lambda expression as the comparison function.
8 lisp> (Gsort X
8 lisp> '(lambda (X Y) (string-not-greaterp (car X) (car Y))))
(("Joe" . 20000) ("Larry" . 7000) ("Moe" . 21000))
9 lisp>
9 lisp> % Now, define a comparison function that compares cdrs of
9 lisp> % pairs, and returns T if the first is less than or equal
9 lisp> % to the second.
9 lisp> (de cdr_leq (pair1 pair2)
9 lisp> (leq (cdr pair1) (cdr pair2)))
CDR_LEQ
10 lisp>
10 lisp> % Use the cdr_leq function to sort X.
10 lisp> (Gsort X 'cdr_leq)
(("Larry" . 7000) ("Joe" . 20000) ("Moe" . 21000))
Utilities 7 February 1983 PSL Manual
page 17.24 section 17.9
17.9. Hashing Cons
17.9. Hashing Cons
17.9. Hashing Cons
HCons
HCons
HCONS is a loadable module. The HCons function creates unique dotted
HCons Eq HCons Eq
HCons _ _ Eq HCons _ _ _ Eq _
pairs. In other words, HCons(A, B) Eq HCons(C, D) if and only if A Eq C
Eq
_ Eq _
and B Eq D. This allows rapid tests for equality between structures, at
the cost of expending more time in creating the structures. The use of
HCons
HCons
HCons may also save space in cases where lists share common substructure,
since only one copy of the substructure is stored.
Hcons
Hcons ____ ____ _____
Hcons works by keeping a pair hash table of all pairs that have been
HCons
HCons
created by HCons. (So the space advantage of sharing substructure may be
offset by the space consumed by table entries.) This hash table also
allows the system to store property lists for pairs--in the same way that
LISP has property lists for identifiers.
HCons RplacA RplacD
HCons ______ ___ RplacA RplacD
Pairs created by HCons should not be modified with RplacA and RplacD.
Doing so will make the pair hash table inconsistent, as well as being very
likely to modify structure shared with something that you don't wish to
change. Also note that large numbers may be equal without being eq, so the
HCons Eq HCons
HCons Eq HCons
HCons of two large numbers may not be Eq to the HCons of two other numbers
that appear to be the same. (Similar warnings hold for strings and
vectors.)
The following "user" functions are provided by HCONS:
HCons
HCons _ ___ ____ _____
(HCons [U:any]): pair macro
HCons
HCons
The HCons macro takes one or more arguments and returns their
"hashed cons" (right associatively). With two arguments this
Cons
Cons
corresponds to a call of Cons.
HList
HList _ ___ ____ _____
(HList [U:any]): list nexpr
HList List
HList List
HList is the "HCONS version" of the List function.
HCopy
HCopy _ ___ ___ _____
(HCopy U:any): any macro
HCopy Copy HCopy
HCopy Copy HCopy
HCopy is the HCONS version of the Copy function. Note that HCopy
Copy
Copy
serves a very different purpose than Copy, which is usually used
to copy a structure so that destructive changes can be made to
HCopy
HCopy
the copy without changing the original. HCopy only copies those
Cons
Cons
parts of the structure which haven't already been "Consed
HCons
HCons
together" by HCons.
HAppend
HAppend _ ____ _ ____ ____ ____
(HAppend U:list V:list): list expr
HCons Append
HCons Append
The HCons version of Append.
PSL Manual 7 February 1983 Utilities
section 17.9 page 17.25
HReverse
HReverse _ ____ ____ ____
(HReverse U:list): list expr
HCons Reverse
HCons Reverse
The HCons version of Reverse.
Get Put
Get Put
The following two functions can be used to "Get" and "Put" properties for
pairs or identifiers. The pairs for these functions must be created by
HCons SetF
HCons SetF
HCons. These functions are known to the SetF macro.
Extended-Put
Extended-Put _ __ ____ ___ __ ____ ___ ___ ____
(Extended-Put U:{id,pair} IND:id PROP:any): any expr
Extended-Get
Extended-Get _ __ ____ ___ ___ ___ ____
(Extended-Get U:{id,pair} IND:any): any expr
17.10. Graph-to-Tree
17.10. Graph-to-Tree
17.10. Graph-to-Tree
GRAPH-TO-TREE is a loadable module. For resident functions printing
circular lists see Section 15.8.
Graph-to-Tree
Graph-to-Tree _ ____ ____ ____
(Graph-to-Tree A:form): form expr
Graph-to-Tree
Graph-to-Tree
The function Graph-to-Tree copies an arbitrary s-expression,
removing circularity. It does NOT show non-circular shared
Eq
Eq
structure. Places where a substructure is Eq to one of its
ancestors are replaced by non-interned ids of the form <n> where
n is a small integer. The parent is replaced by a two element
list of the form (<n>: u) where the n's match, and u is the
(de-circularized) structure. This is most useful in adapting any
printer for use with circular structures.
CPrint
CPrint _ ___ ___ ____
(CPrint A:any): NIL expr
CPrint
CPrint
The function CPrint, also defined in the module GRAPH-TO-TREE, is
PrettyPrint Graph-to-Tree
PrettyPrint Graph-to-Tree
simply (PrettyPrint (Graph-to-Tree X)).
Note that GRAPH-TO-TREE is very embryonic. It is MUCH more inefficient
than it needs to be, heavily consing. A better implementation would use a
stack (vector) instead of lists to hold intermediate expressions for
comparison, and would not copy non-circular structure. In addition
facilities should be added for optionally showing shared structure, for
performing the inverse operation, and for also editing long or deep
structures. Finally, the output representation was chosen at random and
can probably be improved, or at least brought in line with CL or some other
standard.
Utilities 7 February 1983 PSL Manual
page 17.26 section 17.11
17.11. Inspect Utility
17.11. Inspect Utility
17.11. Inspect Utility
INSPECT is a loadable module.
Inspect
Inspect ________ ______ ____
(Inspect FILENAME:string): expr
This is a simple utility which scans the contents of a source
file to tell what functions are defined in it. It will be
embellished slightly to permit the on-line querying of certain
Inspect
Inspect
attributes of files. Inspect reads one or more files, printing
and collecting information on defined functions.
Usage:
(LOAD INSPECT)
(INSPECT "file-name") % Scans the file, and prints proc
% names. It also
% builds the lists ProcedureList!*
% FileList!* and ProcFileList!*
% File-Name can DSKIN other files
On the Fly printing is controlled by !*PrintInspect, default is T. Other
lists built include FileList!* and ProcFileList!*, which is a list of
(procedure . filename) for multi-file processing.
For more complete process, do:
(LOAD INSPECT)
(OFF PRINTINSPECT)
(INSPECTOUT)
(DSKIN ...)
(DSKIN ...)
(INSPECTEND)