perm filename SAIL.PUB[DOC,AIL]27 blob sn#256530 filedate 1977-01-06 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00003 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	This addendum describes changes and additions to Sail since the August 1976
C00007 00003	.sec(Declarations)
C00010 ENDMK
C⊗;
This addendum describes changes and additions to Sail since the August 1976
manual, AIM-289.

.sec(double precision)
Double precision floating-point arithmetic is available.
Use the <type_qualifier> LONG in declarations.  For example,
.exa
	LONG REAL X,Y,Z;
	LONG REAL ARRAY XA[0:N];
.endexa
Currently LONG has meaning only when it appears as part of LONG REAL.
(At some future time LONG INTEGERs may also exist.)

The runtime routines LREALIN and LREALSCAN operate the same as REALIN and
REALSCAN, except for returning LONG REAL values.  The routine CVEL takes a
LONG REAL value and returns a string representation like that of CVE,
except that "@@" is used to signify LONG when delimiting the exponent.
Any of "@", "@@", "E", or "D" are acceptable exponent delimiters to
LREALIN and LREALSCAN.

Variables which are declared LONG REAL are represented in KI10 hardware
format double precision, take two consecutive words of storage, and
provide 62 bits of precision (approximately 18 decimal digits) to
represent the fraction part of a floating-point number.  Regular REAL
variables occupy a single word and have 27 bits (8 decimal digits) of
precision.  The exponent range of both REAL and LONG REAL variables
is from -(2↑128) to 2↑127, where 2↑127 is approximately 10↑38.

In type coercion LONG REAL is a dominant type; to perform any operation
involving a LONG REAL, both operands are first converted to LONG REAL if
necessary, then the appropriate LONG REAL operation is performed.  The
type coercion path is linear:  STRING ↔ INTEGER ↔ REAL ↔ LONG REAL.
Conversion from REAL to LONG REAL is performed by assigning the (only)
word of the REAL to the most significant word of the LONG REAL and setting
the second (least significant) word of the LONG REAL to zero.  Conversion
from LONG REAL to REAL is by UUO which rounds.

Arithmetic and assignment operations are compiled into DFAD, DFSB, DFMP,
DFDV, DMOVE, DMOVEM instructions.  The Sail operations ASH, LSH, ROT,
LAND, LOR, EQV, XOR are performed on both words (ASHC, LSHC, ROTC, 2 ANDs,
2 IORs, etc.).  LOCATION of a LONG REAL variable gives an address E such
that DMOVE AC,E fetches the appropriate words of memory.  When passed by
value as an actual parameter to a procedure, both words are placed on the
P stack:  PUSH P,X ↔ PUSH P,X+1.  LONG REAL fields in record classes are
handled much like STRING fields, except that the address in the record
field points to the first word of a 2-word block (rather than to the
second word as in the case with STRINGs).

LONG REAL ARRAYs are stored as contiguous blocks of 2-word values.
ARRTRAN done on two LONG REAL arrays is a transparent operation, but for
ARRYIN, ARRYOUT, or ARRBLT the actual word count is specified; think about
whether you should multiply by 2!  At runtime the array descriptor for a
LONG ARRAY has bit 12 (40,,0 bit) set in MULT(n), the multiplier for the
last dimension (which would otherwise be =1).  Similarly, a LONG ARRAY is
allocated by setting bit 12 (40,,0) bit in the parameter which specified
the number of dimensions to ARMAK.
.sec(Declarations)
In order for the notion of "scope" to work properly, declarations must occur
before use.  For example, the compiler will think that K is undefined in
.exa
BEGIN "FOO"
  PROCEDURE BAR; BEGIN PRINT(K) END;
  INTEGER K;
END "FOO"
.endexa
even though the reference to PRINT(K) is legal by the ALGOL60 notion of scope.

.sec(Two-character Operators)
The compiler now recognizes "**" as equivalent to "↑", ":=" for "←",
"<=" for "≤", and ">=" for "≥".

.sec(Requires)
REQUIRE OVERLAP_OK; will suppress the message which occurs at initialization
when two programs have declared items.
REQUIRE VERIFY_DATUMS; causes the compiler to generate an additional instruction
for each DATUM reference, to make sure (dynamically, at run time) that the type
of the item in the DATUM construct is the same as the compiler expected.

.sec(CASE statement)
In an explicitly numbered CASE statement the word ELSE can appear where
a case number is normally used.  The statement following the ELSE is a 
catch-all for any case number not mentioned, including anything which
would otherwise generate a CASE index error.  For example,
	CASE K OF BEGIN [3] J←3; ELSE J←4; [5] J←5 END
is another way of accomplishing
	     IF K=3 THEN J←3
	ELSE IF K=5 THEN J←5
	ELSE J←4
A CASE statement containing an ELSE case does not generate a call to the CSERR
runtime routine, and in addition the jump table usually contains only
max_case - min_case +1 words (rather than max_case +1).