perm filename SAIL.PUB[DOC,AIL]4 blob
sn#106777 filedate 1974-06-18 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00009 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 .REQUIRE "PUBMAC[DOC,AIL]" SOURCE_FILE
C00005 00003 .SEC |NUMERICAL ROUTINES|
C00011 00004 .SEC |NEW PROCESS FEATURES|
C00017 00005 .SEC |ERROR HANDLING|
C00025 00006 .SEC |INEXHAUSTIBLE STRING SPACE|
C00030 00007 .SEC |RECORD STRUCTURES|
C00047 00008 .SEC |MISCELLANEOUS NEW FEATURES|
C00059 00009 .MAN_BACK
C00061 ENDMK
C⊗;
.REQUIRE "PUBMAC[DOC,AIL]" SOURCE_FILE;
.TITLEPG←TRUE;
.ONECOL
.DOCNAME←"SAIL Addendum #1"
.STAND_FRONT
.SEC |INTRODUCTION|
The following short manual describes the changes that have
happened to SAIL since the publishing of the Manual in July 1973.
It accurately reflects the state of SAIL, version 7, which was
put up on December 4, 1973. The reader should be warned that many
of these new features were designed for veteran SAIL hackers.
The reader may also want to refer to the following documents, which
are usually kept updated.
.LIST(20,0)
MACLIE.WRU[DOC,AIL]\A summary of commonly made errors when using macros and
what to do about them.
TUTOR.DOC[DOC,AIL]\In introduction to LEAP.
LEAP.WRU[DOC,AIL]\A detailed description of the runtime environment of LEAP
for the hardy few who want to interface to LEAP in assembly language.
SAIL.DOC[AIM,DOC]\The July '73 manual (AIM-204) in LPT form. Warning: this version
is the Stanford character set. It is also almost 300 pages long. You can
get a 120 page version, set in two columns of nice type from the National
Technical Information Service, Springfield, Virginia 22151.
LIES[DOC,AIL]\This file contains the know mistakes in the Manual. Soon it will
also contain the known mistakes in this document.
.end
.SEC |NUMERICAL ROUTINES|
A collection of numerical routines has been added to SAIL. These
are pre-declared in the compiler, and are loaded
from the standard SAIL library. The functions are quite standard;
following are the equivalent definitions:
.LIST(4,0)
1.\The standard trigonometric functions. ASIN, ACOS,
ATAN and ATAN2 return results in radians. The ATAN2 call
takes arc-tangent of the quotient of its arguments;
in this way, it correctly preserves sign information.
.NOFILL
REAL PROCEDURE SIN (REAL RADIANS);
REAL PROCEDURE COS (REAL RADIANS);
REAL PROCEDURE SIND (REAL DEGREES);
REAL PROCEDURE COSD (REAL DEGREES);
REAL PROCEDURE ASIN (REAL ARGUMENT);
REAL PROCEDURE ACOS (REAL ARGUMENT);
REAL PROCEDURE ATAN (REAL ARGUMENT);
REAL PROCEDURE ATAN2 (REAL NUMERATOR,DENOMINATOR);
.FILL
2.\The hyperbolic trigonometric functions.
.NOFILL
REAL PROCEDURE SINH (REAL ARGUMENT);
REAL PROCEDURE COSH (REAL ARGUMENT);
REAL PROCEDURE TANH (REAL ARGUMENT);
.FILL
3. \The square-root function:
.NOFILL
REAL PROCEDURE SQRT (REAL ARGUMENT);
.FILL
4.\A pseudo-random number generator. The argument specifies
a new value for the seed (If the argument is 0, the
old seed value is used. Thus to get differing random
numbers, this argument should be zero.) Results
are normalized to lie in the range [0,1].
.NOFILL
REAL PROCEDURE RAN (INTEGER SEED);
.FILL
5.\Logarithm and exponentiation functions. These
functions are the same ones used by the SAIL exponentiation
operator. The base is e (2.71828182845904).
The logarithm to the base 10 of e is .4342944819.
.NOFILL
REAL PROCEDURE LOG (REAL ARGUMENT);
REAL PROCEDURE EXP (REAL ARGUMENT);
.FILL
.END
These functions may occasionally be asked to compute
numbers that lie outside the range of legal floating-point
numbers on the PDP-10. In these cases, the routines issue
sprightly error messages that are continuable.
.SS |OVERFLOW|
In order to better perform their tasks, these routines enable
the system interrupt facility for floating-point overflow
and underflow errors. If an underflow is detected, the results
are set to 0 (a feat not done by the PDP-10 hardware, alas).
Be aware that such underflow fixups will be done to every
underflow that occurs in your program.
If you would like to be informed of any numerical exceptions,
you can call the runtime:
.NOFILL
TRIGINI ( LOCATION(simple-procedure-name) );
.FILL
Every floating-point exception that is not expected by the
interrupt handler (the numerical routines use a special
convention to indicate that arithmetic exception was expected)
will cause the specified simple procedure to be called. This
procedure may look around the world as described in the
Manual for 'export' interrupt handlers, page 79.
If no TRIGINI call is done, the interrupt routine will simply
dismiss unexpected floating-point interrupts.
.SS |ENTRY POINTS|
In order to avoid confusion (by the loader) with older trig packages,
the entry points of the SAIL arithmetic routines all have a "$" appended
to the end. Thus, SIN has the entry point SIN$, etc. WARNING: If
a program plans to use the SAIL intrinsic numerical routines, it should
NOT include external declarations to them, since this will probably
cause the FORTRAN library routines to be loaded.
.SEC |NEW PROCESS FEATURES|
.SS|SPROUT APPLY|
The <procedure call> in a SPROUT statement may be an APPLY construct.
In this case SPROUT will do the "right" thing about setting up the
static link for the APPLY. That is, "up-level" references by the process
will be made to the same variable instances that would be used if the
APPLY did not occur in a SPROUT statement. (See page 77 of the manual.)
However, there is a glitch. The sprout mechanism is not yet smart enough
to find out the block of the declaration of the procedure used to define the procedure
item. It would be nice if it did, since then it could warn the user when
that block was exited and yet the process was still alive, and thus
potentially able to refer to deallocated arrays and etc.
What the sprout does instead is assume the procedure was declared in
the outer block.
This may be fixed eventually, but in the meantime some extra care should
be taken when using apply in sprouts to avoid exiting a block with
dependents.
Similarly, be warned that the "DEPENDENTS
(<blockid>)" construct may not give the "right" result for sprout
applies. Page 68 of the Manual contains the description of this protection
mechanism for non-APPLY Sprouts.
.SS|SPROUT_DEFAULTS|
SAIL now provides a mechanism by which the user may specify the
"default" options to be used when individual procedures are sprouted.
.EXA
Syntax:
PROCEDURE <procid> ...
BEGIN
<some declarations>;
SPROUT_DEFAULTS <integer constant>;
<perhaps some more declarations>;
:
:
<statements>
:
END;
.ENDEXA
In other words, SPROUT_DEFAULTS is a declaration.
Semantics:
If one of the "allocation" fields of the options word passed to the
SPROUT routine -- i.e. QUANTUM,STRINGSTACK,PSTACK, or PRIORITY -- is
zero, then SPROUT will look at the corresponding field of the
specified <integer constant> for the procedure being sprouted. If the
field is non-zero, then that value will be used; otherwise the
current "system" default will be used.
NOTE: SPROUT_DEFAULTS only applies to "allocations", i.e. the
process status control bits (e.g. SUSPME) are not affected.
.EXA
Example:
RECURSIVE PROCEDURE FOO;
BEGIN
SPROUT_DEFAULTS STRINGSTACK(10);
INTEGER XXX;
:
:
END;
:
SPROUT(P1,FOO,STRINGSTACK(3));
SPROUT(P2,FOO);
COMMENT P1 will have a string stack of 3*32 words.
P2 will have a string stack of 10*32 words;
.ENDEXA
.SS |SUSPEND|
SUSPEND now behaves like RESUME in that it returns an item.
.nofill
itm ← SUSPEND(<process item>)
.fill
Frequently, one is suspending some other process than the one that is executing the SUSPEND
statement. In this case, the item returned is ANY.
However, in cases like:
.nofill
X ← SUSPEND(MYPROC);
.fill
where the process suspends itself, it might happen that this process is
made running by a RESUME from another process. If so, then X receives the
<return_item> that was an argument to the RESUME.
.SS |FAIL AND SUCCEED|
FAIL and SUCCEED now behave like RESUME and SUSPEND in that they also return
an item. The item returned is ANY unless the Matching Procedure containing
the FAIL or SUCCEED was (1) sprouted as a process, and (2) made running by a
RESUME construct. In the latter case, the item returned is the <return_item>
that was an argument to the RESUME. [Note that the only case in which a
Matching Procedure can be reactivated at a FAIL is by being RESUMEd.]
.SEC |ERROR HANDLING|
.SS |ERROR MODES|
SAIL's error handler has at long last been modified to do what is
claimed it will do in Section 20 of the manual (pgs 95 - 97), and in
the description of USERERR (pg 42). In brief, it allows one to have
error messages automatically sent to a "log" file while one is
compiling, and to use USERERR as a trace statement.
The description given in the manual differs from reality in two ways:
"Keep" mode has not been implemented (the error handler will flush
all type-ahead except a <lf>);
all of the other modes ("Quiet", "Logging", and
"Numbers") are implemented ONLY IN THE COMPILER. However, one can
get the effect of error modes at runtime by using a brand new feature
called user error procedures.
.SS |USER ERROR PROCEDURES|
A user error procedure is a user procedure that is run before or
instead of the SAIL error handler everytime an error occurs at
runtime. This includes all array errors, IO errors, Leapish errors
and all USERERRs. It does not include system errors, such as Ill Mem
Ref or Ill UUO.
The procedure one uses for a user error procedure must be of the
following type:
.CENTER
SIMPLE INTEGER PROCEDURE proc (INTEGER loc; STRING msg, rsp);
.FILL
Only the names proc, loc, msg, and rsp may vary from the example
above, except that one may declare the procedure INTERNAL if one
wishes to use it across files.
Whenever the external integer _ERRP_ is loaded with LOCATION(proc),
the error handler will call proc before it does anything else. It
will set loc to the core location of the call to the error handler.
Msg will be the message that it would have printed.
Rsp will be non-NULL only if the error was from a USERERR which had
response string argument.
Proc can do anything that a simple procedure can do. When it exits,
it should return an integer which tells the error handler if it
should do anything more. If the integer is 0, the error handler will
(1) print the message, (2) print the location, and (3) query the tty
and dispatch on the response character (i.e ask for a <cr>, <lf>, etc.).
If the right half of the integer is non-zero, it is taken as the ascii for
a character to dispatch upon.
The left half may have two bits to control printing.
If bit 17 in the integer is on,
message printing is inhibited. If bit 16 is on, then the location printing is
inhibited.
For example, "X"+(1 LSH 18) will cause the location to be printed and the
program exited. "C"+(3 LSH 18) will cause the error handler to continue
without printing anything.
Note that simple procedures can not do a non-local GOTO. However,
the effect of a non-local GOTO can be achieved in a user error
procedure by loading the external integer _ERRJ_ with the LOCATION of
a label.
The label should be a on a call to a non-simple procedure which does the desired
GOTO.
The error handler clears _ERRJ_ before calling the procedure
in _ERRP_. If _ERRJ_ is non-zero when the user procedure returns, and continuing
was specified,
then the error handler's exit consists of a simple transfer to that
location.
WARNING! Handling errors from strange places like the string garbage
collector and the core management routines will get you into deep
trouble.
A user error procedure has been written which gives a traceback through the
run-time stack. The traceback routine lists the name of each non-simple
calling procedure and the location (in octal) of the PUSHJ it did, starting with
the most recently called procedure and ending with the main procedure of the
current process.
The procedure is currently available via REQUIRE "LIBSA7[1,JFR]" LIBRARY or
via REQUIRE "WALK.REL[1,JFR]" LOAD_MODULE. The procedure will move to the
system LIBSA7 as soon as possible.
To use the procedure say EXTERNAL PROCEDURE _TRON_; ... _TRON_; COMMENT _TRON_
is for "trace on";.
Subsequent run-time errors will give the traceback, then request the usual response.
To get the traceback at any time, say EXTERNAL PROCEDURE WALK; ... WALK;. This
can be useful in checking recursion level or in other debugging.
To intercept the trackback, say EXTERNAL PROCEDURE UMWALK(INTEGER LOC); ...
UMWALK(LOCATION(user_procedure));. Then user_procedure("NAME",LOC) is called
once for every procedure in the traceback chain, instead of printing
"CALLED FROM "&NAME&" AT "&CVOS(LOC)&CRLF on the terminal.
To discontinue tracing on errors: EXTERNAL INTEGER _ERRP_; ... _ERRP_←0;.
.SEC |INEXHAUSTIBLE STRING SPACE|
The string garbage collector has been modified to expand string space
(using discontiguous blocks) whenever necessary to satisfy the demand
for places to put strings. To take advantage of this feature, one
need not change his programs.
Here are some points which might be of interest, however:
.LIST(4,0);
1)\Although we are going to provide user control over all size
parameters eventually, currently only the initial string space
size is settable by the user, either via REQUIRE or the ALLOC
sequence, as before. The size of each string space increment will
be the same as the original size, which need not be monstrous any
more unless you know that all runs of your program will need a
monstrous string space anyhow. The threshold (see below) for
expanding will be set at 1/8 the string space size (increment
size).
2)\One can, in his program, modify these values independently, if he
is willing to use the USERCON function, and to follow this format:
.NOFILL; LPTFONT;
USER TABLE ENTRY NAME VALUE
STINCR lh: number of chars. in increment
rh: number of words in increment + 4
STREQD lh: number of chars. in threshold
rh: number of words in threshold.
.FILL; SELECT 1;
3)\The threshold.
After garbage collection, let us say that M-1 discontiguous string
spaces are full, and the M'th has n free characters in it
(available for new strings). The garbage collector was called
because some routine wanted to create a string R characters long,
and there were not that many available (free). After garbage
collection, the new algorithm requires that N be greater than
R+LH(STREQD). If it is not, expansion takes place (to M+1 spaces),
to satisfy this requirement. In other words, if STREQD is 1/8
the size of the current space, that space will not be allowed to
become more than about 7/8 full. This helps avoid frequent,
nearly useless calls on the garbage collector when space is about
gone. All but the current space are allowed to become as full as
possible, however.
4)\New statistics are maintained by the garbage collector. Soon
there will be a built-in routine you can use to print them. For
now, you may look at them using USERCON, although this document does
not say what they are. In order to activate timing of the
garbage collector (slows it down), set SGCTIME in the user table
to -1.
5)\Future plans.
The new structure not only allows expansion of string space, it
also will allow for partial garbage collections (no visible
benefits except increased speed, since a partial collection will
be almost as effective as a complete one, and much faster), and
the ability to move string space blocks, in order to compact
memory. Push on your local representative to get these things
done.
.END
.SEC |RECORD STRUCTURES|
.SS |INTRODUCTORY REMARKS|
.SS |RECORD CLASS DECLARATIONS|
RECORD_CLASS <classid> (<formal parameter list>);
RECORD_CLASS <classid> (<formal parameter list>)[<handler procid>];
.SEC |MISCELLANEOUS NEW FEATURES|
.SS|NEW MTAPE OPTIONS|
.nofill
MTAPE(chan,NULL)
.fill
will cause an MTAPE 0 to be issued for channel chan. For mag. tapes,
this will cause you to wait until all activity ceases. For other
devices, various random things can happen, depending on the device
and system.
In export SAIL, MTAPE(chnl,"I") sets the 'IBM compatible'
mode for a tape drive. (It does an MTAPE chnl,101.)
.ss|INITIALIZATION PHASES|
User initializations are now done in successive phases, with all
initializations required for one phase being done before
initializations required for the next phase.
.NOFILL
Syntax:
REQUIRE <procid> INITIALIZATION;
REQUIRE <procid> INITIALIZATION [<phase no>];
where <phase no> is an integer constant.
Semantics:
.FILL
<phase no> specifies the number of the user initialization
phase. If it is left out, then one is used. Currently, there are
three phases, numbered 0, 1, and 2. If the demand is great enough,
additional phases may be added later. (Note for assembly language
hackers: internally, user phases are numbered '400000, '400001, etc.)
.SS|CHNCDB|
val←CHNCDB(channel)
This integer procedure returns a pointer to the three word block used
to open the specified channel. It is provided for the benefit of
assembly language procedures that may want to do I/O inside some fast
inner loop, but which may want to live in a SAIL core image & use the
SAIL OPEN, etc.
.SS |ARRCLR|
.nofill
ARRCLR(arry)
.FILL
This new runtime routine clears any kind of array. That is, arthmetic
arrays get filled with zeros, string arrays with NULLs, and itemvar
arrays with ANYs.
One may use ARRCLR with set and list arrays, but the set and list
space will be lost (i.e. un-garbage-collectable).
The alternative form:
.nofill
ARRCLR(arry,val)
.fill
where val is either an integer or a real number, will fill arry with
that value. Do not do this to string or list arrays unless you do
not care whether or not your program works. Also using a real val for
an itemvar array is apt to cause strange results. (If you use an integer,
arry will be filled with CVI(val).)
.SS |SETPL|
.nofill
SETPL(channel, @linnum, @pagnum, @sosnum)
.fill
This new runtime routine allows one to keep track of the string input from
CHANNEL. Whenever a '12 is encountered, LINNUM is incremented. Whenever
a '14 is encountered, PAGNUM is incremented, and LINNUM is zeroed. Whenever
an SOS line number is encountered, it is placed into SOSNUM. When fully
implemented (soon), this will work on the INPUT, INTIN, and REALIN functions
as well.
.SS |EVALREDEFINE|
EVALREDEFINE bears the same relationship to REDEFINE as EVALDEFINE does to DEFINE.
See pages 47 and 50 of the Manual.
.SS|CVPS|
CVPS(<macro_parameter>) converts <macro_parameter> to a string and returns
the string. See about macro parameters on page 48 of the manual.
.SS|EXPRESSIONS IN REQUIRES|
Previously, all REQUIRE constructs had to have only constants in them. Now
SAIL allows compile time expressions as well. See about compile time
expressions on page 47 of the Manual.
.SS|RELEASE|
RELEASE now takes an optional second argument, the CLOSE inhibit bits.
These are described in the UUO manual (Stanford System). These are defaulted
to zero when not specified so that
old programs which did not specify them will work as before.
.SS|TTYUP|
.nofill
oldval←TTYUP(newval)
.fill
This routine casuse conversion of lower case characters (a-z) to their
upper case equivalents for strings read by any of the SAIL teletype routines
that do not use break tables. If newval is TRUE, then conversion will
take place on all subsequent inputs until TTYUP is called with newval
FALSE. Oldval will always get set to the value of newval used in the
previous call. (If TTYUP has never been called, then no conversions will
take place, and the first call to TTYUP will return FALSE).
.SS|BREAKSET MODES ⊗≡⊗K⊗≡⊗ AND ⊗≡⊗F⊗≡⊗|
A "K" specification as a BREAKSET mode will cause lower to upper case
conversion when that break table is used. Conversion takes place before
each character is checked for breaking or omission. An "F" specification
turns off the conversion -- i.e. it undoes the effects of "K".
.SS|INOUT|
.nofill
INOUT(inchan,outchan,howmany)
.fill
INOUT reads howmany words from channel inchan and writes them out on
channel outchan. Each channel must be open in a mode between 8 and 12.
on return, the EOF variables for the two channels will be the same as if
ARRYIN & ARRYOUT had been used. If howmany is less than zero, then
transfer of data will cease only upon end of file or a device error.
(note: INOUT uses BLTs to transfer data directly from one set of buffers
to the other)
.SS|GETSTS & SETSTS|
.nofill
SETSTS(chan,new_status)
issues a SETSTS uuo on channel chan with the status value new_status.
status←GETSTS(chan)
.fill
returns the results of a GETSTS uuo on channel chan.
.SS|CHANGES TO ⊗≡⊗OPEN⊗≡⊗ ERROR HANDLING|
If the EOF variable supplied to OPEN is non-zero and the device name
is invalid, then OPEN will fail without giving the error message
"INVALID DEVICE NAME FOR OPEN", and the EOF value will be unchanged.
If a device is unavailable, and EOF=0, then the user is now given the
options of trying again or going on without opening the device, in which
case EOF will be set to non-zero as usual.
.ss|ASH|
ASH has been added as an arithmetic operator. Its syntax is just like that
of LSH, and it generates similar code (except for putting out a
PDP-10 ASH instruction instead of a LSH).
.SS|ARG_LIST|
.nofill
ARG_LIST(<arg1>,...,<argn>)
.fill
where each <arg> may be any valid argument to the REF_ITEM construct,
assembles a list of "temporary" reference items that will be deleted
by APPLY after the applied procedure returns. Thus
.nofill
APPLY(proc,ARG_LIST(foo,bar,VALUE baz))
is roughly equivalent to
.begin verbatim
tmplst←{{REF_ITEM(foo),REF_ITEM(bar),REF_ITEM(VALUE baz)}};
APPLY(proc,tmplst);
WHILE LENGTH(tmplst) DO DELETE(LOP(tmplst));
.end
.FILL
but is somewhat easier to type. Note that the reference items created
by ARG_LIST are just like those created by REF_ITEM, except that they
are marked so that APPLY will know to kill them.
.MAN_BACK
.EVERY HEADING (,,);
.PORTION TITLEPAGE
.turn on "→{↑"
.SELECT 1
STANFORD ARTIFICIAL INTELLIGENCE LABORATORY→{(↑MONTH)} {YEAR}
.SKIP 6
.SELECT 2; CENTER
SAIL USER MANUAL
.SELECT 1;
.SKIP 1
UPDATE
.SKIP 3
James R. Low
John F. Reiser
Hanan J. Samet
Robert F. Sproull
Daniel C. Swinehart
Russell H. Taylor
Kurt A. VanLehn
.SKIP 10
ABSTRACT
.FILL;CRSPACE;INDENT 0,0;ADJUST
.SKIP 1;
This document describes recent changes to the SAIL language
since the "new" manual (AIM-204) was published in July 1973.
It reflects the various new features implemented
as of 26 March, 1974 for SAIL version 7 and
corrects a number of minor errors in the earlier manual.