PSL Manual                    7 February 1983                         RLISP
section 3.0                                                        page 3.1

                                 CHAPTER 3
                                 CHAPTER 3
                                 CHAPTER 3
                               RLISP SYNTAX
                               RLISP SYNTAX
                               RLISP SYNTAX




     3.1. Motivation for RLISP Interface to PSL .  .  .  .  .  .  .     3.1
     3.2. An Introduction to RLISP  .  .  .  .  .  .  .  .  .  .  .     3.2
          3.2.1. LISP equivalents of some RLISP constructs  .  .  .     3.2
     3.3. An Overview of RLISP and LISP Syntax Correspondence  .  .     3.3
          3.3.1. Function Call Syntax in RLISP and LISP  .  .  .  .     3.4
                                                                        ...
          3.3.2. RLISP Infix Operators and Associated LISP Functions....3.4
                 
          3.3.3. Differences between Parse and Read.  .  .  .  .  .     3.6
          3.3.4. Procedure Definition  .  .  .  .  .  .  .  .  .  .     3.6
          3.3.5. Compound Statement Grouping .  .  .  .  .  .  .  .     3.7
          3.3.6. Blocks with Local Variables .  .  .  .  .  .  .  .     3.7
          3.3.7. The If Then Else Statement  .  .  .  .  .  .  .  .     3.8
     3.4. Looping Statements  .  .  .  .  .  .  .  .  .  .  .  .  .     3.8
          3.4.1. While Loop.  .  .  .  .  .  .  .  .  .  .  .  .  .     3.8
          3.4.2. Repeat Loop  .  .  .  .  .  .  .  .  .  .  .  .  .     3.8
          3.4.3. For Each Loop.  .  .  .  .  .  .  .  .  .  .  .  .     3.9
          3.4.4. For Loop  .  .  .  .  .  .  .  .  .  .  .  .  .  .     3.9
          3.4.5. Loop Examples.  .  .  .  .  .  .  .  .  .  .  .  .     3.9
     3.5. Switch Syntax .  .  .  .  .  .  .  .  .  .  .  .  .  .  .    3.10
     3.6. RLISP I/O Syntax .  .  .  .  .  .  .  .  .  .  .  .  .  .    3.10
     3.7. Transcript of a Short Session with RLISP .  .  .  .  .  .    3.11




3.1. Motivation for RLISP Interface to PSL
3.1. Motivation for RLISP Interface to PSL
3.1. Motivation for RLISP Interface to PSL

  Most  of  the  PSL  users  at  Utah  prefer  to  write LISP code using an
ALGOL-like (or PASCAL-like) preprocessor language, RLISP,  because  of  its
similarity to the heavily used PASCAL and C languages.  RLISP was developed
as  part  of  the  REDUCE  Computer  Algebra project [Hearn 73], and is the
ALGOL-like user language as well as the  implementation  language.    RLISP
provides  a  number of syntactic niceties which we find convenient, such as
                                   If-Then-Else
                                   If-Then-Else
vector subscripts, case statement, If-Then-Else, etc.  We  usually  do  not
distinguish LISP from RLISP, and can mechanically translate from one to the
other in either direction using a parser and pretty-printer written in PSL.
That  is,  RLISP  is  a  convenience,  but it is not necessary to use RLISP
syntax rather than LISP.  A complete BNF-like definition of RLISP  and  its
translation  to  LISP using the MINI system is given in Section 22.4.  Also
discussed in Chapter 22 is an extensible table driven parser which is  used
for  the  current RLISP parser.  There we give explicit tables which define
RLISP syntax.

  In this chapter we provide enough of an introduction to make the examples
and sources readable, and to assist the user in writing RLISP code.
RLISP                         7 February 1983                    PSL Manual
page 3.2                                                        section 3.2

3.2. An Introduction to RLISP
3.2. An Introduction to RLISP
3.2. An Introduction to RLISP

  An  RLISP  program  consists  of  a  set of functional commands which are
evaluated sequentially.  RLISP expressions are built up from  declarations,
statements  and  expressions.    Such entities are composed of sequences of
numbers, variables, operators, strings, reserved words and delimiters (such
as commas and parentheses), which in turn are sequences of characters.  The
evaluation proceeds by a  parser  first  converting  the  ALGOL-like  RLISP
source  language  into  LISP S-expressions, and evaluating and printing the
                                 Parse-Eval-Print
                                 Parse-Eval-Print
result.  The basic cycle is thus Parse-Eval-Print,  although  the  specific
functions, and additional processing, are under the control of a variety of
switches, described in appropriate sections.


