perm filename TELLEM[DOC,AIL]8 blob sn#208178 filedate 1976-03-29 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00027 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002
C00004 00003	INTRODUCTION
C00005 00004	OPTIONS
C00009 00005	PARTS LIST (see appendix II for expanded explanations)
C00015 00006	REMOVING THE FILES FROM THE DISTRIBUTION TAPE
C00016 00007	INSTALLING AN INITIAL SAIL SYSTEM
C00020 00008	MODIFYING THE COMPILER
C00025 00009
C00030 00010	NON-SHARED, NO LIBRARY RUNTIME ROUTINES {BIGRUN}
C00032 00011	RUN-TIME LIBRARY {LIB}
C00039 00012	SHARED SECOND SEGMENT EXECS {TWOSEG}
C00046 00013	OPERATING WITH SHARED SEGMENTS {TWOSEG}
C00050 00014	RUNNING SAIL UNDER TENEX
C00058 00015	APPENDIX I -- SAILMAKER's CHECKLIST
C00062 00016
C00065 00017	APPENDIX II -- FILE DESCRIPTIONS
C00072 00018
C00078 00019	APPENDIX III -- REFERENCES TO OTHER USEFUL DOCUMENTATION
C00080 00020	APPENDIX IV -- THE PARSE TABLES (HEL) AND PRODUCTION COMPILER (PTRAN)
C00085 00021
C00089 00022
C00096 00023
C00099 00024	III.  Pre-loaded symbol table input format (program RTRAN).
C00107 00025	APPENDIX V -- DDT
C00114 00026	APPENDIX VI -- ADDITIONAL SUPPORT SOFTWARE -- SCISS, MAKTAB
C00124 00027	APPENDIX VII.  HOW THE "EXPORT" SAIL IS PUT TOGETHER AND A FINAL NOTE
C00128 ENDMK
C⊗;






















	SAILMAKERS GUIDE










				Bob Sproull
				October 1970
				Revised May 1971 by D. Swinehart
				Revised September 1971 by D. Swinehart
				Revised Jan 1973 by D. Swinehart and J. Low
				Revised May 1973 by R. Taylor
				Revised June 1973 by H. Samet 
				Revised October 1975 by J. Reiser
				Revised November 1975 by R. Smith


INTRODUCTION

This document describes the various parts of the SAIL system, and how
they  might  be  combined.    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.
OPTIONS

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:

TENEX -- for operating under the TENEX timesharing system,  a differ-
     ent assembly process altogether is required.  If you have TENEX,
     skip to the section on TENEX below.

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

LIB  --  describes the process for creating the LIBSAn 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 (HLBSAn) that goes with such programs.

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

GLOB, NOGLOB & GLOC,  NOGLOC  &  STANFO-NOSTANFO --  These   refer to
     differences between SAIL as it exists at Stanford & as it exists
     elsewhere.   These  differences  include  a  slightly  different
     interface  to  the (non-DEC-standard) Stanford operating system,
     and to the Stanford "global model", which requires special  UUOs
     found  only at Stanford.  In times past, the export sources were
     modified to omit Stanford-only features.  In accordance  with  a
     new  file  maintainence  policy,  they  are being left in.  They
     certainly will not work on a regular DEC or TENEX system, and we
     make no promises, either implicit or explicit, to those who feel
     like monkeying around with them.  To avoid problems,  leave  the
     switch  STANSW  set  to  0  in  file HEAD (and don't go changing
     GLOCSW or GLOBSW).

When these tags appear, they will be between braces ({}) in the text.

PARTS LIST (see appendix II for expanded explanations)

A  Files needed to get initial compiler and operating system going
   FILES (list of files in order on tape)
   TELLEM (this listing)
   SAIL.REL
   DDT.REL (currently can't use any configuration of DEC's DDT)
   LIBSAn.REL (n, a digit.Library of runtime routines for transfer to SYS:)
   BKTBL.BKT (needs to be on SYS when STDBRK is called)
   2OPS2.OPS (START_CODE opcode table, created by compiling and
		running MAKTAB)
   PROCES.DEF (a collection of SAIL macros for use with processes)
   RECORD.DEF (a collection of SAIL declarations for use with records)
   GOGTAB.DEF (a collection of SAIL macros that define user table indices).

B. Source files for SAIL compiler and execs(runtimes)
   HEAD

E. Files to build parser tables (FAIL files for inclusion in SAIL)
   FOO2
   HEL
   PROD.QQQ (output of PTRAN, input is HEL)
   FOO2.TNX		(TENEX-only)

F. Source files for SAIL compiler
   SAIL
   PARSE
   (HEL, FOO2 as comments)
   PROD (output of PTRAN, input is HEL)
   DATA (if reentrant compiler)
   RESTAB (output of RTRAN, input is PROD and FOO2)
   ENDDAT (if reentrant compiler)
   SYM
   GEN
   ARRAY
   EXPRS
   STATS
   LEAP
   TOTAL
   PROCSS 
   COMSER
   XTCHDR (for use if you want a reentrant compiler that supports /X)

also, for TENEX, you will need:
   TENXSW
   DEFJS
   JSYSES
   CC
   DATA
   RESTAB.TNX
   ENDDAT


