perm filename TELLEM[S,AIL]1 blob sn#000865 filedate 1972-09-27 generic text, type T, neo UTF8
 00001 00001
 00004 00002	
 00005 00003	INTRODUCTION
 00006 00004	OPTIONS
 00008 00005	PARTS LIST (see appendix II for expanded explanations)
 00025 00009	
 00033 00011	RUN-TIME LIBRARY {LIB}
 00053 00015	
 00061 00017	
 00075 00020	
 00079 00021	
 00084 00022	
 00087 00023	
 00107 00026	B. MAKTAB.SAI
 00111 ENDMK


				Bob Sproull
				October 1970
				Revised May 1971 by D. Swinehart
				Revised Sept 1971 by D. Swinehart

This document describes the various parts of the SAIL system, and how
they   might  be  combined  to  form  many  optional  manifestations.
Hopefully  not  only  the  methods  for  installing  SAIL,  but   the
motivations behind them will be explained.

The first sections are somewhat wordy, and describe in detail what is
going on.  Later sections may be used as checklists in performing the
actual    installation.    Appendices    follow,    explaining   less
commonly-needed facts.

You will probably not want a system with all  the  available  options
and configurations (especially since some are mutually exclusive). So
that you may readily ignore explanations of features you don't  want,
sections   which  represent  optional  things  are  labelled  in  the
following manner:

LEAP -- this section is of interest only if you want a SAIL with  the
    LEAP  features. 
NOLEAP -- this section of interest only if you want one without LEAP.

TWOSEG--this section describes  the  sharable  (2d  segment)  runtime
     routines  configuration. 
NOTWOSEG -- of interest only in non-sharableconfigs etc.

TSCOMP -- describes  the  compiler  which  uses  the  TWOSEG  runtime
NOTSCOMP -- etc.

LIB  --  describes the process for creating the LIBSAI library. 
NOLIB-- etc.

REENT -- describes the process for creating re-entrant SAIL programs,
     such  that not only the runtimes, but the entire user program is
     sharable; and the library that goes with such programs.

BIGRUN, NOBIGRUN -- describes the process  for  creating  RUNTIM.REL,
all runtimes, non-sharable.

When these tags appear, they will be between braces ({}) in the text.
PARTS LIST (see appendix II for expanded explanations)

A. File necessary to get the file-restoring program off the tape.
   GETSAV.MAC (paper tape so labelled)

B. File necessary to get all the rest of the files off the tape.
   SAVE.SAV    (first file on tape)

C. Files needed to get initial compiler and operating system going
   TELLEM (this listing)
   DDT.REL (currently can't use any configuration of DEC's DDT)
   LIBSAI.REL (library of runtime routines for transfer to SYS:)
D. Source files for SAIL compiler and execs
   STRSER	     }

E. Files to build parser tables (FAIL files for inclusion in SAIL)
   PROD.QQQ (output of PTRAN, input is HEL2)

F. Source files for SAIL compiler
   (HEL2, FOO2 as comments)
   PROD (output of PTRAN, input is HEL2)
   RESTAB (output of RTRAN, input is FOO2)

G. Source files for Execs

H. Required software support, if any modifications are to be made
   FAIL.REL (a one-pass assembler)
   PTRAN.SAI (creates FAIL-readable parser tables from HEL2)
   RTRAN.SAI (creates FAIL-readable symbol table (reserved wds) from FOO2)
    (above previously HYSS and HYRS, respectively)
   CMDSCN.SAI (gets REQUIRED as a .REL file by PTRAN and RTRAN)
   MAKTAB.SAI (creates 1OPS1.OPS)

I. Other files needed to complete standard feature set
   BKTBL.BKT (needs to be on SYS when STDBRK is called)
   1OPS1.OPS (START_CODE opcode table, created by compiling and running MAKTAB)