3.2.1. LISP equivalents of some RLISP constructs
3.2.1. LISP equivalents of some RLISP constructs
3.2.1. LISP equivalents of some RLISP constructs

  The  following gives a few examples of RLISP statements and functions and
their corresponding LISP forms.  To see the exact LISP equivalent of  RLISP
code, set the switch !*PECHO to T [On PECHO; in RLISP, (On PECHO) in LISP].

  Assignment statements in RLISP and LISP:

   X := 1;                         (setq x 1)

  A procedure to take a factorial, in RLISP:

   LISP PROCEDURE FACTORIAL N;
     IF N <= 1 THEN 1
      ELSE N * FACTORIAL (N-1);

  in LISP:

   (de factorial (n)
     (cond
       ((leq n 1)  1)
       (T
         (times n (factorial (difference n 1))))))

  Take the Factorial of 5 in RLISP and in LISP:

   FACTORIAL 5;                    (factorial 5)

  Build a list X as a series of "Cons"es in RLISP:

   X := 'A . 'B . 'C . NIL;

   in LISP:
   (setq x (cons 'a  (cons 'b (cons 'c nil))))
PSL Manual                    7 February 1983                         RLISP
section 3.3                                                        page 3.3

3.3. An Overview of RLISP and LISP Syntax Correspondence
3.3. An Overview of RLISP and LISP Syntax Correspondence
3.3. An Overview of RLISP and LISP Syntax Correspondence

  The  RLISP parser converts RLISP expressions, typed in at the terminal or
read  from  a  file,  into  directly  executable  LISP  expressions.    For
convenience  in the following examples, the "==>" 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 [On
Pecho; in RLISP, (On Pecho) in LISP].  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 action_1  ELSE action_2
                  __________ ______ _     ______ _
      ==> (COND ((expression action_1) (T action_2)))

  In RLISP, a function is recognized as an "ftype" (one of the tokens EXPR,
FEXPR, etc. or none) 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 <statement> followed by a semicolon.  In LISP
syntax, a function is defined using one of the "Dx" functions, i.e. one  of
De  Df  Dm     Dn
De  Df  Dm     Dn
De, Df, Dm, or Dn, depending on "ftype".  For example:

   EXPR PROCEDURE NULL(X);
     EQ(X, NIL);
      ==>  (DE NULL (X) (EQ X NIL))


3.3.1. Function Call Syntax in RLISP and LISP
3.3.1. Function Call Syntax in RLISP and LISP
3.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(X1, X2, ... Xn)"   in   RLISP   and    as
"(FN X1 X2 ... Xn)" in LISP.  Commas are required to separate the arguments
in RLISP but not in LISP.  A zero argument function call is "FN()" 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
RLISP                         7 February 1983                    PSL Manual
page 3.4                                                        section 3.3

argument of any unary function in RLISP.


3.3.2. RLISP Infix Operators and Associated LISP Functions
3.3.2. RLISP Infix Operators and Associated LISP Functions
3.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, B)".

  Refer to Chapter 22 for details on how the association of "op"  and  "fn"
is installed.

  Parentheses   may   be   used   to  specify  the  order  of  combination.
"((A op_a B) op_b C)" in RLISP becomes "(fn_b (fn_a A B) C)" in LISP.

  If two or  more  different  operators  appear  in  a  sequence,  such  as
"A op_a B 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 B) op_b C"
if     Precedence(op_a) >= Precedence(op_b);     "A op_a (B 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 B op C", grouping is normally to the  left  (Left  Associative;  i.e.
"(fn (fn A B) C)"),  unless  the  operator  is explicitly Right Associative
               Cons             SetQ
               Cons             SetQ
(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 B" parses  into
"(nfn A B C D)" rather than into "(nfn (nfn (nfn A B) C) D)".

  The current binary operator-function correspondence is as follows:
PSL Manual                    7 February 1983                         RLISP
section 3.3                                                        page 3.5

________       ________       __________
Operator       Function       Precedence

               Cons
               Cons
.              Cons           23  Right Associative
               Expt
               Expt
**             Expt           23

               Quotient
               Quotient
/              Quotient       19
               Times
               Times
*              Times          19  N-ary

               Difference
               Difference
-              Difference     17
               Plus
               Plus
+              Plus           17  N-ary

Eq             Eq
Eq             Eq
Eq             Eq             15
               Equal
               Equal
=              Equal          15
               Geq
               Geq
>=             Geq            15
               GreaterP
               GreaterP
>              GreaterP       15
               Leq
               Leq
<=             Leq            15
               LessP
               LessP
<              LessP          15
Member         Member
Member         Member
Member         Member         15
Memq           MemQ
Memq           MemQ
Memq           MemQ           15
Neq            Neq
Neq            Neq
Neq            Neq            15

And            And
And            And
And            And            11  N-ary

Or             Or
Or             Or
Or             Or             9  N-ary

               SetQ
               SetQ
:=             SetQ           7  Right Associative


  Note:  There  are  other INFIX operators, mostly used as key-words within
                                    Then    Else        If           Do
                                    Then    Else        If           Do
other syntactic constructs (such as Then or Else in the If-...,  or  Do  in
     While
     While
the  While-..., etc.).  They have lower precedences than those given above.
These key-words include: the parentheses "()", the brackets "[]", the colon
":", the comma ",", the semi-colon ";", the dollar sign "$", and  the  ids:
Collect   Conc   Do   Else   End   Of  Procedure  Product  Step  Such  Sum
Collect   Conc   Do   Else   End   Of  Procedure  Product  Step  Such  Sum
Collect,  Conc,  Do,  Else,  End,  Of, Procedure, Product, Step, Such, Sum,
Then  To      Until
Then  To      Until
Then, To, and Until.

  As pointed out above, an 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
                                   Plus   Minus       Recip
                                   Plus   Minus       Recip
unary prefix operators, mapping to Plus,  Minus  and  Recip,  respectively,
with  precedence  26.  Certain other unary operators (RLISP key-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.
RLISP                         7 February 1983                    PSL Manual
page 3.6                                                        section 3.3

3.3.3. Differences between Parse and Read
3.3.3. Differences between Parse and Read
3.3.3. 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
                    Parse                                   Cons
                    Parse                                   Cons
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
                                               Read
                                               Read
RLISP mode, in which case it is interpreted by Read as part of the notation
                                                   Read
                                                   Read
for  pairs,  as  in  (SETQ X '(Y . Z)).  Note that Read called from LISP or
from RLISP uses slightly different scan tables (see Chapter 12).  In  order
                        Cons                               Cons
                        Cons                               Cons
to  use  the  function  Cons in LISP one must use the word Cons in a prefix
position.


3.3.4. Procedure Definition
3.3.4. Procedure Definition
3.3.4. Procedure Definition

  Procedure definitions in PSL (both RLISP and LISP) are not nested  as  in
ALGOL;  all  appear  at the same top level as in C.  The basic function for
                       PutD
                       PutD
defining procedures is PutD (see Chapter 10).  Special syntactic forms  are
provided in both RLISP and LISP:

     mode ftype PROCEDURE name(v_1,...,v_n); body;
        ==> (Dx name (v_1 ... v_N) body)

  Examples:

   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.

  In the general definition given above "mode" is usually optional; it  can
be  LISP  or  SYMBOLIC  (which  mean  the  same  thing) or SYSLISP [only of
                                                              ____   _____
                                                              ____   _____
                                                              ____   _____
                                                              expr   fexpr
                                                              expr   fexpr
importance if SYSLISP and LISP are inter-mixed].  "Ftype" is  expr,  fexpr,
_____   _____       ______
_____   _____       ______
_____   _____       ______
macro   nexpr       smacro
macro   nexpr       smacro
macro,  nexpr,  or  smacro (or can be omitted, in which case it defaults to
____
____
____
expr
expr
expr).  Name(v_1,...,v_N) is any legal form of call, including infix.    Dx
             ____            _____          _____         _____
             ____            _____          _____         _____
             ____            _____          _____         _____
    De       expr   Df       fexpr   Dm     macro  Dn     nexpr      Ds
    De       expr   Df       fexpr   Dm     macro  Dn     nexpr      Ds
is  De  for  expr,  Df  for  fexpr,  Dm for macro, Dn for nexpr, and Ds for
______
______
______
smacro
smacro
smacro.

      ______                          _____
      ______                          _____
      ______                          _____
      smacro                          macro
      smacro                          macro
  The smacro is a simple substitution macro.
PSL Manual                    7 February 1983                         RLISP
section 3.3                                                        page 3.7

   SMACRO PROCEDURE ELEMENT X;    % Defines ELEMENT(x)  to substitute
    CAR CDR (X);                  % as Car Cdr x;
      ==> (DS ELEMENT (X) (CAR (CDR X)))

In  code  which  calls  ELEMENT after it was defined, ELEMENT(foo); behaves
exactly like CAR CDR foo;.


3.3.5. Compound Statement Grouping
3.3.5. Compound Statement Grouping
3.3.5. 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.

  The RLISP <<A; B; C; ... Z>> becomes (PROGN A B C ... Z) in  LISP.    The
value of the group is the value of the last expression, Z. 
  Example:

   X:=<<PRINT X; X+1>>;          % prints old X then increments X
     ==> (SETQ X (PROGN (PRINT X) (PLUS X 1)))


3.3.6. Blocks with Local Variables
3.3.6. Blocks with Local Variables
3.3.6. Blocks with Local Variables

  A  more  powerful  construct,  sometimes used for the same purpose as the
                    Begin-End                       Prog
                    Begin-End                       Prog
<< >> 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
                                             Return
                                             Return
exited  at  a  number  of  points, using the Return statement, and each can
                                                                       GoTo
                                                                       GoTo
return a different value.   The  block  also  permits  labels  and  a  GoTo
construct.

  Example:

   BEGIN SCALAR X,Y;  % SCALAR declares locals X and Y
           X:='(1 2 3);
     L1:   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))
RLISP                         7 February 1983                    PSL Manual
page 3.8                                                        section 3.3

3.3.7. The If Then Else Statement
3.3.7. The If Then Else Statement
3.3.7. The If Then Else Statement

                     If                                     Cond
                     If                                     Cond
  RLISP  provides an If statement, which maps into the LISP Cond statement.
See Chapter 9 for full details.  For example:

   IF e THEN s;
      ==> (COND (e s))

   IF e THEN s1 ELSE s2;
      ==> (COND (e s1) (T s2))

   IF e1 THEN s1
    ELSE IF e2 THEN s2
    ELSE s3;
      ==> (COND (e1 s1)
                (e2 s2)
                (T  s3))



3.4. Looping Statements
3.4. Looping Statements
3.4. Looping Statements

                 While   Repeat   For       For  Each
                 While   Repeat   For       For  Each
  RLISP provides While,  Repeat,  For  and  For  Each  loops.    These  are
discussed in greater detail in Chapter 9.  Some examples follow:


3.4.1. While Loop
3.4.1. While Loop
3.4.1. While Loop

   WHILE e DO s;           % As long as e NEQ NIL, do s
      ==>  (WHILE e s)


3.4.2. Repeat Loop
3.4.2. Repeat Loop
3.4.2. Repeat Loop

   REPEAT s UNTIL e;       % repeat doing s until "e" is not NIL
      ==>  (REPEAT s e)


3.4.3. For Each Loop
3.4.3. For Each Loop
3.4.3. For Each Loop

       For  Each
       For  Each
  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 s;   % y is a list, x traverses list bound to eac
                           % element in turn.
      ==>  (FOREACH x IN y DO s)

   FOR EACH x ON y DO s;   % y is a list, x traverses list Bound to suc
                           % Cdr's of y.
      ==>  (FOREACH x ON y DO s)

  Other options can return modified lists, etc.  See chapter 9.
PSL Manual                    7 February 1983                         RLISP
section 3.4                                                        page 3.9

3.4.4. For Loop
3.4.4. For Loop
3.4.4. For Loop

      For
      For
  The For loop permits an iterative form with a compacted control variable.
Other options can compute sums and products.

   FOR i := a:b DO s;      % step i successively from a to b in
                           % steps of 1.
      ==> (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)


3.4.5. Loop Examples
3.4.5. Loop Examples
3.4.5. Loop Examples

   LISP PROCEDURE count lst; % Count elements in lst
    BEGIN SCALAR k;
          k:=0;
          WHILE PAIRP lst DO <<k:=k+1; lst:=CDR lst>>;
          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 lst; % Count  NIL elements in lst
    BEGIN SCALAR k;
          k:=0;
          FOR EACH x IN lst 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)))