G. Source files for Runtime routines
   GOGOL
   TRIGS
   STRSER
   IOSER
   ARYSER
   RECSER
   TRIGS {LIB}
   UP {TWOSEG}
   LOW {TWOSEG}
   TAILOR {TWOSEG}
   LEPRUN
   WRDGET
   NWORLD
   SPARES
   ORDER {LIB}


   also, for TENEX only, you will need:

   TENXSW
   DEFJS
   JSYSES
   UP.TNX
   CALL.TNX
   IOSER.TNX
   LOW.TNX
   WNTHED
   TRIG1.TNX
   TRIG2.TNX
   WNTEND
   3OPS3.OPS

G' Source files for BAIL (a debugger for SAIL)
   BAIL.SAI
   BPDAHD.FAI (header file)
   BSM1HD.FAI (header file)
   BAILDD.FAI (for setting up .JBDDT at load time; assemble and put on the
	back of BAIL.REL with FUDGE2)

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 HEL)
   RTRAN.SAI (creates FAIL-readable symbol table (reserved words) from FOO2)
    (above previously HYSS and HYRS, respectively)
   SCNCMD.SAI (gets REQUIRED as a source file by PTRAN and RTRAN)
   WNTSLS.SAI (gets REQUIRED as a source file by PTRAN and RTRAN)
   MAKTAB.SAI (creates 2OPS2.OPS)
   MAKTAB.TNX  (TENEX-only for START!CODE table)

I. Other useful files
   PROFIL.SAI -- This program lists the .KNT file and .LST file, giving a
   nice frequency profile of statement execution (See /K Switch in manual)
   LOADER.MAC (our LOADER)
   FAIL.FAI
   DDT.FAI (our slightly modified version -- block structure)
   CREF.MAC (modified for block structure)
   SCISS.SAI (makes a a library, two-segment HLBSAn {REENT} or one-segment
	LIBSAn. Uses the file ORDER as input with other exec sources)
   FAIL.PMP -- FAIL assembler manual (large)
   SAIL.KVL-- SAIL manual -- (very large)

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.
   ARRSER,EXTEND,SRTSER,SYMSER,LP4MAT,LPDUMP,LPREAD,
   CONST.HDR,CONST.SAI,MUNGE.SAI,IOMODS.SAI
   ABBREV.SAI,MACROS.SAI,LEPAUX.SAI,LEPAUX.HDR
   SPACE.HDR,SPACE.FAI,IOMOD.HDR,IOMOD.SAI

REMOVING THE FILES FROM THE DISTRIBUTION TAPE

A.DECTAPE

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. Magnetic Tape, 7 track only

Use FAILSAFE
INSTALLING AN INITIAL SAIL SYSTEM

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,
and the library (LIBSAn), with the /B loader switch, using version 54
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 which runs without DDT.

The  file  LIBSAn.REL  is  the  library  which  is  REQUIREd  by  all
SAIL-compiled programs.   The LOADER will look on device SYS for this
file, and will not really let you  go on until such a file is  found.
The version of LIBSAn 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

	X	SAIL,SAI,SAIL

