perm filename TELLEM[NEW,AIL]1 blob
sn#408233 filedate 1979-01-08 generic text, type T, neo UTF8
;; File taken from Su-AI 3/77
;; Last Stanford edit -
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.JFR-- 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.
"JOBDAT" SYMBOLS: The compiler and runtimes refer to symbols as
JOBSA, JOBREL, etc. The standard LINK-10 does not have these
predefined and does not search SYS:JOBDAT.REL, so it will complain
that they are undefined. Tough. (Just because someone decided to
refer to the same locations as .JBSA, .JBREL, etc. does not
"undefine" the references to the old names.) The source for LINK-10
has an assembly-time switch which causes both JOB and .JB forms to be
included in the initial symbol table. Reassemble LINK-10 with this
switch set properly. Of course you can always include whatever you
want in a suitable library. (In fact, an appropriate module at the
end of LIBSAn and HLBSAn might do wonders.)
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
for 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,/LLIBSAn,/BDDT.REL 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.