perm filename BAIL.DOC[DOC,AIL]9 blob sn#160727 filedate 1975-05-28 generic text, type T, neo UTF8
BAIL User Manual                                         May 28, 1975

















                     BAIL -- A debugger for SAIL










                           John F. Reiser
                     Computer Science Department
                         Stanford University











This work  was supported  in part  by a  National Science  Foundation
graduate  fellowship.    Computer  facilities  provided  by  Stanford
Artificial   Intelligence    Laboratory    and   by   Institute   for
Mathematical Studies in the Social Sciences, Stanford.
BAIL User Manual                                         May 28, 1975








BAIL is  a debugging   aid for  SAIL programs.    BAIL consists  of a
breakpoint package and an expression interpreter which allow the user
to stop his program at selected points, examine and change the values
of variables, and  evaluate general SAIL expressions.   In  addition,
BAIL  can display  text  from  the source  file corresponding  to the
current location in the program. In may respects BAIL is  like DDT or
RAID, except that  BAIL is oriented towards SAIL and knows about SAIL
data types, primitive operations,  and procedure implementation.

The  first  portion   of  this  manual  contains   several  annotated
examples  which  illustrate  the mechanics  of  using  BAIL, and  the
features which are available.   Technical details are covered in  the
second part of the manual.






























                                  1
BAIL User Manual                                         May 28, 1975


                                 This  is  a  test  program,  run  on
                                 TENEX.
@TYPE TEST1.SAI

;  <REISER>TEST1.SAI;1   SAT 10-MAY-75 2:37PM         PAGE 1


BEGIN "TEST"
EXTERNAL PROCEDURE BAIL;

INTEGER I,J,K;
STRING A,B,C;
REAL X,Y,Z;
INTEGER ARRAY FOO[0:15]; STRING ARRAY STRARR[1:5,2:6];
INTEGER ITEMVAR DAY; ITEMVAR QQ;