RLISP                         7 February 1983                    PSL Manual
page 3.10                                                       section 3.5

3.5. Switch Syntax
3.5. Switch Syntax
3.5. Switch Syntax

  Two  declarations are offered to the user for turning on or off a variety
of switches in the system.  Switches are global variables  that  have  only
the  values  T  or  NIL.    By convention, the switch name is XXXX, but the
associated global variable is !*XXXX.  The RLISP commands ON and OFF take a
list of switch names as argument and turn  them  on  and  off  respectively
(i.e. set the corresponding !* variable to T or NIL).

  Example:

   ON ECHO, FEE, FUM;    % Sets !*ECHO, !*FEE, !*FUM to T;
      ==> (ON  ECHO FEE FUM)

   OFF INT,SYSLISP;       % Sets !*INT and !*SYSLISP to NIL
      ==> (OFF  INT SYSLISP)

  [??? Mention SIMPFG property ???]
  [??? Mention SIMPFG property ???]
  [??? Mention SIMPFG property ???]

  See Section 6.7 for a complete set of switches and global variables.



3.6. RLISP I/O Syntax
3.6. RLISP I/O Syntax
3.6. RLISP I/O Syntax

  RLISP provides special commands to OPEN and SELECT files for input or for
output  and  to CLOSE files.  File names must be enclosed in "....".  Files
                                               In
                                               In