in  the  PROCESS  macro  in  COMPIL.MAC  (DEC  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  2OPS2.OPS
and  BKTBL.BKT  to  SYS.   Always  load  SAIL-compiled  programs with
version  54  of  the  LOADER  or  later (LOADER 52 may be used if the
compiler is reassembled with the  LOADVR  switch  in  file  SAIL  set
to =52), with SAILSW and FAILSW  turned  on (or  ours, which  has its
points), and always use our DDT.

Loaders: Stanford does have LINK-10 and a  few people use it; several
patches   were  needed  to   make  the   DEC-supplied  version  work,
particularly with  polish  fixups and  externals.   Current  Stanford
LOADER seems  to be compatible with  DEC LOADER version 54  or later.
Stanford LOADER automatically does /B/K.  It also recognizes /Y as an
abbreviation  for  SYS:SAILOW, to  make  operating  with  the  shared
runtime segment more convenient.  The loader will sort the DDT symbol
table if /?  is specified.   The symbol  table is also  sorted if  /V
(abbreviation for SYS:RAID) is used.

DDT: Stanford  DDT and RAID  support block-structured  symbol tables.
They operate  with a special sorted symbol  table which cuts the time
for symbolic typeout.  RAID  requires the symbol table to be  sorted,
and  will do  the  sorting itself  if  the loader  has  not done  it
already.  DDT operates with whatever table (sorted or unsorted) it is
given.
MODIFYING THE COMPILER

The comments which accompany the source  files are  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, then you need only reassemble
   and reload.

  The  configuration  of  the compiler  when  it  is  running  (i.e.,
  sharable  or  not,  using SAISGn  or  not,  designed to  facilitate
  debugging or not) determines the assembly and loading procedure.

    1.   The switch  FTDEBUG (0  or 1  only) controls  code which  is
      intended to help debug the compiler itself.  The usual practice
      is to make one compiler with FTDEBUG←←0 and put it on SYS, then
      make  another   with  FTDEBUG←←1   and  keep   it  around   for
      emergencies.   Both versions are  loaded with DDT  and symbols.
      In the case FTDEBUG←←1, DDT stays around all the time.  In case
      FTDEBUG←←0, the  locations containing DDT  and its symbols  are
      ordinarily  reused  by the  symbol  table  for  SAIL. (This  is
      controlled by what the compiler  sees in location '137 when  it
      is started.)  Thus  the compiler  can still  be easily  patched
      without incurring a space penalty during compilation.

    2. The  compiler uses some  of the  runtime routines to  optimize
      constant expressions; in STR←"A"&"B" the  concatenation is done
      at  compile-time using  CAT, the  same  routine which  would be
      called at  runtime if  the statement  were STR←U&V  .   If  you
      already  execute  programs  with  SAISGn  (the  shared  runtime
      segment)  then it  is reasonable for  the compiler  to use this
      segment, too.  In this case the compiler must be assembled with
      RENCSW←←0; when compiling you  will have a 13K SAISGn upper and
      a 34K compiler lower (after DDT is wiped out).

    3. The compiler itself can be made reentrant by setting RENCSW←←1
      and loading  with  HLBSAn (the  library in  which  most of  the
      runtime  routines  have  been  assembled  to  run at  addressed
      greater than '400000).   You  will get  a 28K upper  and a  18K
      lower.   This configuration  will save disk  space when  the /X
      save-and-continue  feature is  used, since under  /X the entire
      lower segment must be saved.   Of course it also saves  core if
      two  jobs are  compiling,  but there  can be  a  trade-off with
      SAISGn use by programs, since runtimes like CAT will be in both
      the compiler and in SAISGn.

See the checklist appendix for exact commands to produce the version
which you want.



B. Changes to HEL (parse table) or FOO2 (built-in procedures)

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

  1.  PTRAN --  Production Translator (see Appendix IV)  This program
    takes the  pseudo Floyd-Evans productions  found in file  HEL (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.

    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←HEL<cr>.   When  another  `*'  appears,  PROD  and
    PROD.QQQ have  been created.   PROD  is the  parse table  (HEL 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<cr>.  The resultant RESTAB is the initial symbol
    table, expressed in FAIL.  (See the appendix for use of RTRAN  by
    BAIL.)

  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.


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 in runtimes (standard), off
  otherwise.

  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 HLBSAn 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
  UUO.

  LOADVR -- the decimal value of the loader version to be  used;  =52
  or >=52, typically - loader block type problems.  (Hopefully this
  is now obsolete because everybody agrees on the block types.)

NON-SHARED, NO LIBRARY RUNTIME ROUTINES {BIGRUN}

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

RUNTIM←HEAD,GOGOL,TRIGS,STRSER,IOSER,ARYSER,RECSER,NWORLD,LEPRUN,
	 WRDGET,SPARES

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, 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 13K long.
RUN-TIME LIBRARY {LIB}

The  obvious  solution  to  the  large  execution  package  has  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).  (If  the
universal file  HDRFIL.FUN produced  by FAIL is  still around  from a
previous run and HEAD and GOGOL have not been modified since, then no
HDRFIL.FAI is produced.) Then it writes one FAIL source file for each
desired  library entry,  extracting  its code  from  the file  GOGOL,
STRSER, or IOSER etc.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.  The file
ORDER contains  the correspondence  between library  entries and  the
source files as well as "n" the version of the library.

FAIL assembles  all  the little  FAIL files  into  little .REL  files
(using HDRFIL.FUN  to save assembly time), and  chains back to SCISS,
this time in  CCL mode,  thus indicating pass  2.  On  pass 2,  SCISS
copies all the .REL files into LIBSAn.REL, removing local symbols and
cleaning  things up.   All the  FAIL and  .REL files,  along with the
HDRFIL.FAI and CCL files, are deleted if desired.

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


Read  into  GOGOL,  looking  for the COMPILE macro, the ENDCOM macro.
Also  look  at the file ORDER.  These should give 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.   It will read the file  ORDER (from the current  area) as
input. 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 LIBSAn.REL  exists  for the
using.  Put  this library  onto whatever area  you intend  to use  it
from.   Also,  SCISS  will  have  created a  file  GOGTAB.DEF,  which
contains  macro definitions  for indices  into  the SAIL  user table.
This file should similarly be  put wherever you intend to REQUIRE  it
from.   Several of the  SAIL programs supplied with  the distribution
tape    (notably,   BAIL.SAI)    include   the    statement   REQUIRE
"SYS:GOGTAB.DEF"  SOURCE!FILE.   If  you  decide  to  put  GOGTAB.DEF
somewhere else, you will have to modify this appropriately.

{REENT}
Use  an  option  of  SCISS (see appendix VI) to  get the high segment
library (HLBSAn). Programs compiled with /H will use HLBSAn -- others
will  use  the  shared  segment  (see {TWOSEG} below) or LIBSAn.  You
should  create  only  a  LIBSAn  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.
SHARED SECOND SEGMENT EXECS {TWOSEG}

This option  represents the  latest step  in the  evolution of  these
things. In this version, we are back to the 13K 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 minimizes this possibility of dissynchroni-
zation.

To create one of these clever beasts, first look at the file HEAD. In
HEAD, you will find several pages  that used to be called FILSPC  and
that contain  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  the  FILSPC  part  of  HEAD  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 string:

LOWER←HEAD,LOW,GOGOL,STRSER,IOSER,ARYSER,RECSER,NWORLD

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.

Now use FAIL to assemble:

TAILOR←HEAD,TAILOR

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←HEAD,UP,ORDER,GOGOL,STRSER,IOSER,ARYSER,RECSER,NWORLD,LEPRUN,
	 WRDGET,SPARES

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 with global symbols (remember to
include a  /B in the command string). 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).
OPERATING WITH SHARED SEGMENTS {TWOSEG}

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.
RUNNING SAIL UNDER TENEX

TENEX is another timesharing  system for the PDP10.   This section is
of little  use to you unless you are running  TENEX.  It assumes some
knowledge of TENEX.

Since TENEX offers  a compatibility package under which  DEC programs
may be run, it is possible to run DEC-SAIL under TENEX pretty much as
described in the rest of this document.  However, SAIL offers a TENEX
conditional compilation  feature, and  the TENEX version  offers some
strong features, including: (1) runs without the emulator; (2) offers
complete TENEX-oriented  I/O; (3) has  pseudo-interrupts, random  I/O
and many  TENEX runtimes; (4) offers  a 3 segment  runtime system for
additional code sharing.

Most TENEX sites  that have been interested  in SAIL are also  on the
ARPANET.   It is quite simple  to FTP a set of  .SAV files from SUMEX
and the current version will be found on directory <XSAIL> at SUMEX.

We now describe how to recreate a TENEX SAIL system from the sources.
Most of  the files  that are involved  in the  DEC assembly are  also
involved in the TENEX assembly.  A few files were added, particularly
for I/O and for the bootstraps.

MAKING A SEGMENT.  On  TENEX, only a segment is used  for the runtime
routines.  The  library contains only a few things.  The segment runs
at core address 640000,  making it possible  for shared user code  to
run at 400000.  This increases memory sharing.

To create a segment, you need to do the following FAIL assemblies:

UPPER←TENXSW,DEFJS,JSYSES,HEAD,UP.TNX,GOGOL,CALL.TNX,STRSER,IOSER.TNX,
	ARYSER,RECSER,NWORLD,LEPRUN,WRDGET,SPARES
LOWER←TENXSW,DEFJS,JSYSES,HEAD,LOW.TNX,GOGOL

As can be  seen, these are  the same files  as for the  DEC assembly,
except  the files that  end with .TNX  and the  TENXSW, DEFJS, JSYSES
files, which are peculiar to TENEX.

The  assembly produces  files  LOWER.REL  and UPPER.REL.    UPPER.REL
should then  be loaded and run.  It will ask  you for the name of the
shared segment, printing out the name it expects, something like:

T-5-SAISG8.SAV

Type in the same  name, terminating with a carriage return.   When it
exits,  you   will  have  2  files:  LOWTSA.REL  and  T-5-SAISG8.SAV.
LOWTSA.REL  goes  on  directory   <SUBSYS>  and  T-5-SAISG8.SAV   (or
whatever) goes on  directory <SAIL>.  It is necessary  to have access
to <SUBSYS> and a directory <SAIL> to complete the creation of a SAIL
system.

Next, one assembles  a compiler.  First,  one needs to run  PTRAN and
RTRAN  to create the production  and reserved word tables.   The PROD
and RESTAB.TNX files supplied are for the standard case.  (See page 9
`∂r  details about  creating new  PROD and  RESTAB files  should this
become necessary.) RESTAB.TNX is created using FOO2.TNX.

SAIL←TENXSW,DEFJS,JSYSES,HEAD,SAIL,CC,PARSE,PROD,DATA,RESTAB.TNX,ENDDAT,
	SYM,GEN,ARRAY,EXPRS,STATS,LEAP,TOTAL,PROCSS,COMSER

Here, the TENEX-specific files are TENXSW,DEFJS,JSYSES,CC, and RESTAB.TNX.
After assembly, the using should load with the command:

@LOADER
*LOWTSA,/SSAIL$

After loading has finished, the core image should be STARTed and then
SSAVEd as <SUBSYS>SAIL.SAV.   Starting it gets the assembly date into
the banner line.

The TENEX libraries only contain the  trigonometric routines plus the
HEAD  symbols.   The main  runtime  routines are  all in  the runtime
segment.  To create a library, the following two FAIL  assemblies are
needed:

HEAD←WNTHED,TENXSW,HEAD

and

TRIGS←TRIG1.TNX,TENXSW,DEFJS,JSYSES,HEAD,TRIG2.TNX,TRIGS,WNTEND

This produces  two files, HEAD.REL  and TRIGS.REL.   Concatenate them
together into a file called HLBSA8.REL and a similar file LIBSA8.REL.
The TENEX commands to do this are:

@copy head.rel,trigs.rel (to)  LIBSA8.REL  [New file]

@copy head.rel,trigs.rel (to)  HLBSA8.REL  [New file]

These files should then remain on directory <SAIL>.

The file  3OPS3.OPS contains the  START!CODE symbol  table, including
jsyses.  This should  be put on directory <SAIL>.  A new symbol table
can be created  using MAKTAB.TNX, which  reads the  STENEX file on  a
given system to  incorporate those jsys'es available  on that system.
3OPS3.OPS  is a SSAVEd file that the  compiler reads into memory when
it encounters the START!CODE or QUICK!CODE reserved word.

Also,  one can  put the  file  UDDT.SAV onto  directory  <SAIL>.   It
contains a special version of TENEX UDDT with single stepping.

OTHER SAIL FEATURES UNDER  TENEX.  Most other SAIL  features, such as
BAIL and PROFIL, will now work under TENEX, either in the same way as
under the DEC system, or  via conditional compilation.  For  example,
the BKTBL.BKT file that contains  the standard breaktables can now be
moved to  directory SAIL, and the PROFIL program works the same under
TENEX.  BAIL must be assembled with a TENEX switch  turned on, but it
works somewhat better  under TENEX than under DEC,  owing to the fact
that TENEX has pseudo-interrupts, and BAIL uses one for  interrupting
a running program.
APPENDIX I -- SAILMAKER's CHECKLIST

A. Getting files from MTA
 ( )1. Use FAILSAFE.

B. Getting a SAIL system up
 ( )1. Load the SAIL.REL,/BDDT.REL,/LLIBSAn provided with our LOADER
 	or with any version 54 or later LOADER with FAILSW and SAILSW
	turned on.
 ( )2. Save as SAIL.SAV or something in a convenient place.
 ( )3. Transfer LIBSAn.REL, 2OPS2.OPS, PROCES.DEF, GOGTAB.DEF, RECORD.DEF,
	and BKTBL.BKT to SYS -- also SAIL, and/or FAIL, and/or LOADER, 
	and/or DDT, if desired. (The .DEF files are somewhat optional,
        but recommended).

C. Changing the productions (HEL) or built-in descriptions (FOO2)
 ( )1. Make the appropriate edits
 ( )2. Compile PTRAN.SAI, RTRAN.SAI (require SCNCMD,WNTSLS as source
					files)
 ( )3. Load and run PTRAN
        Command string is PROD←HEL<cr>.
 ( )4. Load and run RTRAN
	Command string is RESTAB←PROD,FOO2<cr>.
 ( )5. Reassemble and reload the compiler (see below).

D. Producing a reentrant compiler
 ( )1. Create a file RENCSW with RENCSW←←1 and assemble with FAIL
    SAIL←RENCSW,HEAD,SAIL,PARSE,HEL,FOO2,PROD,DATA,RESTAB,ENDDAT,SYM,GEN,
	ARRAY,EXPRS,STATS,LEAP,TOTAL,PROCSS,COMSER
 ( )2. Run SCISS to generate the file SAILOR.FAI from GOGOL (or extract it
	some other way) and then assemble with FAIL
    XTCLOR←XTCHDR,SAILOR
 ( )3. Load
     ( )a. LOADER
	SAIL/S/B,XTCLOR,HLBSAn/L,DDT$
     ( )b. LINK-10
	=SAIL/LOCALS,XTCLOR,HLBSAn/SEARCH,DDT/GO
 ( )4. START and SSAVE as SYS:SAIL.

E. Producing a compiler which uses SAISGn
 ( )1. Assemble with FAIL
    SAIL←HEAD,SAIL,PARSE,HEL,FOO2,PROD,RESTAB,SYM,GEN,ARRAY,EXPRS,
	STATS,LEAP,TOTAL,PROCSS,COMSER
 ( )2. Load
     ( )a. LOADER
	SYS:SAILOW,DSK:SAIL/S/B,DDT$
     ( )b. LINK-10
	=SYS:SAILOW,DSK:SAIL/LOCALS,DDT/GO

F. Producing a compiler with internal debugging aids
 ( )1. Create a file DB containing FTDEBUG←←1 and assemble with FAIL
    SAIL←DB,HEAD,SAIL,PARSE,HEL,FOO2,PROD,RESTAB,SYM,GEN,ARRAY,EXPRS,
	STATS,LEAP,TOTAL,PROCSS,COMSER
 ( )2. Load
     ( )a. LOADER
	SYS:SAILOW,DSK:SAIL/S/B,DDT$
     ( )b. LINK-10
	=SYS:SAILOW,DSK:SAIL/LOCALS,DDT/GO

G. Assembling a great big RUNTIM.REL
 ( )1. Assemble with FAIL:
  RUNTIM←HEAD,GOGOL,TRIGS,STRSER,IOSER,
		ARYSER,RECSER,NWORLD,LEPRUN,WRDGET,SPARES
 ( )2. Load SAIL programs with RUNTIM.

H. Creating a standard LIBSAn.REL
 ( )1. Compile and load SCISS.SAI
 ( )2. Save as SCISS.SAV
 ( )4. Run SCISS.  Reply Y<cr> to all questions.
 ( )5. After much typeout, it should report that LIBSAn.REL exists
       so put it where you like, preferably on SYS.  Put GOGTAB.DEF
       in the same place.
 ( )6. {REENT}For creation of HLBSAn  see Appendix VI
 ( )7. If you get in trouble, Appendix VI may provide some shortcuts
       for getting out of it.

I. Creating shared runtime segment SAISGn
 ( )1. Modify FILSPC parts of HEAD to taste
 ( )2. Assemble LOWER←HEAD,LOW,GOGOL,STRSER,IOSER,ARYSER,RECSER,NWORLD
 ( )3. Assemble TAILOR←HEAD,TAILOR
 ( )4. Assemble UPPER←HEAD,UP,GOGOL,STRSER,IOSER,ARYSER,RECSER,
					NWORLD,LEPRUN,WRDGET,SPARES
 ( )5. Load TAILOR and UPPER with a SAIL-compatible LOADER
		(include /B in the command string)
 ( )6. Run result, getting SAILOW.REL and SAISGn.SHR
 ( )7. Transfer SAILOW to SYS, SAISGn.SHR to wherever FILSPC says.

J. Running with shared runtime segment SAISGn
 ( )1. Load SAILOW.REL FIRST!!!!!
 ( )2. Load DDT and programs
 ( )3. Save core image if you want.
 ( )4. Start job -- segment will hook up right away.

K. {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 HLBSAn library will provide al(most al)l high-segment
	routines.


APPENDIX II -- FILE DESCRIPTIONS

A. SAIL COMPILER:

HEAD -- 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
routines.   NOTE:  This  is  the file  that  contains  all the  "site
configuration" switch settings.

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

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

HEL  --  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 (HEL) as source, and
dumps its output into PROD.

FOO2 -- 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.

PROD -- Syntax tables, generated by PTRAN.

DATA -- A call to the DATA macro, to put the predeclared symbol table
in  the  low segment.    The  table is  not  reentrant  because fixup
information is modified during compilation (sigh).

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

ENDDAT -- A call on the ENDDATA macro. See DATA.
SYM -- 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.

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

ARRAY -- Contains generators for array references.

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

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

LEAP -- Generators for LEAP, backtracking and procedure items.

PROCSS -- Generators for process,coroutine, event constructs.

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

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


SAIL RUNTIME:

GOGOL -- 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.

TRIGS  -- Contains trigonometric functions (SIN,   COS,  etc.) and an
interrupt routine for processing floating underflow.

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

IOSER -- Contains runtime routines for doing I/O a few other things.

ARYSER  -- Contains  runtime routines  for doing  array  allocation &
deallocation, run time "go to solving", and the apply construct.

RECSER -- Contains runtime routines for records & references.  

NWORLD -- Contains runtime routines for process handling

LEPRUN -- Runtime routines for LEAP.

WRDGET -- Contains one-word,two-word and string descriptor providers,
as well as REMEMBER, FORGET and RESTORE routines.

SPARES --  Contains the END  statement.  Also,   contains  spare HERE
table entries which may be used to add additional runtime routines to
the segment.

UP, LOW, TAILOR -- Files used for making sharable runtime routines.



BAIL

BAIL.SAI -- Source for the debugger.

BPDAHD.FAI  and BSM1HD.FAI  --  header files  for  making the  SAISGn
runtimes known to BAIL.  See page 4 of BAIL.SAI for how to use these.

BAILDD.FAI -- for setting up .JBDDT at load time.  Assemble and put
on the back of BAIL.REL using FUDGE2.

SAIL SERVICE:

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

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

SCNCMD,WNTSLS
-- SAIL source files required by PTRAN and RTRAN.

MAKTAB.SAI
-- SAIL program to write the file 2OPS2.OPS, which  contains  op-code
definitions for the inline code generators (START_CODE).


NON-TEXT FILES -- TO HELP YOU GET SAIL UP FAST:

SAIL.REL
-- 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.

LIBSAn.REL
-- A good library file.

BKTBL.BKT
-- The specification file for the STDBRK function.

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

PROCES.DEF
-- A set of useful macros which a multiple process programmer may
require as a source file.

OTHER SYSTEM PROGRAMS:

FAIL and FAIL.REL
-- 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).

LOADER
-- 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.

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

CREF.MAC
-- 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 may fix it sometime, but it
didn't seem like the most important thing in the world, also conditional
compilation is known to put out incorrect listing files).


SCISS.SAI
-- This  program creates the LIBSAn and HLBSAn libraries, as described
in  varying degrees of detail in other parts of this document.

PROFIL.SAI
-- 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 the SAIL manual, to create a "program profile" listing.

FAIL.PMP, SAIL.KVL
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.

OTHERS
Take a  look at them  if you  like and decide  whether they might  be
useful to you.  Otherwise forget them.
APPENDIX III -- REFERENCES TO OTHER USEFUL DOCUMENTATION

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 GOGOL for a listing of 
   the COMPIL, ENDCOM, and ORDER constructs used by SCISS -- and
   for the usage of the HERE macro to conveniently create the upper
   segment transfer vector (HERE may be defined in HEAD).

C. 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.

D. See SAIL.UPD for recent changes to the language.

APPENDIX IV -- THE PARSE TABLES (HEL) AND PRODUCTION COMPILER (PTRAN)

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 has a few
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 specified 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 or a previously defined
class-name. Note that two classes are predeclared. These are RESERVED 
which contains all the reserved words and TERMINAL which contains all
the terminal symbols.  

Corresponding to each class there is a bit which tells whether or not
a  symbol is a  member of the  class.  Each  symbol has  two words to
store these bits, so there can be at most 72 classes.  At  last count
there were already  72 classes in use by the  compiler, so you cannot
create any new classes unless you are a real wizard.

5.	Finally we are ready to state the productions.  We  give  the
pseudo-op  <PRODUCTIONS>  to  start  this off.  The name of the first
production is  BB0  (this  may be changed by altering the contents of
the cell PRODGO in file PARSE).

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
explanation:
-- 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 :.
	(If you plan to use the debugger (FTDEBUG← 1) it is advisable
	 to  have  only  3  character  label  names to avoid spurious
	 production breaks).

-- 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
        production.

--  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
        stack.

-- 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  away from  the top  of 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).   (This  is
       explained further in an example on the next page.) 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).

