perm filename WRTON.JFR[DOC,AIL] blob
sn#106779 filedate 1974-06-18 generic text, type T, neo UTF8
COMMENT ⊗ VALID 00002 PAGES
RECORD PAGE DESCRIPTION
00001 00001
00002 00002 .SEC |WRITEON|
00020 ENDMK
⊗;
.SEC |WRITEON|
.FILL
Note. As of March 26, l974, the following feature is not available
from the SAIL system on [1,3], but does exist on [1,JFR] in files
SAIL.DMP and LIBSA7.REL. The feature will become available from
the system SAIL as soon as possible.
****** FURTHER NOTE: This feature may look somewhat different by the time it is actually
incorporated into the system -- RHT
**************
SAIL now has a WRITEON feature similar to the WRITEON statement of
ALGOLW. SAIL WRITEON consists of a new key-word statement (WRITEON),
a pre-declared initialization procedure (WR_INI), and runtime support
routines. The WRITEON statement takes an arbitrary number of SAIL
expressions as parameters, produces a string representation of each
expression, concatenates the strings, and writes the resulting string
to the terminal and to a file.
.SS |Definition|
The syntax of WRITEON is
.NOFILL
WRITEON(<exp1>,<exp2>, ... ,<expn>)
.FILL
where <exp1>,<exp2>, ... ,<expn> are SAIL expressions.
A string representation of each expression is produced and then output.
The expressions are processed in order from left to right.
.BEGIN VERBATIM
Type of <exp> String representaion of <exp>
STRING <exp> itself
INTEGER CVS(<exp>)
REAL CVG(<exp>)
ITEM the PNAME of the item, if it has one [the items
ANY, BINDIT, MAINPI, and EVENT_TYPE are normally
considered to have PNAMES];
else "ITEM_"&CVS(CVN(<exp>))
SET if <exp>={} then "PHI" else "{"& <string
representation of each item in the set> &"}"
LIST if <exp>={{}} then "NIL" else "{{"& <string
representation of each item in the list> &"}}"
array concatenation of the string representation of
each element of the array; the elements are
taken in ascending memory location order
.END VERBATIM
The initialization procedure is
.NOFILL
WR_INI("DEVICE","FILE",CHANNEL,MAXLENGTH)
.FILL
where DEVICE is a device name, FILE is a file name, CHANNEL is a
system channel number, and MAXLENGTH is the number of characters
desired per line.
.fill
If FILE is not NULL, then DEVICE:FILE is OPENed for output on
channel CHANNEL, and then ENTERed. Subsequent WRITEON statements
will direct output to this channel/file, independent of whether
output is also going to the terminal. If FILE is NULL, then no
OPEN or ENTER is done, and subsequent WRITEON statements will not
direct output to any file except the terminal.
Remember to CLOSE(CHANNEL) if the file is to be made permanent.
.ss |Example|
.BEGIN VERBATIM
The following is an actual example of a program using WRITEON.
BEGIN "WRTEST"
EXTERNAL INTEGER WR_CHN;
EXTERNAL STRING WR_S1,WR_S2,WR_S3,WR_S4;
REQUIRE PNAMES; REQUIRE 10 NEW_ITEMS;
INTEGER J,K; ITEMVAR ITB; INTEGER ITEM ITA,ITB;
REAL PI; STRING GREET; SET S; LIST L;
STRING ARRAY ALPHABET[1:26]; INTEGER ARRAY EVENS[0:9];
DEFINE CRLF="('15&'12)", TAB="'11";
J←7; PI←3.14159265; ITVA←ITA; GREET←"HELLO"; DATUM(ITA)←117;
PUT ITB IN S; PUT ITA IN S;
PUT ITA IN L; PUT NEW IN L; PUT ITB IN L;
FOR K←0 STEP 1 UNTIL 9 DO EVENS[K]←K+K;
FOR K←1 STEP 1 UNTIL 26 DO
ALPHABET[K]←"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[K FOR 1];
COMMENT SET SPACING BETWEEN WRITEONS; WR_S1←CRLF;
COMMENT SET SPACING BETWEEN EXPRESSIONS; WR_S2←" ";
COMMENT SET SPACING BETWEEN ARRAY ELEMENTS; WR_S3←TAB;
COMMENT SET SPACING BETWEEN SET & LIST ITEMS; WR_S4←", ";
WR_INI("DSK","OUTPUT.OUT",GETCHAN,50);
WRITEON(J,PI,ITV,GREET,DATUM(ITA);
WRITEON(S,L,25,SQRT(3.),{},GREET & GREET);
WRITEON EVENS,CRLF&"SAY YOUR ABC's",ALPHABET);
CLOSE(WR_CHN)
END "WRTEST"
The file OUTPUT.OUT, after the program is run:
7 3.141593 ITA HELLO 117
{ITA, ITB} {{ITA, ITB, ITEM_11}} 25 1.732051
PHI HELLOHELLO
0 2 4 6 8 10 12
14 16 18
SAY YOUR ABC's A B C D E
F G H I J K
L M N O P Q
R S T U V W
X Y Z
.END VERBATIM
.ss |Runtime particulars|
.fill
The WRITEON runtime keeps track of the print length of the line
being assembled. If a string to be concatenated to the end of
the line would cause the print length to exceed MAXLENGTH characters,
then the runtime inserts a CRLF and resets its counter before
concatenating the string.
Example: Suppose MAXLENGTH is 50, there are 35 characters already
in the line, and the runtime is asked to concatenate a string of
21 characters to the end of the line. Since 35+21>50, the runtime
concatenates a CRLF, zeroes its counter, and then concatenates the
21-character string. This produces one line of 35 characters and
another (as yet partial) line of 21 characters. Suppose the runtime
is then asked to concatenate strings of 58 characters and 10 characters.
Since 21+58>50, the runtime concatenates a CRLF, zeroes its count, and
concatenates the 58-character string. Since 58+10>50, the runtime
concatenates a CRLF, zeroes its count, and concatenates the 10-character
string. Thus there are lines of 35, 21, 58, and (a partial line of )
10 characters.
The runtime will recognize a CRLF contained in a string to be concatenated
if the CRLF appears as either the first two or the last two characters
(but it will recognize only one CRLF if CRLF appears at both the beginning
and end). The runtime will recognize a TAB in a string to be concatenated
if the TAB is the first character of the string.
The runtime routine contains several INTERNAL variables which control
the WRITEON environment. The user may declare these EXTERNAL to look
at them or change their values. Variables are initialized to
0(FALSE) if integers and to NULL if strings.
.BEGIN VERBATIM
Integer Variables Function
WR_TTK Terminal kill flag. If true, do not send
output to the terminal.
WR_FIL File flag. If false, do not send output to
DEVICE:FILE of WR_INI.
WR_LEN Maximum line length before CRLF is inserted.
(MAXLENGTH is copied to this location.)
WR_CHN Channel number for file output.
(CHANNEL is copied to this location.)
WR_ACT Activation control--when to actually do the
output to the terminal or file.
=0 at the end of the WRITEON statement
=1 after each inserted or recognized CRLF
≥2 after each expression in the WRITEON
≥3 after each element of an array, set, or list
WR_USR If ≠0, the location of a SIMPLE procedure to be
called instead of OUTSTR and OUT to dispose of
the current line. This procedure should be
declared like SIMPLE PROCEDURE GOBBLE(STRING S).
Then say EXTERNAL INTEGER WR_USR;
WR_USR←LOCATION(GOBBLE).
WR_LPK Leap name killer. If true then the empty set
prints as {}, the empty list as {{}}, and
the items ANY, BINDIT, MAINPI, and EVENT_TYPE
are not treated in any special manner.
WR_CUR "Cursor" position. This variable holds the print
length of the current line.
String Variables Function
WR_S1 Concatenated to the end of the line after
each WRITEON statement.
WR_S2 Inserted into the line between each expression
appearing in the WRITEON statement.
WR_S3 Inserted into the line between consecutive
elements of the same array.
WR_S4 Inserted into the line between consecutive
items in the same set or list.
WR_ST This is the current line being assembled.
If WR_USR≠0, then the call to the user
procedure is user_proc(WR_ST).
.END VERBATIM
.FILL
All CVS and CVG calls are done with the current settings or
WIDTH and DIGITS (see SETFORMAT).
To minimize the number of string concatenations (at the expense of calls
to OUTSTR and OUT), use WR_ACT←3. To minimize the number of calls to
OUTSTR and OUT (at the expense of string concatenations) use WR_ACT←0
(the default).
To use multiple channels, non-Stanford I/O structures, etc:
.begin verbatim
A. Do the I/O initializations for each file/channel. A standard
OPEN and ENTER sequence may be done for each file simply by
calling WR_INI several times (once for each file/channel).
B. Set WR_FIL←TRUE and WR_LEN←<length>.
C. To switch channels, save and restore the values of parameters
that are pecular to each channel, then do the WRITEON. The
values which normally will need to be saved and restored are
WR_ST, WR_CUR, and WR_CHN. Here is one way to do this:
PROCEDURE SWITCH_CHAN(INTEGER NEWCHAN);
BEGIN OWN INTEGER ARRAY CURSOR[0:20]; OWN STRING ARRAY STR[0:20];
EXTERNAL INTEGER WR_CUR,WR_CHN; EXTERNAL STRING WR_ST;
IF NEWCHAN=WR_CHN THEN RETURN;
CURSOR[WR_CHN]←WR_CUR; STR[WR_CHN]←WR_ST;
WR_CUR←CURSOR[NEWCHAN]; WR_ST←STR[NEWCHAN]; WR_CHN←NEWCHAN
END;
.
.
.
SWITCH_CHAN(<new channel number>);
WRITEON(<whatever>);
.end verbatim
.ss |Using WRITEON for other purposes|
.fill
At compile time SAIL constructs a one-word descriptor for each expression
appearing in the WRITEON statement. These descriptors are fed one at a
time to the runtime routine WR_TON, which interprets the descriptors
in the appropriate manner. After all the expressions appearing in the
WRITEON statement have been processed, the compiler inserts an extra
call to WR_TON with an all zero descriptor to flag the end of the
WRITEON statement.
The descriptor of an expression is identical to the datum which would
be produced by REF_ITEM of the expression; WRITEON does not create new
items. The format of a descriptor is:
.exa
Bits Name Comment
1 REFB "Reference" bit. If this bit is on, then the
address field points to a "permanent" location.
If this bit is off, then the address field points
to a temporary location. Temporaries may be
reused by the compiler within the same WRITEON.
2 QUESB On if ? itemvar.
3 BINDB On if BINDING itemvar.
4 PROCB "Procedure" bit.
5 ITEMB On if item or itemvar.
6 ARY2B On if λ array itemvar array.
7-12 MSK6BT Type code, same as LEAP datum type (see TYPEIT).
13-35 ADDR Effective address which points at the object
referred to. String temporaries reside on top
of the string stack (ADDR is SP,,0). All
other objects reside in fixed memory locations
(ADDR is 0,,address). The address of an array
is the address of its HEAD word (see SAIL manual,
p.106).
.endexa
.fill
By writing his own routine named WR_TON the user may do anything he
wants with the descriptors.
Caution. In the case of a string temporary, the user must pop the stack.
The locations housing other temporaries may possibly be used more than once
within the same WRITEON.