with the extension ".sl" or ".lsp" are read by In in LISP mode rather  than
RLISP mode.

   IN "<griss.stuff>fff.red","ggg.lsp"; % First reads fff.red
                                        % Then reads ggg.lsp
   OUT "keep-it.output";                % Diverts output to "keep-it.ou
   OUT "fum";                           % now to fum, keeping the other
   SHUT "fum";                          % to close fum and flush the bu

  File  names can use the full system conventions.  See Chapter 12 for more
detail on I/O.



3.7. Transcript of a Short Session with RLISP
3.7. Transcript of a Short Session with RLISP
3.7. Transcript of a Short Session with RLISP

  The following is a transcript of RLISP running on the DEC-20.
PSL Manual                    7 February 1983                         RLISP
section 3.7                                                       page 3.11

   @psl:rlisp
   PSL 3.1 Rlisp, 27-Oct-82
   [1] % Notice the numbered prompt.
   [1] % Comments begin with "%" and do not change the prompt number.
   [1] Z := '(1 2 3);              % Make an assignment for Z.
   (1 2 3)
   [2] Cdr Z;                      % Notice the change in the prompt nu
   (2 3)
   [3] Lisp Procedure Count L;     % "Count" counts the number of eleme
   [3]   If Null L Then 0          %    in a list L.
   [3]     Else 1 + Count Cdr L;
   COUNT
   [4] Count Z;                    % Try out "Count" on Z.
   3
   [5] Tr Count;          % Trace the recursive execution of "Count".
   (COUNT)
   [6]                    % A call on "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) = 1
     COUNT (level 2) = 2
   COUNT = 3
   3
   [7] Lisp Procedure Factorial X;
   [7]   If X <= 1 Then 1
   [7]     Else X * Factorial (X-1);
   FACTORIAL
   [8] Tr Factorial;
   (FACTORIAL)
   [9] Factorial 4;            % Trace execution of "Factorial".
   FACTORIAL being entered
      X:   4
     FACTORIAL (level 2) being entered
        X: 3
       FACTORIAL (level 3) being entered
          X:       2
         FACTORIAL (level 4) being entered
            X:     1
         FACTORIAL (level 4) = 1
       FACTORIAL (level 3) = 2
     FACTORIAL (level 2) = 6
   FACTORIAL = 24
   24