6.  An  extension  has been made to production language to enable the 
implementation  of conditional compilation in SAIL.  This consists of 
maintaining  two  parser stacks.  When certain reserved words such as
IFC  are seen a "push jump" is done to a production which is accessed
by  an  index  to a table via the left hand entry of the words symbol
table  semantic  entry.  Parsing  then  continues in a coroutine-like
manner. The  PRESUME  construct has been added to production language
to  facilitate  a change in the current parser stack from conditional
compilation  to  SAIL-like  compilation.  Coroutine-like parser stack
switches  from  SAIL  to conditional compilation is done when certain
reserved  words  are  seen  such  as ELSEC.  A PRESUME followed by ↓↓
indicates that the conditional compilation process is finished.  Also
note  that  when DEFINE is seen, it is treated in the same way as IFC
with  the  exception  that  there is no need for an additional stack.  
If  you  do  not  understand  all  this  don't worry, you are in good 
company.

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

	@DCL INTEGER REAL BOOLEAN COMPLEX STRING

and if you wrote a production

%CON:	@DCL IDENT , →→ @DCL	EXEC @DCL ENTID SCAN 2	¬%CON

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.

Numerical parameters can also be passed to exec routines.  This is 
done in the same manner as parsing class-type information.  The only 
difference being that the @ symbol is followed by an integer instead 
of a class name.  
III.  Pre-loaded symbol table input format (program RTRAN).