INTEGER PROCEDURE ADD(INTEGER I,J); BEGIN "ADD"
OUTSTR("
HI. GLAD YOU STOPPED BY."); RETURN(I+J) END "ADD";

RECURSIVE INTEGER PROCEDURE FACT(INTEGER N); BEGIN "FACT"
RETURN(IF N LEQ 1 THEN 1 ELSE N*FACT(N-1)) END "FACT";

SIMPLE PROCEDURE SIMPROC(REFERENCE INTEGER M); BEGIN "SBEG"
ADD(M,M←32) END "SBEG";

FOR I←0 STEP 1 UNTIL 15 DO FOO[I]←I*I;
FOR I←1 STEP 1 UNTIL 5 DO
    FOR J←2 STEP 1 UNTIL 6 DO
        STRARR[I,J]←64+8*I+J;
I←4; J←6; K←112;
A←"BIG DEAL"; B←"QED"; C←"THE LAST PICASSO";

X←3.14159265; Y←0; Z←23.;

BAIL;

ADD(7,45);
SIMPROC(J);

USERERR(0,1,"THIS IS A TEST");

END "TEST";

↑L




                                  2
BAIL User Manual                                         May 28, 1975


                                 Compile and load with BAIL.
@SAIL.SAV;10
 TENEX SAIL 8.1 4-4-75  (? FOR HELP)
*TEST1,←
**/27B
**
TEST1.SAI;1 1
END OF COMPILATION.
LOADING

LOADER 6+9K CORE
EXECUTION

↑C

                                 Save the core image for later use.
@SSAVE (PAGES FROM) 0 (TO) 577 (ON) TEST1 [NEW FILE]
 [CONFIRM] 

                                 Start the program.
@START

                                 BAIL identifies itself and the files
                                 involved.
BAIL VER. 10-MAY-75
TEST1.SM1;2
  TEST1.SAI;1
End of BAIL initialization.

1:45;

                                 The  "1:"  is  BAIL's   prompt.   It
                                 indicates  the  level  of  recursive
                                 invocations  of  BAIL  and  the fact
                                 that BAIL is awaiting input.

                                 See  how constants  are  entered and
                                 printed.  The "45;<cr>" is  typed by
                                 the user, and the next line  "45" is
                                 BAIL's reply.
   45
1:7.089;
    7.089000    
1:"SOME RANDOM STRING";
   "SOME RANDOM STRING"

                                  An octal constant; all  printout is
                                 decimal.

                                  3
BAIL User Manual                                         May 28, 1975


1:'275;
   189

                                 Symbolic  constants  More  than  one
                                 expression requested
1:TRUE,FALSE,NULL;
   -1   0   ""

                                 Variables, assignment
1:I;
   4
1:J,X;
   6    3.141593    
1:I←46;
   46
1:I;
   46

                                 Relational operators; remember  0 is
                                 FALSE.
1:I<J;
   0
1:I GEQ J;
   -1
1:98 LAND '17;
   2

                                 An undeclared identifier
1:XYZ;

UNKNOWN ID:  XYZ
                ;

                                 Usable as a desk calculator
1:45*(89.4-53.06);
    1635.300    
1:X+J;
    9.141593    

                                 Procedure call
1:ADD(3,4);

HI. GLAD YOU STOPPED BY.   7

                                 Argument list checking
1:ADD(3);

ADD TAKES 2 ARGUMENTS.:  ADD(3)

                                  4
BAIL User Manual                                         May 28, 1975


                               ;

                                 Arrays.    Array  name   only  gives
                                 dimension   and   subscript   bounds
                                 information.
1:FOO;
   <ARRAY>[ 0:15]
1:FOO[4];
   16

                                 Substring notation has been extended
                                 to cover array elements.
1:FOO[5 FOR 3];
   25   36   49
1:STRARR;
   <ARRAY>[ 1:5 2:6]
1:STRARR[1 FOR 2, 4 TO 6];
   "L"   "M"   "N"   "T"   "U"   "V"

                                 Array accesses are interpreted
1:FOO[35];

SUBSCRIPTING ERROR.   INDEX    VALUE    MIN    MAX
                        1       35      0       15      :  FOO[35]

                                 LENGTH, LOCATION, and MEMORY
1:A;
   "BIG DEAL"
1:LENGTH(A);
   8
1:I;
   46
1:LOCATION(I);
   718
1:MEMORY[718]←64;
   64
1:I;
   64

                                 Substringing
1:A[2 TO INF];
   "IG DEAL"
1:B[3 TO 4];
   "D"

                                 Type-in  must  be  terminated  by  a
                                 semicolon
1:B

                                  5
BAIL User Manual                                         May 28, 1975


;
   "QED"

                                 Tracing of procedure entry and exit
1:TRACE("FACT");

1:FACT(4);

 ENTERING FACT   4
  ENTERING FACT   3
   ENTERING FACT   2
    ENTERING FACT   1
    EXITING FACT=   1

   EXITING FACT=   2

  EXITING FACT=   6

 EXITING FACT=   24
   24
1:UNTRACE("FACT");

1:FACT(5);
   120

                                 Breakpointing
1:BREAK("ADD");

1:ADD(3,4);

                                 Now   one  level   deeper   in  BAIL
                                 recusion.  ARGS prints the arguments
                                 list.
2:ARGS;
   3   4

                                 Parameter  names evaluate  just like
                                 variables.
2:I;
   3
2:J;
   4
2:K;
   112

                                 To exit from one level of BAIL
2:!!GO;


                                  6
BAIL User Manual                                         May 28, 1975


HI. GLAD YOU STOPPED BY.   7

                                 The message is from ADD  itself; the
                                 value 7 is from BAIL.

                                 Leave another level of BAIL.
1:!!GO;

                                 And come back again.  Where are we?
1:TEXT;

                                 Static block structure
LEXICAL SCOPE, TOP DOWN:
$RUN$
TEST
ADD

                                 Dynamic procedure  invocations.  The
                                 #4 means coordinate number 4.
DYNAMIC SCOPE, MOST RECENT FIRST:
ROUTINE         TEXT
ADD     #4      INTEGER PROCEDURE ADD(INTEGER I,J); BEGI
TEST    #24     ADD(7,45);
SIMPROC(J);

USERERR(0,1,"

1:ARGS;
   7   45

                                 Remove the breakpoint.
1:UNBREAK("ADD");

1:!!GO;

                                 Output  from  other  calls   in  the
                                 program
HI. GLAD YOU STOPPED BY.
HI. GLAD YOU STOPPED BY.
THIS IS A TEST
CALLED FROM 642124  LAST SAIL CALL AT 400303
↑B

                                 Entry to BAIL from the error handler
1:TEXT;

LEXICAL SCOPE, TOP DOWN:
$RUN$

                                  7
BAIL User Manual                                         May 28, 1975



DYNAMIC SCOPE, MOST RECENT FIRST:
ROUTINE         TEXT
α.SIMPLE.        '642124 %%% FILE NOT VIEWABLE
TEST    #26     USERERR(0,1,"THIS IS A TEST");

END "T

1:I;

UNKNOWN ID:  I
              ;

                                 The  static  scope needs  to  be set
                                 back one on the dynamic chain.
1:SETLEX(1);

LEXICAL SCOPE, TOP DOWN:
$RUN$
TEST

1:I;
   64
1:C;
   "THE LAST PICASSO"
1:!!GO;

END OF SAIL EXECUTION





















                                  8
BAIL User Manual                                         May 28, 1975


                                 Leap   and   records,   DEC  TOPS-10
                                 system.
α.TYPE TEST2.SAI

BEGIN "TEST"
EXTERNAL PROCEDURE BAIL;
REQUIRE 500 SYSTEM!PDL, 10 PNAMES;

LIST L; SET S,S1,S2,S3,S4,S5;
INTEGER ITEM SUNDAY; ITEM MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,
        SATURDAY;
INTEGER ITEMVAR DAY; ITEMVAR QQ;
ITEMVAR ARRAY P[1:10];

RECORD!CLASS CELL (RECORD!POINTER(CELL) CAR,CDR);
RECORD!POINTER(CELL) CX,CY;

CX←NEW!RECORD(CELL);
CY←NEW!RECORD(CELL);
CELL:CAR[CX]←NULL!RECORD; CELL:CDR[CX]←NULL!RECORD;
CELL:CAR[CY]←CX; CELL:CDR[CY]←NULL!RECORD;

P[1]←SUNDAY; P[2]←MONDAY;
L←{{SUNDAY}}; DATUM(SUNDAY)←0; DAY←SUNDAY;  QQ←MONDAY; S←{QQ};
S1←{SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY};
S2←{MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY};
S3←{MONDAY,WEDNESDAY,FRIDAY}; S4←{SATURDAY,SUNDAY};
S5←{SUNDAY,FRIDAY};

FOREACH DAY SUCH THAT DAY IN S1 DO MAKE DAY XOR SUNDAY EQV SATURDAY;

BAIL;

USERERR(0,1,"THIS IS A TEST");

END "TEST";


EXIT
↑C









                                  9
BAIL User Manual                                         May 28, 1975


α.EXECUTE TEST2.SAI(27B,)
SAIL: TEST2  1
LOADING
LOADER 15K CORE
25K MAX 153 WORDS FREE
EXECUTION

BAIL VER. 10-MAY-75
TEST2.SM1
  TEST2.SAI
END OF BAIL INITIALIZATION.

1:L;
   {{SUNDAY}}
1:S4;
   {SUNDAY, SATURDAY}
1:S5;
   {SUNDAY, FRIDAY}
1:S4 UNION S5;
   {SUNDAY, FRIDAY, SATURDAY}
1:FRIDAY IN S4;
   0
1:S2 LEQ S2;
   -1
1:DAY;
   SATURDAY
1:DATUM(DAY);
   0
1:CX;
   CELL.9231
1:CELL:CAR[CX];
   NULL!RECORD
1:CELL:CAR[CY];
   CELL.9231
1:SUNDAY ASSOC SATURDAY;
   {SUNDAY}
1:SUNDAY EQV SATURDAY;
   {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY}
1:SUNDAY XOR SATURDAY;
   PHI
1:SUNDAY EQV SUNDAY;
   PHI
1:↑C






                                 10
BAIL User Manual                                         May 28, 1975


                                 Go back to the earlier examle
@TEST1.SAV;1

                                 Initialization  uses   file  created
                                 last time.
BAIL ver. 10-May-75 using TEST1.BAI
End of BAIL initialization.

                                 Switch  /27B  at  compile-time makes
                                 SAIL  predeclared  runtime  routines
                                 known to BAIL.
1:OPENFILE(NULL,"W");
TODAY.TMP
   4
1:OUT(4,"THIS IS A TEMPORARY FILE CREATED WHILE IN BAIL.");

1:CFILE(4);
   -1
1:OPENFILE("","RC");
TODAY.TMP [OLD VERSION]
   4
1:SINI(4,200,"Z");
   "THIS IS A TEMPORARY FILE CREATED WHILE IN BAIL."
1:ODTIM(-1,-1);
   "SATURDAY, MAY 10, 1975 17:19:29"

                                 Quickie review of BAIL capabilities
1:?

EXPRESSION;
PROCEDURE!CALL;
TRACE("PROCEDURE");
UNTRACE("PROCEDURE");
BREAK("PROCEDURE, BLOCK, OR LABEL");
UNBREAK("PROCEDURE, BLOCK, OR LABEL");
!!GO;
SETLEX(LEVEL);
TEXT;
ARGS;
HELP;
DDT;
?

1:↑C

                                 End of the examples.



                                 11
BAIL User Manual                                         May 28, 1975


                       I. Compile-time action

The principal   result of  activating  BAIL  at  compile-time  is the
generation of  a file of information about the source program for use
by the  run-time interpreter.  This  file has the  same name   as the
.REL file produced  by the compilation, except that  the extension is
.SM1.  If requested, BAIL will also generate some additional code for
SIMPLE  procedures  to make  them  more  palatable  to  the  run-time
interpreter.

The action of BAIL  at compile time is governed  by the value  of the
/B switch  passed to the  compiler.  If the  value of this  switch is
zero (the   default  if   no  value  is   specified)  then   BAIL  is
completely  inactive.   Otherwise, the  low-order bits  determine the
actions  which  BAIL  performs.   [The  value  of  the  /B  switch is
interpreted as octal.]

        bit     action

        1       If this bit  is on, then  the .SM1 file  will contain
             the program counter to source/listing text di rectory.

        2       If this bit  is on, then  the .SM1 file  will contain
             symbol  information for all  SAIL symbols encountered in
             the source.   If this bit  is  off, then  information is
             kept  only  for   procedures,  parameters,  blocks,  and
             internals;   i.e., non-   internal local   variables are
             not recorded.

        4       If this  bit is on,  then SIMPLE procedures  will get
             procedure descriptors, and one additional instruction (a
             JFCL   0,   which   is   the   fastest   machine   no-op
             instruction) is   inserted at  the beginning   of SIMPLE
             procedures.     Except  for   these  two   changes,  all
             properties of   SIMPLE procedures  remain  the  same  as
             before.  The  procedure descriptor  is necessary  if the
             procedure is  to  be called  interpretively  or  if  the
             procedure is to be TRACEd.

        '10     If  this   bit  is   on,  then   BAIL  will  not   be
             automatically   loaded and   initialized,   although all
             other  actions  requested   are  performed.     This  is
             primarily  intended  to  make it   easier to   debug new
             versions     of   BAIL     without    interfering   with
             SYS:BAIL.REL.  By using this switch the decision to load
             BAIL is delayed until load time.



                                 12
BAIL User Manual                                         May 28, 1975


        '20     If  this   bit  is  on,   then  a  request   to  load
             SYS:BAIPDn.REL   is  generated.     This  file  contains
             procedure   descriptors   for    most   of    the   SAIL
             pclared runtime  routines,  making it  possible  to them
             from BAIL.   The procedure descriptors and their symbols
             occupy about 6K.

The B switch must occur on the binary term, not the listing or source
term.  Thus:
        α.R SAIL                or      .COM PROG(27B,)

        *PROG/27B←PROG

The  program counter  to source/listing  index  is  kept in  terms of
coordinates.  The  coordinate counter is  zeroed at the  beginning of
the compilation and is incremented  by one for each BEGIN, ELSE,  and
semicolon seen by the parser, provided  at least one word of code has
been  compiled since the previous coordinate  was defined.  Note that
COMMENTs are  seen only  by the  scanner,  not the  parser, and  that
DEFINEs and many declarations  merely define symbols and do not cause
instructions to  be generated.   For  each coordinate  the  directory
contains the coordinate number, the value of the program counter, and
a  file pointer to the  appropriate place.  The  appropriate place is
the source file unless a listing file is being produced and  the CREF
switch is  off, in which case  it is the listing  file.  [The listing
file produced  for CREF is nearly unreadable.] On a non-CREF listing,
the program counter is replaced by the coordinate number  if bit 1 of
the /B switch is on.

The symbol table information consists  of the block structure and the
name, access information, and type for each symbol.

If a  BEGIN-END pair  has  declarations (i.e., is  a  true  block and
not just a  compound statement) but  does not have  a name, then BAIL
will invent one.   The name is of  the form Bnnnn where nnnn   is the
decimal value of the current coordinate.













                                 13
BAIL User Manual                                         May 28, 1975


                         II. Run-time action

The BAIL run-time interpreter is itself a  SAIL program which resides
on  the   system  disk   area.   This   program  is   usually  loaded
automatically, and  does  some initialization  when entered  for  the
first time.

The   initialization   generates  a   .BAI   file    of   information
collected from  the .SM1 files produced  by separate compilations (if
any).  The  .SM1 files correspond  to .REL files,  and the .BAI  file
corresponds to the .DMP or .SAV file.  Like RPG or CCL, BAIL will try
to bypass much of the initialization and use an existing .BAI file if
appropriate.  During  initialization BAIL displays  the names of  the
.SM1  files it  is  processing.  For each  .SM1  file which  contains
program counter/text index  information, BAIL displays  the names  of
the text files and determines whether the text files are accessable.

The  interpreter   is   activated  by   explicit   call,   previously
inserted  breakpoints, or the  SAIL error  handler.  For  an explicit
call, say  EXTERNAL  PROCEDURE  BAIL;  ... BAIL;.    From  the  error
handler,  respond B.   Breakpoints  will be  described later  in this
section.

Debugging  Requests.   When  entered,   BAIL  prints   the  debugging
recursion level followed by a colon, and awaits a  debugging request.
Options which are available are
        <expression not involving AND, OR, IF-THEN-ELSE, or CASE>;
        <procedure!call>;
        TRACE("procedure");
        UNTRACE("procedure");
        BREAK("procedure, block, or label");
        UNBREAK("procedure, block, or label");
        !!GO;
        SETLEX(level);
        TEXT;
        ARGS;
        HELP;
        DDT;
        ?

Expressions  and  procedure  calls  are  evaluated  as   if  they had
appeared  in the  source  file at  the point  of  the break.   TRACE,
UNTRACE, BREAK, and UNBREAK handle breakpoint insertion and deletion.
!!GO resumes execution  of the program.  SETLEX allows  access to the
static  environment of dynamic ancestors.   TEXT displays the current
static and dynamic scopes,  with text from the original  source file.
ARGS prints the arguments to the most recently called procedure.  DDT


                                 14
BAIL User Manual                                         May 28, 1975


transfers control to an assembly  language debugging program (if  one
was loaded).  HELP and "?" both print the above list.

Breakpoints.  Breakpoints are handled by evaluating a call to  one of
four procedures defined inside BAIL.
        procedure               description

TRACE("proc name")           Prints  the procedure  name  at  each
                             entry  and  exit,  the parameters  at
                             entry, and  the  value  RETURNed  (if
                             any) at exit. 

UNTRACE("proc name")         Discontinues tracing of the procedure.

BREAK("location")            Plants a breakpoint (a  call to BAIL)
                             at location, which may be a procedure,
                             label, or block name.

UNBREAK("location")          Remove a breakpoint.

        Naming conventions:  Names defined within the current lexical
(static) scope are always recognized.  After that, objects with names
that are globally unique and have a fixed memory location (everything
except parameters and recursive locals) are recognized.   After that,
BAIL gives up.

Extended  specification   of  location  names:  In  case  the desired
location is not unique, the following extended syntax may be used.
        location := label | procedure | blockname delim location

where delim is  any non-identifier character (e.g.,  altmode, period,
,virgule,space,...).  The last blockname should be the block in which
the label or procedure is delared.  The complete search algorithm is:
Search the blocks in memory-location order of BEGINs until a block is
found  which has  the first  blockname as  its name.   If there  is a
second   blockname,   continue  the   search   of   the   blocks   in
memory-location  order, beginning  with the  block  which immediately
follows the block which matched the first blockname.  Continue  until
all blocknames  have been  matched.   This yields  some block in  the
program.  Construct  the block structure ancestry of that block.  The
label or procedure must then be  declared within the scope of one  of
the blocks of that ancestry.

Examining  variables   not  in   the  current   lexical  scope:   The
procedure  SETLEX(n) changes the  lexical scope  to the scope  of the
n-th entry in the dynamic scope list.  SETLEX(0) is the scope  of the
breakpoint; SETLEX(1) is the scope  of the most recent procedure call
in the dynamic scope; etc.

                                 15
BAIL User Manual                                         May 28, 1975


BAIL and DDT:   If BAIL is  initialized  in a core  image  which does
not have  DDT or   RAID, then  things  will  be set  up  so  that the
monitor command DDT gets  you into BAIL in the  right way.  That  is,
BAIL will be your DDT.  To enter BAIL from DDT, use
        pushi P,<program counter>$X

        JRST BAIL$X

For example, if .JBOPC contains the program counter,
        PUSH P,.JBOPC$X

        JRST BAIL$X

To enter DDT from BAIL, simply say  DDT;.  For operation under TENEX,
control-B is a pseudo-interrupt character which gets you into BAIL.

        Syntax  extension:  The  TO and  FOR  substring  and  sublist
operators  have been extended  to operate as  array subscript ranges,
FOR PRINT-OUT ONLY.  Thus if FOO is an array, then FOO[3  TO 7]; will
act like  FOO[3], FOO[4],  FOO[5], FOO[6], FOO[7];  but is  easier to
type.  This extension is for print-out only; no general APL syntax or
semantics are provided.

WARNING: Since BAIL  is itself a  SAIL procedure, entering  BAIL from
the  error handler  or DDT  after  a push-down  overflow or  a string
garbage collection error will get you into trouble.

BAIL  and SIMPLE  procedures: SIMPLE  procedures cause  headaches for
BAIL  because they  do  not  keep a  display  pointer.   [Indeed, the
compiler gets lost in the following example, and does not complain:
        BEGIN "LOST"
        PROCEDURE A(INTEGER I); BEGIN "A"
          SIMPLE PROCEDURE B; OUTSTR("THE VALUE OF I IS " & CVS(I));
          PROCEDURE C(INTEGER J); B;
        C(2);
        END "A";

        A(1);
        END "LOST";                                     ]

BAIL tries valiantly to do the right  thing, but occasionally it also
gets lost.  BAIL will try to warn you if it can.  In general, looking
at value string parameters of SIMPLE procedures does not work.






                                 16
BAIL User Manual                                         May 28, 1975


                        III.  Resources Used

A.  Compile-time

    1.      One channel.  This  means that REQUIREd source  files may
        only be nested to a depth of about 9.

    2.       Memory.  Upto  11*(maximum lexical  nesting  depth) more
        words  of  memory  may  be  required  compared  with previous
        compilations.

    3.      CPU  time.  Approximately 0.3  seconds per page  of dense
        text.

B.  Run-time

    1.      Channels.   Three during initialization,  two thereafter.
        Channels are obtained via GETCHAN.

    2.       BAIL uses  7 of  the privile7ged  breaktables, obtaining
        them by GETBREAK.

    3.       REQUIRE  64  STRING!PDL.   Necessary  if  the  debugging
        recursion level will exceed 3 or 4.

    4.      Memory.  (9.5K +((# of coordinates+127) DIV 128) +  (2* #
        of blocks) + (5* # of symbols)) words.

    5.      CPU time.

        a.   Initialization.   Typically  4  seconds  for  a  30 page
            program.

        b.   Debugging requests.   0.07 seconds  per  simple request.
            DDT response time.

C.  Disk space

    1.  The .SM1 file  for a /7B compilation is  typically one-fourth
        the size of the corresponding .REL file.

    2.       The  .BAI  file  for  a  group  of  /7B  compilations is
        typically one-third the total size of the  corresponding .REL
        files.





                                 17
BAIL User Manual                                         May 28, 1975


                         IV. Current Status

The  state  of  the  world  is  determined  by  the  values   of  the
accumulators and the value of the SAIL varaible !SKIP!.

The run-time interpreter recognizes  only the first 15  characters of
identifier  names;  the  rest  are  discarded  without  comment.  The
characters which are legal in identifiers are
        ABCDEFGHIJKLMNOPQRSTUVWXYZ
        abcdefghijklmnopqrstuvwxyz
        0123456789!_αβπλ⊂⊃∀∃→~#$\|

        Notable for its absence: period.

LOCATION of a procedure does not work.

PROPS is read-only.

Bracketed triple items are not allowed.

Functional arguments are not handled correctly.

Contexts are not recognized.

The run-time interpreter will not recognize macros.
























                                 18