RLISP                         7 February 1983                    PSL Manual
page 3.12                                                       section 3.7

   [10] UnTr Count,Factorial;
   NIL
   [11] 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, excep
   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 backtrace
   Q        Exit break loop back to ErrorSet
   C        Return last value to the ContinuableError call
   R        Reevaluate ErrorForm!* and return
   M        Display ErrorForm!* as the "message"
   E        Invoke a simple structure editor on ErrorForm!*
                   (For more information do Help Editor.)
   I        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:
   LIST2 CDR COUNT PLUS2 PLUS COND COUNT
   NIL
   3 lisp break> Q             % To exit the Break Loop.
   [12]                        % Load in a file, showing the file
   [12] In "small-file.red";   % and its execution.
   X := 'A . '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
   [13]                        % This leaves RLISP and enters
   [13] End;                   %   LISP mode.
   Entering LISP...
   PSL, 27-Oct-82
   6 lisp> (SETQ X 3)          % A LISP assignment statement.
   3
   7 lisp> (FACTORIAL 3)       % Call "Factorial" on 3.
   6
   8 lisp> (BEGINRLISP)        % This function returns us to RLISP.
   Entering RLISP...
   [14] Quit;                  % To exit call "Quit".
   @continue
PSL Manual                    7 February 1983                         RLISP
section 3.7                                                       page 3.13

   "Continued"
   [15] X;                     % Notice the prompt number.
   3
   [16] ^C                     % One can also quit with <Ctrl-C>.
   @start                     % Alternative immediate re-entry.
   [17] Quit;
   @