J. Other useful files
   LOADER.052 (our slightly modified version)
   DDT.FAI (our slightly modified version -- block structure)
   CREF.MAC (modified for block structure)
   SCISS.SAI (makes a library, HISEG {REENT} or one-segment
   EXTRACT.SAI, DATALIST.SAI -- help in documenting SAIL.
   NEWMAN -- changes to manual since last published.
   FAIL.ON -- FAIL assembler manual
   SAIL.ON -- SAIL manual -- restoration of these last two to DSK should
	      be inhibited if disk storage is scarce -- about 100K worth.
   PROFIL.SAI -- See NEWMAN for description of PROFILE feature. This program
    lists the .KNT file and .LST file, giving a nice program profile. 
    omitted.  We tacked it onto the end.

K. Some additional files of marginal usefulness.  They are either documents,
    or programs whose only documentation is self-contained, if at all.  You
    can take a look at them if you want to.  They are mostly SAIL programs
    and their manuals.


This  presents  no  problem. The files are stored on several DECtapes
with  the  directories  plainly  listed thereon. They are  stored  in
standard PDP-10 DECTAPE format.

B. Mag Tape, 7 track only

We  converted  from  FAILSAFE  to  a  locally  written backup program
several years ago.  Therefore, you and we do  not  possess  a  common
tape format for transporting files.  Instead, we have sent a program,
SAVE, on the tape.

Obtain SAVE by assembling  the  paper  tape  GETSAV.MAC  program  and
running  it.   This will fetch the file SAVE.SAV from MTA0, 7 tracks,
556bpi, even parity.

Run SAVE.SAV, responding to the * with  /H<cr>.  This  will  print  a
listing describing the operation of the SAVE program.

Use the *.* restore option to retrieve the rest of the files from the

If you have no disk system, or your disk is not large enough to  hold
all the files at once, you will have to rely on your own resources to
solve the problem.

After SAVE returns from a *.* restore operation, typing  *.* again
will retrieve the additional marginally-interesting files mentioned
on the previous page and in the appendices. The SAVE writeup will also
tell you how to get  selected  files  from  there   (PROFIL.SAI,  for

C. Subsequent updates to the SAIL system will  probably  be  provided
via SOUP update files, so KEEP THESE ORIGINALS, INTACT!!

The file SAIL.REL should run on any  standard  DEC  10/50  system  of
recent  (year  or  two)  vintage.  Load it with the DDT.REL provided,
using version 52 or later of  the  LOADER,  with  SAILSW  and  FAILSW
turned  on,  and  save it as SAIL.SAV (one segment) somewhere.  Later
descriptions will indicate a method for creating  a  version  without

The  file  LIBSAI.REL  is  the  library  which  is  REQUIREd  by  all
SAIL-compiled programs.  It uses a  recently-installed  LOADER  block
type  to  cause the automatic search.  The LOADER will look on device
SYS for this file, and will not really let you go  on  until  such  a
file  is  put  there.   The  version  of  LIBSAI  supplied  should be
sufficient in all important  details  (at  least  till  you  get  the
bootstrapping done).

If  you have installed SAIL on your SYS device, CCL may be changed to
include SAIL as a standard processor by including the line
program).  You may  also  include  "FAIL,FAI,FAIL"  if  you  want  to
promote use of the FAIL assembler.

To  complete a SAIL system (if you're not going to investigate any of
the other, better options or make any  changes),  transfer  1OPS1.OPS
and  BKTBL.BKT  to  SYS.   Always  load  SAIL-compiled  programs with
version 52 of the LOADER or later, with SAILSW and FAILSW  turned  on
(or  ours,  which  has  its points), and always use our DDT (at least
until we can get together with DEC on it).

There is one additional thing you can do if you want  to  --  install
the  LOADER  provided  with  SAIL.  This LOADER uses the /Y switch to
make shared-segment  loading  more  convenient  (See  Operating  with
shared  segments, below. In addition, it automatically invokes /B and
/K to cut core to reasonable sizes after loading.  It is by no  means
necessary to use our LOADER, though.
PS. Our Loader has some fixes pertaining to two-segment loading, which
will be contained in future DEC releases.

Appendix VI contains a description of some programs you can run (with
difficulty)  to obtain some direct summaries of the data declarations
and routine descriptions of the compiler -- direct in that  they  are
gleaned  from  the  assembly  listing  of  the  compiler itself.  The
comments which accompany the source  files are also fairly extensive.
This,  however,  is  about  the  only  assistance  you  will  get  in
understanding the compiler,  except  for  the  Parser  discussion  in
appendix  IV.  Therefore,  this  section  is  not  intended to aid in
anything but the actual mechanics (assembly, etc.) of modifying SAIL.

A. If you have only modified FAIL code, the process is fairly simple:

  1. One Segment Compiler

  The assumed value of COM2SW should be overriden to make  it  0  in
  HEAD (see C, below, and HEAD for conditional assembly descriptions
  -- a complete set of such references is found in appendix III).

  Then  this  command  string  should  be  typed  to  FAIL  (or  the
  equivalent formulation given via CCL:


  SAIL.REL will be created.  This version is tailored for  slimness,
  and is not intended to be loaded with DDT.  Otherwise it should be
  loaded and saved as described on the previous page.

  2. One Segment Compiler, tailored for debugging.

  This version should  (sort  of  must)  be  loaded  with  DDT.   It
  contains  code  for  the  /nM options described in the SAIL manual
  (and slightly better in the file PARSE just ahead of the code that
  does  it).  With  this  compiler  it  is much easier to track down
  elusive "line 99500, page 47" bugs.

  The command string is the same, except that FTDEBUG should be made
  1  instead  of 0 (never -1, 3, or anything but 0 or 1!!!!!) in the
  file SAIL (or insert a file with FTDEBUG←←1 in it ahead of SAIL).

  This is the version which was sent to you as SAIL.REL.

  3. Two Segment Compiler, no debugging {TSCOMP, TWOSEG}

  Leave COM2SW the way it was (1) when you got it  (in  HEAD)  leave
  FTDEBUG=0,  and use the above command string with GOGOL and STRSER
  omitted.  Load without DDT,  but  as  if  it  were  a  two-segment
  SAIL-compiled  program  (see Two Segment operation, below).   Save
  in ONE segment, always (as with any SAIL-compiled job, see below).
  When it runs, it will pick up the shared stuff.

  4.  Two  segments,  debugging  mode  Same  as  version 3, but make
  FTDEBUG←←1, load with DDT.
B. Changes to HEL2 (parse table) or FOO2 (built-in procedures)

  If for any reason you change either of these files, more work  has
  to be done:

  NOTE -- PTRAN and RTRAN replace HYRS and HYSS, resp.

  1.  PTRAN  -- Production Translator (see Appendix IV) This program
  takes the pseudo Floyd-Evans productions found in  file  HEL2  (or
  any  other),  and  converts  it  to  FAIL  assembly  language data
  statements which define interpretation tables for  the  parser  of
  SAIL.   In  addition,  it issues an auxilliary file containing the
  names of  the  reserved  words,  for  use  in  the  RTRAN  program
  described below.

  First  compile  CMDSCN.SAI  with your shiny new copy of SAIL. Then
  compile PTRAN.SAI with your slightly used copy of  SAIL,  load  it
  and  run  it.   It  will  respond  with a `*', to which you should
  counter:    PROD←HEL2<cr>.  When another  `*'  appears,  PROD  and
  PROD.QQQ  have  been  created.   PROD  is the parse table (HEL2 is
  included only as a comment in the assembly  above,  as  is  FOO2).
  PROD.QQQ is the list of reserved words for RTRAN.

  2. RTRAN -- Reserved Word Translator

  This  program  issues  FAIL  source code which defines the initial
  configuration of the SAIL internal symbol table, for the  reserved
  words  like  BEGIN  and  END,  and for the execution routines like
  INPUT, BREAKSET, etc.  Input for the  reserved  words  comes  from
  PROD.QQQ  via  PTRAN.   Input  for the executions is from the file
  FOO2.  Appendix IV describes the formats of these files in detail.
  The  command  string  is:    RESTAB←PROD,FOO2,HEL2<cr>.  The third
  argument  is  a  dummy,  included  for  historical  reasons.   The
  resultant RESTAB is the initial symbol table, expressed in FAIL.

  Now proceed as given in part A.

  PTRAN  will  read  commands from nnnPTR.TMP if started in CCL mode.
  RTRAN will read from nnnRTR.TMP. Make what you like of that.

C. Some particularly interesting conditional assembly switches

  FTDEBUG -- 1 for debug/mode, 0 for non-debug mode, as above.

  LEAPSW  {LEAP}  -- on for LEAP features (standard), off otherwise.
  If you turn it off, you should also set the LEAPSW entry  in  HEL2
  to off (see Appendix ??)

  COM2SW -- on for two-segment compiler (standard), off otherwise.

  TIMER  --  on  if  routine and alternate starting address is to be
  provided to run the compiler interpretively, in order to determine
  where the time is going -- number of instructions executed in each
  of a number  of  general  compiler  areas  is  available  after  a
  compilation  --  see  PARSE for a detailed (the code) description.
  This feature makes  the  "compiler"  run  approximately  25  times
  slower than usual.

  RENSW -- usually 1 -- on if compiler is to be capable of generating
  re-entrant (two-segment) code.  To get it to do that, use /H in the
  command string.  Such a file will REQUIRE the HLBSAI library, each
  file of which has been HISEGed (see below).  Most of the program
  can thus be shared, if the program has reached CUSP status.

  SIXSW -- turn this on if you use sixbit project-programmer numbers.
  Otherwise, SAIL assumes octal ones.  Examine all SIXSW-dependent
  code if you use something else entirely, and make changes.

  TMPCSW -- turn this off if your system does not support the TEMPCOR

The files  GOGOL, STRSER, IOSER, and LEPRUN,  along  with  the  macro
and accumulator  definition file HEAD, were historically assembled in
the order


to  create  a  file RUNTIM.REL which contained the storage allocator,
the initializer, the string garbage collector, and all the  execution
routines  (INPUT, BREAKSET, concatenation, CVS, LEAP, etc.).

This  method  may  still  be  used.   Simply assemble the files given
above, (include LEPRUN only if LEAPSW is on  in  HEAD  and want LEAP),
in  the  order  specified.  Specify RUNTIM.REL, or anything else, for
that  matter,  as  the  binary  file.   This  file,  loaded  with   a
SAIL-compiled  program,  will  provide  all  the  support  necessary.
Unfortunately, it is about 8K long.

We  found  that  out.   However,  the  obvious  solution to the large
execution package revealed some drawbacks.  We  wanted  to  create  a
library  for  SAIL  in  the  manner of the FORTRAN library.  However,
given the DEC  library  file  conventions,  each  separately-loadable
entry  would  have  to be assembled separately.  This was not so bad,
but it would mean fragmenting GOGOL  and  friends  into  many  parts,
making the creation of RUNTIM.REL or the shared segment version hard.
It was crucial  that  there  not  be  multiple  copies  of  the  same
routines, because maintenance of one set is hard enough.......

The  current  solution  to the problem is the program SCISS.SAI, some
special macro constructs in GOGOL and friends, and a lot of luck.

SCISS operates in two passes, with a pass of FAIL  between.   On  the
first  pass, it extracts from HEAD and GOGOL some common code used by
all library entries (making  HDRFIL.FAI,  or  some  such).   Then  it
writes   one  FAIL  source  file  for  each  desired  library  entry,
extracting its code from the file GOGOL, STRSER, or IOSER in which it
appears  (removing  comments  and blank lines), naming each after its
library entry.  In addition, it writes a command file (CCL  file)  to
FAIL, then chains to FAIL.

FAIL  assembles  all  the  little FAIL files, each preceded by HDRFIL,
into little .REL files, chaining back to SCISS, this time in CCL mode,
thus  indicating  pass 2.  On pass 2, SCISS copies all the .REL files
into LIBSAI.REL, removing local symbols and cleaning things up.   All
the  FAIL  and  .REL  files, along with the HDRFIL and CCL files, are
deleted if desired.  Also included in LIBSAI,  if  desired,  are  the
LEPRUN routines, and the USERCON symbol definition file, created from
HEAD (see USERCON in the manual).

Here we will only discuss the STANDARD case.  The procedure is:

Read into GOGOL, looking for the COMPILE macro, the ENDCOM macro, and
the ORDER comment on the early pages.  This gives you an idea of what
is going on inside to give SCISS a hand.

Compile  and load  SCISS.SAI, and save it as SCISS.SAV on the area on
which you intend to run it.

Run SCISS.  When it asks  "STANDARD?  ",  answer  "Y<cr>".   It  will
chatter for some time about what it intends to do, then about what it
is doing. Thereafter, FAIL will be invoked to compile all the  little
files.  Finally  SCISS  will  return  with  "STANDARD? ".  Answer Yes
again.  It will drone on some more about the files it is deleting and
copying.   Finally  it  will  report  that  LIBSAI.REL exists for the

The conditional assembly switch RENSW is set by default to 1 in GOGOL.
If you created a library with this switch on, it should be renamed to
HLBSAI.REL and put it on SYS.  Then set RENSW to 0 in GOGOL (just be-
fore the STSW(RENSW,1) in the initial pages) and run SCISS again. This
is the non-reentrant library.  Programs compiled with /H will use
HLBSAI -- others will use the shared segment (see {TWOSEG} below) or
LIBSAI.  You should create only a LIBSAI (RENSW off in GOGOL) if you
don't make a /H-type compiler (RENSW off in SAIL) when you assemble it.

If anything goes wrong,  you  will  probably  profit  from  the  more
complete discussion of SCISS in appendix VI.

This option represents the latest step  in  the  evolution  of  these
things.   In this version, we are back to the 8K runtime package, but
this time it occupies the (entire) second segment of  any  number  of
jobs.   Linkage to routines in this segment is accomplished at LOADER
time by loading as the FIRST THING a file containing  the  name  of a
particular upper segment, as well as symbol names and  locations  for
that upper segment's routines.  In addition, this file  contains some
impure  data  for the SAIL job, along with the UUO trap locations and
the code necessary to attach via GETSEG to the specified segment.
In this way the upper and lower files are keyed to each other, and as
long as standard naming conventions are followed, an  old  .SAV file,
when run, will never link to a new segment with unmatching addresses.
A  transfer  vector in the upper segment,  through which all calls to
runtime routines go, also minimizws this possibility of dissynchroni-

To  create one of these clever beasts, first look at the file FILSPC.
It contains default values  for  this  lower  segment  name  (SAILOW,
typically),  the current upper segment name (SAISGn, n a digit) which
will be unique to this particular manifestation (or at  least  should
change  when  the transfer vector changes), and some parameters which
are probably meaningless in your installation, and should be left  as
they  are.   In  addition, the device (DSK or SYS) and PPN pair where
the  segment file will  be  found  is  also  defined  therein.   Thus
SAISGn.SHR is one file which need not reside on SYS.

Once you are satisfied that FILSPC is OK (modification should include
noting on page 2 the date, the version number if you must,  and  what
glorious  changes  warrant  the new version), Use FAIL on the command


LOWER.REL will be a binary file containing the desired upper  segment
name and location  (for  use  by  the GETSEG routine), and the lower-
segment  initialization  and  impure code, selected from GOGOL by the
conditional assembly in LOW.FAI.

Now use FAIL to assemble:

TAILOR←HEAD,FILSPC,TAILOR (or the CCL equivalent, of course).

TAILOR.REL contains the upper segment name and location,  along  with
the other useless parameters from FILSPC, this time in core locations
rather  than as assembly constants.  This could have been included in
the next assembly, but wasn't so  that  the names  and  other  things
could  be changed without re-assembling the body of the segment code.

The last assembly is:


UPPER.REL contains, after some initial messing around, code PHASEd to
400000 and succeeding locations, so that when it  is  fetched  as  an
upper  segment, it will be able to run there.  The trick is to get it
written out such that this can be done.  Some of that  which  follows
may  look  ridiculous and overly complex to some of you, but remember
that the code, with modifications, must also  be  used  at  Stanford,
where things are done that way.

First load TAILOR and UPPER together.  This tells UPPER what its name
will be.  There is code in UP, before the phase,  and  to  which  the
starting address of the UPPER assembly refers, which will now perform
some contortions:

Start the resultant core image.  The code in UP will first write  out

pure segment code onto the file SAISGn.SHR ON THE  CURRENT  DIRECTORY
AREA,  notwithstanding  its  ultimate destination.  Then it will copy
LOWER.REL to SAILOW.REL  (or  whatever  FILSPC  says),  imbedding  in
SAILOW , in LOADER INTERNAL symbol format, the symbol names and upper
segment addresses for all the runtime routines and other  data  which
SAIL  programs must reference.  These symbols are taken directly from
the current core image's symbol table, which contains all the symbols
and their values, because the UPPER file was loaded with it.

SAILOW.REL   and  SAISGn.SHR  should  be  copied  to  their  intended
destinations (usually SYS).

To  create  a  core  image  which will use the shared SAISGn segment,
whether it be the compiler (see above sections)  or  a  SAIL-compiled
program,  simply  load it with the most recent SAILOW.REL as the VERY
FIRST THING (locations 140 cc.) in the core image.  SAISGn KNOWS that
certain  data  in SAILOW will be at these locations. SAILOW, in turn,
"knows", via the implanted symbols, where the  runtime  routines  for
the  SAISGn  keyed  to  it are.  Therefore, all references to runtime
routines in the files loaded after SAILOW will be  properly  resolved
to upper segment addresses.

After  loading  SAILOW, DDT can be loaded if desired, followed by any
SAIL-compiled or FAIL/MACRO/FORTRAN-processed files.   When  the  job
(which  should  have  a  SAIL  main program) is started, it will do a
GETSEG on the appropriate SAISGn.SHR, and you will be in business.

Leave old versions of SAISGn's (where the n's differ) around, so that
old  .SAV  files  will still work.   In general, you should save core
images BEFORE running them  the  first  time.   Otherwise,  you  will
probably  save  your own copy of the segment and stuff like that.  It
is not really a problem here, because our system's  different;  so  I
don't really know what problems you'll encounter.

Our  LOADER contains the /Y switch,  causing  SYS:SAILOW to be loaded
immediately after the /Y has been scanned. In addition, our CCL  will
look  for .SAI extensions on any of its inputs, and will put out a /Y
first thing (even before /D if debugging, etc.) if it sees  any.   In
the near future, we will probably remove the /Y business, and let CCL
insert the SYS:SAILOW directly-- under a previous,  more  complicated
scheme, the /Y stuff made more sense.

That  should  do  it.  The LOWER, UPPER, and TAILOR .REL files can be
deleted as soon as SAILOW and SAISGn  have  been  made  --  they  are
purely intermediate entities.

A. Getting files from MTA
 ( )1. Assemble GETSAV.MAC from paper tape.
 ( )2. Run it to get SAVE.SAV from MTA0.
 ( )3. Run SAVE, respond with "/H" to its "*" to get explanation
 ( )4. Use *.* restore mode to get rest of files 556  bpi, 7 track

B. Getting a SAIL system up
 ( )1. Load the SAIL.REL and DDT.REL provided with our LOADER
 	or with any version 52 or later LOADER with FAILSW and SAILSW
	turned on.
 ( )2. Save as SAIL.SAV or something in a convenient place.
 ( )3. Transfer LIBSAI.REL, 1OPS1.OPS, and BKTBL.BKT to SYS -- also
	SAIL, and/or FAIL, and/or LOADER, and/or DDT, if desired.

C. Changing the productions (HEL2) or built-in descriptions (FOO2)
 ( )1. Make the appropriate edits
 ( )3. Load and run PTRAN (formerly HYRS). Will REQUIRE CMDSCN.
        Command string is PROD←HEL2<cr>.
 ( )4. Load and run RTRAN (formerly HYSS). 
	Command string is RESTAB←PROD,FOO2,HEL2<cr>.
    5. Do one of parts D, E, F, or G.

D. Assembling Two-segment, no debugging compiler
 ( )1. Assemble with FAIL:
    2. Load as in part B above, but without DDT.
E. Assembling Two-segment, debugging compiler
 ( )1. Change FTDEBUG in SAIL to 1, or insert a file ahead of SAIL
 	in the command string  below (DB, say), with FTDEBUG a 1.
 ( )2. Assemble with FAIL:
    3. Load as in part B.

F. Assembling a One-segment, no debugging compiler
 ( )1. Change COM2SW to 0 in HEAD
 ( )2. Assemble with FAIL:
    3. Load as in part D.

G. Assembling a One-segment, debugging compiler
    1. Guess.
H. Assembling a great big RUNTIM.REL
 ( )1. Assemble with FAIL:
    2. Load SAIL programs with RUNTIM.

I. Creating a standard LIBSAI.REL
 ( )1. Compile and load SCISS.SAI
 ( )2. Save as SCISS.SAV
 ( )3. Edit GOGOL. Set RENSW to 0 just before the STSW(RENSW,1) in
	the early pages.
 ( )4. Run SCISS.  Reply Y<cr> to all questions.
 ( )5. After much typeout, it should report that LIBSAI.REL exists
       so put it where you like, preferably on SYS.
 ( )6. {REENT} Edit the RENSW←←0 out of GOGOL and run SCISS again
	(step 4). Rename LIBSAI.REL to HLBSAI.REL and put that on
	SYS or wherever. Be careful this step does not destroy the
	LIBSAI.REL of step 4.
    5. If you get in trouble, Appendix VI may provide some shortcuts
       for getting out of it.

J. Creating shared segments
 ( )1. Modify FILSPC to taste
 ( )5. Load TAILOR and UPPER with a SAIL-compatible LOADER
 ( )6. Run result, getting SAILOW.REL and SAISGn.SHR
 ( )7. Transfer SAILOW to SYS, SAISGn.SHR to wherever FILSPC says.

K. Running with shared segments
 ( )1. Load SAILOW.REL FIRST!!!!!
 ( )2. Load DDT and programs
 ( )3. Start job -- segment will hook up right away.

L. {REENT} Running with 2-segment programs (/H when compiling)
 ( )1. Compile with /H in command string
 ( )2. Load as usual (DO NOT LOAD SAILOW AT ALL)
    3. The HLBSAI library will provide al(most al)l high-segment


-- a definition file, defines useful macros, accumulators etc.  There
are also definitions for the "user table", the table  of  good  stuff
which  contains  the  non-reentrant  information  for  use by runtime

--  initializer  for  the compiler, command line scanner.  Almost all
the CCL code is in here.

-- The syntax interpreter, the debugging routines (for looking at the
parse stack, symbol table entries, etc.)

--  This  is the file which contains the "english" of the productions
for SAIL.  It is included in the SAIL  assembly  as  a  comment.  The
actual production  interpreter  tables  are  generated from it by the
program PTRAN, which uses this file (HEL2) as source, and  dumps  its
output into PROD.

-- Again included  in  the  assembly  as  a  comment.   This  is  the
"english" specification of the pre-defined procedures.  These are all
the procedures available at runtime.

-- Syntax tables, generated by PTRAN.

--  Reserved  word tables and pre-defined procedure tables, generated
by the program, with FOO2 as input.

--  This is the scanner.  This has the code for inputting from source
files, producing a listing, expanding  macros,  looking  up  symbols,
entering symbols, and delivering and reclaiming symbol table blocks.

-- This is the first part  of  the  generators.   Contains  code  for
initialization,  declarations,  storage allocation in object program,
inline code, syntax error messages, etc.

-- Contains generators for array references.

--   Generators  for  expressions  --  arithmetic,  string,  boolean,
assignment statements.

--    Generators   for   statements:   LOOP   constructs,   procedure
declarations, etc.

-- Generators for LEAP.

--  This  file  contains  the  generator  subroutines  used  for type
conversion,  accumulator  management,  binary  file  output,   symbol
output, and miscellaneous other things.

-- Random service routines for the compiler (e.g. some string garbage
collector goodies).


-- Contains most of  the  runtime  environment  stuff  (also  compile
time).  Core  allocation,  UUO  handler,  string  garbage  collector,
allocation (i.e. of stacks, string space) stuff.

--   Contains   most   of   the  string  handling  routines  such  as
concatenation, substring, etc.

--  Contains  runtime routines for doing I/O, array allocation, and a
few other things.

-- Runtime routines for LEAP.

-- Files used for making shareable runtime routines.

-- SAIL program for compiling syntax tables (see description below).

-- SAIL program for compiling tables for  reserved  word  definitions
and pre-declared procedure definitions.

-- Small SAIL assembly required by PTRAN and RTRAN.

-- SAIL program to write the file 1OPS1.OPS, which  contains  op-code
definitions for the inline code generators (START_CODE).


-- An assembled version of SAIL, with FTDEBUG set (i.e. you must load
it with DDT).  If you are able to assemble your own .REL of SAIL, you
can save considerable space by turning FTDEBUG off.

-- A good library file.

-- The specification file for the STDBRK function.

-- The inline code opcode table.  Make a new one with MAKTAB.SAI.


-- This is the assembler which will assemble all of the SAIL compiler
and runtime text files mentioned above. There  may  be  some  trouble
getting  this  to  run  on your system. If so, I suggest loading FAIL
with our DDT and looking around. Common problems are with the  APRENB
code.   FAIL asks for interrupts on ILL MEM REF so that it can assign
more core, link up free storage, etc.  If you  get  an  ILL  MEM  REF
message  on  your  console  while  running  FAIL, something is wrong:
either your system (this has been known to  happen  with  APRENB)  or
FAIL (there is a rumor that APRENB must be called after each trap).

-- This  loader is set up for SAIL, and contains the /Y (two segment,
see above) option.  It  can  be loaded by almost any previous loader.
If you have V52 or later, and don't need /Y, just use your own  (con-
figured for SAIL and FAIL, of course (of course!). Our  LOADER is set
up  also to provide the /B and /K features automatically, the desired
state for programs with SAIL stuff in them.

-- This is an improved DDT, and you might as well put it up  on  your
system.  There are many new features (see description below).

-- This is the cross-reference program which works for FAIL and SAIL.
(There  are  bugs  in the SAIL compiler output of CREF information --
wrong block names sometimes happen -- we will fix it sometime, but it
didn't seem like the most important thing in the world).

-- This  program creates the LIBSAI library, as described in  varying
degrees of detail in other parts of this document.

-- These programs can be convinced to process the CREF listing of the
compiler,  producing  many  interesting  documentary  summaries.  See
Appendix VI.

-- This program is applied to a SAIL listing file (with /K option) and
a  .KNT  file  created  by  a  program which was compiled using /K, as
described in NEWMAN, to create a "program profile" listing.

-- The magtape file-restoring programs, described above.

-- This represents version 3 of the SOftware UPdate system.  It is vir-
tually the same as version 2A, with some locally-produced modifications
we  hope DEC will adopt.  We will be distributing changes in SOUP form,
but your old version, if you have one, should handle them.  If not, use
this version.

The "recent changes to SAIL" manual, the complete FAIL manual, and the
complete SAIL manual -- of little use to you if you don't have a lower-
case printer, probably.  They're big, so keep them off the disk unless
you have plenty of room.

These are stored after the EOT marks on the tape.  The section on getting
started describes how to get them off.  Take a look at them if you like
and decide whether they might be useful to you.  Otherwise forget them.

A. See HEAD for complete description of conditional assembly
   switches, the macros which simplify their use, and the files
   in which they are defined.

B. See SAIL for a complete listing of FAIL commands for creating
   various kinds of compilers (slightly invalid for non-Stanford

C. See GOGOL for a complete listing of FAIL commands for creating
   various kinds of runtime routines, libraries, etc. -- also for
   the COMPIL, ENDCOM, and ORDER constructs used by SCISS -- lastly
   for the usage of the HERE macro to conveniently create the upper
   segment transfer vector (HERE may be defined in HEAD).

D. See PARSE for a complete description of the features of the 
   debugging versions of the compiler -- features generally useful
   only to the maintainers of SAIL.

E. See NEWMAN for recent changes to the language.

The program  PTRAN   expects   an   input  file  of  a  very  special
format.  The ultimate aim of this input file is to specify a sequence
of productions, but we must first specify  the  production  alphabet,
both terminal and non-terminal.

The  meta  language for specifying productions consumes a few symbols
and conventions.  First, all alphabetic characters in the input  file
must be in upper case.  The only delimiters are space and tab, so →AG
does NOT get interpreted as two separate symbols.

1.  	For  various  undisclosed  reasons,  we  must  first  provide
alternate "names" for all single-letter delimiters we may need,  such
as  (  ) } ↑ [ ], etc.  The pseudo-op <SYMBOLS> is given, followed by
pairs of

	single-letter-delimiter crazy-alternate-name

See the example below for some  instances  of  this  phenomenon.  The
crazier  the  name  the  better.   This is so that the symbols can be
included in the  scanner  table.  Note  the  interaction  with  these
aliases and the reserved word scheme. Thus ≡ which is the same as EQV
is equivalenced by this scheme.

2. 	The terminal symbols of the language are then specfied in two
groups:  first, those which the scanner  knows  about  directly,  and
second,  the group of reserved words in the language (these look like
identifiers to the  scanner,  but  you  obviously  desire  a  special
interpretation).  The  first  group  is  initiated with the pseudo-op
<TERMINALS>, and must include all the single-letter-delimiters  cited
in 1 which do not have reserved word equivalents. The second group is
started with <RESERVED-WORDS>, and  is  merely  a  list  of  all  the
reserved words you desire.

3.	The non-terminal symbols are then declared.  These are things
which you may want to put on the  stack  as  "markers"  of  partially
completed   reductions.    The  pseudo-op  <NON-TERMINAL-SYMBOLS>  is
followed by a list of such symbols.

4.	For efficiency reasons, it is helpful to  define  CLASSES  of
symbols.  Then with one production, we can determine if a whole class
of productions are applicable, and we can often avoid stating all the
productions.   To  specify  classes,  we  start  with  the  pseudo-op
<CLASSES>, and then, on a one-class-to-a-line basis, we specify:

	class-name	class-element class-element ....

where class-name must begin with a @. All of the class-elements  must
have  already  been  defined  in  2  or 3 above, and hence may not be
5.	Finally we are ready to state the productions.  We  give  the
pseudo-op <PRODUCTIONS> to start this off.  The very first production
listed will be the starting point  for  the  production  interpreter.
The  interpreter  will  start  AFTER ONE SCAN, so that the top of the
stack will already have the first "parse token" on it.

The syntax of each production is:

label:	LHS →→ RHS EXEC xxx SCAN α ¬yyy #zzz ↓↓ ↑www

This specifies a  production.   These  symbols  need  at  least  some
-- the label is the production "name". It is optional.  All labels in
        the program must be unique in their first 6 characters. There
	may not be a space between the label and the :.

-- LHS is a left-hand-side-list.  That is, a list of symbols declared
        in 2,3, or 4 above which is to be matched against the current
        top elements of the stack.

--  RHS is a right-hand-side-list.  This is the list of symbols which
        will replace the LHS on the stack if the production succeeds.

--  EXEC  specifies  that a list of execs is to be called.  The names
        you give in this list of exec  routines  should be  the names
        of the procedures that you make up in your exec routine file.

-- SCAN specifies that we are to scan before going  on  to  the  next

--  the  # ¬ ↑ and ↓↓ parts specify where "control" of the production
        interpreter is to go.

The following things are omittable:

-- the label

-- the →→ and right-hand-side-list, in which case it is assumed  that
        if  the  production  succeeds,  the  stack is restored to its
        original condition.

-- the right-hand-side-list, in which case nothing is restored to the

-- EXEC and the list of exec routines which follows it.

--  SCAN  if  you do not want to scan.  Note that SCAN α means scan α
        times before going to the success spot.

-- the #zzz, ↓↓, and/or ↑www may be omitted.
Now for the interpretation.  When the interpreter is pointed at this
production, the stack is compared  against  the  left-hand-side-list.
The  last element in this list is compared against the current top of
the stack, and so on back the list and up the  stack.   Compares  are
equal if:

-- the symbols actually match.

-- the list element in the left-hand-side is  SG,  which  stands  for
        sigma, and compares equal to anything.  SG  is  thus  a  meta
        symbol of the production compiler, and may not be used in any
        other way. In fact, any identifier beginning  with  SG  is  a
        "sigma".   For  the purposes of stack restoring, however, SG1
        matches only SG1, etc.

--  the  list element in the left-hand-side is a class symbol and the
        corresponding stack element belongs to  that  class.  If  the
        left-hand-side-list  fails  to match the top positions of the
        stack, the production interpreter sees a failure and goes  to
        another  production.  The next production is normally the one
        following the one which failed.  If you want to specify  some
        other  failure  production, the #zzz construct is used, where
        zzz is the label of the production you want to go to.

If the left-hand-side-list matches the top of the stack, then:

1. These stack elements are popped off the stack temporarily.

2. If any exec routines have been specified, these  are  called.  The
        statement  EXEC FOOBAZ causes the subroutine called FOOBAZ to
        be  called.   The  statement  EXEC  @DCL  FOOBAZ  causes  the
        following  to happen: FOOBAZ is a routine which wants to know
        some  class  information  about  one  of  the  left-hand-side
        elements.   This  element  is specified by the @DCL (this was
        the same thing that occurred on the left-hand-side). Just how
        this  class information is passed is not important here. Upon
        return from all exec routines, we continue to:

3. The stack is  then  fixed  back  up,  reflecting  any  changes  as
        specified in the right-hand-side-list.

4. The scanner is called if SCAN was specified.

5.  The  production has now "succeeded".  We must cast around for the
        next   production.    Each   production   must   have    some
        specification  of  what  to  do  on  success.   If  you  only
        specified a ¬yyy , then we do a "jump" to the production with
        label yyy. If you specified a ↑aaa and a ¬yyy , we do a "push
        jump"  to  production  aaa.   When  we   return   from   that
        "subroutine,"  we  will go to production yyy.  The "pop jump"
        is specified by ↓↓.  It makes no sense to say: ¬aaa ↓↓  since
        these  two  operations  conflict  (in fact, the pop jump will
        take precedence).
The list of productions must be followed by the pseudo-op <END>

There  is  a  facility  for  passing  class-type  information to exec
routines.   The SAIL  production  interpreter  stores  a  number   in
accumulator  number  2  before executing  the   exec routine that you
specified. This number contains the type  information you  need.  The
problem   of   interpreting   that  number  is  complicated  but  not
impossible.  The  elementary  statement  is:  the number is the index
(starting  at 0) into the line of symbols in which that class type is
declared. So if you declare the class type


and if you wrote a production


then when ENTID is called, AC 2  will contain the following numbers:

	parse token which compared
	equal to @DCL
	INTEGER					0
	REAL					1
	BOOLEAN					2
	COMPLEX					3
	STRING					4

This simple explanation breaks down when, say BOOLEAN was declared to
be a member of another class, and THAT CLASS WAS DECLARED BEFORE @DCL
WAS.  So the easy rule is: declare the classes that will be  required
to  provide  class  information  to semantic routines first, and then
those classes which are used only for parsing purposes.
III.  Pre-loaded symbol table input format (program RTRAN).

This file obeys many of the same conventions as HEL2 (no lower  case,
delimiters are only space and tab, comment operator is MUMBLE, etc.).
Don't play with <ASSIGN> or <DEFINITIONS> unless you  have  become  a
real wizard.  There isn't much content there anyway.

The functions are all listed with their parameter types.  There is no
special order, except that the first function is the default  program
block.   Hence, the default program name is M. I suggest leaving this
as is.

A function description is: (1) the first line has the  function  name
(this  is  what  will  go  out  to the loader as an external request)
followed by the value that the function returns. UNTYPE means it is a
procedure  and not a function (other types are specified by the names
of the semantic bits for them) followed by some  bits  specifying  to
the  compiler  how  to  interpret the rest of the symbol table entry.
OWN absolutely MUST be cited.  Reserved-functions  are  stored  in  a
compact  way,  and  OWN  specifes  this  special  packing.  BILTIN is
specified if the function will save accumulators (except  the  result
ac  if  any)  over the function call.  Most of these routines do save
accumulators, but for a special case, consider INPUT.   The  integers
BREAK and EOF referred to in the call on OPEN to open the channel may
be changed by a call to INPUT.  If  copies  of  these  integers  were
thought by the compiler to be in the ac's at the time, disaster would
(and did!) strike.  The last thing on the first line is the number of
parameters  to  the procedure. Then (2) come the parameters, one to a
line.  There are four elements to  a  parameter  description:  (1)  a
"type"  of  the  parameter,  an  artifact  left  over from an earlier
scheme, and ignored by RTRAN, (2) an optional comment about  what the
parameter  is -- must be a single word (no spaces or tabs) surrounded
by ( ).  Then (3,4) come the right and left halves  of  the  semantic
word  to  specify  what  type  of  parameter we have. Things here are
pretty  obvious  except  for  one  particular  feature  --  reference
parameters  may have many types.  If the routine really only needs an
address (ARRTRAN,ARRBLT, etc.) we don't care what type (INTEGER,REAL,
etc)  the parameter had.  So in this case, the actual-formal match is
made with the condition: "any bit which is on in the actual  must  be
on  in the description of the formal," with the exception that if one
is an array (SBSCRP) they both must be.


To  name  the  program,  type name$:  ($ stands for altmode).  To get
inside a "block", type blockname$& .  If you want to name a symbol in
another block without permanently entering that block (as above) type
block&symbol .

The following changes have been made to DDT:

1.   Halfword  printout  is  now  of  the  form A,,B instead of (A)B.
Either form may be used  on  input.   The  difference  is  that  A,,B
truncates A to 18 bits before swapping halves while (A)B does not.

2.  $U is a new output mode.  It is the same as $A$H.

3.   $F  mode  will  now  print normalized floating permit numbers as
decimal integers.  This means that FORTRAN users may, in general, use
$F to look at all variables and they will be printed correctly either
fixed or floating.

4.  If the address of a string of ASCIZ text is placed in $nB+3, then
whenever  breakpoint  n is reached, DDT will act as if the characters
in the string  were  being  read  from  the  teletype.   If  you  are
preparing  such a string in advance use either $ or ≠ (≠33 octal) for

5.   If a bytepointer to an asciz string is placed in $M-l, DDT  will
act  as  if  the  characters  in  the  string are being read from the

6.  $$7" <delimiter> characters <delimiter> will  act  just  like  an
asciz  statement  in  MACRO  or FAIL,i.e., more than one word will be
filled with asciz for the characters if necessary.  $$" will  have  a
similar effect but with sixbit.

7.   Typing  <number>$$P  will  cause  DDT to do an automatic proceed
<number> times instead of forever.

8.  When printing in $$S mode, no word will be printed out as  an I/O
instruction  (CONO, DATAO, CONI, etc.) unless the device number is in
a special table.  The table is 10 words long and is  in  $I-1,  $I-2,
etc.  Simply  put  device  number  here  to  have the appropriate I/O
instructions printed.

9.  If an address is placed in  $M-2  then  for  each  character  DDT
wishes  to  output,  a  pushj  1,@$M-2 will be executed.  This allows
output to be redirected to some  device  other  than  the  TTY.   The
character is in register 5.  The routine should preserve all AC's and
end with a POPJ l,.

10.  In byte mode output ($<number>0), if a size of 0  is  specified,
DDT will use a special mark in $M+2. The boundry between 1 and 0 bits
specifies the size of the bytes.  For example, a word containing

	11111111111 00000000000 11100010110001

would print 2 . 11 bit bytes, 2 3 bit bytes, 2 1 bit bytes, a  2  bit
bytes, a 3 bit byte, and a 1 bit byte.

11.   Bytes may be input of $<number>%.  This should be followed by a

by an altmode.  If number of bytes in a word is not integral the last
byte is treated as if the word were larger (bit number  greater  than
35).   This makes input compatible with output.  A size of O uses the
mark in $M+2 as above.

12.  It is now possible to print flag words and  T type  instructions
(TRNN, TLNN, etc.) with suitable names for the bit involved.  In $M+3
a pointer of the following form is placed:

			T0:	-------------
				|            |
     -------------  		|            |
$M+3 |  L1 | T0  |		| Table 0    | 
     -------------  		|            |

L1:  L2,,T1			-------------
				|            |
				| Table 1    |
				|            |

L2:  0,,T2			-------------
				|	     |                
				| Table 2    |
				|	     |                

As  many  tables as desired may be included.  The pointer to the last
table should have 0 in the left half. Each table contains  36  words.
The  nth word contains the RADIX50 for the name of bit n.  $<number>J
mode will cause a word to be printed out using the bit names in table
number.   If  an  entry  for  a  bit  is 0, the numeric value will be
printed.  A typical word might look like

foo! baz! 123,, fool! garp! 2

$J means $0J.  $nL causes the left half to be printed in symbolic and
the  right  half  to be printed in this bit mode, using the left-half
bits.  This is for printing out the instructions  like  TLNN,TLO,TLZ,
etc.   The corresponding command for TRNN,TRO,TRZ etc is $V. Needless
to say, the instructions do not have to be TRNN, TLNN etc.,  but  may
be anything.


This description attempts to give a complete description of the possible
modes of operation of SCISS.  It answers the pressing question: What happens
if I reply NO to the "STANDARD? " query.  Here's what happens --

1. Look in GOGOL for the COMMENT ⊗ORDER LOR,LUP,... ⊗ construct.  This will
   be ignored by FAIL whenever it is encountered.  However, SCISS reads it
   to find the list of all possible library entries.  It creates files of
   the form SAILOR, SAISGC, .... when operating.  The SAILOR... form is
   the one you should use in communicating with SCISS.

2. The COMPIL macro has as arguments, among others, the name of the individual
   entry (3 letters, like LOR), the list of ENTRIES to be issued when in
   LIBRARY mode, any EXTERNALS and INTERNALS to be issued, and a short 
   description.  When not in library mode,this macro simply issues the ENTRY
   and INTERNAL lists as INTERNALS, and issues the EXTERNALS.  When SCISS
   encounters it, it compares the name of the entry with the list of those
   selected to be assembled this run.  If the name matches an entry, it
   writes a file SAIccc.FAI, with all the code between the COMPIL and the
   matching ENDCOM (which expands in this case to END) in it.  COMPIL in this
   mode will expand when assembled into the appropriate ENTRYs, TITLEs, etc.
   Notice that there is a COMPIL macro for each possible library entry, and an
   entry in the ORDER list for every instance of COMPIL.  Thus the standard
   case, which uses the whole ORDER list, makes the largest possible library.

3. SCISS will ask -- DO HEAD? --If you say Yes, SAIHED.REL, with many, many
   ENTRIES will be included in the library.  These ENTRIES (and their matching
   INTERNAL symbol definitions) are used by the USERCON function.  The only
   legitimate reason for answering No to this or most other questions is to
   start in the middle after an assembly error or something (SAIHED exists,
   but is not in the library yet, something like that).

4. SCISS will ask -- DO LEAP?  --If so, SAILEP.REL will be created from
   HEAD and LEPRUN.  Otherwise SAILEP.REL will not be created this time.

5. To the question PASS 2 NOW?, respond Yes if you are running SCISS for
   only its pass 2 (copy and delete) functions -- again a start-in-middle

6. To the question LINK TO FAIL?, respond Yes if you want SYS:FAIL to be run
   after pass 1 to assemble the files (it will use nnnFAI.TMP as a command
   file, set up by SCISS).

7. To the question SELECT?, respond Yes if you want SCISS to present you
   with the list of all possible library entries to be assembled (copied)
   for your disposition.

8. To SPECIFY?, respond Yes if you want to type in those few names to be
   assembled instead.  If neither SELECT nor SPECIFY is desired, all
   (except perhaps SAILEP and SAIHED) will be assembled.

9. If SELECT was chosen, SCISS will now type the list of possible entries.
   Respond Y<cr> to retain one,
           N<cr> to leave it out,
     or    DONE<cr> to dispose of the rest as you did the last (all Y or N).

10.If SPECIFY was chosen, SCISS will ask you to type names like SAICOR,
   pausing after each for your response.
   SAISGC (from the legal list in ORDER), each on a new line, terminated
   by "DONE".

11.On pass 2, arrived at either from question 5 or by coming back from
   FAIL, more questions happen.  One is STANDARD? -- answer Yes or No, as
   usual.  If no----

12.The Question DELETE INTERMEDIATE FILES? allows you to leave the .FAI and
   .REL files around, in case the copy is not satisfactory or something.

13. If you answer No to MAKE A LIBRARY?, no copying will be done to LIBSAI,
    but deletion will be done if desired.

    SELECT or SPECIFY exactly the same things again.

14. {REENT} If RENSW was non-zero in GOGOL, you generated a library which
    the LOADER will load into the upper segment.  This library should only
    be used with /H-compiled programs (never with SAISGn, since this segment
    replaces the library completely, leaving the user's program in the low
    segment). Therefore, rename it HLBSAI.REL, and only those programs that
    want it will get it.  Override the STSW(RENSW,1) in GOGOL with a preceding
    ↓RENSW←←0 (see HEAD for definition of STSW), and run SCISS again.  This
    LIBSAI.REL should remain LIBSAI.REL, just like in the good old days.


Assemble and run to get a new copy of  1OPS1.OPS,  just  for  fun  or
because  you  changed  it.   This  file  is  needed on SYS before the
START_CODE feature will work.

C. DATALIST, EXTRACT -- hairy SAIL programs

These programs, combined with a CREF listing of the compiler, provide
a large file full of useful summations and  cross-references  to  the
code of the compiler.  Proceed in the following fashion:

1.  Make  a  listing  file  via  FAIL  of the selected version of the
compiler, starting out with
	,SAIL/C←HEAD(XLR),SAIL,....  The (XLR) is important to select
the proper listing options.

2. Assemble our version of CREF.MAC.  Load and run it, following  the
script as:

This forms one complete CREF listing, and one (CREFIL) with just  the
cross-reference tables in it.


This  SAIL  program  removes  from  the  body  of SAIL.CRF just those
portions which are useful for the remaining procedures.

4. EX DATALIST Then type P<cr> to continue.

This program uses EXTRACT (the  result  of  the  previous  step)  and
CREFIL to make a file containing:

  a. A summary of all DATA names in the compiler, along  with  their
  locations  (EDIT10  (STOPGAP)  and  CREF  numbers,  block and file

  b. A summary  of  all  the  DSCR  macro  names  (DSCR  stands  for
  DESCRIPTION,  and  is  ignored  by  FAIL),  and  their locatons --
  usually, the DSCR's describe routines.

  c. A nice listing of all the data declarations, their accompanying
  commments, etc., wherever they appear in the compiler.

  d.  An  expansion of all the DSCRS in the file, giving a standard,
  formatted description of all the major routines.

  e. An alphabetical summarized  cross-reference  of  all  the  data

  f.  An  alphabetical  summarized cross-reference of all the DSCR'd

5. After verifying that DIRECT (the result of DATALIST) is OK, delete
all intermediate files.  You'll  also  have  to  list  the  CREF,  of
course,  to  get  anything  out  of the CREF line numbers provided in

This file should be very helpful in learning some  things  about  the