This file obeys many  of the same conventions as HEL  (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 specifies  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 bit name "FNYNAM" is used if the function is
to  be known  as  FCN  to  the  compiler (and  hence  in  the  users'
programs), but as FCN$ to  the loader.  This feature is used for some
of the  numerical routines,  in order  to avoid  conflict with  LIB40
names. The  last three  things on the  first line  are the number  of
parameters  to the procedure,  the number of  value string parameters
(BAIL needs  to  know  how may  things  go  on the  string  stack  at
runtime), and which .SM1 file the procedure should go in for BAIL.
   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.  There  is one other feature that may be useful.   If a
"$" is placed before field (3), then the parameter may be "defaulted"
to its null value  (i.e., integers to zero,  itemvars to ANY etc)  if
the  actual  call omits  this  actual  parameter.   Such  defaultable
parameters  must come  at the end  of the  argument list  and must be
value parameters.

Side effect of RTRAN:  This program also generates several  files for
BAIL: BAICLC.FAI, BAIIO1.FAI, BAIIO2.FAI, BAIMSC.FAI, BAIPRC.FAI (all
containing  procedure  descriptors  for  predeclared  runtimes)   and
BAISM1.FAI (a program which will create the corresponding
.SM1 files).

To complete the generation of the files needed by BAIL:
	.R FAIL
	*BAICLC←BPDAHD,BAICLC   ;the   files   containing   procedure
	*BAIIO1←BPDAHD,BAIIO1	;  descriptors
	*BAIIO2←BPDAHD,BAIIO2
	*BAIMSC←BPDAHD,BAIMSD
	*BAIPRC←BPDAHD,BAIPRC
	
	*BAISM1←BSM1HD,BAISM1	;the program  to  construct  the  .SM1
				;  files

	*BAIPDn←BAIPDn		;does a .LOAD on all the procedure
				; files
	*↑C
	.R LOADER
	*/E BAISM1$

Now   transfer   the   files  BAICLC.REL,   BAICLC.SM1,   BAIIO1.REL,
BAIIO1.SM1,   BAIIO2.REL,    BAIIO2.SM1,   BAIMSC.REL,    BAIMSC.SM1,
BAIPRC.REL,  BAIPRC.SM1  and  BAIPD8.REL onto  SYS:  (or  <SAIL>  for
TENEX).   The reason things are  split up this way  is so that people
concerned with the  size of their core  image can explicitly  require
only the group of procedure  descriptors that they want, e.g. REQUIRE
"SYS:BAICLC" LOAD!MODULE; and do not use /20B when compiling.
APPENDIX V -- DDT

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
altmode.

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

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 1,.

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  two 11-bit bytes,  two 3-bit bytes,  two 1-bit  bytes, a
2-bit byte, 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 0 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.
APPENDIX VI -- ADDITIONAL SUPPORT SOFTWARE -- SCISS, MAKTAB

A. SCISS

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  N  to  the  "STANDARD?  "  query.
Here's what happens --

1. The file ORDER consists of a comment (thus ignored by FAIL) of the
form:
	COMMENT ⊗
	NAM,5
	ALL,HEAD,!GOGOL
	HDR, GOGOL
	LOR,LUP,KNT...
	...
	⊗ 
SCISS   reads  it  to  find  the  version  number  of   the   library
(the digit following "NAM," and 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.

NOTE:  if  you  change  the version number of the library, be sure to
also change the library names  accordingly  in  FILSPC  so  that  the
compiler will generate library request for the current version of the
library.

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 the question "STANDARD?" before PASS 1  and  before
PASS2  (unless  PASS  1  was totally suppressed). To get the standard
LIBSAn simply reply Y<cr> to both questions. Otherwise type N<cr> and
then you will get a list of options.

PASS 1

	1 PASS 2 NOW
	2 DON'T CHAIN TO FAIL
	3 DON'T CREATE INTERMEDIATE FILES
	4 MAKE REENTRANT LIBRARY
	5 SELECT ENTRIES FROM PROMPT-LIST
	6 SPECIFY ENTRIES EXPLICITLY
	7 DON'T DELETE INTERMEDIATE FILES (PASS 2)
	8 DON'T MAKE A LIBRARY(PASS 2)

Type the indices of those options you wish to invoke:

1. PASS 2 NOW means don't create the SAIxxx.FAI files or  call  FAIL.
This makes sense only if SCISS has been run before and the SAIxxx.REL
files still exist. This option will cause the  copying  of  the  .REL
files  (which  ones,  may be specified by invoking options 5 or 6) to
form a library (unless inhibited by option 8) and then  deleting  the
.FAI  and .REL files (unless inhibited by option 7). The library will
be named HLBSAn if option 4 is requested (The .REL files should  have
been  created  by  running  SCISS  with a REENTRANT library requested
during the first pass).

2. DON'T CHAIN TO FAIL  means  just  create  the  .FAI  files.  Don't
assemble them.

3. DON'T CREATE INTERMEDIATE FILES.  Don't  create the .FAI files but
unless inhibited assemble the .FAI files generated previously.

4. MAKE REENTRANT LIBRARY means to make a HLBSAn instead of a LIBSAn.
	(command must be given to both PASS 1 and PASS 2)

5. SELECT ENTRIES FROM PROMPT-LIST  means  that  SCISS  will type the
library entries and let you indicate whether you desire that entry in
the  library.  This  option  and the next are very useful in avoiding
reassembling everything when an assembly error has occurred in one or
two library entries. SCISS will type the names of the library entries
like SAICOR, pausing for your response:
		Y<cr> retain this entry
		N<cr> omit this entry
		DONE  dispose  of  the rest of the entries as you did
			the last (all Y or N)

6.  SPECIFY  ENTRIES  EXPLICITLY  - type the names of the entries you
want (SAILOR etc) separated by <cr>. After all  the  names  you  want
type DONE<cr>

7.  DON'T  DELETE  INTERMEDIATE  FILES- don't delete the .FAI or .REL
files (only meaningful if doing PASS 2 now)

8. DON'T MAKE LIBRARY.(only meaningful doing PASS 2 now).

PASS 2

An important thing to remember is that SCISS  doesn't  remember  what
you  requested  at  the  beginning of PASS 1 so if you want something
unusual (e.g. a  reentrant  library  or  a  library  without  certain
entries) you are going to have to tell SCISS again.

	1 DON'T DELETE INTERMEDIATE FILES
	2 DON'T MAKE A LIBRARY
	3 MAKE A REENTRANT LIBRARY
	4 SELECT ENTRIES FROM PROMPT-LIST
	5 SPECIFY ENTRIES EXPLICITLY

These have the same meaning as they did in PASS 1.

NOTE: As now structured SCISS  asks you to type in your SITE  ID.  At
the  moment, all  this is  used for  is  to decide  what to  do about
STANFORD RPG interface.  At a later time this feature may  be further
extended to allow for hairier  site-dependent features.  If it really
annoys you, just delete the offending lines from your copy of ptran &
set STANSW←FALSE.  Later, of course, you may have to put it all back,
but ...


Side  effect of  SCISS:  SCISS  also  generates the  file  GOGTAB.DEF
whenever it writes a  new library file.  This is a file which DEFINEs
the SAIL user  table indices  in a  format which can  be REQUIREd  by
programs which do a lot of fiddling  with the user table.  The clumsy
USERCON linkage still works, but all new programs should use EXTERNAL
ARRAY GOGTAB[0:'245]; REQUIRE  "GOGTAB.DEF" SOURCE!FILE; and then  do
all  user-table accesses via  the array  GOGTAB, which is  faster and
cleaner than USERCON.  You are urged to put this file onto SYS:.

			GOOD LUCK WITH SCISS

B. MAKTAB.SAI

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

APPENDIX VII.  HOW THE "EXPORT" SAIL IS PUT TOGETHER AND A FINAL NOTE

This section is primarily  intended for those who have  access to the
ARPA  network, and who  may want to  snarf the SAIL  source files via
FTP.  Essentially, it describes how we (at Stanford) put together the
export tape, and  is being supplied for  information purposes ONLY.
It  should NOT be construed as  giving instructions to anyone outside
of the Stanford AI  Lab on how to modify  any areas at Stanford.   We
will  be very unhappy  if anyone  should go munging  our files.   So
PLEASE DO NOT DELETE, RENAME,  EDIT, OR OTHERWISE MUTILATE any  files
at Stanford. Copy  them to your  own area or site  first.  So  far we
have only  had one (minor) accident, but we don't  want any more.  If
you want something changed, send us  a note and we will consider  it,
or may make some other special arrangement for you. We will make some
effort  to be  helpful in any  case.   However, it  should perhaps be
pointed out  that  the SAILors  at  Stanford are  primarily  graduate
students  or  other research  types  and not  a  software house.  Our
principal responsibility must be towards our own research, and it may
not always  be possible for  us to do  everything we  might otherwise
like to do for you.

The principal SAIL area at Stanford is [S,AIL].   This is the area on
which  most of  the Stanford  bug fixing,  feature adding,  and other
hacking is done.  This is backed up on an offline disk pack,  and the
SAIL export tape is ordinarily prepared  from the files on the backup
pack.

TENEX stuff is kept on [10X,AIL].

Files that may be of interest to network hackers include:

LIES[DOC,AIL] -- a list of known bugs in the SAIL manual(s)

SAIL.UPD[AIM,DOC] --  an  "incremental"  SAIL  manual  describing  new
features.

BUGS[S,AIL] -- a list of known bugs in  SAIL, with some indication of
fixes

FEATS[S,AIL] -- a list of new SAIL features.

MACLIE.WRU[DOC,AIL]  -- A  summary of commonly  made errors  in using
macros.

TUTOR.DOC[DOC,AIL] -- a LEAP tutorial.

LEAP.WRU[DOC,AIL] -- Detailed notes on the innards of LEAP.

FILES[X,AIL] -- a list of files used in making up an
export tape.