The Portable Standard LISP User's Manual, Version 3.2 USCP Users Manual TR 10 1984

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 434

DownloadThe Portable Standard LISP User's Manual, Version 3.2 USCP-Portable Users Manual-TR 10-1984
Open PDF In BrowserView PDF
TR-10

March 1981

The Portable Standard LISP Users Manual
Part 1: Language Specification
by
The Utah Symbolic Computation Group

Department of Computer Science
University of Utah
Salt Lake City, Utah 84112

Version 3.2: 16 March 1984

Abstract
This manual describes the primitive data structures, facilities and functions present in the
Portable Standard Lisp (PSL) system.
It describes the implementation details and
functions of interest to a PSL programmer. Except for a small number of hand-coded
routines for I/O and efficient function calling, PSL is written entirely in itself, using a
machine-oriented mode of PSL, called SYSLisp, to perform word, byte, and efficient
integer and string operations. PSL is compiled by an enhanced version of the Portable
Lisp Compiler, and currently runs on the DEC-20, VAX, and MC68000.

Copyright (c) 1982

W. Galway, M. L. Griss, B. Morrison, and B. Othmer

Work supported in part by the Hewlett Packard Company, the International Business
Machines Corporation and the National Science Foundation under Grant Numbers
MCS80-07034 and MCS82-04247.

I

j

PSL MANUAL

23 SEPTEMBER 1983

PREFACE

This Portable LISP implementation would not have been started without the effort and
inspiration of the original STANDARD LISP reporters (A. C. Hearn, J. Marti, M. l. Griss and
C. Griss) and the many people who gave freely of their advice (often unsolicited!).

We

especially appreciate the comments of A. Norman, M. Rothstein, H. Stoyan and T. Ager.

It would not have been completed without the efforts of the many people who have
worked arduously on SYSLISP and PSl at various levels: Eric Benson, Will Galway, Ellen
Gibson, Martin Griss, Bob Kessler, Steve lowder, Chip Maguire, Beryl Morrison, Don
Morrison, Bobbie Othmer, Bob Pendleton, John Peterson, and John W. Peterson.

We are also grateful for the many comments and significant contributions by the LISP
users at the Hewlett-Packard Computer Research Center in Palo Alto.

This document has been worked on by most members of the current Utah Symbolic
Computation Group.
M. l.

Griss,

The primary editorial function has been in the hands of B. Morrison,

B. Othmer,

and

W. Galway;

E. Benson, W. Galway, and D. Morrison.

major

sections

have

been

contributed

by

There have also been significant contributions to

the manual from Hewlett-Packard.

We have reorganized the manual for this version, following the Common lisp idea of
having four parts for language definition, utilities, system-dependent information, and
implementation information. Most of this reorganization was done at Hewlett-Packard.

This is a preliminary version of the manual, and so may suffer from a number of errors
and omissions.

We

Please let us know of problems you may detect.

have also

made some stylistic decisions regarding font to indicate semantic

classification and case to make symbols more readable.

Based on feedback from users of

the earlier 3.0 PSl release and manual, we have decided to use LISP syntax as the primary
description language; where appropriate RliSP syntax also appears. We would appreciate
comments on these and other decisions.
Report bugs, errors and mis~features by sending MAil to PSl-BUGS@Utah-20.

PSL Manual

23 September 1983

Permission is given to copy this manual for internal use with the PSL system.

PSL Manual
Table of Contents

23 September 1983

page i

TABLE OF CONTENTS

CHAPTER 1. INTRODUCTION
1.1. Opening Remarks. . . . . . . . . .
1.2. Scope of the Manual . . . . . . . .
1.2.1. Typographic Conventions within
1.2.2. The Organization of the Manual

. .
. .
the
. .

. . . .
. . . .
Manual.
. . . .

1.1
1.2
1.2
1.3

CHAPTER 2. DATA TYPES
2.1. Data Types and Structures Supported in PSL
2.1.1. Data Types. . . . . . . . .
2.1.2. Other Notational Conventions
2.1.3. Structures . . . . . . . . .
2.2. Predicates Useful with Data Types .
2.2.1. Functions for Testing Equality
2.2.2. Predicates for Testing the Type of an Object
2.2.3. Boolean Functions. . . . . . . . . . . . .
2.3. Converting Data Types . . . . . . . . . . . . .

2.1
2.1
2.3

2.4
2.5
2.5
2.6
2.8
2.9

CHAPTER 3. NUMBERS AND ARITHMETIC FUNCTIONS
3.1.
3.2.
3.3.
3.4.
3.5.
3.6.

Big Integers . . . . . . . . . . . . .
Conversion Between Integers and Floats
Arithmetic Functions . . . . . . .
Functions for Numeric Comparison.
Bit Operations . . . . . . . . . .
Various Mathematical Functions . .

3.1
3.1
3.2
3.5
3.7
3.8

CHAPTER 4. IDENTIFIERS
4.1. Introduction . . . . .
4.2. Fields of Ids . . . . .
4.3. Identifiers and the Id hash table
4.3.1. Identifier Functions
4.3.2. Find . . . . . . . . . .
4.4. Property List Functions . . . .
4.4.1. Functions for Flagging Ids .
4.4.2. Direct Access to the Property Cell
4.5. Value Cell Functions. . . . . . . . . .
4.6. System Global Variables, Switches and Other "Hooks"
4.6.1. Introduction . . . . . .
4.6.2. Setting Switches . . . .
4.6.3. Special Global Variables .
4.6.4. S'pecial Put Indicators. .

4.1
4.1

4.2
4.3
4.3

4.4
4.5
4.6
4.6
4.9
4.9
4.10
4.11
4.11

PSL Manual
Table of Contents

23 September 1983

4.6.5. Special Flag Indicators. . . . . . . . . . . .
4.6.6. Displaying Information About Globals. . . . .

page ii

4.12
4.12

CHAPTER 5. LIST STRUCTURE
5.1. Introduction to Lists and Pairs .
5.2. Basic Functions on Pairs. . . .
5.3. Functions for Manipulating Lists
5.3.1. Selecting List Elements .
5.3.2. Membership and Length of Lists
5.3.3. Constructing, Appending, and Concatenating Lists .
5.3.4. Lists as Sets . . . . . . .
5.3.5. Deleting Elements of Lists .
5.3.6. List Reversal . . . . . . .
5.3.7. Functions for Sorting . . .
5.4. Functions for Building and Searching A-Lists
5.5. Substitutions. . . . . . . . . . . . . . .

5.1
5.2

5.4
5.4
5.6
5.7
5.8
5.9
5.10
5.10
5.12
5.14

CHAPTER 6. STRINGS AND VECTORS
6.1. Vector-Like Objects.
6.2. Strings. . . .
6.3. Vectors. .. . . . . .
6.4. Word Vectors. . . .
6.5. General X-Vector Operations.
6.6. Arrays . . . . . . . . . . .
6.7. Common LISP String Functions.

6.1
6.1
6.3
6.5
6.6
6.7
6.7

CHAPTER 7. FLOW OF CONTROL
7.1. Conditionals . . . . . . . . . . .
7.1.1. Conds and Ifs. . . . . . . .
7.1.2. Case and Selectq Statements
7.2. Sequencing Evaluation.
7.3. Iteration . . . . . . . .
7.3.1. For. . . . . . . .
7.3.2. Mapping Functions
7.3.3. Do . . . . . . . .
7.4. Non-Local Exits. . . . .

7.1
7.1
7.3

7.4
7.6
7.7
7.12
7.14
7.16

CHAPTER 8. FUNCTION DEFINITION AND BINDING
8.1. Function Definition in PSL. . .
8.2. Function Types. . . . . . . . . . . . . .
8.2.1. Notes on Code Pointers. . . . . . .
8.2.2. Functions Useful in Function Definition
8.2.3. Function Definition in LISP Syntax
802.4. BackQuote . .
8.2.5. MacroExpand. . . . . . . . . .

8.1
8.1
8.2
8.2
8.5
8.7
8.8

PSL Manual
Table of Contents

23 September 1983

8.2.6. Low Level Function Definition Primitives
8.2.7. Function Type Predicates
8.3. Variables and Bindings. . . . .
8.3.1. Binding Type Declaration
8.3.2. Binding Type Predicates .
8.4. User Binding Functions . . . .

page iii

8.9
8.10
8.10
8.11
8.12
8.12

CHAPTER 9. THE INTERPRETER
9.1.
9.2.
9.3.
9.4.

Evaluator Functions Eval and Apply. . . . . . .
Support Functions for Eval and Apply. . . . . .
Special Evaluator Functions, Quote, and Function
Support Functions for Macro Evaluation. . . . .

9.1
9.5
9.7
9.7

CHAPTER 10. INPUT AND OUTPUT
10.1. Introduction. . .
10.1.1. Organization of this Chapter . .
10.2. Printed Representation of LISP Objects
10.3. Functions for Printing . . . . . . .
10.3.1. Basic Printing . . . . . . . .
10.3.2. Whitespace Printing Functions.
10.3.3. Formatted Printing. . . . . .
10.3.4. The Fundamental Printing Function
10.3.5. Additional Printing Functions
10.3.6. Printing Status and Mode.
10.4. Functions for Reading . . . . .
10.4.1. Reading S-Expressions. .
10.4.2. Reading Single Characters
10.4.3. Reading Tokens . .
10.4.4. Reading Entire Lines
10.4.5. Read Macros. . . .
10.4.6. Terminal Interaction
10.4.7. Input Status and Mode .
10.5. File System Interface: Open and Close.
10.6. Loading Modules. . . . . . . . .
10.7. Reading Files into PSL . . . . . .
10.7.1. RLISP File Reading Functions
10.8. About I/O Channels . . . . . . .
10.9. I/O to and from Lists and Strings .
10.10. Generalized Input/Output Streams
10.10.1. Using the "Special" Form of Open
10.11. Scan Table Internals . . . . . . . . .
10.12. Scan Table Utility Functions. . . . . .

10.1
10.2
10.3
10.6
10.6
10.6
10.7
10.8
10.9
10.10
10.11
10.11
10.13
10.13
10.14
10.15
10.16
10.16
10.17
10.19
10.22
10.23
10.24
10.26
10.28
10.29
10.29
10.33

CHAPTER 11. TOP LEVEL LOOP
11.1. Introduction .

11.1

PSL Manual
Table of Contents

23 September 1983

•

11.2. The General Purpose Top Loop Function.
11.3. Changing the Default Top Level Function
11.4. The Break Loop . . . . . . . . . . . .

page iv

11.1
11.4
11.4

CHAPTER 12. ERROR HANDLING
12.1.
12.2.
12.3.
12.4.
12.5.
12.6.
12.7.

Introduction .
The Basic Error Functions.
Basic Error Handlers
Break Loop . . . . . . .
Interrupt Keys. . . . . .
Details on the Break Loop
Some Convenient Error Calls

12.1
12.1
12.3
12.5
12.9
12.9
12.10

CHAPTER 13. DEBUGGING TOOLS
13.1. Introduction. . .
13.1.1. Brief Summary of Full Debug Package .
13.1.2. Redefining of User Functions by Debug
13.1.3. A Few Known Deficiencies
13.2. Step . . . . . . . . . . .
13.3. Tracing Function Execution .
13.3.1. Tracing Functions . .
13.3.2. Saving Trace Output .
13.3.3. Making Tracing More Selective
13.3.4. Turning Off Tracing . . . . .
13.4. A Break Facility . . . . . . . . . .
13.5. Enabling Debug Facilities and Automatic Tracing and Breaking.
13.6. A Heavy Handed Backtrace Facility
13.7. Embedded Functions. . . . .
13.8. Counting Function Invocations . .
13.9. Stubs. . . . . . . . . . . . . .
13.10. Functions for Printing Useful Information .
13.11. Printing Circular and Shared Structures.
13.12. Internals and Customization . . . . . . .
13. 12. 1. Use r Hooks. . . . . . . . . . . .
13.12.2. Functions Used for Printing/Reading
13.13. Example . . . . . . . . . . . . . . . .

13.1
13.1
13.2
13.3
13.3
13.4
13.4
13.6
13.7
13.9
13.10
13.11
13.12
13.12
13.13
13.14
13.14
13.15
13.16
13.16
13.17
13.18

CHAPTER 14. MISCELLANEOUS USEFUL FEATURES
14.1.
14.2.
14.3.
14.4.
14.5.
14.6.

The HELP Mechanism . . .
Exiting PSL . . . . . . .
Saving an Executable PSL.
Init Files. . . . . . . .
Miscellaneous Functions
Garbage Collection. . .

14.1
14.1
14.2
14.3
14.4
14.4

PSL MANUAL
TABLE OF CONTENTS

23 SEPTEMBER 1983

PAGE V

CHAPTER 15. COMPILER
15.1. Introduction. . . . .
15.2. The Compiler . . . .
15.2.1. Compiling Files
15.2.2. Compiling Functions into FASL Files.
15.2.3. Compiling Functions into Memory.
15.2.4. Fluid and Global Declarations'. . . .
15.2.5. Conditional Compilation . . . . . .
15.2.6. Functions to Control the Time When Something is Done
15.2.7. Order of Functions for Compilation . . . . . . . .
15.2.8. Switches Controlling Compiler . . . . . . . . . .
15.2.9. Differences between Compiled and Interpreted Code
15.2.10. Compiler Errors. . . . . . . . . . . . . .
CHAPTER 16. BIBLIOGRAPHY
CHAPTER 17. INDEX OF CONCEPTS
CHAPTER 18. INDEX OF FUNCTIONS
CHAPTER 19. INDEX OF GLOBALS AND SWITCHES

15.1
15.1
15.1
15.2
15.3
15.3
15.4
15.5
15.5
15.6
15.7
15.8

PSl MANUAL
SECTION 1.0

23 SEPTEMBER 1983

INTRODUCTION
PAGE 1.1

CHAPTER 1
INTRODUCTION
1.1. Opening Remarks. . . . . . . . . .
1.2. Scope of the Manual . . . . . . . .
1.2.1. Typographic Conventions within
1.2.2. The Organization of the Manual

. .
. .
the
. .

. . . .
. . . .
Manual.
. . . .

1.1
1.2
1.2

'.3

1.1. Opening Remarks
This document describes PSL (PORTABLE STANDARD LISP '), a portable, "modern" LISP
developed at the University of Utah for a variety of machines.
with STANDARD LISP [Marti 79].

PSL is upward-compatible

In most cases, STANDARD LISP did not commit itself to

specific implementation details (since it was to be compatible with a portion of "most"
LISPs).

PSL is more specific and provides many more functions than described in that

report.

The goals of PSl include:

* Providing implementation tools for LISP that can be used to implement a
variety of LISP-like systems., including mini-LISPs embedded in other language
systems (such as existing PASCAL or ADA applications).

*

Effectively supporting the REDUCE algebra system on a number of machines,
and providing algebra modules extracted from (or modeled upon) REDUCE to
be included in applications such as CAl and CAGD.

*

Providing a uniform, modern LISP programming environment on all of the
machines that we use (DEC-20, VAX, and 68000 based personal machines)--of
the power of FRANZ LISP, UCI LISP or MACLISP.

* Studying the utility of a LISP-based systems language for other applications
(such as CAGD or VLSI design) in which SYSLISP code provides efficiency
comparable to that of C or BCPL, yet enjoys the interactive program
development and debugging environment of LISP.

1fllSp backwards!
fI

23 September 1983

Introduction
page 1.2

PSL Manual
section 1.2

1.2. Scope of the Manual
This manual is intended to describe the syntax, semantics, and implementation of PSL.
While we have attempted to make it comprehensive, it is not intended for use as a
primer.
is

Some prior exposure to LISP will prove very helpful.

listed

in

the

bibliography

in

Chapter

16;

see

for

A selection of LISP primers
example [Allen

79, Charniak

80, Weissman 67, Winston 81].

The PSL documentation is divided into four parts following the Common LISP practice.
Part 1, the "white pages" (this document), is a language specification.
pages", is a program library document.

Part 2, the "yellow

Part 3, the "red pages", is implementation-

dependent documentation. Part 4, the "blue pages", is an implementation guide.

1.2.1. Typographic Conventions within the Manual
A large proportion of this manual is devoted to descriptions of the functions that make
up PSL.

Each function is provided with a prototypical header line.

.given a name and followed by its allowed type.

Each argument is

If an argument type is not commonly

used, it may be a specific set enclosed in brackets { ... }.

For example, this header shows

that PutD (which defines other functions) takes three arguments:

(PutD FNAME:id TYPE:~ BODY:{lambda, code-pointer}): FNAME:id
1. FNAME, which is an id (identifier).
2. TYPE, which is the "function type" of the function being defined.
3. BODY, which is a lambda expression or a code-pointer.
and returns FNAME, the name of the function being defined.

Some functions are

compiled open; these have a note saying "open-compiled" next to the function type.

Some functions accept an arbitrary number of arguments.

The header for these

functions shows a single argument enclosed in square brackets--indicating that zero or
more occurrences of that argument are allowed. For example:

(And [!:!:form]): extra-boolean
And is a function which accepts zero or more arguments each of which may be any
form.

In some cases, LISP or RLiSP code is given in the function documentation as the

function's definition.

Introduction
page 1.3

23 September 1983

PSL Manual
section 1.2

As far as possible, the code is extracted from the the current PSL

sources (perhaps converted from one syntax to the other); however, this code is not
always necessarily used in PSL, and may be given only to clarify the semantics of the
function. Please check carefully if you depend on the exact definition.

Some features of PSL are anticipated but not yet fully implemented.
documented in this manual they are indicated with the words:

When these are

[not implemented vetl

1.2.2. The Organization of the Manual
This manual is arranged in separate chapters, which are meant to be self-contained
units.

Each begins with a small table of contents serving as a summary of constructs

and as an aid in skimming. Here is a brief overview of the following chapters:

Chapter 2 describes the data types used in PSL.

It includes functions useful for testing

equality and for changing data types, and predicates useful with data types.

The next seven chapters describe in detail the basic functions provided by PSL.

Chapters 3, 4, 5, and 6 describe functions for manipulating the basic data structures of
LISP: numbers, ids, lists, and strings and vectors.

As virtually every LISP program uses

integers, identifiers, and lists extensively, these three chapters (3, 4 and 5) should be
included in an overview. As vectors and strings are used less extensively, Chapter 6 may
be skipped on a first reading.

Chapter 7 and, to some extent, Chapter 2 describe the basic functions used to drive a
computation. The reader wanting an overview of PSL should certainly read these two.

Chapter 8 describes functions useful in function definition and the idea of variable
binding. The novice LISP user should definitely read this information before proceeding to
the rest of the manual.

Chapter 9 describes functions

assoc~ated

with the interpreter.

It includes functions

having to do with evaluation (Eval and Apply.)

Chapter 10 describes the I/O facilities.

Most LISP programs do not require sophisticated

-d

Introduction
page 1.4

23 September 1983

liD, so this may be skimmed on a first reading.

PSL Manual
section 1.2

The section dealing with input deals

extensively with customizing the scanner and reader, which is only of interest to the
sophisticated user.

Chapter 11 presents information about the user interface for PSL.

It includes some

generally useful information on running the system.

Chapter 12 discusses error handling.
the sophisticated user.

Much of the information is of interest primarily to

However, LISP provides a convenient interactive facility for

correcting certain errors which may be of interest to all, so a first reading should include
parts of this chapter.

Chapter 13 discusses some tools for debugging and statistics gathering based on the
concept of embedding function definitions.

Chapter 14 describes some miscellaneous useful facilities.

Chapter 15 describes functions associated with the compiler.

Chapter 16 contains the bibliography.

Chapter 17 is an alphabetical index of concepts.
all functions defined in the manual.

Chapter 18 is an alphabetical index of

Chapter 19 contains an alphabetical index of all

global variables and switches defined in the manual.

PSL MANUAL
SECTION 2.0

DATA TYPES
PAGE 2.1

23 SEPTEMBER 1983

CHAPTER 2
DATA TYPES
2.1
2.1
2.3

2.1. Data Types and Structures Supported in PSL
2.1.1. Data Types. . . . . . . . .
2.1.2. Other Notational Conventions
2.1.3. Structures . . . . . . . . .
2.2. Predicates Useful with Data Types .
2.2.1. Functions for Testing Equality
2.2.2. Predicates for Testing the Type of an Object
2.2.3. Boolean Functions.
2.3. Converting Data Types . . . . . . . . . . . . .

2.4
2.5
2.5
2.6
2.8
2.9

2.1. Data Types and Structures Supported in PSL

2.1.1. Data Types
Data objects in PSL are tagged with their type.

This means that the type declarations

required in many programming languages are not needed.

Some functions are "generic"

in that the result they return depends on the types of the arguments.

A tagged PSL

object is called an item, and has a !§.9. field (9 bits on the DEC-20, 5 bits on the VAX), an
info field (18 bits on the DEC-20, 27 bits on the VAX), and possibly some bits for garbage
collection. The info field is either immediate data or an index or address into some other
structure (such as the heap or id space).

For the purposes of input and output of items,

an appropriate notation is used (see Chapter 10 for full details on syntax, restrictions,
etc.). More explicit implementation details can be found in Part 4 of the manual.

The basic data types supported in PSL and a brief indication of their representations are
described below.
integer

The integers are also called "fixed" numbers. The magnitude of integers
is essentially unrestricted if the "big number" module, BIG, is loaded
(LOAD BIG).
The notation for integers is a sequence of digits in an
appropriate radix (radix lOis the default, which can be overridden by a
radix prefix, such as 2#, 8#, 16# etc).· There are three internal
representations of integers, chosen to suit the implementation:
inurn

A signed number fitting into info.
Inums do not require
dynamic storage and are represented in the same form as
machine integers. (19 bit [-21'\ 18 ... 21'\ 18 - 1] on the DEC-20,

-

------------------------------~~-------------------------------

Data Types
page 2.2

23 September 1983

fixnum

PSL Manual
section 2.1

28 bit on the VAX.)
A full-word signed integer, allocated in the heap. (36 bit on
the DEC-20, fitting into a register; 32 bit on the VAX.)

[??? Do we need fixnums, and if yes how large ???]
bignum

A signed integer of arbitrary precision, allocated as a vector
of integers. Bignums are currently not installed by default; to
use them load the module BIG.

A floating point number, allocated in the heap. The precision of floats is
determined solely by the implementation, and is 72-bit double precision
on the DEC-20, 64-bit on the VAX. The notation for a float is a sequence
of digits with the addition of a single floating point ( . ) and optional
exponent (E  . < right-part».
The < left-part> is known as the Car portion and the < right-part> as
the Cdr portion. The parts may be any item. (Spaces are used to resolve
ambiguity with floats; see Chapter 10).

vector

A primitive uniform structure of items; an integer index is used to access
random values in the structure. The individual elements of a vector may
be any item. Access to vectors is by means of functions for indexing,
sub-vector extraction and concatenation, defined in Section 6.3. In the
notation for vectors, the elements of a vector are surrounded by square
brackets: [item-O item-l ... item-nJ.
A packed vector (or byte vector) of characters; the elements are smal/
integers representing the ASCII codes for the characters (usually inums).
The elements may be accessed by indexing, substring and concatenation
functions, defined in Chapter 6. String notation consists of a series of
characters enclosed in double quotes, as in "THIS IS A STRING". A quote
is included by doubling it, as in "HE SAID, ""LlSP""". (Input strings may
cross the end-of-line boundary, but a warning is given.)
See

PSL Manual
section 2.1

Data Types
page 2.3

23 September 1983

! *EOL InStr ingOK in chapter 10.
word-vector

A vector of machine-sized words, used to implement such things as
fixnums, bignums, etc. The elements are not considered to be items, and
are not examined by the garbage collector.

[??? The word-vector could be used to implement machine-code
blocks on some machines. ???]
Byte-Vector

A vector of bytes. Internally a byte-vector is the same as a string, but it
is printed differently as a vector of integers instead of characters.

Halfword-VectorA vector of machine-sized halfwords.
code-pointer

This item is used to refer to the entry point of compiled functions (exprs,
fexprs, macros, etc.), permitting compiled functions to be renamed,
passed around anonymously, etc. New code-pointers are created by the
loader (Lap,Fasl) and associated functions.
They can be printed; the
printing function prints the number of arguments expected as well as the
entry point. The value appears in the convention of the implementation
(#  on the DEC-20 and VAX, where a is the number of
arguments and nnnn is the entry point).

env-pointer

A data type used to support a funarg capability. [not implemented yet]

2.1.2. Other Notational Conventions
Certain functional arguments can be any of a number of types.
give these commonly used sets a name.
data types.

For convenience, we

We refer to these sets as "classes" of primitive

In addition to the types described above and the names for classes of types

given below, we use the following conventions in the manual.
either data type XXX or data type YYY will do.

{XXX, YYY} indicates that

{XXX}-{YYY} indicates that any object of

type XXX can be used except those of type YYY; in this case, YYY is a subset of XXX.
For example, {integer, float} indicates that either an integer or a float is acceptable;
{any}-{vector} means any type except a vector.

atom
boolean
character
constant

Any
PSL
The
The

of the types given above. S-expression is another term for any. All
entities have some value unless an error occurs during evaluation.
class {any}-{pair}.
class of global variables {T, NIL}, or their respective values, {T,
NIL}. (See Chapter 4.6).
Integers in the range of 0 to 127 representing ASCII character codes.
These are distinct from Single-character ids.
The class of {integer, float, string, vector, code-pointer}. A constant

Data Types
page 2.4

23 September 1983

PSL Manual
section 2.1

evaluates to itself (see the definition of Eval in Chapter 9).
Any value in the system. Anything that is not NIL has the boolean
interpretation T.
The class of definable function types. The set of ids {expr, fexpr, macro,
nexpr}.
The ~ is ONLY an attribute of identifiers, and is not associated with
either executable code (code-pointers) or lambda expressions.
A small integer representing an liD channel.
The class of {integer, float}.
Any kind of vector; i.e., a string, vector, word-vector, or word.
An implementation-dependent value returned by some low-level
functions; i.e., the user should not depend on this value.
A notational convenience used to indicate control functions that do not
return directly to the calling point, and hence do not return a value.
(e.g., Go)

extra-boolean

io-channel
number
x-vector
Undefined
None Returned

2.1.3. Structures
Structures are entities created using pairs.
as parameters to functions.

Lists are structures very commonly required

If a list of homogeneous entities is required by a function,

this class is denoted by xxx-list, in which xxx is the name of a class of primitives or
structures. Thus a list of ids is an id-list, a list of integers is an integer-list, and so on.
list

A list is recursively defined as NIL or the pair (any. list). A special notation
called list-notation is used to represent lists.
List-notation eliminates the
extra parentheses and dots required by dot-notation, as illustrated below.
List-notation and dot-notation may be mixed, as shown in the second and
third examples.
dot-notation
(a • (b • (c • NIL»)
(a • (b • c»
(a
c) • (d • NIL»)

«b.

Note:

list-notation
(a b c)
(a b • c)
(a (b • c) d)

0 is an alternate input representation of NIL.

An a-list, or association list, is a list in which each element is a pair, the Car
part being a key associated with the value in the Cdr part.
A form is an S-expression (any) which is legally acceptable to Eval; that is, it
is syntactically and semantically accepted by the interpreter or the compiler.
(See Chapter 9 for more details.)
lambda

A lambda expression must have the form (in list-notation): (lambda parameters
. body). "Parameters" is an id-list of formal parameters for "body", which is a
form to be evaluated (note the implicit ProgN).
The semantics of the

PSL Manual
section 2.1

Data Types
page 2.5

23 September 1983

evaluation are defined by the Eval function (see Chapter 9).
function

A lambda, or a code-pointer. A function is always evaluated as Eval, Spread.

2.2. Predicates Useful with Data Types
Most functions in this Section return T if the condition defined is met and NIL if it is
not.

Exceptions

are

noted.

Defined

are type-checking

functions

and

elementary

comparisons.

2.2.1. Functions for Testing Equality
Functions for testing equality are listed below. For other functions comparing arithmetic
values see Chapter 3.
(Eq U:any

V: any): boolean

Returns T if
items.

1J.

open-compiled, expr

points to the same object as ':!.., i.e., if they are identical

Eq is not a reliable comparison between numeric arguments.

function should only be used in special circumstances.

This

Normally, equality

should be tested with Equal, described below.
(EqN U:any

V:any): boolean

Returns T if

1J.

and ':!.. are Eq or if

1J.

and ':!.. are numbers and have the same

value and type.
[??? Should numbers of different type be EqN? e.g., 0 vs. 0.0 ???]
(Equal U: any

V:any): boolean

Returns T if !J and ':!.. are the same.

Pairs are compared recursively to the

bottom levels of their trees.

Vectors must have identical dimensions and

Equal values in all positions.

Strings must have identical characters, i.e. all

characters must be of the same case.
Other atoms must be EqN equal.

Code-pointers must have Eq values.

A usually valid heuristic is that if two

objects look the same if printed with the function Print, they are Equal.
one argument is known to be an atom, Equal is open-compiled as Eq.

If

Data Types
page 2.6

23 September 1983

For example, if
(Setq X '(A B C» and (Setq
(EQ X Y) is T
(EQ X '(A B C» is NIL
(EQUAL X '(A B C» is T
(EQ 1 1) is T
(EQ 1.0 1.0) is NIL
(EQN 1.0 1.0) is T
(EQN 1 1.0) is NIL
(EQUAL 0 0.0) is NIL
(Neq U:any

macro

11 YJ)·

V:any): boolean

(Not (Eq U
(EqStr U:any

have been executed, then

V:any): boolean

(Not (Equal
(Ne U:any

Y X)

PSL Manual
section 2.2

open-compiled, expr

~».

V:any): boolean

Compare two

strings, for exact (Case sensitive)

equality.

For case-

INsensitive equality one must load the STRINGS module (see Section 6.7).
EqStr returns T if U and ~ are Eq or if U and ~ are equal strings.
(EqCar U:any

V:any): boolean

Tests whether (Eq (Car U)

~).

If the first argument is not a pair, EqCar

returns NIL.

2.2.2. Predicates for Testing the Type of an Object
(Atom U:any): boolean
Returns T if

open-compiled, expr

11 is not a pair.

(CodeP U: any): boolean
Returns T if U is a code-pointer.

open-compiled, expr

PSL Manual
section 2.2

23 September 1983

Data Types
page 2.7

(ConstantP U:any): boolean
Returns T if

expr

!J is a constant (that is, neither a pair nor an id).

Note that

vectors are considered constants.
[??? Should Eval U Eq U if U is a constant? ???]
(FixP U:any): boolean
Returns T if

open-compiled, expr

!J is an integer. If BIG is loaded, this function also returns T for

bignums.
(Floatp U:any): boolean

open-compiled, expr

Returns T if U is a float.
(IdP U:any): boolean

open-compiled, expr

Returns T if U is an id.
(Null U:any): boolean
Returns T if

open-compiled, expr

!J is NIL. This is exactly the same function as Not, defined in

Section 2.2.3. Both are available solely to increase readability.
(NumberP U:any): boolean

open-compiled, expr

Returns T if U is a number {integer or float}.
(PairP U:any): boolean

open-compiled, expr

Returns T if U is a pair.
(StringP U:any): boolean

open-compiled, expr

Returns T if U is a string.
(VectorP U:any): boolean
Returns T if U is a vector.

open-compiled, expr

L

Data Types
page 2.8

23 September 1983

PSL Manual
section 2.2

2.2.3. Boolean Functions
Boolean functions return NIL for "false"; anything non-NIL is taken to be true, although a
conventional way of representing truth is as T. Note that T always evaluates to itself.
may also be represented as

'0.

NIL

The Boolean functions And, Or, and Not can be applied to

any LISP type, and are not bitwise functions.

And and Or are frequently used in LISP as

control structures as well as Boolean connectives (see Section 7.1).

For example, the

following two constructs will give the same result:

(CONn «AND A B C) D»
(AND ABC D)
Since there is no specific Boolean type in LISP and since every LISP expression has a
value which may be used freely in conditionals, there is no hard and fast distinction
between an arbitrary function and a Boolean function.

However, the three functions

presented here are by far the most useful in constructing more complex tests from
simple predicates.

(Not U:any): boolean
Returns T if

!:!

open-compiled, expr
is NIL. This is exactly the same function as Null, defined in

Section 2.2.2. Both are available solely to increase readability.
-(And [U:form]): extra-boolean
And evaluates each
encountered.

!:!

until a value of NIL is found or the end of the list is·

If a non-NIL value is the last value, it is returned; otherwise

NIL is returned.

Note that And called with zero arguments returns T.

(Or [U:form]): extra-boolean

!:l

open-compiled, fexpr

open-compiled, fexpr

is any number of expressions which are evaluated in order of their

appearance. If one is found to be non-NIL, it is returned as the value of Or.
If all are NIL, NIL is returned.
it returns NIL.

Note that if Or is called with zero arguments,

Data Types
page 2.9

23 September 1983

PSL Manual
section 2.3

2.3. Converting Data Types
The following functions are used in converting data items from one type to another.
They are grouped according to the type returned.

Numeric types may be converted using

functions such as Fix and Float, described in Section 3.2.

(Intern U:{id,string}): id
Gets an id on the id-hash-table.

The argument may be an id.

Intern

searches the id-hash-table (or current id-hash-table if the package system
is loaded) for an id with the same print name as !:! and returns the id on
the id-hash-table if a match is found.

(See Chapter 4 for a discussion of

the id-hash-table. Any properties and GLOBAL values associated with the
uninterned !:! are lost.
and returned.

If!:! does not match any entry, a new one is created

The argument may also be a string in which case an

identifier in the id-hash-table is looked up, created if necessary, and
returned.

Note carefully: The id returned from Interning a string has

exactlv the same print name as the string.

Most identifiers have uppercase

print names (even if you type in lower case!), but interning "abc" yields an
id with a lower case print name.

(EQ (INTERN "abc") 'abc)

= NIL

[??? Rewrite for package system; include search path, global, local,
intern, etc. ???]

The maximum number of characters in any token is 5000.

(NewId S:string): id
Allocates a new uninterned id, and sets its print-name to the

string~.

The

string is not copied.

(Setq New (NewId "NEWONE"»

returns

NEWONE

Note that if one refers directly to the id NEWONE, it will become interned
and a new position in the id space will be allocated to it. One has to refer
to the new id indirectly through the id New.

Data Types
page 2.10

23 September 1983

PSL Manual
section 2.3

(Int2Id I: integer): id
Converts an integer to an id; this refers to the !,th id in the id space. Since

o ...

127 correspond to ASCII characters, Int2Id with an argument in this

range converts an ASCII code to the corresponding single character ida
(Int2Id 250)

returns QUOTIENT

(Id2Int 0: id): integer

expr

Returns the id space position of Q. as a LISP integer.
(Id2Int 'String) returns 182
(Id2String D: id): string
Get name from

expr

id space.

argument as a string.

Id2String returns the Print name of its

This is not a copy, so destructive operations should

not be performed on the result. See CopyString in Chapter 6.
[??? Should it be a copy? ???]
(Id2String 'String)

returns "STRING"

(String2List S:string): inum-list
Creates a Jist of Length (Add 1 (Size

~)),

converting the ASCII characters

into small integers.
[??? What of 0/1 base for length vs length -1.

What of the NUL char

added ???]
(String2List "STRING")

returns (83 84 82 73 78 71)

(List2String L: inum-list): string
Allocates a string of the same Size as

expr

1:,

and converts inums to characters

according to their ASCII code. The inums must be in the range 0 ... 127.
[??? Check if 0 ... 127, and signal error ???]
{List2String '(83 84 82 73 78 71»

b

returns "STRING"

Data Types
page 2.11

23 September 1983

PSL Manual
section 2.3
(String [I: inum]): string

Creates and returns a string containing all the inums given.
(String 83 84 82 13 18 11)

returns "STRING"

(Vector [U:any]): vector

nexpr

Creates and returns a vector containing all the !:!s given.
(Setq X (Vector 83 84 82 13 18 11»
[83 84 82 13 18 11]

returns

(Vector2String V: vector): string

expr

Pack the small integers in the vector into a string of the same Size, using
the integers as ASCII values.

[??? check for integer in range 0 ... 127 ???]
(Vector2String X)
"STRING"

where X is defined as above returns

(String2Vector S: string): vector

expr

Unpack the string into a vector of the same Size.

The elements of the

vector are small integers, representing the ASCJI values of the characters in
~.

(String2Vector "VECTOR") returns [V E C TOR]
(Vector2List V: vector): list
Create a list of the same Size as y.. (Le. of Length Upbv(y")+ 1), copying the
elements in order 0, 1, ... , Upbv(y").
(Vector2List [L I S T])

returns (L I S T)

(List2Vector L: list): vector

expr

Copy the elements of the list into a vector of the same Size.
(List2Vector ,(V E C TOR»

returns [V E C TOR]

L

Data Types
page 2.12

23 September 1983

PSL Manual
section 2.3

(Int2Sys I: integer): UntaggedSystemWord
Converts an integer to an untagged system dependent word.
(Int2Sys 250)

returns 250

(Sys2Int W:UntaggedSystemWord): Inum or FixNum
If the untagged system dependent word will fit into an inum, it will be
converted into an inurn, otherwise it will be converted into a fixnum.
depending on the size.
(Sys2Int (GetMem XX»

returns tagged item at memory location XX

(Lisp2Char X: {Integer or ID or String}): CharacterNumber
If argument isan integer in the 0 to 127 range, then the integer is returned,
otherwise if the argument is an identifier then the character value of the
first character is returned, otherwise if the argument is a string, the
character value of the first character is returned, otherwise a Non Character
Error is signalled.
(Lisp2Char 32) returns 32
(Lisp2Char 'AA) returns 65
(Lisp2Char "hello") returns 104
(Lisp2Char 500) produces the error:
An attempt was made to do a 'LISP2CHAR' on '400',
which is not a character.

*****

(Int2Code I: Integer): CodePointer
Converts the argument integer into a code-pointer.
(Int2Code 3456) returns #

expr

23 SEPTEMBER 1983

PSL MANUAL
SECTION 3.0

ARITHMETIC FUNCTIONS
PAGE 3.1

CHAPTER 3
NUMBERS AND ARITHMETIC FUNCTIONS
3.1.
3.2.
3.3.
3.4.
3.5.
3.6.

Big Integers . . . . . . . . . . . . .
Conversion Between Integers and Floats
Arithmetic Functions . . . . . . .
Functions for Numeric Comparison.
Bit Operations . . . . . . . .
Various Mathematical Functions . .

3.1
3.1
3.2
3.5
3.6
3.8

Most of the arithmetic functions in PSL expect numbers as arguments.

In all cases an

error occurs if the parameter to an arithmetic function is not a number:

***** Non-numeric argument in arithmetic
Exceptions to the rule are noted.

The underlying machine arithmetic requires parameters to be either all integers or all
floats.

If a function receives mixed types of arguments, integers are converted to floats

before arithmetic operations are performed.

The range

of numbers which

represented by an integer is different than that represented by a float.

can

be

Because of this

difference, a conversion is not always possible; an unsuccessful attempt to convert may
cause an error to be signalled.

The MATHUB package contains some useful mathematical functions.

See Section 3.6 for

documentation for these functions.

3.1. Big Integers
Loading the BIG module redefines the basic arithmetic· operations, including the logical
operations, to permit arbitrary precision (or "bignum") integer operations.

Note that fixnums which are present before loading BIG can cause problems, because
loading BIG restricts the legal range of fixnums.

3.2. Conversion Between Integers and Floats
The conversions mentioned above can be done explicitly by the following functions.
Other functions which alter types can be found in Section 2.3.

L

23 September 1983

Arithmetic Functions
page 3.2

PSL Manual
section 3.2

(Fix U:number): integer

expr

Returns the integer which corresponds to the truncated value of U.
result of conversion must retain all significant portions of

1J..

The

If U is an

integer it is returned unchanged.

[??? Note that unless big is loaded, a float with value larger than
2**35-1

on the DEC-20 is converted into

without any error message.

something

strange

but

Note how truncation works on negative

numbers (always towards zero). ???]
(Fix 2.1)

% returns

(Fix -2.1)

%

2

returns-2

(Float U:number): float

expr

The float corresponding to the value of the argument U is returned.

Some

of the least significant digits of an integer may be lost due to the
implementation of Float.

Float of a float returns the number unchanged.

If U is too large to represent in float, an error occurs:
***** Argument to FLOAT is too large

[??? Only if big is loaded can one make an integer of value greater than
2**35-1, so without big you won't get this error message.

The largest

representable float is (2**62-1 )*(2**65) on the DEC-20. ???]

3.3. Arithmetic Functions
The functions described below handle arithmetic operations.

Please note the remarks at

the beginning of this Chapter regarding the mixing of argument types.
(Abs U:number): number
Returns the absolute value of its argument.
(Add1 U:number): number
Returns the value of
(integer or float).

1J.

plus 1; the returned value is of the same type as

1J.

23 September 1983

PSL Manual
section 3.3

Arithmetic Functions
page 3.3
macro

(Deer U:form [Xi:number]): number
Part of the USEFUL package (LOAD USEFUL).

With only one argument, this

is equivalent to
(SETF U

(SUB1 U)}

With multiple arguments, it is equivalent to
(SETF U

(DIFFERENCE U

(PLUS X1 •••

Xn}»

1 lisp> (Load Useful)
NIL
2 lisp> (Setq Y '(1 5 1»
(1 5 1)
3 lisp> (Deer (Car Y»

o
4

lisp> Y

(0 5 1)
5 lisp> (Deer (CadI' Y) 3 4)
-2
6 lisp> Y
(0 -2 1)
(Difference U:number V:number): number
The value of

!J - '1

is returned.

(Divide U:number V:number): pair
The pair (quotient . remainder) is returned, as if the quotient part was
computed by the Quotient function and the remainder by the Remainder
function. An error occurs if division by zero is attempted:

***** Attempt to divide by 0 in Divide
(Expt U:number V: integer): number
Returns

!J

raised to the '1 power. A float

!J

to an integer power'!.. does not

have'!.. changed to a float before exponentiation.

L

23 September 1983

Arithmetic Functions
page 3.4

PSL Manual
section 3.3

(Incr U:form [Xi:number]): number

macro

Part of the USEFUL package (LOAD USEFUL).

With only one argument, this

is equivalent to

(ADD1 U»

(SETF U

With multiple arguments it is equivalent to
(SETF U

(PLUS U

X1 ••• Xn»

(Minus U:number): number
Returns

-1J..

(Plus [U:number]): number

macro

Forms the sum of all its arguments.
argument.

Plus may be called with only one

In this case it returns its argument.

If Plus is called with no

arguments, it returns zero.
(Plus2 U:number V:number): number
Returns the sum of

1J.

and Y...

(Quotient U: number V: number): number
The Quotient of

!:!

divided by Y.. is returned. Division of two positive or two

negative integers is conventional.

If both

!:!

and Y.. are integers and exactly

one of them is negative, the value returned is truncated toward O.
argument

is

a float,

a float

implemented precision of floats.

is

returned

which

is

If either

exact within

the

An error occurs if division by zero is

attempted:

***** Attempt to divide by 0 in QUOTIENT
(Recip U:number): float
Recip converts U to a float if necessary, and then finds the inverse using
the function Quotient.

23 September 1983

PSL Manual
section 3.3

Arithmetic Functions
page 3.5

(Remainder U:integer V: integer): integer
If both!:! and ':1.. are integers the result is the integer remainder of !:! divided
by Y... The sign of the result is the same as the sign of the dividend (U).
!:! and ':1.. are not both integers, the result is currently undefined.

If

An error

occurs if ':1.. is zero:

***** Attempt to divide by 0 in REMAINDER
Note that the Remainder function differs from the Mod function in that
Remainder returns a negative number when

!J.

is negative and Y.. is positive.

(Sub1 U:number): number
Returns the value of

expr

!J.

minus 1.

If

1J. is a float, the value returned is !J.

minus 1.0.
(Times [U:number]): number

macro

Returns the product of all its arguments.
one argument.

Times may be called with only

In this case it returns the value of its argument.

If Times is

called with no arguments, it returns 1.
(Times2 U:number V:number): number
Returns the product of

!J.

and ':1...

3.4. Functions for Numeric Comparison
The following functions compare the values of their arguments.

For functions testing

equality (or non-equality) see Section 2.2.1.
(Geq U:any V:any): boolean
Returns T if

!J. >= Y..,

otherwise returns NIL.

In RLlSP, the symbol ">=" can

be used.
(GreaterP U:number V:number): boolean
Returns T if !:! is strictly greater than ':1.., otherwise returns NIL.
symbol

1/

> can be used.
1/

In RLlSP, the

L

Arithmetic Functions
page 3.6

23 September 1983

PSL Manual
section 3.4

(Leq U:number V:number): boolean
Returns T if U

<= Y.., otherwise returns NIL. In RLlSP, the symbol "<=" can

be used.
(LessP U:number V:number): boolean

11

Returns T if
symbol

"<"

is strictly less than Y.., otherwise returns NIL.

In RLlSP, the

can be used.

(Max [U:number]): number

macro

Returns the largest of the values in !:! (numeric maximum).

If two or more

values are the same, the first is returned.
(Max2 U:number V:number): number
Returns the larger of

11

and Y...

expr
If

1!

and Y.. are of the same value

11

is

returned (U and Y.. might be of different types).
(Min (U:number]): number

macro

Returns the smallest (numeric minimum) of the values in

11.

If two or more

values are the same, the first of these is returned.
(Min2 U:number V:number): number
Returns the smaller of its arguments.

expr
If!:! and Y.. are the same value,

11

is

returned (U and Y.. might be of different types) .
. (MinusP U:any): boolean
Returns T if U is a number and less than O.

expr
If

11

is not a number or is a

positive number, NIL is returned.
(OneP U:any): boolean
Returns T if
otherwise.

1!

expr
is a number and has the value 1 or 1.0.

Returns NIL

23 September 1983

PSL Manual
section 3.4

Arithmetic Functions
page 3.7

(ZeroP U:any): boolean
Returns T if

!J.

expr
is a number and has the value 0 or 0.0.

Returns NIL

otherwise.

3.5. Bit Operations
The functions described in this section operate on the binary representation of the
integers given as arguments. The returned value is an integer.

(LAnd U:integer

V: integer):

integer

Bitwise or logical And.

Each bit of the result is independently determined

from the corresponding bits of the operands according to the following
table.

!J.

o

o

V

o

1

o

Returned Value

o

o

o

(LOr U: integer V: integer): integer
Bitwise or logical Or.

Each bit of the result is independently determined

from corresponding bits of the operands according to the following table.

o

V

o
o

Returned Value

o

1

u

1

o

(LNot U: integer): integer
Logical Not.

Defined as

(-!J.

+ 1) so that it works for bignums as if they

were 2's complement.

[??? need to clarify a bit more ???]
(LXOr U: integer V: integer): integer
Bitwise or logical exclusive Or.

expr
Each bit of the result is independently

determined from the corresponding bits of the operands according to the
following table.

L

23 September 1983

Arithmetic Functions
page 3.8

Returned Value

o
o

o

o

1

PSL Manual
section 3.5

1

o
o

(LShift N: integer K: integer): integer
Shifts

N to the left by

K power.

~

bits. The effect is similar to multiplying by 2 to the

Negative values are acceptable for

~,

and cause a right shift (in

the usual manner). Lshift is a logical shift, so right shifts do not resemble
division by a power of 2.

, 3.6. Various Mathematical Functions
The optionally loadable MATHUB module defines several commonly used mathematical
functions.

Some effort has been made to be compatible with Common Lisp, but this

implementation tends to support fewer features.. The examples used here should be
taken with a grain of salt, since the precision of the results will depend on the machine
being used, and may change in later implementations of the module.
(Ceiling X : number): integer
Returns the smallest integer greater than or equal

to~.

For example:

1 lisp> (ceiling 2.1)
3
2 lisp> (ceiling -2.1)
-2
(Floor X: number): integer
Returns the largest integer less than or equal
from the Fix function.)

1 lisp> (floor 2.1)
2
2 lisp> (floor -2.1)

-3
3 lisp>
-2

(fix

-2.1)

to~.

(Note that this differs

23 September 1983

PSL Manual
section 3.6

Arithmetic Functions
page 3.9

(Round X: number): integer
Returns the nearest integer to ~.1
(TransferSign S:number Val:number): number
Transfers the sign of

~

to VAL by returning abs(VAL) if

~

>= 0, and

-abs(VAL) otherwise. (The same as FORTRANs sign function.)
(Mod M: integer N: integer): integer
Returns M modulo

N. Unlike the remainder function, it returns a positive

number in the range O.. N-1 when

1 lisp> (mod

N is positive, even if M is negative.

-7 5)

3
2 lisp> (remainder -7 5)

-2
[??? Allow to "number" arguments instead of just "integers"? ???]
(DegreesToRadians X:number): number
Returns an angle in radians given an angle in degrees.

1 lisp> (DegreesToRadians 180)

3.1415926
(RadiansToDegrees X:number): number
Returns an angle in degrees given an angle in radians.

1

lisp> (RadiansToDegrees

3.1415926)

180.0

'The behavior of Round is ambiguous when its argument ends in ".5"--needs more
work.

Arithmetic Functions
page 3.10

23 September 1983

PSL Manual
section 3.6

(RadiansToDMS X:number): list
~

Given an angle

in radians, returns a list of three integers giving the angle

in
(Degrees

Minutes

Seconds)

1 lisp> (RadiansToDMS 1.0)

(57 17 45)
(DMStoRadians Degs:number Mins:number Secs:number): number
Returns an angle in radians, given three arguments representing an angle in
degrees minutes and seconds.

1

lisp> (DMStoRadians

57 17 45)

1.0000009
2 lisp> (DMStoRadians 180 0 0)

3.1415926
(DegreesToDMS X: number): list
Given an angle

~

in degrees, returns a list of three integers giving the angle

in (Degrees Minutes Seconds).
(DMStoDegrees Degs:number Mins:number Secs:number): number
Returns an angle in degrees, given three arguments representing an angle
in degrees minutes and seconds.
(Sin X:number): number
Returns the sine of

~,

an angle in radians.

~,

an angle in degrees.

(SinD X : number): number
Returns the sine of

23 September 1983

PSL Manual
section 3.6
(Cos X:number): number
Returns the cosine of

~,

an angle in radians.

~,

an angle in degrees.

(CosD X: number): number
Returns the cosine of

(Tan X:number): number
Returns the tangent of

~,

an angle in radians.

~,

an angle in degrees.

(TanD X: number): number
Returns the tangent of
(Cot X: number): number
Returns the cotangent of

~,

an angle in radians.

~,

an angle in degrees.

(CotD X : number): number
Returns the cotangent of
(Sec X:number): number
Returns the secant of
secant(X)

~,

an angle in radians.

= 1/cos(X)

(SecD X : number): number
Returns the secant of

~,

an angle in degrees.

(Csc X: number): number
Returns the cosecant of

~,

an angle in radians.

~,

an angle in degrees.

secant(X) = 1/sin(X)
(CscD X : number): number
Returns the cosecant of

Arithmetic Functions
page 3.11

L

Arithmetic Functions
page 3.12

23 September 1983

PSL Manual
section 3.6

(Asin X:number): number
Returns the arc sine, as an angle in radians, of

~.

sin(asin(X)) = X
(AsinD X:number): number
Returns the arc sine, as an angle in degrees, of

~.

(Acos X :number): number
Returns the arc cosine, as an angle in radians, of

~.

cos(acos(X)) = X
(AcosD X: number): number
Returns the arc cosine, as an angle in degrees, of

~.

(Atan X:number): number
Returns the arc tangent, as an angle in radians, of

~.

tan(atan(X)) = X
(AtanD X:number): number
Returns the arc tangent, as an angle in degrees, of

~.

(Atan2 Y:number X:number): number
Returns an angle in radians corresponding to the angle between the X axis
and the vector

(~,Y).

1 lisp> (atan2
3.1415927

(Note that Y is the first argument.)
0

-1)

(Atan2D Y:number X:number): number
Returns an angle in degrees corresponding to the angle between the X axis
and the vector

(~,y>.

1 lisp> (atan2D -1 1)

315.0

Arithmetic Functions
page 3.13

23 September 1983

PSL Manual
section 3.6
(Acot X: number): number

~.

Returns the arc cotangent, as an angle in radians, of
cot(acot(X))

=X

(AcotD X:number): number
Returns the arc cotangent, as an angle in degrees, of

~.

(Asee X:number): number
Returns the arc secant, as an angle in radians, of

2S.

sec(asec(X)) = X
(AsecD X:number): number
Returns the arc secant, as an angle in degrees, of

2S.

(Acsc X : number): number
Returns the arc cosecant, as an angle in radians, of

~.

csc(acsc(X)) = X
(AeseD X:number): number
Returns the arc cosecant, as an angle in degrees, of
(Sqrt X:number): number
Returns the square root of

2S.

(Exp X:number): number
Returns the exponential of ~, i.e. eX.
(Log X: number): number
Returns the natural (base
log( exp(X)) = X

~

logarithm of

2S.

~.

Arithmetic Functions
page 3.14

23 September 1983

PSL Manual
section 3.6

{Log2 X:number}: number
Returns the base two logarithm of

~.

(Log10 X:number): number
Returns the base ten logarithm of ~.
{Random N: integer}: integer
Returns a pseudo-random number uniformly selected from the range O..N-1.
The random number generator uses a linear congruential method. To get a
reproducible sequence of random numbers you should assign one (or some
other small number) to the FLUID variable RandomSeed.
RandomSeed [Initially:· set from time]
(Factorial N: integer): integer
Returns the factorial of

N.

factorial{O) = 1
factorial{N) = N*factorial(N-l)

global

PSL MANUAL
SECTION 4.0

23 SEPTEMBER 1983

IDENTIFIERS
PAGE 4.1

CHAPTER 4
IDENTIFIERS
4.1. Introduction . . . . . . . . .
4.2. Fields of Ids . . . . . . . . .
4.3. Identifiers and the Id hash table
4.3.1. Identifier Functions
4.3.2. Find . . . . . . . . . .
4.4. Property List Functions . . . .
4.4.1. Functions for Flagging Ids
4.4.2. Direct Access to the Property Cell
4.5. Value Cell Functions. . . . . . . . . .
4.6. System Global Variables, Switches and Other "Hooks"
4.6.1. Introduction . . . . . .
4.6.2. Setting Switches . . . .
4.6.3. Special Global Variables.
4.6.4. Special Put Indicators. .
4.6.5. Special Flag Indicators. .
4.6.6. Displaying Information About Globals .

4.1
4.1
4.2
4.3
4.3
4.4
4.5
4.6
4.6
4.9
4.9
4.10
4.11
4.11
4 .. 12
4.12

4.1. Introduction
In PSL variables are called identifiers or ids.

An identifier is implemented as a tagged

data object (described in Chapter 2) containing a pointer or offset into a four item
structure - the id space.

One item in this structure is called the print name, which is the

external representation of the id.

The interpreter uses an id hash table to get from the print name of an identifier to its
entry in the id space. The id space and the id hash table are described below.

4.2. Fields of Ids
An id is an item with an info field; the info field is an offset into a special id space
consisting of structures of four fields. The fields (items) are:
print-name

value-cell

function-cell

The print name points at a string of characters which is the external
representation of the identifier. The syntax for identifiers is described in
Section 10.4 on reading functions.
The value of the identifier or a pointer to the value in the heap is stored
in this field. If no value exists, this cell contains an unbound identifier
indicator. These cells can be accessed by functions defined in this
chapter.
An id may have a function or macro associated with it. Access is by

23 September 1983

Identifiers
page 4.2

package-cell

PSL Manual
section 4.2

means of the PutD, GetD, and RemD functions defined in Section 8.2.2.
PSL permits the use of a multiple package facility (multiple id hash
table). The package cell refers to the appropriate id hash table.

4.3. Identifiers and the Id hash table
The method used by PSL to retrieve information about an identifier makes use of the id
hash table (corresponding to the Oblist, or Object list, in some versions of LISP).

A hash

function is applied to the identifier name giving a position in the id hash table.
contents of the hash table at that point contain an offset into the id space.

The

For a new

identifier, the next free position in the id space is found and a pointer to it is placed in
the hash table entry.

The process of putting an id into the hash table is called interning.

This is done

automatically by the LISP reader, so any id typed in at the terminal is interned.

Interning

can also be done by the programmer using the function Intern to convert a string to an
id.

An id may have an entry in the id space without being interned.

In fact it is possible

to have several ids with the same print name, one interned and the others not.

Note that when one starts PSL, the id space already contains approximately 2000 ids.
These include all of the ASCII characters, the functions and globals described in this
manual, plus system functions and globals.

If a user uses any of these names for his

own functions or globals, there can be a conflict.

A warning message appears if a user

tries to redefine a system function.
? Do you really want to redefine the system function 'name?

(Y

or N)

If the user answers "Y", his definition replaces the current definition. (See Chapter 8 for a
description of the switch !*USERMODE which controls the printing of this message.)

Information on converting ids to other types can be found in Chapter 10 and Section
2.3.

L

PSL Manual
section 4.3

23 September 1983

Identifiers
page 4.3

4.3.1. Identifier Functions
The following functions deal with identifiers and the id hash table.
(GenSym ): id
Creates an identifier which is not interned on the id hash table and
consequently not Eq to anything else. The id is derived from a string of the
form "GOOOOII, which is incremented upon each call to GenSym.

[??? Is this interned or recorded on the NIL package ???]
[??? Can we change the GenSym string ???]
(Intern enSym ): id
Similar to GenSym but returns an interned id.
(StringGenSym ): string
S'imilar to GenSym but returns a string of the form "LOOOOII instead of an id.
(RemOb U: id): U: id
If !:! is present on the current package search path it is removed. This does
not affect!:! having properties, flags,. functions and the like. !:! is returned.
(InternP U: {id,string}): boolean
Returns T if !:! is interned in the current search path.
(MapObl FNAME: function): Undefined
MapObl applies function FNAME to each id interned in the current hash
table.

4.3.2. Find
These functions take a string or id as an argument, and scan the id hash table to collect
a list of ids with prefix or suffix matching the argument.
FIND).

This is a loadable option (LOAD

PSL Manual
section 4.3

23 September 1983

Identifiers
page 4.4

(FindPrefix KEY: {id, string}}: id-list

expr

Scans current id hash table for all ids whose prefix matches KEY.

Returns

all the identifiers found as an alphabetically sorted list.

(FindSuffix KEY: {id, string}): id-list

expr

Scans current id hash table for all ids whose suffix matches KEY.

Returns

all the identifiers found as an alphabetically sorted list.

%Finds all identifiers starting with *

(Setq X (FindPrefix '!*)

(Setq Y (FindSuffix "STRING")) %Finds all identifiers ending with STRING
4.4. Property List Functions
The property cell of an identifier points to· a "property list".

The list is used to quickly

associate an id name with a set of entities; those entities are called "flags" if their use
gives the id a boolean value, and "properties" if the id is to have an arbitrary attribute (an
indicator with a property).

(Put U:id IND:id PROP:any): any
The indicator INO with the property PROP is placed on the property list of
the id 1:[.
either of

If the action of

!:l

Put

occurs, the value of PROP is returned.

If

and INO are not ids the type mismatch error occurs and no

property is placed.

(Put 'Jim 'Height 68)
The above returns 68 and places (Height . 68) on the property list of the id
Jim.

(Get U: id IND: id): any
Returns the property associated with indicator INO from the property list of

1:[.

If!J. does not have indicator INO,

could access functions.)

Get

returns

NIL

NIL

(Get 'Jim 'Height) returns 68

is returned.

(In older LISPs,

if U is not an ide

Get

PSL Manual
section 4.4

23 September 1983

Identifiers
page 4.5

(DefList U: list IND: id): list

11

is a list in which each element is a two-element list:

Each id in

11

(10:10 PROP:ANY).

has the indicator INO with property PROP placed on its

property list by the Put function.

The value of DefList is a list of the first

elements of each two-element list.

Like Put, DefList may not be used to

define functions.
(DE DEFLIST (U IND)
(COND «NULL U) NIL)
(f (CONS(PROGN(PUT (CAAR U) IND (CADAR U»
(CAAR U»
(DEFLIST (CDR U) IND»»)
(RemProp U:id IND:id): any
Removes the property with indicator INO from the property list of

11.

Returns the removed property or NIL if there was no such indicator.
(RemPropL U: id-list IND: id): NIL
Remove property INO from all ids in U.

4.4.1. Functions for Flagging Ids
In some LISPs, flags and indicators may clash.

In PSL, flags are ids and properties are

pairs on the prop-list, so no clash occurs.

(Flag U: id-list V: id): NIL
Flag flags each id in
~

in

11,

11

with

y;

that is, the effect of Flag is that for each id

FlagP(X, V) has the value T.

Both

y and all the elements of 11 must

be identifiers or the type mismatch error occurs.
appears on the property list of each id X in

11.

After Flagging, the id Y...
However, flags cannot be

accessed, placed on, or removed from property lists using normal property
list functions Get, Put, and RemProp.

Note that if an error occurs during

execution of Flag, then some of the ids on
others may not be.

!J.

The statement below causes the flag "Lose" to be

placed on the property lists of the ids X and Y.
(Flag

'(X Y)

may be flagged with Y.., and

'Lose)

Identifiers
page 4.6

23 September 1983

PSL Manual
section 4.4

(FlagP U: id V: id): boolean
Returns T if
if either

!J.

!J.

has been flagged with Y..; otherwise returns NIL.

Returns NIL

or Y.. is not an id.

(RemFlag U: id-list V: id): NIL

!J..

Removes the flag y... from the property list of each member of the list
Both Y.. and all the elements of

!J.

must be ids or the type mismatch error

occurs.
(Flag1 U:id V:any): Undefined
Puts flag Y.. on the property list ofid U.
(RemFlag1 U: id V:any): Undefined
Removes the flag Y.. from the property list of id U.

[??? Make Flag 1 and Rem Flag 1 return single value. ???]

4.4.2. Direct Access to the Property Cell
Use of the following functions can destroy the integrity of the property list.

Since PSL

uses properties at a low level, care should be taken in the use of these functions.
(Prop U: id): any
Returns the property list of U.
(SetProp U: id L: any): L: any
Store item

.b as the property list of !J..

4.5. Value Cell Functions
The contents of the value cell are usually accessed by Eval (Chapter 9) or ValueCell
(below) and changed by SetQ or sometimes Set.
(SetQ VARIABLE:id VALUE:any): any
The value of the current binding of VARIABLE is replaced by the value of
VALUE.
(SETQ X 1)

PSLManual
section 4.5

23 September 1983

Identifiers
page 4.7

is equivalent to
(SET 'X 1)
SetQ now conforms to the Common LISP standard, allowing sequential
assignment:
(SETQ A 1 B 2)
==> (SETQ A 1)
(SETQ B 2)
(Set EXP: id VALUE: any): any
EXP must be an identifier or a type mismatch error occurs.

The effect of

Set is replacement of the item bound to the identifier by VALUE.

If the

identifier is not a LOCAL variable or has not been declared GLOBAL, it is
automatically declared FLUID with the resulting warning message:

***

EXP declared FLUID

EXP must not evaluate to T or NIL or an error occurs:

*****

Cannot change T or NIL

(DeSetQ U:any V:any): V:any

macro

This is a function in the USEFUL package.

DeSetQ is a destructuring SetQ.

That is, the first argument is a piece of, list structure whose atoms are all
ids.

Each is SetQ'd to the corresponding part of the second argument.

For

instance
(DeSetQ (a (b) • c) '«1) (2)

(3)

4»

SetQ's a to (1), b to 2, and c to «3) 4).

(PSetQ [VARIABLE:id VALUE:any]): Undefined

macro

Part of the USEFUL package (LOAD USEFUL).
(PSETQ VAR1 VAL 1 VAR2 VAL2 •••

YARn VALn)

SetQ's the VAR's to the corresponding VAL's.

The VAL's are all evaluated

before any assignments are made. That is, this is a parallel SetQ.

Identifiers
page 4.8

23 September 1983

PSL Manual
section 4.5

(SetF [LHS:form RHS:any]): RHS:any

macro

There are two versions of SetF. SetF is redefined on loading USEFUL. The
description below is for the resident SetF.

SetF provides a method for

assigning values to expressions more general than simple ids. For example:

(SETF (CAR X)
==> CAR X

2)
:= 2;

is equivalent to
(RPLACA

X 2)

In general, SetF has the form
(SetF LHS RHS)
in which LHS is the flleft hand side" to be assigned to and RHS is evaluated
to the value to be assigned. LHS can be one of the following:
id
(Eval expression)

(Value expression)
(Car pair)
(Cdr pair)
(GetV vector)
(Indx "indexable object")
(Sub vector)

SetQ is used to assign a value to the id.
Set is used instead of SetQ. In effect, the
flEval" cancels out the "Quote" which would
normally be used.
Is treated the same as Eval.
RplacA is used to store into the Car "field".
RplacD is used to store into the Cdr "field".
Putv is used to store into the appropriate
location.
Setlndx is used to store into the object.
SetSub is used to store into the appropriate
subrange of the vector.

Note that if the LHS is (Car pair) or (Cdr pair), SetF returns the modified
pair instead of the RHS, because SetF uses RplacA and RplacD in these
cases .

.Loading USEFUL brings in declarations to SetF about Caar, Cadr, ... Cddddr.
This is rather handy with constructor/selector macros.
is a selector which maps to Cadadr,
(SETF (Foo X) Y)

For instance, if FOO

PSL Manual
section 4.5

23 September 1983

Identifiers
page 4.9

works; that is, it maps to something which does a
(RPLACA (CDADR X) Y)
and then returns X.
(PSetF [LHS:form RHS:any]): Undefined

macro

Part of the USEFUL package (LOAD USEFUL).

PSetF does a SetF in parallel:

i.e., it evaluates all the right hand sides (RHS) before assigning any to the

left hand sides (LHS).
(MakeUnBound U: id): Undefined
Make!:! an unbound id by storing a "magic" number in the value cell.
(ValueCell U: id): any
Safe access to the value cell of an ide

If!:! is not an id a type mismatch

error is signalled; if !:! is an unbound id, an unbound id error is signalled.
Otherwise the current value of !:! is returned.

[See also the Value and

LispVar functions, described in [], for more direct access].
(UnBoundP U: id): boolean
Tests whether U has no value.

[??? Define and describe General Property LISTs or hash-tables. See Hcons. ???]

4.6. System Global Variables, Switches and Other "Hooks"
4.6.1. Introduction
A number of global variables provide global control of the LISP system, or implement
values which are constant throughout execution.

Certain options are controlled by

switches, with T or NIL properties (e.g., ECHOing as a file is read in); others require a
value, such as an integer for the current output base.

PSL has the convention (following

the REDUCE/RLISP convention) of using a "!*" in the name of the variable: ! *xxxxx for
GLOBAL variables expecting a TINIL value (called "switches"), and xxxxx!* for other
GLOBALs. Chapter 19 is an index of switches and global variables used in PSL.

Identifiers
page 4.10

23 September 1983

PSL Manual
section 4.6

[??? These should all be FLUIDs, so that ANYone of these variables may be rebound,
as appropriate ???]

4.6.2. Setting Switches
Strictly speaking,

xxxx

is a switch and

!*xxxx

is a corresponding global variable that

assumes the TINIL value; both are loosely referred to as switches elsewhere in the
manual.

The On and Orf functions are used to change the values of the variables associated with
switches.

Some switches contain an s-expression on their property lists under the

indicator 'SIMPFG 1. The s-expression has the form of a Cond list:
((T (action-for-ON)) (NIL (action-for-OFF)))
If the 'SIMPFG indicator is present, then the On and orr functions also evaluate the
appropriate action in the s-expression.

(On [U:id]}:None
For each

macro

!J.,

the associated ! *U variable is set to T.

ON})" clause is found by (GET

!J.

If a "(T (action-for-

'SIMPFG), the "action" is EVAL'ed.

(Off [U: id]): None

macro

For each U, the associated ! *U variable is set to NIL.
OFF)" clause is found by (GET

!J.

If a "(NIL (action-for-

'SIMPFG), the "action" is EVAL'ed.

(On Comp Ord Usermode)
will set !*Comp, !*Ord, and !*Usermode to T.

Note that
(Get 'Cref 'Simpfg)
returns

l The name SIMPFG comes from its introduction in the REDUCE algebra system, where
it was used as a "simp flag" to specify various simplifications to be performed as various
switches were turned on or off.

b

PSL Manual
section 4.6

23 September 1983

«T (Crefon»

Identifiers
page 4.11

(Nil (Crefoff»)

Setting CREF on will result in !*CREF being set to T and the function Crefon being
evaluated.

4.6.3. Special Global Variables
NIL [Initially: NIL]

global

NIL is a special GLOBAL variable.

It is protected from being modified by

Set or SetQ.

T [Initially: T]

global

T is a special GLOBAL variable.

It is protected from being modified by Set

or SetQ.

4.6.4. Special Put Indicators
Some actions search the property list of relevant ids for these indicators:
'HELPFUNCTION

An id, a function to be executed to give help about the topic; ideally for
a complex topic, a clever function is used.

'HELPSTRING

A help string, kept in core for important or short topics.

'HELPFILE

The most common case, the name of a file to print; later we hope to
load this file into an EMODE buffer for perusal in a window.

'SWITCHINFO

A string describing the purpose of the SWITCH, see ShowSwitches
below.

'GLOBALINFO

A string describing the purpose of the GLOBAL, see ShowGlobals below.

'BREAKFUNCTION Associates a function to be run with an Id typed at Break Loop, see
Chapter 12.
'TYPE

PSL uses the property TYPE to indicate whether a function is a fexpr,
macro, or nexpr; if no property is present, expr is assumed.

'VARTYPE

PSL uses the property VARTYPE to indicate whether an identifier is of
type GLOBAL or FLUID.

'TRACE

Used by the debug facility to

record

information

about the debug

L

Identifiers
page 4.12

23 September 1983

PSL Manual
section 4.6

facilities being used and the original function definition.
'!*LAMBDALINK

The interpreter also looks under '!*LAMBDALINK for a Lambda expression,
if a procedure is not compiled.

The. compiler and loader use the following indicators: MC, CaNST, EXTVAR, MEMMOD,
NOSIDEEFFECT, REG, TERMINAL, TRANSFER, VAR, ANYREG, CFNTYPE, DESTROYS, DOFN,
EMITFN, EXITING, FLIPTST, GROUPOPS, MATCHFN, NEGJMP, ONE, PATTERN, SUBSTFN,
ZERO.

This are described in more detail with the documentation of compiler and loader

implementation.

4.6.5. Special Flag Indicators
'EVAL

If the id is flagged EVAL, the RLISP top-loop evaluates and outputs any
expression (id ... ) in On Defn (!*DEFN := T) mode.

, IGNORE

If the id is flagged IGNORE, the RLiSP top-loop evaluates but does NOT output
any expression (id ... ) in On Defn (! *DEFN := T) mode.

'LOSE

If an id has the 'LOSE flag, it will not be defined by PutD when it is read in.

'USER

'USER is put on all functions defined when in !*USERMODE, to distinguish
them from "system" functions. See Chapter 8.

See also the functions LoadTime and CompileTime in Chapter 15.

[??? Mention Parser properties ???]

4.6.6. Displaying Information About Globals
The Help function has two options, (HELP SWITCHES) and (HELP GLOBALS), which should
display the current state of a variety of switches and globals respectively.

These caHs

have the same effect as using the functions below, using an initial table of Switches and
Globals.

The function (ShowSwi tches switch-list) may be used to print names, current settings
and purpose of some switches.

Use NIL as the switch-list to get information on ALL

switches of interest; ShowSwi tches in this case does a MapObl (Section 4.3.1) looking for
'Switchlnfo property.
Similarly, (ShowGlobals global-list) may be used to print names, values and purposes of

PSL Manual
section 4.6
important GLOBALs.

23 September 1983

Identifiers
page 4.13

Again, NIL used as the global-list causes ShowGlobals to do a

MapObl looking for a 'Globallnfo property; the result is some information about all globals
of interest.

PSL MANUAL
SECTION 5.0

23 SEPTEMBER 1983

LIST STRUCTURE
PAGE 5.1

CHAPTER 5
LIST STRUCTURE
5.1. Introduction to Lists and Pairs .
5.2. Basic Functions on Pairs. . . .
5.3. Functions for Manipulating Lists
5.3.1. Selecting List Elements .
5.3.2. Membership and Length of Lists
5.3.3. Constructing, Appending, and Concatenating Lists .
5.3.4. Lists as Sets . . . . . . .
5.3.5. Deleting Elements of Lists .
5.3.6. List Reversa I . . . . . . .
5.3.7. Functions for Sorting . . .
5.4. Functions for Building and Searching A-Lists
5.5. Substitutions. . . . . . . . . . . . . . .

5.1.
5.2
5.4
5.4

5.6
5.7
5.8
5.9
5.10
5.10
5.12
5.14

5.1. Introduction to Lists and Pairs
The pair is a fundamental PSL data type, and is one of the major attractions of LISP
programming. A pair consists of a two-item structure.

In PSL the first element is called

the Car and the second the Cdr; in other LISPs, the physical relationship of the parts may
be different. An illustration of the tree structure is given below as a box diagram; the Car
and the Cdr are each represented as a portion of the box.

II

Car

I

II

Cdr

As an example, a tree written as «A . B) . (C . D)) in dot-notation is drawn below as a
box diagram.

II

I

I \

II

----1-------\---I

II

A

B

\

II

II

c

D II

The box diagrams are tedious to draw, so dot-notation is normally used.

Note that a

space is left on each side of the . to ensure that pairs are not confused with floats.

Note

also that in RLiSP a dot may be used as the infix operator f.or the function Cons, as in the

List Structure
page 5.2

23 September 1983

PSL Manual
section 5.1

expression x := 'y . 'z;, or as part of the notation for pairs, as in the expression x := '(y . z).

An important special case occurs frequently enough that it has a special notation.
is a list of items, terminated by convention with the id NIL.

This

The dot and surrounding

parentheses are omitted, as well as the trailing NIL. Thus

(A • (B • (C • NIL»)
can be represented in list-notation as

(A B C)

5.2. Basic Functions on Pairs
The following are elementary functions on pairs.

All functions in this Chapter which

require pairs as parameters signal a type mismatch error if the parameter given is not a
pair.

(Cons U:any V:any): pair
Returns a pair which is not Eq to anything else and has
and

y..

as its Cdr part.

meaning

Cons.

!J

as its Car part

In RLISP syntax the dot, ".", is an infix operator
Thus

{A . (8 . fn C) . D)

is

equivalent

to

Cons {A, Cons (Cons (8, tn C), D)}.
(Car U:pair): any

open-compiled, expr

The left part of U is returned.
pair, except when

!l

A type mismatch error occurs if

is NIL. Then NIL is returned.

pair, except when

is not a

{Car (Cons a b)) == > a.

(Cdr U:pair): any
The right part of

!J

open-compiled, expr

!l
!l

is returned.

A type mismatch error occurs if

is NIL. Then NIL is returned.

!l

is not a

(Cdr (Cons a b)) == > b.

The composites of Car and Cdr are supported up to four levels.

PSL Manual
section 5.2

23 September 1983

List Structure
page 5.3

Cal'

Cdr

Caar
Caaar

Cdar

Cdaar

Cadar

CadI'

Cd dar

Caadr

Cdadr

Cddr
Caddr

Cdddr

Caaaar

Cadaar

Caadar

Cad dar

Caaadr

Cadadr

Caaddr

Cadddr

Cdaaar

Cddaar

Cdadar

Cdddar

Cdaadr

Cddadr

Cdaddr

Cddddr

These are all exprs of one argument.
generally open-compiled.

They may return any type and are

An example of their use is that Cddar p is

equivalent to Cdr Cdr Car p.

As with Car and Cdr, a type mismatch error

occurs if the argument does not possess the specified component.
As an alternative to employing chains of CxxxxR to obscure depths, particularly in
extracting elements of a list, consider the use of the functions First, Second, Third,
Fourth, or Nth (Section 5.3.1), or possibly even the Defstruct package (See Part 2 of the
manual).
(NCons U:any): pair
Equivalent to Cons (U, NIL).
(XCons U:any V:any): pail'
Equivalent to Cons

01.' ill.

(Copy X :any): any
Copies all pairs in ~, but does not make copies of atoms (including vectors
and strings). For example, if A is

([2 5] "ATOM")
and B is the result of (Copy A), then

but
and

(Eq A B) is NIL
(Eq (Cal' A) (Car B» is T
(Eq (CadI' A) (CadI' B» is

See TotalCopy in Section 6.5.

T

Note that Copy is recursive and will not

terminate if its argument is a circular list.
See Chapter 6 for other relevant functions.

List Structure
page 5.4

23 September 1983

PSL Manual
section 5.2

The following functions are known as "destructive" functions, because they change the
structure of the pair given as their argument, and consequently change the structure of
the object containing the pair.
functions

(e.g.

the

They are most frequently used for various "efficient"

non-copying

ReverseIP

and

NConc

functions,

and

destructive

DeleteIP) and to build structures that have deliberately shared sub-structure.

They are

also capable of creating circular structures, which create havoc with normal printing and
list traversal functions.

Be careful using them.

(RplacA U: pair V: any): pair

open-compiled, expr

The Car of the pair 1l is replaced by Y.., and the modified 1l is returned.

1l is (a . b) then (Y.. .b) is returned}.

A type mismatch error occurs if

(If

1l is

not a pair.
(RplacD U: pair V: any): pair

open-compiled, expr

The Cdr of the pair 1l is replaced by Y.., and the modified

!l is (a . b) then fa . YJ is returned}.

!:!

is returned.

A type mismatch error occurs if

!:!

(If
is

not a pair.
(RplacW A:pair B:pair): pair
Replaces the whole pair:

the Car of ~ is replaced with the Car of ~, and

the Cdr of ~ with the Cdr of §.. The modified ~ is returned.

[??? Should we add some more functions here someday?

Probably the RLISP guys

that do arbitrary depth member type stuff. ???]

5.3. Functions for Manipulating Lists
The following functions are meant for the special pairs which are lists, as described in
Section 5.1. Note that the functions described in Chapter 6 can also be used on lists.

[??? Make some mention of mapping with FOR. .. COLLECT and such like. ???]

5.3.1. Selecting List Elements

PSL Manual
section 5.3

23 September 1983

List Structure
page 5.5

(First L: pair): any
A synonym for Car

macro

1:.

(Second L:pair): any

macro

A synonym for Cadr

1:.

(Third L: pair): any

macro

A synonym for Caddr

1:.

(Fourth L :pair): any

macro

A synonym for Cadddr

1:.

(Rest L: pair): any

macro

A synonym for Cdr

1:.

(Las tPair L: pair): any
Last pair of a list.

It is often useful to think of this as a pOinter to the last

element for use with destructive functions such as RplacA.

Note that if

b is

atomic a type mismatch error occurs.
(De LastPair (L)
(Cond «Null (Rest L» L)
(T (LastPair (Rest L»»)
(LastCar L:any): any
Returns the last element of the list

1:.

A type mismatch error results if

not a list. Equivalent to First LastPair

1:

is

1:.

(Nth L:pair N:integer): any
Returns the Nth element of the list

N elements,

1:.

If

1:

is atomic or contains fewer than

an out of range error occurs. Equivalent to (First (PNth L N)).

List Structure
page 5.6

23 September 1983

PSL Manual
section 5.3 .

(PNth L: list N: integer): any
Returns list starting with the Nth element of a list

b. Note that it is often

useful to view this as a pointer to the Nth element of b for use with
destructive functions such as RplacA.

If

b

is atomic or contains fewer than

N elements, an out of range error occurs.
(De PNth (L N)
(Cond «Leq N 1) L)
(T (PNth (Cdr L) (Sub1 N»»)

5.3.2. Membership and Length of Lists
(Member A:any L:list): extra-boolean
Returns NIL if

8. is not Equal to some top level element of list !:; otherwise

it returns the remainder of

!:

whose first element is

8..

(De Member (A L)
(Cond«Null L) Nil)
«Equal A (First L» L)
(T (Member A (Rest L»»)
(MemQ A:any B:list): extra-boolean
Same as Member, but an Eq check is used for comparison.
(De Memq (A L)
(Cond«Null L) Nil)
«Eq A (First L» L)
(T (Memq A (Rest L»»)
(Length X:any): integer
The top level length of the list ~ is returned.
(De Length (X)
(Cond«Atom X) 0)
(T (Plus (Length (Rest X»

1»»

PSL Manual
section 5.3

23 September 1983

List Structure
page 5.7

5.3.3. Constructing, Appending, and Concatenating Lists
(List [U:any]): list
Construct a list of the evaluated arguments. A list of the evaluation of each
element of U is returned.
(Append U: list V: list): list
Returns a constructed list in which the last element of
first element of

':1.

The list

.l1

is copied, but

':1

!:l is followed by the

is not.

(De Append (U V)
(Cond «Null U) V)
(T (Cons (Car U) (Append (Cdr U) V»»)
(NConc U: list V: list): list

expr

Destructive version of Append.
The last Cdr of

.l1

Concatenates

is modified to pOint to

':1

':1.

to

.l1

without copying U.

See the warning on page

5.3 about the use of destructive functions.
(De Nconc (U V)
(Cond «Null U) V)
(T (Rplacd (Lastcdr U V»»)
(AConc U:list V:any): list
Destructively adds element

':1

to the tail of list U.

{LConc PTR:list ELEM:list}: list
Effectively NConc, but avoids scanning from the front to the end of PTR for
the RPLACD(PTR, ELEM) by maintaining a pointer to end of the list PTR.
is (list. LastPair list).

Returns updated PTR.

PTR

PTR should be initialized to

NIL. NIL before calling the first time. Used to build lists from left to right.
(TConc PTR:list ELEM:any): list
Effectively AConc, but avoids scanning from the front to the end of PTR for
the RPLACD(PTR, List(ELEM» by maintaining a pointer to end of the list PTR.
PTR is (list. LastPair list).

Returns updated PTR.

PTR should be initialized

List Structure
page 5.8

23 September 1983

to NIL. NIL before calling the first time.

PSL Manual
section 5.3

Used to build lists from left to

right.

5.3.4. Lists as Sets
A set is a list in which each element occurs only once.

Order of elements does not

matter, so these functions may not preserve order.
(Adjoin ELEMENT:any SET:list): list
Add ELEMENT to SET if it is not already on the top level.

Equal is used to

test for equality.
(AdjoinQ ELEMENT:any SET:list): list
Adjoin using Eq for the test whether ELEMENT is already in SET.
(Union X: list Y: list): list
Set union.
(UnionQ X: list Y: list): list
Eq version of Union.
(InterSection U:list V:list): list
Set intersection.
(InterSectionQ U:list V:list): list
Eq version of InterSection.
(List2Set SET: list): list
Remove redundant elements from the top level of SET using Equal.
(List2SetQ SET: list): list
Remove redundant elements from the top level of SET using Eq.

PSL Manual
section 5.3

23 September 1983

List Structure
page 5.9

5.3.5. Deleting Elements of Lists
Note that functions with names of the form xxxIP indicate that xxx is done InPlace.
(Delete U:any V: list): list
Returns ':!.. with the first top level occurrence of 1:l removed from it.

That

portion of ':!.. before the first occurrence of 1:l is copied.
(De Delete (U V)
(Cond«Null V) Nil)
«Equal (First V) U) (Rest V»
(T (Cons (First V) (Delete U (Rest V»»»
(Del F:funetion U:any V:list): list
Generalized Delete function with

E as

the comparison function.

(DeletIP U:any V: list): list
Destructive Delete; modifies y.. using RplaeD.

expr
Do not depend on V itself

correctly referring to list.
(DelQ U:any V: list): list
Delete1:l from ':!.., using Eq for comparison.
(DelQIP U:any V: list): list
Destructive version of DelQ; see DeletIP.
(DelAse U:any V:a-list): a-list
Remove first (U . xxx) from ':!...
(DelAseIP U:any V:a-list): a-list
Destructive DelAse.
(DelatQ U:any V:a-list): a-list
Delete first (!l . xxx) from ':!.., using Eq to check equality with 1:l.

List Structure
page 5.10

23 September 1983

PSL Manual
section 5.3

(DelatQIP U:any V:a-list): a-list
Destructive DelatQ.

5.3.6. List Reversal
(Reverse U:list): list
Returns a copy of the top level of U in reverse order.
(De Reverse (U)
(Prog (W)
(While U
(ProgN
(Setq W (Cons (Car U) W»
(Setq U (Cdr U»»
(Return W»)
(ReversIP U: list): list
Destructive Reverse.

5.3.7. Functions for Sorting
The Gsort module (LOAD GSORT) provides functions for sorting lists and vectors.
of the functions take a comparison function as an argument.

Some

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 TABLE:list leq-fn: {id,function}): list
Returns a sorted list or vector.

LEQ-FN is the comparison function used to

determine the sorting order.

The original TABLE is unchanged.

a stable sorting algorithm.

In other words, if ~ appears before y... in the

original table then ~ will appear before

Gsort uses

the final table unless ~ and

Y

are out of order. (An unstable sort, on the other hand, might swap ~ and

Y

even if they're in order.

Y in

This could happen when ~ and

Y have

the same

"key field", so either one could come first without making a difference to
the comparison function.)

PSL Manual
section 5.3

23 September 1983

List Structure
page 5.11

(GmergeSort table:list leq-fn: {id,function}): list
The

same

as

Gsort, but destructively modifies the TABLE argument.

GmergeSort has the advantage of being somewhat faster than Gsort.
Note that you should use the value returned by the function--don't depend
on the modified argument to give the right answer.

(IdSort TABLE: list): list
Returns a table of ids sorted into alphabetical order.
unchanged.

The original table is

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.

List Structure
page 5.12

1 lisp>
NIL
2 lisp>
(3 8 -7
3 lisp>
3 lisp>

23 September 1983

PSL Manual
section 5.3

(load gsort)
(setq X '(3 8 -7 2 1
2 1

5»

5)

%Sort from smallest to largest.
(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 II • 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»
5.4. Functions for Building and Searching A-Lists

PSL Manual
section 5.4

23 September 1983

List Structure
page 5.13

(Assoc U:any V:a-list): {pair, NIL}
If !J. occurs as the Car portion of an element of the a-list 'Y..., the pair in
which U occurred is returned, else NIL is returned.

Assoc might not detect

a poorly formed a-list so an invalid construction may be detected by Car or
Cdr.
(De Assoc (U V)
(Cond «Null V) Nil)
«Atom (Car V»
(Error 000 (List V "is a poorly formed alist"»)
«Equal U (Caar V» (Car V»
(T (Assoc U (Cdr V»»)
(Atsoc R1 :any R2:any): any

expr

Scan R2 for pair with Car Eq

Bl.

Eq version of Assoc.

(Ass F:function u:any V:a-list): {pair, NIL}
Ass is a generalized Assoc function.

E is the comparison function.

(SAssoc U:any V:a-list FN:function): any
Searches the a-list 'Y... for an occurrence of!J..

expr
If U is not in the a-list, the

evaluation of function FN is returned.
(De SAssoc (U V FN)
(Cond «Null V) (FN»
«Equal U (Caar V» (Car V»
(T (SAssoc U (Cdr V) FN»»
(Pair U: list V: list): a-list

11.

and 'Y... are lists which must have an identical number of elements.

an error occurs.

If not,

Returned is a list in which each element is a pair, the Car

of the pair being from

11.

and the Cdr being the corresponding element from

'Y....

(De Pair (U V)
(Cond «And U V)(Cons (Cons (Car U)(Car V»
(Pair (Cdr U)(Cdr V»»
«Or U V)(Error 000 "Different length lists in PAIR"»
(T Nil»)

List Structure
page 5.14

23 September 1983

PSL Manual
section 5.5

5.5. Substitutions
(Subst U:any V:any W:any): any

expr

Returns the result of substituting U for all occurrences of ':!.. in W.

Copies

all of W which is not replaced by U. The test used is Equal.
(De Subst (U V W)
(Cond «Null W) Nil)
«Equal V W) U)
«Atom W) W)
(T (Cons (Subst U V (Car W»(Subst

u

V (Cdr W»»»

(SubstIP U:any V:any W:any): any

expr

Destructive Subst.
(SubLis X :a-list Y: any): any

expr

This performs a series of Substs in parallel.

The value returned is the

result of substituting the Cdr of each element of the a-list
occurrence of the Car part of that element in

Eq version of SubLis; replaces atoms only.

for every

y.

(De SubLis (X Y)
(Cond
«Null X) Y)
(T
(Prog (U)
(Setq U (Assoc Y X»
(Return
(Cond
(U (Cdr U»
«Atom Y) Y)
(T (Cons (SubLis X (Car Y»
(SubIA U:a-list V:any): any

~

(SubLis X (Cdr Y»»»»»
expr

PSL MANUAL
SECTION 6.0

23 SEPTEMBER 1983

STRINGS AND VECTORS
PAGE 6.1

CHAPTER 6
STRINGS AND VECTORS
6.1.
6.2.
6.3.
6.4.
6.5.
6.6.
6.7.

Vector-Like Objects.
Strings. . . .
Vectors. . . . . . .
Word Vectors. . . .
General X-Vector Operations.
Arrays . . . . . . . . . . .
Common LISP String Functions.

6.1
6.1
6.3
6.5
6.6
6.7
6.7

6.1. Vector-Like Objects
In this chapter, LISP strings, vectors, word-vectors, halfword-vectors, and byte-vectors
are described.

Each may have several elements, accessed by an integer index.

convenience, members of this set are referred to as x-vectors.
apply to lists.

For

X-vector functions also

Currently, the index for x-vectors ranges from 0 to an upper limit, called

the Size or UpB (upper bound).

Thus an x-vector X has 1 + Size(X} elements.

Strings

index from 0 because they are considered to be packed vectors of bytes. Bytes are 7 bits
on the DEC-20 and 8 bits on the VAX.

[??? Note that with new integer tagging, strings are "packed" words, which are special
cases of vectors.

Should we add byte-vectors too, so that strings are different print

mode of byte vector ???]

[??? Size should probably be replaced by UPLIM or UPB. ???]

6.2. Strings
A string is currently thought of as a Byte vector, or a packed integer vector, with
elements that are ASCII characters.
perhaps a tag.

A string has a header containing its length and

The next M words contain the O... Size characters, packed as appropriate,

terminated with at least 1 NULL.

On the DEC-20, this means that strings have an ASCIZ

string starting in the second word. {ASCIZ strings are NULL terminated.}

Strings and Vectors
page 6.2

23 September 1983

PSL Manual
section 6.2

(MkString UPLIM:integer INITVAL:integer): string
Returns a string of characters all initialized to INITVAL, with upper bound
UPLIM. So, the returned string contains a total of UPLIM + 1 characters.
(string [ARGS: integer]): string
Create string of elements from a list of ARGS.
[??? Should we check each arg in 0 ... 127. What about 128 - 255 with 8
bit vectors? ???]
(String 65 66 67) returns "ABC"
(CopyStringToFrom NEW:string OLD:string): NEW:string
Copy all characters from OLD into NEW. This function is destructive.
(CopyString S:string): string
Copy to new string, allocating heap space.
[??? Should we add GetS, PutS, UpbS, etc ???]
When processing strings it is frequently necessary to be able to specify a particular
character.

In PSL a character is just its ASCII code representation, but it is difficult to

remember the code, and the use of codes does not add to the readability of programs.
(Char U: id): integer

macro

The Char macro returns the ASCII code corresponding to its single character-id
argument. CHAR also can handle alias's for special characters, remove QUOTE marks that
may be needed to pass special characters through the parser, and can accept prefixes to
compute lower case, < Ctrl > characters, and < Meta> characters. For example:
(Char
(Char
(Char
(Char
(Char
(Char

A) returns 65
fa) returns 97
(lower a» returns 97
(control a» returns 1
(meta (control a») returns 129, but
(control (meta a») returns 1

"Control" forces the character code into the range 0-31.

"Meta" turns on the "meta bit".

"Lower" is only well-defined for alphabetic characters.

To get lower-case a one may

precede the a by"!". See also the sharp-sign macros in Chapter 1O.

PSL Manual
section 6.2

23 September 1983

The following

Aliases

are

defined

by PUTing the

Strings and Vectors
page 6.3
association

under the

indicator

'CharConst:
DefList(t«NULL 8'0)
(BELL 811)
(BACKSPACE
(TAB 81/11)
(LF 8/12)

8'10)

(EOL 81112)
(FF 8/14)
(CR 8/15)

(EOF 26)
(ESC 21)
(ESCAPE 21)
(BLANK 32)
(SPACE 32)
(RUB 81/111)
(RUBOUT 811111)

(DEL 811111) .
(DELETE 8#111»,

'CharConst);

Users can add new "modifiers" such as META or CONTROL: just hang the appropriate
function (from integers to integers) off the char-prefix-function property of the modifier.

6.3. Vectors
A vector is a structured entity in which random item elements may be accessed with an
integer index.

A vector has a single dimension.

implementation and available space.

Its maximum size is determined by the

A suggested input/output "vector notation" is

defined (see Chapter 10).

(GetV V: vector INDEX: integer): any
Returns the value stored at position INDEX of the vector ":1. .

expr
The type

, mismatch error may occur. An error occurs if the INDEX does not lie within

O... {UPBV y...) inclusive:

*****

INDEX subscript is out of range

A similar effect may be obtained in RLISP by using ":1...[INDEX];.

· Strings and Vectors
page 6.4

23 September 1983

PSL Manual
section 6.3

(MkVect UPLIM: integer): vector
Defines and allocates space for a vector with UPLIM + 1 elements accessed
as O... UPLIM.

Each element is initialized to NIL.

vector is returned.

An error occurs if UPLIM is

If UPLIM is -1, an empty

< -1 or if there is not

enough space for a vector of this size:
*~'t**~'<

A vector of size UPLIM cannot be allocated

(Make!-Vector UPLIM:integer INITVAL:any): vector
Like MkVect but each element is initialized to INITVAL.

(PutV V:vector INDEX:integer VALUE:any): any
Stores VALUE in the vector

expr

'1. at position INDEX.

type mismatch error may occur.

VALUE is returned.

The

If INDEX does not lie in O... UPBV(~), an

error occurs:
~'t*~b't*

INDEX subscript is out of range

:=VALUE;. It is important to use square brackets, i.e. "[]". ]
(UpbV U:any): {NIL, integer}
Returns the upper limit of

!l

if

!l

is a vector, or NIL if it is not.

(Vector [ARGS :any]): vector
Create vector of elements from list of ARGS.

The vector has N elements,

i.e. Size = N - 1, in which N is the number of ARGS.

(CopyVectorToFrom NEW:vector OLD: vector): NEW:vector
Move elements, don't recurse.
[ ???Check size compatibility? ]

(CopyVector V: vector): vector
Copy to new vector in heap.
The following functions can be used after the FAST!-VECTOR module has been loaded
(LOAD FAST!-VECTOR).

PSL Manual
section 6.3

23 September 1983

(IGetV V:vector INDEX: integer): any

Strings and Vectors
page 6.5
open-compiled, expr

Used the same way as GetV.
(IPutV V:vector INDEX:integer VALUE: any): any

open-compiled, expr

Fast version of PutV.
(ISizeV U:any): {NIL,integer}

open-compiled, expr

Fast version of UpbV.
(ISizeS X: x-vector): integer

open-compiled, expr

Fast version of Size.
(IGetS X: x-vector I: integer): any

open-compiled, expr

Fast version of Indx.
(IPutS X:x-vector I:integer A:any): any

open-compiled, expr

Fast version of Setlndx.

6.4. Word Vectors
Word-vectors or w-vectors are vector-like structures, in which each element is a
"word" sized, untagged entity. This can be thought of as a special case of fixnum vector,
in which the tags have been removed.
(Make!-Words UPLIM:integer INITVAL:integer): Word-Vector
Defines and allocates space for a Word-Vector with UPLIM + 1 elements,
each initialized to INITVAL.
(Make!-Halfwords UPLIM:integer INITVAL:integer): Halfword-Vector
Defines and allocates space for a Halfword-vector with UPLIM + 1 elements,
each initialized to INITVAL.

Strings and Vectors
page 6.6

23 September 1983

PSL Manual
section 6.4

(Make!-Bytes UPLIM:integer INITVAL:integer): Byte-vector
Defines and allocates space for a Byte-Vector with UPLIM + 1 elements,
each initialized to INITVAL.

[??? Should we convert elements to true integers when accessing ???]
[??? Should we add GetW, PutW, UpbW, etc ???]

6.5. General X-Vector Operations
(Size X: x-vector): integer
Size (upper bound) of x-vector.
(Indx X: x-vector I: integer): any
Access the I'th element of an x-vector.

[??? Rename to Getlndex, or some such ???]
Generates a range error if
**~':~':*

! is outside the range 0 ...

Size(~}:

Index is out of range

(Setlndx X:x-vector I:integer A:any): any
Store an appropriate value, ~, as the I'th element of an x-vector.
a range error if

Generates

! is outside the range O... Size(~):

***** Index is out of range
(Sub X:x-vector 11:integer S:integer): x-vector
Extract a subrange of an x-vector, starting at U, producing a new x-vector
of Size.§.. Note that an x-vector of Size 0 has one entry.
(SetSub X:x-vector 11:integer S:integer Y:x-vector): x-vector
Store subrange of

y of size.§. into

~

starting at U. Returns

y.

(SubSeq X:x-vector LO:integer HI:integer): x-vector
Returns an x-vector of Size HI-LO-l, beginning with the element of ~ with
index LO.

In other words, returns the subsequence of ~ starting at LO and

ending just before HI. For example,

PSL Manual
section 6.5

23 September 1983

(Setq A '[0 1 2
(SubSeq A 4 6)

Strings and Vectors
page 6.7

345 6])

returns [4 5].

(SetSubSeq X:x-vector LO:integer HI:integer Y:x-vector): Y:x-vector

'f... must be of Size HI-LO-1; it must also be of the same type of x-vector
as~.

Elements LO through HI-1 in ~ are replaced by elements 0 through

SizeCO of

'1. '1

is returned and ~ is changed destructively.

If A is

"0123456" and B is "abcd", then
(SetSubSeq

A3 7

B)

returns "abcd". A is "012abcd" and B is unchanged.

(Concat X: x-vector Y: x-vector): x-vector
Concatenate two x-vectors.

Currently they must be of same type.

[??? Should we do conversion to common type ???]
(TotalCopy S:any): any
Returns a unique copy of entire structure, i.e., it copies everything for which
storage is allocated - everything but inums and ids.

Like Copy (Chapter 5)

TotalCopy will not terminate when applied to circular structures.

6.6. Arrays
Arrays do not exist in PSL as distinct data-types; rather an array macro package is
anticipated for declaring and managing multi-dimensional arrays of items, characters and
words, by mapping them onto one dimensional vectors.

[??? What operations, how to map, and what sort of checking ???]

6.7. Common LISP String Functions
A Common

LISP compatible

package of string

and

character functions

implemented in PSL, obtained by LOADing the STRINGS module.

has

been

The following functions

are defined from Chapters 13 and 14 of the Common LISP manual [Steele 81].
String are not defined because of PSL functions with the same name.

Char and

Strings and Vectors
page 6.8

23 September 1983

PSL Manual
section 6.7

Common LISP provides a character data type in which every character object has three
attributes: code, bits, and font. The bits attribute allows extra flags to be associated with
a character.
italics).

The font attribute permits a specification of the style of the glyphs (such as

PSl does not- support nonzero bit and font attributes.

Because of this some of

the Common LISP character functions described below have no affect or are not very
useful as implemented in PSL. They are present for compatibility.

Recall that in PSL a character is represented as its code, a number in the range 0... 127.
For an argument to the following character functions give the code or use the Char
function or the sharp-sign macros in Chapter 10.
(Standard! -CharP C: character): boolean
Returns T if the argument is a "standard character", that is, one of the
ninety-five ASCII printing characters or < return >.
(Standard-CharP (Char
(Standard-CharP (Char

A» returns T
!AA» returns

Nil

(GraphicP C: character): boolean
Returns T if ~ is a printable character and Nil if it is a non-printable
(formatting or control) character.

The space character is assumed to be

graphic.
(String! -CharP C: character): boolean
Returns T if ~ is a character that can be an element of a string.

expr
Any

character that satisfies Standard-Charp and Graphicp also satisfies StringCharp.
(AlphaP C: character): boolean
Returns T if

~

is an alphabetic character.

(UpperCaseP C:character): boolean
Returns T if

~

is an upper case letter.

PSL Manual
section 6.7

23 September 1983

Strings and Vectors
page 6.9

(LowerCaseP C: character): boolean
Returns T if

~

is a lower case letter.

(BothCaseP C:character): boolean
In PSL this function is the same as AlphaP.
(Digi tP C: character): boolean
Returns T if ~ is a digit character (optional radix not supported).
(AlphaNumericP C: character): boolean
Returns T if

~

is a digit or an alphabetic.

(Char! = C1 : character

C2: character): boolean

Returns T if Cl and C2 are the same in all three attributes.
(Char!-Equal C1:character

C2:character): boolean

Returns T if Cl and C2 are similar.

Differences in case, bits, or font are

ignored by this function.
(Char!< C1 : character

C2:character): boolean

Returns T if C 1 is strictly less than C2.
(Char!> C1:character

C2:character): boolean

~

is strictly greater than C2.

Returns T if

(Char!-LessP C1:character

C2:character): boolean

Like Char! < but ignores differences in case, fonts, and bits.
(Char!-GreaterP C1:character

C2:character): boolean

Like Char! > but ignores differences in case, fonts, and bits.

Strings and Vectors
page 6.10

23 September 1983

PSL Manual
section 6.7

(Char!-Code C:character): character
Returns the code attribute

of~.

In PSL this function is an identity function.

(Char! -Bi ts C:"character): integer
Returns the bits attribute of

~,

which is always 0 in PSL.

(Char! -Font C: character): integer
Returns the font attribute of

~,

which is always 0 in PSL.

(Code! -Char I: integer): f character, nil}
The purpose of this function is to be able to construct a character by
specifying the code, bits, and font.

Because bits and font attributes are not

used in PSL, Code! -Char is an identity function.
(Character C:fcharacter, string, id}): character
Attempts to coerce
If

~

~

to be a character.

If

~

is a character,

~

is returned.

is a string, then the first character of the string is returned.

symbol, the first character of the symbol is returned.

If

~

is a

Otherwise an error

occurs.
(Char!-UpCase C:character): character
If

LowerCaseP(~)

case

of~.

is true, then Char-UpCase returns the code of the upper

Otherwise it returns the code of

~.

(Char!-DownCase C:character): character
If

UpperCaseP(~)

case

of~.

is true, then Char-DownCase returns the code of the lower

Otherwise it returns the code of

~.

(Digit!-Char C:character): integer
Converts character to its code if
than one digit, Nil is returned.
caused.

expr
~

If

is a one-digit number.
~

If

~

is larger

is not numeric, an error message is

PSL Manual
section 6.7

23 September 1983

Strings and Vectors
page 6.11

(Char!-lnt C:character): integer
Converts character to integer. This is the identity operation in PSL.

(lnt! -Char l: integer): character
Converts integer to character. This is the identity operation in PSL.
The string functions follow.

(RplaChar S:string

l:integer

C:character): character

Store a character .Q. in a string

(String!: S1:string

~

at position

1.

S2:string): boolean

Compares two strings

~

and S2, case sensitive.

(Substring options not

implemented).

(String!-Equal S1 :string
Compare two strings

S2:string): boolean
~

and S2, ignoring case, bits and font.

The following string comparison functions are extra-boolean.

If the comparison results

in a value of T, the first position of inequality in the strings is returned.

(String!< S1:string

S2:string): extra-boolean

Lexicographic comparison of strings. Case sensitive.

(String!> S1 :string

S2:string): extra-boolean

Lexicographic comparison of strings. Case sensitive.

(String!!: S1 :string

S2:string): extra-boolean

Lexicographic comparison of strings. Case sensitive.

Strings and Vectors
page 6.12

23 September 1983

(string! Sl:string

PSL Manual
section 6.7

S2:string): extra-boolean

Lexicographic comparison of strings. Case sensitive.
(String! -LessP S1 :string

S2 :string):extra-boolean

Lexicographic comparison of strings. Case differences are ignored.
(String!-GreaterP Sl:string

S2:string): extra-boolean

Lexicographic comparison of strings. Case differences are ignored.
(String!-Not!-GreaterP Sl:string

S2:string): extra-boolean

Lexicographic comparison of strings. Case differences are ignored.
(String!-Not!-LessP S1:string

S2:string): extra-boolean

Lexicographic comparison of strings. Case differences are ignored.
(String!-Not!-Equal S1:string

S2:string): extra-boolean

Lexicographic comparison of strings. Case differences are ignored.
(String! -Repeat S: string
Appends copy of

~

I: integer): string

to itself total of !-1 times.

(Make! -S tr ing I: in teger C: charac ter): s tr ing
Constructs a string with! characters all initialized to ~.
(String!-Trim BAG:{list, string}

S:string): string

Remove leading and trailing characters in BAG from a string ~.
(String-Trim "ABC" "AABAXYZCB") returns "XYZ"
(String-Trim (List (Char A) (Char B) (Char C»
"AABAXYZCB")
returns "XYZ"
(String-Trim '(65

66 67)

"ABCBAVXZCCff) returns "VXZ"

PSL Manual
section 6.7

23 September 1983

(String!-Left!-Trim BAG:{list, string}

Strings and Vectors
page 6.13

S:string): string

Remove leading characters from string.
(String!-Right!-Trim BAG: {list, string}

S:string): string

Remove trailing characters from string.
(String!-UpCase S:string): string
Copy and raise all alphabetic characters in string.
(NString!-UpCase S:string): string
Destructively raise all alphabetic characters in string.
(String!-DownCase S:string): string
Copy and lower all alphabetic characters in string.
(NString!-DownCase S:string): string
Destructively lower all alphabetic characters in string.
(String!-Capitalize S:string): string
Copy and raise first letter of all words in string; other letters in lower case.
(NString!-Capitalize S:string): string
Destructively raise first letter of all words; other letters in lower case.
(String!-to!-List S:string): list
Unpack string characters into a. list.
(String!-to!-Vector S:string): vector
Unpack string characters into a vector.
(SubString S:string

LO:integer

HI: integer):

string

Same as SubSeq, but the first argument must be a string.
substring of
LO.

~

Returns a

of Size HI - LO - 1, beginning with the element with index

Strings and Vectors
page 6.14

23 September 1983

(String!-Length S:string): integer
Last index of a string, plus one.

PSL Manual
section 6.7

FLOW OF CONTROL
PAGE 7.1

23 SEPTEMBER 1983

PSL MANUAL
SECTION 7.0

CHAPTER 7
FLOW OF CONTROL
7.1
7.1
7.3

7.1. Conditionals . . . . . . . . . . .
7.1.1. Conds and Ifs . . . . . . . .
7.1.2. Case and Selectq Statements
7.2. Sequencing Evaluation.
7.3. Iteration . . . . . . . .
7.3.1. For . . . . . . . .
7.3.2. Mapping Functions
7.3.3. Do . . . .
7.4. Non-Local Exits. . . . .

7.4
7.6
7.7
7.12
7.14
7.16

7.1. Conditionals
7.1.1. Conds and Ifs
open-compiled, fexpr

(Cond [U: form-list]): any
The

LISP

function

Cond

corresponds

to

the

If

statement

of

most

programming languages.

The arguments to Cond have the form:
(COND (predicate action action
(predicate action action

·.. )
·.. )

(predicate action action

·.. )

The predicates are evaluated in the order of their appearance until a
non-NIL value is encountered.

The corresponding actions are evaluated

and the value of the last becomes the value of the Condo

If there are no

corresponding actions, the value of the predicate is returned.

The actions may also contain the special functions Go, Return, Exi t, and
Next, subject to the constraints on placement of these functions given in
Section 7.2.

In these cases, Cond does not have a defined value, but rather

an effect. If no predicate is non-NIL, the value of Cond is NIL.
The following Macros are defined in the USEFUL module for convenience.

Flow Of Control
page 7.2

23 September 1983

PSL Manual
section 7.1

(If E:form SO:form [S:form]): any

macro

If is a macro to simplify the writing of a common form of Cond in which
there are only two clauses and the antecedent of the second is T.
(IF E SO S1 ••• Sn)
The then-clause SO is evaluated if and only if the test g is non-NIL,
otherwise the else-clauses

~i

are evaluated, and the last returned. The else

clauses are optionally present.
Related macros for common COND forms are WHEN and UNLESS.
(When E: form [S: form]): any

macro

(WHEN E S1 S2 ••• Sn)
evaluates the Si and returns -the value of Sn if and only if the test g is nonNIL. Otherwise When returns NIL.

(Unless E: form [U: form]): any

macro

(UNLESS E S1 S2 ••• Sn)
Evaluates the Si if and only if the test g is NIL. It is equivalent to
(WHEN (NOT E) S1 S2 ••• Sn)
While And and Or are primarily of interest as Boolean connectives, they are often used
in LISP as conditionals. For example,
(AND (FOO) (BAR) (BAZ»
has the same result as
(COND «FOO) (COND «BAR) (BAZ»»)
See Section 2.2.3.

PSL Manual
section 7.1

23 September 1983

Flow Of Control
page 7.3

7.1.2. Case and Selectq Statements
PSL provides a numeric case statement, that is compiled quite efficiently; some effort is
made to examine special cases (compact vs. non-compact sets of cases, short vs. long
sets· of cases, etc.). It has: mostly been used inSYSLISP mode, but can also be used from
LISP mode provided that case-tags are numeric.

There is also an FEXPR, Case, for the

interpreter.

(Case I: form [U: case-clause]): any

open-compiled, fexpr

! is meant to evaluate to an integer, and is used as a selector amongst the
various !Js. Each case-clause has the form (case-expr form) where caseexpr has the form:
NIL
-> default case
(11 12
In)
-> where each Ik is an integer or
(RANGE low high)

For example:
(CASE i

«1) (Print "First"»
«2 3) (Print "Second"»
«(Range 4 10» (Print "Third"»
(NIL (Print "Fourth"»)

(Selectq I : form [U:selectq-clause]): any

macro

This function selects an action based on the value of the form !, the "key".
Each selectq-clause has the form (key-part action action ... ).
is a list of keys, or T, or OTHERWISE.

Each key-part

If there is only one key in a key-part

it may be written in place of a list containing it, provided that the key is not
a list, NIL, T, or OTHERWISE, which would be ambiguous.

After! is evaluated, it is compared against the members of each of the keypart lists in turn.

If the key is Eq to any member of a key list, then each of

the forms in that selectq-clause are evaluated, and the value of the last
form of the list is the value of the Selectq.

If a selectq-clause with key-

part T or OTHERWISE is reached, its forms are evaluated without further
testing.

Clearly a T or OTHERWISE clause should be the last of the clauses.

If no clause is satisfied Selectq returns NIL.

Flow Of Control
page 7.4

23 September 1983

PSL Manual
section 7.1

For example:
(SELECTQ (CAR W)
«NIL) NIL)
(END (PRINT 'DONE) 'END)
«0 1 2 3 4 5 6 7 8 9) 'DIGIT)
(OTHERWISE 'OTHER»

[??? Perhaps we should move SELECTQ (and define a SELECT) from the COMMON
module to the basic system ???]

7.2. Sequencing Evaluation
These functions provide for explicit control sequencing, and the definition of blocks
altering the scope of local variables.
(ProgN [U: form]): any

open-compiled, fexpr

!J is a set of expressions which are executed sequentially.

The value

returned is the value of the last expression.
(Prog2 A: form B: form): any
Returns the value of

open-compiled, expr

1!

(the second argument).

[??? Redefine prog2 to take N arguments, return second. ???]
(Prog1 [U:form]): any

macro

Prog 1 is a function defined in the USEFUL package.

Prog 1 evaluates its

arguments in order, as ProgN does, but returns the value of the first.
(Prog VARS:id-list [PROGRAM: [id,form}]): any

open-compiled, fexpr

VARS is a list of ids which are considered FLUID if the Prog is interpreted
and LOCAL if compiled (see the "Variables and Bindings" Section, 8.3).

The

Prog's variables are allocated space if the Prog form is applied, and are
deallocated if the Prog is exited.

Prog variables are initialized to NIL.

PROGRAM is a set of expressions to be evaluated
appearance in the Prog function.

The

in order of their

identifiers appearing in the top level of

the PROGRAM are labels which can be referred to by Go.

The value

Flow Of Control
page 7.5

23 September 1983

PSL Manual
section 7.2

returned by the Prog function is determined by a Return function or NIL if
the Prog "falls through".
There are restrictions as to where a number of control functions, such as Go and
Return, may be placed.

This is so that they may have only locally determinable effects.

Unlike most LISPs, which make this restriction only in· compiled code, PSL enforces this
restriction uniformly in both compiled and interpreted code.

Not only does this help keep

the semantics of compiled and interpreted code the same, but we believe it leads to more
readable programs.

For cases in which a non-local exit is truly required, there are the

functions Catch and Throw, described in Section 7.4.

The functions so restricted are Go, Return, Exit, and Next.

They must be placed at

top-level within the surrounding control structure to which they refer (e.g., the Prog
which Return causes to be terminated), or nested within only selected functions.

The

functions in which they may be nested (to arbitrary depth) are:
* ProgN (compound statement)
* actions of Conds (if then else)
* actions in Cases
(Go LABEL: id): None Returned

open-compiled, fexpr

Go alters the normal flow of control within a Prog function.

The next

statement of a Prog function to be evaluated is immediately preceded by
LABEL. A Go may appear only in the following situations:
a. At the top level of a Prog referring to a LABEL that also appears at the
top level of the same Prog.
b. As the action of a Cond item
i. appearing on the top level of a Prog.
ii. which appears as the action of a Cond item to any level.
c. As the last statement of a ProgN
i. which appears at the top level of a Prog or in a ProgN appearing
in the action of a Cond to any level subject to the restrictions of
b.i, or b.ii.
ii. within a ProgN or as the action of a Cond in a ProgN to any level
subject to the restrictions of b.i, b.ii, and c.i.

If LABEL does not appear at the top level of the Prog in which the Go

23 September 1983

Flow Of Control
page 7.6

PSL Manual
section 7.2

appears, an error occurs:

***** LABEL is not a label within the current scope
If the Go has been placed in a position not defined by rules a-c, another
error is detected:

***** Illegal use of GO To LABEL
open-compiled, expr

(Return U: form): None Returned

Within a Prog, Return terminates the evaluation of a Prog and returns
the value of the Prog.

11.

as

The restrictions on the placement of Return are

exactly those of Go. Improper placement of Return results in the error:

***** Illegal use of RETURN

7.3. Iteration
(While E: form [S: form]): NIL

macro

This is the most commonly used construct for indefinite iteration in LISP.
is evaluated; if non-NIL, the
the process is repeated.

If

~'s

~

are evaluated from left to right and then

g evaluates to NIL the While returns NIL. Exit

may be used to terminate the While from within the body and to return a
value. Next may be used to terminate the current iteration.
(Repeat [S: form E:form]): NIL
The

~'s

macro

are evaluated left to right, and then

until the value of

g is evaluated. This is repeated

g is non-NIL, at which point Repeat returns NIL. Next

and Exit may be used in the

~'s

branch to the next iteration of a Repeat or

to terminate one and possibly return a value. Go, and Return may appear in
the

~'s.

(Next ): None Returned

open-compiled, restricted, macro

This terminates the current iteration of the most closely surrounding While
or Repeat, and causes the next to commence.

See the note in Section

7.2 about the lexical restrictions on placement of this construct, which is
essentially a GO to a special label placed at the front of a loop construct.

PSL Manual
section 7.3

23 September 1983

(Exit [U:form]): None Returned

Flow Of Control
page 7.7
open-compiled,restricted, macro

The U's are evaluated left to right, the most closely surrounding While or
Repeat is terminated, and the value of the last U is returned.
arguments, NIL is returned.

With no

See the note in Section 7.2 about the lexical

restrictions on placement of this construct, which is essentially a Return.
While and Repeat each macro expand into a Prog; Next and Exi t are macro expanded
into a Go and a Return respectively to this Prog.

Thus using a Next or an Exit within a

Prog within a While or Repeat will result only in an exit of the internal Prog.

7.3.1. For
A simple For construct is available in the basic PSL system; an extended form can be
obtained by loading USEFUL. It is planned to make the extended form the version
available in the basic system, combining all the features of FOR and For Each. The basic
PSL For provides only the (FROM .. ) iterator, and (DO ... ) action clause, and uses the
ForEach construct for some of the (IN ... ) and (ON ... ) iterators. Most users should use the
full For construct.
(For [S: form]): any

macro

The arguments to For are clauses; each clause is itself a list of a keyword
and one or more arguments.

The clauses may introduce local variables,

specify return values and when the iteration should cease, have sideeffects, and so on.

Before going further, it is probably best to give some

examples.
(FOR (FROM I 1 10 2) (DO (PRINT I»)
Prints the numbers 1 3 5 7 9
(FOR (IN

U '(A B C» (DO (PRINT U»)
Prints the letters ABC

(FOR (ON U '(A B C»
(DO (PRINT U»)
Prints .the lists (A B C) (B C) and (C)
Finally, the function
(DE ZIP (X Y)
(FOR (IN U X) (IN V Y)
(COLLECT (LIST U V»»

Flow Of Control
page 7.8

23 September 1983

PSL Manual
section 7.3

produces a list of 2 element lists, each consisting of the the corresponding
elements of the three lists X, Y and Z. For example,

(ZIP '( 1 2 3 4) '(A B C) )
produces

«1 a)(2 b)(3 c»
The iteration terminates as soon as one of the (IN .. ) clauses is exhausted.

Note that the (IN ... ), (ON ... ) and (FROM ... ) clauses introduce local variables
U, V or I, that are referred to in the action clause.

All the possible clauses are described below.
iteration variables.

The first few introduce

Most of these also give some means of indicating when

iteration should cease.

For example, if a list being mapped over by an In

clause is exhausted, iteration must cease.

If several such clauses are given

in a For expression, iteration ceases when one of the clauses indicates it
should, whether or not the other clauses indicate that it should cease.
(IN Vl V2)

assigns the variable V1 successive elements of the list V2.
This may take an additional, optional argument: a function to be
applied to the extracted element or sublist before it is assigned
to the variable. The following returns the sum of the lengths of
all the elements of L.

[??? Rather a kludge -- not sure why this is here.
it should come out again. ???]

(DE LENGTHS· (L)
(FOR (IN N L LENGTH)
(COLLECT (LIST N N»)
is the same as

(DE LENGTHS (L)
(FOR (IN N L)
(COLLECT
(LIST (LENGTH N) (LENGTH N»»
)

Perhaps

PSL Manual
section 7.3

23 September 1983

but only calls LENGTH once. Using the
introduce a local LN may be clearer.

Flow Of Control
page 7.9
(WITH

.. ) form

to

For example,
(SUMLENGTHS
'«1 2 3 4 5)(a b c)(x y»)
is

«5 5) (3 3) (2 2»
(ON V1 V2) assigns the variable V1 successive Cdrs of the list V2.
(FROM VAR INIT FINAL STEP)
is a numeric iteration clause. The variable is first assigned INIT,
and then incremented by step until it is larger than FINAL. INIT,
FINAL, and STEP are optional. INIT and STEP both default to 1,
and if FINAL is omitted the iteration continues until stopped by
some other means.
To specify a STEP with INIT or FINAL
omitted, or a FINAL with INIT omitted, place NIL (the constant
-- it cannot be an expression) in the appropriate slot to be
omitted. FINAL and STEP are only evaluated once.
(FOR VAR INIT NEXT)
assigns the variable INIT first, and subsequently the value of the
expression NEXT. INIT and NEXT may be omitted. Note that this
is identical to the behavior of iterators in a Do.
(WITH V1 V2 ... Vn)
introduces N locals, initialized to NIL. In addition, each Vi may
also be of the form (VAR INIT), in which case it is initialized to
INIT.
(DO S1 S2 ... Sn)
causes the Si's to be evaluated at each iteration.

There are two clauses which allow arbitrary code to be executed before the
first iteration, and after the last.
(INITIALLY S 1 S2 ... Sn)
causes the Si's to be evaluated in the new environment (Le. with
the iteration variables bound to their initial values) before the
first iteration.
(FINALLY S 1 S2 ... Sn)
causes the Si's to be evaluated just before the function returns.

Flow Of Control
page 7.10
The

next

PSL Manual
section 7.3

23 September 1983.

few

clauses

build

up

return

types.

Except

for

the

RETURNS/RETURNING clause, they may each take an additional argument
which

specifies

that

instead

of returning

accumulated in the specified variable.

the

appropriate

value,

it is

For example, an unzipper might be

defined as

(DE UNZIP (L)
(FOR (IN U L) (WITH X Y)
(COLLECT (FIRST U) X)
(COLLECT (SECOND U) Y)
(RETURNS (LIST X Y»»
This is essentially the opposite of Zip.

Given a list of 2 element lists, it

unzips them into 2 lists, and returns a list of those 2 lists.

For example,

(unzip '((1 a)(2 b)(3 c})) returns is ((1 2 3)(a be)).
(RETURNS EXP)
causes the given expression to be the value of the For.
Returning is synonymous with returns.
It may be given
additional arguments, in which case they are evaluated in order
and the value of the last is returned (implicit ProgN).
(COLLECT EXP)
causes the successive values of the expression to be collected
into a list. Each value is Appended to the end of the list.
(ADJOIN EXP), (ADJOINQ EXP)
are similar to COLLECT, but a value is added to the result only if
it is not already in the list. ADJOIN tests with EQUAL, ADJOINQ
tests with EQ.
(CONC EXP)
causes the successive values to be NConc'd together.
(JOIN EXP) causes them to be appended.
(UNION EXP), (UNIONQ EXP)
are similar to JOIN, but only add an element to the list if it is
not already there. UNION tests with EQUAL, UNIONQ tests with

EO.
(INTERSECTION EXP), (INTERSECTIONQ EXP)
compute the set of elements that are in all the sets iterated
over. With INTERSECTION, elements are the same if EQUAL,

PSL Manual
section 7.3

23 September 1983

Flow Of Control
page 7.11

with INTERSECTIONQ they are the same if EQ.
(COUNT EXP)
returns the number of times EXP was non-NIL.
(SUM EXP), (PRODUCT EX?), (MAXIMIZE EXP), and (MINIMIZE EXP)
Synonyms are summing, maximizing, and
do the obvious.
minimizing.
(MAXIMAL EXPl EXP2), (MINIMAL EXPl EXP2)
are more general than maximize and minimize.
MAXIMAL
determines the greatest value for EXP2 over the iteration,
returning the value of EXPl rather than the value of EXP2. As a
particular case it is possible to return the value of an iteration
variable for which some function attains a maximum (or
minimum) value, e.g. (MAXIMAL x (f x)). As with other kinds of
clauses, the user may "accumulate" the value of EXPl into a
variable by supplying a third expression which is the name of a
variable.
(ALWAYS EXP)
returns T if EXP is non-NIL on each iteration. If EXP is ever NIL,
the loop terminates immediately, no epilogue code, such as that
introduced by finally is run, and NIL is returned.
(NEVER EXP)
is equivalent to (ALWAYS (NOT EXP)).
(WHILE EXP) and (UNTIL EXP)
Explicit tests for the end of the loop may be given using
(WHILE EXP). The loop terminates if EXP becomes NIL at the
beginning of an iteration.
(UNTIL EXP) is equivalent to
(WHILE (NOT EXP)).
Both While and Until may be given
additional arguments; (WHILE E1 E2 .,. En) is equivalent to
(WHILE (AND El E2 ... En)) and (UNTIL El E2 ... En) is equivalent
to (UNTIL (OR E1 E2 ... En)).
(WHEN EXP)
causes a jump to the next iteration if EXP is NIL.
(UNLESS EXP)
is equivalent to (WHEN (NOT EXP)).
For is a general iteration construct similar in many ways to the LISP Machine and
MACLISP Loop construct, and the earlier Interlisp CLISP iteration construct. For, however,
is considerably simpler, far more "Iispy", and somewhat less powerful.

Flow Of Control
page 7.12

23 September 1983

PSL Manual
section 7.3

All variable binding/updating still precedes any tests or other code.

Also note that all

When or Unless clauses apply to all. action clauses, not just subsequent ones.

This fixed

order of evaluation makes For less powerful than Loop, but also keeps it considerably
simpler. The basic o.rder of evaluation is
a. bind variables to initial values (computed in the outer environment)
b. execute prologue (Le., Initially clauses)
c. while none of the termination conditions are satisfied:
i. check conditionalization clauses (When and Unless),
iteration if all are not satisfied.

and

start next

ii. perform body, collecting into variables as necessary
iii. next iteration
d. (after a termination condition is satisfied) execute the epilogue (Le., Finally
clauses)
For does all variable binding/updating in parallel.

There is a similar macro, For*, which

does it sequentially.
(For! * [S: form]): any

macro

7.3.2. Mapping Functions
The mapping functions long familiar to LISP programmers are present in PSl.

However,

we believe that the For construct described above or the simpler ForEach described
below is generally more useful, since it obviates the usual necessity of constructing a
lambda expression, and is often more transparent. Mapping functions with more than two
arguments are not currently supported.

Note however that several lists may be iterated

along with For, and with considerably more generality. For example:
(Prog (I)
(Setq I 0)
(Return
(Mapcar L
(Function (Lambda (X)
(Progn
(Setq I (Plus I 1»
(Cons I X»»»)

PSL Manual
section 7:3

23 September 1983

Flow Of Control
page 7.13

may be expressed more transparently as
(For (IN X L) (FROM I 1) (COLLECT (CONS I X»)
To-augment the simpler For loop present in basic PSL, the following list iterator has
been provided:
(For Each U:any): any

macro

This macro is essentially equivalent to the the map functions as follows:
Possible forms are:
Setting X to successive elements (CARs) of U:
(FOREACH X IN U DO (FOO X»
--> (MAPC U 'FOO)
(FOREACH X IN U COLLECT (FOO X»--> (MAPCAR U 'FOO)
(FOREACH X IN U CONC (FOO X»
--> (MAPCAN U 'FOO)
(FOREACH X IN U JOIN (FOO X»
--> (MAPCAN U 'FOO)
Setting X to successive CDRs of U:
(FOREACH X ON U DO (FOO X»
--> (MAP U 'Faa)
(FOREACH X ON U COLLECT (FOO X»--> (MAPLIST U 'FOO)
(FOREACH X ON U CONC (FOO X»
--> (MAPCON U 'FOO)
(FOREACH X ON U JOIN (FOO X»
--> (MAPCON U 'FOO)
(Map X:list FN:function): NIL'

expr

Applies FN to successive Cdr segments

of~.

NIL is returned.

This is

equivalent to:
(FOREACH u ON x DO (FN

u»

(MapC X:list FN:function): NIL
FN is applied to successive Car segments of

list~.

NIL is returned. This is

equivalent to:
(FOREACH u IN x DO (FN

u»

(Mapcan X:list FN:function): list
A concatenated list of FN applied to successive Car elements of X is
returned. This is equivalent to:
(FOREACH u IN x CONe (FN

u»

Floyv Of Control
page 7.14

23 September 1983

PSL Manual
section 7.3

(MapCar X: list FN: function): list
Returned is a constructed list, the elements of which are FN applied to each
Car of list~. This is equivalent to:
(FOREACH u IN x COLLECT (FN u»
(MapCon X:list FN:function): list
Returned is a concatenated list of FN applied to successive Cdr segments
of~.

This is equivalent to:

(FOREACH u ON x CONC (FN

u»

(MapList X: list FN: function): list
Returns

a constructed

successive Cdr segments

list, the elements of which are FN applied to
of~.

This is equivalent to:

(FOREACH u ON x COLLECT (FN u»

7.3.3. Do
The MACLISP style Do and Let are now partially implemented in the USEFUL module.
(Do A:list B:list [S:form]): any
The Do macro is a general iteration construct similar to that of LlSPM and
However, it does differ in some details; in particular it is not

friends.

compatible with the "old style Do" of MACLlSP, nor does it support the "no
end test means once only" convention. Do has the form

(DO (11 12 ••• In)
(TEST R1 R2 ••• Rk)
S1

S2
Sm)
in which there may be zero or more I's, R's, and S's. In general the I's have
the form
(var init step)

macro

PSL Manual
section 7.3

Flow Of Control
page 7.15

23 September 1983

On entry to the Do form, all the inits are evaluated, then the variables are
bound to their respective inits.

The test is evaluated, and if non-NIL the

form evaluates the R's and returns the value of the last one.
- --supplied it returns NIL.

If none are

If the test evaluates to NIL the S's are evaluated,

the variables are assigned the values of their respective steps in parallel,
and the test evaluated again. This iteration continues until test evaluates to
a non-NIL value.

Note that the inits are evaluated in the surrounding

environment, while the steps are evaluated in the new environment.

The

body of the Do (the S's) is a Prog, and may contain labels and Go's, though
use of this is discouraged.

This may be changed at a later date.

Return

used within a Do returns immediately without evaluating the test or exit
forms (R's).

There are alternative forms for the I's:
value is left unchanged.

If the step is omitted, the variable's

If both the irit and step are omitted or if the I is

an id, it is initialized to NIL and left unchanged.

This is particularly useful

for introducing dummy variables which are SetQ'd inside the body.
(Do!* A:list B:list [C:forml): any
Do!

*

macro

is like Do, except the variable bindings and updatings are done

sequentially instead of in parallel.
(Do-Loop A:list B:list C:list [S:form]): any

macro

Do-Loop is like Do, except that it takes an additional argument, a prologue.
The general form is
(DO-LOOP (11 12

In)

(P1 P2 ••• Pj)
(TEST R1 R2 ••• Rk)
S1

S2
Sm)
This is executed just like the corresponding Do, except that after the
bindings are established and initial values assigned, but before the test is
first executed the P's are evaluated, in order.

Note that the P's are all

Flow Of Control
page 7.16

23 September 1983

PSL Manual
section 7.3

evaluated exactly once (assuming that none of the P's errs out, or otherwise
throws to a surrounding context).
(Do-Loop!* A:list. B:list C:list [S:formJ): any

macro

Do-Loop! * does the variable bindings and updates sequentially instead of in
parallel.
(Let A:list [B:form]): any
Let

is

a macro

macro

giving

a more

perspicuous form

for writing

lambda

expressions. The basic form is

(LET (V1 11) (V2 12) ... (Vn In)) S 1 S2... Sn)

The /'s are evaluated (in an unspecified order), and then the V's are bound
to these values, the S's evaluated, and the value of the last is returned.
Note that the /'s are evaluated in the outer environment before the V's are
bound.
Note: the id LET conflicts with a similar construct in RLISP and REDUCE
. (Let!* A:list [B:form]): any
Let!

*

macro

is just like Let except that it makes the assignments sequentially.

That is, the first binding is made before the value for the second one is
computed.

7.4. Non-Local Exits
One occasionally wishes to discontinue a computation in which the lexical restrictions
on placement of Return are too restrictive.
Throw exist for these cases.

The non-local exit constructs Catch and

They should not, however, be used indiscriminately.

The

lexical restrictions on their more local counterparts ensure that the flow of control can be
ascertained by looking at a single piece of code.

With Catch and Throw, control may be

passed to and from totally unrelated pieces of code.

Under some conditions, these

functions are invaluable. Under others, they can wreak havoc.

PSL Manual
section 7.4

23 September 1983

(Catch TAG:id [FORM: form]): any

Flow Of Control
page 7.17
Open-Compiled, fexpr

Catch evaluates the TAG and then calls Eval on the FORMs in a protected
environment.

If during this evaluation (Throw TAG VAL) occurs, Catch

immediately returns VAL.
returned.

If no Throw occurs, the value of the last FORM is

Note that in general only Throws with the same TAG are caught.

Throws whose TAG is not Eq to that of Catch are passed on out to
surrounding Catches. A TAG of NIL, however, is special. (Catch NIL FORM)
catches any Throw.

The tag of NIL serves to match any tag specified to

Throw.

ThrowSignal! * [Initially: NIL]

ThrowTag! * [Initially: NIL]

global

The FLUID variables ThrowSignal!* and ThrowTag! * may be interrogated to
find out if the most recently evaluated Catch was Thrown to, and what tag
was passed to the Throw.

ThrowSignal! * is Set to NIL upon normal exit

from a Catch, and to T upon normal exit from Throw.
the first argument passed to the Throw.

ThrowTag! * is Set to

(Mark a place to Throw to, Eval

FORM.)
(Throw TAG: id

VAL:any): None Returned

This passes control to the closest surrounding Catch with an Eq or null
TAG.

If there is no such surrounding Catch it is an error in the context of

the Throw. That is, control is not Thrown to- the top level before the callan
Error. (Non-local Goto.)
Some examples:

-------~-~-~------------------

Flow Of Control
page 7.18

23 September 1983

PSL Manual
section 7.4

With
(DE DOlT (x)
(COND «EQN x 1) 100)
(T (THROW 'Faa 200»»
(CATCH 'Faa (DOlT 1) (PRINT "NOPE") 0)
will continue and execute the PRINT statement
and return 0
while
(CATCH 'FDa (DOlT 2) (PRINT "NOPE") 0)
will of course THROW, returning 200 and not executing
the last forms.

A common problem people encounter is how to pass arguments and/or computed
functions or tags into CATCH for protected evaluation.

The following examples should

ilJustrate. Note that TAG is quoted, since it is evaluated before use in CATCH and THROW.

(DE PASS-ARGS(Xl X2)
(CATCH 'FOa (FEE (PLUS2 Xl X2) (DIFFERENCE Xl X2»»

This is simple, because CATCH compiles open. No FLUID declarations or LIST building is
needed, as in previous versions of PSL.

An explicit Apply must be used for a function

argument; usually, the APPLY will compile open, with no overhead:

(DE PASS-FN(Xl FN)
(CATCH 'Faa (APPLY FN (LIST Xl»»

The following MACROs are provided to aid in the use of Catch and Throw with a NIL
tag, by examining the ThrowSignal! * and ThrowTag! *:
(Catch!-All FN:function [FORM:form]): any
This issues a (Catch NIL ... ); if a Throw was actually done, the function FN is
applied to the two arguments ThrowTag!* and the value returned by the
throw. Thus FN is applied only if a Throw was executed.

macro

Flow Of Control
page 7.19

23 September 1983

PSL Manual
section 7.4

macro

(Unwind!-All FN:function [FORM: form]): any
This issues a (Catch NIL ... ). The function FN is always called, and applied to
the two arguments ThrowTag!

* and

the value returned by the throw. If no

Throw was done then FN is called on NIL and the value returned.
macro

(Unwind!-Protect F:form [C:form1): any
The idea is to execute the "protected" form,

E,

and then run some "clean-

up" forms Q even if a Throw (or Error) occurred during the evaluation of

E-

This issues a (Catch NIL ... ), the cleanup forms are then run, and finally
either the value is returned if no Throw occurred, or the Throw is "rethrown" to the same tag.

A common example is to ensure a file be closed after processing, even if an
error or throw occurred:
(SETQ chan (OPEN file •••• ))
(UNWIND-PROTECT (process-file)
(CLOSE chan))
Note: Certain special tags are used in the PSL system, and should not be interfered with
casually:
!$ERROR!$ Used by Error and ErrorSet which are implemented in terms of Catch and
Throw, see Chapter 12).
!$UNWIND!-PROTECT!$
A special TAG placed to ensure that ALL throws pause at the UNWINDPROTECT "mark".
!$PROG!$

Used to communicate between interpreted PROGs, GOs and RETURNs.

PSL MANUAL
SECTION 8.0

23 SEPTEMBER 1983

FUNCTION DEFINITION
PAGE 8.1

CHAPTER 8
FUNCTION DEFINITION AND BINDING
8.1. Function Definition in PSL. .
8.2. Function Types. . . . . . .
8.2.1. Notes on Code Pointers
8.2.2. Functions Useful in Function Definition
8.2.3. Function Definition in LISP Syntax . .
8.2.4. BackQuote . . . . . . . . . . . . .
8.2.5. Low Level Function Definition Primitives
8.2.6. Function Type Predicates
8.3. Variables and Bindings. . . . .
8.3.1. Binding Type Declaration
8.3.2. Binding Type Predicates .
8.4. User Binding Functions . . . .

8.1
8.1
8.2
8.2
8.4
8.7
8.8
8.9
8.10
8.11
8.11
8.12

8.1. Function Definition in PSL
Functions in PSL are GLOBAL entities.

To avoid function-variable naming clashes, the

Standard LISP Report required that no variable have the same name as a function.
is no conflict in PSL, as separate function cells and value cells are used.
message is given for compatibility.

There

A warning

The first major section in this chapter describes how

to define new functions; the second describes the binding of variables in PSL

8.2. Function Tvpes
Eval-type functions are those called with evaluated arguments.
called with unevaluated arguments.

NoEval functions are

Spread-type functions have their arguments passed

'in a one-to-one correspondence with their formal

parameters.

NoSpread functions

receive their arguments as a single list.

There are four function types implemented in PSL:
expr

An Eval, Spread function, with a maximum of 15 arguments. In referring to
the formal parameters we mean their values.
Each function of this type
should always be called with the expected number of parameters, as indicated
in the function definition. Future versions of PSL wiU check this consistency.

fexpr

A NoEval, NoSpread function. There is no limit on the number of arguments.
In referring to the formal parameters we mean the unevaluated arguments,
collected as a single List, and passed as a single formal parameter to the
function body.

Function Definition
page 8.2

23 September 1983

PSL Manual
section 8.2

An Eval, NoSpread function. Each call on this kind of function may present a
different number of arguments, which are evaluated, collected into a list, and
passed in to the function body as a single formal parameter.
macro

The macro is a function which creates a new S-expression for subsequent
evaluation or compilation. There is no limit to the number of arguments a
macro may have.
The descriptions of the Eval and Expand functions in
Chapter 9 provide precise details.

8.2.1. Notes on Code Pointers
A code-pointer may be displayed by the Print functions or expanded by Explode.

The

value appears in the convention of the implementation (# < Code:a nnnn >, where a is the
number of arguments of the function, and nnnn is the function's entry point, (given in
octal on the DEC-20 and VAX).

A code-pointer may not be created by Compress.

Chapter 10 for descriptions of Explode and Compress.)

(See

The code-pointer associated with

a compiled function may be retrieved by GetD and is valid as long as PSL is in execution
(on the DEC-20 and VAX, compiled code is not relocated, so code-painters do not
change).

A code-pointer may be stored using PutD, Put, SetQ and the like or by being

bound to a variable.

It may be checked for equivalence by Eq.

The value may be

checked for being a code-pointer by the CodeP function .

.8.2.2. Functions Useful in Function Definition
In PSL, ids have a function cell that usually contains an executable instruction which
either JUMPs directly to the entry point of a compiled function or executes a CALL to an
auxiliary routine that handles interpreted functions, undefined functions, or other special
services (such as auto-loading functions, etc).

The user can pass anonymous function

objects around either as a code-pointer, which is a tagged object referring to a compiled
code block, or a lambda expression, representing an interpreted function.
(PutD FNAME:id TYPE:ftype BODY: {lambda,code-pointer}): id
Creates a function with name FNAME and type TYPE, with BODY as the
function definition.

If successful, PutD returns the name of the defined

function.

If the body is a code-pointer or is compiled (i.e., ! *COMP=T as the function
was defined), a special instruction to jump to the start of the code is placed

PSL Manual
section 8.2

23 September 1983

Function Definition
page 8.3

in the function cell. If it is a lambda, the lambda expression is saved on the
property list under the indicator ! *LAMBDALINK and a call to an interpreter
function (LambdaLink) is placed in the function cell.

The· TYPE is recorded on the property list of FNAME if it is not an expr.

[??? We need to add code to check that the the arglist has no more
than 15 arguments for exprs, 1 argument for fexprs and macros, and

??? for nexprs. Declaration mechanisms to avoid overhead also need to
be available.

(In fact are available for the compiler, although still

poorly documented.) When should we expand macros? ???]

After using PutD on

FNAME, GetD returns a pair of the the FNAME's

(TYPE . BODY).

The GlobalP predicate returns T if queried with the defined function's name.
If the function FNAME has already been declared as a GLOBAL or FLUID
variable the warning:

*** FNAME is a non-local variable
occurs, but the function is defined.

If function FNAME is already defined, a

warning message appears:

*** Function FNAME has been redefined
Note: All function types may be compiled.
The following switches are useful when defining functions.

! *REDEFMSG [Initially: T]
If ! *RedefMSG is not NIL, the message

*** Function 'FOO' has been redefined
is printed whenever a function is redefined.

switch

Function Definition
page 8.4

23 September 1983

PSL Manual
section 8.2

! *USERMODE [Initially: T]

switch

Controls action on redefinition of a function.

! *UserMode is T are flagged USER.
be redefined freely.

All functions defined if

Functions which are flagged USER can

If an attempt is made to redefine a function which is

not flagged USER, the query
Do you really want to redefine the system function 'FOO'?
is made, requiring a Y, N, YES, NO, or B response.
so that one can change the setting of !*Usermode.
loop, one must answer Y, Yes, N, or No.

B starts the break loop,
After exiting the break

See YesP in Chapter 10.

If

!*UserMode is NIL, all functions can be redefined freely, and all functions
defined have the USER flag removed.

This provides some protection from

redefining system functions.

!'*COMP [Initially: NIL]

switch

The value of ! *comp controls whether or not PutD compiles the function
defined in its arguments before defining it.
defined as a lambda expression.
compiled.

If! *comp is NIL the function is

If !*comp is non-NIL, the function is first

Compilation produces certain

changes in the

semantics

of

functions, particularly FLUID type access.

(GetD U:any): {NIL, pair}
If U is not the name of a defined function, NIL is returned.

If U is a defined

function then the pair ({expr, fexpr, macro, nexpr} . {code-pointer, lambda})
is returned.

(CopyD NEW: id OLD: id): NEW: id
The function body and type for NEW become the same as OLD.
definition exists for OLD an error:
***** OLD has no definition in COPYD
is given. NEW is returned.

expr
If no

Function Definition
page 8.5

23 September 1983

PSl Manual
section 8.2
(RemO U: id): {NIL, pair}

Removes the function named

!J

from the set of defined functions.

the (ftype . function) pair or NIL, as does GetD.
of

!J

is removed from the property list of

Returns

The function type attribute

!J.

8.2.3. Function Definition in LISP Syntax
The functions De, Of, On, Om, and Os are most commonly used in the LISP syntax form of
PSl.

They are difficult to use from RLiSP as there is not a convenient way to represent

the argument list.

The functions are compiled if the compiler is loaded and the GLOBAL

!*COMP is T.
macro

(De FNAME:id PARAMS:id-list [FN:form]): id
Defines the function named FNAME, of type expr.

The forms FN are made

into a lambda expression with the formal parameter list PARAMS, and this 1
is used as the body of the function.

Previous definitions of the function are lost.

The name of the defined

function, FNAME, is returned.
macro

(Df FNAME: id PARAM: id-list FN:any): id
Defines the function named FNAME, of type fexpr.

The forms FN are made

into a lambda expression with the formal parameter list PARAMS, and this is
used as the body of the function.

Previous definitions of the function are lost.

The name of the defined

function, FNAME, is returned.
macro

(Dn FNAME: id PARAM: id-list FN:any): id
Defines the function named FNAME, of type nexpr.

The forms FN are made

into a lambda expression with the formal parameter list PARAMS, and this is
used as the body of the function.

10r the compiled code pointer for the lambda expression if the compiler is on.

Function Definition
page 8.6

23 September 1983

Previous definitions of the function are lost.

PSL Manual
section 8.2
The name of the defined

function, FNAME, is returned.
(Dm MNAHE: id PARAH: id-listFN:any): id

macro

Defines the function named FNAME, of type macro. The forms FN are made
into a lambda expression with the formal parameter list PARAMS, and this is
used as the body of the function.

Previous definitions of the function are lost.

The name of the defined

function, FNAME, is returned.
(Ds SNAME: id PARAH: id-list FN:any): id
Defines the smacro SNAME.

macro

Smacros are actually a syntactic notation for a

special class of macros, those that essentially treat the macro's argument
as a list of arguments to be substituted into the body of the expression and
then expanded in line, rather than using the computational power of the
macro to customize code. Thus they are a special case of defmacro. See
also the BackQuote facility.

For example:

To make a substitution macro for
FIRST ->CAR we could say
(DM FIRST(X)
(LIST 'CAR (CADR X»)
Instead the following is clearer
(DS FIRST(X)
(CAR X»
The following (and other) macro utilities are in the file PU:USEFUL.SL; use (LOAD
USEFUL) to access. 2

2Useful was written by D. Morrison.

Function Definition
page 8.7

23 September 1983

PSL Manual
section 8.2
(DefMacro A: id

B: form

macro

[C: form]): id

DefMacro is a useful tool for defining macros. A DefMacro form looks like
. (DEFMACRO     •••  is an S-expression made of pairs and ids. It is matched

against the arguments of the macro much like the first argument to DeSetQ.
All of the non-NIL ids in

< pattern>

freely in the body (the < Si ».

are local variables which may be used

If the macro is called the

< Si >

are

evaluated as in a ProgN with the local variables in < pattern> appropriately
bound, and the value of

< Sn >

is returned.

DefMacro is often used with

BackOuote.

macro

(DefLambda ):
DefLarnbda defines a macro much like a substitution macro (smacro) except
that it is a lambda expression.

Thus, modulo redefinability, it has the same

semantics as the equivalent expr.
open compile things.
substitution

macro

It is mostly intended as an easy way to

For example, we would not normally want to define a
for

a

constructor

(NEW-Faa

X)

which

maps

into

(CONS X X), in case X is expensive to compute or, far worse, has side
effects.
which

(DEFLAMBDA NEW-Faa (X) (CONS X X)) defines it as a macro
maps

(NEW-Faa

(SETO

BAR

(BAZ)))

to

((LAMBDA (X) (CONS X X)) (SETO BAR (BAZ))).

8.2.4. BackQuote
Note that the special symbols described below only work in LISP syntax, not RLISP.
RLISP you may simply use the functions BackQuote, UnQuote, and UnQuoteL.

In

Load

USEFUL to get the BackQuote function.

The backquote symbol

11111

(accent grave) 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 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 (Le. strips off the outer

Function Definition
page 8.8

23 September 1983

PSL Manual
section 8.2

layer of parentheses). Thus

'(a

(b

,x) c

d

,@x e f)

is equivalent to
(cons fa {cons (list 'b x) (append '(c d) {append x '(e f»»)
In particular, if x is bound to (1 2 3) this evaluates to
(a (b (1 2

3»

c d 1 2

3 e f)

(BackQuote A: form): form

macro

Function name for back quote ' (accent grave).
(UnQuote A :any): Undefined
Function name for comma,.

It is an error to Eval this function; it should

occur only inside a BackQuote.
(UnQuoteL A: any): Undefined
Function name for comma-atsign ,@.

It is an error to Eval this function; it

should only occur inside a BackQuote.

8.2.5. MacroExpand
(MacroExpand A: form

[B: id]): form

MacroExpand is a useful tool for debugging macro definitions.
argument, HacroExpand expands all the macros in that form.

macro
If given one
Often one

wishes for more control over this process. For example, if a macro expands
into a Let, we may not wish to see the Let itself expanded to a lambda
expression.

Therefore additional arguments may be given to MacroExpand.

If these are supplied, they should be macros, and only those specified are
expanded. HacroExpand is in the USEFUL package.

Function Definition
page 8.9

23 September 1983

PSL Manual
section 8.2

8.2.6. Low Level Function Definition Primitives
The following functions are used especially by PutD and GetO, defined above in Section
8.2.2, and by Eval and Apply, defined in Chapter 9.

(FUnBoundP U: id): boolean
Tests whether there is a definition in the function cell of

!J; returns NIL if

so, T if not.

Note:

Undefined

functions

actually

UndefinedFunction, that invokes Error.

call

a

special

function,

FUnBoundP defines "unbound" to

mean "calls UndefinedFunction".

(FLambdaLinkP U: id): boolean
Tests whether U is an interpreted function; return T if so, NIL if not. This is
done by checking for the special code-address of the lambdaLink function,
which calls the interpreter.

(FCodeP U:id): boolean
Tests whether

!J is a compiled function; returns T if so, NIL if not.

(HakeFUnBound U: id): NIL
Makes

!J an undefined function by planting a special call to an error

function, UndefinedFunction, in th.e function cell of

!J.

(HakeFLambdaLink U: id): NIL
Makes

!J an interpreted function by planting a special call to an interpreter

support function (lambdaLink) function in the function cell of

!J.}

(MakeFCode U: id C: code-pointer): NIL
Makes U a compiled function by planting a special JUMP to the codeaddress associated with Q.

Function Definition
page 8.10

23 September 1983

PSL Manual
section 8.2

(GetFCodePointer U:id): code-pointer
Gets the code-pointer for

!l.

(Code! -Number! ";Of! -Arguments C:code-pointer): {NIL, integer}
Some compiled functions have the argument number they expect stored in
association with the codepointer

~_

This integer, or NIL is returned.

[??? Should be extended for nexprs and declared exprs. ???]

8.2.1. Function Type Predicates
See Section 8.2 for a discussion of the function types available in PSL.
(ExprP U:any): boolean
Test if

!l

is a code-pointer, lambda form, or an id with expr definition.

(FExprP U:any): boolean
Test if

!l

is an id with fexpr definition.

(NExprP U:any): boolean
Test if

!l

is an id with nexpr definition.

(MacroP U: any): boolean
Test if

!l

is an id with macro definition.

8.3. Variables and Bindings
Variables in PSL are ids, and associated valu~s are usually stored in and retrieved from
the value cell of this id.

If variables appear as parameters in lambda expressions or in

Prog's, the contents of the value cell are saved on a binding stack. A new value or NIL is
stored in the value cell and the computation proceeds.
the old value is restored.

On exit from the lambda or Prog

This is called the "shallow binding" model of LISP.

to permit compiled code to do binding efficiently.

It is chosen

For even more efficiency, compiled

code may eliminate the variable names and simply keep values in registers or a stack.
The scope of a variable is the range over which the -variable has a defined value.

There

are three different binding mechanisms in PSL.
LOCAL BINDING

Only compiled functions bind variables locally-

Local variables occur as

PSL Manual
section 8.3

Function Definition
page 8.11

23 September 1983

formal parameters in lambda expressions and as LOCAL variables in
Prog's. The binding occurs as a lambda expression is evaluated or as a
Prog form is executed. The scope of a local variable is the body of the
function in which it is defined.
FLUID BINDING

FLUID variables - are GLOBAL in scope but may occur as formal
parameters or Prog form variables. In interpreted functions, all formal
parameters and LOCAL variables are considered to have FLUID binding
until changed to LOCAL binding by compilation.
A variable can be
treated as a FLUID only by declaration. If FLUID variables are used as
parameters or LOCALs they are rebound in such a way that the previous
binding may be restored. All references to FLUID variables are to the
currently active binding. Access to the values is by name, gOing to the
value cell.

GLOBAL BINDING GLOBAL variables may never be rebound. Access is to the value bound
to the variable. The scope of a GLOBAL variable is universal. Variables
declared GLOBAL may not appear as parameters in lambda expressions
or as Prog form variables. A variable must be declared GLOBAL prior to
its use as a GLOBAL variable since the default type for undeclared
variables is FLUID. Note that the interpreter does not stop one from
rebinding a global variable. The compiler will issue a warning in this
situation.

8.3.1. Binding Type Declaration
(Fluid IDLIST: id-list): NIL
The ids in IDLIST are declared as FLUID type variables (ids not previously
declared are initialized to NIL).
are ignored.

Variables in IDLIST already declared FLUID

Changing a variable's type from GLOBAL to FLUID is not

permissible and results in the error:
*~':***

ID cannot be changed to FLUID

(Global IDLIST: id-list): NIL
The ids of IDLIST are declared GLOBAL type variables.
previously declared, it is initialized to NIL.
GLOBAL are ignored.

If an id has not been

Variables already declared

Changing a variable's type from FLUID to GLOBAL is

not permissible and results in the error:
***** ID cannot be changed to GLOBAL

23 September 1983

Function Definition
page 8.12

PSL Manual
section 8.3

(UnFluid IDLIST: id-list): NIL
The variables in IDUST which have been declared' as FLUID variables are no
longer considered as FLUID variables.
compiled

functions,

as

free

Others are ignored. This affects only

variables

in _ interpreted

functions

are

automatically considered FLUID (see [Griss 81]).

8.3.2. Binding Type Predicates
(FluidP U:any): boolean
If

!J

is FLUID (by declaration only), T is returned; otherwise, NIL is returned.

(GlobalP U:any): boolean
If

!J

has been declared GLOBAL or is the name of a defined function, T is

returned; else NIL is returned.
(UnBoundP U: id): boolean
Tests whether U has no value.

8.4. User Binding Functions
The following functions are available to build one's own interpreter functions that use
the built-in FLUID binding mechanism, and interact well with the automatic unbinding that
takes place during Throw and Error calls.
[??? Are these correct when Environments are managed correctly???]
(UnBindN N: integer): Undefined
Used in user-defined interpreter functions (like Prog) to restore previous
bindings to the last

N values bound.

(LBind1 IDNAME:id VALUETOBIND:any): Undefined
Support for lambda-like binding.

The current value of IDNAME is saved on

the binding stack; the value of VALUETOBIND is then bound to IDNAME.

23 September 1983

PSL Manual
section 8.4

Function Definition
page 8.13

(PBind1 IDNAME:id): Undefined
Support for

Prog.

stack.. Essentially

Binds

NIL

to IDNAME after saving value on the binding

LBind 1(IDNAME, NIL)

-------------------------------------------------------------------------------------

PSL MANUAL
SECTION 9.0

THE INTERPRETER
PAGE 9.1

23 SEPTEMBER 1983

CHAPTER 9
THE INTERPRETER
9.1
9.5

9.1. Evaluator Functions Eval and Apply. . . . . . .
9.2. -Support Functions for Eval and Apply. . . . . .
9.3. Special Evaluator Functions, Quote, and Function
9.4. Support Functions for Macro Evaluation. . . . .

9.7
9.7

9.1. Evaluator Functions Eval and Apply
The PSL evaluator uses an identifier's function cell (SYMFNC(id#) which is directly
accessible from kernel functions only) to access the address of the code for executing
the identifier's function definition, as described in chapter 8.

The function cell contains

either the entry address of a compiled function, or the address of a support routine that
either signals an undefined function or calls the lambda interpreter.

The PSL model of a

function call is to place the arguments (after treatment appropriate to function type) in
"registers", and then to jump to or call the code in the function cell.

Expressions which can be legally evaluated are called forms.

They are restricted S-

expressions:

.... -

id

I
I
I

constant
(id form ... form)
(special. any)

0/0
0/0
0/0

Normal function call
Special cases: COND, PROG, etc.
usually fexprs or macros.

The definitions of Eval and Apply may clarify which expressions are forms.

In Eval, Apply, and the support functions below, ContinuableError is used to indicate
malformed lambda expressions, undefined functions or mismatched argument numbers;
the user is permitted to correct the offending expression or to define a missing function
inside a Break loop.

The functions Eval and Apply are central to the PSL interpreter.

Since their efficiency

is important, some of the support functions they use are hand-coded in LAP.

The

functions LambdaApply, LambdaEvalApply, CodeApply, CodeEvalApply, and IDApply 1 are
support functions for Eval and Apply. CodeApply and CodeEvalApply are coded in LAP.

The Interpreter
page 9.2

23 September 1983

PSL Manual
section 9.1

IDApply1 is handled by the compiler.
(Eval U: form): any
The value of the form U is computed.

The following is an approximation of

the real code, leaving out some implementation details.

PSL Manual
section 9.1

23

September

1983

The Interpreter
page 9.3

(DE EVAL (U)
(PROG (FN)
(CONn
«IDP U) (RETURN (VALUECELL U»»
%ValueCell returns the contents of Value Cell if 1D is
%BoundP, else signals unbound error.
(COND «NOT (PAIRP U» (RETURN U»)

%This is a "constant" which EVAL's to itself
(COND
«EQCAR (CAR U) 'LAMBDA)
(RETURN
(LAMBDAEVALAPPLY (CAR U) (CDR U»»)

% LambdaEvalApply applies the lambda- expression Car U to the
%list containing the evaluation of each argument in Cdr U.
(COND
«CODEP (CAR U»
(RETURN (CODEEVALAPPLY (CAR U) (CDR U»»)

%CodeEvalApply applies the function with code-pointer Car U
%to the list containing the evaluation of each argument in
%Cdr U.
(COND
«NOT (IDP (CAR U»)
(RETURN
%permit user to correct U, and reevaluate.
(CONTINUABLEERROR 1101
"Ill-formed expression in EVAL" U»»
(SETQ FN (GETD (CAR U»)
(COND
«NULL FN)
%user might define missing function and retry
(RETURN
(CONT1NUABLEERROR 1001 "Undefined function EVAL" U»»
(CONn
«EQ (CAR FN) 'EXPR)
(RETURN
(COND
«CODEP (CDR FN»
% CodeEvalApply applies the function with
%codepointer Cdr FN to the list containing the
% evaluation of each argument in Cdr U.
(CODEEVALAPPLY (CDR FN) (CDR U»)

The Interpreter
page 9.4

23 September 1983

PSl Manual
section 9.1

(T
(LAMBDAEVALAPPLY
(CDR FN) (CDR U»»»)

%LambdaEvalApply
%list containing

applies the lambda-expression Cdr FN to the
the evaluation of each argument in Cdr U.

(COND
«EQ (CAR FN) 'FEXPR)
% IDApply1 applies the fexpr Car U to the list of
%unevaluated arguments.
(RETURN (IDAPPLY1 (CDR U) (CAR U»)}
«EQ (CAR FN) 'MACRO)
%IDApply1 first expands the macro call U and then
%evaluates the result.
(RETURN (EVAL (IDAPPLY1 U (CAR U}»»
«EQ (CAR FN) 'NEXPR)
%IDApply1 applies the nexpr Car U to the list obtained
%by evaluating the arguments in Cdr U.

(RETURN (IDAPPLY1 (EVLIS (CDR U»
(Apply FN: {id,function}

(CAR U»»»)

ARGS:form-list): any

Apply allows one to make an indirect function call.
FN with actual parameters ARGS.

It returns the value of

The actual parameters in ARGS are

already in the form required for binding to the formal parameters of FN.
PSl permits the application of macros, nexprs and fexprs; the effect is the
same as (Apply (Cdr (GetD FN» ARGS}; i.e. no fix-up is done to quote
arguments, etc. as in some LISPs.
second argument [e.g.

A call to Apply using List on the

(Apply F (List X Y))l is compiled so that the list is

not actually constructed.

The

following

is

an

implementation details.

approximation

of

the

real

code,

leaving

out

23 September

PSL Manual
section 9.1

The Interpreter
page 9.5

1983

(DE APPLY (FN ARGS)
(PROG (DEFN)
(COND
«CODEP FN)
%Spread the ARGS into the registers and transfer to the
%entry point of the function.
(RETURN (CODEAPPLY FN ARGS»)
«EQCAR FN 'LAMBDA)
%Bind the actual parameters in ARGS to the formal
%parameters of the lambda expression If the two lists
%are not of equal length then signal
% (CONTlNUABLEERROR 1204
%
"Number of parameters do not match"
%
(CONS FN ARGS»
(RETURN (LAMBDAAPPLY FN ARGS»)
«NOT (IDP FN»
(RETURN (CONTINUABLEERROR 1104
"Ill-formed function in APPLY"
(CONS FN ARG»»
«NULL (SETQ DEFN (GETD FN»)
(RETURN (CONTlNUABLEERROR 1004
"Undefined function in Apply"
(CONS FN ARGS»»
(T

%Do EXPR's, NEXPR's, FEXPR's and MACRO's alike, as
%EXPR's
(RETURN (APPLY (CDR DEFN) ARGS»»»
[??? Instead, could check for specific function types in Apply???]
9.2. Support Functions for Eval and ApplV

(EvLis U:any-list): any-list
EvLis returns a list of the evaluation of each element of

U.

The Interpreter
page 9.6

23 September 1983

PSL Manual
section 9.2

(LambdaApply FN:lambda, U:any-list): any
Checks that FN is a legal lambda, binds the formals of the lambda using
LBind 1 to the arguments in
in the lambda body.

!J.,

and then uses EvProgN to evaluate the forms

Finally· the formals are unbound, using UnBindN, and

the result returned.
(LambdaEvalApply FN:lambda, U:form-list): any
Essentially LambdaApply(FN,EvLis(U», though done more efficiently.
(CodeApply FN:code-pointer, U:any-list): any
Efficiently spreads the arguments

in

!J.

into the

"registers",

and

then

transfers to the starting address referred to by FN
(CodeEvalApply FN:code-pointer, U:any-list): any
Essentially CodeApply(FN,EvLis(!J», though more efficient.
The following entry points are used to get efficient calls on named functions, and are
open compiled.
(IdApplyO FN: id): any
(IdApply 1 A1 : form, FN: id): any
(IdApply2 A1 : form, A2: form, FN: id): any

(IdApply3 A1:form, A2:form, A3:form, FN:id): any
(IdApply4 A1:form, A2:form, A3:form, A4:form, FN:id): any
(EvProgN U: form-list): any
Evaluates each form in
various implied ProgNs.

!:!

in turn, returning the value of the last.

Used for

PSL Manual
section 9.3

The Interpreter
page 9.7

23 September 1983

9.3. Special Evaluator Functions, Quote, and Function
(Quote U: any): any
Returns U. Thus the argument is not evaluated by Eval.

(MkQuote U:any): list
(MkQuote!:!) returns (List 'QUOTE U)

(Function FN: function): function
The function FN is to be passed to another function.
effects its free variables must be FLUID or GLOBAL.

If FN is to have side
Function is like Quote

but its argument may be affected by compilation.

[??? Add FQUOTE, and make FUNCTION become CLOSURE ???]
See also the discussion of Closure and related functions in Section 8.4.

9.4. Support Functions for Macro Evaluation
(Expand L:list, FN:function): list
FN is a defined function of two arguments to be used in the expansion of a
macro. Expand returns a list in the form:

(FN L[O] (FN L[ 1] ... (FN L[n-l] L[n]) ... ))

"n" is the number of elements in

.b,

L[i] is the i'th element of

.b.

(DE EXPAND (L FN.)
(COND «NULL (CDR L»
(CAR L»
(T (LIST FN (CAR L) (EXPAND (CDR L) FN»»)

[??? Add RobustExpand (sure!) (document) ???]
[??? Add an Evalhook and Apply hook for CMU toplevel (document) ???]

PSL MANUAL
SECTION 10.0

23 SEPTEMBER 1983

INPUT AND OUTPUT
PAGE 10.1

CHAPTER 10
INPUT AND OUTPUT
10.1
10.2
10.3
10.6
10.6
10.6
10.7
10.8
10.9
10.10
10.11
10.11
10.13
10.13
10.14
10.15
10.16
10.16
10.17
10.19
10.22
10.23
10.24
10.26
10.28
10.29
10.29
10.33

10.1. Introduction. . . . . . . . . . . . .
10.1.1 ~ Organization of this Chapter . .
10.2. Printed Representation of LISP Objects
10.3. Functions for Printing . . . . . . .
10.3.1. Basic Printing . . . . . . . .
10.3.2. Whitespace Printing Functions.
10.3.3. Formatted Printing. . . . . .
10.3.4. The Fundamental Printing Function
10.3.5. Additional Printing Functions
10.3.6. Printing Status and Mode.
10.4. Functions for Reading . . . . .
10.4.1. Reading S-Expressions. .
10.4.2. Reading Single Characters
10.4.3. Reading Tokens . .
10.4.4. Reading Entire Lines
10.4.5. Read Macros. . . .
10.4.6. Terminal Interaction
10.4.7. Input Status and Mode .
10.5. File System Interface: Open and Close.
10.6. Loading Modules. . . . . . . . .
10.7. Reading Files into PSL . . . . . .
10.7.1. RLISP File Reading Functions
10.8. About 1/0 Channels . . . . . . .
10.9. 110 to and from Lists and Strings .
10.10. Generalized InputlOutput Streams
10.10.1. Using the "Special" Form of Open
10.11. Scan Table Internals . . . .
10.12. Scan Table Utility Functions. . . . . .

10.1. Introduction
One category of input and output in LISP is "symbolic" 1/0.

This allows a user to print

or read possibly complex LISP objects with one or a few calls on standard functions.

PSL

also has powerful general-purpose liD.

Input from multiple sources and output to multiple destinations can be done in PSL all
at the same time.
destinations for liD.

PSL provides liD functions with explicit specification of sources and
On the other hand for convenience it is often desirable to let the

source or destination be implicit.

PSL provides the full set of 110 operations through

functions with an implicit source or destination.

Input and Output
page 10.2

PSL Manual
section i 0.1

23 September 1983

The functions with and without an explicit channel designator argument are described
together in this chapter.
destination

In each case calling the function with the implicit source or

is the same as calling the version with

explicit channel argument and

supplying the value of the variable IN!* or OUT!*as the channel.

The current input or output channel can be changed by setting or rebinding the
variables IN!* or OUT!*.

Historically, the functions RDS and WRS have been used for this

and they are also available along with their special features.

10.1.1. Organization of this Chapter
We first discuss the syntax used for symbolic input and output.

The syntax described

applies to PSL programs, interactive typein, format of data in data files, and to output by
PSL programs except when special formatting is used.

Functions for printing and reading follow.
discussed.

All (textual) input and output functions are

Next is Open, for setting up input and output with files, plus related functions.

A great deal of user input/output programming can be done using just a subset of the
functions described in these first sections.

PSL includes functions that load program modules and execute command files.

They

are essential to building of software systems even if the system itself does no I/O.
Functions of this type are described next.

The section on I/O channels discusses some features available for switching the current
output from channel to channel, and documents some fluid variables used in directing
some of the system's input and output.

Functions in the next section actually operate on objects such as LISTS and STRINGS!
Since I/O functions scan input and format output, and since it is possible to read from or
print to a string, I/O functions can be useful for building strings and for scanning them.
Some built-in functions are described.

The last two sections describe mechanisms that make possible some sophisticated uses
of the PSL I/O system.

One describes the mechanism in PSL that permits writing to a

string or taking input from the text buffer of a text editor. The other discusses the tables

PSL Manual
section 10.1

23 September 1983

Input and Output
page 10.3

used by the PSL scanner, which is modifiable.

10.2. Printed Representation of LISP Objects
Most of this' section is devoted to. the representation of tokens .. In addition to tokens
there are composite objects with printed representations: lists and vectors.

We briefly

discuss their printed formats first.
"(" expression expression • • • It)"
U(tt expression expression.
tt " expression}
nett expression expression • • • "]tt

Of these the first two are for lists.

Where possible, the first notation is preferred and

the printing routines use it except when the second form is needed.

The second form is

required when the CDR of a PAIR is neither NIL nor another pair. The third notation is for
vectors. For example:

(A

(B. C}) % An

(A B • C)
(A B C)

[A B C]

S-EXPRESSION
% Same value, list notation
%An ordinary list
%A vector

The following standards for representing tokens are used:

*

Ids begin with a letter or any character preceded by an escape character.
They may contain letters, digits and escaped characters. !Qs may also start
with a digit, if the first non-digit following is a plus sign, minus sign, or letter
other than "b" or "e". This is to allow identifiers such as "1 +" which occur in
some LISPs.
Finally, a string of characters bounded by the IDSURROUND
character is treated as an ide
If !*Raise is non-NIL, unescaped lower case letters are folded to upper case.
The maximum size of an id (or any other token) is currently 5000 characters.
Note: Using lower case letters in identifiers may cause portability problems.
Lower case letters are automatically converted to upper case if the ! *RAISE
switch is T. This case conversion is done only for id input, not for single
character or string input.

[??? Can we retain input Case, but Compare RAISEd ???]
The following examples show identifiers in a form accepted by the LISP scan
table. Note that. most characters are treated as letters by the LISP scan table,
while they are treated as delimiters by the RLISP scan table.

Input and Output
page 10.4

23 September 1983

PSL Manual
section 10.2

- ThislsALongldentifier
- THISISALONGIDENTIFIER
- ThislsALongldentifierAndDifferentFromTheOther
- this _is _a_long_identifier _with _underscores

- an-identifier-with-dashes
- *RAISE
- !2222

* Strings begin with a double quote (") and include all characters up to a
closing double quote. A double quote can be included in a string by doubling
it. An empty string, consisting of only the enclosing quote marks, is allowed.
The characters of a string are not affected by the value of the !*RAISE.
Examples:
- "This is a string"
- "This is a ""string"""

* Integers begin with a digit, optionally preceded by a + or - sign, and consist
only of digits. The GLOBAL input radix is 10; there is no way to change this.
However, numbers of different radices may be read by the following
convention. A decimal number from 2 to 36 followed by a sharp sign (#),
causes the digits (and possibly letters) that follow to be read in the radix of
the number preceding the #.1 Thus 63 may be entered as 8#77, or 255 as
16#ff or 16#FF. The output radix can be changed, by setting OUTPUTBASE! *.
If OutPutBase!* is not 10, the printed integer appears with appropriate radix.
Leading zeros are suppressed and a minus sign precedes the digits if the
integer is negative. Examples:
- 100
- +5234
- -8#44 (equal to -36)

[??? Should we permit trailing
in integers for compatibility with some
LISPs and require digits on each side of . for floats ???]

10ctal numbers can also be written as a string of digits followed by the letter "B". This
"feature" may be removed in the future.

.---------------------------------------------------------

PSl Manual
section 10.2

23 September 1983

Input and Output
page 10.5

* Floats have a period and/or a letter "e" or "E" in them. Any of the following
are read as floats. The value appears in the format [- ]n.nn ... nnE£ - ]mm if the
magnitude of the number is too large or small to display in [- ]nnnn.nnnn
format. The crossover point is determined by the implementation. In BNF,
floats are recognized by the grammar:



.. -- . I

•  I
. 

::=  I 
 ::= !
e!
e-!
e+!
E!
E-I
E+

- !
+!
-

..

That is:

- [+1- ][nnn][.]nnn{eIE}[ +1- ]nnn
- nnn.
- .nnn
- nnn.nnn
Examples:

- le6
-

.2
2.
2.0
-1.25E-9

* Code-pointers cannot be read directly, but can be printed and constructed.
Currently printed as # < Code argument-count octal-address>.
* Anything else is printed as # < Unknown:nnnn >, where nnnn is the octal value
found in the argument register. Such items are not legal LISP entities and
may cause garbage collector errors if they are found in the heap.
They
cannot be read in.

PSL Manual
section 10.3

23 September 1983

Input and Output
page 10.6

10.3. Functions for Printing
10.3.1. Basic Printing
(Prin1- ITM:any): ITM:any
(ChannelPrin1 CHAN: io-channel

ITM:any): ITM:any

ChannelPrin 1 is the basic LISP printing function.

For well-formed, non-

circular (non-self-referential) structures, the result can be parsed by the
function Read.
(Prin2 ITM:any): ITM:any
(ChannelPrin2 CHAN: io-channel

ITM:any): ITM:any

ChannelPrin2 is similar to ChannelPrin 1, except that strings are printed
without the surrounding double quotes, and delimiters within ids are not
preceded by the escape character.
(Print U:any): U:any
(ChannelPrint CHAN: io-channel U:any): U:any
Display

!1

using ChannelPrin 1 and terminate line using ChannelTerpri.

10.3.2. Whitespace Printing Functions
(TerPri ): NIL
(ChannelTerPri CHAN: io-channel): NILTerminate OUTPUT line on channel CHAN, and reset the POSN counter to O.
(Spaces N: integer): NIL

PSL Manual
section 10.3

23 September 1983

Input and Output
page 10.7

(ChannelSpaces CHAN:io-channel N:integer): NIL
ChannelPrin2
than the

N spaces. Will continue across multiple lines if N is greater

number of positions

in the

output

buffer.

(See POSN and

LINELENGTH)
(Tab N: integer): NIL

expr

(ChannelTab CHAN: io-channel N: integer): NIL

expr

Move to position

N on channel CHAN, emitting spaces as needed.

ChannelTerPri if past column

Calls

N.

10.3.3. Formatted Printing
(PrintF FORMAT:string

[ARGS:any]): NIL

(ChannelPrintF CHAN: io-channel FORMAT:string [ARGS:any]): NIL
ChannelPrintF is a simple routine for formatted printing, similar to the
function with the same name in the C language[22].

FORMAT is either a

LISP or SYSLISP string, which is printed on the output channel CHAN.
However, if a

010

is encountered in the string, the character following it is a

formatting directive, used to interpret and print the other arguments to
ChannelPrintF in order.

The following format characters are currently

supported:

* For LISP tagged items, use:
%p

°low
a/or

0/01

print the next argument as a LISP item, using Pr in 1
print the next argument as a LISP item, using Prin2
print the next argument as a LISP item, using ErrPrin
(Ordinarily Prin2 "",; Prin 1 Arg; Prin2 '''If )
same as %w, except lists are printed without top' level
parens; NIL is printed as a blank

* Control formats:
%b
a/of

take next argument as an integer and print that many
blanks
~/fresh-line", print an end-of-Iine character if not at the
beginning of the output line (does not use a matching

a/on
%t

*

PSL Manual
section 10.3

23 September 1983

Input and Output
page 10.8

argument)
print end-of-line character (does not use a matching
argument)
take the next argument as an integer, and ChannelTab to
that position

The following are NOT for use from ordinary LISP programs.
SYSLISP arguments only, use:
a/ad
0/00

a/ox
%c
a/os

print
print
print
print
print

the
the
the
the
the

next
next
next
next
next

argument
argument
argument
argument
argument

as
as
as
as
as

For

a decimal integer
an octal integer
a hexadecimal integer
a single character
a string

If the character following % is not either one of the above or another

0/0 ,

causes an error. Thus, to include a % in the format to be printed, use

0/00/0.

it

There is no checking for correspondence between the number of arguments
the FORMAT expects and the number given.

If the number given is less

than the number in the FORMAT string, then garbage will be inserted for the
missing arguments.

If the number given is greater than the number in the

FORMAT string, then the extra ones are ignored.

(RPrint U:form): NIL
Print in RLISP format. Autoloading.

(PrettyPrint U: form): U
Prettyprints!J.

Autoloading.

This is a rather powerful utility, unfortunately

not properly documented.

10.3.4. The Fundamental Printing Function
(WriteChar CH:character): character

PSl Manual
section 10.3

23 September 1983

(ChannelWriteChar CHANNEL:io-channel
Write one character to CHANNEL.
function.

Input and Output
page 10.9

CH:character): character
All output is defined in terms of this

If CH is equal to char EOl (ASCII IF, 8# 12) the line counter POSN

associated .with CHANNEL is set to zero.

Otherwise, it is increased by one.

The writing function associated with CHANNEL is called with CHANNEL and
CH as its arguments.
(de WRITECHAR (CH)
(CHANNELWRITECHAR QUT!* CH»

10.3.5. Additional Printing Functions
(Prin2L L :any): L
Prin2, except that a list is printed without the top level parens.
(Prin2T X :any): any
(ChannelPrin2T CHAN:io-channel X:any): any
Output ~ using ChannelPrin2 and terminate line with ChannelTerpri.
(PrinC ITM:any): ITM:any
Same function as Prin2.
(ChannelPrinC CHAN:io-channel ITM:any): ITM:any
Same function as ChannelPrin2.
(ErrPrin U:any): None Returned
Prin 1 with special quotes to highlight
(ErrorPrintF FORMAT:string

11.

[ARGS:any1): NIL

ErrorPrintF is similar to PrintF, except that instead of using the currently
selected output channel, ERROUT!* is used.

Also, an end-of-line character

is always printed after the message, and an end-of-line character is printed
before the message if the line position of ERROUT! * is greater than zero.

PSl Manual
section 10.3

23 September 1983

Input and Output
page 10.10
(Eject ): NIL

Skip to top of next output page on current output channel.

(ChannelEject CHAN: io-channel): NIL
Skip to top of next output page on channel CHAN.

10.3.6. Printing Status and Mode
For information on directing various kinds of output see the section on channels.

OutPutBase!

* [Initially:

global

10]

This fluid can be set to control the radix in which integers are printed out.
If the radix is not 10, the radix is given before a sharp sign, e.g. 8#20 is"20"
in base 8, or 16.
(Posn ): integer
(ChannelPosn CHAN:io-channel): integer
Returns number of characters output on this line (Le. POSN counts since
last Terpri) on this channel.
(LPosn ): integer
(ChannelLPosn CHAN:io-channel): integer
Returns number of lines output on this page (Le. LPosn counter since last
Eject or formfeed character) on this channel.
(LineLength LEN: [integer, NIL}): integer
(ChannelLineLength CHAN: io-channel LEN: {integer, NIL}}: integer
Set maximum output line length on CHAN if a positive integer, returning
previous value.

If NIL just return previous value.

Controls the insertion of

automatic Terpri's. If lEN is 0, an EOl character will not be inserted.
The fluid variables PRINlEVEl and PRINlENGTH allow the user to control how deep the
printer will print and how many elements at a given level the printer will print.
useful for debugging or dealing with large or deep objects.

This is

These variables affect the

~-----

... ~~----~~~~~~~~~~~--------------

PSL Manual
section 10.3

23 September 1983

Input and Output
page 10.11

functions Prin 1, Prin2, PrinC, Print, and PrintF (and the corresponding Channel
functions). The documentation of these variables is from the Common Lisp Manual.
PrinLevel [Initially: Nil]

global

Controls how many levels deep a nested data object will print.
is Nil, then no control is exercised.

If PRINLEVEL

Otherwise the value should be an

integer, indicating the maximum level to be printed. An object to be printed
is at level O.
PrinLength [Initially: Nil]

global

Controls how many elements at a given level are printed.

A value of Nil

indicates that there be no limit to the number of components printed.
Otherwise the value of PRINLENGTH should be an integer.

10.4. Functions for Reading
10.4.1. Reading S-Expressions
(Read ): any
(ChannelRead CHAN:io-channel): any
Reads and returns the· next S-expression from input channel CHAN.
input

forms

are:

vector-notation,

strings, and identifiers.
Chapter

4),

unless

pair-notation,

list-notation,

Valid

numbers,

Identifiers are interned (see the Intern function in
the

FLUID

variable

! *COMPRESSING

is

non-NIL.

ChannelRead returns the value of the global variable ! $EOF! $ when the end
of the currently selected input channel is reached.

ChannelRead uses the ChannelReadToken function, with tokens scanned
according to the "Lisp scan table".

The user can define similar read

functions for use with other scan tables.

ChannelRead uses the Read

macro mechanism to do S-expression parsing. See Section 10.4.5 for more
information on read macros and how to add extensions. The following read
macros are defined initially:

PSl Manual
section 10.4

23 September 1983

Input and Output
page 10.12

Starts a scan collecting S-expressions according to list or dot
notation until terminated by a). A pair or list is returned.
Starts a scan collecting S-expressions according to
notation until terminated bya]. A vector is returned.

vector

Calls Read to get an S-expression, x, and then returns the list
(Quote x).
(CHAR EOF) Generates an error when still inside an S-expression:
***** Unexpected EOF while reading on channel
. Otherwise the value of !$EOF!$ is returned.
is EQ to the initial value of !$EOF!$.)

(Actually the value

The USEFUL library 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 example, #\a = #\A = 65, while #\!a = #\(Iower a) = 97.

#.

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.

PSL Manual
section 10.4

23 September 1983

Input and Output
page 10.13

10.4.2. Reading Single Characters
(ReadChar ): character

expr

(ChannelReadChar CHAIDlEL: io-channel): character

expr

Reads one character (an integer) from CHANNEL.

All input is defined in

terms of this function.

If CHANNEL is not open or is open for writing only,

an error is generated.

If there is a non-zero value in the backup buffer

associated with CHANNEL, the buffer is emptied (set to zero) and the value
returned.

Otherwise, the reading function associated with CHANNEL is

called with CHANNEL as argument, and the value it returns is returned by
ChannelReadChar.

***** Channel not open
***** Channel open for write only
(ReadCH ): id
(ChannelReadCH CHAN:io-channel): id
Like ChannelReadChar, but returns the id for the character rather than its
ASCII code.
(UnReadChar CH:character): Undefined
(ChannelUnReadChar CHAN:io-channel CH:character): Undefined
The input backup function.
with CHAN.

CH is deposited in the backup buffer associated

This function should be only called after ChannelReadChar is

called, before any intervening input operations, since it is used by the token
scanner.

The "UnRead" buffer only holds one character, so it is generally

useless to "unread" more than one character.

10.4.3. Reading Tokens
The functions described here pertain to the token scanner and reader.
switches used by these functions are defined at the end of this section.

Globals and

Input and Output
page 10.14

PSL Manual
section 10.4

23 September 1983

(ChannelReadToken CHANNEL:io-channel): rid, number, string}
This is the basic LISP token scanner.

The value returned is a LISP item

corresponding to the next token from the input stream.
unless the FLUID variable ! *COMPRESSING is non-NIL.

!Qs are interned,

The GLOBAL variable

TOKTYPE!* is set to:

o
2

3

if the token is an ordinary id,
if the token is a string,
if the token is a number, or
if the token is an unescaped delimiter such as "(", but not "!(" In
this last c";se, the value returned is the id whose print name is
the same as the delimiter.

The precise behavior of this function depends on two FLUID variables:
CurrentScanTable!*
Is bound to a vector known as a scan table.

Described below.

CurrentReadMacrolndicator!*
Bound to an id known as a read macro indicator.
below.

Described

(RAtom): rid, number, string}
Reads a token from the current input channel.

expr
(Not called ReadToken for

historical reasons.)
[??? Should we bind CurrentScanTable!* for this function too ???]
(ChannelReadTokenWi thHooks CHANNEL: io-channel): any
This function reads a token and performs any action specified jf the token is
marked as a Read macro under the current indicator.
function internally.

Read uses this

Uses the variable CURRENTREADMACROINDICATOR!* to

determine the current indicator.

10.4.4. Reading Entire Lines
Two functions exist for reading entire lines.

PSl Manual
section 10.4

23 September 1983

Input and Output
page 10.15

(ReadLine ): string
(ChannelReadLine CHAN:io-channel): string
ReadLine-and - ChannelReadLine read everything from the current position
of the scanner to the next EOl character.
It is frequently used as in the following example.

(de faa ()
(prog (promptstring*)
(readline)
(setq promptstring* It __ >")
(return (readline»»

When one runs faa, the value of promptstring* is printed and then one types some
characters and ends the line. The string is returned.

4

lisp> (faa)

-->abcd
"abed"

10.4.5. Read Macros
A function of two arguments (Channel, Token) can be associated with any DELIMITER or

DIPHTHONG token (Le., those that have TokType !*=3) by putting the name of the function
on the appropriate indicator for the 10 for the token that is to be a Read macro.

A ReadMacro function is catted by ChannelReadTokenWi thHooks if the appropriate token
with TOKTYPE!*=3 is returned by ChannelReadToken. This function can then take over the
reading (or scanning) process, finally returning a token (actuallv an S-expression) to be
returned in place of the token itself.

Example:

The quote mark, 'x converting to (Quote x), is done by the following example

which makes use of the function PutReadMaero which is defined in Section 10.12.

(de DOQUOTE (CHANNEL TOKEN»
(LIST 'QUOTE (CHANNELREAD CHANNEL»
(PUTREADMACRO LISPSCANTABLE!*

'I'

(FUNCTION DOQUOTE»

PSL Manual
section 10.4

23 September 1983

Input and Output
page 10.16

A ReadMacro is installed on the property list of the macro-character as a function under
the indicators 'LiSPREADMACRO, 'RLISPREADMACRO, etc.

A Diphthong is installed on the

property list of the first character as (second-character. diphthong) under the indicators
'LlSPDIPHTHONG, 'RLlSPDIPHTHONG, etc.

10.4.6. Terminal Interaction
(YesP MESSAGE:string): boolean
If the user responds Y or Yes, YesP returns T and the calculation continues
from that point in the file.

If the user responds N or No, YesP returns NIL

and control is returned to the terminal, and the user can type in further
commands.

However, later on he can use the command CONT; and control

is then transferred back to the point in the file after the last PAUSE was
encountered.

If the user responds B, one enters a break loop.

After

quitting the break loop, one still must respond Y, N, Yes, or No.

(Pause ): Nil
(Only in RLiSP.)
input file.

The command PAUSE; may be inserted at any pOint in an

If this command is encountered on input, the system prints the

message CONT? on the user's terminal and halts by calling YesP.

10.4.7. Input Status and Mode
PROMPTSTRING!* [Initially: "lisp >"]

global

Displayed as a prompt when any input is taken from TTY.
should not be directly printed.

Thus prompts

Instead the value should be bound to

PROMPTSTRING! *.
! *EOLINSTRINGOK [Initially: NIL]
If !*EOLInStringOK is non-NIL, the warning message

*** STRING CONTINUED OVER END-OF-LiNE
is suppressed.

switch

PSL Manual
section 10.4

23 September 1983

Input and Output
page 10.17

! *RAISE [Initially: T]

switch

If !*RAISE is non-NIL, all characters input for ids through PSL input
functions are raised to upper case.

If !*RAISE is NIL, characters are input

as is. A string is unaffected by ! *RAISE.
! *COMPRESSING [Initially: NIL]

switch

If ! *COMPRESSING is non-NIL, ChannelReadToken and other functions that
call it do not intern ids.
CURRENTSCANTABLE!* [Initially: ]

global

This variable is set to LISPSCANTABLE!* by the Read function (the "Lisp
syntax"

reader).

The

RLISP

reader

sets

it

to

RLISPSCANTABLE! *

or

LISPSCANTABLE!* depending on the syntax it expects.
CURRENTREADMACROINDICATOR!* [Initially: ]

global

The function Read binds this variable to the value L1SPREADMACRO.

Its

value determines the property list indicator used in looking up Read macros.
The user may define a set of Read macros using some new indicator and
rebind this variable, then call the function ChannelReadTokenWi thHooks to
perform input with the alternative set of Read macros.

Ordinary Read macros may be added by Puting properties on ids under the
L1SPREADMACRO indicator.

10.5. File System Interface: Open and Close
(Open FILENAME:string

ACCESSTYPE:id): CHANNEL:io-channel

If ACCESSTYPE is Eq to INPUT or OUTPUT, an attempt is made to access the
system-dependent FILENAME for reading or writing.

If the attempt is

unsuccessful, an error is generated; otherwise a free channel is returned
and initialized to the default conditions for ordinary file input or output.

If none of these conditions hold, a file is not available, or there are no free
channels, an error is generated.

PSL Manual
section 10.5

23 September 1983

Input and Output
page 10.18

***** Unknown access type
***** Improperly set-up special

10 open call

***** File not found
***** No free channels
If ACCESSTYPE is Eq to SPECIAL, no file is opened.

Instead the channel is

initialized as a generalized input and/or output stream. See below.

(FileP NAME:string): boolean
This function will return T if file NAME can be opened, and NIL if not, e.g. if
it does not exist.

(Close CHANNEL: io-channel): io-channel
The closing function associated with CHANNEL is called, with CHANNEL as
its argument.

If it is illegal to close CHANNEL, if CHANNEL is not open, or if

CHANNEL is associated with a file and the file cannot be closed by the
operating system, this function generates an error.

Otherwise, CHANNEL is

marked as free and is returned.
Here is a simple example of input from a particular file with output sent to the current
output channel.

This function reads forms from the file MYFILE.DAT and prints out all

those whose CAR is EQ to its parameter.
{defun filter-my-file (x)
{let {{chan (open "myfile.dat" 'input»
form)
{while (neq (setq form (channelread chan»
$eof$)
(if {and (pairp form) {eq (car form) x»
(print form»)
(close chan»)

The same thing with an unwind-protect form to give more assurance that the
(and the file) will be closed in all cases including errors, is shown below.

ch~nnel

----

-----------------------.----------

PSL Manual
section 10.5

23 September 1983

Input and Output
page 10.19

(defun filter-My-file (x)
(let «chan (open "myfile.dat" 'input»
form)
(unwind-protect
(while (neq (setq form (channelread chan»
$eof$)
(if (and (pairp form) (eq (car form) x»
(print form»)
(close chan»»
The following functions are part of RLiSP. Please do not use them in LISP code.
(Out U:string): None Returned
Opens file

~

macro

for output, redirecting standard output.

Note that Out takes a

string as an argument, while Wrs takes an io-channel.
(EvOut L: str ing-list): None Returned

1: is a list containing one file name which must be a string. EvOut js the
called by Out after evaluating its argument.
(Shut [L:string]): None Returned

macro

Closes the output files in the list
arguments, while Close takes

an

1:.

Note that Shut takes file names as
io-channel.

The RLiSP

IN function

maintains a stack of (file-name . io-channel) associations for this purpose.
Thus a shut will also correctly select the previous file for further output.
(EvShut L:string-list): none Returned
Does the same as Shut but evaluates its arguments.

10.6. Loading Modules
Two convenient procedures are

available for loading

modules.

Various

facilities

described in this manual are actually in loadable modules and their documentation notes
that they must be loaded.

Loadable modules typically exist as FASL files (.b files on the

VAX or DEC-20); see Section 15.2.2 for information on producing FASL files.

Input and Output
page 10.20

PSL Manual
section 10.6

23 September 1983

(Load [FILE: {string, id}]): NIL

macro

Each FILE is converted into a file name of the form "lu/locai/lib/psi/file.b
on the VAX, "pl:file.b" on the DEC-20.
function FaslIn on it.

ll

An attempt is made to execute the

Once loaded, the symbol FILE is added to the

GLOBAL variable OPTIONS! *.

All loads consult the OPTIONS! * list and do

not load files that are already present (See ReLoad below to load functions
already

loaded).

LoadExtensions!

Also,

*

consult the

GLOBALS

LoadDirectories! *

and

below for information on where loadable files may be

found and how their names are constructed.

(ReLoad [FILE: {string,id}]): NIL

macro

Removes the filename from the list Options! * and executes the function
Load.

(Imports MODULENAMES: list): NIL
Imports is almost identkal to load in its behavior, though not in the way it
is called.

The only behavioral difference is that if imports is invoked as a

module is being loaded, the actual loading of the additional modules may
be delayed until loading of the current module is complete. This allows the
module loader to reclaim some space that would otherwise be wasted, a
matter that is specific to the way PSL is currently implemented.

!*VerboseLoad [Initially: NIL]

switch

If T, turns on !*RedefMsg during Loads so that every function redefined
during a Load is announced.

Also messages are given when a request is

made to Load a file that is already loaded, and a message is printed for
each file that is actually loaded.
!*PrintLoadNames [Initially: NIL]
If T, turns on printing of the message announcing each file loaded.

switch

PSL Manual
section 10.6

23 September 1983

LoadDirectories!

Input and Output
. page 10.21

* [Initially: A list of strings]

global

Contains a list of strings to append to the front of file names given in Load
commands.

This list may be one of the following, if your system is an

Apollo, Dec-20, or Vax:

('tI, "/utah/psl/lap/")
("" "pI:")
(tItI "/usr/local/src/cmd/psl/dist/lap/")
load tries each directory on this list in turn as it searches for a specific file
to load in as the requested module.

LoadExtensions!

* [Initially: An

a-list]

global

Contains an a-list of (str , fn) in which the str is an extension to append to
the end of the filename and fn is a function to apply, The a-list contains
«".b" • FasIIn)(fI.lap" • LapIn)(tI.sI" • LapIN»
At present the file extensions in this list are searched in order within each of the

directories of LOADDIRECTORIES!*,

The following are some scenarios on the use of Load and Imports.

Suppose that

Module B:
a. requires modules C and 0 during its execution, but can be loaded after
B. Then place (LOAD C D) in the file. When B is loaded interpretively, the load
will be executed immediately. When B is compiled, the LOAD of C and 0 will
be deferred until B is "LOADED", If {IMPORTS '(C 0» had been used, nothing
would happen when B is interpreted, but when B is compiled, the same
deferred load will occur.
b. needs module A to be loaded before it is loaded.
create a .LAP file to load in each of the modules:

It is then necessary to

AS.LAP consists of:
(LOAD A)
(LOAD B)
The user may then load in AB and will get A followed by B.
c. needs module A during its compilation.
somewhere in module B.

Place a {Compiletime (Load A»

PSL Manual
section 10.6

23 September 1983

Input and Output
page 10.22

d. needs module A during its compilation and during
{Bothtimes (Load A)) somewhere in module B.

execution.

Place

a

10.7. Reading File into PSL
The- following procedures are used to read complete files into PSL, by first calling Open,
and then looping until end of file.
were typed into PSL.

The efte!:;t is similar to what would happen if the file

Recall that file names are strings, and therefore one needs string-

quotes (") around file names.

File names may be given using full system dependent file

name conventions, including directories and sub-directories, "Iinks" and "Iogical-devicenames", as appropriate on the specific system.

! *ECHO [Initially: Nil]

switch

The switch !*ECHO is used to control the echoing of input. When (On Echo)
is p.laced in an input file, the contents of the file are echoed on the
standard output device.

Dskin does not change the value of

!~:ECHO,

so

one may say (On Echo) before calling Dskin, and the input will be echoed.

(DskIn F:string): None Returned

expr

Enters a Read-Eval-Print loop on the contents of the file.E.
expects LISP syntax in the file

E.

Use the following format:

DskIn

(Oskln "File").

(LapIn U:string): None Returned
Reads a Single LISP file as "quietly" as possible, i.e., it does not echo or
return values.

Note that LapIn can be used only for LISP files.

By

convention, files with the extension ".LAP" are intended to be read by LapIn.
These

files

are

typically

used

binary (also known as FASL) files.
preferable to using LapIn.

to

load

modules

made

up

of

several

The use of the Load function is normally

For information about fast loading of files of

compiled functions (FASL files) see FASL and the Load and FaslIn functions
in Chapter 15.

PSL Manual
section 10.7

23 September 1983

Input and Output
page 10.23

(FaslIn FILENAME:string): NIL
This

is

an

efficient

binary

read

loop,

constants and compactly stored ids.

which

fetches

blocks

of

code,

It uses a bit-table to relocate code

and to identify special· LISP-oriented constructs.

FILENAME must be a

complete file name.

10.7.1. RLISP File Reading Functions
The following functions are present in RLlSP, they can be used from Bare-PSL by
loading RLiSP.

(In [L :string]): None Returned

macro

Similar to Dskln but expects RLiSP syntax in the files it reads unless it can
determine that the files are not in RLiSP syntax.
than one file name as an argument.

Also

~n

can take more

On most systems the function In

expects files with extension .LSP and .SL to be written in LISP syntax, not in
RLiSP.

This is convenient when using both LISP and RLISP files.

It is

conventional to use the extension .RED (or .R) for RLiSP files and use .LSP
or .SL only for fully parenthesized LISP files.

There are some system

programs, such as TAGS on the DEC-20, which expect RLISP files to have
the extension .RED.

If it is not desired to have the contents of the file echoed as it is read,
either end the In command with a "$" in RLlSP, as
In "FILE1.RED","FILE2.SL"$

or include the statement "0ff ECHO;" in your file.

(PathIn FileName-Tail:string): None Returned

expr

Allows the use of a directory search path with the Rlisp IN function.
finds a list of search paths in the fluid variable PATHIN!*.

It

These are

successively concatenated onto the front of the string argument to PathIn
until an existing file is found (using FileP.
invoked on this file.

VAX,

If one is found, In will be

If not, a continuable error occurs.

For example on the

Input and Output
page 10.24

23

Septem~er

PSL Manual
section 10.7

1983

(Setq PathIn!* '( "" "/u/psl/" "/u/smith/"»
(PathIn "foo.red")
will

attempt

to

open

"foo.red",

then

"/u/psllfoo.red",

and

finally

"/u/smith/foo.red" until a successful open is achieved.

To use Pathin in Bare-PSL, load PATHIN as well as RLiSP.
!*PrintPathin [Initially: NIL]

switch

If T, a message is printed for each file that is read by Pathin.
(EvIn L:string-list): None Returned

!: must be a list of strings that are filenames. EvIn is the function called by
In after evaluating its arguments.

In is useful only at the top-level, while

EvIn can be used inside functions with file names passed as parameters.

10.8. About 1/0 Channels
(Rds {CHANNEL:io-channel, NIL}): io-channel
Rds sets IN!* to the value of its argument, and returns the previous value
of IN!*.

In addition, if SPECIALRDSACTION!* is non-NIL, it should be a

function of 2 arguments, which is called with the old CHANNEL as its first
argument and the new CHANNEL as its second argument.

Rds(NIL) does

the same as Rds(STDIN!*).
(Wrs (CHANNEL: io-channel, NIL}): io-channel
Wrs sets OUT! * to the value of its argument and returns the previous value
of OUT!*.

In addition, if SPECIALWRSACTION!* is non-NIL, it should be a

function of 2 arguments, which is called with the old CHANNEL as its first
argument and the new CHANNEL as its second argument.

Wrs(NIL} does

the same as Wrs(STOOUT!*).
GLOBAL variables containing information about channels are listed below.

23 September 1983

PSl Manual
section 10.8

Input and Output
page 10.25

IN!* [Initially: 0]

global

Contains the currently selected input channel.

May be set or rebound by

the user. This is changed by the function Rds.

OUT!

* [Initially:

global

1]

Contains the currently selected output channel.

May be set or rebound by

the user. This is changed by the function Wrs.

STDIN! * [Initially: 0]

global

The standard input channel (but not in the Unix sense of standard input).
Channel

a

is ordinarily the terminal and this variable is not intended to be

set or rebound.

STDOUT!

* [Initially: 1]

The standard output channel.

global
Like channel 0, channel 1 is ordinarily always

the terminal, and this variable is not intended to be set or rebound.

Breakln!* [Initially: Nil]
The channel from which the BREAK loop gets its input.

global
It has been set to

default to StdIN!*, but may have to be changed on some systems with
buffered-IO.

BreakOut! * [Initially: Nil]
The channel to which the BREAK loop sends its output.

global
It has been set to

default to StdOut! *, but may have to be changed on some systems with
buffered-IO.

Helpln! * [Initially: NIL]

global

The Help mechanism uses this variable's value for input.

HelpOut! * [Initially: Nil]
This variable's value determines the output channel used by the Help
mechanism.

global

ERROUT!

* [Initially:

PSL Manual
section 10.8

23 September 1983

Input and Output
page 10.26

global

1]

The channel used by the ErrorPrintF.
global

SPECIALRDSACTION!* [Initially: NIL]

SPECIALWRSACTION!

* [Initially:

global

NIL]

10.9. I/O to and from Lists and Strings
(BldMsg FORMAT:string, [ARGS:any]): string
PrintF to string.

This can be used as a very convenient way of obtaining

the printed representation of an object for further analysis.

In many cases

it is also a very convenient way of constructing a needed string.

If

overflow occurs BldMsg returns a string stating that the string could not be
constructed.

(FlatSize U:any): integer
Character length of Prin 1 S-expression.

(FlatSize2 U:any): integer
Prin2 version of flatsize.
Note that for many purposes it is easier to use Digi tp, AlphaP, etc. for performing the
kind of testing that Digit and Liter do.

(Digit U:any): boolean
Returns T if U is a digit, otherwise NIL. Effectively this is:
(de DIGIT (U)
(IF (MEMQ U '(! 0 ! 1 ! 2 ! 3 ! 4 ! 5 ! 6 ! 7 ! 8 ! 9 »

T NIL»

(Li ter U: any): boolean
Returns T if U is a character of the alphabet, NIL otherwise.
effectively:

expr
This is

PSL Manual
section 10.9

23 September 1983

Input and Output
page 10.27

(de LITER(U)

(IF (MEMQ U '(A BCD E F G H I J K L M
N 0 P Q R STU V W X Y Z abc d e f
g h i j kim n 0 p q r s t u v w x y

z»

T NIL»

(Explode U:any): id-list
Explode takes the constituent characters of an S-expression and forms a
list

of

single

character

ids.

It

is

implemented

via

the

function

ChannelPrin 1, with a list rather than a file or terminal as destination.
Returned

is

a

list

of

interned

required to print the value of

* Explode 'FOO;

*

iJ..

characters

representing

the

characters

Example:

= > (F 0 0)

Exp I0 d e '(A . B); = > (! ( A!

!.! B !))

[??? add print macros. cf. UCI lisp ???]
(Explode2 U: {atom}-{ vector }): id-list
Prin2 version of Explode.
(Compress U:id-list): {atom}-tvector}

!:!

is a list of single character identifiers which is built into a PSL entity and

returned.

Recognized are numbers, strings, and identifiers with the escape

character prefixing special characters.

The formats of these items appear in

the "Primitive Data Types" Section, Section 2.1.2. Identifiers are not interned
on the Id-hash-table.

Function pointers may not be compressed.

If an

entity cannot be parsed out of U or characters are left over after parsing an
error occurs:

*****

Poorly formed atom in COMPRESS

(Implode U: id-list): atom
Compress with ids interned.

23 September 1983

Input and Output
page 10.28

PSL Manual
section 10.10

10.10. Generalized Input/Output Streams
[??? We should

replace these globals and SPECIAL option

by a (SPECIALOPEN

Readfunction writefunction closefunction) call ???]
All input and output functions· are

impl~mented

in terms of operations on "channels".

A

channel is just a '-;~all integer2 which has 3 functions and some other information
associated with it. The three functions are:
a. A reading function, which is called with the channel as its argument and
returns the integer ASCII value of the next character of the input stream. If
the channel is for writing only, this function is Wri teOnlyChannel.
If the
channel has not been opened, this function is ChannelNotOpen. The reading
function is responsible for echoing characters if the flag !*ECHO is T.
It
should use the function WriteChar to echo the character. It may not be
appropriate for a read function to echo characters. For example, the "disk"
reading function does echoing, while the reader used to implement the
Compress function does not.
The read function must also be concerned with the handling of ends of
"files" (actually, ends of channels) and ends of lines. It should return the
ASCII code for an end of file character (system dependent) when reaching the
end of a channel. It should return the ASCII code for a line feed character to
indicate an end of line (or "newline"). This may require that the ASCII code
for carriage return be ignored when read, not returned.
b. A writing function, which is called with the channel as its first argument and
the integer ASCII value of the character to write as its second argument. If
the channel is for reading only, this function is ReadOnlyChannel.
If the
channel has not been opened, this function is ChannelNotOpen.
c. A closing function, which is called with the channel as its argument and
performs any action necessary for the graceful termination of input and/or
output operations to that channel. If the channel is not open, this function is
ChannelNo tOpen.

The other information associated with a channel includes the current position in the
output line (used by Posn), the maximum line length allowed (used by LineLength and the
printing functions), the single character input backup buffer (used by the token scanner),

2The range of channel numbers is from 0 to MaxChannels, where MaxChannels is a
system-dependent constant, currently 31, defined in IO-OATA.REO. MaxChannels is a
WCONST, and is not available for use at runtime.

PSL Manual
section 10.10

23 September 1983

Input and Output
page 10.29

and other system-dependent information.

Ordinarily, the user need not be aware of the existence of this mechanism.

However,

because of its generality, it -is possible to implement operations other than just reading
.. from and" writing to files using it.

In particular, the LISP functions Explode and Compress

are performed by writing to a list and reading from a list, respectively (on channels 3 and
4 respectively).

10.10.1. Using the IISpecial
Note:

1l

Form of Open

Please pardon the creaky mechanism used to implement this facility.

We expect

to improve it.

If Open

is

called

with

SPECIALREADFUNCTION!*,

ACCESSTYPE

Eq

to

SPECIAL

SPECIALWRITEFUNCTION!*,

and

and

the

GLOBAL

variables

SPECIALCLOSEFUNCTION!*

are

bound to ids, then a free channel is returned and its associated functions are set to the
values

of these

conditions,

which

variables.
can

Other

later

be

non

system-dependent

overridden.

The

WriteOnlyChannel are available as error handlers.

status

functions

is

set

to

default

ReadOnlyChannel

and

The parameter FILENAME is used only

if an error occurs.

The following GLOBALs are used by the functions in this section.
SPEC I ALCLOSEFUNCT ION ! * [Initially: NIL]

global

SPECIALREADFUNCTION!* [Initially: NIL]

global

SPECIALWRITEFUNCTION!* [Initially: NIL]

global

10.11. Scan Table Internals
Scan tables have 129 entries, indexed by 0 through 128.
ASCII

character

code

to

get

an

integer

code

0 through 127 are indexed by

determining

the

treatment

of

the

corresponding character. The last entry is not an integer, but rather an id which specifies
a Diphthong Indicator for the token scanner.

[??? A future implementation may replace the FLUID CurrentReadMacrolndicator! *
with another entry in the scan table. ???]

Input and Output
page 10.30

23 September 1983

PSl Manual
section 10.11

The following encoding for characters is used.

o ...

DIGIT: indicates the character is a digit, and gives the corresponding numeric
value.
lETTER: indicates that the· character is a letter.
DELIMITER: indicates that the character is a delimiter which is not the starting
character of a diphthong.
COMMENT: indicates that the character begins a comment terminated by an
end of line.
DIPHTHONG: indicates that the character is a delimiter which may be the
starting character of a diphthong. (A diphthong is a two character sequence
read as one token, i.e., "< < or ":=".)
IDESCAPE: indicates that the character is an escape character, to cause the
following character to be taken as part of an id. (Ordinarily an exclamation
point, i.e. "!".)
STRINGQUOTE: indicates that the character is a string quote. (Ordinarily a
double quote, i.e. "".)
PACKAGE: indicates that the character is used to introduce explicit package
names. (Ordinarily "\".)
IGNORE: indicates that the character is to be ignored. (Ordinarily BLANK, TAB,
EOl and NULL.)
MINUS: indicates that the character is a minus sign.
PLUS: indicates that the character is a plus sign.
DECIMAL: indicates that the character is a decimal point.
IDSURROUND: indicates that the character is to act for identifiers as a string
quote acts for strings. Although this is not used in the default scan table, the
intended character for this function is a vertical bar, I.)

9

10
11
12
13

II

14

15

16

17
18
19
20
21

System builders who wish to define their own parsers can bind an appropriate scan
table

to

CurrentScanTable!*

and

then

ChannelReadTokenWithHooks for lexical scanning.
tables are described in the next section.

call

ChannelReadToken

or

Utility functions for building scan

PSL Manual
section 10.11

LISPSCANTABLE! * [Initially:

23 September 1983

Input and Output
page· 10.31

as shown in following table]

global

o A@ IGNORE
32 IGNORE
1 AA LETTER
33 ! IDESCAPECHAR
2 AS LETTER
34 " STRINGQUOTE
-35 II LETTER
3 "'C LETTER
4 AD LETTER
36 $ LETTER
5 AE LETTER
- 37 % COMMENTCHAR
6 AF LETTER
38 & LETTER
7 AG LETTER
39 f DELIMITER
8 AH LETTER
40 ( DELIMITER
41 ) DELIMITER
9  IGNORE
10  IGNORE
42 * LETTER
11 AK LETTER
43 + PLUSSIGN
12 AL IGNORE
44 , DIPHTHONGSTART
13  IGNORE
45 - MINUSSIGN
14 AN LETTER
46 . DECIMALPOINT
15 AO LETTER
47 / LETTER
16 Ap LETTER
48 0 DIGIT
17 AQ LETTER
49 1 DIGIT
18 AR LETTER
50 2 DIGIT
19 AS LETTER
51 3 DIGIT
20 AT LETTER
52 4 DIGIT
21 AU LETTER
53 5 DIGIT
22 AV LETTER
54 6 DIGIT
23 AW LETTER
55 7 DIGIT
24 AX LETTER
56 8 DIGIT
25 Ay LETTER
57 9 DIGIT
26 AZ DELIMITER 58 : LETTER
27 $ LETTER
59 ; LETTER
28 A\ LETTER
60 < LETTER
29 A] LETTER
61 = LETTER
30 AA LETTER
62 > LETTER
31 A_ LETTER
63 ? LETTER

64 @ LETTER

65 A LETTER
66 B LETTER
67 C LETTER
68 D LETTER
69 E LETTER
70 F LETTER
71 G LETTER
72 H LETTER
73 I LETTER
74 J LETTER
75 K LETTER
76 L LETTER
77 M LETTER
78 N LETTER
79 0 LETTER
80 P LETTER
81 Q LETTER
82 R LETTER
83 S LETTER
84 T LETTER
85 U LETTER
86 V LETTER
87 WLETTER
88 X LETTER
89 Y LETTER
90 Z LETTER
91 [ DELIMITER
92 \ PACKAGE
93 ] DELIMITER
94 A LETTER
95 LETTER

The Diphthong Indicator in the 128th entry is the identifier

96 f DELIMITER
97 a LETTER
98 b LETTER
99 c LETTER
100 d LETTER
101 e LETTER
102 f LETTER
103 g LETTER
104 h LETTER
105 i LETTER
106 j LETTER
107 k LETTER
108 1 LETTER
109 m LETTER
110 n LETTER
111 0 LETTER
112 P LETTER
113 q LETTER
114 r LETTER
115 s LETTER
116 t LETTER
117 u LETTER
118 v LETTER
119 w LETTER
120 x LETTER
121 Y LETTER
122 z LETTER
123 { LETTER
124 I LETTER
125 } LETTER
126 -.. LETTER
127 

LETTER

LISPDIPHTHONG.

PSL Manual
section 10.11

23 September 1983

Input and Output
page 10.32

global

RLISPSCANTABLE!* [Initially: as shown in following table]

o A@

IGNORE
1 AA DELIMITER
2 AB DELIMITER
'. 3 AC DELIMITER
4 AD DELIMITER
5 AE DELIMITER
6 AF DELIMITER
7 AG DELIMITER
8 AH DELIMITER
9  IGNORE
10  IGNORE
11 AK DELIMITER
12 AL IGNORE
13  IGNORE
14 AN DELIMITER
15 AO DELIMITER
16 Ap DELIMITER
17 AQ DELIMITER
18 AR DELIMITER
19 AS DELIMITER
20 AT DELIMITER
21 AU DELIMITER
22 AV DELIMITER
.23 "W DELIMITER
24 AX DELIMITER
25 Ay DELIMITER
26 AZ DELIMITER
27 $ DELIMITER
28 A\ DELIMITER
29 A] DELIMITER
30 AA DELIMITER
31 A_ DELIMITER

32
IGNORE
33 ! IDESCAPECHAR
34 " STRINGQUOTE
35 II DELIMITER
36 $ DELIMITER
37 %COMMENTCHAR
38 & DELIMITER
39 t DELIMITER
40 ( DELIMITER
41 ) DELIMITER
42 * DIPHTHONGSTART
43 + DELIMITER
44 , DELIMITER
45 - DELIMITER
46 . DECIMALPOINT
47 / DELIMITER
48 0 DIGIT
49 1 DIGIT
50 2 DIGIT
51 3 DIGIT
52 4 DIGIT
53 5 DIGIT
54 6 DIGIT
55 7 DIGIT
56 8 DIGIT
57 9 DIGIT
58 : DIPHTHONGSTART
59 ; DELIMITER
60 < DIPHTHONGSTART
61 = DELIMITER
62 > DIPHTHONGSTART
63 ? DELIMITER

64 @ DELIMITER
65 A LETTER
66 B LETTER
67 C LETTER
68 D LET.TER
69 E LETTER
70 F LETTER
71 G LETTER
72 H LETTER
73 I LETTER
74 J LETTER
75 K LETTER
76 L LETTER
77 M LETTER
78 N LETTER
79 0 LETTER
80 P LETTER
81 Q LETTER
82 R LETTER
83 S LETTER
84 T LETTER
85 U LETTER
86 V LETTER
87 WLETTER
88 X LETTER
89 Y LETTER
90 Z LETTER
91 [ DELIMITER
92 \ PACKAGE
93 ] DELIMITER
94 A DELIMITER
95 LETTER

96 t DELIMITER
97 a LETTER
98 b LETTER
99 c LETTER
100 d LETTER
101 e LETTER
102 f LETTER
103 g LETTER
104 h LETTER
105 i LETTER
106 j LETTER
107 k LETTER
108 1 LETTER
109 rn LETTER
110 n LETTER
111 0 LETTER
112 P LETTER
113 q LETTER
114 r LETTER
115 s LETTER
116 t LETTER
117 u LETTER
118 v LETTER
119 w LETTER
120 x LETTER
121 Y LETTER
122 z LETTER
123 { DELIMITER
124 I DELIMITER
125 } DELIMITER
126 - DELIMITER
127 
DELIMITER

The Diphthong Indicator in the 128th entry is the identifier RLISPDIPHTHONG.
[???

What about the RlispRead scantable ???]

[???

Perhaps describe one basic ta'ble, and changes from one to other, since mostly

the same ???]
global

TOKTYPE! * [Initially: 3]
ChannelReadToken sets TOKTYPE! * to:

o
1
2
3

if
if
if
if

the
the
the
the

token
token
token
token

is
is
is
is

an ordinary id,
a string,
a number, or
an unescaped delimiter.

In the last case, the value returned is the id whose print name is the same

PSL Manual
section 10.11

23 September 1983

Input and Output
page 10.33

as the delimiter.

10.12. Scan Table Utility Functions
- The following functions are-provided to manage scan tables, in the READ-UTILS module
(use via LOAD READ-UTILS):
(PrintScanTable TABLE: vector): NIL
Prints the entire scantable, gives the 0 ... 127 entries with the name of the
character class. Also prints the indicator used for diphthongs.

[???

Make

smarter,

reduce

output,

use

nice

names

for

control

characters, ala EMODE. ???]
(CopyScanTable OLDTABLE:{vector, NIL}): vector
Copies

the

existing

scantable

(or

CURRENTSCANTABLE!*

if

given

NIL).

Currently GenSymO's the indicators used for diphthongs.

[??? Change when we use Property Lists in extra slots of the ScanTable ???]
{PutDiphthong TABLE: vector ,

D1:id

ID2:id

DIP:id}: NIL

Installs DIP as the name of the diphthong 101 followed by 102 in the given
scan table.
(PutReadMacro TABLE:vector

ID1 :id

FNAME:id): NIL

Installs FN-AME as the name of the Read macro function for the delimiter or
diphthong 101 in the given scan table. [not implemented yet]

c

PSL MANUAL
SECTION 11.0

23 SEPTEMBER 1983

TOP LEVEL LOOP
PAGE 11.1

CHAPTER 11
TOP LEVEL LOOP
11.1. Introduction .
.11.2... The General Purpose Top Loop Function.
11.3. Changing the Default Top Level Function
11.4. The Break Loop . . . . . . . . . . . .

11.1
11.1
11.4
11.4

11.1. Introduction
In this chapter those functions are presented relating directly to the user interface; for
example, the general purpose Top Loop function, the History mechanism, and changing
the default Top Level function.

11.2. The General Purpose Top Loop Function
PSL provides a general purpose Top Loop that allows the user to specify his own Read,
Eval and Print functions and otherwise obtain a standard set of services, such as
Timing, History, Break Loop interface, and interface to the Help system.

TopLoopEval! * [Initially: NIL]

global

The Eval used in the current Top Loop.

TopLoopPrint! * [Initially: NIL]

global

The Print. used in the current Top Loop.

TopLoopRead! * [Initially: NIL]

global

The Read used in the current Top Loop.

(TopLoop TOPLOOPREAD!*:function
TOPLOOPEVAL!*:function

TOPLOOPPRINT!*:function

TOPLOOPNAME!*:id

WELCOMEBANNER:string): NIL

This function is called to establish a new Top Loop (currently used for
Standard LISP, RLlSP, and Break).

It prints the WELCOMEBANNER and then

invokes a "Read-Eval-Print" loop, using the given functions.

Note that

TOPLOOPREAD!*, etc. are FLUID variables, and so may be examined (and
changed) within the executing Top Loop.

TopLoop provides a standard

expr

PSL Manual
section 11.2

23 September 1983

Top Level Loop
page 11.2

History and timing mechanism, retaining on a list HISTORYLlST!* the input
constructed

from

TOPLOOPNAME!* and is printed out, prefixed by the History count.

As a

and

output

as

a

list

of

pairs.

A

prompt

is

. convention, the name·'ls followed by a number of 1/>1/'5, indicating the loop
depth.
The initial values ot the following four globals are those that exist in Bare-PSL.

They

may differ in other PSL executables.
global

TopLoopName! * [Initially: lisp]
Short name to put in prompt.

global

TopLoopLevel! * [Initially: 0]
Depth of top loop invocations.

switch

! *EMsgP [Initially: T]
Whether to print error messages.

global

Ini tForms! * [Initially: NIL]
Forms to be evaluated at startup.

! *TIME [Initially: NIL]

switch

If on, causes a step evaluation time to be printed after each command.

(Hist [N: integer]): NIL
This function does not work with the Top Loop used by PSL:RLlSP or by
(beginrlisp); it does work with LISP and with RLiSP if it is started from LISP
using the RLiSP function.

Hist is called with 0, 1 or 2 integers, which

control how much history is to be printed out:
(HIST)
(HIST n m)
(HIST n)
(HIST -n)

Display
Display
Display
Display

full history.
history from n to m.
history from n to present.
last n entries.

[??? Add more info about what a history is. ???]
The following functions permit the user to access and resubmit previous expressions,

PSL Manual
section 11.2

23 September 1983

Top Level Loop
page 11.3

and to re-examine previous results.
(Inp N: integer): any
Return N'th input at this level.
(ReDo N: integer): any
Reevaluate N'th input.
(Ans N: integer): any
Return N'th result.
HistoryCount! * [Initially: 0]

global

Number of entries read so far.
HistoryList! * [Initially: Nil]
List of entries read and evaluated.
TopLoop has been used to define the following StandardLisp and RLISP top loops.
(StandardLisp ): NIL
Interpreter LISP syntax top loop, defined as:
(De StandardLisp Nil
(Prog (CurrentReadMacroIndicator!* CurrentScanTable!*)
(Setq CurrentReadMacroIndicator!* 'LispReadMacro)
(Setq CurrentScanTable!* LispScanTable!*)
(Toploop 'Read 'Print 'Eval "LISP"
"PORTABLE STANDARD LISP"»)
Note that the scan tables are modified.
(RLisp ): NIL
Alternative interpreter RLISP syntax top loop, defined as:

[??? xread described in RLISP Section ???]
(De RLisp Nil
(Toploop 'XRead 'Print 'Eval "RLISP" "PSL RLISP"»
Note that for the moment, the default RLISP loop is not this (though this

global

Top Level Loop
page 11.4

PSL Manual
section 11.2

23 September 1983

may be used experimentally); instead a similar (special purpose hand coded)
function, BeginRlisp, based on the older Begin 1 is used.

It is hoped to

change the RLISP top-level to use the general purpose capability.

(BeginRLisp ): None Returned

expr

Starts RLISP from PSL:PSL only if RLISP is loaded.

The module RLiSP is

present if you started in RLiSP and then entered PSL.

11.3. Changing the Default Top Level Function
As PSL starts up, it first sets the

~tack

pointer and various other variables, and then

calls the function Main inside a While loop, protected by a Catch.

By default, Main calls a

StandardLisp top loop, defined using the general TopLoop function, described in the next
section.

In order to have a saved PSL come up in a different top loop, the function Main

should be appropriately redefined by the user (e.g., as is done to create RLlSP).

(Main ): Undefined
Initialization function, called after setting the stack.

Should be redefined by

the user to change the default TopLoop.

11.4. The Break Loop
The Break Loop uses the top loop mechanism and is described in detail in Chapter 12.
For information, look there.

PSL MANUAL
SECTION 12.0

23 SEPTEMBER 1983 ERROR HANDLING AND RECOVERY
PAGE 12.1

CHAPTER 12
ERROR HANDLING
12.1.
12.2.
12.3.
12.4.
12.5.
12.6.
12.7.

Introduction. . . . . . .
The Basic Error Functions.
Basic Error Handlers
Break Loop . . . . . . .
Interrupt Keys. . . . . .
Details on the Break Loop
Some Convenient Error Calls

12.1
12.1
12.3
12.5
12.9
12.9
12.10

12.1. Introduction
In PSL, as in most LISP systems, various kinds of errors are detected by functions in the
process of checking the validity of their argument types and other conditions.
then "signalled" by a call on an Error function.

Errors are

In PSL, the error handler typically calls an

interactive Break loop, which permits the user to examine the context of the error and
optionally

make

some

corrections

and

continue the

computation,

or to

abort the

computation.

While in the Break loop, the user remains in the binding context of the function that
detected the error; the user sees the value of FLUID variables as they are in the function
itself. If the user aborts the computation, fluid and local variables are unbound.

[??? What about errors signalled to the Interrupt Handler ???]

12.2. The Basic Error Functions
(Error NUMBER:integer

MESSAGE: any):

None Returned

Under the initial (and usual) values of a couple of switches, the error
message is printed and an interactive break loop (see below) is entered.

If

the user "quits" out of the interactive break loop, control returns to the
innermost error handler.

The user may supply an error handler.

The interactive break loop and the

top level loop also supply error handlers, so if the user makes no special
preparation, control will return to an existing break loop or to the top level

Error Handling and Recovery
page 12.2

PSL Manual
section 12.2

23 September 1983

of LISP.

Whenever a call on Error results in return to an error handler, the error
number of the error· becomes the value returned by the error handler.
FLUID

variables

and·: LOCAL

bindings

environment of the error handler.
process.

are

unbound

to

return

to

the

GLOBAL variables are not affected by the

The error message is printed with 5 leading asterisks on both the

standard output device and the currently selected output device unless the
standard output device is not open.
without top level parentheses.

If the message is a list it is displayed

The message from the error call is available

for later examination in the GLOBAL variable EMSG!*.

Note: the exact format of error messages generated by PSL functions
described in this document may not be exactly as given and should not be
relied upon to be in any particular form.
by PSL functions are not fixed.

Likewise, error numbers generated

Currently, a number of different calls on

Error result in the same error message and number.

[??? Describe Error # ranges here, or have in a file on machine ???]
(Con tinuableError NUMBER: in teger
Similar to Error.

MESSAGE: any

FORM: form): any

If an interactive break is entered due to a call on

ContinuableError, the user has options of "continuing" or "retrying" (see
information on the break loop, below).
ContinuableError returns.

In either of these cases the call on

The value returned is as described in the

documentation of the interactive break loop.

The FORM argument is used for "retrying" after a continuable error.

The

FORM is generally made to look like a call on the function that signalled the
error (actual argument values filled in), and the function signalling the error
generally returns with the value returned by the call on ContinuableError.
For example the call on ContError, in the example below is equivalent to
the following call on ContinuableError:

(CONTINUABLEERROR 99 (LIST 'DIVIDE (MKQUOTE U) (MKQUOTE V»)

PSL Manual
section 12.2

23 September 1983

The FORM argument may be NIL.

Error Handling and Recovery
page 12.3

In this case it is expected that the break

will be left via "continue" rather than "retry".

As -in the example above, setting up the ErrorForm! * can get a bit tricky,
often involving MkQuoteing of already evaluated arguments.

The following

MACRO may be useful.
(Con tError [ARGS:any]): any

macro

The format of ARGS is (ErrorNumber, FormatString, {arguments to PrintF},
ReEvaIForm).

The FORMATSTRING is used with the following arguments in

a call on BldMsg to build an error message.

If the only argument to PrintF

is a string, the FORMATSTRING may be omitted, and no call to BldMsg is
made. The ReEvalForm is something like Foo(X, Y) which becomes list('Foo,
MkQuote X, MkQuote Y} to be passed to the function ContinuableError.
(DE DIVIDE (U, V)
(COND«ZEROP V)
(CONTERROR

99

"Attempt to divide by 0 in DIVIDE",
(DIVIDE U V»)
(T (CONS (QUOTIENT U V) (REMAINDER U V»»)

(FatalError S:any): None Returned
This function allows neither continuation nor even a return to any error
handler. Its definition is:
(ProgN (ErrorPrintF ,,***** Fatal error: %s" S)
(While T (Quit»)

12.3. Basic Error Handlers
(ErrSet U: form

! *EMsgP: boolean): any

macro

ErrSet and ErrorSet are the basic PSL error handler functions.

If an error occurs during the evaluation of

~,

associated error call is returned as the value of the ErrSet.
actually a couple of exceptions.

-

the value of NUMBER from the
There are

If a (continuable) error is continued by the

user in the interactive Break loop, no special return to ErrSet is done.

Error Handling and Recovery
page 12.4

PSL Manual
section 12.3

23 September 1983

Also if the user requests the computation to be aborted completely back to
the top level, no return to ErrSet is done.

The boolean argument is evaluated without protection of the error handler.
The

FLUID

variable

!*EMSGP

evaluation of the FORM.

is

bound

to

the

boolean

value

for the

If the value of !*EMSGP is NIL when an error

occurs no error message is printed and no interactive Break loop occurs.
In this case control must return to the innermost error handler except for
the case of a fatal error.

If ErrSet is returned to in the normal way, its value is a list of one element,
the value of the FORM.

If ErrSet is returned to via the error mechanism,

its value is the error number of the error call that caused the return.
(ErrorSet U:any

!*EMsgP:boolean

!*BACKTRACE:boolean): any

This is an older function than ErrSet. ErrSet is generally preferred.

In

most

respects

ErrorSet

behaves

documentation of ErrSet above.

the

same

as Errset.

See the

Note that ErrorSet is an expr, so

!J gets

evaluated once as the parameter is passed and the result is then evaluated
inside ErrorSet.

Since ErrorSet itself calls Eval on its first argument

there are likely to be problems with compiled code that uses ErrorSet.

In addition to binding EMSGP as ErrSet does, ErrorSet overrides the
behavior usually specified by the· !*BACKTRACE switch.

The backtrace

behavior of PSL errors during the execution of a form inside an ErrorSet
error handler is determined by the second parameter to the ErrorSet.
The following two switches and one global variable are used by the functions in this
section. Useage of any of these can be considered advanced.

! *EMsgP [Initially: T]

global

Fluid variable rebound by ErrSet and ErrorSet.
printing during call on error.

Controls error message

If NIL, no error message will be printed and no

interactive break loop will be entered.

·If an unwind backtrace has been

requested through the BACKTRACE flag or a call on ErrorSet, one will be.

PSL Manual
section 12.3

23 September 1983

Error Handling and Recovery
page 12.5

EMSG! * [Initially: NIL]

global

Contains the message generated by the last error call.

Particularly useful in

case printing of the message was suppressed.

! *BackTrace [I n iti a Ily: NIL]

switch

Used by the top level read-eval-print loop to control whether an unwind
backtrace will be printed when errors occur outside the scope of any userspecified error handler.

Since ErrorSet is somewhat obsolete, the precise

behavior controlled by this flag may change.

12.4. Break Loop
On detecting an error, PSL normally enters a Read/Eval/Print loop called a Break loop.
Here the user can examine the state of his computation, change the values of FLUID and
GLOBAL variables, or define missing functions.

He can then dismiss the error call to the

normal error handling mechanism (ErrorSet or ErrSet above).
continuable type, he may continue the computation.
NIL, all Break loops can

be suppressed, and

If the error was of the

By setting the switch ! *BREAK to

just an

error message is

displayed.

Suppressing error messages also suppresses Break loops.

! *BREAK [Initially: T]

switch

Controls whether the Break package is called before unwinding the stack on
error.

BreakLevel! * [Initially:, 0]

global

The current number of nesting level of breaks.

MaxBreakLevel!

* [Initially:

5]

global

The maximum number of nesting levels of breaks permitted.

If an error

occurs with at least this number of nested breaks already existing, no entry
to an interactive break loop is made. Control aborts back to the innermost
error handler instead.
The prompt "Break>" indicates that PSL has entered a Break loop.

A message of the

form "Retry form is ... " may also be printed, in which case the user is able to continue his
computation by repairing the ,offending. expression.

By default, a Break loop uses the

Error Handling and Recovery
page 12.6
functions Read, Eval, and Print.

PSL Manual
section 12.4

23 September 1983

This may be changed by setting BREAKREADER!*,

BREAKEVALUATOR!*, or BREAKPRINTER!* to the appropriate function name.
global

ERRORFORM! * [Initially: NIL]
Contains an expression to reevaluate inside a· Break loop for continuable
errors.

[Not enough errors set this yet].

Used as a tag for various Error

functions.
Several ids, if typed at top-level, are special in a Break loop.

These are used as

commands, and are currently E, M, R, T, Q, A, I, and C. They call functions stored on their
property lists under the indicator 'BreakFunction.

These ids are special only at top-level,

and do not cause any difficulty if used as variables inside expressions.
may not be simply typed at top-level to see their values.
any difficulty.

However, they

This is not expected to cause

If it does, an escape command will be provided for examining the relevant

variables.

The meanings of these commands are:

E

Edit the value of ErrorForm!*. This is the object printed in the "Retry form is
... " message. The function BreakEdi t is the associated function called by this
command.
The Retry command (below) uses the corrected version of
ErrorForm!*. The currently available editors are described in Part 2 of the
manual.

M

Show the modified ErrorForm! *. Calls the function BreakErrmsg.

R

Retry. This tries to evaluate the retry form, and continue the computation. It
evaluates the value of ERRORFORM! *.
This is often useful after defining a
missing function, assigning a value to a variable, or using the Edi t command,
above. This command calls· the function BreakRetry.

C

Continue. This causes the expression last printed by the Break loop to be
returned as the value of the call on ContinuableError. This is often useful
as an automatic stub. If an expression containing an undefined function is
evaluated, a Break loop is entered, and this may be used to return the value
of the function call. This command calls the function BreakContinue.

Q

Quit. This exits the Break loop by throwing to the closest surrounding error
handler. It calls the function BreakQui t.

A

Abort.
Reset.

This. aborts to the top level, i.e., restarts PSL.

It calls the function

PSL Manual
section 12.4
T

23 September 1983

Error Handling and Recovery
page 12.7

Trace. This prints a backtrace of function calls on the stack except for those
on the lists Ignored InBackTrace ! * and_ InterpreterFunctions! *. It calls the
function BackTrace.
Interpreter Trace. - This prints a backtrace of only interpreted functions call on
the stack except for those on the list InterpreterFunctions! *. It calls the
function InterpBackTrace.

An attempt to continue a non-continuable error with R or C prints a message and
behaves as Q.

IgnoredInBacktrace!* [Initially:, '(Eval Apply FastApply CodeApply
CodeEvalApply Catch ErrorSet EvProgN TopLoop BreakEval
BindEval Break Main)]

global

A list of function names that will not be printed by the commands I and T
given within a Break loop.

InterpreterFunctions! * [Initially: '(Cond Prog And Or ProgN SetQ)]
A list of function names that will not be printed by the command

global
given

within a Break loop.
The above two globals can be reset in an init file if the programmer desires to do so.

The following is a slightly edited transcript, showing some of the BREAK options:

Error Handling and Recovery
page 12.8

23 September 1983

%foo is an undefined function, so the following has two errors
% in it
1> (Plus2 (foo 1)(foo 2»
***** 'FOO' is an undefined function {1001}
- ***** Continuable error: -retry form is '(Faa 1) ,
Break loop
1 lisp break> (plus2 1 1)
%We simply compute a value
%prints as 2
2
%continue with this value
2 lisp break> c

%it returns to compute "(foo 2)"
***** 'FOO' is an undefined function {1001}
***** Continuable error: retry form is '(FOO 2)'
Break loop
%again compute a value
1 lisp break> 3
3
2 lisp break> c
%and return
%finally complete
5

%Pretend that we had really meant to call "fee":
2> (de fee (x) (addl x»
FEE
3> (plus2 (foo l)(foo 2»
% now the bad expression
***** 'FOO' is an undefined function f1001}
***** Continuable error: retry form is '(Faa 1)'
Break loop
%lets edit it
1 lisp break> e
Type HELP for a list of commands.
edit> p
% print form
(FOO 1)
edit> ( 1 fee)
% replace l'st by "fee"
edit> p
% print again
(FEE 1)
edit> ok
% we like it
(FEE 1)
2 lisp break> m
% show modified ErrorForm!*
ErrorForm!* : ' (FEE 1) ,
NIL
3 lisp break> r
%Retry EVAL ErrorForm!*
***** 'Foo' is an undefined function {1001}
***** Continuable error: retry form is '(FOO 2)'

PSL Manual
section 12.4

PSL Manual
section 12.4

23 September 1983

Break loop
1 lisp break> (de foo(x) (plus2 x
FOO
2 lisp break> r

1»

Error Handling and Recovery
page 12.9

%define
%and

foo

retry

5
12.5. Interrupt Keys
Need to load the module INTERRUPT to enable. This applies only to the DEC20.

< Ctrl-T> indicates routine currently executing, gives the load average, and gives the
location counter in octal;

< Ctrl-G > returns you to the Top-Loop;

 takes you into a lower-level Break loop.

12.6. Details on the Break Loop
If

the

SWITCH

! *BREAK

is

T,

the

function

BreakO

is

called

ContinuableError before unwinding the stacks, or printing a backtrace.

by

Error

or

Input and output

to/from Break loops is done from/to the values (channels) of BREAKIN!* and BREAKOUT!*.
The channels selected on entrance to the Break loop are restored upon exit.
Breakln!* [Initiatly: NIL]

global

So Rds chooses StdIN! *.
BreakOut! * [Initially: NIL]

global

Similar to Breakin!*.
Break is essentially a Read-Eval-Print function, called in the error context.

Any FLUID

may be printed or changed, function definitions changed, etc. The Break uses the normal
TopLoop mechanism (including History), embedded in a Catch with tag ! $BREAK! $.
TopLoop

attempts

to

use

the

parent

loop's

TOPLOOPREAD! *,

TOPLOOPPRINT! *

The
and

TOPLOOPEVAL! *; the BreakEval function first checks top-level ids to see if they have a
special BreakFunction on their property lists, stored under 'BreakFunction.
expected to be a function of no arguments, and is applied instead of Eval.

This is

Error Handling and Recovery
page 12.10

23 September 1983

PSL Manual
section 12.7

12.7. Some Convenient Error Calls
The following functions may be useful in user packages:

. (RangeError Object: any

Index: integer

Fn: function): None Returned

(StdError (BldMsg "Index %r out of range for %p in %p"
Index Object Fn»
(StdError Message:string): None Returned
(Error 99 Message)
(TypeError Offender:any Fn:function Typ:any): None Returned
(StdError (BldMsg "An attempt was made to do %p on %r,
which is not %w"
Fn Offender Typ»
(UsageTypeError Off:any Fn:function Typ:any Usage:any): None Returned
(StdError
(BldMsg "An attempt was made to use %r as %w in %p,
where %w is needed" Offender Usage Fn Typ»
(IndexError Offender: any Fn: func tion): None Returned
(UsageTypeError Offender Fn "an integer" "an index")
(NonPairError Offender:any Fn:function): None Returned
(TypeError Offender Fn "a pair")
(NonListError Offender:any Fn:function): None Returned
(TypeError Offender Fn "a list or NIL")
(NonIDError Offender:any Fn:function): None Returned
(TypeError Offender Fn "an identifier")

expr

PSL Manual
section 12.7

23 September 1983

Error Handling and Recovery
page 12.11

(NonNumberError Offender:any Fn:function): None Returned
(TypeError Offender Fn "a number fl )
(NonlntegerError Offender:any Fn:function): None Returned
(TypeError Offender Fn "an integer")
(NonPositivelntegerError Offender:any Fn:function): None Returned
(TypeError Offender Fn "a non-negative integer")
(NonCharacterError Offender:any Fn:function): None Returned
(TypeError Offender Fn "a character")
(NonStringError Offender:any Fn:function): None Returned
(TypeError Offender Fn "a string tt )
(NonVectorError Offender:any Fn:function): None Returned
(TypeError Offender Fn "a vector")
(NonWordsError Offender:any Fn:function): None Returned
(TypeError Offender Fn "a words vector")
(NonSequenceError Offender:any Fn:function): None Returned
(TypeError Offender Fn "a sequence tt )

PSL MANUAL
SECTION 13.0

23 SEPTEMBER 1983

DEBUGGING TOOLS
PAGE 13.1

CHAPTER 13
DEBUGGING TOOLS
13.1. Introduction . . .
13.1. L Brief Summary of Full Debug Package.
13.1.2. Redefining of User Functions by Debug
13.1.3. A Few Known Deficiencies
13.2. Step . . . . . . . . . . .
13.3. Tracing Function Execution.
13.3.1. Tracing Functions . .
13.3.2. Saving Trace Output.
13.3.3. Making Tracing More Selective
13.3.4. Turning Off Tracing . . . . .
13.4. A Break Facility . . . . . . . . . .
13.5. Enabling Debug Facilities and Automatic Tracing and Breaking.
13.6. A Heavy Handed Backtrace Facility
13.7. Embedded Functions. . . . .
13.8. Counting Function Invocations . .
13.9. Stubs. . . . . . . . . . . . . .
13.10. Functions for Printing Useful Information.
13.11. Printing Circular and Shared Structures.
13.12. Internals and Customization.

. . . . . .

13.12.1. User Hooks. . . . . . . . . . . .
13.12.2. Functions Used for Printing/Reading
13.13. Example . . . . . . . . . . . . . . . .

13.1
13.1
13.2
13.3
13.3
13.4
13.4
13.6
13.7
13.9
13.10
13.11
13.12
13.12
13.13
13.14
13.14
13.15
13.16
13.16
13.17
13.18

13.1. Introduction
This chapter describes the debugging facilities available in PSL. Most of these are made
available by loading the module DEBUG.
loading STEP.

There is also a stepper made available by

It is described in Section 13.2.

An extensive example showing the use of

the facilities in the debugging package can be found in Section 13.13.

13.1.1. Brief Summary of Full Debug Package
The PSL debugging package contains a selection of functions that can be used to aid
program development and to investigate faulty programs.'
It contains the following facilities.

1Much of this chapter was adapted from a paper by Norman and Morrison.

23 September 1983

Debugging Tools
page 13.2

PSL Manual
section 13.1

*

A trace package. This allows the user to see the arguments passed to and
the values returned by selected functions. It is also possible to have traced
interpreted functions print all the assignments they make with SetQ (see
Section 13.3).

*

A break package. This allows the user to wrap a Break around functions.

*

A backtrace facility. - This allows one to see which of a set of selected
functions were active as an error occurred (see Section 13.6).

*

Embedded functions make it possible to do everything that the trace package
can do, and much more besides (see Section 13.7). This facility is available
only in RLISP.

*

Some primitive statistics gathering (see Section 13.8).

* Generation of simple stubs.

If invoked, procedures defined as stubs simply
print their argument and read a value to return (see Section 13.9).

* Some functions for printing useful information, such as property lists, in an
intelligible format (see Section 13.10).

* PrintX is a function that can print circular and re-entrant lists and vectors,
and so can sometimes allow debugging to proceed even in the face of severe
damage caused by the wild use of RplacA and RplacD (see Section 13.11).

13.1.2. Redefining of User Functions by Debug
Many facilities in Debug depend upon redefining user functions so that they may log or
print behavior when called.

Since several facilities may be active simultaneously for a

single user function, Debug redefines a function only the first time a facility is requested.
Information about which facility was requested is kept on a property list.

If a second

facility is requested for a function, that information is added to the property list.

When

the function is called, the property list is examined to see what activities should occur.

Turning off a specific Debug facility does not cause the function to have its original
definition restored. All that happens is that information about the facility is removed from
the property list.

To restore the original definition of the function use the Restr macro

described in Section 13.3.4.

23 September 1983

PSL Manual
section 13.1

Debugging Tools
page 13.3

13.1.3. A Few Known Deficiencies

*

An attempt to trace certain system functions (e.g. Cons) causes the trace
package to overwrite itself. Given the names. of functions that cause this sort
of trouble it is fairly easy to'changethe trace. package to deal gracefully with
them. The global BreakDebugList ! contains the names of functions known
to cause trouble. Report any other functions causing trouble to a system
expert or send mail to PSL -BUGS.

*

*

The Portable LISP Compiler uses information about registers which certain
system functions destroy.
Tracing these functions may make the
optimizations based thereon invalid. The correct way of handling this problem
is currently under consideration. In the mean time you should avoid tracing
any functions with the ONEREG or TWOREG flags.

13.2. Step
(step F: form): any

expr

step is a loadable option (LOAD STEP).
stepping.
expansions.

E

is

printed,

preceded

After evaluation,

the result of evaluation.

E is

by

It evaluates the form
->

on

entry,

<->

E,

single-

for

macro

printed preceded by < - and followed by

A single character is read at each step to

determine the action to be taken:
 (Next)
Step to the Next thing. The stepper continues until the next
thing to print out, and it accepts another command.
Space

Go to the next thing at this level. In other words, continue to
evaluate at this level, but don't step anything at lower levels.
This is a good way to skip over parts of the evaluation that
don't interest you.

< Ctrl-U > (Up)
Continue evaluating until we go up one level. This is like the
space command, only more so; it skips over anything on the
current level as well as lower levels.
 (eXit)
Exit; finish evaluating without any more stepping.
 or  (Grind)
Grind (Le., prettyprint) the current form.

23 September 1983

Debugging Tools
page 13.4


PSL Manual
section 13.2

Grind the form in Rlisp syntax.

< Ctrl-E > (Editor)
Invoke the structure editor on the current form.
< Ctrl-B > (Break)
Enter a break loop from which you can examine the values of
variables and other aspects of the current environment.
< Ctrl-L>

Redisplay the last 10 pending forms.

?

Display the help file.

To step through the evaluation of function H on argument ~ do

(step

f

(H X»

13.3. Tracing Function Execution

13.3.1. Tracing Functions
To see when a function gets called, what arguments it is given and what value it
returns, do

(TR functionname)
or if several functions are of interest,

(TR name1 name2 ••• )
(Tr [FNAME: id)):

macro

Undefined

If the specified functions are defined (as expr, fexpr, nexpr or macro), Tr
modifies the function definition to include print statements.
arguments are not quoted.

The following example shows the style of

output produced by this sort of tracing:

The input...

Note that the

PSL Manual
section 13.3

23 September 1983

Debugging Tools
page 13.5

(DE XCDR (A)
(CDR A) %A very simple function)
(TR XCDR)
(XCDR '( P Q R»
gives output ...
XCDR entered
A: (P Q R)
XCDR
(Q R)

=

Interpreted functions can also be traced at a deeper level.
(Trst [FNAME: id]): Undefined

macro

(TRST name1 name2 ••• )
causes the body of an interpreted function to be redefined so that all
assignments (made with SetQ) in its b'ody are printed.

Calling Trst on a

function automatically has the effect of doing a Tr on it too, so that it is
not possible to have a function subject to Trst but not Tr.
One can use the Trst facility to cause only assignments to variables specified in a
function to be printed instead of all of them.
(TrstSome FNAME: id [VARS: id]): Undefined

macro

(TrstSome fname varl var2 ••• )
Give the function name first and then the variables.
Trace output often appears mixed up with output from the program being studied, and
to avoid too much confusion Tr arranges to preserve the column in which printing was
taking place across any output that it generates.

If trace output is produced as part of a

line has been printed, the trace data are enclosed in markers ' <' and ' >

'f

and these

symbols are placed on the line so as to mark out the amount of printing that had
occurred before trace was entered.

PSL Manual
section 13.3

23 September 1983

Debugging Tools
page 13.6

switch

!*PrintNoArgs [Initially: NIL]
If !*PrintNoArgs is T, printing of the arguments of traced or broken
functions is suppressed.

global

TracedFns! * [Initially: NIL]
TracedFns!* contains the names of all functions currently being traced.

13.3.2. Saving Trace Output
The trace facility makes it possible to discover in some detail how a function is used,
but in certain cases its direct use results in the generation of vast amounts of (mostly
useless) print-out. There are several options. One is to make tracing more selective (see
Section 13.3.3).

The other, discussed here, is to either print only the most recent

information, or dump it all to a file to be perused at leisure.

Debug has a ring buffer in which it saves information to reproduce the most recent
information printed by the trace facility (both Tr and Trst).

To see the contents of this

buffer use Tr without any arguments
(TR)

(NewTrBuff N: integer): Undefined
To set the number of entries retained to n use
(NEWTRBUFF n)
Initially the number of entries in the ring buffer is 5.
!*TRACE [Initially: T]

switch

Enables runtime printing of trace information for functions which have been
traced.
Turning off the TRACE switch

(OFF

TRACE)

suppresses the printing of any trace information at run time; it is still saved in the ring
.. buffer.

Thus a useful· technique for isolating the function in which an error occurs is to

PSL Manual
section 13.3

23 September 1983

Debugging Tools
page 13.7

trace a large number of candidate functions, do OFF TRACE and after the failure look at
the latest trace information by calling Tr with no arguments.
(TrOut" [FNAME: id]): Undefined

(StdTrace ): Undefined
Normally trace information is directed to the standard output, rather than
the currently selected output. To send it elsewhere use the statement
(TROUT filename)
The statement
(STDTRACE)
closes that file and cause future trace output to be sent to the standard
output.

Note that output saved in the ring buffer is sent to the currently

selected output, not that selected by TrOut.

13.3.3. Making Tracing More Selective
One can specify a predicate when tracing a function so that tracing will be enabled only
when the predicate is true.

(TrWhen FNAME:id PREDICATE: form): Undefined

macro

Trace information for the function FNAME will be printed only if PREDICATE
is T. The variables in the predicate must be either globals or parameters of
the function.
(TrWhen foo (GreaterP x

y»

(TraceCount N: integer): Undefined
The function (TraceCount n) can be used to switch off trace output.

If n is

a positive number, after a call to (TraceCount n) the next n items of trace
output that are generated are not printed.
or zero switches all trace output back on.
residual

count,

suppressed.

i.e.,

the

number

of

(TraceCount n) with n negative
(TraceCount NIL) returns the

additional

trace

entries

that

are

PSL Manual
section 13.3

23 September 1983

Debugging Tools
page 13.8

To get detailed tracing in the stages of a calculation that lead up to an error, try
(TRACECOUNT 1000000) % or some other suitable large number
(TR ••• ) % as required
%run the failing problem
(TRACECOUNT NIL)
It is now possible to calculate how many trace entries occurred before the error, a-nd so
the problem can now be re-run with TraceCount set to some number slightly less than
that.

An alternative to the use of TraceCount for getting more selective trace output is Tr In.
macro

(Tr In [FNAME: id]): Undefined
To use TrIn, establish tracing for a collection of functions, using Tr in the
normal way.

Then do Tr In on some small collection of other functions.

The effect is just as for Tr, except that trace output is inhibited except if
control is dynamically within the Tr In functions.

This makes it possible to

use Tr on a number of heavily used general purpose functions, and then
only see the calls to them that occur within some specific subpart of your
entire program.
TRACEMINLEVEL! * [Initially: 0]

global

TRACEMAXLEVEL! * [Initially: 1000]

global

The global variables TRACEMINLEVEL! * and TRACEMAXLEVEL! * (whose values
should be non-negative integers) are the minimum and maximum depths of
recursion at which to print trace information.

Thus if you only want to see

top level calls of a highly recursive function (like a simple-minded version
of Length) simply do
(SETQ TRACEMAXLEVEL!* 1)

PSL Manual
section 13.3

23 September 1983

Debugging Tools
page 13.9

13.3.4. Turning Off Tracing
If a particular function no longer needs tracing, do
--(UNTR functionname)
or
(UNTR name1 name2 ••• )
(UnTr [FNAME: id]): Undefined

macro

This merely suppresses generation of trace output.

Other information, such

as invocation counts, backtrace information, and the number of arguments
is retained.
To completely destroy information about a function use
(RESTR name1 name2 ••• )
(Restr [FNAME: id]): Undefined

macro

This returns the functions specified to their original state.

If no arguments

are given, all functions will be returned to their original state.
To suppress traceset output without suppressing normal trace output use
(UNTRST name1 name2 ••• )
(UnTrst [FNAME: id]): Undefined

macro

UnTring a Trsted function also UnTrst's it.

TrIn in Section 13.3.3 is undone by UnTr (but not by UnTrst).
(UnTrAll ): Undefined
The function

expr
UnTrAll

untraces

functions on the list TracedFns !*.

all

functions

currently

traced,

i.e.,

all

Debugging Tools
page 13.10

PSL Manual
section 13.4

23 September 1983

13.4. A Break Facility
A break facility exists in Debug that allows one to wrap a Break around a function,

causing a Break to occur both before and after execution of the function.

Variants on the

break function similar to those available for the trace function are available.

(Br [FNAME: id]): Undefined

macro

Br causes a Break to be placed around each of the functions listed.

A

Break occurs both before and after the execution of each broken function.
Give a c command to the Break to continue before execution and an r
command to continue· after execution.
macro

(Brln [FNAME: id]): Undefined
Brln is used in the same way as Trln, to cause breaking of a broken
function only within the functions specified.

Note that if a function specified by Br In terminates abnormally, the Br In facility may
not work properly. To fix it, call Brln with no arguments.
macro

(BrWhen FNAME:id PREDICATE: form): Undefined
One can specify a predicate when breaking around a function so that
Breaks will be enabled only when the predicate is true.

This works exactly

as the macro TrWhen.
BrokenFns!* [Initially: NIL]

global

BrokenFns! * contains the names of all functions currently broken.
Note that the switch ! *PrintNoArgs is also used by the break facility.

(UnBr [FNAME: id]): Undefined
UnBr causes breaking to be disabled for the functions specified.

(UnBrAll ): Undefined
Unbreaks all functions that are currently broken, i.e., all functions on the list
BrokenFns ! *.

macro

PSL Manual
section 13.5

23 September 1983

Debugging Tools
page 13.11

13.5. Enabling Debug Facilities and Automatic Tracing and Breaking
Under the influence of
(ON TRACEALL)
any functions successfully defined by PutD are traced.

Note that if PutD fails (as might

happen under the influence of the LOSE flag) no attempt is made to trace the function.
(ON BREAKALL)

causes any functions successfully defined by PutD to be broken.

To enable those facilities (such as Btr in Section 13.6 and TrCount in Section 13.8)
which require redefinition, but without tracing, use
(ON INSTALL)

Thus, a common scenario might look like
(ON INSTALL)
(DSKIN "MYFNS.SLtf)
(OFF INSTALL)
which would enable the backtrace and statistics routines to work with all the functions
defined in the MYFNS file.

!*INSTALL [Initially: NIL]

switch

Causes DEBUG to know about all functions defined with PutD.
!*TRACEALL [Initially: NIL]

switch

Causes all functions defined with PutD to be traced.
!*BreakAll [Initially: NIL]
Causes all functions defined with PutD to be broken.

switch

PSL Manual
section 13.6

23 September 1983

Debugging Tools
page 13.12

13.6. A Heavv Handed Backtrace Facilitv
The backtrace facility allows one to see which of a set of selected functions were active
as an error occurred.

The function Btr gives the backtrace information.

. kept is controlled by two switches:

The information

! *BTR and ! *BTRSAVE.

When backtracing is enabled (BTR is on), a stack is kept of functions entered but not
left.
with.

This stack records the names of functions and the arguments that they were called
If a function returns normally the stack is unwound.

If however the function fails,

the stack is left alone by the normal LISP error recovery processes.

macro

(Btr [FNAME: id1}: Undefined
When

called

available.

with

no

arguments,

Btr

prints the

backtrace

information

When called with arguments (which should be function names),

the stack is reset to Nil, and the functions named are added to the list of
functions Debug knows about.

(ResBtr [FNAME: id]): Undefined
ResBtr resets the backtrace stack to Nil.

switch

!*BTR [Initially: T]
If !*BTR is T, it enables backtracing of functions which the Debug package
has been told about. If it is Nil, backtrace information is not saved.

switch

!*BTRSAVE [Initially: T]
Controls the disposition of information about functions which failed within
an ErrorSet.

If it is on, the information is saved separately and printed

when the stack is printed. If it is off, the information is thrown away.

13.7. Embedded Functions
Embedding means redefining a function in terms of its old definition, usually with the
intent that the new version does some tests or printing, uses the old one, does some
more printing and then returns.
using a statement of the form:

If ff is a function of two arguments, it can be embedded

PSL Manual
section 13.7

23 September 1983

. Debugging Tools
page 13.13

SYMBOLIC EMB PROCEDURE ff(A1,A2);
« PRINT A1;
PRINT A2;
PRINT ff(A1,A2) »;
The effect- of this particular use of embed is· broadly similar to a call Tr ff, and arranges
that whenever ff is called it prints both its arguments and its result.

After a function has

been embedded, the embedding can be temporarily removed by the use of

UNEMBED ffj
and it can be reinstated by

EMBED ffj
This facility is available only to RLISP users.

13.8. Counting Function Invocations

!*TRCOUNT

[Initially: T]

Enables counting invocations of functions known to Debug.

switch
If the switch

TRCOUNT is ON, the number of times user functions known to Debug are
entered is counted. The statement

(ON TRCOONT)
also resets that count to zero. The statement

(OFF TRCOUNT)
causes a simple histogram of function invocations to be printed.
If regular tracing (provided by Tr) is not desired, but you wish to count the function
invocations, use

(TRCNT name1 name2 ••• )

Debugging Tools
page 13.14

PSL Manual
section 13.8

23 September 1983

macro

(Trent [FNAME: id]): Undefined
See also Section 13.5.

- 13.9. Stubs
Stubs are useful in top-down program development.

If a stub is invoked, it prints its

arguments and asks for a value to return.

(Stub [Funclnvoke: form]):

macro

Each FUNCINVOKE must be of the form (id arg 1 arg2 ... ), where there may
be zero arguments.

Stub defines an expr for each form with name id and

formal arguments arg 1, arg2, etc.

If executed such a stub prints its

arguments and reads a value to return.
The statement
(STUB (FOO U

V»

defines an expr, Faa, of two arguments.
(FStub [Funclnvoke: form]): Nil

macro

FStub does the same as Stub but defines fexprs.
At present the currently (Le., when the stub is executed) selected input and output are
'used.

This may be changed in the future.

Algebraic and possibly macro stubs may be

implemented in the future.

13.10. Functions for Printing Useful Information
(PList [X: id]):
(PLIST id1 id2 ••• )
prints the property lists of the specified ids in an easily readable form.

macro

PSL Manual
section 13.10

23 September 1983

Debugging Tools
page 13.15

(Ppf [FNAME: id]):

macro

(PPF fn1 fn2 ••• )
prints . the definitions and other. useful information about the specified
functions.

13.11. Printing Circular and Shared Structures
Some LISP programs rely on parts of their data structures being shared, so that an Eq
test can be used rather than the more expensive Equal one.

Other programs (either

deliberately or by accident) construct circular lists through the use of RplacA or RplacD.
Such lists can be displayed by use of the function PrintX.

This function also prints

circular vectors.

(PrintX A :any): NIL
If given a normal list the behavior of this function is similar to that of

Print; if it is given a looped or re-entrant data structures it prints it in a
special format. The representation used by PrintX for re-entrant structures
is based on the idea of labels for those nodes in the structure that are
referred to more than once.
Consider the list created by the operations:

(SETQ R t (S W»
(RPLACA R (CDR R»
The function Print called on the list

B gives

«W) W)
If PrintX is called on the list fi, it discovers that the list (W) is referred to twice, and
invents the label %L 1 for it. The structure is then printed as
(~L 1:

( W) • %L 1 )

%L 1: sets the label, and the other instance of %L 1 refers back to it.
appear anywhere within the list being printed.
statements

Labeled sublists can

Thus the list created by the following

PSL Manual
section 13.11

23 September 1983

Debugging Tools
page 13.16
(SETQ L '(A B C»
(SETQ K (CDR L»
(SETQ X (CONS L K»
which is printed as

«A B C) B C)
by Print could be printed by PrintX as

«A %L1, B C) • %L1)
A label set with a comma (rather than a colon) is a label for part of a list, not for the
sublist.

PrintX uses the globals PrinLevel and PrinLength to control the number of levels of
an object that get printed and the number of items of a list or vector that get printed,
respectively. See Chapter 10 for a fuller description.
switch

! *SAVENAMES [Initially: NIL]
If on, names assigned to substructures by PrintX are retained from one use
to the next.

Thus substructures common to different items will be shown

as the same.

13.12. Internals and Customization
This section describes some internal details of the debug package which may be useful
in customizing it for specific applications.

The reader is urged to consult the source for

further details.

13.12.1. User Hooks
These are all global variables whose values are normally NIL.

If non-NIL, they should

be exprs taking the number of variables specified, and are called as specified.
global

PUTDHOOK! * [Initially: NIL]
Takes one argument, the function name.
been

defined, and

any tracing

!*INSTALL has taken place.

It is called after the function has

under the

influence

of

! *TRACEALL or

It is not called if the function cannot be

PSL Manual
section 13. 12

23 September 1983

Debugging Tools
page 13.17

defined (as might happen if the function has been flagged LOSE).

TRACENTRYHOOK! * [Initially: NIL]
the~

: Takes two"arguments,

global
function name and a list of the actual arguments.

It is called by the trace package if a traced function is entered, but before it
is executed.

The execution of a surrounding EMS function takes place after

TRACENTRYHOOK! * is called: This is useful if you need to call special userprovided

print

routines

to

display

critical

data

structures,

as

are

TRACEXITHOOK!* and TRACEXPANDHOOK!*.
TRACEXITHOOK!* [Initially: NIL]

global

Takes two arguments, the function name and the value.

It is called after

the function has been evaluated.

TRACEXPANDHOOK!* [Initially: NIL]

global

Takes two arguments, the function name and the macro expansion.

It is

only called for macros, and is called after the macro is expanded, but before
the expansion has been evaluated.

TRINSTALLHOOK!* [Initially: NIL]
Takes one argument, a function name.

global
It is called if a function is redefined

by the Debug package, as for example when it is first traced.

It is called

before the redefinition takes place.

13.12.2. Functions Used for Printing/Reading
These should all contain EXPRS taking the specified number of arguments.

The initial

values are given in square brackets.

PPFPRINTER!* [Initially: PRINT]
Takes one argument.
function.

It is used by Ppf to print the body of an interpreted

global

23 September 1983

Debugging Tools
page 13.18

PSL Manual
section 13.12

PROPERTYPRINTER! * [Initially: PRETTYPRINT]

global

Takes one argument. It is used by PList to print the values of properties.

STUBPRINTER! * [Initially: PRINTX]

g~obal

Stubs defined with Stub/FStub use it to print their

Takes one argument.
arguments.

STUBREADER! * [Initially: !-REDREADER]

global

Stubs defined with Stub/FStub use it to read their

Takes no arguments.
return value.

TREXPRINTER!* [Initially: PRINT]

global

Takes one argument. It is used to print the expansions of traced macros.

TRPRINTER t * [Initially: PRINTX]
Takes one argument.

global

It is used to print the arguments and values of traced

functions.

TRSPACE! * [Initially: 0]

global

Controls indentation.

13.13. Example
This contrived example demonstrates many of the available features. It is a transcript of
an actual PSL session.

PSL Manual
section 13.13

23 September 1983

Debugging Tools
page 13.19

@PSL
PSL 3.1, 15-Nov-82
1 lisp> (LOAD DEBUG)
NIL
. -2 lisp> (DE FOO (N)
2 lisp> (PROG (A)
2 lisp>
(COND «AND (NEQ (REMAINDER N 2) 0) (LESSP NO»
2 lisp>
(SETQ A (CAR N»» %Should err out if N is a number
2 lisp>
(COND «EQUAL N 0) (RETURN 'BOTTOM»)
2 lisp>
(SETQ N (DIFFERENCE N 2»
2 lisp>
(SETQ A (BAR N»
2 lisp>
(SETQ N (DIFFERENCE N 2»
2 lisp>
(RETURN (LIST A (BAR N) A»»
FOO
3 lisp> (DE FOOBAR (N)
3 lisp> (PROGN (FOO N) NIL»
FOOBAR
4 lisp> (TR FOO FOOBAR)
(FOO FOOBAR)
5 lisp> (PPF FOOBAR FOO)
EXPR procedure FOOBAR(N) [TRACEDjInvoked 0 times):
PROGN
(FOO N)
NIL
EXPR procedure FOO(N) [TRACEDjInvoked 0 times]:
PROG
(A)

(COND «AND (NEQ (REMAINDER N 2) 0) (LESSP NO»
(COND «EQUAL N 0) (RETURN 'BOTTOM»)
(SETQ N (DIFFERENCE N 2»
(SETQ A (BAR N»
(SETQ N (DIFFERENCE N 2»
(RETURN (LIST A (BAR N) A»

(SETQ A (CAR N»»

(FOOBAR FOO)
6 lisp> (ON COMP)
NIL
7 lisp> (DE BAR (N)
7 lisp> (COND «EQUAL (REMAINDER N 2) 0) (FOO (TIMES 2 (QUOTIENT N 4»»
7 lisp>
(T (FOO (SUB1 (TIMES 2 (QUOTIENT N 4»»»)
*** (BAR): base 275266, length 21 words
BAR

23 September 1983

Debugging Tools
page 13.20

PSL Manual
section 13.13

8 lisp> (OFF COMP)
NIL
9 lisp> (FOOBAR 8)
FOOBAR being entered
N:

8

FOO being entered
N: 8
FOO (level 2) being entered
N:

2

Faa (level 3) being entered
N:
0
Faa (level 3) = BOTTOM
FOO (level 3) being entered
N:
0
FOO (level 3) = BOTTOM
FOO (level 2) = (BOTTOM BOTTOM BOTTOM)
FOO (level 2) being entered
N:

2

FOO (level 3) being entered
N:

0

FOO (level 3) = BOTTOM
FOO (level 3) being entered
N:
0
FOO (level 3) = BOTTOM
FOO (level 2) = (BOTTOM BOTTOM BOTTOM)
FOO = (%L1: (BOTTOM BOTTOM BOTTOM) (BOTTOM BOTTOM BOTTOM)
%L 1)

FOOBAR = NIL
NIL
10 lisp> %Notice how in the above PRINTX printed the return values
10 lisp> %to show shared structure
10 lisp> (TRST FOO)
(FOO)
11 lisp> (FOOBAR 8)
FOOBAR being entered
N:
8
FOO being entered
N: 8
N :=

6

FOO (level 2) being entered
N:

2

N := 0

FOO (level 3) being entered
N:
0
FOO (level 3) = BOTTOM
A := BOTTOM

PSL Manual
section 13.13

23 September 1983

N := -2
FOO (level 3) being entered
N:
0
FOO (level 3) = BOTTOM
FOO (level- 2) = (BOTTOM BOTTOM BOTTOM)
A := (BOTTOM BOTTOM BOTTOM)
N := 4
FOO (level 2) being entered
N:
N := 0

2

FOO (level 3) being entered
N:
0
FOO (level 3) = BOTTOM
A := BOTTOM
N := -2

FOO (level 3) being entered
N:

0

FOO (level 3) = BOTTOM
FOO (level 2) = (BOTTOM BOTTOM BOTTOM)
FOO = (%L1: (BOTTOM BOTTOM BOTTOM) (BOTTOM BOTTOM BOTTOM)
%L 1)
FOOBAR = NIL
NIL
12 lisp> (TR BAR)
(BAR)
13 lisp> (FOOBAR 8)
FOOBAR being entered
N:
8
FOO being entered
N: 8
BAR being entered
A1:
6
FOO (level 2) being entered
N:
2
BAR (level 2) being entered
A1:

0

FOO (level 3) being entered
N: 0

FOO (level 3) = BOTTOM
BAR (level 2) = BOTTOM
BAR (level 2) being entered
A1:

-2

FOO (level 3) being entered
N: 0
FOO (level 3) = BOTTOM
BAR (level 2) = BOTTOM

Debugging Tools
page 13.21

23 September 1983

Debugging Tools
page 13.22

PSL Manual
section 13.13

FOO (level 2) = (BOTTOM BOTTOM BOTTOM)
BAR = (BOTTOM BOTTOM BOTTOM)
BAR being entered
A1:
4
FOO (level 2) being entered
N:

2

BAR (level 2) being entered
A 1:

0

FOO (level 3) being entered
N: 0

FOO (level 3) = BOTTOM
BAR (level 2) = BOTTOM
BAR (level 2) being entered
A1:

-2

FOO (level 3) being entered
N: 0
FOO (level 3) = BOTTOM
BAR (level 2) = BOTTOM
FOO (level 2) = (BOTTOM BOTTOM BOTTOM)
BAR = (BOTTOM BOTTOM BOTTOM)
FOO = (%L1: (BOTTOM BOTTOM BOTTOM) (BOTTOM BOTTOM BOTTOM)
%L 1)
FOOBAR = NIL
NIL
14 lisp> (OFF TRACE)
NIL
15 lisp> (FOOBAR 8)
NIL
16 lisp> (TR)
*** Start of saved trace information ***
BAR (level 2) = BOTTOM
FOO (level 2) = (BOTTOM BOTTOM BOTTOM)
BAR = (BOTTOM BOTTOM BOTTOM)
FOO = (%L1: (BOTTOM BOTTOM BOTTOM) (BOTTOM BOTTOM BOTTOM)
%L 1)
FOOBAR = NIL
*** End of saved trace information ***
NIL
17 lisp> (FOOBAR 13)
***** An attempt was made to do CAR on '-1', which is not a pair
Break loop
18 lisp break» Q
19 lisp> (TR)
*** Start of saved trace information ***
FOO being entered
N: 13

PSL Manual
section 13.13

23 September 1983

BAR being entered
A1:
11
FOO (level 2) being entered
N:
3
BAR (level 2) being entered
A1 :

1

FOO (level 3) being entered
N: -1

*** End of saved trace information ***
NIL
20

lisp> (BTR)

*** Backtrace: ***
These functions were left abnormally:
FOO
N: -1

BAR
A1 :

FOO
N:

3

BAR
A1:

11

FOO
N: 13

FOOBAR
N: 13

*** End of back trace ***
NIL
21 lisp> (STUB (FOO N»
*** Function 'FOO' has been redefined
NIL
22 lisp> (FOOBAR 13)
Stub FOO called
N: 13

Return?
22 lisp> (BAR (DIFFERENCE N 2»
Stub FOO called

3
Return?
22 lisp> (BAR (DIFFERENCE N 2»
Stub FOO called

N:

N: -1

Return?
22 lisp>· 'ERROR

Debugging Tools
page 13.23

23 September 1983

Debugging Tools
page 13.24

NIL
23 lisp> (TR)
*** Start of saved trace information
BAR being entered
A1:
11
BAR (level 2) being entered
A1:

NIL
22 lisp> (QUIT)

***

1

BAR (level 2) = ERROR
BAR = ERROR
FOOBAR = NIL
*** End of saved trace information
NIL
24 lisp> (OFF TRCOUNT)
FOOBAR(6)
BAR(16)

PSL Manual
section 13.13

***

******************
*******************************************************

PSL MANUAL
SECTION 14.0

23 SEPTEMBER 1983AISCELLANEOUS USEFUL FEATURES
PAGE 14.1

CHAPTER 14
MISCELLANEOUS USEFUL FEATURES
14.1.· The' HELP .'Mechanism. . .
14.2. Exiting PSL . . . . . . .
14.3. Saving an Executable PSL.
14.4. Init Files. . . . . . . .
14.5. Miscellaneous Functions
14.6. Garbage Collection. . .

14.1
14.1
14.2
14.3
14.4
14.4

14.1. The HELP Mechanism
{Help [TOPICS: idl}: NIL
If no arguments are given, a message describing Help itself and known
topics is printed.

Otherwise, each of the id arguments is checked to see if

any help information is available.

If it has a value under the property list

indicator HelpFunction, that function is called.
indicator HelpString, the value is printed.

If it has a value under the
If it has a value under the

indicator HelpFile, the file is displayed on the terminal. By default, a file
called "topic.HLP" on the logical device, "PH:" is looked for, and printed if
found.

Help also prints out the values of the Top Loop fluidS, and finally searches
the current Id-Hash-Table for loaded modules.

Helpln!

* [Initially: NIL]

global

The channel used for input by the Help mechanism.

HelpOut!

* [Initially:

NIL]

global

The channel used for output by the Help mechanism.

14.2. Exiting PSL
The normal way to suspend PSL execution is to call the Qui t function or to strike
 on the DEC-20 or  on the VAX.

PSL Manual
section 14.2

23 September 1983

Miscellaneous Useful Features
page 14.2
(Qui t ): Undefined

expr

Return from LISP to superior process.

If the operating system permits a

choice, QUIT is a continuable exit, and EXITLISP is a permanent exit (that
terminates the PSL process).

(ExitLisp ): Undefined

expr

Return from LISP to superior process.

If the operating system permits a

choice, QUIT is a continuable exit, and EXITLISP is a permanent exit (that
terminates the PSL process).

14.3. Saving an Executable PSL
(SaveSystem MSG:string FILE:string FORMS:form-list): Undefined
This records the welcome message (after attaching a date) in the global
variable LispBanner!

* used

by StandardLisp's call on TopLoop, and then

calls DumpLisp to compact the core image and write it out as a machine
dependent executable file with the name FILE.

FILE should have the

appropriate

SaveSystem

Usermode !

extension

for

an

executable

file.

also

sets

* to T.

The forms in the list FORMS will be evaluated when the new core image is
started.

For example

(SaveSystem "PSL 3.1" "PSL.EXE" 'CCRead-Init-File "PSL")
Clnitializelnterrupts»)

If RLISP has been loaded, SaveSystem will have been redefined to save the
message in the global variable date !*, and redefine Main to call RlispMain,
which uses date!

* in

Begin 1.

The older SaveSystem will be saved as the

function LispSaveSystem.

LispBanner!

* [Initially: ]

Records the welcome message given by a call to SaveSystem from PSL.
Also contains the date, given by the function Date.

global

PSL Manual
section 14.3
Date!

23 September 1983

Miscellaneous Useful Features
page 14.3

* [Initially: Nil]

global

Records the welcome message given by a call to SaveSystem from RLiSP.
(DumpLisp FILE: string):-Undefined
This calls Reclaim to compact the heap, and unmaps the unused pages
(DEC-20) or moves various segment pointers (VAX) to decrease the core
image.

The core image is then written as an executable file, with the name

14.4. Init Files
Init files are available to make it easier for the user to customize PSL to his/her own
needs.

When PSL, RLlSP, or PSLCOMP is executed, if a file PSL.INIT, RLlSP.INIT, or

PSLCOMP.lNIT (.pslrc, rlisprc, or .pslcomprc on the VAX) is on the home directory, it will
be read and evaluated.

Currently all init files must be written in LISP syntax.

They may

use FASLIN or LOAD as needed.

The following functions are used to implement init files, and can be accessed by
LOADing the INIT -FILE module.

(User-HomeDir-String ): string
Returns a full path name for the user's home directory.

(Init-File-String PROGRAMNAME:string): string
Returns

the

full

pathname

of

the

user's

init

file

for

the

program

PROGRAMNAME.
(Init-File-String

"PSLtt)

(Read-Init-File PROGRAMNAME:string): Nil
Reads and evaluates the init file with name PROGRAM NAME.
File calls Ini t-File-String with argument PROGRAMNAME.
(Read-Init-File ttPSLtt)

expr
Read-Init-

PSL Manual
section 14.5

23 September 1983

Miscellaneous Useful Features
page 14.4

14.5. Miscellaneous Functions
(Reset ): Undefined
".,,: Return to top level of. LISP.

Similar to < Ctrl-C > and Start on the DEC-20,

but with the reset function, unwind-protect forms get a chance to run.

(Time ): integer
CPU time in milliseconds since login time.

(Date ): string
The date in the form 16-Dec-82.

14.6. Garbage Collection
(Reclaim ): Undefined

expr

Reclaim is the user level call to the garbage collector.

Internal system

functions always use ! %Reclaim.

(! %Reclaim ): Undefined

!%Reclaim is is used within the system to call the garbage collector.
Active data in the heap is made contiguous and aU tagged pointers into the
heap from active local stack frames, the binding stack and the symbol table
are relocated. If! *GC is T, prints some statistics. Increments GeKNT! *.

! *Ge [Initially: NIL]

switch

! *Ge controls the printing of garbage collector messages.
indication

of

garbage

collection

occurs.

If

non-NIL

If NIL, no

various

system

dependent messages may be displayed.

GCTime! * [Initially: ]
Time spent in garbage collection. Cumulative (but starting from when?).

global

PSL Manual
section 14.6

23 September 1983

Miscellaneous Useful Features
page 14.5

GCKNT!* [Initially: 0]
Records the number of times that Reclaim has been called to this point.
GCKNT!* may be reset to another value to record counts incrementally, as
desired.

global

PSL MANUAL
SECTION 15.0

23 SEPTEMBER 1983

COMPILER
PAGE 15.1

CHAPTER 15
COMPILER
15.1. Introduction. . . . .
15.2. The Compiler . . . .
15.2.1. Compiling Files
15.2.2. Compiling Functions into FASL Files.
15.2.3. Compiling Functions into Memory.
15.2.4. Fluid and Global Declarations. . . .
15.2.5. Conditional Compilation . . . ... .
15.2.6. Functions to Control the Time When Something is Done
15.2.7. Order of Functions for Compilation . . . . . . . .
15.2.8. Switches Controlling Compiler . . . . . . . . . .
15.2.9. Differences between Compiled and Interpreted Code
15.2.10. Compiler Errors.. . . . . . . . . . . . . . . .

15.1
15.1
15.1
15.2
15.3
15.3
15.4
15.5
15.6
15.6
15.8
15.9

15.1. Introduction
The functions and facilities in the PSL L1SP/SYSLISP compiler and supporting loaders
(LAP and FASL) are described in this chapter.

15.2. The Compiler
The compiler is a version of the Portable LISP Compiler [Griss 81], modified and
extended 1 to more efficiently support both LISP and SYSLISP compilation.

See the later

sections in this chapter and references [Griss 81] and [Benson 81] for more details.

15.2.1. Compiling Files
On some computer systems it is possible to compile a file by invoking PSLCOMP with a
command line argument specifying the name of the file to be compiled.

The Compile-

File function is executed; see immediately below for a description of its behavior.

When

PSLCOMP is invoked with a command line argument, no break loop is entered in case of
error, but the error message is printed along with a warning from the compiler and the
compilation aborts.

1Many of the recent extensions to the PLC were implemented by John Peterson.

PSL Manual
section 15.2

23 September 1983

Compiler
page 15.2

(Compile-File FILE:string): undefined
Load com pi-extra to get this function .

. Compiles a single
written

with

compile-file.

the

file~

producing a .B file of the same name.

same

directory

specification

as

in

The.B file is

the

argument to

If you supply no suffix to compile-file, it will search for a

source file with the name you specified and with one of the suffixes
".BUILD", ".SL", or ".RED", in that order.

The compile-file function assumes

that files with ".BUILD" or ".RED" suffix are in RLiSP syntax.

If the filename

is given with a "random" extension, syntax is assumed to be LISP.

The conservative approach is to supply the suffix explicitly.

This avoids

some technical pitfalls related to "long" filenames that an operating system
may truncate.

15.2.2. Compiling Functions into FASL Files
In order to produce files that may be input using Load or FaslIn, the FaslOut and
FaslEnd pair may be used .

.

(FaslOut FILE:string): NIL
(FaslEnd ): NIL
After the command FaslOut has been given, all subsequent S-expressions
and function definitions typed in or input from Jiles are processed by the
Compiler, LAP and FASL as needed, and output to FILE.

Functions are

compiled and partially assembled, and output as in a compressed binary
form, involving blocks of code and relocation bits.

This activity continues

until the function FaslEnd terminates this process.

Note that a fib" file

extension is automatically appended to the output file.
The FaslOut and FaslEnd pair also use the DFPRINT!* mechanism, turning on the
switch !*DEFN, and redefining DFPRINT!* to trap the parsed input in the RLiSP top-loop.
Currently this is not usable from pure LISP level.

[??? Fix, by adding !*DEFN mechanism to basic top-loop. ???]

PSL Manual
section 15.2

23 September 1983

Compiler
page 15.3

15.2.3. Compiling Functions into Memory
Functions can be compiled directly into memory using a loaded interpretive definition.

! *COMP [Initially: NIL]

switch

If the c"ompiler is loaded (which is usually the case, otherwise load the
COMPILER module), turning on the switch ! *COMP causes all subsequent
procedure definitions of appropriate type to be compiled automatically and
a message of the form

 COMPILED,  WORDS,  LEFT
to be printed.

The first number is the number of words of binary program

space the compiled function took, and the second number the number of
words left unused in binary program space.
Currently, exprs, fexprs, nexprs and macros may be compiled.

This is controlled by a

flag {t COMPILE} on the property list of the procedure type.

If desired, uncompiled functions already resident may be compiled by using

(Compile NAMES: id-list): any
Compiling into memory can be particularly useful as a way of checking the efficiency
(and correctness) of code generated by the compiler.

The switches !*PLAP and !*PGWD

control printing of the LAP (assembly) code generated by the compiler.

See their

documentation for details.

15.2.4. Fluid and Global Declarations
The FLUID and GLOBAL declarations must be used to indicate variables that are to be
used as non-LOCALs in compiled code.
in a particular procedure to LOCAL.

Currently, the compiler defaults variables bound

The effect of this is that the variable only exists as

an "anonymous" stack location; its name is compiled away and called routines cannot see
it (Le., they would

have to use the

name).

Undeclared

automatically declared FLUID by the compiler with a warning.

non-LOCAL variables

are

In many cases, this means

that a previous procedure that bound this variable should have known about this as a
"FLUID.

Declare

automatically fixed.

it

with

FLUID,

below,

and

recompile,

since the

caller cannot

be

Compiler
page 15.4

PSL Manual
section 15.2

23 September 1983

[??? Should we provide an !*AIIFluid switch to make the default Fluid, or should we
make Interpreter have a LOCAL variable as default, or both ???]

--- . DeClaring a variable to be FLUID or GLOBAL causes the-variable to be initialized at the
point of declaration with the value NIL unless it already has a value at that point.

(Fluid NAMES: id-list): any
Declares each variable FLUID (if not previously declared); this means that it
can be used as a Prog LOCAL, or as a parameter.

On entry to the

procedure, its current value is saved and a/l access is always to the VALUE
cell of the variable; on exit (or Throw or Error), the old values are restored.

(Global NAMES: id-list): any
Declares each variable GLOBAL (if not previously declared); this means that
it cannot be used as a LOCAL, or as a parameter.

Access is always to the

VALUE cell (SYMVAL) of the variable.

[??? Should we eliminate GLOBALs ???]

15.2.5. Conditional Compilation

-(If_System SYS-NAME:id, TRUE-CASE:any, FALSE-CASE:any): any
This is a compile-time conditional

macro for system-dependent code.

FALSE-CASE can be omitted and defaults to NIL.
member of the fluid variable System _List!*.
(Dec20 PDP10 Tops20 KL 10).

macro

SYS-NAME must be a

For the Dec-20, System _List!* is

For the VAX it is (VAX Unix VMUnix).

example of its use follows.

PROCEDURE MAIL();
IF_SYSTEM(TOPS20, RUNFORK ftSYS:MM.EXE",
IF_SYSTEM(UNIX, SYSTEM "lBIN/MAIL",
STDERROR "MAIL COMMAND NOT IMPLEMENTED"»;

An

PSL Manual
section 15.2

23 September 1983

Compiler
page 15.5

15.2.6. Functions to Control the Time When Something is Done
Which expressions are evaluated during compilation only, which output to the file for
load time evaluation, and which do both (such as macro definitions) can be controlled by
.. the properties

~EVAL

and ;'IGNOREon _certain ·function names, or the following functions.

(CommentOutCode U: form): NIL

macro

Comment out a single expression; use

<  >

to comment out a block of

code.
(CompileTime U: form): NIL
Evaluate the expression

!J.

at compile time only, such as defining auxiliary

smacros and macros that should not go into the file.

Certain functions have the flag 'IGNORE on their property lists to achieve
the same effect. E.g. FLAGr(LAPOUT LAPEND)/IGNORE) has been done.
(BothTimes U: form): U: form
Evaluate at compile and load time.

This is equivalent in effect to executing

Flagr(f1 f2)/EVAL) for certain functions.
(LoadTime U: form): U: form
Evaluate at load time only.

Should not even compile code, just pass direct

to file.

[??? EVAL and IGNORE are for compatibility, and enable the above sort of functions to
be easily written. The user should avoid EVAL and IGNORE flags, if possible ???]

15.2.7. Order of Functions for Compilation
Non-expr procedures must be defined before their use in a compiled function, since the
compiler treats the various function types differently.

Macros are expanded and then

compiled; the argument list of fexprs quoted; the arguments of nexprs are collected into a
single list.

Sometimes it is convenient to define a dummy version of the function of

appropriate type, to be redefined later.
of the function.

[??? Add such a declaration. ???]

This acts as an "External or Forward" declaration

Compiler
page 15.6

23 September 1983

PSL Manual
section 15.2

15.2.8. Switches Controlling Compiler
The compilation process is controlled by a number of switches, as well as the above
declarations and the

!*R2I

!*COMP

switch, of course.

[Initially: T]

switch

If T, causes recursion removal if possible, converting recursive calls on a
function into a jump to its start.

If this is not possible, it uses a faster call

to its own "internal" entry, rather than going via the Symbol Table function
cell.

The effect in both cases is that tracing this function does not show

the internal or eliminated recursive calls, nor the backtrace information.

! *NOLINKE [Initially: NIL]
If

T,

inhibits use of

switch

!*LINKE

cmacro.

would then immediately return.

If

NIL,

"exit" calls on functions that

For example, the calls on FOO(x) and FEE(X)

in

PROCEDURE DUM(X,Y);
IF X=Y THEN FOO(X) ELSE FEE(X+Y);
can be converted into direct JUMP's to FEE or FOO's entry point.
known as a "tail-recursive" call being converted to a jump.

This is

If this happens,

there is no indication of the call of DUM on the backtrace stack if FEE or
FOO cause an error.

! *ORD [Initially: NIL]

switch

If T, forces the compiler to compile arguments in Left-Right Order, even
though more optimal code can be generated.

[??? !*ORD currently has a bug, and may not be fixed for some time.
Thus do NOT depend on evaluation order in argument lists ???]

! *MODULE [Initially: NIL]

switch

Indicates block compilation (a future extension of this compiler).

When

implemented, even more function and variable names are "compiled away".
Technically the following switches are part of the loader.
. compiler and loader implementation also.

See the documentation of

PSL Manual
section 15.2

23 September 1983

Compiler
page 15.7

! *PLAP [Initially: NIL]

switch

If T, causes the printing of the portable cmacros produced by the the
compiler.

In LAP, causes LAP forms to printed before expansion.

Used

mainly to see output. of compiler before assembly.

! *PGWD [Initially: NIL]

switch

Causes LAP to print the actual DEC-20 mnemonics and corresponding
assembled instruction in octal, displaying OPCODE, REGISTER, INDIRECT,
INDEX and ADDRESS fields. Affects printing during compilation.

! *PCMAC [Initially: NIL]

switch

A combination of !*PLAP and !*PGWD.

! *PWRDS [Initially: T]

switch

Prints out the address and size of each compiled function.

15.2.9. Differences between Compiled and Interpreted Code
The following just re-iterates some of the points made above and in other sections of
the manual regarding the "obscure" differences that compilation introduces.

[??? This needs some careful work, and perhaps some effort to reduce the list of
differences ???]

In the process of compilation, many functions are open-coded, and hence cannot be
redefined or traced in the compiled code.
in the manual.

Such functions are noted to be OPEN-CODED

If called from compiled code, the call on an open-compiled function is

replaced by a series of online instructions.

Most of these functions have some sort of

indicator on their property lists: 'OPEN, 'ANYREG, 'CMACRO, 'COMPFN, etc.
SETQ, CAR, CDR, COND, WPLUS2, MAP functions, PROG, PROGN, etc.

For example:

Also note that some

functions are defined as macros, which convert to some other form (such as PROG),
which itself might compile open.

Some optimizations are performed that cause inaccessible or redundant code to be
removed, e.g. O*foo(x) could cause foo(x) not to be called.

Compiler
page 15.8

23 September 1983

PSL Manual
section 15.2

Unless variables are declared (or detected) to be Fluid or global, they are compiled as
local variables.
Binding Stack.

This causes their names to disappear, and so are not visible on the
Further more, these variables are NOT available to functions called in the

. dynamic. scope of the function containing their binding.

Since compiled calls on macros, fexprs and nexprs are different from the default exprs,
these functions must be declared (or defined) before compiling the code that uses them.
While fexprs and nexprs may subsequently be redefined (as new functions of the same
type), macros are executed by the compiler to get the replacement form, which is then
compiled.

The interpreter of course picks up the most recent definition of ANY function,

and so functions can switch type as well as body.

[??? If we expand macros at PUTD time, then this difference will go away. ???]
As noted above, the

!~:R2I, !~':NOLINKE

and !*MODULE switches cause certain functions to

call other functions (or themselves usually) by a faster route (JUMP or internal call).

This

means that the recursion or call may not be visible during tracing or backtrace.

15.2.10. Compiler Errors
A number of compiler errors are listed below with possible explanations of the error.
*** Function form converted to APPLY
This message indicates that the Car of a form is either
a. Non-atomic,
b. a local variable, or
c. a global or fluid variable.
The compiler converts (F Xl X2 ... ), where F is one of the above, to (APPLY F (LIST Xl X2

... )).

*** NAME already SYSLISP non-local
This indicates that NAME is either a WVAR or WARRAY in SYSLISP mode, but is being
used as a local variable in LISP mode. No special action is taken.
*** WVAR NAME used as local
This indicates that NAME is a WVAR, but is being used as a bound variable in SYSLISP
mode. The variable is treated as an an anonymous local variable within the scope of its
binding.

PSL Manual
section 15.2

***

23 September 1983

Co~piler

page 15.9

NAME already SYSLISP non-local

This indicates that a variable was previously declared as a SYSLISP WVAR or WARRA Y
and is now being used as a LISP fluid or global. No special action is taken.

***

NAME already LISP non-local

This indicates that a variable was previously declared as a LISP fluid or global and is now
being used as a SYSLISP WVAR or WARRAY.

***

No special action is taken.

Undefined symbol NAME in Syslisp, treated as WVAR

A variable was encountered in SYSLISP mode which is not local nor a WVAR or WARRA Y.
The compiler declares it a WVAR.

This is an error, all WVARs should be explicitly

declared.

***

NAME declared fluid

A variable was encountered in LISP mode which is not local nor a previously declared
fluid or global.

The compiler declares it fluid.

This is sometimes an error, if the variable

was used strictly locally in an earlier function definition, but was intended to be bound
non-locally. All fluids should be declared before being used.

PSL MANUAL
SECTION 16.0

23 SEPTEMBER 1983

BIBLIOGRAPHY
PAGE 16.1

CHAPTER 16
BIBLIOGRAPHY
The following books and articles either are directly referred to in the manual text, or will
.. - ··:··be helpful for supplementary reading.
[Allen 79]

Allen, J. R.
The Anatomy of LISP.
McGraw-Hili, New York, New York, 1979.

[Baker 78]

Baker, H. G.
Shallow Binding in LISP 1.5.
CACM 21(7):565, July, 1978.

[Benson 81]

Benson, E. and Griss, M. L
SYSLlSP: A Portable LISP Based Systems Implementation Language.
Utah Symbolic Computation Group Report UCP-81, University of Utah,
Department of Computer Science, February, 1981.

[Bobrow 76]

Bobrow, R. J.; Burton, R. R.; Jacobs, J. M.; and Lewis, D.
UCI LISP MANUAL (revised).
Online Manual RS:UCLSP.MAN, University of California, Irvine, ??, 1976.

(Charniak 80]

Charniak, E.; Riesbeck, C. K.; and McDermott, D. V.
Artificial Intelligence Programming.
Lawrence Erlbaum Associates, Hillsdale, New Jersey, 1980.

[Fitch 77]

Fitch, J. and Norman, A.
Implementing LISP in a High Level Language.
Software: Practise and Experience 7:713-xx, 1977.

[Foderaro 81]

Foderaro, J. K. and Sklower, K. L.
The Franz LISP Manual.
, 1981.

[Frick 78]

Frick, I. B.
Manual for Standard LISP on the DECSYSTEM 10 and 20.
Utah Symbolic Computation Group Technical Report TR-2, University
of Utah, Department of Computer Science, July, 1978.

[Griss 77a]

Griss, M. L
BIL: A Portable Implementation Language for LISP-Like Systems.
Utah Symbolic Computation Group Opnote No. 36, University of Utah,
Department of Computer Science, 1977.

[Griss 77b]

Griss, M. L. and Swanson, M. R.
MBALM/1700 : A Micro-coded LISP Machine for the Burroughs B 1726.
In Proceedings of Micro-10 ACM, pages 15. ACM, 1977.

Bibliography
page 16.2

23 September 1983

PSL Manual
section 16.0

[Griss 78a]

Griss, M. L. and Kessler, R. R.
REDUCE 1700: A Micro-coded Algebra System.
In Proceedings of The 11th Annual Microprogramming Workshop,
pages 130-138. IEEE, November, 1978.

[Griss 78b]

Griss, M. L.
MBALM/BIL: A Portable LISP Interpreter.
Utah Symbolic Computation Group Opnote No. 38, University of Utah,
Department of Computer Science, 1978.

[Griss 79a]

Griss, M. L.; Kessler, R. R.; and Maguire, G. Q. Jr.
TLiSP - A Portable LISP Implemented in P-code.
In Proceedings of EUROSAM 79, pages 490-502. ACM, June, 1979.

[Griss 79b]

Griss, M. L. and Kessler, R. R.
A Microprogrammed Implementation of LISP and REDUCE on the
Burroughs B 1700/B 1800 Computer.
Utah Symbolic Computation Group Report UCP 70, University of Utah,
Department of Computer Science, 1979.

[Griss 81]

Griss, M. L. and Hearn, A. C.
A Portable LISP Compiler.
Software - Practice and Experience 11 :541-605, June, 1981.

[Griss 82]

Griss, M. L.; Benson. E.; and Hearn, A. C.
Current Status of a Portable LISP Compiler.
In Proceedings of the SIGPLAN 1982 Symposium on Compiler
Construction, pages 276-283. ACM SIGPLAN, June, 1982.

{Harrison 73]

Harrison, M. C.
Data structures and Programming.
Scott, Foresman and Company, Glenview, Illinois, 1973.

[Harrison 74]

Harrison, M. C.
A Language Oriented Instruction Set for BALM.
In Proceedings of SIGPLAN/SIGMICRO 9, pages 161. ACM, 1974.

[Hearn 66]

Hearn, A. C.
Standard LISP.
SIGPLAN Notices Notices 4(9):xx, September, 1966.
Also Published in SIGSAM Bulletin, ACM Vol. 13, 1969, p. 28-49 ..

[Hearn 73]

Hearn, A. C.
REDUCE 2 Users Manual.
Utah Symbolic Computation Group, Report UCP-19, University of Utah,
Department of Computer Science, 1973.

[Kessler 79]

Kessler, R. R.
PMETA - Pattern Matching META/REDUCE.
Utah Symbolic Computation Group, OpNote 40, University of Utah,
Department· of Computer Science, January, 1979.

Bibliography
page 16.3

23 September 1983

PSL Manual
section 16.0
[Lefaivre 78]

Lefaivre, R.
RUTGERS/UCI LISP MANUAL.
Online Manual, RS:RUTLSP.MAN, Rutgers University, Computer Science
. Department, May, 1978.

[L1SP360 xx]

xx.
L1SP/360 Reference Manual.
Technical Report, Stanford Centre for Information Processing, Stanford
University, xx.

[MACLISP 76]

xx.
MACLISP Reference Manual.
Technical Report, MIT, March, 1976.

[Marti 79]

Marti, J. B., et al.
Standard LISP Report.
SIGPLAN Notices 14( 10):48-68, October, 1979.

[McCarthy 73]

McCarthy, J. C. et al.
LISP 1.5 Programmer's Manual.
M.I.T. Press, 1973.
7th Printing January 1973.

[Moore 76]

J. Strother Moore II.
The INTERLISP Virtual Machine Specification.

CSL 76-5, Xerox, Palo Alto Research Center, 3333 Coyote Road,etc,
September, 1976.
[Nordstrom 73]

Nordstrom, M.
A Parsing Technique.
Utah Computational Physics Group Opnote No. 12, University of Utah,
Department of Computer Science, November, 1973.

[Nordstrom 78]

Nordstrom, M.; Sandewall, E.; and Breslaw, D.
LISP F3 : A FORTRAN Implementation of InterLlSP.
Manual, Datalogilaboratoriet, Sturegatan 2 B, S 752 23, Uppsala,
SWEDEN, 1978.
Mentioned by M. Nordstrom in 'Short Announcement of LISP F3', a
handout at L1SP80.

[Norman 81]

Norman, A.C. and Morrison, D. F.
The REDUCE Debugging Package.
Utah Symbolic Computation Group Opnote No. 49, University of Utah,
Department of Computer Science, February, 1981.

[Pratt 73]

Pratt, V.
Top Down Operator Precedence.
In Proceedings of POPL-l, pages ??-??

[Quam 69]

ACM, 1973.

Quam, L. H. and Diffie, W.
. Stanford LISP 1.6 Manual.
Operating Note 28.7, Stanford Artificial Intelligence Laboratory, 1969.

Bibliography
page 16.4

23 September 1983

PSL Manual
section 16.0

[Sandewall 78]

Sandewall, E.
Programming in an Interactive Environment : The LISP Experience.
Computing Surveys 1O( 1):35-72, March, 1978.

[Steele 81]

Steele, G. L. and Fahlman, S. E.
Spice LISP Reference' Manual.
Manual , Carnegie-Mellon University; Pittsburgh, September, 1981.
(Preliminary Common LISP Report).

[Teitelman 78]

Teitelman, W.; et al.
Interlisp Reference Manual, (3rd Revision).
Xerox Palo Alto Research Center, 3333 Coyote Hill Road, Palo
Alto,Calif. 94304, 1978.

[Teitelman 81]

Teitleman, W. and Masinter, L.
The InterLiSP Programming Environment.
IEEE Computer 14(4):25-34, 1981.

[Terashima 78]

Terashima, M. and Goto, E.
Genetic Order and Compactifying Garbage Collectors.
Information Processing Letters 7(1 ):27-32, 1978.

[Weinreb 81]

Weinreb, D. and Moon, D.
LISP Machine Manual.
, 1981.
Fourth edition.

[Weissman 67]

Weissman.
LISP 1.5 Primer.
Dickenson Publishing Company, Inc., 1967.

[Winston 81]

Winston, P. H., and Horn, B. K. P.
LISP.
Addison-Wesley Publishing Company, Reading, Mass., 1981.

PSL MANUAL
SECTION 17.0

23 SEPTEMBER 1983

CONCEPT INDEX
PAGE 17.1

CHAPTER 17
INDEX OF CONCEPTS
The following· is an alphabetical list of concepts, with the page on which they are
discussed.

flError handlers" . . . . . . . . . . . . . .
A-Lists . . . . . . . . . . . . . . . . . . . . .
Absolute Value . . . . . . . . . . . . . . .
Access to Value Cell ......... .
Addition . . . . . . . . . . . . . . . . . . . .
Always . . . . . . . . . . . . . . . . . . . . .
And function . . . . . . . . . . . . . . . .
And . . . . . . . . . . . . . . . . . . . . . . .
Any -catchall data type ....... .
Appending Lists . . . . . . . . . . . . . .
Arc cosecant function ........ .
Arc cosine function .......... .
Arc cotangent function ........ .
Arc secant function .......... .
Arc sine function . . . . . . . . . . . . .
Arc tangent function ......... .
Arguments .... : . . . . . . . . . . . . .
Arithmetic . . . . . . . . . . . . . . . . . .
Arrays . . . . . . . . . . . . . . . . . . . . .
ASCII . . . . . . . . . . . . . . . . . . . . . .
Assignment . . . . . . . . . . . . . . . . .
Association list. . . . . . . . . . . . . . .
Association lists . . . . . . . . . . . . . .
Atom . . . . . . . . . . . . . . . . . . . . . .
Atoms . . . . . . . . . . . . . . . . . . . . .
Automatic Breaking .......... .
Automatic Tracing ........... .
Back Quote. . . . . . . . . . . . . . . . . .
Backtrace . . . . . . . . . . . . . . . . . . .
Backup Buffer . . . . . . . . . . . . . . . .
Big Integers . . . . . . . . . . . . . . . . .
BigNum . . . . . . . . . . . . . . . . . . . .
Binary Trees . . . . . . . . . . . . . . . . .
Binary. . . . . . . . . . . . . . . . . . . . . .
Binding Type . . . . . . . . . . . . . . . .
Binding . . . . . . . . . . . . . . . . . . . . .
Bit Operations . . . . . . . . . . . . . . .
Boolean Functions ........... .
Boolean . . . . . . . . . . . . . . . . . . . .

12.3
2.4, 5.9, 5.12
3.2
15.3
3.2

7.7
2.8

7.7
2.3

5.7
3.1~

3.12
3.13
3.13

3.12
3.12
8.1, 8.10
3.2

6.7
10.3, 10.11
4.6
2.4
5.9, 5.12
2.6
2.3
13.11
13.11

8.7
13.12
10.11
3.1
2.1, 3.1
5.1
10.22
8.11, 8.12
4.6, 8.10
3.7
2.8
2.6, 3.5

C~ncept

Index
page 17.2

23 September 1983

Booleans
Box Diagrams . . . . . . . . . . . . . . .
Break Commands . . . . . . . . . . . .
Break Facility . . . . . . . . . . . . . . .
Break Loop . . . . . . . . . . . . . . . . .
Breaking Functions . . . . . . . . . . .
Building A-Lists . . . . . . . . . . . . .
Byte-Vector . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.

2.3
5.1
12.5
13.10
11.4,12.1,12.5,12.9
13.10
5.12
2.1,6.5

Car Manipulation . . . . . . . . . . . .
Case Statement . . . . . . . . . . . . .
Catch . . . . . . . . . . . . . . . . . . . . .
Cdr Manipulation . . . . . . . . . . . .
Channels . . . . . . . . . . . . . . . . . .
Characters . . . . . . . . . . . . . . . . .
Circular Functions . . . . . . . . . . .
Circular Structures . . . . . . . . . . .
Classes of Data Types ........
Closing Channels . . . . . . . . . . . .
Code-Pointer . . . . . . . . . . . . . . .
Coliect . . . . . . . . . . . . . . . . . . . .
Common Lisp . . . . . . . . . . . . . . .
Comparison . . . . . . . . . . . . . . . .
Compilation . . . . . . . . . . . . . . . .
Compiled Functions ..........
Compiled VS. Interpreted .......
Compiler . . . . . . . . . . . . . . . . . .
Compiling files . . . . . . . . . . . . . .
Compiling Functions . . . . . . . . . .
Compiling to FASL Files .......
Compiling to Memory .........
Composites of Car and Cdr ....
Cone . . . . . . . . . . . . . . . . . . . . .
Concatenating Lists ..........
Cond . . . . . . . . . . . . . . . . . . . . .
Conditional Compilation .......
Conditionals . . . . . . . . . . . . . . . .
Constant . . . . . . . . . . . . . . . . . .
Constants . . . . . . . . . . . . . . . . . .
Continuing After Errors ........
Control Time of Execution .....
Converting Data Types ........
Copying Functions . . . . . . . . . . .
Copying Strings . . . . . . . . . . . . .
Copying Vectors . . . . . . . . . . . . .
Copying X-Vectors . . . . . . . . . . .
Copying . . . . . . . . . . . . . . . . . . .
Cosecant function . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

5.2
7.3
12.1, 12.9
5.2
10.17
2.3,6.1
3.8
13.15
2.3
10.17
2.1, 2.6, 8.2, 8.9, 10.11
7.7
6.7
5.10
8.10,15.7
8.9
15.7
15.1
15.1
15.2, 15.3
15.2
15.3
5.2
7.7
5.7
7.4
15.4
7.1
2.6
2.3
12.1
15.5
2.9,3.1
8.2
6.1
6.3
6.6
5.2
3.11

PSL Manual
section 17.0

PSl Manual
section 17.0

23 September 1983

Cosine function .............
Cotangent function ...........
Count . . . . . . . . . . . . . . . . . . . . .
Counting Function Calls .......
Customizing Debug ..........

.
.
.
.
.

3.11
3.11
7.7
13.13
13.16

Data Type Conversion ........
Data Types .................
Debug and Redefinition .......
Debug Deficiencies ...........
Debug Example .............
Debug Printing Functions ......
Debug Reading Functions ......
Debugging Tools ............
Decimal Output .............
Declaration .................
Default Top level ............
Deficiencies in Debug .........
Deletion from lists ...........
Delimiters . . . . . . . . . . . . . . . . . .
Digits . . . . . . . . . . . . . . . . . . . . .
Diphthong Indicator ..........
Diphthong . . . . . . . . . . . . . . . . .
Division . . . . . . . . . . . . . . . . . . .
Do . . . . . . . . . . . . . . . . . . . . . . .
Dot Notation
Dot-notation ...............

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

2.9,3.1
2.1, 10.6, 10.11
13.2
13.3
13.18
13.17
13.17
13.1
10.7
8.10, 8.11
11.4
13.3
5.9
10.3, 10.11
10.11
10.29
10.33
3.2
7.7
5.1
2.2

Each . . . . . . . . . . . . . . . . . . . . . .
Editing in the Break loop ......
Elementary Functions .........
Embedded Functions .........
Enabling debug facilities .......
End of file . . . . . . . . . . . . . . . . .
. End of line . . . . . . . . . . . . . . . . .
EOF . . . . . . . . . . . . . . . . . . . . . .
EOl . . . . . . . . . . . . . . . . . . . . . .
Equality testing functions ......
Error Calls . . . . . . . . . . . . . . . . .
Error Functions ..............
Error Handling ..............
Error Number ...............
Errors . . . . . . . . . . . . . . . . . . . . .
Eval flag . . . . . . . . . . . . . . . . . . .
Eval Type Functions' ..........
Evaluation . . . . . . . . . . . . . . . . .
Examples . . . . . . . . . . . . . . . . . .
Executable . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

7.13
12.5
3.8
13.12
13.11
10.28
10.28
10.28
10.28
2.5
12.10
12.1
12.1
12.1
8.12
4.12
8.1
9.1
12.5,13.18
14.2

Concept Index
page 17.3

Concept Index
page 17.4

23 September 1983

Exit . . . . . . . . . . . . . . . . . . . . . .
Exiting PSL . . . . . . . . . . . . . . . . .
Explicit Sequence Control ......
Exponent . . . . . . . . . . . . . . . . . .
. Exponential Functions .........
Exponentiation . . . . . . . . . . . . . .
Expr . . . . . . . . . . . . . . . . . . . . . .
Extra-Booleans . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.

7.1,7.18
14.1
7.4
2.1
3.8
3.2
8.1, 8.10
2.3

Factorial function ............ .
FASL . . . . . . . . . . . . . . . . . . . . . .
Fexpr . . . . . . . . . . . . . . . . . . . . . .
Field . . . . . . . . . . . . . . . . . . . . . . .
File Input . . . . . . . . . . . . . . . . . . .
File Names . . . . . . . . . . . . . . . . . .
File Output . . . . . . . . . . . . . . . . . .
Filename Conventions ........ .
Finally . . . . . . . . . . . . . . . . . . . . .
Find . . . . . . . . . . . . . . . . . . . . . . .
FixNum . . . . . . . . . . . . . . . . . . . . .
Flag indicators . . . . . . . . . . . . . . .
Flagging Ids . . . . . . . . . . . . . . . . .
Flags ...................... .
Float. . . . . . . . . . . . . . . . . . . . . . .
Floats . . . . . . . . . . . . . . . . . . . . . .
Fluid Binding . . . . . . . . . . . . . . . .
Fluid Declarations ............ .
For . . . . . . . . . . . . . . . . . . . . . . . .
Form . . . . . . . . . . . . . . . . . . . . . .
Format . . . . . . . . . . . . . . . . . . . . .
Formatted Printing ........... .
From . . . . . . . . . . . . . . . . . . . . . .
FType . . . . . . . . . . . . . . . . . . . . . .
Function Cell . . . . . . . . . . . . . . . .
Function Definition ........... .
Function Execution Tracing ..... .
Function Order . . . . . . . . . . . . . . .
Function Redefinition ......... .
Function types . . . . . . . . . . . . . . .
Function . . . . . . . . . . . . . . . . . . . .

3.14
10.22
8.1, 8.10
2.1
10.22
10. 17, 10.22
10.22
10.23
7.7
4.3
2.1
4.12

Garbage Collection ...........
Global Binding . . . . . . . . . . . . . .
Global Declarations ..........
Globals . . . . . . . . . . . . . . . . . . . .
Go . . . . . . . . . . . . . . . . . . . . . . .

14.4
8.10

.
.
.
.
.

Halfword-Vector ............. .

4.5
4.4,4.5
2.1, 2.6, 10.11
3.1
8.10
15.3

7.7
2.4
10.7,10.11,10.26
10.7
7.7
2.3
4.1, 9.1
8.1
13.4

15.5
13.2
8.1, 8.10
2.4

15.3
4.12
7.1
2.1,6.5

PSL Manual
section 17.0

PSL Manual
section 17.0

23 September 1983

Handlers . . . . . . . . . . . . . . . . . . .
Heap . . . . . . . . . . . . . . . . . . . . .
Help . . . . . . . . . . . . . . . . . . . . . .
Hexadecimal Output ..........
. Historv Mechanism . . . . . . . . . . .
Hook . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.

10.17
2.1
4.12, 14.1
10.7
11.1
4.2

I/O Buffer . . . . . . . . . . . . . . . . . . .
I/O . . . . . . . . . . . . . . . . " ..... .
Id hash table . . . . . . . . . . . . . . . .
Id Space . . . . . . . . . . . . . . . . . . . .
Id-Hash-Table . . . . . . . . . . . . . . .
Id . . . . . . . . . . . . . . . . . . . . . . . . .
Identifier. . . . . . . . . . . . . . . . . . . .
If Then Construct . . . . . . . . . . . . .
Ignore flag . . . . . . . . . . . . . . . . . .
In . . . . . . . . . . . . . . . . . . . . . . . . .
Indexing vectors and strings ... .
Indicator, on property list ...... .
Init Files . . . . . . . . . . . . . . . . . . . .
Initially . . . . . . . . . . . . . . . . . . . . .
Input Functions '.' . . . . . . . . . . . .
Input in Files . . . . . . . . . . . . . . . .
Input . . . . . . . . . . . . . . . . . . . . . .
Integer . . . . . . . . . . . . . . . . . . . . .
Integers . . . . . . . . . . . . . . . . . . . .
Intern . . . . . . . . . . . . . . . . . . . . . .
Internals in Debug ........... .
Interpretation . . . . . . . . . . . . . . . .
Interpreted Functions ......... .
Interpreter . . . . . . . . . . . . . . . . . .
Interrupt Keys . . . . . . . . . . . . . . . .
Inum . . . . . . . . . . . . . . . . . . . . . .
Inverse Circular Functions ..... .
Inverse Trigonometric Functions ..
Item . . . . . . . . . . . . . . . . . . . . . . .
Iteration ........... '.' ...... .

10.11
10.26
4.2,4.3
2.1, 4.1
14.1
2.1, 2.6, 2.9, 4.1, 10.11
2.1, 2.6, 2.9, 4.1, 10.11
7.1
4.12
7.7
6.1
4.4
14.3
7.7
10.11
10.22
10.1
2.1, 2.6, 2.9, 10.l1
3.1
2.9,4.2
13.16
15.7
8.9,8.12
9.1
12.9
2.1, 2.9
3.11
3.11
2.1
7.6

Join . . . . . . . . . . . . . . . . . . . . . . .

7.7

Lambda . . . . . . . . . . . . . . . . . . .
Length . . . . . . . . . . . . . . . . . . . .
Letter -as Token Type .........
Line feed . . . . . . . . . . . . . . . . . .
Lisp syntax . . . . . . . . . . . . . . . . .
List Concatenation . . . . . . . . . . .
List Element Deletion .........
List Element Selection ........

2.4, 8.10, 8.12, 9.5
5.6
10.11
10.28
10.3, 10.17
5.7
5.9
5.4

.
.
.
.
.
.
.
.

Concept Index
page 17.5

Concept Index
page 17.6

23 September 1983

List 10
List Length . . . . . . . . . . . . . . . . .
List Manipulation . . . . . . . . . . . .
List Membership Functions .....
List Notation . . . . . . . . . . . . . . . .
List Reversal. . . . . . . . . . . . . . . .
List Substitutions . . . . . . . . . . . .
List-notation . . . . . . . . . . . . . . .
List . . . . . . . . . . . . . . . . . . . . . . .
Loading FASL Files ...........
Loading Modules . . . . . . . . . . . .
Local Binding . . . . . . . . . . . . . . .
Logarithms . . . . . . . . . . . . . . . . .
Logical And . . . . . . . . . . . . . . . .
Logical Exclusive Or ..........
Logical Not . . . . . . . . . . . . . . . . .
Logical Or . . . . . . . . . . . . . . . . .
Looping Constructs ..........
Lose flag . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

10.26
5.6
5.4
5.6
5.1
5.10
5.14
2.4
2.4, 2.9, 4.4, 5.1
10.19
10.19
8.10
3.8
3.7
3.7
3.7
3.7
7.6
4.12

Macro. . . . . . . . . . . . . . . . . . . . .
Mapping Functions ...........
Mathematical Functions .......
Maximize . . . . . . . . . . . . . . . . . .
Minimize . . . . . . . . . . . . . . . . . .
Minus as Token Type .........
Modulo function . . . . . . . . . . . . .
Multiplication . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.

8.2, 8.10, 9.7
7.13
3.8
7.7
7.7
10.11
3.9
3.2

Never . . . . . . . . . . . . . . . . . . . . .
Newline . . . . . . . . . . . . . . . . . . .
Nexpr . . . . . . . . . . . . . . . . . . . . .
Next . . . . . . . . . . . . . . . . . . . . . .
NIL . . . . . . . . . . . . . . . . . . . . . . .
NoEval Type Functions ........
Non-Local Exit . . . . . . . . . . . . . .
None Returned . . . . . . . . . . . . . .
NoSpread Type Functions ......
Not function . . . . . . . . . . . . . . . .
Not. . . . . . . . . . . . . . . . . . . . . . .
Notation . . . . . . . . . . . . . . . . . . .
Number . . . . . . . . . . . . . . . . . . .
Numbers . . . . . . . . . . . . . . . . . .
Numeric Comparison .........

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

7.7
10.28
8.1, 8.10
7.1
·2.6, 2.8, 4.11
8.1
7.18
2.3
8.1
2.8
7.7
2.1
2.6, 2.9, 10.11
2.3,3.1
3.5

Object list . . . . . . . . . . . . . . . . . .
Oblist . . . . . . . . . . . . . . . . . . . . . .
Octal Output. . . . . . . . . . . . . . . . .

4.2
4.2,4.3
10.7

PSL Manual
section 17.0

PSL Manual
section 17.0

23 September 1983

OFF command . . . . . . . . . . . . . . .
ON command . . . . . . . . . . . . . . . .
On . . . . . . . . . . . . . . . . . . . . . . . .
Open Coding . . . . . . . . . . . . . . . .
Or- function . . . . . . . . . . . . . . . . . .
Or . . . . . . . . . . . . . . . . . . . . . . . .
Order of Functions . . . . . . . . . . . .
Output Base . . . . . . . . . . . . . . . . .
Output . . . . . . . . . . . . . . . . . . . . .
OutPutBase!* . . . . . . . . . . . . . . . .
Overflow . . . . . . . . . . . . . . . . . . .

4.10
4.10
7.7
15.7
2.8
7.7
15.5
10.10
10.1
10.10
10.26

Package Cell. . . . . . . . . . . . . . . . .
Package . . . . . . . . . . . . . . . . . . . .
Pair Construction . . . . . . . . . . . . .
Pair Manipulation . . . . . . . . . . . . .
Pair . . . . . . . . . . . . . . . . . . . . . . .
Pairs. . . . . . . . . . . . . . . . . . . . . . .
Parameters . . . . . . . . . . . . . . . . . .
Parser . . . . . . . . . . . . . . . . . . . . .
Plus as Token Type .......... .
Predicates . . . . . . . . . . . . . . . . . .
Print Name . . . . . . . . . . . . . . . . . .
Printing Circular Lists ......... .
Printing Functions . . . . . . . . . . . .
Printing Property Lists ........ .
Printing Registers . . . . . . . . . . . . .
Printing . . . . . . . . . . . . . . . . . . . .
Product . . . . . . . . . . . . . . . . . . . .
Prog . . . . . . . . . . . . . . . . . . . . . . .
ProgN . . . . . . . . . . . . . . . . . . . . . .
Properties . . . . . . . . . . . . . . . . . . .
Property Cell Access ......... .
Property Cell ... " . . . . . . . . . . . . .
Property List . . . . . . . . . . . . . . . . .
Put Indicators . . . . . . . . . . . . . . . .

4.1
4.2
5.2
5.2
2.1,2.4,2.6,5.1
5.1
8.1, 8.10
10.11
10.11
2.5, 3.5, 5.6, 8.9, 8.10, 8.12
4.1
13.15
13.14
13.14
10.10
10.6
7.7
7.4,8.10,8.12
7.4
4.4
4.6
4.1,4.4
4.1, 4.4, 4. 11
4.11

Radix for I/O . . . . . . . . . . . . . . .
Random Numbers . . . . . . . . . . . .
Read macro indicator .........
Read Macros . . . . . . . . . . . . . . .
Reading Entire Lines . . . . . . . . . .
Reading Functions . . . . . . . . . . .
Register and Tracing .........
Registers . . . . . . . . . . . . . . . . . .
Remainder function . . . . . . . . . .
Removing Functions . . . . . . . . . .
Return . . . . . . . . . . . . . . . . . . . .

10.11
3.8
10.14
10.15
10.14
10.11
13.3
10.10
3.2
8.2
7.1

.
.
.
.
.
.
.
.
.
.
.

Concept Index
page 17.7

Concept Index
page 17.8

23 September 1983

Returns . . . . . . . . . . . . . . . . . . . .
Reversal of lists . . . . . . . . . . . . . .

7.7
5.10

S-expression . . . . . . . . . . . . . . . .
10. i 1
S-Expressions . . . . . . . . . . . . . . .
.2.3
S-Integer . . . . . . . . . . . . . . . . . . .
2.9
Saving Executable PSL ........ .
14.2
Saving Trace Output . . . . . . . . . . .
13.6
Scan Table . . . . . . . . . . . . . . . . . .
10.11,10.14,10.33,11.1
Scope of Variables . . . . . . . . . . . .
8.10
Searching A-Lists . . . . . . . . . . . . .
5.12
Secant function . . . . . . . . . . . . . .
3.11
Selective Trace . . . . . . . . . . . . . . .
13.7
Sequence of Evaluation ....... .
7.4
Set Functions . . . . . . . . . . . . . . . .
5.8
Sharp-Sign Read Macros ...... .
10.12
SIMPFG indicator . . . . . . . . . . . . .
4.10
Sine function . . . . . . . . . . . . . . . .
3.10
Skip to Top of Page . . . . . . . . . . . . 10.10
Sorting . . . . . . . . . . . . . . . . . . . . .
5.10
Special I/O Functions ......... .
10.17
Spread Type Functions ........ .
8.1
Square Root function ......... .
3.13
String 10 . . . . . . . . . . . . . . . . . . .
10.26
String Operations . . . . . . . . . . . . .
6.1
String Quotes . . . . . . . . . . . . . . . .
10.11
String . . . . . . . . . . . . . . . . . . . . . .
2.1, 2.6, 2.9, 10.11
Structure . . . . . . . . . . . . . . . . . . .
2.4
Stubs . . . . . . . . . . . . . . . . . . . . . .
13.14
Substitutions . . . . . . . . . . . . . . . .
5.14
Substring Matching . . . . . . . . . . .
4.3
Subtraction . . . . . . . . . . . . . . . . . .
3.2
Sum . . . . . . . . . . . . . . . . . . . . . . .
7.7
Switches Controlling Compiler .. .
15.6
Switches . . . . . . . . . . . . . . . . . . .
4.10, 4.12
T ........................
Tag Field . . . . . . . . . . . . . . . . . .
Tangent function . . . . . . . . . . . .
Terminal Interaction . . . . . . . . . .
Throw . . . . . . . . . . . . . . . . . . . .
Time Control Functions .......
Token scanner . . . . . . . . . . . . . .
Top Level Function . . . . . . . . . . .
Top Level Loop . . . . . . . . . . . . . .
Top Loop Mechanism .........
Top Loop . . . . . . . . . . . . . . . . . .
Trace Output . . . . . . . . . . . : ...

.
.
.
.
.
.
.
.
.
.
.
.

4.11
2.1
3.11
10.16
12.1
15.5
10.11
11.4
11.1
12.9
11.1
13.6

PSL Manual
section 17.0

PSL Manual
section 17.0

23 September 1983

Trace Predicate
Trace ring buffer . . . . . . . . . . . .
Tracing Functions . . . . . . . . . . . .
Tracing Macros ... : .........
Tracing New Functions ........
Transcendental Functions ......
Trigonometric Functions .......
Truth and falsity . . . . . . . . . . . . .
Turning Off Trace . . . . . . . . . . . .
Type Checking Functions ......
Type Conversion . . . . . . . . . . . .
Type Declarations . . . . . . . . . . . .
Type Field . . . . . . . . . . . . . . . . .
Type Mismatch . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.

Unary Functions . . . . . . . . . . . . .
Undefined . . . . . . . . . . . . . . . . . .
Union . . . . . . . . . . . . . . . . . . . . .
Unless . . . . . . . . . . . . . . . . . . . .
Until . . . . . . . . . . . . . . . . . . . . . .
Untraceable Functions ........
User flag . . . . . . . . . . . . . . . . . .
User Function Redefinition .....
User Hooks in Debug .........
User Interface . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.

Value Cell . . . . . . . . . . . . . . . . . .
.Variable Binding . . . . . . . . . . . . .
Vector Indexing . . . . . . . . . . . . .
Vector Operations . . . . . . . . . . .
Vector . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.

4.1, 4.6, 8.10
4.6, 8.10

When . . . . . . . . . . . . . . . . . . . . .
While . . . . . . . . . . . . . . . . . . . . .
With . . . . . . . . . . . . . . . . . . . . . .
Word Operations . . . . . . . . . . . .
Word-Vector . . . . . . . . . . . . . . .
Word . . . . . . . . . . . . . . . . . . . . .
Writing Functions . . . . . . . . . . . .

.
.
.
.
.
.
.

7.7
7.7
7.7

X-Vector Operations . . . . . . . . . . .
X-Vector . . . . . . . . . . . . . . . . . . .
X-Vectors . . . . . . . . . . . . . . . . . . .

13.7
13.6
13.4
13.3
13.11
3.8
3.8
2.8
13.9

2.6
2.9,3.1
2.1

2.1
10.26
3.2
2.3
7.7
7.7
7.7
13.3

4.12
13.2
13.16
11.1

6.1
6.3

2.1, 2.6, 2.9

6.5
2.1,6.5
2.1
10.6
6.6

6.1
2.3

Concept Index
page 17.9

PSL MANUAL
SECTION 18.0

23 SEPTEMBER 1983

FUNCTION INDEX
PAGE 18.1

CHAPTER 18
INDEX OF FUNCTIONS
The following is an alphabetical list of the PSL functions, with the page on which they
are defined.

!%Reclaim . . . . . . . . . . . . . . . . . . expr
Abs . . . . . . . . . . . . . . . . . . . . . . . expr
AConc . . . . . . . . . . . . . . . . . . . . . expr
Acos . . . . . . . . . . . . . . . . . . . . . . expr
AcosD . . . . . . . . . . . . . . . . . . . . . expr
Acot . . . . . . . . . . . . . . . . . . . . . . . expr
AcotD . . . . . . . . . . . . . . . . . . . . . . expr
Acsc . . . . . . . . . . . . . . . . . . . . . . . expr
AcscD . . . . . . . . . . . . . . . . . . . . . expr
Addl . . . . . . . . . . . . . . . . . . . . . . expr
Adjoin . . . . . . . . . . . . . . . . . . . . . expr
AdjoinQ . . . . . . . . . . . . . . . . . . . . expr
AlphaNumericP . . . . . . . . . . . . . . . expr
AlphaP . . . . . . . . . . . . . . . . . . . . . expr
And . . . . . . . . . . . . . . . . . . . . . . . fexpr
Ans . . . . . . . . . . . . . . . . . . . . . . . expr
Append . . . . . . . . . . . . . . . . . . . . expr
Apply . . . . . . . . . . . . . . . . . . . . . . expr
Asec . . . . . . . . . . . . . . . . . . . . . . . expr
AsecD . . . . . . . . . . . . . . . . . . . . . expr
Asin . . . . . . . . . . . . . . . . . . . . . . . expr
AsinD . . . . . . . . . . . . . . . . . . . . . . expr
Ass . . . . . . . . . . . . . . . . . . . . . . . expr
Assoc . . . . . . . . . . . . . . . . . . . . . . expr
Atan2 . . . . . . . . . . . . . . . . . . . . . . expr
Atan2D . . . . . . . . . . . . . . . . . . . . . expr
Atan . . . . . . . . . . . . . . . . . . . . . . . expr
AtanD . . . . . . . . . . . . . . . . . . . . . . expr
Atom . . . . . . . . . . . . . . . . . . . . . . expr
Atsoc . . . . . . . . . . . . . . . . . . . . . . expr
BackQuote . . . . . . . . . . . . . . . . . .
BeginRLisp . . . . . . . . . . . . . . . . . .
BldMsg . . . . . . . . . . . . . . . . . . . . .
BothCaseP . . . . . . . . . . . . . . . . . .
BothTimes . . . . . . . . . . . . . . . . . .
Br. . . . . . . . . . . . . . . . . . . . . . . . .
Brln . . . . . . . . . . . . . . . . . . . . . . .
. BrWhen . . . . . . . . . . . . . . . . . . . .
Btr . . . . . . . . . . . . . . . . . . . . . . . .

macro
expr
expr
expr
expr
macro
macro
macro
macro

14.4
3.2

5.7
3.12
3.12
3.13
3.13
3.13
3.13
3.2

5.8
5.8
6.9
6.8
2.8
11.3

5.7
9.4
3.13
3.13
3.12
3.12
5.13
5.13
3.12
3.12
3.12
3.12
2.6
5.13

8.8
11.4
10.26
6.9

15.5
13.10
13.10
13.10
13.12

Function Index
page 18.2

23 September 1983

Car. . . . . . . . . . . . . . . . . . . . . . . .
Case. . . . . . . . . . . . . . . . . . . . . . .
Catch!-AII . . . . . . . . . . . . . . . . . . .
Catch .......................
Cdr. . . . . . . . . . . . . . . . . . . . . . . .
Ceiling . . . . . . . . . . . . . . . . . . . . .
Channel Eject . . . . . . . . . . . . . . . .
ChannelLineLength ............
ChannelLPosn . . . . . . . . . . . . . . . .
ChannelPosn . . . . . . . . . . . . . . . .
ChannelPrin 1 . . . . . . . . . . . . . . . .
ChanneiPrin2 . . . . . . . . . . . . . . . .
ChanneiPrin2T . . . . . . . . . . . . . . .
ChannelPrinC . . . . . . . . . . . . . . . .
ChannelPrint . . . . . . . . . . . . . . . . .
ChannelPrintF . . . . . . . . . . . . . . . .
ChannelRead . . . . . . . . . . . . . . . .
ChannelReadCH . . . . . . . . . . . . . .
ChannelReadChar . . . . . . . . . . . . .
ChannelReadLine . . . . . . . . . . . . .
ChannelReadToken . . . . . . . . . . . .
ChannelReadTokenWithHooks ....
ChannelS paces . . . . . . . . . . . . . . .
ChannelTab . . . . . . . . . . . . . . . . .
ChannelTerPri . . . . . . . . . . . . . . . .
ChannelUnReadChar ...........
ChannelWriteChar . . . . . . . . . . . . .
Char!-Bits . . . . . . . . . . . . . . . . . . .
Char!-Code . . . . . . . . . . . . . . . . . .
Char!-DownCase . . . . . . . . . . . . .
Char!-Equal . . . . . . . . . . . . . . . . .
Char!-Font . . . . . . . . . . . . . . . . . .
Char!-GreaterP . . . . . . . . . . . . . . .
Char!-Int . . . . . . . . . . . . . . . . . . .
Char!-LessP . . . . . . . . . . . . . . . . .
Char!-UpCase . . . . . . . . . . . . . . . .
Char! < .....................
Char!= . . . . . . . . . . . . . . . . . . . . .
Char! > .....................
Char . . . . . . . . . . . . . . . . . . . . . . .
Character . . . . . . . . . . . . . . . . . . .
Close . . . . . . . . . . . . . . . . . . . . . .
Code!-Char. . . . . . . . . . . . . . . . . .
Code!-Number!-Of!-Arguments ...
CodeApply . . . . . . . . . . . . . . . . . .
CodeEvalApply . . . . . . . . . . . . . . .
CodeP . . . . . . . . . . . . . . . . . . . . .

expr
fexpr
macro
fexpr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
macro
expr
expr
expr
expr
expr
expr
expr

5.2
7.3
7.20
7.18

5.2
3.8
10.10
10.10
10.10
10.10
10.6
10.6
10.9
10.9
10.6
10.7
10.11
10.13
10.13
10.15
10.14
10.14
10.7
10.7
10.6
10.13
10.9
6.10
6.10
6.10
6.9
6.10
6.9
6.11
6.9
6.10
6.9
6.9
6.9
6.2
6.10
10.18
6.10
8.10
9.6
9.6

2.6

PSL Manual
section 18.0

PSL Manual
section 18.0

23 September 1983

CommentOutCode ............
Compile-File . . . . . . . . . . . . . . . . .
Compile . . . . . . . . . . . . . . . . . . . .
CompileTime . . . . . . . . . . . . . . . .
Compress . . . . . . . . . . . . . . . . . . .
. Concat . . . . . . . . . . . . . . . . . . . . .
Cond .......................
Cons ..........
ConstantP . . . . . . . . . . . . . . . . . . .
ContError . . . . . . . . . . . . . . . . . . .
ContinuableError. . . . . . . . . . . . . .
Copy . . . . . . . . . . . . . . . . . . . . . .
CopyD . . . . . . . . . . . . . . . . . . . . .
CopyScanTable . . . . . . . . . . . . . . .
CopyString . . . . . . . . . . . . . . . . . .
CopyStringToFrom ............
CopyVector . . . . . . . . . . . . . . . . .
CopyVectorToFrom ............
Cos . . . . . . . . . . . . . . . . . . . . . . .
CosO . . . . . . . . . . . . . . . . . . . . . .
Cot . . . . . . . . . . . . . . . . . . . . . . . .
CotO . . . . . . . . . . . . . . . . . . . . . .
0

• • • • • • • • • • •

macro
expr
expr
expr
expr
expr
fexpr
expr
expr
macro
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr

15.5
15.2
15.3
15.5
10.27
6.7
7.1
5.2

2.7
12.3
12.2
5.3

8.4
10.33
6.2
6.2
6.4
6.4
3.11
3.11
3.11
3.11

esc . . . . . . . . . . . . . . . . . . . . . . . expr

3.11

CscD .........

expr

3.11

expr
macro
maero
macro
expr
macro
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
macro
macro
expr
expr
expr
expr

14.4

0

• • • • • • • • • • • •

Date . . . . . . . . . . . . . . . . . . . . . . .
De . . . . . . . . . . . . . . . . . . . . ' ....
Decr . . . . . . . . . . . . . . . . . . . . . . .
OefLambda . . . . . . . . . . . . . . . . . .
OefList . . . . . . . . . . . . . . . . . . . . .
DefMacro . . . . . . . . . . . . . . . . . . .
DegreesToDMS . . . . . . . . . . . . . . .
DegreesToRadians ............
Del . . . . . . . . . . . . . . . . . . . . . . . .
DelAse . . . . . . . . . . . . . . . . . . '...
DeiAseiP . . . . . . . . . . . . . . . . . . . .
DelatQ . . . . . . . . . . . . . . . . . . . . .
DelatQIP . . . . . . . . . . . . . . . . . . . .
Delete . . . . . . . . . . . . . . . . . . . . .
DeletlP . . . . . . . . . . . . . . . . . . . . .
DeIQ. . . . . . . . . . . . . . . . . . . . . . .
DelQIP . . . . . . . . . . . . . . . . . . . . .
DeSetQ. . . . . . . . . . . . . . . . . . . . .
Of. . . . . . . . . . . . . . . . . . . . . . . . .
Difference . . . . . . . . . . . . . . . . . .
Oigit!-Char . . . . . . . . . . . . . . . . . .
Digit . . . . . . . . . . . . . . . . . . . . . . .
DigitP . . . . . . . . . . . . . . . . . . . . . .

Function Index
page 18.3

8.5
3.3

8.7
4.5

8.7
3.10
3.9

5.9
5.9
5.9
5.9
5.10

5.9
5.9
5.9
5.9
4.7
8.5
3.3
6.10
10.26
6.9

_____________

i

~J

Function Index
page 18.4

23 September 1983

Divide . . . . . . . . . . . . . . . . . . . . . .
Dm . . . . . . . . . . . . . . . . . . . . . . . .
DMStoDegrees . . . . . . . . . . . . . . .
DMStoRadians . . . . . . . . . . . . . . .
Dn . . . . . . . . . . . . . . . . . . . . . . . .
Do!* . . . . . . . . . . . . . . . . . . . . . . .
Do-Loop!* . . . . . . . . . . . . . . . . . .
Do-Loop . . . . . . . . . . . . . . . . . . . .
Do . . . . . . . . . . . . . . . . . . . . . . . .
Ds . . . . . . . . . . . . . . . . . . . . . . . .
Dskln . . . . . . . . . . . . . . . . . . . . . .
DumpLisp . . . . . . . . . . . . . . . . . . .

expr
macro
expr
expr
macro
macro
macro
macro
macro
macro
expr
expr

3.3
8.6
3.10
3.10
8.5
7.17
7.17
7.17
7.16
8.6
10.22
14.3

Eject. . . . . . . . . . . . . . . . . . . . . . .
Eq . . . . . . . . . . . . . . . . . . . . . . . .
EqCar . . . . . . . . . . . . . . . . . . . . . .
EqN . . . . . . . . . . . . . . . . . . . . . . .
EqStr . . . . . . . . . . . . . . . . . . . . . .
Equal . . . . . . . . . . . . . . . . . . . . . .
Error . . . . . . . . . . . . . . . . . . . . . .
ErrorPrintF . . . . . . . . . . . . . . . . . .
ErrorSet . . . . . . . . . . . . . . . . . . . .
ErrPrin . . . . . . . . . . . . . . . . . . . . .
ErrSet . . . . . . . . . . . . . . . . . . . . . .
Eval . . . . . . . . . . . . . . . . . . . . . . .
Evln . . . . . . . . . . . . . . . . . . . . . . .
EvLis . . . . . . . . . . . . . . . . . . . . . .
EvOut . . . . . . . . . . . . . . . . . . . . . .
EvProgN . . . . . . . . . . . . . . . . . . . .
EvShut . . . . . . . . . . . . . . . . . . . . .
Exit . . . . . . . . . . . . . . . . . . . . . . .
ExitLisp . . . . . . . . . . . . . . . . . . . . .
Exp . . . . . . . . . . . . . . . . . . . . . . . .
Expand . . . . . . . . . . . . . . . . . . . . .
Explode2 . . . . . . . . . . . . . . . . . . .
Explode . . . . . . . . . . . . . . . . . . . .
ExprP . . . . . . . . . . . . . . . . . . . . . .
Expt . . . . . . . . . . . . . . . . . . . . . . .

expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
macro
expr
expr
expr
expr
expr
expr
macro
expr
expr
expr
expr
expr
expr
expr

10.10
2.5
2.6
2.5
2.6
2.5
12.1
10.9
12.4
10.9
12.3
9.2
10.24
9.5
10.19
9.6
10.19
7.7
14.2
3.13
9.7
10.27
10.27
8.10
3.3

Factorial . . . . . . . . . . . . . . . . . . . .
FaslEnd . . . . . . . . . . . . . . . . . . . .
Faslln . . . . . . . . . . . . . . . . . . . . . .
FaslOut . . . . . . . . . . . . . . . . . . . . .
FatalError . . . . . . . . . . . . . . . . . . .
FCodeP . . . . . . . . . . . . . . . . . . . . .
FExprP . . . . . . . . . . . . . . . . . . . . .
FileP . . . . . . . . . . . . . . . . . . . . . . .
FindPrefix . . . . . . . . . . . . . . . . . . .

expr
expr
expr
expr
expr
expr
expr
expr
expr

3.14
15.2
10.23
15.2
12.3
8.9
8.10
10.18
4.4

PSL Manual
section 18.0

PSL Manual
section 18.0

23 September 1983

FindSuffix . . . . . . . . . . . . . . . . . . .
First . . . . . . . . . . . . . . . . . . . . . . .
Fix . . . . . . . . . . . . . . . . . . . . . . . .
FixP . . . . . . . . . . . . . . . . . . . . . . .
Flagl . . . . . . . . . . . . . . . . . . . . . .
Flag . . . . . . . . . . . . . . . . . . . . . . .
FlagP . . . . . . . . . . . . . . . . . . . . . .
FLambdaLinkP . . . . . . . . . . . . . . . .
FiatSize2 . . . . . . . . . . . . . . . . . . .
FlatSize . . . . . . . . . . . . . . . . . . . .
Float. . . . . . . . . . . . . . . . . . . . . . .
FloatP . . . . . . . . . . . . . . . . . . . . . .
Floor . . . . . . . . . . . . . . . . . . . . . .
Fluid . . . . . . . . . . . . . . . . . . . . . . .
FluidP . . . . . . . . . . . . . . . . . . . . . .
For!* . . . . . . . . . . . . . . . . . . . . . . .
For . . . . . . . . . . . . . . . . . . . . . . . .
ForEach . . . . . . . . . . . . . . . . . . . .
Fourth . . . . . . . . . . . . . . . . . . . . .
FStub . . . . . . . . . . . . . . . . . . . . . .
FUnBoundP . . . . . . . . . . . . . . . . . .
Function . . . . . . . . . . . . . . . . . . . .

expr
macro
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
macro
macro
macro
macro
macro
expr
fexpr

4.4
5.5
3.2
2.7
4.6
4.5
4.6
8.9
10.26
10.26
3.2
2.7
3.8
8.11, 15.4
8.12
7.13
7.8
7.14
5.5
13.14
8.9
9.7

GenSym . . . . . . . . . . . . . . . . . . . .
Geq . . . . . . . . . . . . . . . . . . . . . . .
Get. . . . . . . . . . . . . . . . . . . . . . . .
GetD . . . . . . . . . . . . . . . . . . . . . .
GetFCodePointer. . . . . . . . . . . . . .
GetV. . . . . . . . . . . . . . . . . . . . . . .
Global . . . . . . . . . . . . . . . . . . . . .
GlobalP . . . . . . . . . . . . . . . . . . . .
GmergeSort . . . . . . . . . . . . . . . . .
Go . . . . . . . . . . . . . . . . . . . . . . . .
GraphicP . . . . . . . . . . . . . . . . . .~.
GreaterP . . . . . . . . . . . . . . . . . . . .
Gsort . . . . . . . . . . . . . . . . . . . . . .

expr
expr
expr
expr
expr
expr
expr
expr
expr
fexpr
expr
expr
expr

4.3
3.5
4.4
8.4
8.10
6.3
8.11, 15.4
8.12
5.11
7.5
6.8
3.5
5.10

Help . . . . . . . . . . . . . . . . . . . . . . . fexpr
Hist . . . . . . . . . . . . . . . . . . . . . . . nexpr

14.1
11.2

Id21nt . . . . . . . . . . . . . . . . . . . . . .
Id2String . . . . . . . . . . . . . . . . . . .
IdApplyO . . . . . . . . . . . . . . . . . . . .
IdApply 1. . . . . . . . . . . . . . . . . . . .
IdApply2. . . . . . . . . . . . . . . . . . . .
IdApply3. . . . . . . . . . . . . . . . . . . .
IdApply4 . . . . . . . . . . . . . . . . . . . .
IdP . . . . . . . . . . . . . . . . . . . . . . . .

2.10
2.10
9.6
9.6
9.6
9.6
9.6
2.7

expr
expr
expr
expr
expr
expr
expr
expr

Function Index
page 18.5

Function Index
page 18.6

23 September 1983

IdSort . . . . . . . . . . . . . . . . . . . . . .
If . . . . . . . . . . . . . . . . . . . . . . . . .
If_System . . . . . . . . . . . . . . . . . . .
IGetS . . . . . . . . . . . . . . . . . . . . . .
IGetV .......................
Implode . . . . . . . . . . . . . . . . . . . .
Imports . . . . . . . . . . . . . . . . . . . .
In . . . . . . . . . . . . . . . . . . . . . . . . .
Incr . . . . . . . . . . . . . . . . . . . . . . .
IndexError. . . . . . . . . . . . . . . . . . .
Indx . . . . . . . . . . . . . . . . . . . . . . .
Init-File-String . . . . . . . . . . . . . . .
Inp . . . . . . . . . . . . . . . . . . . . . . . .
IntI-Char . . . . . . . . . . . . . . . . . . .
Int2Code . . . . . . . . . . . . . . . . . . .
Int21d . . . . . . . . . . . . . . . . . . . . . .
Int2Sys . . . . . . . . . . . . . . . . . . . . .
Intern . . . . . . . . . . . . . . . . . . . . . .
InternGenSym . . . . . . . . . . . . . . . .
InternP . . . . . . . . . . . . . . . . . . . . .
InterSection . . . . . . . . . . . . . . . . .
InterSeetionO . . . . . . . . . . . . . . . .
IPutS . . . . . . . . . . . . . . . . . . . . . .
IPutV . . . . . . . . . . . . . . . . . . . . . .
ISizeS . . . . . . . . . . . . . . . . . . . . . .
ISizeV . . . . . . . . . . . . . . . . . . . . . .

expr
macro
macro
expr
expr
expr
expr
macro
macro
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr

LambdaApply . . . . . . . . . . . . . . . .
LambdaEvalApply . . . . . . . . . . . . .
LAnd . . . . . . . . . . . . . . . . . . . . . .
Lapin . . . . . . . . . . . . . . . . . . . . . .
LastCar . . . . . . . . . . . . . . . . . . . . .
LastPair . . . . . . . . . . . . . . . . . . . .
LBind 1 . . . . . . . . . . . . . . . . . . . . .
LCone . . . . . . . . . . . . . . . . . . . . . .
Length . . . . . . . . . . . . . . . . . . . . .
Leq . . . . . . . . . . . . . . . . . . . . . . . .
LessP . . . . . . . . . . . . . . . . . . . . . .
Let!* . . . . . . . . . . . . . . . . . . . . . . .
Let . . . . . . . . . . . . . . . . . . . . . . . .
LineLength . . . . . . . . . . . . . . . . . .
Lisp2Char . . . . . . . . . . . . . . . . . . .
List2Set . . . . . . . . . . . . . . . . . . . .
List2SetO . . . . . . . . . . . . . . . . . . .
List2String . . . . . . . . . . . . . . . . . .
List2Vector . . . . . . . . . . . . . . . . . .
List. . . . . . . . . . . . . . . . . . . . . . . .
Liter . . . . . . . . . . . . . . . . . . . . . . .

expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
macro
macro
expr
expr
expr
expr
expr
expr
fexpr
expr

5.11
7.2
15.4
6.5
6.5
10.27
10.20
10.23

3.4
12.10
6.6

14.3
11.3
6.11
2.12
2.10
2.12
2.9

4.3
4.3
5.8
5.8
6.5
6.5
6.5
6.5
9.6
9.6
3.7
10.22
5.5
5.5
. 8.12

5.7
5.6
3.6
3.6
7.18
7.17
10.10
2.12
5.8
5.8
2.10
2.11

5.7
10.26

PSL Manual
section 18.0

PSl Manual
section 18.0

23 September 1983

lNot . . . . . . . . . . . . . . . . . . . . . . .
load . . . . . . . . . . . . . . . . . . . . . . .
loadTime . . . . . . . . . . . . . . . . . . .
log10 . . . . . . . . . . . . . . . . . . . . . .
log2 . . . . . . . . . . . . . . . . . . . . . . .
log .........................
lOr. . . . . . . . . . . . . . . . . . . . . . . .
lowerCaseP . . . . . . . . . . . . . . . . .
LPosn . . . . . . . . . . . . . . . . . . . . . .
LShift . . . . . . . . . . . . . . . . . . . . . .
LXOr. . . . . . . . . . . . . . . . . . . . . . .

expr
macro
expr
expr
expr
expr
expr
expr
expr
expr
expr

3.7
10.20
15.5
3.14
3.14
3.13
3.7
6.9
10.10
3.8
3.7

MacroExpand . . . . . . . . . . . . . . . .
MacroP . . . . . . . . . . . . . . . . . . . . .
Main . . . . . . . . . . . . . . . . . . . . . . .
Make!-Bytes . . . . . . . . . . . . . . . . .
Make!-Halfwords . . . . . . . . . . . . .
Make!-String . . . . . . . . . . . . . . . .
Make!-Vector . . . . . . . . . . . . . . . .
Make!-Words . . . . . . . . . . . . . . . .
MakeFCode . . . . . . . . . . . . . . . . . .
MakeFLambdaLink . . . . . . . . . . . . .
MakeFUnBound . . . . . . . . . . . . . . .
MakeUnBound . . . . . . . . . . . . . . .
Map . . . . . . . . . . . . . . . . . . . . . . .
MapC . . . . . . . . . . . . . . . . . . . . . .
MapCan . . . . . . . . . . . . . . . . . . . .
MapCar . . . . . . . . . . . . . . . . . . . .
MapCon . . . . . . . . . . . . . . . . . . . .
MapList . . . . . . . . . . . . . . . . . . . .
MapObl . . . . . . . . . . . . . . . . . . . .
Max2 . . . . . . . . . . . . . . . . . . . . . .
Max . . . . . . . . . . . . . . . . . . . . . . .
Member .....................
MemQ . . . . . . . . . . . . . . . . . . . . .
Min2 . . . . . . . . . . . . . . . . . . . . . . .
Min . . . . . . . . . . . . . . . . . . . . . . .
Minus . . . . . . . . . . . . . . . . . . . . . .
MinusP . . . . . . . . . . . . . . . . . . . . .
MkQuote . . . . . . . . . . . . . . . . . . .
MkString . . . . . . . . . . . . . . . . . . . .
MkVect . . . . . . . . . . . . . . . . . . . . .
Mod . . . . . . . . . . . . . . . . . . . . . . .

macro
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
macro
expr
expr
expr
macro
expr
expr
expr
expr
expr
expr

. 8.8
8.10
11.4
6.6
6.5
6.12
6.4
6.5
8.9
8.9
8.9
4.9
7.14
7.15
7.15
7.15
7.15
7.15
4.3
3.6
3.6
5.6
5.6
3.6
3.6
3.4
3.6
9.7
6.2
6.4
3.9

NConc . . . . . . . . . . . . . . . . . . . . .
NCons . . . . . . . . . . . . . . . . . . . . .
Ne . . . . . . . . . . . . . . . . . . . . . . . .
Neq . . . . . . . . . . . . . . . . . . . . . . .

expr
expr
expr
macro

5.7
5.3
2.6
2.6

Function Index
page 18.7

Function Index
page 18.8
Newld.
NewTrBuff
·.
NExprP.
·.
Next.
·.
NonCharacterError
NonlDError.
NonlntegerError .
·.
NonUstError.
·.
NonNumberError.
NonPairError.
·.
NonPositivelntegerError
NonSequenceError . · .
NonStringError .
·.
NonVectorError.
·.
NonWordsError.
·.
Not.
·.
NString!-Capitalize . · .
NString!-DownCase · .
NString!-UpCase.
·.
Nth.
·.
Null
·.
NumberP
·.

23 September 1983

expr
expr
expr
macro
expr
.. -.- .. expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr·
expr
expr
expr
expr

2.9
13.6
8.10
7.7
12.11
12.10
12.11
12.10
12.11
12.10
12.11
12.11
12.11
12.11
12.11
2.8
6.13
6.13
6.13

5.5
2.7
2.7

Off . . . . . . . . . . . . . . . . . . . . . . . .
On . . . . . . . . . . . . . . . . . . . . . . . .
OneP . . . . . . . . . . . . . . . . . . . . . .
Open . . . . . . . . . . . . . . . . . . . . . .
Or . . . . . . . . . . . . . . . . . . . . . . . .
Out . . . . . . . . . . . . . . . . . . . . . . .

macro
macro
expr
expr
fexpr
macro

4.10
4.10
3.6
10.17
2.8
10.19

Pair . . . . . . . . . . . . . . . . . . . . . . .
PairP . . . . . . . . . . . . . . . . . . . . . .
Pathln . . . . . . . . . . . . . . . . . . . . . .
Pause . . . . . . . . . . . . . . . . . . . . . .
PBind 1 . . . . . . . . . . . . . . . . . . . . .
PUst . . . . . . . . . . . . . . . . . . . . . . .
Plus2 . . . . . . . . . . . . . . . . . . . . . .
Plus . . . . . . . . . . . . . . . . . . . . . . .
PNth . . . . . . . . . . . . . . . . . . . . . . .
Posn . . . . . . . . . . . . . . . . . . . . . . .
Ppf . . . . . . . . . . . . . . . . . . . . . . . .
PrettyPrint . . . . . . . . . . . . . . . . . .
Prin 1 . . . . . . . . . . . . . . . . . . . . . .
Prin2 . . . . . . . . . . . . . . . . . . . . . .
Prin2L. . . . . . . . . . . . . . . . . . . . . .
Prin2T . . . . . . . . . . . . . . . . . . . . .
Prine . . . . . . . . . . . . . . . . . . . . . .
Print . . . . . . . . . . . . . . . . . . . . . . .

expr
expr
expr
expr
expr
macro
expr
macro
expr
expr
macro
expr
expr
expr
expr
expr
expr
expr

5.13
2.7
10.23
10.16
8.13
13.14
3.4
3.4
5.6
10.10
13.15
10.8
10.6
10.6
10.9
10.9

TO.9
10.6

PSL Manual
section 18.0

PSl Manual
section 18.0

23 September 1983

PrintF . . . . . . . . . . . . . . . . . . . . . .
PrintScanTable ...............
PrintX . . . . . . . . . . . . . . . . . . . . . .
Prog 1 . . . . . . . . . . . . . . . . . . . . . .
Prog2 . . . . . . . . . . . . . . . . . . . . G_.
Prog . . . . . . . . . . . . . . . . . . . . . . .
ProgN . . . . . . . . . . . . . . . . . . . . . .
Prop . . . . . . . . . . . . . . . . . . . . . . .
PSetF . . . . . . . . . . . . . . . . . . . . . .
PSetQ. . . . . . . . . . . . . . . . . . . . . .
Put . . . . . . . . . . . . . . . . . . . . . . . .
PutD . . . . . . . . . . . . . . . . . . . . . . .
PutDiphthong ................
PutReadMacro ...............
PutV ............... : . . . . . . .

expr
expr
expr
macro
expr
fexpr
fexpr
expr
macro
macro
expr
expr
expr
expr
expr

10.7
10.33
13.15

7.4
7.4
7.4
7.4
4.6
4.9
4.7

4.4
8.2
10.33
10.33

6.4

Quit . . . . . . . . . . . . . . . . . . . . . . . expr
Quote ....................... fexpr
Quotient .................... expr

14.2
9.7
3.4

RadiansToDegrees ............
RadiansToDMS ...............
Random ...
RangeError ..................
RAtom . . . . . . . . . . . . . . . . . . . . .
Rds . . . . . . . . . . . . . . . . . . . . . . .
Read-Init-File ................
Read . . . . . . . . . . . . . . . . . . . . . .
ReadCH ....................
ReadChar ...................
ReadLine ...................
Recip . . . . . . . . . . . . . . . . . . . . . .
Reclaim ....................
ReDo . . . . . . . . . . . . . . . . . . . . . .
Reload . . . . . . . . . . . . . . . . . . . . .
Remainder ....... ' ...........
RemD . . . . . . . . . . . . . . . . . . . . . .
RemFlag 1 ...................
Rem Flag ....................
RemOb . . . . . . . . . . . . . . . . . . . . .
RemProp ...................
RemPropL. ..................
Repeat ............. : .......
ResBtr . . . . . . . . . . . . . . . . . . . . .
Reset ........ '..............
Rest ..................
Restr . . . . . . . . . . . . . . . . . . . . .
Return .

3.9
3.10
3.14
12.10
10.14
10.24
14.3
10.11
10.13
10.13
10.15
3.4
14.4
11.3
10.20
3.5
8.5

G

• • • • • • • • • • • • • • • •

G

• • • •

G

G

• • • • • • • • • • • • • • • • • • •

expr
expr
expr
expr
expr
expr
expr
expr
expr
expr.
expr
expr
expr
expr
macro
expr
expr
expr
expr
expr
expr
expr
macro
expr
expr
macro
macro
expr

4.6
4.6
4.3
4.5
4.5

7.6
13.12
14.4
5.5
13.9

7.6

Function Index
page 18.9

Function Index
page 18.10

23 September 1983

Reverse . . . . . . . . . . . . . . . . . . . .
ReverslP . . . . . . . . . . . . . . . . . . . .
RLisp . . . . . . . . . . . . . . . . . . . . . .
Round . . . . . . . . . . . . . . . . . . . . .
RplacA . . . . . . . . . . . . . . . . . . . . .
RplacD ...._. . . . . . . . . . . . . . . . .
RplaChar . . . . . . . . . . . . . . . . . . .
RplacW . . . . . . . . . . . . . . . . . . . . .
RPrint . . . . . . . . . . . . . . . . . . . . . .

expr
expr
expr
expr
expr
expr
expr
expr
expr

5.10
5.10
11.3
3.9
5.4
5.4
6.11
5.4
10.8

SAssoc . . . . . . . . . . . . . . . . . . . . .
SaveSystem . . . . . . . . . . . . . . . . .
Sec . . . . . . . . . . . . . . . . . . . . . . .
SecD . . . . . . . . . . . . . . . . . . . . . .
Second . . . . . . . . . . . . . . . . . . . . .
Selectq . . . . . . . . . . . . . . . . . . . . .
Set . . . . . . . . . . . . . . . . . . . . . . . .
SetF . . . . . . . . . . . . . . . . . . . . . . .
Setlndx . . . . . . . . . . . . . . . . . . . . .
SetProp . . . . . . . . . . . . . . . . . . . .
Seta. . . . . . . . . . . . . . . . . . . . . . .
SetSub . . . . . . . . . . . . . . . . . . . . .
SetSubSeq . . . . . . . . . . . . . . . . . .
Shut . . . . . . . . . . . . . . . . . . . . . . .
Sin . . . . . . . . . . . . . . . . . . . . . . . .
SinD . . . . . . . . . . . . . . . . . . . . . . .
Size . . . . . . . . . . . . . . . . . . . . . . .
Spaces . . . . . . . . . . . . . . . . . . . . .
Sqrt . . . . . . . . . . . . . . . . . . . . . . .
Standard!-CharP . . . . . . . . . . . . . .
Standard Lisp . . . . . . . . . . . . . . . . .
StdError . . . . . . . . . . . . . . . . . . . .
StdTrace . . . . . . . . . . . . . . . . . . . .
Step . . . . . . . . . . . . . . . . . . . . . . .
String!-Capitalize . . . . . . . . . . . . .
String!-CharP . . . . . . . . . . . . . . . .
String!-DownCase ............
String!-Equal . . . . . . . . . . . . . . . .
String!-GreaterP . . . . . . . . . . . . . .
String!-Left!-Trim .............
String!-Length . . . . . . . . . . . . . . .
String!-LessP . . . . . . . . . . . . . . . .
String!-Notl-Equal ............
String!-Not!-GreaterP ..........
String!-Not!-LessP ............
String!-Repeat . . . . . . . . . . . . . . .
String!-Right!-Trim ............
String!-to!-List ........ -........

expr
expr
expr
expr
macro
macro
expr
macro
expr
expr
fexpr
expr
expr
macro
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr

5.13
14.2
3.11
3.11
5.5
7.3
4.7
4.8
6.6
4.6
4.6
6.6
6.7
10.19
3.10
3.10
6.6
10.6
3.13
6.8
11.3
12.10
13.7
13.3
6.13
6.8
6.13
6.11
6.12
6.13
6.14
6.12
6.12
6.12
6.12
6.12
6.13
6.13

PSL Manual
section 18.0

23 September 1983

PSL Manual
section 18.0

String!-to!-Vector . . . . . . . . . . . . .
String!-Trim.
String!-UpCaseo
String! 
String! <
String!=
String! >!=
String! > ....
String2List . . . . . . . . .
String2Vector . . . . . . . . . . . . . . . .
String . . . . . . . . . . . . . . . . . .
StringGenSym . . . . . . . . . . . . . . .
StringP . . . . . . . . . . . . . . . . . . . . .
Stub . . . . . . . . . . . . . . . . . . . . . . .
Sub 1 . . . . . . . . . . . . . . . . . . . . . .
Sub.
SubiA . . . . . . .
SubLis . . . . . . . . . . . . . . . . .
SubSeq . . . . . . . . . . . . . . . . . . . .
Subst . . . . . . . . . . . . . . . . . . . . . .
SubstlP . . . . . . . . . . . . . . . . . . . . .
SubString . . . . . . . . . . . . . . . . . . .
Sys2lnt.

expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
expr
nexpr
expr
expr
macro
expr
expr
expr
expr
expr
expr
expr
expr
expr

Tab .....
Tan ..
TanD .
TConc .
TerPri
o.
Third ..
Throw
Time
Times2 ..
Times ...
TopLoop
TotalCopy
Tr ....
TraceCount.
TransferSign ...
TrCnt
Trln .....
TrOut . . . . . . .
Trst ...
TrstSome . . . . . . . . . . . . . . . . . . .
TrWhen ......
TypeError ....

expr
expr
expr
expr
expr
macro
expr
expr
expr
macro
expr
expr
macro
expr
expr
macro
macro
expr
macro
macro
macro
expr

0

•

0

0

0

0

0

••

0

••

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

•

0

0

••

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

0

••

0

000

0

0

0

0

0

0

0

•

0

0

•

0

0

0

0

0

.0

0

0

0

0

0

0

•

0

0

0

•

0

••

0

0

0

0

0

0

0

0

0

0

0

0

•

0

0

0

0

0

0

0

0

0

•••

0

• • • • • • • • • • • • • • •

0

0

• • • • • • • •

0

0

• • • • • • • • • • • • • •

0

0

• • • • • • • • • • • • •

• • • • • • • • •

0

0

••

•

0

0

• • • • • •

0

••

0

••

0

0

0

•

• • • • • • • •

0

••

0

0

• • • • • • • • • • • • •

0

• • • • • • • • • • • • • • • •

0

0

0

0

••

•

0

0

• • • • • • •

0

•

0

••

0

0

0

0

• • • • • •

••••

0

•

0

• • • • •

0

••

0

••••

•

0

••

0

0

••

0

0

•

0

0

0

0

0

0

0

0

0

0

••••

0

000

0

0

0

0

••

0

0

0

0

•

0

••••

0

0

0

••••

0

• • • • • • • •

0

0

0

0

••

•

0

0

• • •

0

0

0

• • •

• • • • • • • • • • • • • • • • • • • • •

0

0

0

0

0

0

0

0

••••

0

••

0

0

0

•

0

••••

0

••

0

0

• • • • • • •

0

••

••

0

0

0

0

• • • • • • • • •

0

•••

0

•

0

•••

• • • • • • • • •

0

•

0

•

0

•••

0

• • • • •

0

0

•

0

0

•

0

0

0

0

••

0

0

0

0

0

0

0

0

0

0

•

•••

0

•

0

•

0

0

•

0

•••

0

•

0

•

•••

0

0

••

• • • • •

0

•••

0

••

0

• • • •

0

• • • • • •

••••

0

•

0

••

0

0

0

0

••

0

•••

• • • • • • • • • • • •

••

0

• • • • • • • •

0

0

••

6.13

6.12
6.13
6.11

6.12
6.11
6.11
6.11

6.11
2.10
2.11
2.11, 6.2
4.3

2.7
13.14

3.5
6.6

5.14
5.14
6.6
5.14
5.14

6.13
2.12
10.7
3.11
3.11

5.7
10.6

5.5
7.19
14.4

3.5
3.5
11.1

6.7
13.4
13.7
3.9

13.14
13.8

13.7

13.5
13.5
13.7

12.10

Function Index
page 18.11

Function Index
page 18.12

23 September 1983

UnBindN . . . . . . . . . . . . . . . . . . . .
UnBoundP . . . . . . . . . . . . . . . . . .
UnBr. . . . . . . . . . . . . . . . . . . . . . .
UnBrAl1. . . . . . . . . . . . . . . . . . . . .
UnFluid . . . . . . . . . . . . . . . . . . . . .
Union . . . . . . . . . . . . . . . . . . . . . .
UnionQ. . . . . . . . . . . . . . . . . . . . .
Unless . . . . . . . . . . . . . . . . . . . . .
UnQuote . . . . . . . . . . . . . . . . . . . .
UnQuoteL . . . . . . . . . . . . . . . . . . .
UnReadChar . . . . . . . . . . . . . . . . .
UnTr. . . . . . . . . . . . . . . . . . . . . . .
UnTrAl1. . . . . . . . . . . . . . . . . . . . .
UnTrst . . . . . . . . . . . . . . . . . . . . .
Unwind!-AII . . . . . . . . . . . . . . . . .
Unwind!-Protect . . . . . . . . . . . . . .
UpbV . . . . . . . . . . . . . . . . . . . . . .
UpperCaseP . . . . . . . . . . . . . . . . .
UsageTypeError . . . . . . . . . . . . . .
User-HomeDir-String . . . . . . . . . .

expr
expr
macro
expr
expr
expr
expr
macro
fexpr
fexpr
expr
macro
expr
macro
macro
macro
expr
expr
expr
expr

ValueCell . . . . . . . . . . . . . . . . . . .
Vector2List . . . . . . . . . . . . . . . . . .
Vector2String . . . . . . . . . . . . . . . .
Vector . . . . . . . . . . . . . . . . . . . . .
VectorP . . . . . . . . . . . . . . . . . . . .

expr
expr
expr
nexpr
expr

When . ~ . . . . . . . . . . . . . . . . . . . .
While . . . . . . . . . . . . . . . . . . . . . .
WriteChar . . . . . . . . . . . . . . . . . . .
Wrs . . . . . . . . . . . . . . . . . . . . . . .

macro
macro
expr
expr

8.12
4.9,8.12
13.10
13.10
8.12

5.8
5.8
7.2
8.8

8.8
10.13
13.9
13.9
13.9

7.20
7.20
6.4
6.8
12.10
14.3
4.9

2.11
2.11
2.11, 6.4

2.7
7.2
7.6
10.8
10.24

XCons . . . . . . . . . . . . . . . . . . . . . expr

5.3

YesP . . . . . . . . . . . . . . . . . . . . . . expr

10.16

ZeroP . . . . . . . . . . . . . . . . . . . . . . expr

3.7

PSL Manual
section 18.0

PSL MANUAL
SECTION 19.0

23 SEPTEMBER 1983

GLOBAL INDEX
PAGE 19.1

CHAPTER 19
INDEX OF GLOBALS AND SWITCHES
The following is an alphabetical list of the PSL global variables, with the page on which
they are defined.

!$BREAK!$ . . . . . . . . . . . . . . . . . . .
!*BackTrace . . . . . . . . . . . . . . . . .
!*BREAK . . . . . . . . . . . . . . . . . . . .
!*BreakAlI . . . . . . . . . . . . . . . . . . .
!*BTR . . . . . . . . . . . . . . . . . . . . . .
P'=BTRSAVE . . . . . . . . . . . . . . . . . .
!*COMP . . . . . . . . . . . . . . . . . . . .
!*COMPRESSING ...........' ...
!*DEFN . . . . . . . . . . . . . . . . . . . . .
!*ECHO . . . . . . . . . . . . . . . . . . . . .
!*EMsgP . . . . . . . . . . . . . . . . . . . .
!*EMsgP . . . . . . . . . . . . . . . . . . . .
!*EOLINSTRINGOK . . . . . . . . . . . . .
!*GC . . . . . . . . . . . . . . . . . . . . . . .
!*INSTALL . . . . . . . . . . . . . . . . . . .
!*MODULE. . . . . . . . . . . . . . . . . . .
!*NOLINKE . . . . . . . . . . . . . . . . . . .
!*ORD . . . . . . . . . . . . . . . . . . . . . .
!*PCMAC . . . . . . . . . . . . . . . . . . .
!*PGWD . . . . . . . . . . . . . . . . . . . .
!*PLAP . . . . . . . . . . . . . . . . . . . . .
!*PrintLoadNames . . . . . . . . . . . . .
!*PrintNoArgs . . . . . . . . . . . . . . . .
!*PrintNoArgs . . . . . . . . . . . . . . . .
!*PrintPathin . . . . . . . . . . . . . . . . .
!*PWRDS . . . . . . . . . . . . . . . . . . .
!*R21. . . . . . . . . . . . . . . . . . . . . . .
!*RAISE . . . . . . . . . . . . . . . . . . . . .
!*REDEFMSG . . . . . . . . . . . . . . . . .
!*SAVENAMES . . . . . . . . . . . . . . . .
!*TIME . . . . . . . . . . . . . . . . . . . . .
!*TRACE . . . . . . . . . . . . . . . . . . . .
!*TRACEALL . . . . . . . . . . . . . . . . .
!*TRCOUNT . . . . . . . . . . . . . . . . . .
!*USERMODE . . . . . . . . . . . . . . . .
!*VerboseLoad . . . . . . . . . . . . . . .

global
switch
switch
switch
switch
switch
switch
switch
switch
switch
global
switch
switch
switch
switch
switch
switch
switch
switch
switch
switch
switch
global
switch
switch
switch
switch
switch
switch
switch
switch
switch
switch
switch
switch
switch

12.9
12.5
12.5, 12.9
13.11
13.12
13.12
8.4, 15.3
10.11, 10.14, 10.17
15.2
10.22, 10.28
12.4
11.2
10.16
14.4
13.11, 13.16
15.6
15.6
15.6
15.7
15.7
15.7
10.20
13.10
13.6
10.24
15.7
15.6
10.4, 10.17
8.3
13.16
11.2
13.6
13.11, 13.16
13.13
8.4
10.20

BreakDebugList!* . . . . . . . . . . . . .
BREAKEVALUATOR!* ...........
Breakln!*.....................
BreakLevel!* . . . . . . . . . . . . . . . . .

global
global
global
global

13.3
12.5
10.25, 12.9
12.5

Global Index
page 19.2

23 September 1983

BreakOut!* . . . . . . . . . . . . . . . . . .
BREAKPRINTER!* . . . . . . . . . . . . . .
BREAKREADER!* . . . . . . . . . . . . . .
BrokenFns!* . . . . . . . . . . . . . . . . .

global
global
global
global

10.25, 12.9
12.6
12.5
13.10

CurrentReadMacrolndicator!* .... global
CurrentScanTable!* . . . . . . . . . . . . global

10.14,10.17
10.14,10.17,10.30,10.33

Date!* . . . . . . . . . . . . . . . . . . . . . . global
DFPRINT!* . . . . . . . . . . . . . . . . . . . global

14.3
15.2

EMSG!* . . . . . . . . . . . . . . . . . . . . . global
ERRORFORM!* . . . . . . . . . . . . . . . . global
ERROUT!* . . . . . . . . . . . . . . . . . . . global

12.2, 12.5
12.6
10.9, 10.26

GCKNT!* . . . . . . . . . . . . . . . . . . . . global
GCTime!* . . . . . . . . . . . . . . . . . . . global

14.5
14.4

Helpln!* . . . . . . . . . . . . . . . . . . . .
HelpOut!* . . . . . . . . . . . . . . . . . . .
HistorvCount!* . . . . . . . . . . . . . . .
Historvlist!* . . . . . . . . . . . . . . . . .

global
global
global
global

10.25, 14.1
10.25, 14.1
11.3
11.3

IgnoredlnBacktrace!* ...........
IN!* . . . . . . . . . . . . . . . . . . . . . . .
InitForms!* . . . . . . . . . . . . . . . . . .
InterpreterFunctions!* ..........

global
global
global
global

12.7
10.24, 10.25
11.2
12.7

lispBanner!* . . . . . . . . . . . . . . . . .
LlSPSCANTABLE!* . . . . . . . . . . . . .
LoadDirectories!* . . . . . . . . . . . . .
LoadExtensions!* . . . . . . . . . . . . .

global
global
global
global

14.2
10.17, 10.30
10.20, 10.21
10.20, 10.21

MaxBreakLevel!* . . . . . . . . . . . . . . global

12.5

NIL . . . . . . . . . . . . . . . . . . . . . . . . global

4.11

OPTIONS!* . . . . . . . . . . . . . . . . . . global
OUT!* . . . . . . . . . . . . . . . . . . . . . . global
OUTPUTBASE!* . . . . . . . . . . . . . . . global

10.20
10.24, 10.25
10.4, 10.10

PATHIN!* . . . . . . . . . . . . . . . . . . .
PPFPRINTER!* . . . . . . . . . . . . . . . .
PrinLength . . . . . . . . . . . . . . . . . .
PrinLevel . . . . . . . . . . . . . . . . . . .
PROMPTSTRING!* . . . . . . . . . . . . .
PROPERTVPRINTER!* ...........
PUTDHOOK!*. . . . . . . . . . . . . . . . .

10.23
,13.17
10.11
10.11
10.16
13.18
13.16

global
global
global
global
global
global
global

PSL Manual
section 19.0

PSL Manual
section 19.0

23 September 1983

Global Index
page 19.3

RandomSeed . . . . . . . . . . . . . . . . global
RLiSPSCANTABLE!* . . . . . . . . . . . . global

3.14
10.17, 10.31

SPECIALCLOSEFUNCTION!* ......
SPECIALRDSACTION!* ..........
SPECIALREADFUNCTION!* .......
SPECIALWRITEFUNCTION!* ......
SPECIALWRSACTION!* ..........
STDIN!* . . . . . . . . . . . . . . . . . . . .
STDOUT!* . . . . . . . . . . . . . . . . . . .
STUBPRINTER!* . . . . . . . . . . . . . . .
STUBREADER!* . . . . . . . . . . . . . . .

global
global
global
global
global
global
global
global
global

10.29- .
10.24,
10.29
10.29
10.24,
10.24,
10.24,
13.18
13.18

T .........................
ThrowSignal!* . . . . . . . . . . . . . . . .
ThrowTag!* . . . . . . . . . . . . . . . . . .
TOKTYPE!* . . . . . . . . . . . . . . . . . .
TopLoopEval!* . . . . . . . . . . . . . . .
TopLoopLevef!* . . . . . . . . . . . . . . .
TopLoopName!* . . . . . . . . . . . . . .
TopLoopPrint!* . . . . . . . . . . . . . . .
TopLoopRead!* . . . . . . . . . . . . . . .
TracedFns!* . . . . . . . . . . . . . . . . .
TRACEMAXLEVEL!* . . . . . . . . . . . .
TRACEMINLEVEL!* . . . . . . . . . . . . .
TRACENTRYHOOK!* . . . . . . . . . . . .
TRACEXITHOOK!* . . . . . . . . . . . . .
TRACEXPANDHOOK!* ..........
TREXPRINTER!* . . . . . . . . . . . . . . .
TRINSTALLHOOK!* . . . . . . . . . . . . .
TRPRINTER!* . . . . . . . . . . . . . . . . .
TRSPACE!* . . . . . . . . . . . . . . . . . .

global
global
global
global
global
global
global
global
global
global
global
global
global
global
global
global
global
global
global

4.11
7.19
7.19
10.14, 10.15, 10.32
11.1, 12.9
11.2
11.2
11.1, 12.9
11.1,12.9
13.6
13.8
13.8
13.17
13.17
13.17
13.18
13.17
13.18
13.18

10.26

10.26
10.25
10.25

The Portable Standard LISP Users Manual
Part 2:

Utilities

by
The Utah Symbolic Computation Group

Department of Computer Science
University of Utah
Salt Lake City, Utah 84112

Version 3.2: 16 March 1984

Abstract
This manual describes the primitive data structures, facilities and functions present in the

Portable Standard Lisp (PSL) system.
It describes the implementation details and
functions of interest to a PSL programmer. Except for a small number of hand-coded
routines for I/O and efficient function calling, PSL is written entirely in itself, using a
machine-oriented mode of PSL, called SYSLisp, to perform word, byte, and efficient
integer and string operations. PSL is compiled by an enhanced version of the Portable
Lisp Compiler, and currently runs on the DEC-20, VAX, and MC68000.

Copyright (c) 1982

W. Galway, M. L. Griss, B. Morrison, and B. Othmer

Work supported in part by the Hewlett Packard Company, the International Business
Machines Corporation and the National Science Foundation under Grant Numbers
MCS80-07034 and MCS82-04247.

PSL MANUAL

16 MARCH 1984

PREFACE

Part 2 of The Portable Standard Lisp User's Manual contains information about various
utilities. It includes two chapters describing some of the many utility packages available
on the utility directory.
Many of these are not documented.
A list of these
undocumented utilities is given in Chapter 22.
An objects package is described in
Chapter 23.
Chapter 24 describes three editors that are no longer widely used: a simple structure
editor; EMODE, an EMACS-like screen editor; and a full structure editor adapted from UCI
lisp. Most PSL users now make use of NMODE, a screen editor based on EMODE. Its
documentation is available separately.
PSL gives the user the option of using an Algol-like syntax called RLisp. Chapter 25
describes the syntax of RLisp.
Chapter 26 describes two parser writing tools:
an
extensible table-driven parser that is used for the RLisp parser, and the MINI parser.
Sections 1.2 and 1.3 and Chapter 3 were contributed by Cris Perdue, Alan Snyder, and
other members of the Hewlett-Packard Research Center in Palo Alto.

PSL Manual: Part 2
Table of Contents

6 December 1983

page i

TABLE OF CONTENTS

_.

CHAPTER 1. MAJOR UTILITIES

1.1. Introduction . . .
1.2. Fast Numeric Operators . . . .
1.2.1. Introduction . . . . . .
1.2.2. Common LISP operators.
1.2.3. Operators Not in Common LISP
1.2.4. The Fast-Integers Switch
1.2.5. Cautions . .
1.3. Vector Operations. . . .
1.3.1. Introduction . . .
1.3.2. Vector Operations.
1.3.3. The Fast-Vectors Switch.
1.3.4. Cautions . . . . . . . .
1.4. RCREF - Cross Reference Generator for PSL Files
1.4.1. Restrictions.
1.4.2. Usage .
1.4.3. Options
1.5. Picture RLiSP .
-'
1.6. DefStruct. . .
1.6.1. Options
1.6.2. Slot Options
1.6.3. A Simple Example.
1.7. Bignums . . . . . . . .
1.7.1. BigNum Structure and "Constants"
1.7.2. The Functions in Big Big . . . . .

1.1
1.1
1.1
1.2
1.3
.1.4
1.5
1.5
1.5

1.5
1.6
1.6
1.7
1.8
1.8
1.8
1.9
1.17
1.19
1.20

1.21
1.25
1.25
1.26

CHAPTER 2. MISCELLANEOUS UTILITIES
2.1. Introduction .
2.2. Simulating a Stack
2.3. DefConst. . .
2.4. Hashing Cons.
2.5. Graph-to-Tree
2.6. Inspect Utility.
2.7. If_System . . .
2.8. Profiler for Compiled Functions.
2.9. Timing Function Calls. . . . .
2.10. Parenthesis Checker . . . . .
- 2.11. A Simple Rational Function Evaluator
2.12. Undocumented Utilities. . . . . . ..

2.1
2.1

2.2
2.2
2.3
2.4

2.5
2.5
2.8
2.9
2.9

2.10

-

-----~-----~~~~------------------------------

PSL MANUAL: PART 2
TABLE OF CONTENTS

6 DECEMBER 1983

PAGE II

CHAPTER 3. THE OBJECTS MODULE

3.1. Introduction

. .
3.1.1. Defflavor .
.- 3.1.2. Creating Objects
3.1.3: Methods . . . .
3.1.4. Sanctity of Objects
3.2. Reference Information. .
3.2.1. Loading the Module.
3.2.2. Defflavor. . . . . .
3.2.3. Defmethod . . . . .
3.2.4. Creating New Instances of Flavors
3.3. Operating on Objects . . . .
3.4. Useful Functions on Objects. . . . .
3.5. Debugging Information . . . . . . .
3.6. Declare-Flavor and Undeclare-Flavor .
3.7. Representation Information . . . . .

3.1
3.2
3.2
3.3
3.3

3.3
3.3
3.4
3.5
3.6
3.7

3.9
3.9
3.9
3.10

CHAPTER 4. EDITORS

4.1. A Mini Structure-Editor . . . . . . .
4.2. The EMODE Screen Editor. . . . . . .
4.2.1. Windows and Buffers in Emode. .
4.3. Introduction to the Full Structure Editor.
4.3.1. Starting the Structure Editor. . .
4.3.2. Structure Editor Commands . . .

4.1
4.2
4.5
4.5
4.5
4.6

CHAPTER 5. RLISP SYNTAX

5.1. Motivation for RLISP Interface to PSL. . . . . .
5.2. An Introduction to RLiSP. . . . . . . . . . . . . .
5.2 . 1. LISP equivalents of some RLISP constructs . .
5.3. An Overview of RLISP and LISP Syntax Correspondence
5.3.1. Function Call Syntax in RLiSP and LISP . . . . .
5.3.2. RLISP Infix Operators and Associated LISP Functions.
5.3.3. Referencing Elements of Vectors in RLISP.
5.3.4. Differences between Parse and Read
5.3.5. Procedure Definition. . . . . .
5.3.6. Compound Statement Grouping
5.3.7. Blocks with Local Variables
5.3.8. The If Then Else Statement
5.3.9. Case Statement.
5.4. Looping Statements.
5.4.1. While Loop. .
5.4.2. Repeat Loop .
5.4.3. Next and Exit.
5.4.4. For Each Loop
5.4.5. For Loop. . .

5.1
5.2
5.2
5.3
5.3
5.3
5.5
5.5
5.6
5.7
5.7

5.8
5.9
5.9
5.10
5.10
5.10
5.10
5.11

PSL Manual: Part 2
Table of Contents

6 December 1983

5.4.6. Loop Examples . . . . . . .
5.5. RLiSP Specific Input/Output . . . .
5.5.1. RLiSP File Reading Functions.
5.5.2. RLiSP File Output . . . . . .
-5.6. Transcript -ofa Short -Session-- with RLiSP

page iii

5.11
5.12
5.13
5.13
5.14

CHAPTER 6. PARSER TOOLS
6.1. Introduction . . . .
6.2. The Table Driven Parser. . . . . .
6.2.1. Flow Diagram for the Parser.
6.2.2. Associating the Infix Operator with a Function.
6.2.3. Precedences . . . . . . . . .
6.2.4. Special Cases of 0 < -0 and 0 0
6.2.5. Parenthesized Expressions. . .
6.2.6. Binary Operators in General . .
6.2.7. Assigning Precedences to Key Words.
6.2.8. Error Handling . . . . . . . . . . .
6.2.9. The Parser Program for the RLiSP Language.
6.2.10. Defining Operators. . . . .
6.3. The MINI Translator Writing System
6.3.1. A Brief Guide to MINI .
6.3.2. Pattern Matching Rules
6.3.3. A Small Example
6.3.4. Loading Mini . . . . .
6.3.5. Running Mini . . . . .
6.3.6. MINI Error messages and Error Recovery
6.3.7. MINI Self-Definition. . . . .
6.3.8. The Construction of MINI . .
6.3.9. History of MINI Development.
6.4. BNF Description of RLisp Using MINI
CHAPTER 7. INDEX OF CONCEPTS
CHAPTER 8. INDEX OF FUNCTIONS
CHAPTER 9. INDEX OF GlOBAlS AND SWITCHES

6.1
6~2
6.2
6.4
6.4
6.5
6.5

6.6
6.6

6.6
6.7
6.7
6.9
6.9
6.11
6.11
6.11
6.12
6.12
6.12
6.14
6.15
6.16

PSL MANUAL
SECTION 1.0

13 DECEMBER 1983

MAJOR UTILITIES
PAGE 1.1

CHAPTER 1
MAJOR UTILITIES
Ll.· Introduction... . . . ..
L2~

1.3.

1.4.

1.5.
1.6.

1.7.

Fast- Numeric'Operators
1.2.1. Introduction . .
1.2.2. Common LISP operators.
1.2.3. Operators Not in Common LISP
1.2.4. The Fast-Integers Switch
1.2.5. Cautions . .
Vector Operations. . . .
1.3.1. Introduction . . .
1.3.2. Vector Operations.
1.3.3. The Fast-Vectors Switch.
1.3.4. Cautions . . . . . . . .
RCREF - Cross Reference Generator for PSL Files
1.4.1. Restrictions.
1.4.2. Usage .
1.4.3. Options
Picture RLISP .
DefStruct. . .
1.6.1. Options
1.6.2. Slot Options
1.6.3. A Simple Example.
Bignums . . . . . . . .
1.7.1. BigNum Structure and "Constants"
1.7.2. The Functions in BigBig . . . . .

1.1
1.1
1.1
1.2
1.3
1.4
1.5
1.5

1.5
1.5
1.6
1.6
1.7
1.8
1.8
1.8
1.9

1.17
1.19
1.20

1.21
1.25
1.25

1.26

1.1. Introduction
This chapter describes some of the larger utility packages available in PSL. Its purpose
is to record the existence and capabilities of a number of tools. More information on
existing packages can sometimes be found by looking at the current set of HELP files (in
PH: on the DEC-20, $ph on the VAX).

1.2. Fast Numeric Operators
1.2.1. Introduction
The library module NUMERIC-OPERATORS defines a set of arithmetic functions that are
a superset of the numeric operators defined by the Common LISP compatibility package.
The operators are described in full detail here. All the operators in this package share the
- .characteristic of a short name made of. non-alphabetic characters, such as "+". They also
all . cause the compiler to' generate very efficient integer arithmetic code for their

13 December 1983

Major Utilities
page 1.2

PSL Manual
section 1.2

occurrences when the switch "fast-integers" is turned on.
This module al~o modifies the FOR macro to use the numeric operators to implement
the FROM clause; thus, FOR statement FROM clauses will use fast integer arithmetic when
'." ,·",the FAST-INTEGERS switch' is' on.
The consequences of turning on the "fast-integers" switch are discussed in a separate
section, below. The individual descriptions of the operators describe behavior with that
switch off. Note that when we say certain argument values are "incorrect", we mean that
the result is undefined. The implementation mayor may not check for that situation and
an error mayor may not be signalled.

1.2.2. Common LISP operators
(= X:number

Y:number): number

Numeric Equal. True if and only if the two arguments are numbers of the
same type and same value. Unlike the Common LISP operator, no type
coercion is done, no error is signalled if one or both arguments are nonnumeric, and only two arguments are permitted.
Instead, it is merely
incorrect to supply a non-numeric argument.

(/= X:number

Y:number): number

Numeric Not Equal. True if X and V are numbers of equal type and value;
NIL if X and V are numbers of unequal type or value. it is incorrect to
supply a non-numeric argument. Agrees with the Common LISP operator if
given two numeric arguments of the same type.
(< X:number

Y:number): number

Numeric' Less Than. True if X is less than Y, regardless of type. An error is
signalled if either argument is not numeric. Agrees with Common LISP if
two arguments are supplied.
(> X: number

Y: number): number

Numeric Greater Than. True if X is greater than V, regardless of type. An
error is signalled if either argument is not numeric. Agrees with Common
LISP if two arguments are supplied.

(< = X: number

Y: numb~r): number

Numeric Less Than or Equal. True if X is less than or equal to V, regardless
,of numeric type. An error is signalled if either argument is not numeric.
, Agrees, with Common LISP if two arguments are supplied.

PSL Manual
section 1.2
(>: X:number

13 December 1983

Major Utilities
page 1.3

Y:number): number

Numeric Greater Than or Equal. True if X is greater than or equal to V,
regardless of numeric type. An error is signalled if either argument is not
numeric. --Agrees :~iith Common LISP if two arguments- are supplied.

(+ [N:number]): number

macro

Numeric Addition. The value returned is the sum of all the arguments. The
arguments may be of any numeric type.
An error is signalled if any
argument is not numeric. If supplied no arguments, the value is O. This is
defined to agree with the definition of the Common LISP operator except
that this is a macro.

(- N:number

[N:number]): number

macro

Numeric Minus or Subtraction. If given one argument, returns the negative
of that argument. If given more than one argument, returns the result of
successively subtracting succeeding arguments from the first argument.
Signals an error if no arguments are supplied or if any argument is nonnumeric.
Agrees with the Common LISP operator except in that this
operator is a macro.

(* [N:number]): number

macro

Numeric Multiplication. The value returned is the sum of all the arguments.
The arguments may be of any numeric type. An error is signalled if any
argument is not numeric. If supplied no arguments, the value 'is 1. This is
defined to agree with the definition of the Common LISP operator except
that this is a macro.

(/ N:number

[N:number]): number

Numeric Reciprocal or Division.
If given one argument, returns the
reciprocal of that argument. If given more than one argument, returns the
result of successively subtracting succeeding arguments from the first
argument. Signals an error if no arguments are supplied or if any argument
is non-numeric. Agrees with the Common LISP operator except in that this
operator is a macro.

1.2.3. Operators Not in Common LISP
(-: X:number

Y:number): number

-Numeric Not Equal. Same as /=.

macro

Major Utilities
page 1.4
(/ / X: integer

13 December 1983

PSL Manual
section 1.2

Y: integer): integer

Integer Remainder. Same as Remainder .
. (- X: integer): integer

Integer Bitwise Logical Not. Same as LNOT.
(& X: in teger

Y: in teger): in teger

Integer Bitwise Logical And. Same as LAnd.

(I

X: in teger

Y: in teger): in teger

Integer Bitwise Logical Or. Same as LOr.
(A X: integer

Y: integer): integer

Integer Bitwise Logical Xor. Same as LXOR.

«<

X: integer

Y: integer): integer

Integer Bitwise Logical Left Shift. Same as LShift.
(»

X: integer

Y: integer): integer

Integer Bitwise Logical Right Shift. Same as (LShift X (Minus V)).

1.2.4~

The Fast-Integers Switch

Fast-Integers [Initially: ]
At compilation time the switch FAST-INTEGERS controls generation by the
compiler of efficient, unchecked, inline machine code for occurr"ences of
these operators.
When the switch is on, uses of these operators will
compile into appropriate machine instructions of the target machine. The
arguments are assumed to be integers in the "INUM" range, no larger than
about plus or minus 16 million on the HP9836. No checking of argument
types is done, nor is the value returned checked for being in the legal
range. Floating point operands are NOT handled by code compiled with the
FAST-INTEGERS switch turned on.

switch

PSL Manual
section 1.2

13 December 1983

Major Utilities
page 1.5

1.2.5. Cautions
No checking of either arguments or results is done. The code that is generated is fast
and can be intermixed with other LISP arithmetic operations because a LISP number
. within -the "INUM" range·· is represented the .same·way· that the _host computer represents
.. that number. An out of range . result of one of these ."fastoperations" should be thought
of as a "garbage" value.
A "garbage" value can cause the system to damage itself when treated as a tagged
item. For example, the item might appear to be a pointer to a pair. If passed to a
printing routine or seen by the garbage collector it could cause machine exceptions for
an illegal memory reference or attempt to access an "odd address" (operand alignment
error). A copying or compacting garbage collector might relocate the value.
Note that the * and < < operators are particularly likely to be dangerous in this mode
because they can produce large results from small operands.

1.3. Vector Operations
1.3.1. Introduction
Here we describe the library modules SLOW-VECTORS and FAST-VECTORS.
These
modules provide a set of operations on vectors that can be compiled into efficient in-line
machine code. The functions defined here are used extensively in the NMODE editor and
other modules.
The functionality provided here overlaps what is provided in some other ways. The
functions provided here have well-chosen names and definitions, they provide the option
of generating efficient code, and they are consistent with the esthetic preferences of our
community.
In many cases one just loads FAST-VECTORS, which makes available the facilities of
SLOW-VECTORS for the use of interpretive code. The FAST-VECTORS module adds no
new functions. It only sets up generation of efficient code for these operations by the
compiler, controllable by a switch. To use these functions, load either module. To permit
generation of very efficient coder load FAST-VECTORS.

1.3.2. Vector Operations
(VECTOR-FETCH V: vector

I: integer): any

Accesses an element of a PSL VECTOR. Vector indexes start with O.
thing stored in that position of the vector is returned.

The

Major Utilities
page 1.6
(VECTOR-STORE V: vector
Stores into a PSL

13 December 1983

I: integer
VECTOR.

PSL Manual
section 1.3

X: any): any

Vector indexes start with O.

-(VECTOR-SIZE"V: vector): integer
Returns the number of elements in a PSL vector. Since indexes start with
index 0, the size is one larger than the greatest legal index. See also just
below.

(VECTOR-UPPER-BOUND V:vector): integer
Returns the greatest legal index for accessing or storing into a PSL
See also just above.

VECTOR.

(VECTOR-EMPTY? V:vector): boolean
True if the vector has at least one element, otherwise NIL.

'1.3.3. The Fast-Vectors Switch
Fast-vectors [Initially: ]

switch

At compilation time the switch FAST-INTEGERS controls generation by the
compiler of efficient, unchecked, inline machine code for occurrences of
these operations. When the switch is on, uses of these operators will
compile into appropriate machine instructions of the target machine. The
switch is initially turned on when the module FAST-VECTORS is loaded, but
the switch should be explicitly turned on and off within source files. A
request to "(load FAST-VECTORS)" does not necessarily mean that any
module will be loaded -- library modules are only loaded in response to the
first request for a load.

1.3.4. Cautions
The types of the arguments are not checked. Integer arguments are assumed to be
integers in the "INUM" range, no larger than about plus or minus 16 million on the
HP9836. Vector arguments are assumed to be valid Lisp VECTORS. Range checking of
vector indexes is not done.
All this means that it is possible to access or store into memory that is protected, does
not exist, or at least does not contain an element of a vector. This is especially likely to
happen if a non-integer is used as the vector index in one of these operations.
- Storing-_into arbitrary memory Jocations .isclearly--verydestructive.Accessing "garbage"
"values obtained from -erroneous-' vector~_a-ccess is also -dangerous, aside from causing your
code to -get incorrect results.

6 December 1983

PSL Manual
section 1.3

Major Utilities
page 1.7

A "garbage" value can cause the system to damage itself when treated as a tagged
item. For example, the item might appear to be a pointer to a pair. If passed to a
printing routine or seen by the garbage collector it could cause machine exceptions for
an illegal memory reference or attempt to access an "odd address" (operand alignment
.-~- error). A copying or compacting garbage collector.might relocate the value.

1.4. 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:
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 (Le.
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.
ii.
iii.
iv.

Functions
Functions
Functions
Functions

in
in
in
in

which
which
which
which

it
it
it
it

is
is
is
is

used as a declared FLUID or GLOBAL.
used but not declared before.
bound.
changed by SetQ.

c. A "function usage" table showing for each function:
i.
ii.
iii.
iv.

Where it is defined.
Functions which call this function.
Functions called by it.
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.

Major Utilities
page 1.8

6 December 1983

PSL Manual
section 1.4

1.4.1. Restrictions
Algebraic procedures in Reduce are treated as if they were symbolic, so that algebraic
constructs actually appear as calls to symbolic functions, such as AEval .
.. SYSLisp procedures are not correctly analyzed.

1.4.2. Usage
RCREF should be used in PSL:RLisp. To make a file FILE.CRF which is a cross reference .
listing for files FILE 1.EX 1 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.

1.4.3. Options
! *CREFSUMMARY [Initially: NIL]

switch

If the switch CREFSUMMARY is ON then only the summary (see
produced.

above) is

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 s~e
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

PSL Manual
section 1.4

6 December 1983

Major Utilities
page 1.9

(AND COND LIST MAX MIN OR PLUS PROG PROG2 PROGN TIMES LAMBDA ABS
ADD1 APPEND APPLY ASSOC ATOM CAR CDR CAAR CADR CDAR CDDR CAAAR
CAADR CADAR CADDR COAAR CDADR CDDAR CDDDR CAAAAR CAAADR CAADAR
CAADDR CADAAR CADADR CADDAR CADDDR CDAAAR CDAADR CDADAR CDADDR
CODAARCDDADR-CDDDAR CODDDR CLOSE:CODEPCOMPRESS CONS CONSTANTP
DE.DEFLI-ST .. DELETE DF .DIFFERENCE DIGIT DIVIDE DM EJECT EQ EQN
EQUAL ERROR ERRORSET EVAL EVLIS EXPAND EXPLODE EXPT FIX FIXP FLAG
FLAGP FLOAT FLOATP FLUID FLUIDP FUNCTION GENSYM GET GETD GETV
GLOBAL GLOBALP GO GREATERP IDP INTERN LENGTH LESSP LINELENGTH
LITER LPOSN MAP MAPC MAPCAN MAPCAR MAPCON MAPLIST MAX2 MEMBER
MEMQ MINUS MlNUSP MIN2 MKVECT NCONC NOT NULL NUMBERP ONEP OPEN
PAGELENGTH PAIR PAIRP PLUS2 POSN PRINC PRINT PRIN1 PRIN2 PROG2
PUT PUTD PUTV QUOTE QUOTIENT RDS READ READCH REMAINDER REMD
REMFLAG REMOB REMPROP RETURN REVERSE RPLACA RPLACD SASSOC SET
SETQ STRINGP SUBLIS SUBST SUB1 TERPRI TIMES2 UNFLUID UPBV VECTORP
WRS ZEROP)
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.

1.5. Picture RLISP
[??? 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. PRLlSP
is a 3D version; PRLlSP2D is a faster, smaller 2D version which also drives more
terminals. Two demonstration files, PR-DEMO.RED and PR-DEMO.SI, are available on PU.
See the help files PH:PRLlSP.HLP and PRLlSP2D.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 .
.. -_.

BEZIERO

caus.es the point-set to be interpreted as the specification points for a BEZIER
curve, open pointset.

Major Utilities
page 1.10
BSPlINE(}

6 December 1983

PSL Manual
section 1.5

does the same for a Bspline curve, closed pointset.

TRANSFORMS:
Mostly return a transformation matrix.
. Translation:-Move the:- specified' · amount along the specified axis.
YMOVE(deltaY); ZMOVE(deltaZ); MOVE(deltaX, deltaY, deltaZ);

XMOVE(deltaX);

Scale:

Scale the Model SCALE (factor) XSCALE(factor); YSCALE(factor); ZSCALE(factor);
SCALE 1(x.scale.factor, y.scale.factor, z.scale.factor); SCALE < Scale factor>;.
Scale along all axes.

Rotation:

ROT(degrees);
ROT(degrees,
YROT(degrees); ZROT(degrees);

point.specifying.axis);

XROT(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.
ERASEO

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".

PSL Manual
section 1.5

6 December 1983

Major Utilities
page 1.11

HPUNITO, TEK!.INIT{), TEL!.INITO
Initializes the operating system's view of the characteristics of HP2648A
terminal, TEKTRONIX 4006-1 (also ADM-3A with Retrographics board, and
Teleray-l 061).
For example, the Model

(A

C & {1,2}

B

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} _ {O,2} _ £1,1};

%We are ready for the Cube face
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

e_
e-

&
&
&
&
&

Cubeface
Cube face I
Cube face I
Cube face I
Cubeface I
Cubeface I

XROT
YROT
YROT
XROT
XROT

(180) % 180 degrees
( 90)
(-90)
( 90)
(-90) ;

Major Utilities
page 1.12

6 December 1983

PSl Manual
section 1.5

%In order to have a more pleasant look at
%the picture shown on the screen we magnify
%cube by 5 times.
BigCube : = Cube

.1

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.
%Now draw cube
%
SHOW BigCube;

% Draw it again rotated and moved left
%
SHOW

(BigCube I XROT 20 I YROT 30 I ZROT 10);

%Dynamically expand the faces out
%
Tranz
ZMOVE 12;
%
SHOW (BigCube I YROT 30 1 ZROT 10);
00-

%Now show 5 cubes, each moved further right by 80
%
Tranz
ZMOVE 10;
%
SHOW (Cube SCALE 2.5 1 XMOVE (-240) I REPEATED(5, XMOVE 80»;
0-

0-

PSL Manual
section 1.5

6 December 1983

Major Utilities
page 1.13

%

%Now try pointset modifier.

% Given a pointset (polygon) as control point's either a BEZlER or a
% BSPLlNE curve·· can be drawn.
%
Cpts :~ {O,O} _ {70,-60} _{189,-69} ~ {206,33} ~ {145,t30} _ {48,130}
_ {O,84} $

%Now draw Bezier curve
%Show the polygon and the Bezier curve
%
SHOW (Cpts & Cpts I BEZlER(»;

%Now draw Bspline curve
%Show the polygon and the Bspline curve
%
SHOW (Cpts & Cpts I BSPLlNE(»;

%Now work on the Circle
%Given a center position and a radius a circle is drawn
%
SHOW ( {10,10} I 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 I XROT(180)
& Face I YROT(90)
& Face I YROT(-90)
& Face I XROT(90)
& Face I XROT(-90)
%just return the value of the one statement

Major Utilities
page 1.14

6 Decem ber 1983

% 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 I Buildcube() I XMOVE(-15) &
(Outline I 'Tranz) I Buildcube() I XMOVE 15;
%
SHOW (P I SCALE 5);
% Now define a procedure which returns a Model of
% a cube when passed the half size parameter
Symbolic Procedure Cubemodel;
List 'Cubemodelj
%put the name onto the property list
Put('Cubemodel,'Pbintrp, 'Docubemodel);
Symbolic Procedure Docubemodel HSizej
« 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} »;

PSL Manual

section 1.5

PSL Manual
section 1.5

6 December 1983

%Imbed the parameterized cube in some Models
%
His!.cube:= 'His!.size I Cubemodel();
Her!.cube:= 'Her!.size I Cubemodel();
R : = His!. cube I -XMOVE ( 60 ) &
Her!.cube I XMOVE (-60) ;

%Set up some sizes and SHOW them
His!.size := 50;
Her!.size := 30;
%
SHOW R;
%

%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

:=

SHOW Rotatedtriangle;

{O,O}

{50,50}

{100~0} _ {O,O} I Zrot (45);

Major Utilities
page 1.15

Major Utilities
page 1.16

6- December 1983

PSl Manual
section 1.5

%
% 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!.pyramld := Pyramid Vertices;
%
SHOW ( My!.pyramid I 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 I REPEATED(count, ZROT rotatedangle»
end$
%
%Now draw a wheel consisting of 8 cubes
%
Cubeonspoke:= (Outline I ZMOVE 10 I SCALE 2) I buildcube();
Eight!.cubes := Cubeonspoke I XMOVE 50 , WHEEL(8);
%
SHOW Eightl.cubes;

PSL Manual
section 1.5

6 December 1983

%
%Draw a cube in which each face consists of just
% a wheel of 8 Outlines
%
-Flat L,Spoke : = outline 1 XMOVE 25$
A! .Fancy! •Cube := Flat! .Spoke -I WHEEL(8) 1-- ZMOVK50
%
SHOW A!.Fancy!.Cube;

Major Utilities
page 1.17

I

Buildcube()$

%
% 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 th.e 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.

1.6. De.fStruct
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. (Note: the MacLisp version is available in PSL; load
NSTRUCT.) It is implemented in PSL 1 as a function which builds access macros and fns

lDefstruct was implemented by Russ Fish.

Major Utilities
page 1.18

6 December 1983

PSL Manual
section 1.6

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 NAME: id): extra-boolean
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 S:struct): id
This returns the type name field of an instance of a structured type, or NIL
if ~ cannot be a Defstruct type.
(SubTypeP NAME 1 : id

NAME2 : id): boolean

This returns true if NAMEl 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 NAME 1 can be
applied to NAME2.)
Now the function which defines the beasties, in all its gory glory:
{Defstruct NAME-AND-OPTIONS:{id,list}

[SLOT-DESCS:{id,list}]): id

Defines a record-structure data type. A general call to 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~jnit 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

PSL Manual
section 1.6

6 December 1983

Major Utilities
page 1.19

keyword id, or the keyword followed by its argument list. Options are described below.
A call to a constructor macro has the form:

(MakeThing (slot-name-1value-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 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.
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.

1.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

Major Utilities
page 1.20

6 December 1983

PSl Manual
section 1.6

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 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 !:Jnclude them.
The !:Includelnit 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.

1.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.

6 December 1983

PSL Manual
section 1.6

Major Utilities
page 1.21

1.6.3. A Simple Example
(Input lines have a

">

II

prompt at the beginning.)

>>

%This example is in Rlisp syntax

>
>

%A definition of Complex, structure with Real and Imaginary parts.
%Redefine to see what functions were defined. Give 0 Init values.

%-(Do---definitions twice to see -what functions were defined.)
> macro procedure TWICE u; list( 'PROGN, second u, second u );
TWICE

TWICE
Defstruct( Complex ( !:Creator(Complex) ), R(O), 1(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
>
>

Major Utilities
page 1.22

CO := MakeComplex();
[COMPLEX 0 0]

>

. 6 December 1983

PSL Manual

section 1.6

%Constructor with default inits.

> ComplexP CO;% Predicate.
T

C1:=MakeComplex( R 1, I 2 );
[COMPLEX 1 2]

>

>
1

% Constructor with named values.

R(C1); I(C1);% Named selectors.

2

C2:=Complex(3,4) % Creator with positional values.
[COMPLEX 3 4]

>

AlterComplex( C1, R(2), 1(3) );
[COMPLEX 2 3]

>

%Alterant with named values.

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
> 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
>
>

PSL Manual

6 December 1983

section 1.6

Major Utilities
page 1.23

> MO := MakeMoreComplex();
[MORECOMPLEX 0 0 99]
> M1 := MakeMoreComplex( R 1, I 2, Z 3 );
--[MORECOMPLEX 1 2 3]
> R

C1;

5
> R M1;

> % 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 ••. )
> TWlCE% Redef to show fns generated.
> Defstruct(
>
EXDefstructDescriptor( !:Prefix(EXDsDesc), !:Creator ),
>DsSize(!:Type int),
% (Upper Bound of vector.)
>Prefix(!:Type string ),
>SlotAlist(
!:Type alist ), % (Cdrsare SlotDescriptors.)
>ConsName(
!:Type fnld ),
>AltrName(
!:Type fnld ),
>PredName(
!:Type fnld ),
>CreateName( !:Type fnld ),
>Include(
!:Type typeid ),
>lncllnit(
!:Type alist )
> );

Major Utilities
page 1.24

6 December 1983

***Function 'MAKEEXDEFSTRUCTDESCRIPTOR' has been redefined
*** Function 'ALTEREXDEFSTRUCTDESCRIPTOR' has been redefined
*** Function 'EXDEFSTRUCTDESCRIPTORP' has been redefined
*** Function 'CREATEEXDEFSTRUCTDESCRIPTOR' has been redefined
*** Function' 'EXDSDESCDSSIZE' has been r.edefined
··**.*.-.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
*** 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 fnld ), % Selector/Depositor ide
!:Type type ), % Hm •••
>SlotType(
>UserGet(
!:Type boolean ),
>UserPut(
!:Type boolean)
> );

PSL Manual

section 1.6

. 6 December 1983

PSL Manual
section 1.6

Major Utilities
page 1.25

***
***
***
***
***
...***
***
***
***
***
***
***
***
***
***
***
***

Function 'MAKEEXSLOTDESCRIPTOR' has been redefined
Function 'ALTEREXSLOTDESCRIPTOR' has been redefined
Function 'EXSLOTDESCRIPTORP' has been redefined
Function 'CREATEEXSLOTDESCRIPTOR' has been redefined
Functioil""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
>

1.7. Signums
1.7.1. SigNum Structure and "Constants"
Load BIG to get the bignum package. 2 The current PSL bignum package was written
using vectors of "Big Digits" or "Big its". The first element of each vector is either BIGPOS
or BIGNEG, depending whether the number is positive or negative. A bignum of the form
[BIGPOS abc d]
has a value of
a + b * bbase!* + c *

bbase!~:

** 2 + d *

bbase!~: *~!:

3

BBaseP'= is a fluid variable which varies from one machine to another.
the DEC-20, it is calculated as follows:

For the VAX and

bbits!* := (n-l )/2; bbase!* := 2 ** bbits!*;
"n" is the total number of bits per word on the given machine.

2 This section is adapted from a help file and· was written by Beryl Morrison.

On the DEC-20, n is 36,

Major Utilities
page 1.26

6 December 1983

PSL Manual
section 1.7

so bbits!* is 17 and bbase!* is 131072. On the -VAX, n is 32, so bbits!* is 15 and bbase!*
is 32768.

1.1.2. The Functions in BigBig
The functions defined by BigBig for bignums are as follows:
BLOr

Takes two
PoslfZero.

BigNum

arguments, returning

a bignum.

Calls BSize, GtPos,

BLXOr

Takes two BigNum
TrimBigNum 1.

arguments, returning

a bignum.

Calls

BlAnd

Takes two BigNum
TrimBigNum 1.

arguments, returning

a bignum.

Calls SSize, GtPos,

BLNot

Takes one BigNum argument, returning a bignum. Calls BMinus, BSmallAdd.

BLShift

Takes two BigNum arguments, returning a bignum.
BTwoPower, BMinus, BTimes2.

BMinus

Takes one BigNum argument, returning
BMinusP, GtPos, GtNeg.

BMinusP

Takes one BigNum argument, returning a bignum or NIl.

SPlus2

Takes two SigNum arguments,
BDifference2, BMinus, BPlusA2.

Calls BMinusP, BQuotient,

a bignum.

returning

a

BSize, GtPos,

Calls

bignum.

BleroP,

Calls

BSize,

BMinusP,

>BDifference BleroP, SMinus, BMinusP, BPlusA2, BDifference2.
STimes2

-BDivide

Takes two BigNum arguments, returning a bignum.
GtPos, GtNeg, BDigitTimes2, Poslflero, TrimBigNum 1.

Calls BSize, BMinusP,

Takes two BigNum arguments, returning a pair- of bignums. Calls BSize, GtPos,
BSimpleDivide, BHardDivide.

BGreaterP Takes two BigNum arguments, returning a bignum or NIl.
BDifference.

Calls BMinusP,

BLessP

Takes two BigNum arguments, returning a bignum or NIl.
BDifference.

Calls BMinusP,

BAdd1

Takes a BigNum argument, returning a bignum. Calls BSmallAdd.

BSubl

Takes a BigNum argument, returning a bignum. Calls BigSmaliDiff.

FloatFromBigNum
Takes -a bignum, returning a float.
BMinusP.

Calls BZeroP, BGreaterP, BLessP, BSize,

PSL Manual
section 1.7

6 December 1983

Major Utilities
page 1.27

BChanneiPrin2
Calls BigNumP, NonBigNumError, BSimpleDivide, BSize, BZeroP.
BRead

Calls GtPos, BReadAdd, BMinus.

BigFromFloat
Takes a float and converts to a bignum.
Calls BNum, BPlus2, BTimes2,
BTwoPower, FloatFromBigNum, BMinus, PoslfZero.
The following functions are support functions for those given above.
SetBits

Takes as an argument the total number of bits per word on a given machine;
sets some fluid variables accordingly.
NOTE:
FloatHi!~: must be changed
separately from this procedure by hand when moving to a new machine both
in bigbig.red and in bigface.red.
Calls TwoPower, BNum, BMinus, BSub 1,
BTwoPower, BAdd 1.

BigNumP

Checks if the argument is a bignum. Calls no special functions.

NonBigNumError
Calls no special functions.
BSize

Gives size of a bignum, i.e. total number of bigits (the tag "BIGPOS" or
"BIGNEG" is number 0). Calls BigNumP.

PoslfZero

Takes a bignum; if it is a negative zero, it is converted to a positive zero.
Calls BPosOrNegZeroP, BMinusP.

BPosOrNegZeroP
Takes a BigNum; checks if magnitude is zero. Calls BSize.
GtPos

Takes an inum/fixnum. Returns a vector of size of the argument; first (Le.Oth)
element is BIGPOS, others are NIL.

GtNeg

Takes an inum/fixnum. Returns a vector of size of the argument; first (Le.Oth)
element is BIGNEG, others are NIL.

TrimBigNum
Takes a BigNum as an argument; truncates any trailing "NIL"s.
NonBigNumError, TrimBigNum 1, BSize.

Calls BigNumP,

TrimBigNum 1
Does dirty work for TrimBigNum, with second argument the size of the
BigNum.
Big2Sys

Calls BLessP, BGreaterP, BSize, BMinusP.

TwoPower Takes and returns a fix/inurn. 2**n.
BTwoPowerTakes a fix/inurn or bignum, returns a bignum of value
Big2Sys, GtPos, TwoPower, TrimBigNum 1.

2~:*n.

Calls BigNumP,

Major Utilities
page 1.28

6·December 1983

BZeroP

Checks size of BigNum (0) and sign. Calls BSize, BMinusP.

BOneP

Calls BMinusP, BSize.

PSL Manual
section 1.7

BAbs· ... Calls. BMinusP,. BMinus.
BGeq

Calls BLessP.

BLeq

Calls BGreaterP.

BMax

Calls BGeq.

BMin

Calls BLeq.

BExpt

Takes a BigNum and a fix/inurn. Calls Int2B, BTimes2, BQuotient.

AddCarry

Support for trapping the carry in addition.

BPlusA2

Does the dirty work of addition of two BigNums with signs pre-checked and
identical. Calls BSize, GtNeg, GtPos, AddCarry, PoslfZero, TrimBigNum 1.

SubCarry

Mechanism to get carry in subtractions.

BDifference2
Does the dirty work of subtraction with signs pre-checked and identical.
BSize, GtNeg, GtPos, SubCarry, PoslfZero, TrimBigNum 1.

Calls

'SDigitTimes2
Multiplies the first argument (BigNum) by a single Bigit of the second BigNum
argument. Returns the partially completed result. Calls no special functions.
BSmaliTimes2
Takes a BigNum argument and a fixnum argument, returning a bignum.
GtPos, BMinusP, GtNeg, PoslfZero, TrimBigNum 1.

Calls

BQuotient . Takes two BigNum arguments, returning a bignum. Calls BDivide.
BRemainder
Takes two BigNum arguments, returning a bignurn. Calls BDivide.
BSimpleQuotient
Calls BSirnpleDivide.
BSirnpleRernainder
Calls BSimpleDivide.
BSimpleDivide
Used to divide a BigNum by an inurn. Returns a dotted pair of quotient and
remainder, both being bignums.
Calls BMinusP, GtPos, GtNeg, PoslfZero,
TrimBigNurn 1.
BHardDivide

6 December 1983

PSL Manual
section 1.7

Major Utilities
page 1.29

Used to divide two "true" BigNums. Returns a pair of bignums. Algorithm
taken from Knuth. Calls BMinusP, GtPos, GtNeg, BAbs, BSmaliTimes2, BSize,
BDifference, BPlus2, TrimBigNum 1, BSimpleQuotient, PoslfZero .
.- BReadAdd

Calls- BSmaliTimes2, BSmaliAdd.

BSmallAdd Adds an· inurn to a BigNum, returning a bignum.
Calls BZeroP, BMinusP,
BMinus, BSmallDiff, BSize, GtPos, AddCarry, PoslfZero, TrimBigNum 1.
BNum

Takes an inurn and returns a BigNum of one bigit; test that the inurn is less
than bbase!* is assumed done. Calls GtPos, GtNeg.

BSmaliDiff Calls BZeroP,
TrimBigNum1.
Int28

BMinusP,

BMinus,

BSmallAdd,

GtPos,

SubCarry,

Takes a fix/inurn and converts to a BigNum. Calls BNum, BRead.

PoslfZero,

PSt MANUAL
SECTION 2.0

6 DECEMBER 1983

MISCELLANEOUS UTILITIES
PAGE 2.1

CHAPTER 2
MISCELLANEOUS UTILITIES
_2.1.: Introduction . . .
--- - 2.2. Simulating a Stack
2.3. DefConst. . .
2.4. Hashing Cons. .
2.5. Graph-to-Tree
2.6. Inspect Utility.
2.7. If_System . . .
2.8. Profiler for Compiled Functions.
2.9. Timing Function Calls. . . . .
2.10. Parenthesis Checker . . . . .
2.11. A Simple Rational Function Evaluator
2.12. Undocumented Utilities. . . . . . .

2.1
2.1
2.2
2.2
2.3
2.4
2.5
2.5
2.8
2.9
2.9
2.10

2.1. Introduction
This chapter describes an ass,ortment of utility packages. It also provides a list of many
of the undocumented packages that reside on the utility directory with some indication of
their purposes.

2.2. Simulating a Stack
The following macros are in the USEFUL package.
deleting things from the head of a list.

(Push ITM:any STK:list): any

They are convenient for adding and

macro

(PUSH ITEM STACK)
is equivalent to

(SETF STACK

(CONS ITEM STACK»

(Pop STK:list): any
(POP STACK)
does

(SETF STACK (CDR STACK»

macro

Miscellaneous Utilities
page 2.2

6 December 1983

PSL Manual
section 2.2

and returns the· item popped off STACK. An additional argument may be
supplied to Pop, in which case it is a variable which is SetQ'd to the popped
value .

. 2.3. DefConst
(DefCons t [U: i d

V: number]): Undefined

macro

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 U: id): number

macro

They are referred to by the macro Const, so
(CONST FOOSIZE)
would be replaced by 3.

2.4. Hashing Cons
HCONS is a loadable module. The HCons function creates unique dotted pairs. In other
words, (HCons ~ ID Eq (HCons ~ Q) if and only if ~ Eq ~ and ~ Eq Q. This allows rapid
tests for equality between structures, at the cost of expending more time in creating the
structures. The use of HCons may also save space in cases where lists share common
substructure, since only one copy of the substructure is stored.
Hcons works by keeping a pair hash table of all pairs that have been 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.
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 of two large numbers may not be Eq to the
.",' HConsof tW.o.other numbers that appear to be the same. (Similar warnings hold for
strings and vectors.)

6 December 1983

PSL Manual
section 2.4

Miscellaneous Utilities
page 2.3

The following "user" functions are provided by HCONS:

(HCons [U:any]): pair

macro

- - The---HCons macro~ takes one or more 'arguments and returns their "hashed
----cons" -{right associatively).-With two arguments this corresponds to a call
of Cons.

(HList [U:any]): list
HList is the "HCONS version" of the List function.
(HCopy U: any): any

macro

HCopy is the HCONS version of the Copy function. Note that HCopy serves a
very different purpose than Copy, which is usually used to copy a structure
so that destructive changes can be made to the copy without changing the
original. HCopy only copies those parts of the structure which haven't
already been "Consed together" by HCons.
(HAppend U:list

V:list): list

The HCons version of Append.
(HReverse U: list): list
The HCons version of Reverse.
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. These functions are
known to the SetF macro.

(Extended-Put U:{id,pair}

IND:id

PROP:any): any

(Extended-Get U: {id,pair}

IND:any): any

2.5. Graph-to-Tree
GRAPH-TO-TREE is a loadable module.
circular lists.

PrintX obtained by loading DEBUG also prints

(Graph-to-Tree A:form): form
-- -The- function -Graph-to-Tree -copies an arbitrary s-expression, removing
-circularity. It. does NOT show non-circular shared -structure. Places where
a substructure is Eq to one of its ancestors are replaced by non-interned

Miscellaneous Utilities
page 2.4

6 December 1983

PSL Manual
section 2.5

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 A : any): NIL
The function CPrint, also defined in the module GRAPH-TO-TREE, is 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.

2.6. Inspect Utility
INSPECT is a loadable module. Currently INSPECT does not work in Lisp syntax.
(Inspect FILENAME:string):
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 online querying of certain 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 !*Printlnspect, 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:

6 December 1983

PSL Manual
section 2.6

Miscellaneous Utilities
page 2.5

(LOAD INSPECT)
(OFF PRINTINSPECT)
(INSPECTOUT)
(DSKIN ••• )
..... (DSKIN ••• )
(INSPECTEND)
2.7. If_System

(If_System ): any

macro

This is a compile-time conditional macro for system-dependent code.
FALSE-CASE can be omitted and defaults to NIL. SYS-NAME must be a
For the Dec-20,
member of the fluid variable System_List !*.
System_List!* is (Dec20 PDP10 Tops20 KL10). For the VAX it is (VAX
Unix VMUnix). Load IF_SYSTEM to use this macro. An example of its use
follows.
(de mail ()
{if_system tops20 (runfork ttSYS:MM.EXEtt)
(if_system unix (system "/bin/mail")
(stderror "Mail command not implemented"»»
2.8. Profiler for 'Compiled Functions

Load PROFILE to get a module that allows one to determine run times for compiled PSL
functions. 1 This version does not yet try to account for overhead of PROFILE itself.
USAGE: After loading PROFILE module:
will display default table, sorted alphabetically
This takes :KEYWORD options, any pair can
be omitted
e.g. PRINT!-PROFILE(!:MINCALLS,1,
%only show if called at least once
!:MINTIME,10,
%only show if time> 10 ms
! : NAMES , '(FOO FEE FUM»;
PROFILE fnlist;
Explicitly profiles functions in fnlist
UNPROFILE fnlist;
Explicitly unprofiles functions in fnlist
UNPROFILE '!:ALL;
Explicitly unprofiles ALL profiled functions
CLEAR!-PROFILE fnlist;Resets all counters for functions on FNLIST
CLEAR!-PROFILE '!:ALL; Resets ALL
will cause all new PUTD's to have PROFILE code added.
ON PROFILE;

PRINT!-PROFILE();

1Based on B. Hulshof's original version at RAND .... May 1983 Rewritten and optimized by M. Griss

Miscellaneous Utilities
page 2.6

OFF PROFILE;

6 December 1983

PSL Manual
section 2.8

will stop this redefinition, but will NOT change
already profiled code

A log of Profile's use on the Dec20 follows:

PSL Manual
section 2.8

6 December ·1983

RLisp

[Keeping rlisp]
Extended 20-PSL 3.1 RLisp, 15-Jun-83
[1] load "pnew:profile"j
NIL
[2] on profile;
NIL
[3] in nprofile-fns.red";
%Profile-fns.red
procedure top N;
«subcall N; subcall N»;
*** (TOP): base 1324652, length 10 words
TOP
procedure subcall N;
for i:=1:n do fac1 N;
*** (SUBCALL): base 1324672, length 10 words
SUBCALL
procedure fac1 n;
if n<=1 then 1 else n*fac2(n-1);
*** (FAC1): base 1324711, length 10 words
FAC1
procedure fac2 n;
if n<=1 then 1 else n*fac1(n-l);
*** (FAC2): base 1324726, length 10 words
FAC2
End;
NIL
[4] off profile;
NIL
[5] on time;
NIL
TIME: 1101 MS
[6] top 20;
NIL
TIME: 1662 MS
[7] print!-profile();

Miscellaneous Utilities
page 2.7

Miscellaneous Utilities
page 2.8

function
FAC1
FAC2
SUBCALL
- TOP
Total (4 fns):
NIL
TIME: 384 MS

6 December 1983

PSl Manual
section 2.8

calls
400
400

793
716

2
1

90

1599

2

1601

803

1601

time (ms)

tree-time (ms)
1509
1~32

2.9. Timing Function Calls
load TIME-FNC to get code to time function calls.

Usage:
do

(timef function-name-1 function-name-2 ••• )
Timef is a fexpr.
It will redefine the functions named so that timing information is
kept on these functions.
This information is kept on the prQperty list of the function name.
The properties used are 'time' and 'number-of-calls'.
(get function-name 'time) gives you the total time in the function.
(not counting gc time).
Note, this is the time from entrance to exit.
The timef function redefines the function with an
unwind-protect, so calls that are interrupted
by *throws are counted.
(get function-name 'number-of-calls) gives you the number of times
the function is called.
To stop timing do :
(untimef function-name1 •• )
or do (untimef) for all functions.
(untimef) is a fexpr.
To print timing information do
- (print-time-info function-name-1 function-name-2 •• )
or do (print-time-info) for timing information on all function names.
special variables used:
*timed-functions* : list of all functions currently being timed.

PSL Manual
section 2.9

6 December 1983

Miscellaneous Utilities
page 2.9

*all-timed-functions* : list of all functions ever timed in the
current session.
Comment: if tr is called on a called on a function that is already
. . being timed, and theo··untimef. is called on .the function, the
function will no longer be traced.
2.10. Parenthesis Checker
PCHECK "'{ill read a Lisp syntax (.SL) file, printing some of the top-level of each Sexpression. It is meant to survey the file, and if the file has unbalanced parensthesis, will
show where things get confused.
To use:

(LOAD PCHECK)
(PCHECK "foo.sl")
2.11. A Simple Rational Function Evaluator
POLY is a simple (pedagogic) Rational Function Evaluator.
After loading
expressions:

POLY, run

function

ALGGO;

or RATO; These accept a sequence

of

 ; I QUIT; (Semicolon terminator)
 ::=  [+  I - ]
 ::=  [*  I / ]
 ::=  [A  I ' 
is exponentiation, t is derivative
 ::=  I  I (  )
A

It includes a simple parser (RPARSE), 2 evaluators (RSIMP x) and (PRESIMP), and 2
prettyprinters, (RATPRINT) and (PREPRINT)

PREFIX Format:  I  I (op arg1 arg2)
+ -> PLUS2
- -> DIFFERENCE (or MINUS)
* -> TIMES2
/ -> QUOTIENT
_> EXPT
, -> DIFF
A

Canonical Formats: Polynomial:
term
power
Rational

integer I (term. polynomial)
(power • polynomial)
(variable • integer)
(polynomial. polynomial)

Miscellaneous Utilities
page 2.10

6 December 1983

PSL Manual
section 2.12

2.12. Undocumented Utilities
This section lists most of the utilities available in PSL that are not documented. Consult
the sources in directory pu: on the DEC-20, $pu on the VAX, or the utility directory on
'vour~system. These modules can be loaded.
ADDR21D

Converts a code pointer to a symbol (function name)

ASSOCIATION
Mutable association lists
CLCOMP1

Incompatible Common Lisp compatibility

COMMON

Compile-time and read-time support for Common Lisp compatibility

EVALHOOK Support for special evaluation
FAST-ARITH
Speed up generic arithmetic
FAST-EVECTORS
Fast-compiled evector operations
SLOW-STRINGS
Defines some string operations
FAST -STRINGS
Fast versions of the functions in SLOW-STRINGS
'STRINGX

Some useful string functions

STRING-INPUT
Input from strings
STRING-SEARCH
General purpose searches for substrings
UN-RLISP

Translates a program written in RLisp syntax into Lisp syntax

UTIL

General utility/support functions

EXTENDED-CHAR
Nine-bit terminal input characters
HASH

Hash table package

HEAP-STATS
Part of heap statistics gathering package
H-STATS-l Part of heap,statistics"gathering package
PARSE-COMMAND-STRING

PSL Manual
section 2.12

6 December 1983

Miscellaneous Utilities
page 2.11

Parse command string given at invocation of PSL
PROGRAM-COMMAND-INTERPRETER
Redefine startup routine to read command given at invocation of PSL
~PATHNAMEX

Useful functions involving pathnames
PSL -INPUT -STREAM
File input stream objects
PSL-QUTPUT-STREAM
File output stream objects

PSL MANUAL
SECTION 3.0

6 DECEMBER 1983

THE· OBJECTS MODULE
PAGE 3.1

CHAPTER 3
THE OBJECTS MODULE
.. 3.1. Introduction . . . . .
3.1.1. Defflavor. . . .
3.1.2. Creating Objects
3.1.3. Methods . . . .
3.1.4. Sanctity of Objects
3.2. Reference Information. .
3.2.1. Loading the Module.
3.2.2. Defflavor. . . . . .
3.2.3. Defmethod . . . . .
3.2.4. Creating New Instances of Flavors
3.3. Operating on Objects . . . .
3.4. Useful Functions on Objects. . . . .
3.5. Debugging Information . . . . . . .
3.6. Declare-Flavor and Undeclare-Flavor .
3.7. Representation Information . . . . .

3.1
3.2
3.2
3.3
3.3
3.3
3.3
3.4
3.5
3.6
3.7
3.9
3.9
3.9
3.10

3.1. Introduction
1 The OBJECTS module provides simple support for object-oriented programming in
PSL. It is based on the "flavors" facility of the Lisp Machine, which is the source of its
terminology. The Lisp Machine manual contains a much longer introduction to the idea of
object oriented programming, generic operations, and the flavors facility in particular.
This discussion goes over the basics of using flavored objects once briefly to give you an
idea of what is involved, then goes into details.

A datatype is known as a flavor (don't ask). The definition of a flavor can be thought of
in -two parts: the DEFFLAVOR form ("flavor definition"), plus a set of DEFMETHOD forms
("method definitions") for operating on objects of that flavor.
With the objects package the programmer completely controls what operations are to
be done on objects of each flavor, so this is a true object-oriented programming facility.
Also, all operations on flavored objects are automatically "generic" operations.
This
means that any programs you write that USE flavored objects have an extra degree of
built-in generality.
What does it mean to say that operations on flavored objects are generic? This means
that the operations can be done on an object of any flavor, just so long as the operations
are defined for that flavor of object. The same operation can be defined for many flavors,
and whenever the operation is invoked, what is actually done will depend on the flavor of

1This chapter is adapted from the file ph:objects.doc which was written by Cris Perdue and Alan Snyder

The Objects Module
page 3.2

6 December'1983

PSL Manual
section 3.1

the object it is being done to.
We may wish to write a scanner that reads a sequence of characters out of some
object and processes them. It does not need to assume that the characters are coming
.,from a, file,. or, even from an I/O-channel.
Suppose the scanner gets a character by invoking the GET-CHARACTER operation. In
this case any object of a flavor with a GET-CHARACTER operation can be passed to the
scanner, and the GET-CHARACTER operation defined for that object's flavor will be done
to fetch the character. This means that the scanner can get characters from a string, or
from a text editor's buffer, or from any object at all that provides a GET-CHARACTER
operation. The scanner is automatically general.

3.1.1. Defflavor
A flavor definition looks like:

(defflavor flavor-name (var1 var2 ••• ) () option1 option2 •.• )
'Example:

(defflavor complex-number

(real-part
(imaginary-part 0.0»
()

gettable-instance-variables
initable-instance-variables
)
A flavor definition specifies the fields, components, or in our terminology, the "instance
variables" that each object of that flavor is to have. The mention of the instance variable
imaginary-part indicated that by default the imaginary part of a complex number will be
initialized to 0.0. There is no default initialization for the real-part.
Instance variables may be strictly part of the implementation of a flavor, totally invisible
'to users. Typically though, some of the instance variables are directly visible in some
way to the user of the object.
The flavor definition may specify "initable-instancege
variables", " ttable-instance-variables", and "settable-instance-variables".
None, some
of, or all of the instance variables may be specified in each option.

3.1.2. Creating Objects
The function MAKE-INSTANCE provides a convenient way to create objects of any flavor.
Theflav.or of the object to be created and the initializations to be done are given as
. parameters in ··a-waythat is fully independent of the internal representation of the object.

PSL Manual
section 3.1

6 December 1983

The Objects Module
page 3.3

3.1.3. -Methods
The function "=>", whose name is intended to suggest the sending of a message to an
object, is usually used to invoke a method.
Examples:

(=>
(=>

my-object zap)
thing1 set-location 2.0 3.4)

The first "argument" to => is the object being operated on: my-object and thing 1 in the
examples. The second "argument" is the name of the method to be invoked: zap and setlocation.
The method name IS NOT EVALUATED.
Any further arguments become
arguments to the method. (There is a function SEND which is just like => except that the
method name argument is evaluated just like everything else.)
Once an object is created, all operations on it are performed by "methods" defined for
objects of its flavor. The flavor definition itself also defines some methods. For each
"gettable" instance variable, a method of the same name is defined which returns the
current value of that instance variable. For "settable" instance variables a method named
"set-" is defined.
Given a new value for the instance variable, the
method sets the instance variable to have that value.

3.1.4. Sanctity of Objects
Most Lisps and PSL in particular leave open the possibility for the user to perform illicit
operations on Lisp objects. Objects defined by the objects package are represented as
ordinary Lisp objects (evectors at present), so in a sense it is quite easy to do illicit
operations on them: just operate directly on its representation (do evector operations).
On the other hand, there are major practical pitfalls in doing this. The representation of
a flavor of objects is generated automatically, and there is no guarantee that a particular
flavor definition will result in a particular representation of the objects. There is also no
guarantee that the representation of a flavor will remain the same over time. It is likely
that at some point evectors will no longer even be used as the representation.
In addition, using the objects package is quite convenient, so the temptation to operate
on the underlying representation is reduced.
For debugging, one can even define a
couple of extra methods "on the fly" if need be.

3.2. Reference Information
3.2.1. Loading the Module
NOTE: -THIS FILE DEFINES BOTH MACROS AND ORDINARY LISP FUNCTIONS. IT MUST BE
----LOADED BEFORE ANY OF -THESE FUNCTIONS ARE USED. The recommended way of doing

The Objects Module
page 3.4

6 December 1983

PSL Manual
section 3.2

this is to put the expression

(BothTimes (load objects»
atthe·beginning of-your source file .. This will· cause the~package to be loaded at both
compile and load time.

3.2.2. Defflavor
The macro DEFFLAVOR is used to define a new flavor of object.

(defflavor name:id instance-variables:list
mixin-flavors: NIL [option: form]): id-list
Examples:

(defflavor complex-number (real-part imaginary-part) ()
gettable-instance-variables
initable-instance-variables
)

(defflavor complex-number «real-part 0.0)
(imaginary-part 0.0)
)

()
gettable-instance-variables
(settable-instance-variables real-part)
)
The INSTANCE-VARIABLES form a list. Each member of the list is either a
symbol (id) or a list of 2 elements. The 2-element list form consists of a
symbol and a default initialization form.
Note: Do not use names like "IF" or "WHILE" for instance variables: they are
translated freely within method bodies (see DEFMETHOD). The translation
process is not very smart about which occurrences of the symbol for an
instance variable are actually uses of the variable, though it does
understand the nature of QUOTE.
The MIXIN-FLAVORS list must be empty. In the Lisp Machine flavors facility,
this may be a list of names of other flavors.
Recognized options are:

macro

6 December 1983

PSL Manual
section 3.2

(GETTABLE-INSTANCE-VARIABLES
(SETTABLE-INSTANCE-VARIABLES
(INITABLE-INSTANCE-VARIABLES
•

_ .c_

var1 var2
var1 var2
var1 var2

GET! ABLE- INSTANCE~ VARIABLES . [make
SETTABLE-INSTANCE-VARIABLES· ·[make
INITABLE-INSTANCE-VARIABLES [make

The Objects Module
page 3.5

· .. )
· .. )
· .. )

all instance variables
all instance variables
all instance variables

GETTABLE]
SETTABLE]
INITABLE]

An empty list of variables is taken as meaning all variables rather than
none, so (GETTABLE-INSTANCE-VARIABLES) is equivalent to GETTABLEINSTANCE-VARIABLES.
For each gettable instance variable a method of the same name is
generated to access the instance variable. If instance variable LOCATION is
gettable, one can invoke (:>  LOCATION).
For each settable instance variable a method with the name SET-
is generated. If instance variable LOCATION is settable, one can invoke (:>
 SET-LOCATION  socket assert-as-plugged-in self»

3.2.4. Creating New I-nstances of Flavors
There are two ways to create a new instance of a flavor:
Instantiate-Flavor.

use Make-Instance or

(make-instance flavor-name:id [instance-var:id init-val:any]): object
MAKE-INSTANCE takes as arguments a flavor name and an optional sequence
of initializations, consisting of alternating pairs of instance variable names
and corresponding initial values. Note that all the arguments are evaluated.
It returns an object of the specified flavor.
Examples:
(setq x (make-instance 'complex-number»
(setq y (make-instance 'complex-number 'real-part 0.0
'imaginary-part 1.0»
Initialization of a newly made object happens as follows:
Each instance variable with initialization specified in the call to makeinstance is initialized to the value given.
Any instance variables not
initialized in this way, but having default initializations specified in the flavor
definition are initialized by the default initialization specified there. All other
instance variables are initialized to the symbol *UNBOUND*.
If a method named INIT is defined for this flavor- of object, that method is
The INIT
invoked automatically after the initializations just discussed.
method is passed as its one argument a list of alternating variable names
and initial values. This list is the result of evaluating the initializations
given to make-instance. For example, if we call:
(make-instance 'complex-number 'real-part (sin 30)
-, imaginary;;.;par t (cos 30»

macro

6· December 1983

PSL Manual
section 3.2

The Objects Module
page 3.7

then the argument to the INIT method (if any) would be
(real-part

.5

imaginary-part

.866).

The INIT· method may· do' anything desired' to' set up the desired initial state
of the object.
At present, this value passed to the INIT method is of virtually no use to
the INIT' method since the values have been stored into the instance
variables already.
In the future, though, the objects package may be
extended to permit keywords other than names of instance variables to be
in the initialization part of calls to make-instance. If this is done, INIT
methods will be able to use the information by scanning the argument.

(Instantiate-Flavor flavor-name:id init-list:list): object
This is the same as Make-Instance, except that the initialization list is
provided as a single (required) argument.
Example:
(instantiate-flavor 'complex-number
(list 'real-part (sin 30) 'imaginary-part (cos

30»)

3.3. Operating on Objects
Operations on an object are done by the methods of the flavor of the object. We say
that a method is invoked, or we may say that a message is sent to the object. The
notation suggests the sending of messages. In this metaphor, the name of the method to
use is part 'of the message sent to the object, and the arguments of the method are the
rest of the message. There are several approaches to invoking a method:

* = > A convenient form for sending a message. Examples:
(=> r real-part)
(=> r set-real-part 1.0)
The message name is not quoted. Arguments to the method are supplied as
arguments to =>. In these examples, r is the object, real-part and set-realpart are the methods, and 1.0 is the argument to the set-real-part method.

*

SEND Send a message in which the message is evaluated. Examples:

The Objects Module
page 3.8

6 December 1983

PSL Manual
section 3.3

(send r 'real-part)
(send r 'set-real-part 1.0)
.:The meanings ·of,·these'two examples are -the same .as the meanings of the
-- previous two. Only the syntax is different: the ·message name is quoted.

*

SEND-IF-HANDLES Conditionally Send a Message (Evaluated Message Name)
Examples:

(send-if-handles r 'real-part)
(send-if-handles r 'set-real-part 1.0)
SEND-IF-HANDLES is like SEND, except that if the object defines no method to
handle the message, no error is reported and NIL is returned.

*

LEXPR-SEND Send a Message (Explicit "Rest" Argument List) Examples:

(lexpr-send foo 'bar abc list)
The last argument to LEXPR-SEND is a list of the remaining arguments.

* LEXPR-SEND-IF-HANDLES This is the same as LEXPR-SEND, except that no
error is reported if the object fails to handle the message.

* LEXPR-SEND-1 - Send a Message (Explicit Argument List) Examples:

(lexpr-send-1 r 'real-part nil)
(lexpr-send-1 r 'set-real-part (list 1.0»
Note that the message name is quoted and that the argument list is passed
as a single argument to LE~PR-SEND-l.

*

LEXPR-SEND-1-IF-HANDLES This is the same as LEXPR-SEND-l, except that
no error is reported if the object fails to handle the message.

*

EV-SEND - EXPR form of LEXPR-SEND-1 EV-SEND is just like LEXPR-SEND-l,
except that it is an EXPR instead of a MACRO. Its sole purpose is to be used
as a run-time function object, for example, as a function argument to a
function.

PSL Manual
section 3.4

6 December 1983

The Objects Module
page 3.9

3.4. Useful Functions on Objects
(Object-Type object:id): id,NIL
-- The--Object-Type function returns the 'type (anlQL-of the specified object, or
NIL, if the argument is not an object. At present this function cannot be
guaranteed to distinguish between objects created by the OBJECTS package
and other Lisp entities, but the only possible confusion is with vectors or
evectors.

3.5. Debugging Information
Any object may be displayed symbolically by invoking the method DESCRIBE, e.g., (= > x
describe). This method prints the name of each instance variable and its value, using the
ordinary Lisp printing routines. Flavored objects are liable to be complex and nested
deeply or even circular. This makes it often a good idea to set PRINLEVEL to a small
integer before printing structures containing objects to control the amount of output.
When printed by the standard Lisp printing routines, "flavored objects" appear as
evectors whose zeroth element is the name of the flavor.
For each method defined, there is a corresponding Lisp function named $. Such function names show up in backtrace printouts.
It is permissible to define new methods on the fly for debugging purposes.

3.6. Declare-Flavor and Undeclare-Flavor

*** Read these warnings carefully! ***
This facility can reduce the overhead of invoking methods on particular variables, but it
should be used sparingly. It is not well integrated with the rest of the language. At
some point a proper declaration facility is expected and then it will be possible to make
declarations about objects, integers, vectors, etc., all in a uniform and clean way.
The DECLARE-FLAVOR macro allows you to declare that a specific symbol is bound to
an object of a specific flavor. This allows the flavors implementation to eliminate the
run-time method lookup normally associated with sending a message to that variable,
which can result in an appreciable improvement in execution speed. This feature is
motivated solely by efficiency considerations and should be used ONLY where the
performance improvement is critical.
Details: if you declare the variable X to be bound to an object of flavor FOO, then
WITHIN THE CONTEXT OF THE DECLARATION (see below), expressions of the -form (= > X
GORP ... ) or (SEND X 'GORP ... ) will be replaced by function invocations of the form
(FOO$GORP X ... ). Note that there is no check made that the flavor FOO actually contains
a method GORP. If -it does not, then a run-time error "Invocation of undefined function
FOO$GORP" will be reported.

The Objects Module
page 3.10

6 December 1983

PSL Manual
section 3.6

WARNING: The DECLARE-FLAVOR feature is not presently well integrated with the
compiler. Currently, the DECLARE-FLAVOR macro may be used only as a top-level form,
like the PSL FLUID declaration.
It takes effect for all code evaluated or compiled
henceforth. Thus, if you should later compile a different file in the same compiler, the
":.:;declaration will still be .in effect! . THIS· IS·A DANGEROUS CROCK, SO BE CAREFUL! To
avoid problems, I recommend that DECLARE-FLAVOR be used only for uniquely-named
variables. The effect of a DECLARE-FLAVOR can be undone by an UNDECLARE-FLAVOR,
which also may be used only as a top-level form. Therefore, it is good practice to
bracket your code in the source file with a DECLARE-FLAVOR and a corresponding
UNDECLARE-FLAVOR.
Here are the syntactic details:
(DECLARE-FLAVOR FLAVOR-NAME VAR1 VAR2 ... ) (UNDECLARE-FLAVOR VAR1 VAR2 ... )

***

Did you read the above warnings???

***

3.7. Representation Information
(You don't need to know any of this to use this stuff.)
A flavor-name is an ID. It has the following properties:
VARIABLE-NAMES
A list of the instance variables of the flavor, in order of their location in the
instance evector. This property exists at compile time, dskin time, and load
time.
~NITABLE-VARIABLES

A list of the instance variables that have been declared to be INITABLE.
property exists at dskin time and at load time.

This

METHOD-TABLE
An association list mapping each method name (ID) defined for the flavor to
the corresponding function name (ID) that implements the method.
This
property exists at dskin time and at load time.
INSTANCE-VECTOR-SIZE
An integer that specifies the number of elements in the evector that
represents an instance of this flavor. This property exists at dskin time and at
load time. It is used by MAKE-INSTANCE.
The function that implements a method has a name of the form FLAVOR$METHOD. Each
such function ID has the following properties:
SOURCE-CODE
A list· of the form (LAMBDA (SELF ... ) ..• ) which is the untransformed source
·:code for the method. This -propertvexists at compile time and dskin time.

PSL Manual
section 3.7

6 December 1983

The Objects Module
page 3.11

Implementation Note:
A tricky aspect of the code that implements the objects package is making sure that the
right things happen at the right time. When a source file is read and evaluated (using
- -DSKIN), then· everything must ....happen at once; However, when a···source file is compiled
to produce a FASL file~then some actions -must be performed at compile-time, whereas
other actions are supposed to occur when the FASL file is loaded. Actions to occur at
compile time are performed by macros; actions to occur at load time are performed by
the forms returned by macros.
Another goal of the implementation is to avoid consing whenever possible during
method invocation. The current scheme prefers to compile into (APPLY HANDLER (LIST
args ... )), for which the PSL compiler will produce code that performs no consing.

PSL MANUAL
SECTION 4.0

6 DECEMBER 1983

EDITOR
PAGE 4.1

CHAPTER 4
EDITORS
. 4.1; A Mini Structure-Editor .. , . .......
4.2; TheEMODE Screen Editor . . .,,_. .... .
4.2.1. Windows and Buffers in Emode. .
4.3. Introduction to the Full Structure Editor.
4.3.1. Starting the Structure Editor.
4.3.2. Structure Editor Commands . . .
A.

.',.

•

• •, .

_.

4.1
4.2

.'

4.5
4.5
4.5

.'

4.6

4.1. A Mini Structure-Editor
PSL and RLisp provide. a fairly simple structure editor, essentially a subset of the
structure editor described below in section 4.3. This mini editor is usually resident in PSL
and RLisp, or can be LOADed. It is useful for correcting errors in input, often via the E
option in the BREAK loop. Do HELP(ED1TOR) for more information.
To edit an expression, call the function Edi t with the expression as an argument. The
edited copy is returned. To edit the definition of a function, call Edi tF with the function
name as an argument.
In the editor, the following commands are available (N indicates a non-negative integer):

P
Prints the subexpression under consideration. On entry, this is the entire
expression.
This only prints down PLevel levels, replacing all edited
subexpressions by ***. Plevel is initially 3.

PL (00
Changes PLEVEL to

N.

N:integer

edit-command

Sets the subexpression under consideration to be the nth subexpression of
the current one. That is, walk down to the nth subexpression.
-N:integer
Sets the current subexpression to be the nth Cdr of the current one.

UP
Go to the subexpression you were in just before this one.

edit-command

6 December 1983

EDITOR
page 4.2

PSL Manual
section 4.1

T
Go to the top of the original expression.

Find the first occurrence of the S-expression~. The test is performed by
Equal, not Eq. The current level is set to the first level in which ~ was
found.
(N:integer)

edit-command

Delete the Nth element of the current expression.
(N:integer [ARG1)

edit-command

Replace the Nth element by ARGs.
(-N:integer [ARG])

edit-command

Insert the elements ARGs before the nth element.

,(R S1 S2)

Replace all occurrences of 51 (in the tree you are placed at) by S2.

B
Enter a Break loop under the editor.

OK
Leave the editor, returning the edited expression.

HELP
Print an explanatory message.
If the editor is called from
ErrorForm! *.

a Break loop, the edited value is assigned back to

4.2. The EMODE Screen Editor
EMODE is an EMACS-like screen editor, written entirely in PSL. To invoke EMODE, call
the function EMODE after LOADing the EMODE module. EMODE is modeled after EMACS,
so use that fact as a guide.
After starting up EMODE i . you can' use one of the ·following commands to exit.

6 December 1983

PSL Manual
section 4.2

EDITOR
page 4.3


"quits" to the EXEC (you can continue or start again).

goes back into "normal" I/O mode.
EMODE is built to run -on ··a Teleray terminal as the default. To use some other terminal
you must LOAD in a set of different driver functions after loading EMODE. The following
drivers are currently available:

* HP2648A
* TELERAY
* VT100
* VT52
* AAA [Ann Arbor Ambassador]
The sources for these files are on < PSl.EMODE > (logical name PE:). It should be quite
easy to modify one of these files for other terminals.
See the file PE:TERMINALDRIVERS.TXT for some more information on how this works.
An important (but currently somewhat bug-ridden) feature of EMODE is the ability to
evaluate expressions that are in your buffer. Use < Meta-E > to evaluate the expression
starting on the current line.
< Meta-E > (normally) automatically enters two window
mode if anything is "printed" to the OUT_WINDOW buffer, which is shown in the lower
window. If you don't want to see things being printed to the output window, you can set
the variable !*OUTWINDOW to NIl. (Or use the Rlisp command "OFF OUTWINDOW;".)
This prevents EMODE from automatically going into two window mode if something is
printed to OUT_WINDOW. You must still use the "< Ctrl-X > 1" command to enter one
window mode initially.
You may also find the  command useful.
buffer the text printed as a result of the last < Meta-E >.

This inserts into the current

The function "PrintAIIDispatch" prints out the current dispatch table.
EMODE before this table is set up.

You must call

While in EMODE, the  (meta-question mark) character asks for a command
character and tries to print information about it.
The basic dispatch table is (roughly) as follows:

Character






. Linefeed



Function

Comments

SETMARK
!$BEGINNINGOFLINE
!$BACKWARDCHARACTER
!$DELETEFORWARDCHARACTER
!$ENDOFLINE
!$FORWARDCHARACTER
!$CRLF
Acts like carriage return
KILL LINE
FULLREFRESH

EDITOR

6 December 1983

page 4.4

Return





section 4.2

!$CRLF
!$FORWARDLINE
OPENLINE
!$BACKWARDLINE








PSL Manual

DOWNWINDOW
KILL REGION
!$DOCNTRLX

Backward search for string, type
:acarriage return to terminate
the string
Forward search for string
Repea t a command. Asks"· for
count (terminate with a carriage
return), then it asks for the
command character

As in EMACS,  is a
prefix for "fancier" commands

INSERT KILL BUFFER
Yanks back killed text

DOCONTROLMETA
As in EMACS, acts like

escape
ESCAPEASMETA
As in EMACS, escape acts like
the  key
rubout
!$DELETEBACKWARDCHARACTER

BACKWARD SEXPR

FORWARD SEXPR

KILL FORWARD SEXPR

INSERT- LAST- EXPRESSION Insert the last "expression"
typed as the result of a


OLDFACE
Leave EMODE, go back to
"regular" RLISP
 KILL BACKWARD SEXPR

!$BEGINNINGOFBUFFER
As in EMACS, move to beginning
of buffer

!$HELPDISPATCH
Asks for a character, tries to
print information about it

BACKWARD WORD

KILL FORWARD WORD

Evaluate an expression

UPWINDOW
As in EMACS, move up a window

COpy REGION

!$DOMETAX
As in EMACS,  is another
prefix for "fancy" stuff

UNKILL PREVIOUS
As in EMACS

KILL BACKWARD WORD
  PRINTBUFFERNAMES
Prints a list of buffers
  CNTRLXREAD
Read a file' into the buffer
  CNTRLXWRITE
Write the buffer out to a file
  EXCHANGEPOINTANDMARK
 
As in EMACS, exits to the EXEC
 1
ONEWINDOW
Go into one window mode
 2
TWOWINDOWS
Go into two window mode
 B
CHOOSE BUFFER
EMODE asks for a buffer name,
and then puts you in that buffer
 0
OTHERWINDOW
Select other window
.;,-· p'
. WRITESCREENPHOTO
·Wrl.te. a'''photograph'' of the
screen to a file

6 December 1983

PSL Manual
section 4.2

EDITOR
page 4.5

4.2.1. Windows and Buffers in Emode
[??? This section to be completed at a later date. ???]

4.3.: Introduction to the Full Structure Editor
PSL also provides an extremely powerful form-oriented editor 1. This facility allows the
user to easily alter function definitions, variable values and property list entries.
It
thereby makes it entirely unnecessary for the user to employ a conventional text editor in
the maintenance of programs. This document is a guide to using the editor. Certain
features of the UCI LISP editor have not been incorporated in the translated editor, and
we have tried to mark all such differences.

4.3.1. Starting the Structure Editor
This section describes normal user entry to the editor ·{with the Edi tF, Edi tP and Edi tV
fuunctions} and the editing commands which are available. This section is by no means
complete. In particular, material covering programmed calls to the editor routines is not
treated. Consult the UCI LISP manual for further details.
To edit a function named FOO do

*(EDITF FOO)
To edit the value of an atom named BAZ do

*(EDITV BAZ)
To edit the property list of an atom named FOOBAZ do

*(EDITP FOOBAZ)
These functions are described later in the chapter.
Warning:
Editing the property list of an atom may position pointers at unprintable
structures. It is best to use the F (find) command before trying to print property lists.
This editor capability is variable from implementation to implementation.
The editor prompts with

-E-

*
You can then input any editor command. The input sc~nner is not very smart. It
terminates its scan and begins processing when it sees a printable character immediately

1This version of. the· UCI LISP editor was translated toto Standard LISP by Tryg Ager and Jim MacDonald of IMSSS.
Stanford, and adapted to PSl by E. Benson.

The UCI LISP editor is derived from the Interlisp editor.

EDITOR
page 4.6

6 December 1983

PSL Manual
section 4.3

followed by a carriage return. Do not use escape to terminate an editor command. If the
editor seems to be repeatedly requesting input type P< ret> (print the current expression)
or some other command that ordinarily does no damage, but terminates the input
solicitation .
... ·ThefolioWing set of topics makes a good "first glance" at the editor.
Entering the editor:
Leaving. the editor:
Editor's attention:
Changing attention:
Printing:
Modification:
Changing parens:
Undoing changes:

EDITF, EDITV.
OK.
CURRENT -EXP.
paS-INTEGER, NEG-INTEGER, 0, ", NX, BK.
P, PP.
paS-INTEGER, NEG-INTEGER, A, B, :, N.
BI, BO.
UNDO.

For the more discriminating user, the next topics might be some of the following.
Searches:
Complex commands:
Changing parens:
UndOing changes:

PATTERN, F, BF.
R, SW, XTR, MBD, MOVE.
L1, LO, RI, RD.
TEST, UNBLOCK, !UNDO.

Other features should be skimmed but not studied until it appears that they may be
useful.

4.3.2. Structure Editor Commands
Note that arguments contained in angle brackets

<>

are optional.

A ([ARG])
This command inserts the ARGs (arbitrary LISP expressions) 8fter the
current expression. This is accomplished by doing an UP and a (-2 exp 1
exp2 ... expn) or an (N exp 1 exp2 ... expn), as appropriate. Note the way in
which the current expression is changed by the UP.
B ([ARG])

This command inserts the ARGs (arbitrary LISP forms) ~efore the current
expression. This is accomplished by dOing an UP followed by a (-1 exp1
exp2 ... expn). Note the way in which the current expression is changed by
the UP.

PSL Manual
section 4.3

6 December 1983

EDITOR
page 4.7

BELOW (COM, )

Also can be used as:
BF PAT

This command performs a ~ackwards find, searching for PAT (an edit
pattern). Search begins with the expression immediately before the current
expression and proceeds in reverse print order. (If the current expression is
the top level expression, the entire expression is searched in reverse print
order.)
Search begins at the end of each list, and descends into each
element before attempting to match that element.
If the match fails,
proceed to the previous element, etc. until the front of the list is reached.
At that point, BF ascends and backs up, etc.
The search algorithm may be slightly modified by use
argument. Possible FLGs and their meanings are as follows.
T

NIL

of a second

begins search with the current expression rather than with the
preceding expression at this level.
or missing - same as BF PAT.

NOTE: if the variable UPFINDFLG is non-NIL, the editor does an UP after the
expression matching PAT is located. Thus, dOing a SF for a function name
yields a current expression which is the entire function call. If this is not
desired, UPFINDFLG may be set to NIl. UPFINDFLG is initially T.

SF is protected from circular searches by the variable MAXLEVEL. If the total
number of Cars and Cdrs descended into reaches MAXLEVEL (initially 300),
search of that tailor element is abandoned exactly as though a complete
search had failed.

BI (N1, N2)
This command inserts a pair of parentheses in the current expression; i.e. it
is a !!alanced !nsert.. (Note that parentheses ,are ALWAYS balanced, and
hence must be added or· removed in pairs.) A left parenthesis is inserted
before element N 1 of the current expression. A right parenthesis is inserted

EDITOR
page 4.8

6 December 1983

PSL Manual
section 4.3

after element N2 -of the current expression. 80th. N 1 and N2 are usually
integers, and element N2 must be to the right of element N 1.
(BI n 1) is equivalent to (BI n 1 n 1).
The .:NTH···command: is.used.in the. search, so thatNl and N2 may be any
location specifications. The expressions used are the first element of the
current expression in which the specified form is found at any level.

BIND ([COM])
This command provides the user with temporary variables for use during
the execution of the sequence of edit commands coms. There are three
variables available: # 1, #2 and #3. The binding is recursive and BIND may
be executed recursively if necessary. All variables are initialized to NIL.
This feature is useful chiefly in defining edit macros.

BK
The current expression becomes the expression immediately preceding the
present current expression; i.e. §!ack !J.p. This command generates an error
if the current expression is the first expression in the list.

BO (W
The BO command removes a pair of parentheses from the Nth element of
the current expression; i.e. it is a ~alanced RemQve. The parameter N is
usually an integer. The NTH command is used in the search, however, so
that any location specification may be used. The expression referred to is
the first element of the current expression in which the specified form is
found at any level.

(CHANGE LOC To [ARG])
This command replaces the current expression after executing the location
specification LOC by ARGs.

(COMS [ARG])
This command evaluates its ARGs and executes them as edit commands.

(COMSQ [ARG])
This command executes each ARG as an edit command.
At any ·given time, the attention ·of the ·editor is focused on a single· expression or form.
We. call· that form· the current-expression. Editor commands may be· divided into two
broad classes.
Those commands which change the current expression are called

PSL Manual
section 4.3
attention- changing commands.
structure modification commands.

6 December 1983

EDITOR
page 4.9

Those commands which modify structure are called

DELETE

edit
This command deletes the current expression. If the current expression is a
tail, only the first element is deleted. This command is equivalent to (:).

(E FORM 
This command inserts a left parenthesis (and, of course, a matching right
parenthesis); i.e. .beft Parenthesis insert. The left parenthesis is inserted
before the Nth element of the current expression and the right parenthesis
at the end of the current expression. Thus, this command is equivalent to
(BI n -1).
The NTH command is used in the search, so that N, which is usually an
integer, may be any location specification. The expression referred to is the
first element of the current expression which contains the form specified at
any level.

(LO

~J

This command removes a left parenthesis (and a matching right parenthesis,
of course) from the Nth element of the current expression; i.e.
.beft
Parenthesis RemQve. All elements after the Nth are deleted.
The command uses the NTH command for the search. The parameter N,
which is usually an integer, may be any location specification.
The
expression actually referred to is the first element of the' current expression
which contains the -specified form at any depth.
Many of the more complex edit commands take as an argument a location specification

PSL Manual
section 4.3

6 December 1983

EDITOR
page 4.13

(abbreviated LOC throughout this document). A- location specification is a list of edit
commands, which are, with two exceptions, executed in the normal way. Any -command
not recognized by the editor is treated as though it were preceded by F. Furthermore, if
one of the commands causes an error and the current expression has been changed by
prior commands~the -location operation continues;-rather·-than aborting. This is a sort of
_. back-up operation. For -example, -suppose the location specification is (COND 2 3), and
the first clause of the first Cond has only 2 forms. The location operation proceeds by
searching for the next Cond and trying again. If a point were reached in which there were
no more Conds, the location operation would then fail.
(LP COMS)
This command, useful in macros, repeatedly executes COMS (a sequence of
edit commands) until an editor error occurs; i.e. .booQ. As LP exits, it prints
the number of OCCURRENCES; that is, the number of times COMS was
successfully executed.
After execution of the command, the current
expression is left at what it was after the last complete successful
execution of CO MS.
The command terminates if the number of iterations exceeds the value of
the variable MAXLOOP (initially 30).

jLPQ COMS)
This command, useful in macros, repeatedly executes COMS (a sequence of
edit commands) until an editor error occurs; i.e.
.booQ Quietly.
After
execution of the command, the current expression is left at what it was
after the last complete successful execution of COMS.
The command terminates if the number of iterations exceeds the value of
the variable MAXLOOP (initially 30).
This command is equivalent to LP, except that OCCURRENCES is not printed.
(M (NAM) ([EXP) COMS)])

This can also be used as:
(M NAM COMS)

or as:
(M (NAM) ARG COMS)
The editor provides the user with a macro facility; i.e. M. The user may
define frequently used command sequences to be edit macros, which may
then be invoked simply -by giving the macro name as an edit command.
·~·--..The~M~command-provides the-user with a methodof.defining edit macros.
The first alternate form of the command defines an atomic command which

EDITOR
page 4.14

6 December 1983

- PSL Manual
section 4.3

takes no arguments. The argument NAM is the atomic name of the macro.
This defines NAM to be an edit macro equivalent to the sequence of edit
commands CaMS. If NAM previously had a definition as an edit macro, the
new definition replaces the old.
NOTE:
Edit command names take
- precedence- ·over macros.
It is not possible:to-~-.. redefine -edit command
names.
The main form of the M command as given above defines a list command,
which takes a fixed number of arguments. In this case, NAM is defined to
be an edit macro equivalent to the sequence of edit commands CaMS.
However, as (nam exp 1 exp2 ... expn) is executed, the expi are substituted
for the corresponding argi in CaMS before CaMS are executed.
The second alternate form of the M command defines a list command
which may take an arbitrary number of arguments. Execution of the macro
NAM is accomplished by substituting (exp 1 exp2 .... expn) (that is, the Cdr of
the macro call (nam exp 1 exp2 _.. expn)) for all occurrences of the atom
ARG in CaMS, and then executing CaMS.

(MAKEFN (NAM VARS) ARGS Nl  To COM )
The MOVE command allows the user to Move a structure from one point to
another. The user may specify the form to be moved (via LaC 1, the first
location specification), the position to which it is to be moved (via LOC2,
the second location specification) and the action to be performed there (via
COM). The argument COM may be BEFORE, AFTER or the name of a list
command (e.g. :, N, etc.). This command performs in the following manner.
Take the current expression after executing LOC1 (or its first element, if it is
a tail); call it expr. Execute LOC2 (beginning at the current expression AS
OF ENTRY TO MOVE -- NOT the expression which would be current after
execution of LOC1), and then execute (COM expr). Now go back and delete
expr from its original position. The current expression is not changed by
this command.
If LOC1 is NIL (that is, missing), the current expression is moved. In this
case, the current expression becomes the result of the execution of (COM
expr).
If LOC2 is NIL (that is missing) or HERE, then the current expression
specifies the point to which the form given by LOC2 is to be moved.
(N [EXP])

This command adds the EXPs to the end of the current expression; i.e. Add
at End. This compensates for the fact that the negative integer command
does not allow insertion after the last element.

(-N:integer

[EXP])

edit-command

Also can be used as:

-N
This is really two separate commands. The atomic form is an attention
changing command. The current expression becomes the nth form from
the end of the old current expression; i.e. Add Before ED.d. That is, -1
specifies the last element, -2 the second from last, etc.
The list form of the command is a structure modification command. This
command inserts exp 1 through expn (at least one expi must be present)
before the nth element (counting from the BEGINNING) of the current
- expression-.
That is, -1 inserts _ before the. first element, -2 before the
second, etc.

EDITOR
page 4.16

6 December 1983

PSL Manual

section 4.3

(NEX COM)
Also can be used as:

NEX
This- command is equivalent to (BELOW COM) followed -by NX. That is, it does
repeated Os until a current expression matching com is found. It then backs
off by one 0 and does a NX.
The atomic form of the command is equivalent to {NEX J. This is useful if
the user is dOing repeated {NEX x)s. He can MARK at x and then use the
atomic form.

(NTH LOC)
This command effectively performs (LeL LOC), (BELOW <), UP. The net effect
is to search the current expression only for the form specified by the
location specification LOC. From there, return to the initial level and set the
current expression to be the tail whose first element contains the form
specified by LOC at any level.

·.(NX

~J

Also can be used as:

NX
The atomic form of this command makes the current expression the
expression following the present current expression (at the same level); i.e.
Ne!!t.
The Jist form of the command is equivalent to n (an integer number)
repetitions of NX. If an error occurs (e.g. if there are not N expressions
following the current expression), the current expression is unchang.ed.

OK
This command causes normal exit from the editor.
The state of the edit is saved on property LASTVALUE of the atom EDIT. If
the next form edited is the same, the edit is restored. That is, it is (with
the exception of a BLOCK on the undo-list) as though the editor had never
been exited.
It is possible to save edit states for more than one form by exiting from the
editor via the SAVE command.

PSL Manual
section 4.3

6 December 1983

EDITOR
page 4.17

(ORF [PAT])
This command searches the current expression, in print order, for the first
occurrence of any form which matches one of the PATs; i.e. Print Order
., Einal;'~ -:If-.. :found, an -UPis.executed,andthe· current .expression becomes the
expression so· ·specified. This . command is .. equivalent to (F (*ANY* patl pat2
... patn) N). Note that the top level check is not performed.

(ORR [CaMS])
This command operates in the following manner. Each CaMS is a list of
edit commands. ORR first executes the first COMS. If no error occurs, ORR
terminates, leaving the current expression as it was at the end of executing
CaMS. Otherwise, it restores the current expression to what it was on
entry and repeats this operation on the second COMS, etc. If no CaMS is
successfully executed without error, ORR generates an error and the current
expression is unchanged.

(P Nl " arrow is used to indicate the: Lisp actually produced from. the input RLisp. To see
- _the Lisp -equivalents of RLisp code on the machine, set the switch ! *PEcho to T. As far as
possible, upper and lower cases are used as follows:
a. Upper case tokens and punctuation represent items which must appear as is
in the source RLisp or output Lisp.
b. Lower case tokens represent other legal RLisp constructs or corresponding
Lisp translations. We typically use "e" for expression, "s" for statement, and
"v" for variable; "-list" is tacked on for lists of these objects.
For example, the following rule describes the syntax of assignment in RLisp:

VAR := number;
==> (SETQ VAR number)
Another example:

IF

expression

THEN

==> (COND «

action 1 ELSE action 2
expression action 1) (T action _2) ) )

5.3.1. Function Call Syntax in RLISP and LISP
A function call with N arguments (called an N-ary function) is most commonly
represented as "FN(Xl, X2, ... Xn)" in RLisp and as "(FN Xl X2 ... Xn)" in Lisp. Commas are
required to separate the arguments in RLisp but not in Lisp. A zero argument function
call is "FNO" in RLisp and "(FN)" in Lisp. An unary function call is "FN(a)" or "FN a" in
RLisp and "(FN a)" in Lisp; i.e., the parentheses may be omitted around the single
argument of any unary function in RLisp.

5.3.2. RLISP Infix Operators and Associated LISP Functions
Many important PSl binary functions, particularly those for arithmetic operations, have
associated infix operators, consisting of one or two special characters. The conversion of
an RLisp expression "A op B" to its corresponding Lisp form is easy: "(fn A B)", in which
"fn" is the associated function. The function name fn may also be used as an ordinary
RLiSP function call, "fn(A, BY'.
Refer to Chapter 6 for details on how the association of "op" and "fn" is installed.
Parentheses may be--used to -specify the order of combination.
RLisp becomes "(fn _b (fn _a A B) C)" in Lisp.

(/((A op...:,a B) op b C)" in

6 Decem ber 1983

RLiSP
page 5.4

PSL Manual
section 5.3

If two or more different operators appear in a sequence, such as "A op_a 8 op_b C",
grouping (similar to the insertion of parentheses) is done based on relative precedence of
the operators, with the highest precedence operator getting the first argument pair:
"(A op_a 8) op_b C" if Precedence{op_a) >= Precedence(op_b); "A op_a (8 op_b C)" if
. Precedence{ op.:.., a) <"'Precedence( op ~ b).
If two or more of the same operator appear in a sequence, such as "A op 8 op C",
grouping is normally left-to-right {Left Associative; Le., "(fn (fn A 8) C)"), unless the
operator is explicitly Right Associative {such as. for Cons and
:= for SetQ; i.e.,
"{fn A (fn B C»").
The operators + and * are N-ary; i.e., "A nop B nop C nop 8" parses into "(nfn A 8 C Dr
rather than into "{nfn (nfn (nfn A B) C) 0)".
The current binary operator-function correspondence is as follows:
higher on the list are done first.)
Operator
Function
Precedence
Cons
Expt

23 Right Associative
23

Quotient
Times

19
19 N-ary

Difference
Plus

17
17 N-ary

Member
Memq
Neq

Eq
Equal
Geq
GreaterP
Leq
LessP
Member
MemQ
Neq

15
15
15
15
15
15
15
15
15

And

And

11

Or

Or

9 N-ary

SetQ

7 Right Associative

/

+

Eq
=

>=
>

<=
<

(Operation groups

N-ary

Note: There are other INFIX operators, mostly used as key-words within other syntactic
constructs (such as Then or Else in the If-... , or Do in the While-... , etc.). They have
lower precedences than those given above. These key-words include: the parentheses
"0", the brackets "[l", the colon ":", the comma ",", the semi-colon ";", the dollar.. sign "$",
. ~. and the ids: Collect, Conc~ Do, Else, End, 'Of;--Pro'cedure,' Product, 'step, Such, Sum, Then,
To, and Until.

PSL Manual
section 5.3

6 December 1983

RLiSP
page 5.5

As pointed out above, a unary function FN can be used with or without parentheses:
FN(a}; or FN a;. In the latter case, FN is -assumed to behave as a prefix operator with
highest precedence (99) so that "FOO 1 ** 2" parses as "FOO( 1) ** 2;". The operators +, -,
- and / can also be used as unary prefix operators, mapping to Plus, Minus and Recip,
respectively;-withprecedence 26~ - Certain-other:. -unary operators(RLispkey~words) have
low precedences or explicit special purpose parsing functions. These include: BEGIN,
CASE, CONT, EXIT, FOR, FOREACH, GO, GOTO, IF, IN, LAMBDA, NOOP, NOT, OFF, ON, OUT,
PAUSE, QUIT, RECLAIM, REPEAT, RETRY, RETURN, SCALAR, SHOWTIME, SHUT, WHILE and
WRITE.

5.3.3. Referencing Elements of Vectors in RLISP
In RLisp syntax, X[i]; may be used to access the i'th element of an x-vector, and X[i]:=y;
is used to change the i'th element to y. These- functions correspond to the Lisp functions
Indx and Setlndx.

5.3.4. Differences between Parse and Read
A single character can be interpreted in different ways depending on context and on
whether it is used in a Lisp or in an RLisp expression.
Such differences are not
immediately apparent to a novice user of RLisp, but an example is given below.
The RLisp infix operator "." may appear in an RLisp expression and is converted by the
Parse function to the Lisp function Cons, as in the expression x := 'y . 'z;. A dot may also
occur in a quoted expression in RLisp mode, in which case it is interpreted by Read as
part of the notation for pairs, as in x := '(y . z);. Note that Read called from Lisp uses
slightly different scan tables than Read called from RLisp.
What constitutes a valid id name depends upon the scan table in use by the reader. In
RLisp the scan table bound to RLISPSCANTABLE!
shown below. ids begin with a letter
or any character preceded by an escape character. They may contain letters, digits,
underscores, and escaped characters. You will note that many characters such as "$" and
"*,, that are treated as letters by the Lisp scan table are treated as delimiters by the RLisp
scan table. Characters regarded as delimiters by the RLisp scan table must be preceded
by an escape character, currently"!", when they appear in an id name.

*,

Here are some examples of valid id names using the RLisp scan table.
first and second examples are read as the same identifier if ! *RAISE is T.

*
*
*
*
*
*
*

ThislsALongldentifier
THISISALONGIDENTIFIER
ThislsALongldentifierAndDifferentFromTheOther
this _is _a_long_identifier_with _underscores
an!-identifier!-with!-dashes
P':HAISE
!2222

Note that the

6 December 1983

RLiSP
page 5.6

PSL Manual
section 5.3

RLISPSCANTABLE!* [Initially: as shown in following table]

o A@

IGNORE
32
1 AA DELIMITER
33
,311
2 AB DELIMITER
35
3'''C DELIMITER
4 "DDELIMITER ,-' 36
5 AE DELIMITER
37
38
6 "F DELIMITER
7 "G DELIMITER
39
40
8 "H DELIMITER
41
9  IGNORE
42
10  IGNORE
11 "K DELIMITER 43
411
12 "L IGNORE
45
13  IGNORE
14 "N DELIMITER 46
15 "0 DELIMITER 47
16 "P DELIMITER 48
17 "Q DELIMITER 49
18 "R DELIMITER 50
19 AS DELIMITER 51
20 "T DELIMITER 52
21 "U DELIMITER 53
22 AV DELIMITER 511
23 "W DELIMITER 55
24 AX DELIMITER 56
25 Ay DELIMITER 57
'26 "Z DELIMITER 58
59
27 $ DELIMITER
28 "\ DELIMITER 60
29 ,,] DELIMITER 61
30 AA DELIMITER 62
31
DELIMITER 63
A_

IGNORE

! IDESCAPECHAR

STRINGQUOTE
'DELIMITER
$ DELIMITER
%COMMENTCHAR
& DELIMITER
' DELIMITER
( DELIMITER
) DELIMITER
* DIPHTHONGSTART
+ DELIMITER
, DELIMITER
- DELIMITER
• DECIMALPOINT
/ DELIMITER
0 DIGIT
1 DIGIT
2 DIGIT
3 DIGIT
4 DIGIT
5 DIGIT
6 DIGIT
7 DIGIT
8 DIGIT
9 DIGIT
: DIPHTHONGSTART
; DELIMITER
 DIPHTHONGSTART
? DELIMITER
It

II

611
65
66
,67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
811
85
86
87
88
89
90
91
92
93
94
95

@ DELIMITER
A LETTER
BLETTER
C'LETTER
D LETTER'
E LETTER
F LETTER
G LETTER
H LETTER
I LETTER
J LETTER
K LETTER
L LETTER
M LETTER
N LETTER
0 LETTER
P LETTER
Q LETTER
R LETTER
S LETTER
T LETTER
U LETTER
V LETTER
WLETTER
X LETTER
Y LETTER
Z LETTER
[ DELIMITER
\ PACKAGE
] DELIMITER
DELIMITER
LETTER
A

global
96 I DELIMITER
97 a LETTER
98 b LETTER
-99 c LETTER
-- '100 d LETTER
101 e LETTER
102 f LETTER
103 g LETTER
104 h LETTER
105 i LETTER
106 j LETTER
107 k LETTER
108 1 LETTER
109 m LETTER
110 n LETTER
111 0 LETTER
112 P LETTER
113 q LETTER
114 r LETTER
115 s LETTER
116 t LETTER
117 u LETTER
118 v LETTER
119 w LETTER
120 x LETTER
121 Y LETTER
122 z LETTER
123 [ DELIMITER
124 I DELIMITER
125 } DELIMITER
126 - DELIMITER
127 
DELIMITER

The Diphthong Indicator in the 128th entry is the identifier RLISPDIPHTHONG.

5.3.5. Procedure Definition
When defining a function in RLisp, one gives an "ftype" (one of the tokens EXPR, FEXPR,
etc.) followed by the keyword PROCEDURE, followed by an "id" (the name of the function),
followed by a "v-list" (the formal parameter names) enclosed in parentheses. A
semicolon terminates the title line. The body of the function is a  followed
by a semicolon.
mode ftype PROCEDURE name(v_1, ••• ,v_n); body;
::> (Dx name (v_1 ••• v_N) body)
In the general definition given above "mode" is usually optional; it can be LISP or
SYMBOLIC (which mean the same thing.), ALGEBRAIC (for Reduce code), or SYSLISP [only
"of importanc,etf SYSLisp and Usp- are-::int~r-mixedl-H,"Ftype" is'expr,fexpr, macro, nexpr, or
smacro (or can- be,omitted,in which case it defaults to expr). Name(v_1, ... ,v_N) is any

PSL Manual
section 5.3

6 December 1983

legal form of call, including infix.
nexpr, and Ds for smacro.

Dx is De for expr, Df--for- fexpr, Om for -macro, On for

RLiSP
page 5.7

Examples:
-EXPR--PROCEDURE NULL(X);
EQ(X, NIL);
==> (DE NULL (X) (EQ X NIL»
PROCEDURE ADD1 N;
N+1 ;
==> (DE ADD1 (N) (PLUS N 1»
MACRO PROCEDURE FOO X;
LIST('FUM, CDR X, CDR X);
==> (DM FOO (X) (LIST 'FUM (CDR X) (CDR X»
The value returned by the procedure is the value of the body; no assignment to the
function name (as in Algol or Pascal) is needed.

5.3.6. Compound Statement Grouping
A group of RLisp expressions may be used in any position in which a single expression
is expected by enclosing the group of expressions in double angle brackets," < < and
"> >", and separating them by the ";" delimiter.
11

The RLisp <  > becomes (PROGN A 8 C ... Z) in Lisp.
group is the value of the last expression, Z.
Example:

The value of the

X:=«PRINT X; X+1»;
%prints oid X then increments X
==> (SETQ X (PROGN (PRINT X) (PLUS X 1»)

5.3.1. Blocks with Local Variables
A more powerful construct, sometimes used for the same purpose as the "< < > >"
group, is the Begin-End block in RLisp or Prog in Lisp_ This construct also permits the
allocation of 0 or more local variables, initialized to NIL. The normal value of a block is
NIL, but it may be exited at a number of points, using the Return statement, and each
can return a different value. The block also permits labels and a GoTo construct.
Example:

RLISP
page 5.8

6 December 1983

PSL Manual

section 5.3

BEGIN SCALAR X,Y; %SCALAR declares locals X and Y
X:='(1 2 3);
Ll:
IF NULL X THEN RETURN Y;
Y:=CAR X;
·"X:=CDR X;
GOTO L1;
END;
==> (PROG (X Y)
(SETQ X '(1 2 3})
L1
(COND «NULL X) (RETURN Y»)
(SETQ Y (CAR X»
(SETQ X (CDR X)}
(GO L1»

5.3.8. The If Then Else Statement
The Lisp function Cond corresponds to the I f statement of most programming
languages. In RLisp this is simply the familiar I f ... Then ... Else construct. For example:
IF predicate THEN action 1

ELSE action2
==> (COND (predicate action 1)
(T action2»
""Action 1 is evaluated if the predicate has a non-NIL evaluation; otherwise, action2 is
evaluated. Dangling Elses are resolved in the Algol manner by pairing them with the
nearest preceding Then. For example:
IF F(X) THEN
IF G(Y) THEN PRINT(X)
ELSE PRINT(Y};
is equivalent to
IF F(X) THEN
« IF G(Y) THEN PRINT(X)
ELSE PRINT(Y) »;
Note that if F(X) is NIL, nothing is printed.
The If... Then construct also exists.

PSL Manual
section 5.3

6 December 1983

RLiSP
page 5.9

IF predicate THEN action;

==>

(COND (predicate action»

- . ·· .. The. actions may~also-.co.ntain the special functions Go, Return, Exit, and Next, subject
to' the constraints on placement of- ·these -functions described, in the control flow chapter
of Part 1 of this manual.

5.3.9. Case Statement
PSL provides a numeric case statement that is compiled quite efficiently; some effort is
made to examine special cases (compact vs. non-compact sets of cases, short vs. long
sets of cases, etc.). It has mostly been used in SYSLisp mode, but can also be used from
Lisp mode provided that case-tags are numeric. The FEXPR Case can also be used
interpretively.
The RLisp syntax is:
Case-statement
Case-clause
Case-expr
Tag-expr

·.·· .-.·.-.·...--

CASE expr OF case-clause END
Case-expr [; Case-clause
Tag-expr : expr
DEFAULT I OTHERWISE
tag I tag, tag ••• tag
tag TO tag

·.-.-

Tag

Integer

I

Wconst-Integer

An example in RLisp is:
CASE i
1:

OF

Print("First fl ) ;
Print(nSecond");
2,3:
4 to 10: Print("Third");
Default: Print("Fourth rt );

END

5.4. Looping Statements
RLisp provides While, Repeat, For and For Each loops. These are discussed in greater
detail in the chapter on control flow in Part 1 of this manual. Some examples follow:

RLiSP
page 5.10

6 December 1983

PSL Manual

section 5.4

5.4.1. While Loop
WHILE e DO s;
(WHILE e s)

==>

%As

long as e NEQ NIL, do s

5.4.2. Repeat Loop
REPEAT s UNTIL e;
(REPEAT s e)

==>

%repeat

doing s until "e" is not NIL

5.4.3. Next and Exit
Next and Exi t, described in the control flow chapter of Part 1, are available in RLisp.
Care must be taken in using them in While and Repeat loops. While and Repeat each
macro expand into a Prog; Next and Exit are macro expanded into a Go and a Return
respectively to the Prog immediately containing the Next or Exit. Thus using a Next or
an Exit within a Prog within a While or Repeat will result only in an exit of the internal
Prog.
In RLisp be careful to use
WHILE E DO «

S1; ••• ;EXIT(1); ••• ;Sn»

'not
WHILE E DO BEGIN S1; ••• jEXIT(1); ••• jSn;END;

5.4.4. For Each Loop
The For Each loops provide various mapping options, processing elements of a list in
some way and sometimes constructing a new list.
FOR EACH x IN Y DO Sj

==>

list bound to each

(FOREACH x IN Y DO s)

FOR EACH x ON Y DO s;

==>

%y is a list, x traverses
%element in turn.
%y is a list,
%Cdr's of y.

x traverses list Bound to successive

(FOREACH x ON Y DO s)

Other options can return modified lists, etc.
of this manual.

See the chapter on control flow in Part 1

Note that FOR EACH may be -written as FOREACH

PSL Manual
section 5.4

6 December 1983

RLiSP
page 5.11

Examples of use of the ForEach function follow.

[1] X := '(1 3 5);
- - [2] Foreach Y in X do Print Y;
1

3
5

NIL
[3] Foreach Y in X collect add1 Y;
(2 4 6)
[4] Foreach Y on X do Print Y;
(1 3 5)
(3 5)
(5)
NIL
5.4.5. For Loop

The For loop permits an iterative form with a compacted control variable.
options can compute sums and products.
FOR i := a:b DO s;

%step i successively
%steps of 1.

from a to b in

==> (FOR (FROM I a b 1) DO s)

FOR i := a STEP b UNTIL c DO s; %More general stepping
==> (FOR (FROM I a c b) DO s)
5.4.6. Loop Examples

Other

6 December 1983

RLiSP

page 5.12

PSL Manual
section 5.4

LISP PROCEDURE count 1st; %Count elements in 1st
BEGIN SCALAR k;
k:=O;
WHILE PAIRP 1st DO «k:=k+1; lst:=CDR 1st»;
RETURN k;
END;
==>

(DE COUNT (LST)
(PROG (K)
(SETQ K 0)
(WHILE (PAIRP LST)
(PROGN
(SETQ K (PLUS K 1»
(SETQ LST (CDR LST»»
(RETURN K»)

or
LISP PROCEDURE CountNil 1st; %Count NIL elements in 1st
BEGIN SCALAR k;
k:=O;
FOR EACH x IN 1st DO If Null x then k:=k+1;
RETURN k;
END;
==>

(DE COUNTNIL (LST)
(PROG (K)
(SETQ K 0)
(FOREACH X IN LST DO (COND
«NULL X) (SETQ K (PLUS K 1»»)
(RETURN K»)

5.5. RLISP Specific Input/Output

RLisp provides some special commands not available in Lisp syntax for file input and
output. These are described in this section. Also specific to RLisp is a function RPrint
that prints a form in RLisp format.
(RPrint U: form): NIL
Print in RLisp format. Autoloading.

PSL Manual
section 5.5

6 December 1983

RLiSP
page 5.13

5.5.1. RLISP File Reading Functions
The following functions are present in RLisp, they can be used from Bare-PSL by loading
RLiSP.

- (In [L :string]): None Returned

macro

Similar to DskIn but expects RLisp syntax in the files it reads unless it can
determine that the files are not in RLisp syntax. Also In can take more
than one file name as an argument. On most systems the function In
expects files with extension .LSP and .SL to be written in Lisp syntax, not in
RLisp.
This is convenient when using both Lisp and RLisp files.
It is
conventional to use the extension .RED (or .R) for RLisp files and use .LSP or
.SL only for fully parenthesized Lisp files. There are some system programs,
such as TAGS on the DEC-20, which expect RLisp files to have the
extension .RED.
If it is not desired to have the contents of the file echoed as it is read,
either end the In command with a 1/$" in RLisp, as
In "FILE1.RED","FILE2.SL"$
or include the statement "Off ECHO;" in your file.

{EvIn L:string-list}: None Returned

1:

must be a list of strings that are filenames. EvIn is the function called by
In after evaluating its arguments. In is useful only at the top-level, while
EvIn can be used inside functions with file names passed as parameters.

5.5.2. RLISP File Output
(Out U:string): None Returned

macro

Opens file 1! for output, redirecting standard output. Note that Out takes a
string as an argument, while Wrs takes an io-channel.
(EvOut L:string-list): None Returned

1:

is a list containing. one file name which must be a string.
function called by Out after evaluating its argument.

EvOut is the

(Shut [L:string]): None Returned
.. Closes. the ·output files. in the list !:;···Note··,thatShut takes file ·names as
. arguments, 'whileClose takes an io-channel.
The RLisp IN function

macro

RLiSP
page 5.14

6 December 1983

PSL Manual
section 5.5

maintains a stack of (file-name . io-channel) associations for this purpose.
Thus a shut will also correctly select the previous file for further output .

. c .. -

(EvShut L:string-list): none Returned
. -.. Does the same as Shut but evaluates its arguments.

5.6. Transcript of a Short Session with RLISP
The following is a transcript of RLisp running on the DEC-20.

PSL Manual
section 5.6

. 6 December 1983

RLiSP
page 5.15

@psl:rlisp
Extended 20-PSL 3.2 Rlisp, 21-Jul-B3
[1] % Notice .the numbered prompt.
[1] % Comments begin with "%" and do not change the prompt number.
%·Make an assignment Tor Z •
[1] ·Z:= '('- 2 3);
.( 1 2 3)

[2] Cdr Z;
(2

% Notice the change in the prompt number.

3)

[3] Procedure Count L;
% "Count" counts the number of elements
[3]
If Null L Then 0
%
in a list L.
[3]
Else 1 + Count Cdr L;
COUNT
[4] Count Z;
% Tryout "Count" on Z.
3
[5] Tr Count;
% Trace the recursive execution of "Count".
(COUNT)
[6]
% A calIon "Count" now shows the value of
[6]
% "Count" and of its argument each time it
[6] Count Z;
% is called.
COUNT being entered
L:
(1 2 3)
COUNT (level 2) being entered
L: (2 3)

COUNT (level 3) being entered
L:

(3)

COUNT (level 4) being entered
L:

NIL

COUNT (level 4) = 0
COUNT (level 3) =
COUNT (level 2) = 2
COUNT = 3
3
[7] UnTr Count;
NIL
[B] Count 'A;
***** An attempt was made to do CDR on 'A', which is not a pair
Break loop
1 lisp break> ?
BREAK():{Error,return-value}
This is a Read-Eval-Print loop, similar to the top level loop, except
that the following IDs at the top level cause functions to be called
rather than being evaluated:
?
Print this message, listing active Break IDs
T
Print stack back trace
Q
Exit break loop back. to ErrorSet

----------------------------------------RLISP

6 December 1983

page 5.16

C
R
M
E

I

PSL Manual

section 5.6

Return last value to the ContinuableError call
Reevaluate ErrorForm!* and return
Display ErrorForm!* as the "message"
Invoke a simple structure editor on ErrorForm!*
(For:more information do'Help Editor.)
Show a -trace of.'any,interpreted functions

See the manual for details on the Backtrace, and how ErrorForm!* is
set. The Break Loop attempts to use the same TopLoopRead!* etc, as
the calling top loop, just expanding the PromptString!*.
NIL
2 lisp break>
%Get a Trace-Back of the
2 lisp break> I
% interpreted functions.
Backtrace, including interpreter functions, from top of stack:
CDR COUNT PLUS2 PLUS COND COUNT
NIL
3 lisp break> Q
%To exit the Break Loop.
[9]
%Load in a file, showing the file
[9] In "small-file.red"; %and its execution.
X : = 'A • t B • NIL; (A B)
%Construct a list with "." for Cons.
Count X;2

% Call "Count" on X.

Reverse X;(B A)

%Call "Reverse" on X.

NIL
[10]
[10] End;
Entering LISP •••
PSL, 27-0ct-82
6 lisp> (SETQ X 3)
3
7 lisp> (FACTORIAL 3)
6
8 lisp> (BEGINRLISP)
Entering RLISP •••
[11] Quit;
@continue
"Continued"
[12] X;

3
[ 13] "C
@start
[14] Quit;
@

%This leaves RLISP and enters
% LISP mode.

%A LISP assignment statement.
%Call "Factorial" on 3.
%This function returns us to RLISP.
%To exit call "Quit".

%Notice the prompt number.
%One can also quit with .
%Alternative immediate re-entry_

PSL MANUAL
SECTION 6.0

·6 DECEMBER 1983

PARSER TOOLS
PAGE 6.1

CHAPTER 6
PARSER TOOLS
6.1. Introduction . . _ . . '. . . . _... _ . .
6.2.- The Table Driven Parser. . . . . .
6.2.1. Flow Diagram for the Parser .
6.2.2. Associating the Infix Operator with a Function.
6.2.3. Precedences . . . . . . . . .
6.2.4. Special Cases of 0 < -0 and 0 0
6.2.5. Parenthesized Expressions. . .
6.2.6. Binary Operators in General . .
6.2.7. Assigning Precedences to Key Words.
6.2.8. Error Handling . . . . . . . . . . .
6.2.9. The Parser Program for the RLlSP Language.
6.2.10. Defining Operators. . . . .
6.3. The MINI Translator Writing System
6.3.1. A Brief Guide to MINI .
6.3.2. Pattern Matching Rules
6.3.3. A Small Example
6.3.4. Loading Mini . . . . .
6.3.5. Running Mini . . . . .
6.3.6. MINI Error messages and Error Recovery
6.3.7. MINI Self-Definition. . . . .
6.3.8. The Construction of MINI . .
6.3.9. History of MINI Development.
6.4. BNF Description of RLisp Using MINI

6.1
6.2
6.2

6.4
6.4
6.5
6.5
6.6
6.6

6.6
6.7
6.7
6.9
6.9
6.11
6.11
6.11
6.12
6.12
6.12
6.14
6.15
6.16

6.1. Introduction
In many applications, it is convenient to define a special "problem-oriented" language,
tailored to provide a natural input format. Examples include the RLisp Algol-like surface
language for algebraic work, graphics languages, boolean query languages for data-base,
etc. Another important case is the requirement to accept existing programs in some
language, either to translate them to another language, to compile to machine language,
to be able to adapt existing code into the PSL environment (e.g. mathematical libraries,
etc.), or because we wish to use PSL based tools to analyze a program written in another
language.
One approach is to hand-code a program in PSL (called a "parser") that
translates the input language to the desired form; this is tedious and error prone, and it is
more convenient to use a "parser-writing-tool".
In this Chapter we describe in detail two important parser writing tools available to the
PSL programmer: an extensible table-driven parser that is used for the RLisp parser
(described in Chapter 5), and the MINI parser generator. The table-driven parser is most
useful for languages that are simple extensions of- RLisp, or in tact for rapidly adding new
···"syntactic··constructs to RLisp. The Mini system' is used for the development of more
complete user languages.

. Parser Tools
page 6.2

6 December 1983

PSL Manual
section 6.2

6.2. The Table Driven Parser
The parser is a top-down recursive descent parser, which uses a table of Precedences
to control the parse; if numeric precedence is not adequate, Lisp functions may be
inserted-'into the table to· provide:.more::control. Theparser'described here was developed
. by' ·Nordstrom .[Nordstrom 73], and ··js--very similar to parser described by Pratt [Pratt 73],
and apparently used for the CGOL language, another Lisp surface language.
The parser reads tokens from an input stream using a function Scan. Scan calls the
ChannelReadToken function described in the chapter on I/O in Part 1 of this manual, and
performs some additional checks, described below. Each token is defined to be one of
the following:
non-operator
right operator
binary operator

o
0->
<-0->

All combinations of ... 0- > O... and 0 < -0- > ... are supposed to be legal, while the
combinations ... 0-> <-0-> ..., ... <-0-> <-0-> ... and 0 O... are normally illegal
(error ARG MISSING and error OP MISSING, respectively).
With each operator (which must be an id) is associated a construction function, a right
,precedence, and for binary operators, a left precedence.
The Unary Prefix operators have this information stored under the indicator
.'RlispPrefix and Binary operators have it stored under 'Rlisplnfix.
(Actually, the
indicator used at any time during parsing is the VALUE of GramPrefix or Gramlnfix,
which may be changed by the user).

';6.2.1. Flow Diagram for the Parser
In this diagram RP stands for Right Precedence, LP for Left Precedence and CF for
Construction Function. OP is a global variable which holds the current token.

PSL Manual
section 6.2

6 December 1983

procedure PARSE(RP);
RDRIGHT(RP,SCAN(»;

%SCAN reads next token

.. RDRIGHT(RP;Y)
1

\11
I
Y is Right OP

Iyes
1-----> Y:=APPLY(Y.CF,
I
RDRIGHT(Y.RP»;

1

\11 no
1

I no

ERROR
yes 1
ARG
<----1
MISSING
1

Y is Binary OP

I

RDLEFT:
ERROR
nol
OP
<----1
MISSING
1

I---~>

OP:=
SCAN();

1--------<------------<------*

\ 11
I

OP is Binary

1

\11
I

RETURN
(Y)

yes 1

<----1

yes

Ino

RP > OP.lp
1---> Y:=APPLY(OP.cf,Y,
-----------------------PARSE(OP.lp,SCAN(»;

Parser Tools
page 6.3

Parser Tools
page 6.4

·6 December 1983

PSL Manual
section 6.2

This diagram reflects the major behavior, though some trivial additions are included in
the RLisp case to handle cases such as op-> <-OP, 'I;, etc. [See PU:RLlSP-PARSER.RED
for full details.]
->:.:rhe -technique involved ,-may also be:·described by thefo.llowing:figure:
... 0-> Y <-0 ...
rp Ip

Y is a token or an already parsed expression between two operators (as indicated).

If
O->'s RP is greater than <-O's LP, then 0-> is the winner and Y goes to O->'s
construction function (and vice versa). The result from the construction function is a
"new Y" in another parse situation.
By associating precedences and construction functions with the operators, we are now
able to parse arithmetic expressions (except for function calls) and a large number of
syntactical constructions such as IF - THEN - ELSE - ; etc. The following discussion of
how to expand the parser to cover a language such as RLisp (or Algol) may also be seen
as general tools for handling the parser and defining construction functions and
precedences.

6.2.2. Associating the Infix Operator with a Function
The Scan, after calling RAtomHook, checks ids and special ids (those with TokType!* = 3)
to see if they should be renamed from external form to internal form (e.g. '!+ to Plus2).
This is done by checking for a NEWNAM or NEWNAM! -OP property on the id. For special ids,
the NEWNAM! -OP property is first checked. The value of the property is a replacement
token, i.e.
PUT('!+,'NEWNAMI-OP,'PLUS2)
has been done.
Scan also handles the ' mark, calling RlispRead to get the S-expression.
a version of Read, using a special ScanTable, RlispReadScanTable! *.

RlispRead is

The function Scan also sets SEMIC!* to 'I; or '!$ if CURSYM!* is detected to be
'!*SEMICOL!* (the internal name for 'I; and "!$). This controls the RLisp echo/no-echo
capability. Finally, if the renamed token is 'COMMENT then characters are ReadCh'd until a
'I; or '!$ .

6.2.3. Precedences
To set up precedences, it is often helpful to set up a precedence matrix of the operators
involved. If any operator has one "precedence" with respect to one particular operator
and another "precedence" with respect to some other, it is sometimes not possible to run
the parser- with just numbered precedences for the operators without introducing
'-'··'··'ambiguities. If this is the· case, replace the numbe(HP bvthe.operator RP and test with
something like:

PSL Manual
section 6.2

6- December 1983

Parser Tools
page 6.5

IF RP *GREATER* OP ...
*GREATER* may check in the precedence matrix. An example in which such a scheme
might be used is the case for which Algol uses ":" both as a label marker and as an
-index separator(althoughin_- this case there_ is _no -need -for the change above). It is also a
_.. good- policy to .have even numbers -for right precedences and odd numbers for left
precedences (or vice versa).

6.2.4. Special Cases of 0 < -0 and 0 0
If ... 0 O. .. is a legal case (Le. F A may translate to (F A)), ERROR
replaced by:

op MISSING is

Y:=REPCOM(Y,RDRIGHT(99,OP}); GO TO RDLEFT;
The value 99 is chosen in order to have the first object (F) behave as a right operator
with maximum precedence. If ... O <-0 ... is legal for some combinations of operators,
replace ERROR ARG MISSING by something equivalent to the illegal RLisp statement:

IF ISOPOP(OP,RP,Y)
THEN «OP:=Y;
Y:=(something else, i.e. NIL);
GOTO RDLEFT»
ELSE ERROR ARG MISSING;
ISOPOP is supposed to return T if the present situation is legal.

6.2.5. Parenthesized Expressions
(a) is to be translated to a.
E.g.
BEGIN a END translates to (PROG a).
Define "(" and BEGIN as right operators with low precedences (2 and -2 respectively).
Also define ")" and END as binary operators with matching left precedences (1 and -3
respectively). The construction functions for "(" and BEGIN are then something like: [See
pu:RLlSP-PARSER.RED for exact details on ParseBEGIN]

BEGIN
1t(It

(X);PROG2(OP:=SCAN();MAKEPROG(X»;
(X);PROG2(IF OP=') THEN OP:=SCAN()
ELSE ERROR, x);

Note that the construction functions in these cases have to read the next token; that is
the _eff~ct of ")" closing the last "(" and not all earlier "{"'S. This is also an example of
binary operators declared only for the purpose of having a left precedence.

Parser Tools
page 6.6

6 December 1983

PSL Manual
section 6.2

6.2.6. Binary Operators in General
As almost all binary operators have a construction function like
.' .. LlST{OP,X, V);
it is "assumed to be of -that kind if no' other is given. If OP 'is a binary operator, then
"a OP b OP c" is interpreted as "(a OP b) OP c" only if OP's LP is less than OP's RP.
Example:
A + B + C translates to (A + B) + C
because +'RP = 20 and +'LP = 19
A " B "C translates to A " (B " C)
because "'RP = 20 and "'LP = 21
If you want some operators to translate to n-ary expressions, you have to define a
proper construction function for that operator.
Example:

PLUS

(X,Y); IF CAR(X)

= 'PLUS

THEN NCONC(X,LIST(Y»
ELSE LIST('PLUS,X,Y);

By defining "," and ";" as ordinary binary operators, the parser automatically takes care
of constructions like ... e,e,e,e,e. . . and ... stm;stm;stm;stm;. .. It is then up to some
other operators to remove the "," or the ";'1 from the parsed result.

6.2.7. Assigning Precedences to Key Words
If you want some operators to have control immediately, insert
IF RP = NIL THEN RETURN Y ELSE
as the very first test in RDRIGHT and set the right precedence of those to NIL. This is
sometimes useful for key-word expressions. If entering a construction function of such
an operator, X is the token immediately after the operator. E.g.: We want to parse
PROCEDURE EO(X,Y); . .. Define PROCEDURE as a right operator with NIL as precedence.
The construction function for PROCEDURE can always call the parser and set the rest of
the expression. Note that if PROCEDURE was not defined as above, the parser would
misunderstand the expression in the case of EO as declared as a binary operator.

6.2.8. Error Handling
For the present, if an error occurs a message is- printed but no attempt is made to
correct or handle the error.
Mostly the. parser goes wild for a while (until a left
. precedence less than current right precedence is found) and then goes on as usual.

PSL Manual
section 6.2

6 December 1983

Parser Tools
page 6.7

. 6.2.9. The Parser Program for the RLISP Language
SCANO;
: The~purpose . of this function is to .read the next_token from the input stream. It uses
thegener-al-purpose-table .. driven·token. scanner described in Chapter INPUT, with a
specially set up ReadTable, RlispScanTable! *. As RLisp has multiple identifiers for the
same operators, Scan uses the following translation table:
= EQUAL
>= GEQ
+ PLUS
> GREATERP
- DIFFERENCE
<= LEQ
/ QUOTIENT
< LESSP
CONS
* TIMES
:= SETQ
** EXPT
In these cases, Scan returns the right hand side of the table values.
cases are taken care of in Scan:

Also, two special

a. ' is the QUOTE mark. If a parenthesized expression follows ' then the syntax
within the parenthesis is that of Lisp, using a special scan table,
RlispReadScanTable! *. The only major difference from ordinary Lisp is that !
is required for all special characters.
b. ! in RLisp means actually two things:
i. the following symbol is not treated as a special symbol (but belongs to
the print name of the atom in process);
ii. the atom created cannot be an operator.
Example: !( in the text behaves as the atom "(".
To signal to the parser that this is the case, the flag variable ESCAPEFL must be set to
T if this situation occurs.

6.2.10. Defining Operators
To define operators use:
DEFINEROP(op,p{,stm});
For right or prefix operators.
DEFINEBOP(op,lp,rp{,stm});
For binary operators.
These use the VALUE of DEFPREFIX and DEFINFIX' to store the precedences and
. construction functions. ·The default is set for RLisp;' to be 'RLISPPREFIX and 'RLISPINFIX.
The same identifier can be defined both as the right and binary operator. The context

Parser Tools
page 6.8

6 December 1983

PSL Manual
section 6.2

defines which one applies.
Stm is the construction function.

If stm is omitted, the common defaults are used:

-- LlST(OP,x}" prefix'-case,: x'is pars-ed-exp-ression"following;- x=RDRIGHT{p,SCANO}.
LlST(OP,x,Y) binary case, x is previously parsed expression, y is expression following,
y=RDRIGHT{rp,SCANO}·
If stm is an id, it is assumed to be a procedure of one or two arguments, for "x" or
"x,y". If it is an expression, it is embedded as (LAMBDA(X) stm) or (LAMBDA(X Y) stm),
and should refer to X and V, as needed.
Also remember that the free variable OP holds the last token (normally the binary
operator which stopped the parser). If "p" or "rp" is NIL, RDRIGHT is not called by default,
so that only SCANO (the next token) is passed.

For example,
DEFINEBOP('DIFFERENCE,17,18};
%Most common case, left associative, stm=LIST(OP,x,y);
DEFINEBOP('CONS,23,21);
%Right Associative, default stm=LIST(OP,x,y)
DEFINEBOP('AND,11,12,ParseAND);
%Left Associative, special function
PROCEDURE ParseAND(X,Y);
HARY( 'AND,X, Y);
DEFINEBOP('SETQ,7,6,ParseSETQ);
%Right Associative, Special Function
PROCEDURE ParseSETQ(LHS,RHS);
LIST(IF ATOM LHS THEN 'SETQ ELSE 'SETF, LHS, RHS);
DEFINEROP('MINUS,26);

%default C-fn, just (list OP arg)

DEFINEROP('PLUS,26,ParsePLUS1); %
DEFINEROP{'GO,NIL,ParseGO );
%Special Function, DO NOT use default PARSE ahead
PROCEDURE ParseGO X;
X is now JUST next-token
IF X EQ 'TO THEN LIST('GO,PARSEO(6,T»
%Explicit Parse ahead
ELSE «OP := SCAN(); %get Next Token
LIST('GO,X»>;
DEFINEROP('GOTO,NIL,ParseGOTO );

PSL Manual
section 6.2

6 December 1983

Parser Tools
page 6.9

%Suppress· Parse Ahead, just pass NextToken
PROCEDURE ParseGOTO X;
«OP := SCAN();
L1ST('GO,X»>;
6.3. The MINI Translator Writing System
Note that MINI is now autoloading.

6.3.1. A Brief Guide to MINI
The following is a brief introduction to MINI, the reader is referred to [Marti 79] for a
more detailed discussion of the META/RLISP operators, which are very similar to those of
MINI.
The MINI system reads in a definition of a translator, using a BNF-like form. This is
processed by MINI into a set of Lisp functions, one for each production, which make calls
on each other, and a set of support routines that recognize a variety of simple constructs.
MINI uses a stack to perform parsing, and the user can access sub-trees already on the
stack, replacing them by other trees built from these sub-trees. The primitive functions
that recognize ids, integers, etc. each place their recognized token on this stack.
For example,

FOO: 1D '!- 1D +(PLUS2 12 11) ;
defines a rule FOO, which recognizes two identifiers separated by a minus sign (each 10
pushes the recognized identifier onto the stack). The last expression replaces the top 2
elements on the stack (#2 pops the first ID pushed onto the stack, while # 1 pops the
other) with a Lisp statement.

(1d ): boolean
See if current token is an identifier and not a keyword.
onto the stack and fetch the next token.

If it is, then push

(Anyld ): boolean
See if current token is an id whether or not it is a key word.

(AnyTok ): boolean
Always succeeds by pushing the current token onto the stack.

Parser Tools
page 6.10

6 December 1983

PSL Manual
section 6.3

(Num ): boolean
Tests to see if the current token is a number, if so it pushes the number
onto the stack and fetches the next token.

(Str ): boolean
Same as Num, except for strings.
Specification of a parser using MINI consists of defining the syntax with BNF-like rules
and semantics with Lisp expressions. The following is a brief list of the operators:
Used to designate a terminal symbol (Le. 'WHILE, 'DO, '!=).
Identifier

Specifies a nonterminal.

( )

Used for grouping (Le. (FOO BAR) requires
immediately by BAR).

< >

Optional parse, if it fails then continue (Le.

/

rule FOO to parse followed

< FOO > tries to parse FOO).

Optional rules (Le. FOO / BAR allows either FOO or BAR to parse, with FOO
tested first).

STMT*

Parse any number of STMT.

:STMT[ANYTOKEN]*
Parse any number of STMT separated by ANYTOKEN, create a list and push
onto the stack (i.e. 10[']* parses a number of identifiers separated by commas,
like in an argument list).
##n

Refer to the nth stack location (n must be an integer).

#n

Pop the nth stack location (n must be an integer).

+(STMT)

Push the unevaluated (STMT) onto the stack.

.(SEXPR)

Evaluate the SEXPR and ignore the result.

=(SEXPR)

Evaluate the SEXPR and test if result non-NIL.

+.(SEXPR)

Evaluate the SEXPR and push the result on the stack.

@ANYTOKEN
Specifies a ·statement terminator; used in the error recovery mechanism to
search for the occurrence of errors.
@@ANYTOKEN
Grammar terminator; also stops scan, but if encountered in error-recovery,

PSL Manual
section 6.3

6 December 1983

Parser Tools
page 6.11

terminates grammar.

6.3.2.Patter.n Matching Rules
In addition "to the BNF ..... like -rules that define procedures-with 0 arguments and which
scan tokens by calls on NEXT!- TOKO and operate on the stack, MINI also includes a
simple TREE pattern matcher and syntax to define Pattern Procedures that accept and
return a single argument, trying a series of patterns until one succeeds.

E.g.

template

->

replacement

PATTERN = (PLUS2 &1 0) -> &1,
(PLUS2 &1 &1) -> (LIST 'TIMES2 2 &1),
&1
-> &1;
defines a pattern with 3 rules. &n is used to indicate a matched sub-tree in both the
template and replacement. A repeated &n, as in the second rule, requires Equal subtrees.

6.3.3. A Small Example

%A simple demo of MINI, to produce a LIST-NOTATION reader.
% INVOKE 'LSPLOOP reads S-expressions, separated by
mini 'lsploop;

% Invoke MINI, give name of ROOT

%Comments can appear anywhere,
lsploop:lsp* @@#
lsp:

%prefix by %to end-of-line
%@@# is GRAMMAR terminator
% like '# but stops TOKEN SCAN
%@; is RULE terminator, like ';
% but stops SCAN, to print

sexp @;
.(print #1)
.(next!-tok)
% so call NEXT!-TOK() explicitly
sexp:
id / num / str / I( dotexp ') ;
dotexp: sexp* < I . sexp +.(attach #2 #1) >;
fin
symbolic procedure attach(x,y);
«for each z in reverse x do y:=z • y; y»;
6.3.4. Loading Mini
MINI is loaded from PH: using LOAD MINI;.

Parser Tools
page 6.12

6

December

1983

PSL Manual
section 6.3

6.3.5. Running Mini

A MINI grammar is run by calling Invoke rootname;. This installs appropriate Key Words
(stored on the property list of rootname), and start the grammar by calling the Rootname
as·.first .procedure.
6.3.6. MINI Error messages and Error Recovery

If MINI detects a non-fatal error, a message be printed, and the current token and stack
is shown. MINI then calls NEXT!-TOKO repeatedly until ,either a statement terminator
(@ANYTOKEN) or grammar terminator (@ANYTOKEN) is seen. If a grammar terminator,
the grammar is exited; otherwise parsing resumes from the ROOT.
[???

Interaction with BREAK loop rather poor at the moment ???]

6.3.7. MINI Self-Definition

%The following is the definition of the MINI meta system in terms of
%itself. Some support procedures are needed, and exist in a
%separate file.
%To define a grammar, call the procedure MINI with the argument
%being the root rule name. Then when the grammar is defined it may
%be called by using INVOKE root rule name.
% The following is the MINI Meta self definition.
MINI 'RUL;

%

Define the diphthongs to be used in the grammar.
DIP: !I!I, I-I>, !+!., !@!@

% The root rule is called RUL.
RUL: ('DIP ': ANYTOK[,]* .(DIPBLD 11) '; /
(ID .(SETQ !ILABLIST!I NIL)
( ,. ALT
+(DE 12 NIL 11) @; /
': PRUL[,]* @;
.(RULE!-DEFINE '(PUT(QUOTE 112)(QUOTE RB)
(QUOTE 111»)
+ (DE lii/1 ( A)
(RBMATCH A (GET (QUOTE 11) (QUOTE RB»
NIL»)
.(RULE!-DEFINE 11) . (NEXT!-TOK) »* @@FIN ;

% An alternative is a sequence of statements separated by I's;
ALT:SEQ <, / ALT +(OR fl2 111) >;

% A sequence is a list of items that must be matchede

PSL Manual
section 6.3

SEQ: REP

<

6 December 1983

SEQ +(AND #2 (FAIL!-NOT #1»

Parser Tools
page 6.13

>;

% A repetition may be 0 or more single items (*) or 0 or more items
."% ""separated. by any ·token (ID[, J* parses a list of ID's separated
%
by, 's.
REP: ONE
<'[ (ID +(#1) /
" ANYKEY +(EQTOK!-NEXT (QUOTE #1» /
ANYKEY +(EQTOK!-NEXT (QUOTE #1») 'J +(AND #2 #1) ,* BLD!-EXPR /
,* BLD!-EXPR>;

% Create an sexpression to build a repetition.
BLD!-EXPR: +(PROG (X) (SETQ X (STK!-LENGTH»
$1 (COND (#1 (GO $1»)
(BUILD!-REPEAT X)
(RETURN T});
ANYKEY: ANYTOK • (ADDKEY fU/1);

% Add a new KEY

% One defines a single item.
ONE: "ANYKEY
'@ ANYKEY
I@@ ANYKEY
1+ UNLBLD
I . EVLBLD
': EVLBLD
'< ALT '>
'( ALT ')
1+. EVLBLD
ID

+(EQTOK!-NEXT (QUOTE #1» /
.(ADDRTERM ##1) +(EQTOK (QUOTE #1»
.(ADDGTERM ##1) +(EQTOK (QUOTE #1»
+(PUSH #1) /
+(PROGN #1 T) /
/
+(PROGN #1 T) /
/
+(PUSH #1) /
+('1) ;

/
/

% This rule defines an un evaled list. It builds a list with
% everything quoted.
UNLBLD: I( UNLBLD (t. UNLBLD ') +(CONS #2 #1) /
UNLBLD* I) +(LIST • (#2 • #1»
') +(LIST • #1» /
LBLD
/
ID
+(QUOTE #1) ;

% EVLBLD builds a list of evaled items.
EVLBLD: '( EVLBLD

EVLBLD ') +(CONS #2 #1) /
EVLBLD* ') +(#2 • #1) /

(I.

') ) /

"LBLD /
ID

/

Parser Tools
page 6.14

6 December 1983

LBLD: 'I NOM
'II NOM
'$ NOM
'& NOM

+(EXTRACT 11) /
+(REF 11) /
+(GENLAB 11) /
+(CADR (ASSOC 11 (CAR VARLIST») /

·.NOM

/

STR

I

"

PSL Manual
section 6.3

UNLBLD* ') +(LIST .11) I
ANYTOK +(QUOTE 11»;

(I(

% Defines the pattern matching rules (PATTERN

->

BODY).

PRUL: .• (SETQ INDEXLIST!* NIL)
PAT '-> (EVLBLD)*
+(LAMBDA (VARLIST T1 T2 T3) (AND. 11»
.(SETQ PNAM (GENSYM»
.{RULE!-DEFINE (LIST 'PUTD (LIST 'QUOTE PNAM)
'(QUOTE EXPR) (LIST 'QUOTE #1»)
+.(CONS #1 PNAM);

% Defines a pattern.
% We now allow the. operator to be the next to last in a ().
PAT: '& ('< PSIMP[/J* '> NOM
+.(PROGN (SETQ INDEXLIST!* (CONS 1#1 INDEXLIST!*»
(LIST '!& 12 11) ) /
NOM

+.(COND «MEMQ 111 INDEXLIST!*)
(LIST '!& '!& #1»
{T (PROGN (SETQ INDEXLIST!* (CONS #11 INDEXLIST!*»
(LIST '!& 11»» )
/ ID
I '!( PAT* <'. PAT +.(APPEND 12 #1»
/ " ANYTOK
I STR
I NOM ;

I!)

% Defines the primitives in a pattern.
PSIMP: ID / NOM I '( PSIMP*

I) I

.1

ANYTOK;

% The grammar terminator.
FIN

6.3.8. The Construction of MINI
MINI is actually described in terms of a. support package for any· MINI-generated parser
. and a ·self-description of MINI. The useful files (on PU: and PL:) are as· follows:

PSL Manual
section 6.3

6 December 1983

Parser Tools
page 6.15

MINI.MIN
The self definition of MINI in MINI.
MINI.SL
A Standard LISP version of MINI.MIN, translated by MINI itself.
MINI.RED
The support RLiSP for MINI.
MINI-PATCH.RED and MINI.FIX
,. , Some additions' being'tested.
MINI.LAP
The prec-ompiled'LAP file. Use LOAD MINI.
MINI-LAP-BUILD.CTL
A batch file that builds PL:MINI.LAP from the above files.
MINI-SELF-BUILD.CTL
A batch file that builds the MINI.SL file by loading and translating MINI.MIN.

6.3.9. History of MINI Development
The MINI Translator Writing System was developed in two steps. The first was the
enhancement of the META/RLISP [Marti 79] system with the definition of pattern matching
primitives to aid in describing and performing tree-to-tree transformations. META/RLISP
is very proficient at translating an input programming language into LISP or LISP-like
trees, but did not have a good method for manipulating the trees nor for direct
generation of target machine code. PMETA (as it was initially called) [Kessler 79] solved
these problems and created a very good environment for the development of compilers.
In fact, the PMETA enhancements have been fully integrated into META/RLISP.
The second step was the elimination of META/RLISP and the development of a smaller,
faster system (MINI). Since META/RLISP was designed to provide maximum flexibility and
full generality, the parsers that is creates are large and slow. One of its most significant
problems is that it uses its own single character driven LISP functions for token scanning
and recognition. Elimination of this overhead has produced a faster translator. MINI uses
the hand coded scanner in the underlying RLisp. The other main aspect of MINI was the
elimination of various META/RLISP features to decrease the size of the system (also
decreasing the flexibility, but MINI has been successful for the various purposes in COG).
MINI is now small enough to run on small LISP systems (as long as a token scanner is
provided). The META/RLI,SP features that MINI has changed or eliminated include the
following:
a. The ability to backup the parser state upon failure is supported in META/RLISP.
However, by modifying a grammar definition, the need for backup can be
mostly avoided and was therefore eliminated from MINI.
b. META/RLISP has extensive mechanisms to allow arbitrary length diphthongs.
MINI only supports two character diphthongs, declared prior to their use.
c. The target machine language and error specification operators
supported because they can be implemented with support routines.

are

not

d. RLISP subsyntax for specification of semantic operations is not supported
. (only LISP is provided).
Although MINI lacks many of the features of META/RLlSP, it still has been quite sufficient

Parser Tools
- page 6.16

6 December 1983

PSL Manual
section 6.3

for a variety of languages.

6.4. BNF Description of RLisp Using MINI
-The -following formal scheme for the translation of RLisp·syntax·to Lisp syntax is
presented to eliminate misinterpretation of the definitions. We have used the above MINI
syntactic form since it is close enough to BNF and has also been checked mechanically.
Recall that the transformation scheme produces an S-expression corresponding to the
input RLisp expression. A rule has a name by which it is known and is defined by what
follows the meta symbol:. Each rule of the set consists of one or more "alternatives"
separated by the meta symbol If being the different ways in which the rule is matched by
source text. Each rule ends with a;. Each alternative is composed of a "recognizer" and
a "generator". The "generator" is a MINI + expression which builds an S-expression from
constants and elements loaded on the stack. The result is then loaded on the stack. The
#n and ##n refer to elements loaded by MINI primitives or other rules. The "generator"
is thus a template into which previously generated items are substituted. Recall that
terminals in both recognizer and generator are quoted with a ' mark.
This RLisp/SYSLisp syntax is based on a series of META and MINI definitions, started by
R. Loos in 1970, continued by M. Griss, R. Kessler and A. Wang.

[??? This MINI.RLlSP grammar is a bit out of date ???]

[??? Need to confirm for latest RLISP ???]

mini trlisp;
dip: !: , !!>

,

,....,--

termin: t., / '$ ., .
rtermin: @; / @$ ;
rlisp: ( cmds rtermin
cmds:

%------

,

!*!* , !!= , !t , !f!f

%$ used to not echo result
.(next!-tok»*

%Note explicit Scan

procdef / rexpr
Procedure definition:

procdef: emodeproc (ftype procs/ procs) /
ftype procs / procs ;
ftype:

'fexpr.(setq FTYPE!* 'fexpr) / % function type
. 'macro .(setq FTYPE!* 'macro) /
'smacro .(setq FTYPE!* 'smacro) /
'nmacro .(setq FTYPE!* 'nmacro) /

PSL Manual
section 6.4

6 December 1983

Parser Tools
page 6.17

('expr I =T) .(setq FTYPE!* 'expr)
. emodeproc: ·'syslsp • (setqEMODE!* 'syslsp)1
.:( 'lisp/'symbolic/=T) .• (setq EMODE!·* '·symbolic)
procs: 'procedure id proctail
+(putd (quote 12) (quote FTYPE!* ) 11) ;
proctail: '( id[,]* ') termin rexpr +(quote (lambda 12 11»
termin rexpr +(quote (lambda nil #1» I
id termin rexpr +(quote (lambda (12) 11»

%------

Rexpr definition:

rexpr: disjunction;
disjunction: conjunction (disjunctail I =T) ;
disjunctail: ('or conjunction ('or conjunction)*)
+.(cons 'or (cons #3 (cons 12 #1»)
conjunction: negation (conjunctail I =T) ;
conjunctail: ('and negation ('and negation)*)
+.(cons (quote and) (cons 13 (cons 12 11»)
negation: 'not negation +(null 11) I
'null negation +(null 11) I
relation ;
relation: term reltail
reltail: relop term +(12 12 #1) I =T ;
term: ('- factor +(minus 11) I factor) termtail ;
termtail: (plusop factor +(#2 #2 #1) termtail) I =T
factor: powerexpr

factortai~

;

factortail: (timop powerexpr +(12 12 #1) factortail) I =T
powerexpr:dotexpr powtail ;

I

Parser Tools
page 6.18

6 December 1983-

section 6.4

powtail: ('** dotexpr +(expt '2 '1) powtail) / =T
dotexpr: primary dottail ;
dottaii:· ('.···primary+(.cons -112· 1/1 )··dottail) I =T
primary: ifstate / groupstate / begins tate /
whilestate / repeats tate / forstmts /
definestate / onoffstate / lambdas tate /
('( rexpr ') ) /
(" (lists / id / num) +(quote '1» /
id primtail / num ;
primtail:(':= rexpr +(setq 12 '1» /
(': labstmts ) /
'( actualst / (primary +(#2 #1»

/ =T

lists: '( (elements)* ') ;
elements: lists / id / num

.%------

If statement:

ifstate: 'if rexpr 'then rexpr elserexpr
+(cond ('3 12) (T 11»
elserexpr: 'else rexpr / =T +nil ;

%------

PSL Manual

While statement:

whilestate: 'while rexpr 'do rexpr
+( while 112 # 1)

%----- Repeat statement:
repeatstate: 'repeat rexpr 'until rexpr
+(repeat '2 #1) ;

%---- For statement:
forstmts: 'for fortail
fortail: ('each foreachstate) / forstate ;
.. foreachstate:' Id ·inoron rexpr -actchoice rexpr
+(foreach 15 14 13 12 11);

PSL Manual
section 6.4

6 December 1983

Parser Tools
page 6.19

inoron: ('in +in / 'on +on) ;
..---- .. -actchoice: ('do +do / 'collect +collect / 'conc +conc)
forstate: id ':= rexpr loops
loops: (': rexpr types rexpr
+(for '5 ('4 1 '3) '2 #1) ) /
('step rexpr 'until rexpr types rexpr
+(for '6 ('5 '4 '3) '2 #1) ) ;
types: ('do +do / 'sum +sum / 'product +product)

%-----

Function call parameter list:

actualst: ') +('1) / rexpr(,J* ') +.(cons 112 /1.1)
%-----~

Compound group statement:

groupstate: '«

%------

rexprlist '»

+.(cons (quote progn) '1)

Compound begin-end statement:

beginstate: 'begin blockbody 'end
blockbody: decllist blockstates
+.(cons (quote prog) (cons '2 #1»
decllist: (decls[;J* +.(flatten '1»
decls: ('integer

/ (=T +nil)

/ 'scalar) id[,J* ;

blockstates: labstmts[jJ* ;
labstmts: ('return rexpr +(return 81» /
«'goto / 'go 'to) id +(go #1» /
('if rexpr 'then labstmts blkelse
+(cond (#3 #2) (T #1») /
rexpr ;
blkelse: 'else labstmts / =T +nil
rexprlist: rexpr [jJ* ;
lambdastate: 'lambda lamtail

;

Parser Tools
page 6.20

6 December 1983

lamtail: '( id[,]* ') termin rexpr +(lambda 12 11) /
term in rexpr +(lambda nil 11) /
id termin. r.expr +( lambda (12) 11) ;

%-...;---- Define statement : (id- -and value are put onto table
%
named DEFNTAB:
definestate: 'define delist +.(cons (quote progn) 11) ;
delist: (id

%------

'=

rexpr +(put (quote 12)
(quote 11»)[,]*

(quote defntab)

On or off statement:

onoffstate: ('on +T / 'off +nil) switchlists
switchlists: 'defn +(set '!*defn 11)
timop: ('* +times / 'I +quotient) ;
plusop: ('+ +plus2 I '- +difference)
relop: ('< +lessp / '<= +lep I '= +equal I
'>= +gep / '> +greaterp) ;
FIN

PSL Manual
section 6.4

PSL MANUAL
SECTION 7.0

6 DECEMBER 1983

CONCEPT INDEX
PAGE 7.1

CHAPTER 7
INDEX OF CONCEPTS
The following is an alphabetical list of concepts, with the page on which they are
discussed.

« » ...
Arithmetic •

5.3

...

1.1

Assigning Precedence .

6.6

Bignums • . . . .

1.25

Binary Infix Operators.

6.2

Binary Operators.

6.6

BNF . . • . . . .

·.

6.9, 6.16

Buffers in EMOOE.

4.5

Case Statement

5.9

CGOl • • • . . • .

6.2

Circular Structures.

2.3

Comments • . . .

6.4

Compound Statements.

5.7

Conditional Statements

5.8

Construction Function.

6.2

Construction of MINI

6.14

CREF . . . . . .

· ..

1.7

Cross Reference Generator..

1.7

OefConst . . .

2.2

Dot Notation.

5.5

..

Edit Commands.

Editing in the Break loop
Editing with EMOOE.

. . . . · ..
EMOOE . • . . . · ..

4.1. 4.6
4.1
4.2

Editor •.

4.1

Error Handling in MINI

6.12

Error Handling •.

...

4.2
6.6

Error Recovery in MINI.

6.12

Escaped Characters .

6.7

Example of MINI. .
Examples . . .

..

..

6.11
1.21, 5.2, 5.3, 6.6, 6.?

Exclamation Point in RliSP.

6.7

Extensible Parser

6.1

External Form .

6.4

Fast operations

1.1, 1.5

Filename Conventions .

5.13

Files about MINI .

..

Form Oriented Editor .
From clause

....

6.14
4.5
1.2

Function Calls

6.4

Function definition.

5.6

Concept Index
page 7.2

6 December 1983

Function profiler.

2.5

Generator • • • . • . •

6.16

Generic operations.

3.1

Graph:-to-Tr.ee

2.3

Hash . table • •

2.2

Hashing Cons ••

2.2

History of MINI

6.15

If Then Statements

5.B

Infix Operators.

5.3, 6.4

Input • • . • .

5.12, 6.2

INTERLISP.•

4.5

InternalF orm

6.4

Key Words . . . . . . .

6.6

LISP Surface Language . . •

6.2

LISP. compared with RliSP.

5.3

list Notation Reader

6.11

Local Variables.

5.7

Loops • . . • • .

5.9, 5.11

Meta Compiler. . . •

6.1

MINI Development .

6.15

MINI Error Handling .

6.12

MINI Error Recovery

6.12

MINI Example • • • •

6.11

MINI Operators . . • .

6.9

MINI

~elf-Definition

.

MINI • • • • . . . . .

6.12
6.9

N-ary Expressions.

6.6

N-ary Functions •.

5.3

Numeric operators.

1.1

Objects • . . . . . . .

3.1

Operator Definition .

6.7

Operator Precedence

5.3

Operators.

6.2

Output . . .

5.12

Pair hash table. . . .

2.2

Parentheses. . . . . .

6.5

Parenthesis Checker.

2.9

Parse function . . . .

5.5

Parser Flow Diagram .

6.2

Parser Generator

6.1

Parsers • . . • . .

6.1

-Parsing Precedence

6.2

-Pattern Matcher ..

6.11

Pattern Matching in MINI.

6.11

Picture RLISP. . . . . • . .

1.9

PSL Manual
section 7.0

PSL Manual
section 7.0

6 December 1983

Precedence Table

6.2

Precedence. • •

5.3, 6.4

Print Name . . .

6.7

Printing Circular lists •

2.3

Printing Circular Vectors

2.3

PRlISP • • • . •

1.9

Procedure definition. •

5.6

Productions.

6.9

Prog • . • . . • •

5.7

Progn . • • • .

5.7

Property List.

6.4

Quote Mark in RlISP .

6.7

Quote Mark

6.4

RCREF . . .

1.7

Read function

5.5

Read . . .

6.2

Recognizer . .

6.16

Reduce • • . .

5.1

Right Precedence

6.2

RlISP Input. .

5.12

RliSP Output.

5.12

RliSP Parser.

6.7

RliSP Syntax.

5.2, 5.5

RliSP to LISP Translation. •

6.16

RlISP to LISP USing MINI. •

6.16

RlISP, compared with LISP.

5.3

RLiSP • • • . • •

5.1

Running MINI . . . . • • . • •

6.12

Scalar.

5.3, 5.7, 5.11

Scan Table ..

6.4

Screen Editor

4.2

Stack . • . . .

2.1

Starting MINI.

6.11

Structure Definition

1.17

Structure Editor . .

4.5

Table Driven Parser.

6.2

Template and Replacement

6.11

Tokens

6.2

Trees .•

6.9

UCI LISP

4.5

Unary Functions . . . . .

5.3

Unary Prefix Operators.

6.2

Utility modules.

1.1, 2.1

Vectors • . . . .

1.5

. Windows in EMODE.

4.5

Concept Index
page 7.3

PSL MANUAL
SECTION 8.0

6 DECEMBER 1983

FUNCTION INDEX
PAGE 8.1

CHAPTER 8
INDEX OF FUNCTIONS
The following is an alphabetical list of the PSL functions, with the page on which they
are defined.

& • • • • • • • • • • • • • • . • • • • • • • • • • • • • expr

1.4

*. . . . . . . . . . . . . . . . . . . . . .

• macro

1.3

+ . . . . . . . • . . • . . . . . . . . . . . • . . • • • macro

1.3

-.

1.3

• macro

II.
1= .
I ...... .

@gt=. •

• • • • • . . . • • • • • • . • • • • • • expr

1.4

• • • • • • • . • • • • • • • • • • • • • expr

1.2

• macro

1.3

• expr

1.2

. . • • . . . . • • • • • • • • • • . • expr

1.3

@gt . • • • • . • • • • • • • . • • • • • •

• ••• expr

@gt@gt • • . .

• • • • expr

1.4

• •. expr

1.2

@It= ••••
@It • • . • • . .

..••....•••.•

1.2

• expr

1.2

••• expr

1.4

• • • • • • • • . • • • • . • • • . • • • • • • • • • expr

1.4

@It@lt ••

A • • • . • • •

• ••. edit

Anyld • • • . .

• ••• expr

6.9

AnyTok • • • • • • • • • • . . . • • • . . • • • • • • • expr

6.9

4.6

B •.•••

• edit

4.2.4.6

BELOW.

• edit

4.7

BF • . • •

• edit

4.7

BI .•••

· edit

4.7

BIND- ••••.
BK ••.•

· edit

4.8

· edit

4.8

BO • . • •

edit

4.8

CHANGE

edit

4.8

COMS ••

edit

4.8

COMSQ ••

edit

4.8

Const ••.

macro

2.2

CPrint •••

expr

2.4

DetConst . . .

• • . • • • • macro

2.2

Detflavor •••

• ••. macro

3.4

Detmethod ••

• macro

3.5

Defstruct ••.

· fexpr

1.18

DetstructP • .

· expr

1.18

Defstruct Type

· expr

1.18

-I

Function Index
page 8.2

6 December 1983

PSL Manual

section 8.0

DELETE.

edit

4.9

E ••••

. edit

4.9

EditF ••

expr

EditFns ••

fexpr

EditP •.
EditV .••
I

4.9
-4.9

fexpr

4.9

• • fexpr

4.9

EMBED ••

edit

Evln ••

expr

EvOut ••

expr

5.13

EvShut •

expr

5.14

Extended-Get.

expr

2.3

Extended-Put.

expr

2.3

EXTRACT.

edit

4.10

F=.

• edit

4.11

F •

• edit

4.2, 4.10

4.9
5.13

For

macro

FS.

edit

4.11

Graph-to-Tree

expr

2.3

• expr

2.3

HAppend

1.2

HCons.

macro

2.3

HCopy.

macro

2.3

HELP.

• edit

4.2,4.11

Hlist •

nexpr

2.3

HReverse.

expr

2.3
4.11

I ..

edit

Id •

expr

6.9

IF

edit

4.11

If_System.

macro

2.5

In •••

macro

5.13

INSERT

• edit

4.12

Inspect

expr

2.4

Instantiate-Flavor

expr

3.7

LC ••

edit

4.12

LCL.

edit

4.12

U.

edit

4.12

LO .•

edit

4.12

LP.

edit

4.13

LPO .

edit

4.13
4.13

M ...

edit

Make-instance .

macro

MAKEFN

edit

MARK.

ecfit

4.14

MBo •

edit

4.14

MOVE.

edit

4.15

3.6
4.14

N •.

edit

4.15

NEX.

edit

4.16

PSL Manual

6 December 1983

Function Index
page 8.3

section 8.0
NTH.

• edit

Num.

• expr

NX ••

edit

Object-Type

expr

OK ••

edit ..

4.2, 4.16

ORF.

edit

4.17

ORR.

edit

4.17

Out

macro

4.16
6.10
4.16
3.9

5.13

P .•

edit

4.1, 4.17

Pl. .

edit

4.1

Pop.

macro

PP ••

edit

Push.

macro

R ••
REPACK.

edit

2.1
4.18
2.1
4.2. 4.18

• edit

4.18

RI ••.

edit

4.19

RO ••.

•• edit

4.19

RPrint.

• expr

5.12

S ...

edit

4.19

SAVE.

edit

4.19

SECOND

edit

4.20

Shut.

• macro

STOP .•

• edit

Str . . •

• expr

SubTypeP.

• expr

SW

edit

5.13
4.20
6.10
1.18
4.20

T .

edit

4.2

TEST .

edit

4.20

THIRD.

edit

4.20

THROUGH.

edit

4.20

TO •.

edit

4.21

TTY: ••••

edit

4.21

UNBLOCK.
UNDO.
UP •••••

edit

4.21

• edit

4.21

edit

4.1, 4.22

VECTOR-EMPTY?

expr

1.6

VECTOR-FETCH

expr

1.5

VECTOR-SIZE. . .

expr

1.6

VECTOR-STORE .

expr

1.6

VECTOR-UPPER-BDUND.

expr

1.6

XTR.

edit

4.22

I ..

expr

1.4

expr

1.3

expr

1.4

PSL MANUAL
SECTION 9.0

6 DECEMBER 1983

GLOBAL INDEX
PAGE 9.1

CHAPTER 9
INDEX OF GLOBALS AND SWITCHES
The following is an alphabetical list of the PSL global variables, with the page on which
they are defined.

!*CREFSUMMARY • . . • . . . • • • . . . . . . . . • switch

1.8

Fast-Integers . . . . . . . . . . . . . . . . . • . . • . switch

1.4

Fast-vectors . • . . . . . • . . . . . . • . • . . . • • switch

1.6

MAXLEVEL . . . . . . . . . . . . . . . . . . . . . . . global

4.1 1

NOLlST!* . . . . . . • . . • . . . . . • . . . • . . • • global

1.8

PLEVEL. . . . . . . . . . . . . • • . . . . . • . . . • global

4.1

RlISPSCANT ABLE!* . . . . . . . • • . . . . . . . • . global

5.5

UPFINOFlG. . . . . . . . . . . . . • . • . . • . . • • global

4.11

The Portable Standard LISP Users Manual
Part 3: System Dependent Information

by
The Utah Symbolic Computation Group

Department of Computer Science
University of Utah
Salt Lake City, Utah 84112

Version 3.2: 16 March 1984

Abstract
This manual describes the primitive data structures, facilities and functions present in the
Portable Standard Lisp (PSL) system.
It describes the implementation details and
functions of interest to a PSL programmer. Except for a small number of hand-coded
routines for lID and efficient function calling, PSL is written entirely in itself, using a
machine-oriented mode of PSL, called SYSLisp, to perform word, byte~ and efficient
integer and string operations. PSL is compiled by an enhanced version of the Portable
Lisp Compiler, and currently runs on the DEC-20, VAX, and MC68000.

Copyright (c) 1982

W. Galway, M. L. Griss, B. Morrison, and B. Othmer

Work supported in part by the Hewlett Packard Company, the International Business
Machines Corporation and the National Science Foundation under Grant Numbers
MCS80-07034 and MCS82-04247.

PSL MANUAL

5 DECEMBER 1983

PREFACE

Part 3 of The Portable Standard Lisp User's Manual contains system-dependent
- information. It includeschaptersabout:PSLon the Dec-20, the-Vax running Berkeley Unix,
- -and the Apollo. Each -chapter provides information on the PSL executables, the PSL file
structure, and how to get started using PSL on the particular system. Documentation on
the interface between PSL and each operating system is also given.
These chapters were adated from chapters in the January 19, 1983 version of the
manual.
Contributions were made by Russ Fish, Will Galway, Robert Kessler, Bobbie
Othmer, and John W. Peterson.

5 December 1983

PSL Manual: Part 3
Table of Contents

page i

TABLE OF CONTENTS

~CHAPTER1.

1.1.
1.2.
1.3.
1.4.
1.5.
1.6.
1.7.
1.8.
1.9.

PSlONTHE DECSYSTEM-20

Purpose of This Chapter. . . . . . . . . . .
Logical Device Names for DecSystem-20 PSL .
PSL Executables. . . . . . . . . . . .
File Structure on the DecSystem-20 . .
Sample Session with DecSystem-20 PSL
Init files . . . . . . . . . . . .
Error and Warning Messages . . .
Reporting Errors and Misfeatures.
Tops-20 Interface. . . . . . . .
1.9.1. User Level Interface. . . .
1.9.2. The Basic Fork Manipulation Functions
1.9.3. File Manipulation Functions
1.9.4. Miscellaneous Functions. . . . . . .
1.9.5. Jsys Interface. . . . . . . . . . . .
1.9.6. Bit, Word and Address Operations for Jsys Calls.
1.9.7. Examples. . . . . . . . . . . . . . . . . . .

1.1
1.1
1.2
1.3
1.4
1.6
1.7
1.7
1.8
1.8
1.10
1.11
1.11
1.12
1.14
1.15

CHAPTER 2. PSL UNDER VAX UNIX
2.1.
2.2.
2.3.
2.4.
2.5.
2.6.
2.7.
2.8.
2.9.

Purpose of This Chapter. .
Getting started on Vax Unix
PSL Executables. . . . . .
Unix File Structure in PSL .
Sample Session with Vax Unix PSL·.
Init Files for PSL . . . . . . . .
Error and Warning Messages. . .
Reporting Errors and Misfeatures.
Unix Interface. . . . . . . . . .
2.9.1. Miscellaneous Unix Functions
2.9.2. Loading C code into PSl.
2.9.3. Calling oloaded functions
2.9.4. Oload Internals . . . . .
2.9.5.' I/O Control Functions. .

2.1
2.1
2.2
2.3
2.5
2.7
2.8
2.8
2.8
2.8
2.9
2.10
2.11
2.12

CHAPTER 3. PSL ON THE APOLLO
3.1.
3.2.
3.3.
3.4.
3.5.

Purpose of This Chapter. .
Setting up Logical Names .
File Structure on the Apollo
Sample Session with Apollo
Init Files . . . . . . . . .

. .
. .
PSL
. .

.
.
.
.

3.1
3.1
3.2
3.3
3.5

PSL Manual: Part 3
Table of Contents

5 December 19B3

3.6. Error and Warning Messages.
3.7. Reporting Errors and Misfeatures.
3.B. Aegis System Interface . . . .
3.B.1. Introduction . . . . . . .
- 3.8.-2;~How,-the-Package Works . .
3.B.3. Handling-_Simple Arguments
3.B.4. More Complicated Data Types
3.B.5. Some Real Examples . .
3.B.6. System Interface Package
3.8.7. Demonstration Program
3.9. Dumplisp Utility. . . . . .
3.9.1. Using DumpLisp. . . .
3.9.2. Using Saved Images. .
3.9.3. Other DumpLisp Details
CHAPTER 4. INDEX OF CONCEPTS
CHAPTER 5. INDEX OF FUNCTIONS
CHAPTER 6. INDEX OF GLOBALS AND SWITCHES

page ii

3.6
3.6
3.6
3.6
3.7
3.7
3.8
3.10
3.13
3.13
3.14
3.14
3.15
3.16

PSL MANUAL
SECTION 1.0

5 DECEMBER 1983

PSL ON THE DECSYSTEM-20
PAGE 1.1

CHAPTER 1
PSL ON THE DECSYSTEM-20
1.1;-Purpose of This Chapter. . . . . . . . ._ . _.
1.2; Logical- Device -Names for -DecSystem-20 PSL .
1.3. PSL Executables. . . . . . . '. . . . .
1.4. File Structure on the DecSystem-20 . .
1.5. Sample Session with DecSystem-20 PSL
1.6. Init files . . . . . . . . . . . .
1.7. Error and Warning Messages. . .
1.8. Reporting Errors and Misfeatures.
1.9. Tops-20 Interface. . . . . . . .
1.9.1. User Level Interface. . . .
1.9.2. The Basic Fork Manipulation Functions
1.9.3. File Manipulation Functions
1.9.4. Miscellaneous Functions. . . . . . .
1.9.5. Jsys In.terface. . . . . . . . . . . .
1.9.6. Bit, Word and Address Operations for Jsys Calls.
1.9.7. Examples. . . . . . . . . . . . . . . . . . .

1.1
1.1
1.2
1.3
1.4
1.6
1.7
1.7
1.8
1.8
1.10
1.11
1.11
1.12
1.14
1.15

1.1. Purpose of This Chapter
This chapter is for beginning users of PSL on the DecSystem-20.
It begins with
descriptions of how to set up various logical device definitions required by PSL and how
to run PSL. The chapter continues with a description of the file structure associated with
PSL, an example on use of the PSL system, and miscellaneous hints and reminders. It
concludes with a discussion of interfacing to the Tops-20 operating system.

1.2. Logical Device Names for DecSystem-20 PSL
In order to make all DecSystem-20 versions of PSL compatible, PSL makes heavy use of
logical names for access to various directories. Also, as each release of PSL is prepared,
we may find it convenient to change the names and number of subdirectories. The
DecSystem-20 allows these logical names to be used as if they were directory names.
These definitions are edited at installation time to reflect local usage, and stored in a file
whose name is something like "Iogical-names.xxx". This file is normally placed on an
appropriate directory like ss: < psi> at Utah.
Contact your installer to find its exact
location and name. It is absolutely essential that TAKE LOGICAL-NAMES.CMD be
inserted in your LOGIN.CMD file, or COMAND.CMD file (if you frequently push to new
execs), or executed at EXEC level before using PSL. PSL is written to rely on these logical
device definitions in place of "hard-coded" directory names. PSL also uses TOPS-20
search paths; for example, "PL:" is the directory (or search list) on which PSL looks for
Lap and Fasl files of the form "xxxx.b".
The logical name "PSL:" is defined to be the directory on which the PSL executables

PSL on the DecSystem-20
page 1.2

5 December 1983

PSL Manual
section 1.2

reside.
Thus "PSL:PSL.EXE" should start PSL executing.
There should usually be a
PSL:BARE-PSL.EXE, PSL:PSL.EXE, PSL:RUSP.EXE and PSL:PSLCOMP.exe. These executables
are described in the next section.

·.1.3.PSL Executables
After defining the device names, type either PSL:RUSP or PSL:PSL to the at-sign prompt,
@. A welcome message indicates the nature of the system running, usually with a date
and version number. This information may be useful in describing problems.
BARE-PSL.EXE is a "bare" PSL using Lisp (I.e. parenthesis) syntax. This is a small coreimage and is ideal for simple Lisp execution.
It also includes a resident Fasl, so
additional modules can be loaded. BARE-PSL is used as the base for creating all of the
other executables.
Certain modules are not present in the "kernel" or "bare-psi" system, but can be loaded
as options. Optional modules can be loaded by executing

(LOAD modulename)
PSL.EXE is an installation dependent "enhanced" BARE-PSL. Your system installer has
determined which modules are to be included in your base system. At Utah, the only
additional modules in PSL.EXE are the ones necessary to permit the the reading of an
. initialization file upon startup (see Section 1.6 for details of the initialization files). You
:can discover which modules are loaded into your system by examining the variable
. ·OPTIONS!* upon startup of PSL.EXE.
RUSP.EXE is also an "enhanced" BARE-PSL with additional modules loaded; typically
::.including the compiler, the RLisp parser and the init-file module. For more information
about RLisp see the RUSP chapter in Part 2 of the PSL Reference Manual.
PSLCOMP.EXE is an executable that permits compilation of Lisp, RLisp or build files into
loadable binary modules. PSLCOMP.EXE is built from BARE-PSL.EXE and includes the
following modules: pslcomp-main, init-file, objects, common, strings, pathnames, fastvector and nstruct. The pslcomp-main module implements a function that will read the
information on the PSLCOMP.EXE executation line, interpret that as the name of a file and
compile the file. When the file name does not include an extension, PSLCOMP first looks
for .BUILD (an RUSP build file that usually reads in a number of files to make
into a single loadable module),  .SL (a PSL Lisp syntax source file) and finally
.RED (an RUSP source file). The file will be compiled and a binary file will be
created in the SAME DIRECTORY as the input file. Therefore, if there is a file FOO.SL in
the XX: directory:

@PSL:PSLCOMP XX:FOO

%Will compile xx:foo.sl into xx:foo.b
NMODE.EXE is the NMODE text editor and PSL environment {see the NMODE reference

PSL Manual
section 1.3

5 December 1983

PSL on the DecSystem-20
page 1.3

manual for further details}.
It is assumed by PSL and RLisp that file names be of the form I/*.sl" or I/*.Isp" for Lisp
files, "*.red" for RLisp files, "*.bl/ for Fasl files, and "*.Iapl/ for Lap files.

1.4. File Structure on· the DecSvstem-20
At Utah, the DecSystem-20 is used as the primary system for source code for all of the
PSL supported machines. Thus a hierarchical directory structure is .utilized to maintain
the various sources. At the top of the tree is the PSL: directory. This directory contains
the executables, the logical-names definition file, a couple of news files and a set of
NMODE description files. Under the PSL: directory is a set of directories that generally
contain the target machine independent files for a particular area of the system. Then
under that directory are a set of target machine dependent directories. This scheme is
reflected in the use of the logical names. The generic logical name consists of three
parts:
p
The 'p' denotes that all of the directories are associated with PSl.
abbreviation> is a code for the specific target machine as follows:
An empty 

signifies

The  % Notice the numbered prompt.
1 "Lisp> % Comments begin with-"%" and do ·.not change the prompt
1 Lisp> % number.
% Make an assignment for Z.
1 Lisp> (Setq Z '(1 2 3»
(1 2 3)
2 Lisp> (Cdr Z)
%Notice the change in prompt number.
(2 3)
3 Lisp> (De Count (L)
%Count counts the number or elements
(Cond «Null L) 0) % in a list L.
3 Lisp>
3 Lisp>
(T (Add1 (Count (Cdr L»»»
COUNT
4 Lisp> (Count Z)
%Call Count on Z.
3
5 Lisp> (Tr Count) %Trace the recursive execution of "Count".
(COUNT)
6 Lisp>
%A callan "Count" now shows the value of
6 Lisp>
%"Count" and of its arguments each time
6 Lisp> (Count Z)
%it is called.
COUNT being entered
L:
(123)
COUNT (level 2) being entered
L: (2 3)

COUNT (level 3) being entered
L:

(3)

COUNT (level 4) being entered
L:
NIL
COUNT (level 4) = 0
COUNT (level 3) =
COUNT (level 2) = 2
COUNT = 3
3
7 Lisp> (Untr Count)
NIL
8 Lisp> (Count 'A) %This generates an error causing the break
%loop to be entered.
***** An attempt was made to do CDR on 'A', which is not a pair
Break loop
9 Lisp break» ?
BREAK():{Error,return-value}
This is' a Read-Eval-Print loop, similar to the top level loop,
except that the following IDs at thetop--Ievel' cause functions to
be called rather than being evaluated:

PSL on the DecSystem-20
page 1.6
?

T
Q

A
C
R
M
E
I

5

December

1983

PSL Manual
section 1.5

Print this message, listing active Break IDs
Print stack backtrace
Exit break loop back to ErrorSet
Abort to top level, i.e. restart PSL
- - ---Return last value to the ContinuableError call
-Reevaluate ErrorForm!* and return
Display ErrorForm!* as the "message"
Invoke a simple structure editor on ErrorForm!*
(For more information do Help Editor.)
Show a trace of any interpreted functions

See the manual for details on the Backtrace, and how ErrorForm!* is
set. The Break Loop attempts to use the same TopLoopRead!* etc, as
the calling top loop, just expanding the PromptString!*.
NIL
10 Lisp break»
%Get a Trace-Back of the
10 Lisp break» I
%interpreted functions.
Backtrace, including interpreter functions, from top of stack:
CDR COUNT ADD1 COND COUNT
NIL
11 Lisp break» Q
%To exit the Break Loop.
12 Lisp>
%Load in a file, showing its execution.
12 Lisp>
%The file contains the following:
12 Lisp>
% (Setq X (Cons 'A (Cons 'B Nil)})
12 Lisp>
% (Count X)
12 Lisp>
% (Reverse X)
12 Lisp> (Dskin "small-file.sl")
(A B)

2
(B A)

NIL
13 Lisp> (Quit)
@continue
"Continued"
14 Lisp> "C
@start
15 Lisp> (Quit)
1.6. Init files

Init files are available to make it easier for the user to customize PSL to his/her own
needs. When PSL, RLlSP, or PSLCOMP is executed, if a file PSL.INIT, RLlSP.INIT, or
PSLCOMP.INIT is on the home directory, it will be read and evaluated. Currently all init
fUes must be written in Lisp syntax. They may use Faslin or Load as needed. More
details on init files are available in Part 1 of this manual.

PSL Manual
section 1.7

5 December 1983

PSL on the DecSystem-20
page 1.7

1.1. Error and Warning Messages
Many functions detect and signal appropriate errors (see the chapter on error handling
in Part 1 of this manual for details); in many cases, an error message is printed. The
- error conditions ···aregivenas -. part of -. a function's· definition in the manual. An error
- -message is··preceded by-five stars (*); a warning message is preceded by three. For
example, most primitive functions check the type of their arguments and display an error
message if an argument is incorrect. The type mismatch error mentions the function in
which the error was detected, gives the expected type, and prints the actual value passed.
Sometimes one sees a prompt of the form:
Do

you really want to redefine the system function 'FOO'?

This means you have tried to define a function with the same name as a function used by
the PSL system. A Y, N, YES, NO, or B response is required. B starts a break loop. After
quitting the break loop, answer Y, N, Yes, or No to the query. See the definition of YesP
in the input/output chapter in Part 1 of this manual. An affirmative response is extremely
dangerous and should be given only if you are a system expert. Usually this means that
your function must be given a different name.
A common warning message is
*** Function "FOQ" has been redefined
If this occurs without the query above, you are redefining your own function.
happens normally if you read a file, edit it, and read it in again.

This

1.8. Reporting Errors and Misfeatures
Send bug MAIL to PSL -BUGS@UTAH-20. The message will be distributed to a list of
users concerned with bugs and maintenance, and a copy will be kept in < PSL > BUGSMISSFEATURES.TXT at UTAH-20.

(Bug ): undefined

DEC-20 only, expr

The function BugO; can be called from within PSL:RLisp. This starts MAIL
(actually MM) in a lower fork, with the To: line set up to PSLBUGS@UTAH-20. Simply type the subject of the complaint, and then the
message.
After typing message about a bug or a misfeature end finally with a

Z>.

< Ctrl-N >

aborts the message.

< Ctrl-

PSL on the DecSystem-20
page 1.8

5 December 1983

PSL Manual
section 1.9

1.9. Tops-20 Interface
In the DecSystem-20 implementation, there are a set of functions that permit the user
to access specific Tops-20 services. These include the ability to submit commands to be
run in··a·'~lower.-fork~~;such as· starting: an 'editor~' submitting a: system print command,
.. Iisting directories, and so on.- We also· provide an interface to the DecSystem-20 Jsys
function with appropriate support functions (such as bit operations, byte-pointers, etc.).

1.9.1. User. Level Interface
The basic function of interest is DoCmds, which takes a list of strings as arguments,
concatenates them together, starts a lower fork, and submits this string (via the Rescan
buffer). The string should include appropriate < CR > < LF >, "POP" etc. A global variable,
CRLF, is provided with'" the < CR > < LF > string.
Some additional entry points, and
common calls have been defined to simplify the task of submitting these commands.
Load EXEC to get these functions.

(DoCmds L:string-list): any
Concatenate strings into a single string (using ConcatS), place into the
rescan buffer using PutRescan, and then run a lower EXEC, trying to use an
existing Exec fork if possible.

CRLF [Initially: ""]

global

This variable is "CR-LF", to be appended to or inserted in Command strings
for fnc(DoCmds}. It is (STRING(Char CR,Char LF».
(Concats L: string-list): string
Concatenate string-list into a single string, ending with CRLF.

[??? Probably ConcatS should be in STRING, we add final CRLF in PutRescan
???]
(Cmds [L :string]): any
Submit a set of commands to lower EXEC
E.g. (CMDS "VDIR *.RED " CRLF "DEL *.LPT" CRLF "POP").
The following useful commands are defined:
(VDir L:string): any
.. Displav~,adir.ectory-,.and. return to . PSL, e.g. (VDIR "R. *")..
(LIST "VDIR'" L CRLF "POP"».

Defined 'as (DoCmds

PSL Manual
section 1.9

5 December 1983

PSL on the DecSystem-20
page 1.9

(HelpDir ): any
Display PSL help directory.
"POP")).

Defined as {DoCmds (LIST "DIR PH:*.HLP" CRLF

{Sys L:string}:any
Defined as {DoCmds (LIST "SYS

II

L CRLF "POP")).

(Take L: list): any
Defined as (DoCmds (LIST "Take" FileName CRLF "POP")).

(Type L:string): any
Type out files. Defined as (DoCmds (LIST "TYPE

II

L CRLF"POP")).

While definable in terms of the above DoCmds via a string, more direct execution of
files and fork manipulation is provided by the following functions. Recall that file names
are simply Strings, e.g. "< psi >foo.exe", and that ForkHandles are allocated by TOPS-20 as
large integers.

{Run FILENAME:string}: any
Create a fork, into which file name will be loaded, then run it, waiting for
completion. Finally Kill the fork.

(Exec ): any
Continu~ a lower EXEC, return with POP. The Fork will be created the first
time this is run, and the ForkHandle preserved in the global variable
ExecFork.

(Emacs ): any
Continue a lower EMACS fork. The Fork will be created the first time this is
run, and the ForkHandle preserved in the global variable EmacsFork.

(MM ): any
Continue a lower MM fork. The Fork will be created the first time this is
run, and the ForkHandle preserved in the global variable MMFork.

[??? MM looks in the rescan buffer for commands, so fairly useful
mailers (e.g.- for BUG reports) can be created.
Perhaps make
MM(s:string) for this purpose. ???]

PSL on the DecSystem-20
page 1.10

5 December 1983

PSL Manual
section 1.9

(Reset ): None Returned
This function c,auses the system to be restarted.

- 1.9~2. The: Basic ,Fork Manipulation' Functions
(GetFork JFN: integer): integer
Create a fork handle for a file; a GET on the file is done.
(StartFork FH: integer): None Returned
Start a fork running, don't wait, do something else.
Restart a fork, after a WaitFork.

Can also be used to

(WaitFork FH:integer): Unknown
Wait for a running fork to terminate.
(RunFork FH: integer): Unknown
Start and Wait for a FORK to terminate.
(KillFork FH: integer): Unknown
Kill a fork (may not be restarted).
(OpenFork FILENAME: string): integer
Get a fHe into a Fork, ready to be run.
(PutRescan S:string): Unknown
Copy a string into the rescan buffer, and announce to system, so that next
PBIN will get this characters. Used to pass command strings to lower forks.
(GetRescan ): {NIL,string}
See if there is a string in the rescan buffer. If not, Return NIL, else extract
that string and return it. This is useful for getting command line arguments
in PSL, if MAINO is rewritten by the user. This will also include the program
name, under which this is called.

PSL Manual
section 1.9

5 December 1983

PSL on the DecSystem-20
page 1.11

1.9.3. File Manipulation Functions
These mostlv return a JFN, as a small integer.

(GetOldJfnFILENAME:string): integer
Get a Jfn on an existing file.

(GetNewJfn FILENAME :string): integer
Get a Jfn for an new (non-existing) file.

(RelJfn JFN: integer): integer
Return Jfn to TOPS-20 for re-use.

(FileP FILENAME:string): boolean
Check if FILENAME is existing file; this is a more efficient method than the
kernel version that uses ErrorSet.

(OpenOldJfn JFN: integer): integer
Open file on Jfn to READ 7-bit bytes.

(OpenNewJfn JFN: integer): Unknown
Open file on Jfn to write 7 bit bytes.

(GtJfn FILENAME:string BITS: integer): integer
Get a Jfn for a file, with standard Tops-20 Access bits set.

(NameFromJfn JFN:integer): string
Find the name of the File attached to the Jfn.

1.9.4. Miscellaneous Functions
(GetUName ): string
Get USER name as a string

PSL on the DecSystem-20
page 1.12

5 December 1983

PSL Manual
section 1.9

(GetCDir ): string
Get Connected DIRECTORY
. (ClockTime ): string
Get the time of day in the form "hh:mm:ss".
(GetLoadAverage ): string
Get the load average over the last minute in the form "dd.dd".
(InFile [FILS: id-list]): Unknown
Either solicit user for file name (In File), and then open that file, else open
specified file, for input.

1.9.5. Jsys Interface
The Jsys interface and jsys-names (as symbols of the form jsXXX) are defined in the
source file P20U:JSYS.RED.
The access to the Jsys call is modeled after IDapply to avoid CONS and register reloads.
These could easily be done open-coded
The following SYSLISP calls, XJsys'n', expect W-values in the registers, R1... R4, a Wvalue for the Jsys number, Jnum and the contents of the 'nth' register. Unused registers
should be given O. Any errors detected will result in the JsysError being called, which
'will use the system ErStr JSYS to find the error string, and issue a StdError.
(XJsysO R1:s-integer R2:s-integer R3:s-integer R4:s-integer
Jnum:s-integer): s-integer
Used if no result register is needed.
(XJsys1 R1:s-integer R2:s-integer R3:s-integer R4:s-integer
Jnum:s-integer): s-integer

(XJsys2 R1:s-integer R2:s-integer R3:s-integer R4:s-integer
Jnum:s-integer): s-integer

(XJsys3 R1:s-integer R2:s-integer R3:s-integer R4:s-integer
Jnum:s-integer): s-integer

PSL Manual
section 1.9

5 December 1983

PSL on the DecSystem-20
page 1.13

. (XJsys4 R1:s-integer R2:s-integer R3:s-integer R4:s-integer
Jnum:s-integer): s-integer
The following functions are the Lisp level calls, and expect integers or s for the
·arguments,which··areh.converted· into'ds-integers by the function J.conv, below. We will
use JS to·indicate .. the ·argument ·type. The:result returned· is an integer, which should be
converted to appropriate type by the user, depending on the nature of the Jsys. See the
examples below for clarification.
(JsysO R1:JS R2:JS R3:JS R4:JS Jnum:s-integer): integer
Used is no result register is needed.
(Jsys1 R1 :JS R2:JS R3:JS R4:JS Jnum:s-integer): integer
(Jsys2 R1 :JS R2:JS R3:JS R4:JS Jnum:s-integer): integer
(Jsys3 R1:JS R2:JS R3:JS R4:JS Jnum:s-integer): integer
(Jsys4 R1 :JS R2:JS R3:JS R4:JS Jnum:s-integer): integer
The JConv converts the argument type, JS, to an appropriate s-integer, representing
either an integer, or string pointer, or address.
(JConv J:{integer,string}): s-integer
An integer J is directly converted to a s-integer, by (Int2Sys J). A string J
is converted to a byte pointer by the call (Lor 8#10700000000 (Strinf J».
Otherwise a (StdError "'J' not known in Jconv") is produced.
Additional conversions of interest may be performed by the functions Int2Sys, Sys2Int,
and the following functions:
(Str2Int S:string): integer
Returns the physical address of the string start as an integer; this can
CHANGE if a GC takes place, so should be done just before calling the Jsys.
(Int2Str J: integer): string
J is assumed to be the address of a string, and a legal, tagged string is
created.

PSL on the DecSystem-20
page 1.14

5 December 1983

PSL Manual
section 1.9

1.9.6. Bit, Word and Address Operations for Jsys Calls
(RecopyStringToNULL S:w-string): string

"s

is>assumedto -be-the-:address of a string,-and a:-Iegal, tagged string is
create d, by searching for the terminating NULL, allocating a HEAP string,
and copying the characters into it. This is used to ensure that addresses
not in the Lisp heap are not passed around "cavalierly" (although PSL is
designed to permit this quite safely).

(Swap X: integer): integer
Swap half words of

2S;

actually (Xword (LowHalfWord X) (HighHalfWord X)).

(LowHalfWord X: integer): integer

expr

Return the low-half word of the machine representation of
(Land X 8#777777).

2S.

Actually

(HighHalfWord X: integer): integer

expr

Return the upper half word as a small integer, of the machine word
representatio n of 2S. Actually (Lsh (Land X 8#777777000000) -18).

(Xword X: in teger Y: in teger): in teger
Build a Word from
(LowHalfWord V)).

Half-Words,

actually

(Lor(Lsh(LowHalfWord

X)

18)

(JBi ts L: list): integer
Construct a word-image by OR'ing together selected bits or byte-fields. L
is list of integers or integer pairs. A single integer in the range 0... 35,
BitPos, represents a single bit to be turned on.
A pair of integers,
(FieldValue . RightBitPos), causes the integer FieldValue to be shifted so its
least significant bit (LSB) wi" fall in the position, RightBitPos. This value is
then OR'ed into the result. Recall that on the DEC-20, the most significant
bit (MSB), is bit 0 and that the LSB is bit 35.

(Bi ts L: list): integer
A convenient access to Jbits: (JBits (cdr L».

macro

PSL Manual
section 1.9

5 December 1983

PSL on the DecSystem-20
page 1.15

1.9.7. Examples
The following range of examples illustrate the use of the above functions.
examples can be found in P20U:exec.red.

(Jsys1 0 0 0 0 jsPBIN)
%Reads a character, returns the ASCII code.
(JsysO ch 0 0 0 jsPBOUT)
%Takes ch as Ascii code, and prints it out.
(De OPENOLDJfn (Jfn)
%. OPEN to READ
(JSYSO Jfn (Bits ( (7 • 5) 19» 0 0 jsOPENF»
(De GetFork (Jfn)
%. Create Fork, READ File on Jfn
(Prog (FH)
(Setq FH (JSYS1(Bits '(1» 000 jsCFork»
(JSYSO (Xword FH Jfn) 0 0 0 jsGet)
(return FH»)
(De GetOLDJfn (FileName) %. test If file OLD and return Jfn
(Prog (Jfn)
(Cond «NULL (StringP FileName» (return NIL»)
(Setq Jfn (JSYS1(Bits'(2,3,17» FileName 0 0 jsGTJfn»
% OLD! MSG !SHORT .
(Cond «Lessp Jfn 0) (return NIL»)
(return Jfn»)
(De GetUNAME ()
%. USER name
(Prog (S)
(Setq S (Mkstring 80»
%Allocate a 80 char buffer
(JSYSO s (JSYS1 a 0 a 0 jsGJINF) a a jsDIRST)
(Return RecopyStringToNULL S»)
%Since a NULL may be appear before end
(De ReadTTY ()
(Prog (S)
(Setq S (MkString 30»
% Allocate a String Buffer
(JsysO S (BITS '(10 (30 • 35») "Retype it!" a jsRDTTY)
%Sets a length halt (Bit 10),
%and length 30 (field at 35) in R2
%Gives a Prompt string in R3
%The input is RAISE'd to upper case.
%The Prompt will be typed .if  is input
. (Return RecopyStringToNULL S»)
%Since S will now possibly have a shorter

More

PSL on the DecSystem-20
page 1.16

5 December 1983

%string returned

PSL Manual
section 1.9

3 APRIL 1984

PSL MANUAL
SECTION 2.0

PSL UNDER VAX UNIX
PAGE 2.1

CHAPTER 2
PSL UNDER VAX UNIX
2.1.
2.2.
2.3.
2.4.
2.5.
2.6.
2.7.
2.8.
2.9.

Purpose of This Chapter. .
Getting started on Vax Unix
PSL Executables. . . . . .
Unix File Structure in PSL .
Sample Session with Vax Unix PSL .
Init Files for PSL . . . . . . . .
Error and Warning Messages. . .
Reporting Errors and Misfeatures.
Unix Interface. . . . . . . . . .
2.9.1. Miscellaneous Unix Functions
2.9.2. Loading C code into PSL.
2.9.3. Calling oloaded functions
2.9.4. Oload Internals . . . .
2.9.5. I/O Control Functions. .

2.1
2.1
2.2
2.3
2.5
2.7

2.8
2.8
2.8
2.8
2.9
2.10
2.11
2.12

2.1. Purpose of This Chapter
This chapter is for beginning users of PSL on the Vax running Berkeley Unix. It begins
with descriptions of how to set up various csh variables required by PSL and how to run
PSl. The chapter continues with a description of the file structure associated with PSL,
an example of use of the PSL system, and miscellaneous hints and reminders.
It
concludes with a discussion of interfacing to the Unix operating system.

2.2. Getting started on Vax Unix
PSL under Unix makes extensive use of C-shell variables ('Idollar sign" variables) to
describe pathnames to the various PSL subdirectories. 1 These variables must be defined
for PSL to work. To do this you should put the following line at the end of your • cshrc
file. (The file which is executed whenever you start up a new shell, including when you
first log in.)
source -psl/dist/psl-names
This line reads a file from the $psl directory to define all the csh variables used by PSl.
This is absolutely required only for systems personnel installing or updating PSL. It is
optional for other users, but eases reference to the PSL sources. These variables are
automatically known in PSl. See section 2.4 and the release notes for more details.

1Most of this Information depends on the use of the Berkeley C-shell (csh) and will need modification (or might not
work) if the Bourne shell (sh) is your command shell of choice.

PSL under Vax Unix
page 2.2

3 April 1984

PSL Manual
section 2.2

Depending on where the PSL executables have been installed on your system, you may
have to change the definition of path in your .login file. The PSL executables typically
reside on the $psys directory, so a line something like the following will make them
available:
set path=(. $psys /bin /usr/bin)
However, it is more common for the installer of PSL to create symbolic links to the PSL
executables in some standard directory of executable files, which makes the above
unnecessary. In short, talk to your local PSL installer to get the details on what is
available and how to run it.

2.3. PSL Executables
There are several different executable forms of PSL available, one or more of them may
be installed on your system. Type either psI or rlisp to the C-shell. A welcome
message indicates the nature of the system running, usually with a date and version
number. This information may be useful in describing problems.
bare-psI is a "bare" PSL using Lisp (Le., parenthesis) syntax. This is a small core-image
and is ideal for simple Lisp execution. It also includes a resident loader, so additional
modules can be loaded. Bare-psi is used as the base for creating all of the other
executables.
Certain modules are not present in the "kernel" or "bare-psi" system, but can be loaded
as options. Optional modules can be loaded by executing

(LOAD

modulename)

psI is an installation dependent "enhanced" bare-psI.
Your system installer will
determined which modules are to be included in your base system. At Utah, the only
additional modules in psI are the ones necessary to permit the reading of an initialization
file upon startup (see Section 2.6 for details of the initialization files). You can discover
which modules are loaded into your system by examining the variable OPTIONS!* upon
startup of psI.
rlisp is also an "enhanced" bare-psi with additional modules loaded; typically including
the compiler, the RLisp parser and the init-file module. For more information about RLisp
see the RLisp chapter in Part 2 of the PSL Reference Manual.
pslcomp is an executable that permits compilation of Lisp, RLisp, or build files into
loadable binary modules. pslcomp includes a function that will read the information on
the pslcomp executation line, interpret that as the name of a file and compile the file.
When the file name does not include an extension, pslcompfirst looks for filename.BUILD
(an RLisp build file that usually reads in a number of files to make into a single loadable
module), filename.SL (a PSL Lisp syntax source file) and finally filename. RED (an RLisp
source file). The file will be compiled and a binary file will be created in the SAME
DIRECTORY as the input file. Therefore, if there is B" file faa. sl in the xx directory:

3 April 1984

PSL Manual
section 2.3

PSL under Vax Unix
page 2.3

pslcomp foo.sl

%Will

compile xx/foo.sl into xx/foo.b

nmode is the NMODE text editor and PSL environment (see the NMODE reference manual
for further details).
It is assumed by PSL and RLisp that file names be of the form *.51 or * .lsp for Lisp
files,
red for RLisp files,
b for Fasl files, and .lap for Lap files.

*.

*.

*

2.4. Unix File Structure in PSL
The specific location of PSL directories is left to the installer, to reflect the conventions
of local usage and file system layout.
The root of the PSL tree is (on a "typical"
installation) located in the home directory of a pseudo-user named "psl", and hence may
be accessed as "-psl".
The C-shell provides two kinds of substitution features which can map filenames into
their "true" form. One kind of substitution is called "variable SUbstitution", and is used for
"$ variables" (Le., "C-shell variables"). The other kind of substitution is called "filename
SUbstitution", and supports "*,, and "?" wildcards; and also "-" (twiddle) at the beginning
of filenames to refer to home directories. PSL supports "$" and "-" substitutions, but
only at the beginning of filenames. As in csh, "environment" variables are automatically
known as "$" variables.
Nearly all of the PSL subdirectories have corresponding C-shell variables.
The
definitions for these variables are in the file -psl/dist/psl-names. Some of the most
commonly used variables are: 2
$pu

holds sources for many utility routines.

$pvu

holds sources for utilities s'pecific to vax-unix.

$pv

holds sources for those parts of the PSL "kernel" specific to vax-unix.

$pl

holds most PSL "binaries".3 This is one of the default directories searched by
PSL's load function.

$pll

holds "local binaries" and is also searched by the Load function.

Variable substitution in PSL is implemented by having PSL read the file confignames.sl from the PSL root directory and psl-names.sl from the user's home directory.

2These variables are also put in the shell environment via setenv to avoid each of the PSl maintenance scripts sourcing
psi-names everytime they are executed.

3These were once known as LAP files,

t~us

the name "pi" for "PSl LAP" .

PSL under Vax Unix
page 2.4

3 April 1984

PSL Manual
section 2.4

These files contain expressions that give the mapping from variables to their values.
example, the expression:

For

(put 'psI 'pslnames "/v/misc/psl/dist ft )
defines the 'Iipsl" variable for use in PSL.
Rather than have the user create psl-names.sl by hand, PSL automatically creates the
file for the user and writes an appropriate psI-names. s1 file. It reads through the .cshrc
and .cshinit files on the home directory and all files "source'ld by them collecting "set"
statements. The message "creating psl-names.sl, please wait ... " is displayed while the
file is being created. When psI-names .sl is being read at PSL startup time, the write
times of the C-shell source files are checked and if any are newer than psl-names.sl,
then psI-names .s1 is created.
PSL uses the concept of a current "working" directory (or dot) as the shell does. Unix
filenames are treated as paths from the current directory unless they begin with a slash
(in which case they start from the "root'l directory). PSL's working directory is initially the
same as the working directory of the shell when PSL is started.
Following are some PSL functions available on the Vax Unix version of PSL that pertain
to directories.
(cd DIR:string): boolean
Like the shell's "change directory'l ("cd") utility, sets the current working
directory for PSL. Unless cd is executed, the working directory will remain
the same as the working directory of the shell at the time the PSl was
started. Cd returns T if it successfully finds DIR, NIL otherwise.
(pwd ): string
Similar to the shell's "print working directory'l ('Ipwd") utility. Returns the
current directory of the PSL as a string, terminated with a slash so
filenames may be directly concated to it. The trailing slash is ignored by
cd.
(path S:string): string
This is the function used to perform "variable substitution on filenames. It
examines the argument string and if it starts with 11$" or "_11, extracts the
next string up to the "/11 (if any), and converts it to (an upper-case) id.
Then an associated string is looked for on the id's property list under the
indicator PSLNAMES and in the environment via the getenv function.
user names are looked up via getputnam, and the home directory is
substituteed. "- /" is the user's home directory. If an associated string is
not found, an Error is generated. If ~ does not start with "$" or "_", it is
returned unchanged.
ll

PSL Manual
section 2.4

3 April 1984

PSL under Vax Unix
page 2.5

For example, one could type

(cd (path "$pu"»
to change to the PSL utility directory as the working directory. (Note that
the call to path is done automatically in this case.) When VAX-PATH is
loaded (which is the case except in a very "bare" PSL), Open is redefined to
apply Path to the filename. Thus Open, In, Dskin, Out, FileP, etc. can use
"$n variables in file names without calling Path explicitly.

2.5. Sample Session with Vax Unix PSL
The following is a transcript of running PSL under Unix.

PSL under Vax Unix
page 2.6

3 April 1984

1 cs> psI
PSL 3.2, 26-0ct-83

%Notice the numbered prompt.
%Comments begin with n%n and do not change the prompt
%number.
%Make an assignment for Z.
1 Lisp> (Setq Z '(1 2 3»
1 Lisp>
1 Lisp>
1 Lisp>

(1 2 3)

2 Lisp> (Cdr Z)
%Notice the change in prompt number.
(2 3)
3 Lisp> (De Count (L)
%Count counts the number or elements
(Cond «Null L) 0) %in a list L.
3 Lisp>
(T (Add1 (Count (Cdr L»»»
3 Lisp>
COUNT
~ Lisp> (Count Z)
%Call Count on Z.

3

5 Lisp> (Tr Count) %Trace the recursive execution of "Count".
(COUNT)
6 Lisp>
% A calIon "Count" now shows the value of
6 Lisp>
% "Count" and of its arguments each time
6 Lisp> (Count Z)
% it is called.
COUNT being entered
L:
(1 2 3)
COUNT (level 2) being entered
L: (2 3)

COUNT (level 3) being entered
L:
(3)
COUNT (level ~) being entered
L:

NIL

COUNT (level ~) = 0
COUNT (level 3) = 1
COUNT (level 2) = 2
COUNT = 3
3
7 Lisp> (Untr Count)
NIL
8 Lisp> (Count 'A) % This generates an error causing the break
%loop to be entered.
***** An attempt was made to do CDR on 'A', which is not a pair
Break loop
9 Lisp break» ?
BREAK():{Error,return-value}
This is a Read-Eval-Print loop, similar to the top level loop,
except that the following IDs at the top level cause functions to
be called rather than being evaluated:

PSL Manual
section 2.5

PSL Manual
section 2.5

?
T
Q
A

C
R
M

E
I

3

April 1984

PSL under Vax Unix
page 2.7

Print this message, listing active Break IDs
Print stack back trace
Exit break loop back to ErrorSet
Abort to top level, i.e. restart PSL
Return last value to the ContinuableError call
Reevaluate ErrorForm!* and return
Display ErrorForm!* as the "message"
Invoke a simple structure editor on ErrorForm!*
(For more information do Help Editor.)
Show a trace of any interpreted functions

See the manual for details on the Backtrace, and how ErrorForm!* is
set. The Break Loop attempts to use the same TopLoopRead!* etc, as
the calling top loop, just expanding the PromptString!*.
NIL
10 Lisp break»
%Get a Trace-Back of the
10 Lisp break» I
%interpreted functions.
Backtrace, including interpreter functions, from top of stack:
CDR COUNT ADD1 COND COUNT
NIL
11 Lisp break» Q
%To exit the Break Loop.
12 Lisp>
%Load in a file, showing its execution.
12 Lisp>
%The file contains the following:
12 Lisp>
%(Setq X (Cons 'A (Cons 'B Nil»)
12 Lisp>
%(Count X)
12 Lisp>
~ (Reverse X)
12 Lisp> (Dskin "small-file.sl ft )
(A B)
2
(B A)

NIL
13 Lisp> (Quit)
2 cs> jobs
[1] +Stopped

psI

3 cs> %1
"Continued"
lij Lisp> (ExitLisp)
ij cs>
2.6. Init Files for PSL
On starting up, psI will read and execute the file .pslrc on your home directory, if the

file is present. Similarly, rlisp will use the file .rlisprc; pslcomp will use .pslcomprc;
and nmode will use .nmoderc. These files must use Lisp syntax, even the one for RLisp.

PSL under Vax Unix
page 2.8

3 April 1984

PSL Manual
section 2.6

These initialization files are typically used to load modules of personal interest, and to
initialize variables (such as !*BREAK) to suit personal tastes.

2.7. Error and Warning Messages
Many functions detect and signal appropriate errors (see the chapter on error handling
in Part 1 of this manual for details); in many cases, an error message is printed. The
error conditions are given as part of a function's definition in the manual. An error
message is preceded by five stars, *; a warning message is preceded by three. For
example, most primitive functions check the type of their arguments and display an error
message if an argument is incorrect. The type mismatch error mentions the function in
which the error was detected, gives the expected type, and prints the actual value passed.
Sometimes one sees a prompt of the form:
Do you really want to redefine the system function 'Foof?
This means you have tried to define a function with the same name as a function used by
the PSL system. A Y, N, YES, NO, or B response is required. (Note that Y and N don't work
in NMODE.) B starts a break loop. After quitting the break loop, answer Y, N, Yes, or No
to the query. See the definition of YesP in the input/output chapter of this manual. An
affirmative response is extremely dangerous and should be given only if you are a system
expert. Usually this means that your function must be given a different name.
A common warning message is

*** Function "FOO has been redefined
II

If this occurs without the query above, you are probably redefining one of your own
functions. This happens normally if you read a file, edit it, and read it in again.

2.8. Reporting Errors and Misfeatures
Send bug mail to PSL-BUGS@UTAH-20(Arpanet) or utah-cs!psl-bugs(uucp address).
The message will be distributed to a list of users concerned with bugs and maintenance,
and a copy will be kept in SS:BUGS-MISSFEATURES. TXT at UTAH-20.

2.9. Unix Interface
2.9.1. Miscellaneous Unix Functions
(Exi tLisp ): undefined
Since the PSL quit behaves like a .... Z, saving your core image, a separate
function is needed when you really want the PSL to terminate. ExitLisp
does it. (A "'\ from the keyboard has the same effect, assuming you have

3 April 1984

PSL Manual
section 2.9

PSL under Vax Unix
page 2.9

your core-dump limit set low.)
(ExitLispWlthStatus CODE: integer): undefined
Like Exi tLisp but returns an integer status code to Unix, available as
$status in csh. ExitLisp always returns status 0, to signal normal exit.
(GetEnv ENVVARNAME:string): string
Returns value of the specified Unix environment variable as a string, or NIL
if the argument is not a string or the environment variable is not set.
(System UNIXCMD:string): undefined
Starts up a sub-shell and passes the Unix command to it via the Unix
"system" command. The working directory of the command will be the
same as PSL's current working directory.
(FileStatus FileName:string, DoStrings:boolean): Alist
Returns an alist of information about the file, or NIL if the file was not
found. Both the numerical file information and the string interpretation are
given if DoStrings is T. Time and consing can be saved if the interpretations
are not needed by calling with DoStrings NIL. An example of the return
value:
t (

(
(
(
(
(
(
(

Owner • ( "psI" • 39 »
Group • ( "small" • 8 »
Mode. ( tt-rwxr-xr--tt • 81764 »
Size. ( ttll • 123456789 »
WriteTime • ( "Tue Nov 22 13:48:26 1983" • 438382106 »
AccessTime • ( "Tue Nov 22 13:48:26 1983" • 438382106 »
StatusChangeTime •
( ttTue Nov 22 13:48:26 1983" • 438382106 »

)

File size is given in bytes. Numerical times are Unix system time counts in
seconds since 00:00:00 GMT, Jan. 1, 1970, and can be used for file time
comparisons or sorting.

2.9.2. Loading C code into PSL
(oload load-specs: {string, NIL}): boolean

PSl under Vax Unix
page 2.10

3 April 1984

PSL Manual
section 2.9

Oload 4 provides a mechanism for linking Unix ".0" and ".a" files ("object" and "archive"
files) into a running PSL. It was developed to get access to existing C code driver
libraries for graphics devices, but should work for any Unix compiled code with C calling
conventions.
The single argument to oload is a string containing arguments for the Unix "Id" loader,
separated by blanks. File names ending in ".0" are compiled relocatable code files. ".a"
. files are "ar" load libraries, which are assumed to contain a set of ". 0 " files, all of which
are to be loaded. Other loader arguments should follow, specifying whatever libraries are
necessary to satisfy all external references from the ".0" and ".a" files mentioned. Library
specs are in the form "-Ifoo" to search the "libfoo.a'l library on Illb, lusr 111b,
lusr Iloeal/lib, etc., e.g., -Ie for the C library.
Oload performs an lIincremental" (-A flag) load. Symbols which are already known in
the running PSL will be linked to the existing addresses.
If LOAD-SPECS is NIL, an attempt is made to re-Ioad from an existing .oload.out file.
This can only be done if the BPS and WARRAY base addresses are exactly the same as
they were on the previously done, full oload. An error message results if the BPS
locations are different. This is meant to facilitate rapidly repeating an oload at startup
time, and is probably useful only to a PSL system expert.
A customized version of PSL may be saved by the function SaveSystem, after first
performing oloads and loading PSL code which interfaces to the oloaded code.
Oload returns a status code of T if it succeeds, or NIL if not.

2.9.3. Calling oloaded functions
[??? We need to clarify the (rather nontrivial) process by which one can convert code
that uses oload into "kernel" code. ???]
All entry points and global data objects loaded by oload are made known to the PSL
system.
C functions may be called from compiled code only, and are flagged
ForeignFunetion by oload.
Data areas are flagged ForeignData, with a property
containing a pair of the data location and size in bytes for use by SYSLisp interface code.
Foreign function calls may be compiled into Fasl files, in which case the C function
names must be flagged foreign function at compile time in order to get the proper calling
sequence.
The names of oloaded C functions within PSL are the "true" names, which have an
underscore (,1_") prefixed to the C name. This makes it easy to make a compiled "pass
through" interface function which gives the same name within PSL as the C nam-es. For
example, your PSL definition might look like this:

4rhe name "oload" comes from the fact that the function loads object, or ".0", files.

3 April 1984

PSL Manual
section 2.9

PSL under Vax Unix
page 2.11

(de foo ()
(_foo) )
while your C program might read:
foo( )

/

/

{
fflush( stdout );

}
Note that. the C language version of foo must be all lower case, and does not start with
an underscore (the underscore is added by the C compiler).
Functions which take integer arguments can be called directly, due to the "invisible
tagging" of integers with up to 27 bits in the Vax implementation of PSL. 5 Similarly,
integer return values will be passed back from the C functions. String or structured
arguments will require a bit of conversion code in the interface functions, requiring
removal of tags when passing arguments to C functions, and adding them to return
values.
For returning strings from C functions, we have provided the function
ImportForeignString.
(ImportForeignstring C_STRING:word): string
Constructs and returns a PSL string, given a C string (something of type
"pointer to character"). A NULL (Le. 0) string pointer is returned as NIL.
Note that, currently, foreign function calls may have no more than five arguments and
that no support is provided for floating point and struct values. We hope to eventually
remedy this problem.. These restrictions may be circumvented by putting arguments in
work areas and passing the address of the work area as an argument to an intermediate
C "kludge function" which unpacks the real arguments and passes them on to the target
C function.
If work areas are needed in SYSLisp interface code, as when arrays must be passed to
the C code, use a LispVar to hold the address of a word block acquired via GtWArray (for
static arrays) or GtWrds (for dynamic blocks in the heap). Pass the array address to the C
function as the pointer argument. (The LispVar function is used to access PSL "FLUID"
variables in the symbol table from SYSLisp code.)

2.9.4. Oload Internals
Oload invokes the Unix "Id" loader through a C-shell script to convert the relocatable
code in .0 files into absolute form, then reads the absolute form into space allocated
within the BPS area of PSL. The text segment goes at the low end of BPS, and the data

5Working with integers larger than this will require more care on the part of the programmer.

3 April 1984

PSL under Vax Unix
page 2.12

PSL Manual
section 2.9

and bss segments go at the high end, following the BPS storage allocation conventions of
the PSL compiler.
Since an incremental (-A) load is done, oload needs a filename path to the executable
file containing the loader symbol table of the previous load.
The variable
SymbolFileName* tells both oload and the SaveSystem and DumpLisp functions the
filename string to use. (Since oload reads the executable file, it should be publicly
readable.)
When PSL is started, SymbolFileName* is automatically set to the name of the executed
PSL file. This is done by importing the Unix argument string to variable UnixArgs*.
UnixArgs* is a vector, and its zeroth entry is the (possibly partial) path to the PSL file
which was executed. The Unix environment variable PATH contains a set of path prefixes
to which partial paths are appended, until a valid filename results. "." refers to the path
to the current directory, which is returned by the pwd function. (Unix system interface
functions are contained in file $pv/system-extras.red.)
SymbolfileName* is set to .oload.out" by oload, so that successive loads will
accumulate a loader symbol table, and so that the C function "unexec", called by
DumpSystem, will get the right symbol table in the saved PSL. (It may be useful to know
that the initial value of SymbolFileName* is saved in StartupName*.)
II

A number of work files are created on the current directory by the oload script, with file
names that begin ".oload". In particular, the .oload .out file is quite large because it
spans the gap of unused space in BPS. It is a good idea to remove those files if you do
not intend to repeat the load exactly.

2.9.5. 1/0 Control Functions
(EchoOff ): undefined
EchoOff enters raw, character-at-a-time input mode for Emode, Nmode,
and similar keystroke oriented environments.
(EchoOn ): undefined
EchoOn is used to return to normal, line oriented, input mode after calling
EchoOff.
The names' EchoOff and EchoOn are not exactly appropriate. In addition to turning off
echoing, EchoOff also turns off processing of output characters. For example, on some
systems a linefeed character will normally be printed as a carriage return/linefeed pair.
EchoOff turns off this processing, so that it will print as just a linefeed. EchoOff may
also turn off the "special" meaning of some input characters. For example, typing the
control-C character serves to interrupt the execution of a program, but the Unix version
of EchoOff turns this off~

PSL Manual
section 2.9

3 April 1984

PSL under Vax Unix
page 2.13

(CharsInInputBuffer ): integer
Returns the number of characters waiting for input from the nY, including
those still in the Stdio buffer and those not yet read from Unix.

(PauseFor Input n60ths): undefined
PauseForInput pauses until either the time limit given by N60THS (in 60ths
of a second) is exceeded, or until input is available from the standard input,
whichever comes first. PauseFor Input is only meant to be used after
calling EchoOff, otherwise it may not work correctly.
(FlushStdOutputBuffer ): None Returned
The standard output from PSL is in Stdio line-buffered mode, and is
normally flushed to the TTY whenever an end-of-line is printed or before
waiting for input.
In screen-oriented output environments like
Emode/Nmode which use screen cursor positioning, it is necessary to
explicitly flush the buffer at appropriate times.
(ChannelFlush Chnl: io-channel): None Returned
Flushes any channel, as FlushStdOutputBuffer does for StdOut*.

PSL MANUAL
SECTION 3.0

5 DECEMBER 1983

PSL ON THE APOLLO
PAGE 3.1

CHAPTER 3
PSL ON THE APOLLO
3.1. Purpose of This Chapter. .
,3.2 .. Setting up Logical Names .
3.3. File Structure on the Apollo
3.4. Sample Session with Apollo PSL .
3.5. Init Files . . . . . . . . . . . .
3.6. Error and Warning Messages. . .
3.7. Reporting Errors and Misfeatures.
3.8. Aegis System Interface . . . .
3.8.1. Introduction . . . . . . .
3.8.2. How the Package Works. .
3.8.3. Handling Simple Arguments
3.8.4. More Complicated Data Types
3.8.5. Some Real Examples . .
3.8.6. System Interface Package
3.8.7. Demonstration Program
3.9. Dumplisp Utility. . . . . .
3.9.1. Using DumpLisp. . . .
3.9.2. Using. Saved Images . .
3.9.3. Other DumpLisp Details

3.1
3.1
3.2
3.3
3.5
3.6
3.6
3.6
3.6
3.7
3.7
3.8
3.10
3.13
3.13
3.14
3.14
3.15
3.16

3.1. Purpose of This Chapter
This chapter is for beginning users of PSL on the Apollo. It begins with descriptions of
how to set up various logical device definitions required by PSL and how to run PSl. The
chapter continues with a description of the file structure associated with PSL, an example
of use of the PSL system, and miscellaneous hints and reminders. The next section
contains a discussion of interfacing to the Aegis operating system.
The chapter
concludes with a description of the DumpLisp utility.

3.2. Setting up Logical Names
The Apollo version of PSL uses a link in the current naming directory to reference files
it needs while running. This link is called" -- p" and should have a link text poi~ting to the
psi_links subdirectory of the root PSL directory.
For example, if the PSL system was installed in the directory "/lisp", then the " ...... p" link
would be created with

$ crl -p /lisp/psl_links -r
.' This link MUST exist· for PSL to run, since PSL,uses it to resolve the location of the init
files.

PSL on the Apollo
page 3.2

5 December 1983

PSL Manual
section 3.2

With the link in place,

$ -p\psi
starts up the:PSLexecutable.
the psi executable, Le.:

It maybe .. desirableto addaJink in your -com directory to

$ cri -com/psI -p\psi
or to add the directory "- p\" to your command search path.
This executable does not contain any optional loadable modules. They can be loaded as
options. Optional modules can be loaded by executing

(LOAD modulename)
The global variable OPTIONS!* contains a . list ,-of modules currently loaded; it does not
mention those in the "bare-psi" kernel.
If more complete versions of the system
.SaveSystem (see Section 3.9).

are desired, they can be created with

3.3. File Structure on the Apollo
When PSL is installed, a system of link files is used to access the various directories.
-These are generally easier to type and also provide a system independent method for PSL
to locate its system files. They are accessed with a link called" - p" on the user's naming
directory. The links referencing the files are indicated by [- p/xxxx] below.
binfiles/?*

Directory containing binary files to rebuild kernel and each module's init
files[ - p/bin]

comp/?*

Directory containing general compiler sources[ - pic]

comp/apollol?*
Apollo-specific compiler sources [ ...... p/ac]
demol?*

Directory containing demo programs {note they depend on all_ syscalls, some
may require L_lnitplot to be called before starting).[ ...... p/demo] .

docl?*

Documentation directory; Pascal_compat.txt describes some of the more useful
functions in all_syscalls. [- p/d]

help/?*

Help files for use with the help utility [-- p/h]

Ipt/?~'t

Machine readable copy of the manual, suitable for printing on a line printer.

"-f-- p/lpt]

5 December 1983

PSL Manual
section 3.3
kernel/?*

PSL on the Apollo
page 3.3

Directory for sources to the kernel. [-- p/k]

kernellapollol?*
Contains subdirectory with Apollo specific sources. [- p/ak]
·.tests/?*Directory,containing--general PSL timing tests. [--pit]

test/apollol?*
Subdirectory contains specific files for the apollo version. [-- plat]
lap/?*

Directory for PSL loadable binaries (for use with "load" function) [- pill

supportl?*t Directory containing Apollo system specific sources (e.g., syscall packages)
[-- p/sup]
uti II? *

Directory containing general PSL utilities sources [-.. p/u]

psl.map

Binder Mapfile of the PSL kernel (used for debugging) .

• psl.init' ~'INIT file required for PSL system startup (loads -each of the init files from the
-- p/bin directory. To make startup faster, you may want to concatenate all of
the init files together into one file, saving the overhead of opening 17 files).
psi

Executable file.

psl-intro

A small file to -point users at PSL documentation, and how to start PSL. It
should be edited for local use.

psl_links/?* Directory containing abbreviated names for access to the various PSL
directories. Its contents should be rebuilt with the psi_names script before
the system is used.
psi_names Command script for creating -- pl ... directories.

3.4. Sample Session with Apollo PSL
The following is a transcript of running PSL on the Apollo.

on the Apollo
page 3.4

PSL

5

December

1983

$ -p\psl

PSL 3.2, 11-Dec-83
1 Lisp> %Notice the numbered prompt.
1 .Lisp> %. Comments·begin with "%" and. do.not··change the prompt
Lisp> %·number.
1 Lisp> (Setq Z '(1 23»
% Make an assignment for Z.
(1 2 3)
2 Lisp> (Cdr Z)
% Notice the change in prompt number.
(2 3)
%. Count counts the number or elements
3 Lisp> (De Count (L)
3 Lisp>
(Cond «Null L) 0) % in a list L.
3 Lisp>
(T (Add1 (Count (Cdr L»»»
COUNT
4 Lisp> (Count Z)
% Call Count on Z.
3
5 Lisp~ (Tr Count) % Trace the recursive execution of "Count".
(COUNT)
6 Lisp>
%A callan "Count" now shows the value of
6 Lisp>
%"Count" and of its arguments each time
6 Lisp> (Count Z)
%it is called.
COUNT being entered
L:

(1 2 3)COUNT (level 2) being entered
L: (2 3)

COUNT (level 3) being entered
L:

(3)

COUNT (level 4) being entered
L:
NIL
COUNT (level 4) = 0
COUNT (level 3) =
COUNT (level 2) = 2
COUNT = 3
3
7 Lisp> (Untr Count)
NIL
8 Lisp> (Count 'A) %This generates an error causing the break
%loop to be entered.
***** An attempt was made to do CDR on 'A', which is not a pair
Break loop
9 Lisp break» ?
BREAK():{Error,return-value}
This is a Read-Eval-Print loop, similar to the top level loop,
except thatthe.following IDs at the top.level cause functions to
be called rather than being evaluated:

Manual
section 3.4

PSL

PSL Manual
section 3.4

?
T
Q
A
. C.
R
M
E
I

. 5 December

1983

PSL on the Apollo
page 3.5

Print this message, listing active Break IDs
Print stack backtrace
Exit break loop back to ErrorSet
Abort to top level, i.e. restart PSL
""Return last·,valueto the·ContinuableError call
. Reevaluate ErrorForm!* and return
Display ErrorForm!* as the "message"
Invoke a simple structure editor on ErrorForm!*
(For more information do Help Editor.)
Show a trace of any interpreted functions

See the manual for details on the Backtrace, and how ErrorForm!* is
set. The Break Loop attempts to use the same TopLoopRead!* etc, as
the calling top loop, just expanding the PromptString!*.
NIL
10 Lisp break»
%Get a Trace-Back of the
10 Lisp break» I
%interpreted functions.
Backtrace, including interpreter functions, from top of-stack:
CDR COUNT ADD1 COND COUNT
NIL
11 Lisp break» Q
%To exit the Break Loop.
12 Lisp>
%Load in a file, showing its execution.
12 Lisp>
%The file contains the following:
12 Lisp>
% (Setq X (Cons fA (Cons 'B Nil»)
12 Lisp>
% (Count X)
12 Lisp>
% (Reverse X)
12 Lisp> (Dskin "small-file.sl")
(A B)

2
(B A)

NIL
13 Lisp> (Quit)
$

3.5. Init Files
Init files are available to make it easier for the user to customize PSL to his/her own
needs. When . . . p\psl is executed, if a file -- user_data/psi exists, it will be read by psLinit
after the other init files are read. Currently all init files must be written in Lisp syntax.
They may use Faslin or Load as needed. More details on init files are available in Part 1
of this manual.

·1

5 December 1983

PSL on the Apollo
page 3.6

3.6. Error and

~arning

PSL Manual
section 3.6

Messages

Many functions. detect and signal appropriate errors (see the chapter on error handling
in Part 1 of this manual for details); in many cases, an error message is printed. The
-error-conditions .. are giv.en: as::-partof . a: Junction's definition in the manual. An error
me'Ssage is'-preceded by five'" stars"'(*); a warning- message is prece.ded by three. For
example, most primitive functions check the type of their arguments and display an error
message if an argument is incorrect. The type mismatch error mentions the function in
which the error was detected, gives the expected type, and prints the actual value passed.
Sometimes one sees a prompt of the form:

Do you really want to redefine the system function 'FOO'?
This means you have tried to define a function with the same name as a function used by
the PSL system. A Y, N, YES, NO, or B response is required. B starts a break loop. After
quitting the break loop, answer Y, N, Yes, or No to the query. See the definition of YesP
in the inputloutput· chapter of this manual.
An affirmative response IS extremely
dangerous and should be given only if you are a system expert. Usually this means that
your function must be given a different name.
''0

A common warning message is
*** Function "FOO" has been redefined
If this occurs without the query above, you are redefining your own function.
happens normally if you read a file, edit it, and read it in again .

This

.'·3.7. Reporting Errors and Misfeatures
Send bug MAIL to PSL-BUGS@UTAH-20 (Arpanet) or utah-cs!psl-bugs (uucp).
The
message will be distributed to a list of users concerned with bugs and maintenance, and
a copy will be kept in BUGS-MISSFEATURES.TXT at UTAH-20.

3.8. Aegis System Interface
3.8.1. Introduction
The Aegis operating system provides a wide variety of user-callable routines for system
services such as graphics, file manipulation, pad and window usage, etc. A package
called SvsCalis has been developed to allow Apollo PSL to interactively use these
routines. This package allows virtually any procedure documented in the Apollo System
Programmer's guide to be called from PSL without requiring modifications to the PSL
system.
In addition to calling. existing Aegis routines, user written libraries can also be used by
loading them with the shell command INUB before executing PSL. The only restriction on

5 December 1983

PSL Manual
section 3.8

PSL on the Apollo
page 3.7

user-libraries is they must use call by reference parameters instead of call by value.

3.8.2. How the Package Works
Aegis -stores a symbol-table for· all globally accessible routines. The undocumented
system function KG_ $LOOKUP( SYMBOLNAME) returns the address of the routine specified
in the string SYMBOLNAME. To maintain Fortran compatibility, all Aegis routines are call
by reference, that is, the parameters passed to the routines are pointers to the actual
data elements pushed onto the stack before calling the routine. The sources for the
syscall package reside in -- p/sup/syscalls.red.
The syscall package reserves an area of storage called the CALLADDRESSBLOCK. This is
where the parameters (pointers to Pascal data objects) are stored when setting up the
SysCali. When the call is executed, the elements (32 bit pointers) are pushed sequentially
onto the stack. For immediate data values (Le., 16 and 32 bit integers) a space in memory
is reserved called the CallArgumentBlock which is used as a place to put these
- parameters- so that there is a memory address for them which can be used for the call by
reference. The following functions call Aegis routines, automatically store the desired
values into the CaliArgumentBlock and create the proper pointers in the CaliAddressBlock.

(SysCall RoutineName: ID, ArgCount: Integer): any
Once the argument block is correctly loaded, SysCal1 executes the call.
The ROUTINENAME is the name of the Pascal system routine. A value is
returned by Pascal if the routine is declared as a Pascal FUNCTION instead
of a PROCEDURE. Some examples:
SysCall('GPR_!$SET_ATTRIBUTE_BLOCK,2);
AtrDescptr:=SysCall('GPR_!$ATTRIBUTE_BLOCK,2);

%call to Pascal
% procedure
%call to Pascal
%

function

3.8.3. Handling Simple Arguments
Interface to the SysCalis package is generally through three routines:
and ClearArg.

PutArg, GetArg,

(PutArg ArgNum: integer, LispArg: any, PasType: IDlist): NIL
PutArg places incoming Lisp arguments into the argument block (Incoming
arguments are those declared as "IN" within the Pascal definition). ARGNUM
is the Pascal input argument number, determined by counting from left to
right in the Pascal definition, with the first argument being 1. L1SPARG is
. the input"parameter declaredin-the"·Lisp function definition. PASTYPE is the
data type the Lisp parameter should be converted to. Currently supported

PSL on the Apollo
page 3.8

5 December 1983

PSL Manual
section 3.8

are (Integer16), (Integer32) and (String). Some examples:

PutArg(1, StreamID, '(Integer16»;
- PutArg(2, BufferPointer, '(Integer32»;
PutArg(4, FileName, '(String»;
(ClearArg ArgNumber: Integer): NIL
Before the SysCall procedure can be called, any arguments returned by the
system procedure (declared as "OUT" in the Pascal definition) must be
cleared with ClearArg so space is properly reserved. ARGNUMBER is the
Pascal argument, as above. Note this routine should always be called to
clear the returned status (Status _$t) from a system routine.
(GetArg ArgNumber: Integer, PasType:IDlist, LispType: IDlist): Any
GetArg is used for retrieving returned values from the Pascal procedure.
(Note values returned from a Pascal FUNCTION are handled with the SysCall
function,
above).
After
the
SysCall
. has
completed,
the
CALLADDRESSBLOCK contains the addresses of the actual data items. To
get these values back to Lisp, a scalar (local) variable is usually declared to
receive the value from GetArg. ARGNUMBER and PASTYPE paramaters are
used as described in PutArg, above. The L1SPTYPE is a corresponding Lisp
variable type, which can be (String), (Inurn) [integers of 16 bits or less, e.g.
16 bit Pascal quantities], or (FixN) [integers of > 16 bits, e.g., pointers or
Status words].
Some examples: (all destinations declared Scalar)
Status:=GetArg(5, '(Integer32), '(FixN»;
%32 bit Aegis status word
Font_ID:=GetArg(2, '(Integer16), '(Inum»;
% 16 bit Pascal integer
FileName:=GetArg(2, cons('STRING,Length), '(String»;
% Note Pascal string is built from length
% the string type

3.8.4. More Complicated Data Types
When the cjatatype to be: passed or .~received ··from.:the SysCali. package is more
. complicated. than a simple integer or string, the Lisp program making the call is expected
to handle the data allocation and storage.

PSL Manual
section 3.8

5 December 1983

PSL on the Apollo
page 3.9

(PutObjPointer ArgNumber: integer LispPointer: FixN): None
PutObjPointer loads the
< Lisp Pointer> to the object
corresponding argument slot in CaliAddressBlock.
This should
before--invoking- SysCallO, ,'. -even-~'-Jor: OUTgoing =-arguments. ' - For
-'suppose we-wish to pass a list to -a Pascal routine requiring
declared with:

into the
be done
_example,
a record

type Position t = record
Xpos, Ypos: integer;
end;
From the Apollo Pascal Programmer's guide, we discover this record is
stored as two 16 bit integers stored into a single fullword.
Thus, the
resulting Lisp code would be (assuming LispPos is a list):

begin scalar PosWord;
-PosWord:=GtWrds(1);

%allocate one 32 bit worda:hd have PosWord
%point to it.
PutHalfword(PosWord, 0, First LispPos); %Place the first arg in
%the first 16 bits of the
%fullword.

PutHalfword(PosWord, 1, Second LispPos);
%Note the second argument
%denotes the location in the
%array returned by GtWrds.
PutObjPointer(2, PosWord);
%Now put the pointer into
%the call address block as
%the second argument.
SysCall('THE_!$ROUTINE_NAME,3);

% Call routine, with three

%args in this case.
In cases where the routine returns a complicated argument, the allocation
and call to PutObjPointer must still happen before the actual routine is
invoked. For example (Using the same data types as above):

PSL on the Apollo
page 3.10

5 December 1983

begin Scalar PosWord;
PosWord:=GtWrds(1);
PutObjPointer(1, PosWord);
SysCall( 'THE__ !$ROUTINE,J);

PSL Manual
section 3.8

%Allocate space for it.
%Place the address of the array into
%the CallAddressBlock as argument
. % Call Aegis routine
% (three args specified) •

return GetHalfWord(PosWord,O) • GetHalfWord(PosWord,1);
%Return the arguments as a lisp
%dotted pair. Note that GetArg was
%NOT called; Pascal used the address
%we specified in PutObjPointer.
3.8.5. Some Real Examples

These are some examples taken from the GPR (Graphics Primitives Library):

PSL Manual
section 3.8

5 December 1983

PSL

on

the Apollo
page 3.11

%

%GPR_Inq_Coordinate_Origin- returns the value of the current bitmap's
%origin as a lisp dotted pair, i.e. (orgX • orgY).
%
.... -SysCall PROCEDURE gpr _inq~coor-dinate~origin ();
begin scalar origin,
% the coordinate origin
status;
%returned Aegis status word.
Origin:=GtWrds(1);
PutObjPointer(1, Origin);
ClearArg(2);

%Allocate space for returned value.
%Place pointer in CallAddressBlock as first
%arg.
%Clear the second arg (the returned status)
%Make the call

Status:=GetArg(2, '(Integer32), '(FixN»;
%get the status back •••
if Status eq 0
- % and check to see if it's ok( =0).then «
%if it is, return the valid args.
Origin:=GetHalfword(Origin, 0) • GetHalfword(Origin, 1);
%Reform the Origin(as a pointer to a fullword)
%into a Lisp dotted pair.
return Origin;
%and return it.
» else Return ApolloError(Status);
%else, return trouble.
%Note: ApolloError is defined in the module
%ApolloCalls.b, it calls Error_SPrint() to get
%a textual description of what went wrong.
end;

PSL on the
page 3.12

Apollo

5 December 1983

PSL Manual
section 3.8

% GPR_LOAD_FONT_FILE loads a font contained in a file into an appro% priate area (based on the current display mode and configuration).
%
SysCall PROCEDURE

gpr~load_font_file

pn,
pnlen);
begin scalar

font_id,
status;

(

%pathname of file
%pathname length

%returned font id
%returned status

PutArg(1,PN,
'(STRING»;
PutArg(2,PNlen, '(Integer16»;
ClearArg(3);
ClearArg(4);

%Pass args into Argument block.
%Set up slots for returned args.

Status:=GetArg(4, '(Integer32), '(FixN»;
if status eq 0
%Check the status
then «
Font_ID:=GetArg(3, '(Integer16), '(Inum»;% If OK, return the Font ID
return Font_ID;
» else Return ApolloError(Status);
end;

% GPR LINE draws a line from the CP to the given position
%

and sets the CP to the given position.

SysCal1 PROCEDURE

gpr_Iine (x,y);

begin scalar status;
PutArg(1,x,'(Integer16»;
PutArg(2,y,'(Integer16»;
ClearArg(3) ;

%returned status
% Place args in parameter block

%Clear way for status.

SysCall('GPR_!$LINE,3);
Status:=GetArg(3, '(Integer32), '(FixN»;
if Status eq 0 then return Status
%Function returns 0 (status ok)
% if all goes well.
else return ApolloError(Status);
end;

5 December 1983

PSL Manual
section 3.8

PSL on the Apollo
page 3.13

Note how the status is handled; in Aegis calls it is usually returned as the last
argument. Most of the time it is handled as above (Returned with ApolloError if there
was an error) but in special cases (e.g., the MBX, STREAM, and SMD calls) the program
may need to take specific action on certain status values.
See the Apollo System
.. Programmerl.s Guide·for··moreinformation.

3.8.6. System Interface Package
Many of the more frequently used Aegis calls have already been defined in files called
CAL_SYSCALLS, MBX_SYSCALLS, PAD _SYSCALLS, etc., corresponding to the respective
packages defined for Pascal or Fortran in Isys/ins/.... These files are designed to 'look'
like the Pascal include files, with the argument passing methods changed to Lisp
conventions (like the examples in the previous section). In addition to these packages,
there is a package defined in - p/sup/Pascal_compat.red containing a number of
definitions using the syscall package for Pascal routines built into the kernel in earlier
releases. It also contains a number of routines for making life in Lisp easier; for example,
the. function L _ Invoke_Shell () invokes a shell underneath PSL. By typing "Z, control
can be returned back to PSL.
Generally these functions are accessed by doing:

(Load AIl_Syscalls)
This loads the actual syscall package along with a collection of the most commonly used
XXX_Syscalls packages and Pascal_Compat. Details on the contents of the Pascal_Compat
package can be found in - p/d/Pascal_Compat.txt, and the files contained in AII_ syscalls
can be determined by looking in - p/sup/AII_ Syscalls.build. Consult the sources to the
xxx _Syscalls packages found in - p/sup/xxx _Syscalls.red for the exact calling sequences of
the individual routines. Also note the implementations of the XXX _syscalls packages are
not guaranteed to be complete or accurate; in many cases routines were implemented as
they. were needed.

3.8.7. Demonstration Program
On the directory - p/demo there is a small demonstration programing showing how the
graphics primitives (GPR) can be used with PSL. To run the program, first enter PSL, then
give the commands:

.1

PSL on the Apollo
page 3.14

5 December 1983

(load all syscalls)

%load

the rlisp parser

PSL Manual
section 3.8

& syscall

routines

(Faslin n-p/demo/pattern.b n ) %load the demo program.
JL_InitPlot)
-- % initialize the graphics routines.Note
%-the'windowisnow broken into three
% sections, Lisp Input, Lisp Output,
% and a graphics frame.
(SQpat)
% run the demo program. Note you may
% have to scroll the graphics window
% to see the entire result
(L_erase)
%Erase the graphics •••
(L_EndPlot)
% Closes the graphics frame and returns
% to two window mode.

3.9. Dumplisp Utility
A utility for saving a running Lisp environment called DumpLisp is distributed with this
release.
(DumpLisp Filename:String): None
DumpLisp works by copying the running PSL image (including the active
HEAP and BPS space) into a mapped object and then un-mapping it. When
a PSL saved image is started again, it copies the saved image into your
current working directory and maps this into your address space. FILENAME
is the name used in the first part of the output files, as described below.

3.9.1. Using DumpLisp
The first step is to load the DumpLisp module along with any other modules you wish
to have in the saved system:
(load DumpLisp Rlisp Compiler AII_Syscalls)
Then execute the
example:

DumpLisp procedure, giving the filename with no extension, for

(DumpLisp "/tmp/pslsave")
The above creates two files, the mapped image Itmp/pslsave.sav, and another file
containing _. -information about the image (such as the re-entry address) called
Itmp/pslsave.mif (MIF stands for Map Information File). Note when DumpLisp completes
you are still in PSL,and further changes won't appear in the saved image since the object
has already -.been --mapped out; Note also -DumpLispfails ifthe.savfile already exists.
In addition to DumpLisp, the PSL system conta-ins a function called SaveSystem allowing

5 December 1983

PSL Manual
section 3.9

PSL on. the Apollo
page 3.15

specific initialization code to be executed when a saved image is started.
the PSL manual for more details .

See Part 1 of

.

..···.3.9.2. Using Saved Images
[??? A transcript of saved PSL image use is badly needed here ???]
To run a saved image, use the program run_image, stored in -- p\.
It takes one
argument, the name of the file the PSL system was saved under (again, without
extension). For example, to run the above image:
-p\run_image Itmp/pslsave
This copies the saved image ("/tmp/pslsave.sav" in this case) to a file in your working
directory with a .cor extension (e.g., "pslsave.cor"). It then maps in the .COR file and
executes it. Note the saved image always starts up in Lisp mode, even if it was saved
while running RLisp. RLisp can be re-entered by typing
(rlisp)
as usual. If it is desired for the saved image to come up in RLisp, use the SaveSystem
function to write out the image (see the PSL manual for more details).
If the saved PSL system is exited by giving it an EOF (" Z on most systems), the PSL
image is unmapped, and the .COR file is deleted. NOTE- if you change the working
directory of the process while a saved PSL is running, it won't be able to find the .COR
file when it exits. This is usually not desirable, since .COR files generally take up a lot of
disk space. If the PSL image is exited by the QuitO function, a quit fault (" Q on most
systems) or a fatal error, it is not unmapped but instead is still in the address space.
Executing the Aegis command las prints out a listing of the current address space and
will indicate (usually towards the end of the listing) if the PSL image is mapped in.
In this case, it can be re-entered without mapping it back in by executing the program
- p\restart. Restart, like run_image, takes one argument, the PSL saved image name.
For example, if the above image was exited with a "Q (quit fault) or a call to Qui t,
-p\restart Itmp/pslsave
would re-enter the image. Again, like run_image, PSL comes back in Lisp mode even if it
was running RLisp. Restart is useful when PSL dies with a fatal error or when a runaway PSL program must be stopped with "Q. Again like run;,;.,image, restart un-maps the
image if PSL is exited. with an end of file (" Z). Restart aborts with
reference to illegal address (from

as I

MST manager)

if it is executed without a PSLimage already in the address space.

PSL on the Apollo
page 3.16

5 December 1983

PSL Manual
section 3.9

If enough memory is not available at the address the image needs to reside at,
run_image aborts with the error

···no ·space available (from OS / MST.manager)
This error also occurs if run_image is used when a PSL image is already in the address
space (use restart instead).

3.9.3. Other DumpLisp Details
When a PSL system is saved with DumpLisp, it is stored starting at a specific address.
The image must be loaded into exactly that same address to work correctly.
On a
specific node, this is normally not a problem. But if the saved image is moved to another
node (particularly one with a different hardware configuration, e.g., a PEB board is
installed) it is possible the previously saved address may not be available when you try to
load it in again.
Another important consideration is that saved PSL images usually do not work across
different releases of the Aegis operating system. This is because when a normal Aegis
applications program is executed, the addresses of system functions (e.g., I/O calls) are
resolved at load time. Thus, dumped versions of PSL have already had their address
resolved and will not be changed upon start with run-image. When a new version of
Aegis is installed the addresses of these system functions will probably change and
become incompatible with the ones stored in the saved image. It is also possible the
availability of the image's load address may change with different releases (or
configurations) of the Aegis operating system. Thus, saved PSL images should not be
u.sed for long-term storage of application systems.
If for some reason it is not possible to exit the PSL image using /\ Z and you need to
free up the address space, the unmap command removes the image from the address
space.
As above, unmap takes one argument, the saved PSL image name with no
extension, e.g.:

-p\unmap Itmp/pslsave
Alternatively, closing the shell the image was executed in also unmaps the image.

PSL MANUAL
SECTION 4.0

6 DECEMBER 1983

CONCEPT INDEX
PAGE 4.1

CHAPTER 4
INDEX OF CONCEPTS
The following is an alphabetical list of concepts, with the page on which they are
discussed.

Aegis Interface . . • . • • • •

3.13

Aegis System Interface. . .

3.6

Apollo PSl Sample Session.

3.3

Apollo . • . • . . . . . • . . .

3.1

Bugs •.

1.7, 2.B, 3.6

C programming language

2.9

Core Images . . . . . • .

3.14

DecSystem-20 PSl Sample Session.

1.4

Dumplisp . • . . .

3.14

Error Messages .

1.7, 2.B, 3.6

Errors ••.

1.7, 2.B. 3.6

Examples . . . . .

1.4, 2.5, 3.3

File Manipulation Functions.

1. 11

File Structure on the Apollo. • • • •

3.2

File Structure on the DecSystem-20

1.3

Fork Manipulation Functions

1.10

Function Redefinition. • • . • • . . . • •

1.7. 2.B. 3.6

I/O Control Functions in PSl on Unix.

2.12

Init Files . . . . . . . . • . . . .

1.6. 3.5

Initialization files for Unix PSl. • . . • • .

2.7

Jsys Interface .

1.12

links . . . . . . . . . . • .

3.1

loading C code into PSl '.

2.9

loading Modules. • . . . .

1.2

Logical Device Names for DecSystem-20 PSl.

1.1

Logical Names . . • . . . . . . . . . . . . . . . . •

3.1

Messages.

1.7. 2.B. 3.6

Modules.

1.2, 2.2, 3.2

Oload ..

2.9

Optional Modules.

1.2, 2.2. 3.2

PSl Executables.

1. 1. 1.2, 2.2

Reporting Bugs. .

1.7, 2.B, 3.6

System interface.

2.1,3.1

Concept Index
page 4.2

6 December 1983

Tops-20 Interface • . • . . •

1.8

Unix File Structure in PSl . •

2.3

Unix functions • • • •

2.8

Unix ••• - •• -••••.•..•.•.•

2.1

- User ·level· Interface • , • •

Using Saved Images on the Apollo

1.8
3.15

Vax Unix PSl Sample Session.

2.5

Vax • • • • • . . . •

2.1

Warning Messages.

1.7. 2.8. 3.6

PSL Manual
section 4.0

PSL MANUAL
SECTION 5.0

6 DECEMBER 1983

FUNCTION INDEX
PAGE 5.1

CHAPTER 5
INDEX OF FUNCTIONS
The following is an alphabetical list of the PSL functions, with the page on which they
are defined.

Bits ••

macro

1.14

Bug.

expr

1.7

2.4

· .......

· expr

ChannelFlush • • • •

expr

2.12

CharslnlnputButfer •

• expr

2.12

ClearArg

· expr

3.8

ClockTime.

· expr

Cd .•

1.12

Cmds ..

fexpr

1.8

ConcatS.

expr

1.8

OoCmds .•

expr

1.8

OumpLisp •

expr

3.14

EchoOff ••

• • expr

2.12

EchoOn •

expr

2.12

Emacs •.

expr

1.9

·.

expr

1.9

ExitLisp.

expr

2.8

· . ........

expr

1. 11

FlushStdOutputButfer.

· expr

2.12

Exec

FileP

GetArg .•

• . expr

3.8

GetCOir.

· expr

1.12

GetEnv .

• expr

2.9

GetFork •.

· expr

1.10

• ••• expr

1.12

GetNewJtn.

· expr

1. 11

GetOldJfn.

• expr

1. 11

GetRescan

· expr

1.10

GetUName

· expr

1. 11

GtJfn • . .

· expr

1. 11

HelpDir •.

expr

1.9

HighHalfWord.

expr

1.14

GetloadAverage .

ImportF oreignString

· expr

2. J 1

InFile

• fexpr

1.12

Int2Str

· expr

1.13

JBits

· expr

1.14

JConv ••

· expr

1.13

JsysO.

· expr

1.13

Jsysl •

· expr

1.13

Jsys2.

· expr

1.13

Jsys3 ••

· expr

1.13

Function Index
page 5.2

6 December 1983

PSL Manual
section 5.0

Jsys4. • • • • • • • • • • • • • • . • • . . • . . . • • expr

1• 13

Kill Fork •

• • • . • • . • . . . . . . • • • . . . • expr

1.10

lowHalfWord. • • . . •• • • • • .• . • ••• • • • .expr

1. 14

MM . . . . . . . • . . . . . • • . . • • . • . . . . . . expr

1.9

NameFromJfn • • . . • . • . • • . . • • • . . . . • • . expr

1.11

2.9

Oload . . . •

expr

Open Fork . .

expr

1.10

OpenNewJfn

expr

1.11

OpenOldJfn .

• expr

1.11

Path • . . . . •

expr

2.4

PauseF or Input. •

expr

2.12

PutArg . . . •

expr

3.7

PutObjPointer.

• expr

3.9

PutRescan.

expr

Pwd • . . . . .

. ••• expr

1.10
2.4

RecopyStringToNUll.

• expr

1.14

RelJfn.

· expr

1.11

Reset .••

expr

1.10

Run • . .

expr

1.9

RunFork ••

expr

1.10

StartFork.

expr

1.10

Str21nt

expr

1.13

Swap ..

• expr

1.14

Sys • . .

expr

SysCall .

expr

System.

• •• expr

1.9
3.7
2.9

Take ••

expr

1.9

Type

expr

1.9

. . • • . • . • . . . . . . . . . . . . . . . expr

1.8

VDir •

WaitFork . . . . • . . • • . • . . . • . . . . . . • . • expr

1.10

XJsysO

• expr

1.12

XJsysl

• expr

1.12

XJsys2

expr

1.12

XJsys3

expr

1.12

XJsys4

expr

1.13

Xword

expr

1.14

PSL MANUAL
SECTION 6.0

6 DECEMBER 1983

GLOBAL INDEX
PAGE 6.1

CHAPTER 6
INDEX OF GLOBALS AND SWITCHES
The following is an alphabetical list of the PSL global variables, with the page on which
they are defined.

CRlF . . . . . . • . . . . • . . . . . . • • • . . . . . global

1.8

--

---------------------------------------------


Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.7
Linearized                      : Yes
Author                          : Utah Symbolic Computation Group
Create Date                     : 2010:11:11 14:33:11-08:00
Modify Date                     : 2016:03:16 10:24:42-07:00
Subject                         : TR-10, Department of Computer Science, University of Utah, March 16, 1984
Has XFA                         : No
XMP Toolkit                     : Adobe XMP Core 5.6-c015 81.157285, 2014/12/12-00:43:15
Metadata Date                   : 2016:03:16 10:24:42-07:00
Creator Tool                    : Adobe Acrobat 9.4
Format                          : application/pdf
Title                           : The Portable Standard LISP User's Manual, Version 3.2
Description                     : TR-10, Department of Computer Science, University of Utah, March 16, 1984
Creator                         : Utah Symbolic Computation Group
Document ID                     : uuid:b945062a-5435-0044-b745-0153de4b7152
Instance ID                     : uuid:3263882e-9d9a-41c6-8961-d2a245708f35
Producer                        : Adobe Acrobat 9.4 Paper Capture Plug-in
Page Mode                       : UseOutlines
Page Count                      : 434
EXIF Metadata provided by EXIF.tools

Navigation menu