

***************************************************************************
** COPYRIGHT (C) MASSACHUSETTS INSTITUTE OF TECHNOLOGY AND HARVARD       **
** UNIVERSITY, BIOMEDICAL ENGINEERING CENTER 1977.  ALL RIGHTS RESERVED. **
***************************************************************************

STOIC  (STACK ORIENTED INTERACTIVE COMPILER)
J. SACHS
2/14/77

	STOIC IS A GENERAL PURPOSE INTERACTIVE PROGRAM
WHICH INCORPORATES THE CAPABILITIES OF A COMPILER, EDITOR
ASSEMBLER, DEBUGGER, LOADER, AND OPERATING SYSTEM WITHIN
A SINGLE CONSISTENT ARCHITECTURE.  IT IS CORE-EFFICIENT
WHILE RETAINING HIGH RUNNING SPEEDS.  IN ADDITION, THE
LANGUAGE IS EXTREMELY FLEXIBLE, PERMITTING THE USER TO
DEVELOP A WORKING VOCABULARY OF SUBROUTINES TAILORED TO
HIS SPECIFIC APPLICATION.

	THE SINGLE MOST PROMINENT FEATURE OF STOIC IS ITS
PRINCIPAL DATA STRUCTURE, CALLED THE DICTIONARY.  THE
DICTIONARY IS AN ORDERED LIST OF ENTRIES CALLED WORDS.
ASSOSCIATED WITH THE DICTIONARY ENTRY FOR EACH WORD IS A
NAME; A LEGAL NAME FOR A WORD IS ANY STRING OF UP TO 127
ASCII CHARACTERS.  PUNCTUATION, NUMERICS, AND MOST OTHER
SPECIAL CHARACTERS MAY BE FREELY USED WITHIN A NAME.  TWO
NAMES ARE EQUIVALENT IF AND ONLY IF THEIR FIRST FIVE CHARACTERS
ARE THE SAME AND THEY HAVE EXACTLY THE SAME LENGTH.  ILLEGAL
CHARACTERS WITHIN A NAME ARE:

	SPACE
	TAB
	CARRIAGE RETURN
	FORM FEED
	LINE FEED
	RUBOUT
	NULL

EXAMPLES:

ABCDE   IS NOT EQUIVALENT TO  ABCDEF
(HEAD1) IS EQUIVALENT TO      (HEAD2)

	A LITERAL IS A SEQUENCE OF CHARACTERS WHICH DESCRIBES
A CONSTANT.  THE BASIC STOIC SUPPORTS TWO TYPES OF LITERAL;
16-BIT INTEGER AND STRING.  THE LANGUAGE MAY BE EXTENDED TO
INCLUDE OTHER DATA TYPES SUCH AS FLOATING POINT OR DOUBLE
PRECISION INTEGER.

	AN INTEGER LITERAL IS A SEQUENCE OF DIGITS
OPTIONALLY PRECEDED BY A PLUS OR MINUS SIGN.  ALL DIGITS
MUST BE LESS THAN THE CURRENT RADIX.  NO SPACES MAY BE
EMBEDDED WITHIN THE LITERAL.  INTEGER LITERAL MUST BE IN
THE RANGE OF -32768 TO 32767 IS SIGNED OR 0 TO 65535 IF
UNSIGNED.

EXAMPLES:

-1234	IS A LEGAL LITERAL
+-100	IS NOT A LEGAL LITERAL
-AFC0	IS A LEGAL LITERAL IF RADIX IS HEXADECIMAL


	STRING LITERALS MAY TAKE ONE OF THREE FORMS:
1) A STRING ENCLOSED IN DOUBLE QUOTES:

 "STRING"

2) A STRING ENCLOSED IN BACKSLASHES:

 \STRING\

3) A STRING PRECEDED BY SINGLE QUOTE AND TERMINATED BY SPACE OR TAB:

 'STRING

IN ANY OF THE ABOVE TYPES OF STRING LITERAL, THE END OF THE
LINE (RETURN OR FORM FEED) MAY SERVE AS A TERMINATOR.  SPECIAL
CHARACTERS SUCH AS RETURN, RUBOUT, ETC. MAY BE INCLUDED IN A
STRING LITERAL BY ENCLOSING THE CORRESPONDING OCTAL ASCII CODE
BETWEEN TWO AMPERSANDS (&).

EXAMPLES:

"THIS IS A STRING LITERAL"
\THIS LITERAL CONTAINS A RETURN &15&\
'&177&&15&


	STOIC SYNTAX IS QUITE SIMPLE.  A LEGAL COMMAND
LINE CONSISTS OF A SEQUENCE OF LITERALS AND/OR NAMES OF WORDS
SEPARATED BY SPACES OR TABS, AND TERMINATED BY CARRIAGE
RETURN OR FORM FEED.

	PROGRAMMING IN STOIC CONSISTS PRIMARILY OF
DEFINING A SET OF NEW WORDS BASED ON WORDS WHICH HAVE
ALREADY BEEN DEFINED.  AN INITIAL VOCABULARY OF ABOUT ONE
HUNDRED WORDS CALLED THE KERNEL ENABLES THE USER TO GET
STARTED.

	THE PRINCIPAL VEHICLE FOR COMMUNICATION BETWEEN
WORDS IS THE PARAMETER STACK, FREQUENTLY CALLED "THE
STACK".   TYPICALLY, THE PARAMETERS UPON WHICH A WORD WILL
OPERATE ARE PUSHED ON THE STACK, THE WORD POPS ITS
PARAMETERS FROM THE STACK AND PUSHES ITS RESULTS ON THE
STACK.  COMMUNICATION THROUGH VARIABLES IN FIXED
LOCATIONS IS ALSO USED.

	STOIC USES REVERSE POLISH NOTATION FOR ALL
OPERATIONS.  THIS MEANS THAT ALL OPERANDS PRECEDE THEIR
OPERATORS;  PARENTHESES ARE NEVER NECESSARY.

EXAMPLES:

1 1 + 2 *   IN ALGEBRAIC NOTATION IS   (1+1)*2
1 2 3 * -   IN ALGEBRAIC NOTATION IS   1-(2*3)

	UNLIKE MOST OTHER HIGER LEVEL LANGUAGES, STOIC
ENABLES THE USER TO MANIPULATE ADDRESSES AS WELL AS DATA.
IT IS VERY IMPORTANT HOWEVER FOR THE USER TO REMAIN AWARE
OF THE DISTINCTION BETWEEN AN ADDRESS AND ITS CONTENTS.
	THERE ARE THREE COMMON TYPES OF WORDS WHICH PUSH
NUMBERS ON THE STACK; LITERALS, CONSTANTS, AND VARIABLES.
A REFERENCE TO A LITERAL OR A CONSTANT CAUSES ITS VALUE
TO BE PUSHED ON THE STACK.  A REFERENCE TO A VARIABLE
CAUSES ITS ADDRESS TO BE PUSHED ON THE STACK.  THE TWO
OPERATORS "@" AND "!" ARE USED TO OBTAIN AND MODIFY THE
VALUE OF A VARIABLE.  THEY ARE DEFINED AS FOLLOWS:

	@	REPLACE THE ADDRESS ON THE TOP OF THE
		STACK BY THE CONTENTS OF THAT ADDRESS.
		THIS WORD IS USED TO LOAD THE CONTENTS
		OF A MEMORY LOCATION ONTO THE STACK.

	!	STORE AT THE ADDRESS ON THE TOP OF THE
		STACK THE NUMBER NEXT TO TOP OF THE
		STACK.  BOTH NUMBERS ARE REMOVED FROM
		THE STACK.

EXAMPLES:

IN THE FOLLOWING EXAMPLES, X, Y, AND Z ARE VARIABLES,
WHILE A, B, AND C ARE CONSTANTS.

100 X !		SET VALUE OF X TO 100.

X 100 !		STORE THE ADDRESS OF X IN LOCATION 100
		(UNDER NORMAL CIRCUMSTANCES, THIS WOULD
		BE A VERY SERIOUS ERROR).

X @ Y !		SET THE VALUE OF Y TO THE VALUE OF X

X Y !		SET THE VALUE OF Y TO THE ADDRESS OF X

X @ Y @ + Z !	ADD THE VALUES OF X AND Y AND STORE THE
		RESULT IN Z.

X A + Y !	STORE (ADDRESS OF X)+A IN Y.

X A B + + @ Y !	SET VALUE OF Y TO THE CONTENTS OF
		LOCATION X+A+B.


	STOIC PROVIDES THE USER WITH AN UNUSUALLY LARGE
NUMBER OF FIXED POINT OPERATORS FROM WHICH THE FOLLOWING
MORE COMMON EXAMLES HAVE BEEN EXTRACTED.  UNLESS OTHERWISE
SPECIFIED, ALL NUMBERS ARE 16-BIT INTEGERS.

UNARY OPERATORS

THE FOLLOWING OPERATORS REPLACE THE TOP OF THE STACK
WITH THEIR RESULT.  THE NUMBER ON THE TOP OF THE
STACK IS CALLED "A".

	MINUS	-A

	ABS	ABSOLUTE VALUE OF A

	NOT	LOGICAL COMPLEMENT OF A

	2*	A*2

	2/	A/2 (SIGNED)

	U2/	A/2 (UNSIGNED)

	1+	A+1

	1-	A-1

	EQZ	-1 IF A EQUAL TO 0
		 0 OTHERWISE

	NEZ	-1 IF A NOT EQUAL TO 0
		 0 OTHERWISE

	LTZ	-1 IF A LESS THAN 0
		 0 OTHERWISE

	LEZ	-1 IF A LESS OR EQUAL TO 0
		 0 OTHERWISE

	GEZ	-1 IF A GREATER OR EQUAL TO 0
		 0 OTHERWISE

	GTZ	-1 IF A GREATER THAN 0
		 0 OTHERWISE

BINARY OPERATORS

THE FOLLOWING OPERATORS REPLACE THE TOP TWO NUMBERS ON
THE STACK WITH THEIR RESULT.  THE NUMBER ON THE TOP OF
THE STACK IS CALLED "A", THE NEXT TO TOP IS CALLED "B".

	+	B+A

	-	B-A

	*	B*A

	/	B/A

	MAX	MAXIMUM (B,A) (SIGNED)

	MIN	MINIMUM (B,A) (SIGNED)

	AND	LOGICAL AND OF B,A

	OR	LOGICAL OR OF B,A

	XOR	LOGICAL EXCLUSIVE OR OF B,A

	EQ	-1 IF B EQUAL TO A
		 0 OTHERWISE

	NE	-1 IF B NOT EQUAL TO A
		 0 OTHERWISE

	LT	-1 IF B LESS THAN A
		 0 OTHERWISE

	LE	-1 IF B LESS OR EQUAL TO A
		 0 OTHERWISE

	GE	-1 IF B GREATER OR EQUAL TO A
		 0 OTHERWISE

	GT	-1 IF B GREATER THAN A
		 0 OTHERWISE


	A NUMBER OF OPERATORS ARE ALSO PROVIDED WHOSE
SOLE FUNCTION IS TO REORGANIZE THE ELEMENTS OF THE STACK:

		STACK	STACK
	NAME	BEFORE	AFTER	DESCRIPTION

	DUP	A	A	DUPLICATES TOP OF STACK
			A

	OVER	A	B	DUPLICATES TOP - 1
		B	A
			B

	2OVER	A	C	DUPLICATES TOP - 2
		B	A
		C	B
			C

	3OVER	A	D	DUPLICATES TOP - 3
		B	A
		C	B
		D	C
			D

	UNDER	A	A	STORES TOP AT TOP - 1
		B

	2UNDER	A	B	STORES TOP AT TOP - 2
		B	A
		C

	3UNDER	A	B	STORES TOP AT TOP - 3
		B	C
		C	A
		D

	DROP	A	B	DISCARDS TOP
		B

	2DROP	A	C	DISCARDS TOP 2 STACK ENTRIES
		B
		C

	3DROP	A	D	DISCARDS TOP 3 STACK ENTRIES
		B
		C
		D

	SWAP	A	B	EXCHANGES TOP AND TOP - 1
		B	A

	2SWAP	A	A	EXCHANGES TOP - 1 AND TOP - 2
		B	C
		C	B

	FLIP	A	C	EXCHANGES TOP AND TOP - 2
		B	B
		C	A

	+ROT	A	B	ROLL TOP 3 STACK ENTRIES UP
		B	C
		C	A

	-ROT	A	C	ROLL TOP 3 STACK ENTRIES DOWN
		B	A
		C	B

	DDUP	A	A	DUPLICATE THE TOP 2 STACK ENTRIES
		B	B
			A
			B

I/O WORDS
"N" IS THE NUMBER ON THE TOP OF THE STACK.

	COLUMN	VARIABLE CONTAINING THE CURRENT COLUMN NUMBER

	TYO	OUTPUT THE ASCII CHARACTER IN THE RIGHTMOST
		8 BITS OF N.  COLUMN IS INCREMENTED UNLESS THE
		CHARACTER OUTPUT IS A RETURN IN WHICH CASE IT
		IS ZEROED.

	CR	OUTPUT A RETURN FOLLOWED BY A LINE FEED.
		COLUMN IS ZEROED.

	IFCR	OUTPUTS A RETURN, LINE FEED IF COLUMN IS NON-ZERO.

	SPACE	OUTPUT A SPACE.

	SPACES	OUTPUT N SPACES.

	TAB	TAB TO COLUMN N.  IF ALREADY AT OR BEYOND COLUMN
		N, NOTHING IS OUTPUT.

	TYI	INPUT A CHARACTER.

	=	OUTPUT N IN THE CURRENT RADIX FOLLOWED BY SPACE.

	?	OUTPUT THE CONTENTS OF THE LOCATION
		ADDRESSED BY N FOLLOWED BY SPACE.

	TYPE	OUTPUT N CHARACTERS STARTING AT BYTE
		POINTER AT TOP - 1.


WORDS WHICH CHANGE THE CURRENT RADIX

	OCTAL	SET CURRENT RADIX TO OCTAL

	DECIMAL	SET CURRENT RADIX TO DECIMAL

	HEX	SET CURRENT RADIX TO HEXADECIMAL


WORDS USED TO REFERENCE MEMORY LOCATIONS

A REPRESENTS THE TOP OF THE STACK, B REPRESENTS
THE NEXT TO TOP.

	<-	STORE A AT LOCATION B (SAME AS "!" EXCEPT
		ARGUMENTS ARE REVERSED).

	0<-	STORE 0 AT LOCATION A

	-1<-	STORE -1 AT LOCATION A

	+!	ADD B TO THE CONTENTS OF LOCATION A

	1+!	INCREMENT LOCATION A

	1-!	DECREMENT LOCATION A

	MOVE	COPY THE CONTENTS OF THE LOCATION ADDRESSED
		BY B TO THE LOCATION ADDRESSED BY A.

	XCHG	EXCHANGE THE CONTENTS OF LOCATIONS A AND B.

	MVBYTES	COPIES BYTES SEQUENTIALLY FROM ONE AREA TO ANOTHER
		BYTE COUNT AT TOP, SOURCE BYTE ADDRESS AT TOP - 2,
		DESTINATION BYTE ADDRESS AT TOP - 1.

EXAMPLES:

0> 1 MINUS =
-1

0> -1 ABS =
1

0> -1 EQZ =
0

0> 0 EQZ =
-1

0> 1 1 + =
2

0> 1 1 1 + + =
3

0> 1 2 3 = = =
3 2 1

0> 1 2 SWAP = =
1 2

0> 1 2 DUP = = =
2 2 1

0> 1 2 1 - EQ =
-1

0> 100 X ! X ?
100

0> -1 5 MAX =
5

0> -1 5 MIN =
-1


COLON DEFINITIONS

	STOIC PROVIDES THE CAPABILITY OF DEFINING A NEW
WORD IN TERMS OF PREVIOUSLY DEFINED WORDS BY MEANS OF
THE COLON DEFINITION.  ITS SYNTAX IS AS FOLLOWS:

'NEWWORD : WORD1 WORD2 ... WORDN ;

	THIS CREATES A NEW DICTIONARY ENTRY CALLED NEWWORD
WHICH, WHEN EXECUTED, WILL IN TURN EXECUTE WORD1, WORD2,
... IN SEQUENCE.  AFTER EXECUTING WORDN, IT WILL RETURN.
EACH OF THE WORDS WORD1, WORD2, ... MUST ALREADY EXIST
AS ENTRIES IN THE DICTIONARY.  IF NOT, A FATAL ERROR
MESSAGE OF THE FOLLOWING FORM WILL BE GENERATED:

UNDEFINED
(NAME OF UNDEFINED WORD)

	A WORD MAY BE REDEFINED AT ANY TIME.  IN THIS
CASE, ALL PRIOR DEFINITIONS WHICH REFERENCED THAT WORD
WILL STILL EXECUTE THE OLD VERSION.  ALL SUBSEQUENT
DEFINITIONS HOWEVER WILL EXECUTE THE MOST RECENTLY
DEFINED VERSION. REDEFINING A WORD WILL GENERATE THE
FOLLOWING WARNING MESSAGE:

REDEFINING (NAME OF WORD)

EXAMPLES:

'AVERAGE : + 2/ ;

	THIS DEFINES THE WORD AVERAGE WHICH COMPUTES
	THE AVERAGE OF THE TOP 2 NUMBERS ON THE STACK.

	0> 2 4 AVERAGE =
	3

'SPACE : 40 TYO ;

	THIS DEFINES THE WORD "SPACE" WHICH TYPES A SPACE.
	(THE ASCII CODE FOR SPACE IS 40 OCTAL).

	IF THE NAME OF A WORD BEING REDEFINED APPEARS
WITHIN THE NEW DEFINITION, ITS OLD MEANING WILL BE USED.
THE PROCEDURE FOR MAKING RECURSIVE CALLS IS DESCRIBED
BELOW UNDER "RECURSION".


ITERATION

	STOIC PROVIDES FIVE MEANS FOR ITERATIVE
EXECUTION OF A SEQUENCE OF WORDS, NAMELY:

N ( ... )

	EXECUTE THE WORDS INCLUDED IN PARENTHESES N TIMES.

BEGIN ... END

	EXECUTE WORDS BETWEEN "BEGIN" AND "END" UNTIL A CONDITION
	IS SATISFIED.

BEGIN ... IF ... REPEAT

	SIMILAR TO BEGIN ... END EXCEPT THE CONDITION
	IS TESTED AT THE BEGINNING OF THE LOOP.

DO ... LOOP

	EXECUTE THE WORDS BETWEEN "DO" AND "LOOP", RUNNING
	AN INDEX FROM A LOWER TO AN UPPER LIMIT, INCREMENTING
	BY 1 EACH TIME.

DO ... N +LOOP

	EXECUTE THE WORDS BETWEEN "DO" AND "+LOOP", RUNNING
	AN INDEX FROM A LOWER TO AN UPPER LIMIT, INCREMENTING
	BY N EACH TIME.

	ITERATIONS MAY BE NESTED SUBJECT TO THE NORMAL
RESTRICTIONS ON OVERLAPPING RANGES, I.E. ANY ITERATION
WHICH IS INITIATED WITHIN THE RANGE OF ANOTHER ITERATION
MUST BE TERMINATED WITHIN THAT SAME RANGE.


( ... )

	A SEQUENCE OF WORDS MAY BE EXECUTED REPETITIVELY
USING THE FOLLOWING SYNTAX:

N ( WORD1 WORD2 ... WORDN )

	THIS CAUSES THE SEQUENCE WORD1, WORD2, ... TO BE
EXECUTED N TIMES WHERE N IS THE NUMBER ON THE TOP OF THE
STACK.  IF N IS ZERO OR NEGATIVE, THE SEQUENCE OF WORDS
IS NOT EXECUTED AT ALL AND CONTROL PASSES TO THE WORD
FOLLOWING THE ")".

EXAMPLE:

'DINGDING : 2 ( DING ) ;

	THIS DEFINITION IS FUNCTIONALLY EQUIVALENT TO:

	'DINGDING : DING DING ;

	IN EITHER CASE, EXECUTING "DINGDING" CAUSES THE
	WORD "DING" TO BE EXECUTED TWICE.

'SPACES : ( SPACE ) ;

	THIS IS A DEFINITION OF THE WORD "SPACES".
	THUS "20 SPACES" CAUSES "SPACE" TO BE EXECUTED
	20 TIMES.

	AN UNSIGNED VERSION OF PARENTHESIS ITERATION IS USED
WHERE THE ITERATION COUNT IS BETWEEN 32767 AND 65535:

	N U( ... )


BEGIN ... END

	THE BEGIN ... END SYNTAX PERMITS THE USER TO EXECUTE
A SEQUENCE OF WORDS AND THEN, DEPENDING ON A COMPUTED
LOGICAL VARIABLE, EITHER LOOP BACK OR CONTINUE ON:

BEGIN WORD1 WORD2 ... WORDN END

	THE SEQUENCE WORD1, WORD2, ... IS EXECUTED ONCE.
WHEN THE "END" IS REACHED, THE TOP OF THE STACK IS
POPPED AND  TESTED.  IF IT IS TRUE (NON-ZERO) THEN
CONTROL PASSES TO THE WORD FOLLOWING "END".  IF IT IS
FALSE (ZERO) CONTROL PASSES BACK TO THE WORD FOLLOWING
"BEGIN".

EXAMPLE:

	'EXAMPLE : BEGIN 1- DUP DUP = EQZ END DROP ;

	THIS DEFINES THE WORD "EXAMPLE" WHICH MIGHT BE
	CALLED AS FOLLOWS:

	0> 5 EXAMPLE
	4 3 2 1 0

	EACH TIME THROGH THE LOOP, THE TOP OF THE STACK
	(INITIALLY THE NUMBER 5) IS DECREMENTED, PRINTED,
	AND COMPARED TO ZERO.  IF IT IS NOT ZERO, THE
	LOOP IS REPEATED,  WHEN IT BECOMES ZERO, THE LOOP
	TERMINATES.


BEGIN ... IF ... REPEAT

	BEGIN ... IF ... REPEAT IS SIMILAR TO BEGIN ...
END EXCEPT THAT THE TEST IS MADE AT THE BEGINNING OF THE
LOOP RATHER THAN AT THE END.  THE WORDS FROM "BEGIN" TO
"IF" ARE EXECUTED.  IF THE TOP OF THE STACK IS TRUE
(NON-ZERO) THE WORDS BETWEEN "IF" AND "REPEAT" ARE
EXECUTED AND CONTROL THEN PASSES BACK TO THE WORD
FOLLOWING "BEGIN".  IF THE TOP OF THE STACK IS FALSE
(ZERO), CONTROL PASSES TO THE WORD FOLLOWING "REPEAT".

EXAMPLE:

	BEGIN EOF NOT IF READ-RECORD REPEAT

	THIS EXAMPLE MIGHT BE USED TO READ THE CONTENTS
	OF A FILE.  "EOF" RETURNS A -1 IF END OF FILE
	HAS BEEN ENCOUNTERED; A 0 OTHERWISE.  "READ-RECORD"
	READS THE NEXT ENTRY IN THE FILE.  BY TESTING
	FOR EOF AT THE BEGINNING OF THE LOOP, THE
	CASE OF A ZERO-LENGTH FILE IS PROPERLY
	HANDLED.


DO LOOPS

	A DO LOOP FACILITY IS PROVIDED BY STOIC FOR
INDEXING THROUGH A SEQUENCE OF WORDS.  THERE ARE TWO
FORMS OF DO LOOP:

HIGH LOW DO WORD1 WORD2 ... WORDN LOOP

HIGH LOW DO WORD1 WORD2 ... WORDN INCR +LOOP

	THE LIMITS "HIGH" AND "LOW" (THE TOP TWO STACK
ENTRIES) ARE COMPARED.  IF "HIGH" IS LESS THAN OR EQUAL TO
"LOW", CONTROL PASSES TO THE WORD FOLLOWING "LOOP" OR
"+LOOP".  OTHERWISE, THE SEQUENCE WORD1, WORD2, ... IS
EXECUTED.  "LOOP" CAUSES THE LOWER LIMIT ("LOW") TO BE
INCREMENTED BY 1 AND COMPARED TO THE UPPER LIMIT ("HIGH").
IF "LOW" IS EQUAL TO OR GREATER THAN "HIGH", THE LOOP IS
TERMINATED.  OTHERWISE ANOTHER ITERATION IS PERFORMED.
"+LOOP" IS IDENTICAL TO "LOOP" WITH THE EXCEPTION THAT
"LOW" IS INCREMENTED BY THE WORD ON THE TOP OF THE STACK
("INCR").  "INCR" IS NORMALLY A POSITIVE NUMBER.

	WITHIN THE RANGE OF THE LOOP, THE CURRENT VALUE
OF THE LOOP INDEX IS AVAILABLE BY USING THE WORD "I".
IF DO LOOPS ARE NESTED, "I" ALWAYS CONTAINS THE VALUE
OF THE INNERMOST INDEX.  THE NEXT OUTER INDICES ARE
AVAILABLE USING THE WORDS "J" AND "K".  THE WORD "I'"
IS USED TO OBTAIN THE VALUE OF "HIGH"+"LOW"-I-1.  THIS IS
USED TO RUN AN INDEX BACKWARDS FROM "HIGH"-1 TO "LOW".
THE WORDS "J'" AND "K'" ARE SIMILARLY DEFINED.  WHEN
PARENTHESES ARE NESTED WITH "DO" LOOPS, THEY COUNT AS
ONE LEVEL OF INDEXING.  "I" USED WITHIN THE RANGE
OF A PARENTHESIS ITERATION WILL RETURN THE CURRENT VALUE
OF THE ITERATION COUNT (WHICH RUNS FROM ITS INITIAL VALUE
DOWNWARDS TO ONE).

	THE WORD "EXIT", CAUSES THE INNERMOST LOOP IN
WHICH IT IS EMBEDDED TO UNCONDITIONALLY TERMINATE ON THE
NEXT CYCLE, WHETHER A DO LOOP OR A PARENTHESIS LOOP.

EXAMPLES:

	5 0 DO I = LOOP

	THIS CUASES THE NUMBERS FROM 0 TO 4 INCLUSIVE
	TO BE TYPED OUT.

	5 0 DO 5 0 DO J 5 * I + = LOOP CR LOOP

	THIS TYPES OUT THE NUMBERS FROM 0 TO 24
	INCLUSIVE AS 5 LINES OF 5 NUMBERS EACH.

	5 0 DO I' = LOOP

	THIS TYPES OUT THE NUMBERS FROM 4 TO 0
	INCLUSIVE.

	0 21 1 DO I + DUP = 2 +LOOP DROP

	THIS TYPES OUT THE FIRST 10 PERFECT SQUARES
	STARTING WITH 1.

	WHEN USING "I'" (OR "J'" OR "K'") IN CONJUNCTION WITH
"+LOOP", "HIGH" SHOULD BE REPLACED BY "HIGH"-"INCR"+1, IF IT
IS DESIRED TO PRODUCE THE SAME SET OF INDICES AS WITH "I".
FOR EXAMPLE:

	0> 24 0 DO I = 4 +LOOP
	0 4 8 12 16 20

	0> 24 0 DO I' = 4 +LOOP
	23 19 15 11 7 3 1

	0> 24 4 - 1 + 0 DO I' = 4 +LOOP
	20 16 12 8 4 0

	AN UNSIGNED DO LOOP IS USED WHERE THE LIMITS MUST BE
CONSIDERED AS UNSIGNED NUMBERS; E.G. WHERE THE LIMITS ARE BYTE
ADDRESSES IN THE UPPER 32K BYTES OF MEMORY:

	HIGH LOW UDO ... ULOOP
	HIGH LOW UDO ... INCR U+LOOP


CONDITIONALS

	STOIC HAS A POWERFUL IF ... ELSE ... THEN CONSTRUCTION
WHICH ALLOWS COMPLICATED LOGICAL TESTS TO BE PERFORMED.
CONDITIONALS MAY BE NESTED, WITH THE SAME RESTRICTIONS
THAT APPLY TO ITERATIONS.

FOR THE PURPOSES OF THE CONDITIONAL, "TRUE" IS CONSIDERED
TO BE ANY NON-ZERO VALUE; "FALSE" IS ANY ZERO VALUE.

N IF T1 T2 ... TN THEN

	THE TOP OF THE STACK, "N" IS TESTED.

	IF TRUE (NON-ZERO) THE WORDS T1, T2, ... TN ARE
	EXECUTED.

	IF FALSE (ZERO) CONTROL PASSES TO THE WORD
	FOLLOWING "THEN".

N IF T1 T2 ... TN ELSE F1 F2 ... FN THEN

	THE TOP OF THE STACK, "N" IS TESTED.

	IF TRUE (NON-ZERO) THE WORDS T1, T2, ... TN
	ARE EXECUTED; CONTROL THEN PASSES TO THE WORD
	FOLLOWING "THEN".

	IF FALSE (ZERO) CONTROL PASSES TO THE WORD
	FOLLOWING "ELSE".  THE WORDS F1, F2, ... FN ARE
	EXECUTED.

EXAMPLES:

	'ABS : DUP LTZ IF MINUS THEN ;

	THIS DEFINES THE WORD "ABS" WHICH REPLACES THE
	TOP OF THE STACK WITH ITS ABSOLUTE VALUE.

	'MAX : DDUP GT IF DROP ELSE UNDER THEN ;

	THIS DEFINES THE WORD "MAX" WHICH COMPARES THE
	TOP TWO STACK ENTRIES AND LEAVES THE LARGER OF
	THE TWO.


COMMENTS

	THE WORD "%" APPEARING ON A LINE CAUSES THE
REMAINDER OF THAT LINE TO BE IGNORED.  NOTE THAT THE "%",
TO BE RECOGNIZED AS A WORD, MUST BE PRECEDED AND FOLLOWED
BY SPACE OR TAB.

EXAMPLES:

	X @ Y !		% THIS IS A COMMENT
	%THIS IS NOT A COMMENT


USING STOIC FROM THE KEYBOARD

	WHEN TYPING IN A COMMAND FROM THE KEYBOARD,
THE RUBOUT KEY MAY BE USED TO DELETE THE LAST CHARACTER;
TYPING A NULL DELETES THE ENTIRE COMMAND LINE.

	WHEN ACTIVATED, STOIC TYPES A PROMPT MESSAGE
CONSISTING OF THE CURRENT NESTING DEPTH (SEE BELOW)
FOLLOWED BY "> " TO INDICATE THAT IT IS AWAITING KEYBOARD
INPUT.  AT THIS POINT THE OPERATOR TYPES IN A COMMAND LINE.
AS SOON AS RETURN OR FORM FEED IS TYPED, STOIC COMPILES
THE COMMAND LINE AND, IN THE ABSENCE OF COMPILATION ERRORS,
EXECUTES IT.  UPON COMPLETION OF COMMAND EXECUTION, THE
COMPILED CODE FROM THE LAST COMMAND IS DISCARDED AND STOIC
AGAIN TYPES ITS PROMPT MESSAGE AND WAITS FOR THE NEXT COMMAND
LINE.


NESTING DEPTH AND CONTINUATION LINES

	STOIC MAINTAINS A NESTING DEPTH WHICH IS USED
FOR SYNTAX CHECKING AND TO DETERMINE WHEN A MULTI-LINE
COMMAND HAS BEEN COMPLETED AND IS READY TO EXECUTE.
INITIALLY, THE NESTING DEPTH IS SET TO ZERO; IT IS INCREMENTED
WHENEVER ANY OF THE FOLLOWING WORDS ARE ENCOUNTERED DURING
COMPILATION:

IF	ELSE	(	U(	BEGIN	DO	:
UDO

THE NESTING DEPTH IS DECREMENTED BY THE FOLLOWING WORDS:

THEN	ELSE	)	END	LOOP	+LOOP	;
ULOOP	U+LOOP
REPEAT (DECREMENTS NESTING DEPTH BY 2)

IF THE NESTING DEPTH EVER BECOMES NEGATIVE, THE FATAL
ERROR "SYNTAX ERROR" IS GIVEN.  A "SYNTAX ERROR" IS ALSO
GENERATED IF THE NESTING DEPTH IS NON-ZERO EITHER AT THE
BEGINNING OR AT THE END OF A COLON DEFINITION.

	AFTER COMPILING A LINE, STOIC CHECKS THE NESTING
DEPTH; IF IT IS ZERO, THE LINE IS EXECUTED, IF NON-ZERO,
IT CONTINUES COMPILATION ON THE NEXT LINE.  FOR EXAMPLE:

	0> 3 0 DO
	1> 2 0 DO
	2> I =
	2> LOOP
	1> CR
	1> LOOP
	0 1
	0 1
	0 1
	0>

THUS, THE EXECUTION OF THE DO LOOP IS AUTOMATICALLY
POSTPONED UNTIL THE NESTING DEPTH RETURNS TO ZERO,
I.E. WHEN THE "LOOP" MATCHING THE FIRST "DO" IS ENCOUNTERED.
SIMILARLY, A MULTI-LINE COLON DEFINITION IS EXTENDED TO
INCLUDE ALL WORDS UP TO THE MATCHING ";".

	EXECUTION OF COMPILED CODE MAY BE POSTPONED
EVEN IF THE NESTING DEPTH IS ZERO BY USING THE WORD
"^".  IF "^" IS USED ANYWHERE ON A LINE, COMPILATION
WILL UNCONDITIONALLY CONTINUE ON TO THE NEXT LINE.
THIS FEATURE MAY BE USED AS FOLLOWS:

	0> 5 0 DO I = LOOP ^
	0> 5 0 DO I = LOOP
	0 1 2 3 4 0 1 2 3 4
	0>

	A MORE REASONABLE APPLICATION OF "^" INVOLVES
THE USE OF STRING LITERALS.  SINCE COMPILED CODE OUTSIDE
OF A COLON DEFINITION IS DISCARDED AFTER EXECUTION,
STRING LITERALS TYPED IN ON ONE LINE ARE NOT ACCESIBLE TO
SUBSEQUENT LINES UNLESS "^" IS USED TO FORCE THE
COMPILED STRING LITERAL TO BE SAVED.  FOR EXAMPLE:

0> \THIS IS A LONG MESSAGE WHICH USES THE ENTIRE LINE\ ^
0> MSG
THIS IS A LONG MESSAGE WHICH USES THE ENTIRE LINE
0>

REPEATING THE LAST COMMAND LINE

	TYPING A LINE FEED CAUSES STOIC TO RECOMPILE AND RE-EXECUTE
THE LAST COMMAND LINE EXECUTED. FOR EXAMPLE:

0> 2 2 + =
4
0>		(LINE FEED TYPED)
4
0>		(LINE FEED TYPED)
4


ERROR HANDLING

	THE FOLLOWING TWO WORDS ARE USED TO HANDLE FATAL
ERRORS IN STOIC:

	ABORT	CLEARS THE PARAMETER, RETURN, AND LOOP
		STACKS, RESETS THE NESTING DEPTH TO ZERO,
		AND FORCES CONTROL TO RETURN TO THE
		KEYBOARD.  "ABORT" IS INVOKED BY CONTROL A.

	ERR	TYPES THE STRING AT THE TOP OF THE STACK
		FOLLOWED BY THE NAME OF THE WORD LAST
		SCANNED FROM THE INPUT STREAM, AND, IF
		INPUT IS NOT COMING FROM THE KEYBOARD,
		THE LINE LAST COMPILED FROM THE INPUT FILE.
		"ABORT" IS THEN INVOKED TO RESET STOIC.


DEFINING CONSTANTS, VARIABLES, AND ARRAYS

CONSTANTS

	A CONSTANT IS A DICTIONARY ENTRY WHICH CAUSES A
16-BIT INTEGER TO BE PUSHED ON THE PARAMETER STACK.  TO
DEFINE A CONSTANT, THE WORD "CONSTANT" IS USED:

VALUE 'NAME CONSTANT

	HERE, "VALUE" IS THE NUMBER ON THE TOP OF THE
STACK AND "NAME" IS THE NAME TO BE ASSIGNED TO THE
CONSTANT.

EXAMPLE:

	5 'NPTS CONSTANT

	THIS SETS UP A DICTIONARY ENTRY WITH NAME
	"NPTS".  EXECUTING THE WORD "NPTS" WILL CAUSE
	A 5 TO BE PUSHED ON THE STACK.

VARIABLES

	A VARIABLE IS A DICTIONARY ENTRY WHICH CONTAINS
A 16-BIT INTEGER AS ITS VALUE.  WHEN EXECUTED, IT CAUSES
THE ADDRESS OF ITS VALUE TO BE PUSHED ON THE PARAMETER
STACK.  VARIABLES ARE DEFINED AS FOLLOWS:

VALUE 'NAME VARIABLE

	"VALUE" IS THE NUMBER ON THE TOP OF THE STACK
AND "NAME" IS THE NAME TO BE ASSIGNED TO THE VARIABLE.
"VALUE" IS USED TO SET THE INITIAL VALUE OF THE VARIABLE.

EXAMPLE:

	100 'X VARIABLE

	THIS DEFINES A VARIABLE "X" WITH AN INITIAL
	VALUE OF 100.


ARRAYS

	WHILE STOIC DOES NOT HAVE A BUILT-IN ARRAY
HANDLING FACILITY, ITS ABILITY TO PERFORM ADDRESS
ARITHMETIC MAKES SUBSCRIPTING POSSIBLE.  THERE
ARE SEVERAL METHODS FOR SETTING ASIDE STORAGE FOR
AN ARRAY.  THE SIMPLEST IS TO USE THE WORD "ARRAY":

	LENGTH 'NAME ARRAY

	THIS DEFINES AND ZEROS AN ARRAY WHOSE LENGTH (IN
	16-BIT WORDS) AND NAME ARE SPECIFIED.  THE ARRAY IS
	JUST A VARIABLE WITH EXTRA STORAGE LOCATIONS
	RESERVED.  REFERENCING AN ARRAY THUS CAUSES
	THE ADDRESS OF THE ZEROTH ELEMENT TO BE PUSHED.

	EXAMPLE:

	100 'BUFFER ARRAY

	THIS DEFINES AND ZEROES A 100-WORD ARRAY NAMED
	"BUFFER".

	AN EXAMPLE OF A CONVENIENT TECHNIQUE FOR
	DEFINING SMALL ARRAYS IS :

	0 '3VEC VARIABLE 1 , 2 ,

	THIS DEFINITION SETS UP A 3-VECTOR CALLED "3VEC"
	WHOSE INITIAL VALUE IS (0,1,2).  THE WORD ","
	TAKES A NUMBER FROM THE TOP OF THE STACK AND
	APPENDS IT TO THE END OF THE DICTIONARY,
	AUTOMATICALLY EXTENDING THE LENGTH OF THE
	MOST RECENT DEFINITION.  THIS SERVES THE
	DUAL FUNCTIONS OF RESERVING SPACE IN THE
	DICTIONARY AND INITIALIZING THE ARRAY.


THE CONTENTS OF AN ARRAY MAY BE INITIALIZED TO ZERO OR
ANY CONSTANT VALUE USING THE FOLLOWING WORDS:

	FILL	FILLS AN ARRAY WHOSE ADDRESS IS AT TOP-2
		AND HAS LENGTH (IN WORDS) AT TOP-1 WITH THE
		CONSTANT VALUE AT TOP.

	0FILL	ZERO FILLS AN ARRAY WHOSE ADDRESS IS AT
		TOP-1 AND HAS LENGTH (IN WORDS) AT TOP.

	EXAMPLE:

	100 'X ARRAY
	X 100 -1 FILL

	THIS DEFINES A 100-WORD ARRAY "X" WHICH IS THEN
	FILLED WITH -1'S.  EQUIVALENTLY, THE SAME ACTION
	IS PERFORMED BY:

	-1 'X VARIABLE 99 ( -1 , )


REFERENCING ARRAY ELEMENTS

	TO REFERENCE AN ELEMENT OF AN ARRAY, ALL THAT IS
NECESSARY IS TO ADD AN APPROPRIATE OFFSET TO THE ADDRESS
OF THE ZEROTH ELEMENT.  NOTE THAT SINCE THE FIRST ELEMENT
HAS OFFSET ZERO, THE NTH ELEMENT HAS OFFSET N-1.

EXAMPLE:

	10 'X ARRAY
	10 0 DO I X I 2* + ! LOOP

	THE ABOVE CODE DEFINES A 10 ELEMENT ARRAY "X"
	AND FILLS IT WITH THE NUMBERS 0 TO 9.

	NOTE THAT SINCE ADDRESSES ARE IN BYTES, THE
	INDEX MUST BE MULTIPLIED BY 2.

	MULTIDIMENSIONAL SUBSCRIPTING IS HANDLED IN A
SIMILAR FASHION.

EXAMPLE:

	100 'X ARRAY
	10 0 DO 10 0 DO I J + J 10 * I + 2* X + ! LOOP LOOP

	THIS EXAMPLE SETS UP A 100 ELEMENT ARRAY "X"
	WHICH IS TREATED AS A 10 BY 10 MATRIX AND
	THEN STORES I+J IN THE ELEMENT (I,J).


THE DICTIONARY

	THE DICTIONARY STARTS IN LOW CORE AND GROWS
UPWARD TOWARD THE TOP OF MEMORY.  EACH DEFINITION, AS
IT IS MADE, IS APPENDED TO THE END OF THE DICTIONARY.
THE VARIABLE ".D" IS A POINTER TO THE FIRST FREE WORD
FOLLOWING THE END OF THE DICTIONARY.

THE WORD "." PUSHES THE VALUE OF THE DICTIONARY
POINTER (".D") AND IS EQUIVALENT TO TYPING ".D @".

	THE ADDRESS OF A DICTIONARY ENTRY MAY BE
OBTAINED BY INVOKING THE FOLLOWING WORD:

	() NAME

		PUSHES ON THE STACK THE ADDRESS OF
		THE PARAMETER FIELD OF THE NAMED
		WORD.

	THIS WORD MAKES IT POSSIBLE TO MODIFY THE
	VALUE OF A CONSTANT.  FOR EXAMPLE:

	100 'N CONSTANT
	200 () N !

	THE FIRST LINE DEFINES A CONSTANT "N" WHOSE
	VALUE IS 100.  THE NEXT LINE RESETS THE VALUE
	TO 200.

	THIS FEATURE SHOULD NOT BE USED IN ANY PROGRAM
	WHICH WILL SUBSEQUENTLY BE COMMITTED TO READ-
	ONLY MEMORY.

	THE FOLLOWING WORD IS USED TO OBTAIN THE
	ADDRESS OF A WORD IN THE DICTIONARY GIVEN
	ITS NAME:

	ADDRESS		TAKES A STRING ARGUMENT ON
			THE STACK WHICH IS LOOKED
			UP IN THE DICTIONARY.  IF
			NOT FOUND, AN ERROR MESSSAGE
			IS TYPED.  IF FOUND, THE ADDRESS
			OF THE PARAMETER FIELD OF THE
			WORD IS RETURNED ON THE STACK.

	EXAMPLE:

	'NEWVAL : ADDRESS 200 SWAP ! ;

	THIS DEFINES A WORD "NEWVAL" WHICH SETS THE
	PARAMETER FIELD OF ITS ARGUMENT TO 200.
	THUS,

	'N NEWVAL

	IS EQUIVALENT TO THE PREVIOUS EXAMPLE.


EXECUTING PROGRAMS

	STOIC PROGRAMS ARE STORED AS ASCII SOURCE
FILES.  EXECUTING A FILE CAUSES STOIC TO ACCEPT ITS
COMMANDS FROM THE FILE INSTEAD OF THE KEYBOARD.
FILE EXECUTION IS CONTROLLED BY THE FOLLOWING WORDS:

	LOAD	EXECUTE A PROGRAM; ADDRESS OF NAME IS
		ON TOP OF STACK.

	;F	TERMINATES EXECUTION OF THE CURRENT FILE
		AND RETURNS CONTROL TO THE CALLING INPUT
		FILE OR TO THE SYSTEM KEYBOARD.

SINCE STOIC USES THE LOOP STACK TO SAVE CERTAIN INTERPRETER
VARIABLES WHEN EXECUTING "LOAD", NO EXECUTED FILE MAY
PUSH ANYTHING ON THE LOOP STACK THAT IS NOT REMOVED WITHIN
THAT SAME FILE.  "LOAD" WORKS BY MODIFYING THE STOIC READ-
NEXT-LINE ROUTINE SO THAT IT ACCEPTS INPUT FROM THE SPECIFIED
FILE INSTEAD OF THE KEYBOARD.  THUS, "LOAD" DOES NOT CAUSE
THE CONTENTS OF THE FILE TO BE EXECUTED UNTIL THE CURRENT
LINE HAS BEEN EXECUTED.

EXAMPLES:

	'DEFS LOAD

	THIS EXECUTES A FILE CALLED "DEFS"

	'LDDEFS : . = 'DEFS LOAD ;

	THIS DEFINES "LDDEFS" WHICH TYPES OUT THE
	CURRENT VALUE OF THE DICTIONARY POINTER AND
	EXECUTES "DEFS".

	'A LOAD 'B LOAD 'C LOAD

	THIS COMMAND LINE CAUSES ONLY THE CONTENTS OF FILE
	"C" TO BE EXECUTED AND LEAVES SEVERAL EXTRANEOUS
	NUMBERS ON THE LOOP STACK.  MULTIPLE LOADS MAY NOT
	BE EXECUTED FROM THE SAME COMMAND LINE; THEY MUST
	BE SEPARATED BY CARRIAGE RETURNS.  THUS, THE CORRECT
	WAY TO LOAD THE THREE FILES IS:

	'A LOAD
	'B LOAD
	'C LOAD


STOIC FILE SYSTEM

	THE STOIC FILE SYSTEM SUPPORTS CONTIGUOUS FILES WHICH
ARE REFERENCED BY SIX-LETTER NAMES.  THESE NAMES AND THE LOCATIONS
OF THE FILES ON THE STORAGE MEDIUM ARE STORED IN A DIRECTORY
WHICH OCCUPIES BLOCK ZERO.  NEW FILES ARE ALWAYS ADDED AT THE
END OF THE MEDIUM.  THE BLOCKS TAKEN UP BY A FILE WHICH HAS BEEN
DELETED ARE NOT AVAILABLE UNTIL THE WORD "SQUASH" HAS BEEN EXECUTED.
"SQUASH" SLIDES ALL THE FILES DOWN AND RESTRUCTURES THE DIRECTORY
TO ELIMINATE ALL GAPS.  THE FOLLOWING WORDS CONTROL DIRECTORY
MAINTENANCE AND FILE ACCESS:

ZERO-DIRECTORY	INITIALIZES THE DIRECTORY.  THE PREVIOUS CONTENTS
		OF THE DIRECTORY ARE LOST.

LIST-DIRECTORY	TYPES A DIRECTORY LISTING IN TWO COLUMNS.

LEFT		RETURNS ON THE STACK THE NUMBER OF UNUSED BLOCKS
		ON THE STORAGE MEDIUM.

CCONT		CREATES A CONTIGUOUS FILE WHOSE LENGTH (IN BLOCKS)
		IS AT THE TOP OF THE STACK, THE NAME IS AT TOP - 1.

DELETE		DELETES THE FILE WHOSE NAME IS AT TOP OF STACK.

RENAME		RENAMES FILE WHOSE NAME IS AT TOP - 1 TO NAME AT TOP.

FILE		CREATES A 3-WORD FILE CONTROL TABLE WHOSE NAME IS AT
		TOP.  WHEN REFERENCED, THE ADDRESS OF THE FILE CONTROL
		TABLE IS STORED IN THE VARIABLE "FCT".  THIS CAUSES
		THE FILE CONTROL TABLE TO BECOME THE CURRENT FILE
		CONTROL TABLE.

OPEN		OPENS THE FILE WHOSE NAME IS AT TOP USING THE CURRENT
		FILE CONTROL TABLE.  THE NUMBER OF THE FIRST BLOCK OF
		THE FILE IS STORED IN THE FIRST WORD OF THE FILE CONTROL
		TABLE AND THE OTHER TWO WORDS ARE ZEROED.

WOPEN		OPENS A FILE FOR WRITING; FILE NAME AT TOP OF STACK.
		ANY PREVIOUS VERSION OF THE FILE IS DELETED, A NEW
		VERSION IS CREATED WHOSE LENGTH IS EQUAL TO THE ENTIRE
		REMAINING FREE SPACE, AND THE FILE IS OPENED USING
		THE CURRENT FILE CONTROL TABLE.  IF MORE THAN ONE
		OUTPUT FILE IS ACTIVE AT A TIME, ALL BUT ONE OF THEM
		MUST BE CREATED WITH "CCONT" AND OPENED WITH "OPEN",
		GIVING THE FILE LENGTH IN ADVANCE.  THE LAST ONE MAY
		BE VARIABLE LENGTH AND OPENED WITH "WOPEN".

SHRINK		USING THE CURRENT FILE CONTROL TABLE, THE END OF
		THE DIRECTORY IS MOVED DOWN TO THE FIRST FREE BLOCK
		FOLLOWING THE CURRENT FILE.  THIS WORD IS USED ONLY
		WITH FILES WHICH HAVE BEEN OPENED USING "WOPEN" TO
		RELEASE WHATEVER STORAGE IS NOT USED BY THE OUTPUT
		FILE.

CLOSE		ZEROES THE FIRST WORD OF THE CURRENT FILE CONTROL
		TABLE, SIGNALLING IT AS INACTIVE.

GETBYTE		USING THE CURRENT FILE CONTROL TABLE,
		RETURNS THE NEXT BYTE FROM THE FILE.

GETBYTES	USING THE CURRENT FILE CONTROL TABLE, AND TAKING
		A BYTE COUNT AT TOP AND A BUFFER ADDRESS AT TOP - 1,
		THE SPECIFIED NUMBER OF BYTES ARE READ FROM THE FILE
		INTO THE BUFFER.

PUTBYTE		USING THE CURRENT FILE CONTROL TABLE,
		STORES BYTE AT TOP IN NEXT BYTE OF FILE.

PUTBYTES	USING THE CURRENT FILE CONTROL TABLE, AND TAKING
		A BYTE COUNT AT TOP AND A BUFFER ADDRESS AT TOP - 1,
		THE SPECIFIED NUMBER OF BYTES ARE WRITTEN INTO THE FILE
		FROM THE BUFFER.

GPOS		USING THE CURRENT FILE CONTROL TABLE,
		RETURNS A DOUBLE PRECISION INTEGER FILE POSITION
		AT TOP AND TOP - 1.  (MOST SIGNIFICANT WORD AT TOP).

SPOS		USING THE CURRENT FILE CONTROL TABLE
		SETS THE FILE POSITION TO THE DOUBLE PRECISION
		INTEGER VALUE AND TOP AND TOP - 1.

EXIST		SEARCHES THE DIRECTORY FOR THE NAME AT TOP.  IF
		FOUND, THE ADDRESS OF THE DIRECTORY ENTRY IS LEFT AT
		TOP.  IF NOT FOUND, THE ERROR "FILE DOES NOT EXIST"
		IS GIVEN.

NOT-EXIST	SEARCHES THE DIRECTORY FOR THE NAME AT TOP.  IF
		FOUND, THE ERROR "FILE ALREADY EXISTS" IS GIVEN.

OPEN?		GIVES THE MESSAGE "FILE NOT OPEN" IF THE
		CURRENT FILE CONTROL TABLE IS NOT OPEN.

FSQUASH		REMOVES DELETED ENTRIES FROM THE END OF THE
		DIRECTORY.  DELETED ENTRIES WITHIN THE
		DIRECTORY ARE NOT AFFECTED.  FSQUASH IS
		CALLED AUTOMATICALLY AFTER A "DELETE".

SQUASH		REMOVES ALL DELETED ENTRIES FROM THE DIRECTORY.
		THE REMAINING FILES ARE MOVED DOWN TO FILL UP
		THE EMPTY SPACE.

SEARCH		SEARCHES THE DIRECTORY FOR THE NAME AT TOP.  IF
		FOUND, A -1 IS RETURNED AT TOP AND A POINTER TO
		THE DIRECTORY ENTRY AT TOP - 1.  IF NOT FOUND,
		A ZERO IS LEFT AT TOP.

DIRECTORY	RETURNS ON THE TOP OF THE STACK THE ADDRESS OF
		THE FIRST BYTE OF A BUFFER CONTAINING THE
		DIRECTORY.

SLOT		RETURNS THE ADDRESS OF THE END-OF DIRECOTRY ENTRY
		IN THE DIRECTORY BUFFER.

SBLK		GIVEN THE ADDRESS OF A DIRECTORY ENTRY AT TOP, RETURNS
		THE STARTING BLOCK NUMBER FOR THE FILE.

PRINT		TYPES OUT ON THE SYSTEM CONSOLE THE CONTENTS OF THE
		FILE WHOSE NAME IS AT TOP.

COPY		COPIES THE FILE WHOSE NAME IS AT TOP - 1 TO A FILE
		WHOSE NAME IS AT TOP.  THE DESTINATION FILE IS CREATED
		AT THE END OF THE DIRECTORY; ANY PREVIOUS VERSION IS
		DELETED.


DIRECTORY ENTRY FORMAT:

WORD	CONTENTS

0	1ST WORD OF NAME
	 (= -1 IF DELETED)
	 (=  0 IF END OF DIRECTORY)

1	2ND WORD OF NAME

2	3RD WORD OF NAME

3	NUMBER OF FIRST BLOCK OF FILE
	 (NUMBER OF FIRST FREE BLOCK IF 1ST WORD = 0)


FILE CONTROL TABLE FORMAT:

WORD	CONTENTS

0	NUMBER OF FIRST BLOCK OF FILE
	(= 0 IF NOT OPEN)

1	CURRENT RELATIVE BLOCK NUMBER

2	CURRENT RELATIVE BYTE NUMBER WITHIN CURRENT BLOCK


BASIC BLOCK I/O WORDS

	THE FILE SYSTEM IS BUILT ON A SET OF LOWER LEVEL WORDS
WHICH MAY BE USED DIRECTLY BY THE USER TO PERFORM OPERATIONS
ON BLOCKS OF STORAGE:

L M N RDBLKS	READS N BLOCKS STARTING AT BLOCK M INTO MEMORY
		STARTING AT LOCATION L.

L M N WRBLKS	WRITES N BLOCKS STARTING AT BLOCK M FROM MEMORY
		STARTING AT LOCATION L.

BUFFER HANDLING WOWRS

	STOIC MAINTAINS A POOL OF SYSTEM BUFFERS WHICH ARE
USED TO HOLD BLOCKS FROM THE STORAGE MEDIUM IN MEMORY.  THEY
ARE ALLOCATED USING A "LEAST RECENTLY USED" ALGORITHM.

RBLOCK	RETURNS THE ADDRESS OF A BUFFER CONTAINING THE BLOCK
	WHOSE NUMBER IS AT TOP.  WHEN A BLOCK IS REQUESTED USING
	"RBLOCK", IF THE SPECIFIED BLOCK IS ALREADY IN MEMORY,
	ITS ADDRESS IS IMMEDIATELY RETURNED.  IF IT IS NOT IN
	MEMORY, THE LEAST RECENTLY USED BUFFER IS FREED (I.E.
	WRITTEN OUT IF MODIFIED), AND THE BLOCK IS READ IN.

WBLOCK	RETURNS THE ADDRESS OF A BUFFER CONTAINING THE BLOCK
	WHOSE NUMBER IS AT TOP.  THE BUFFER IS FLAGGED AS
	MODIFIED.  IF THE BLOCK IS NOT ALREADY IN MEMORY, IT
	IS NOT READ IN.

FLUSH	WRITES OUT ALL MODIFIED BUFFERS.  THIS WORD MUST BE
	EXECUTED BEFORE SHUTTING DOWN THE SYSTEM OR CHANGING
	MEDIA TO ENSURE THAT THE INFORMATION ON THE STORAGE
	MEDIUM IS CURRENT.

EBUF	FLAGS ALL BUFFERS AS EMPTY.  THIS WORD MUST BE USED
	WHEN CHANGING MEDIA.

UPDATE	FLAGS THE MOST RECENTLY ACCESSED BUFFER AS MODIFIED.
	WHENEVER THE VALUE OF ANY WORD WITHIN AN I/O BUFFER
	IS MODIFIED, THIS WORD MUST BE CALLED, OTHERWISE THE
	MODIFIED VERSION WILL NOT BE WRITTEN BACK ON THE
	STORAGE MEDIUM.


SAVING AND RESTORING CORE IMAGES

	TWO WORDS ARE PROVIDED WITHIN THE KERNEL WHICH
ENABLE THE USER TO SAVE A "SNAPSHOT" OF THE DICTIONARY AND
ALL STOIC VARIABLES IN A FILE AND, AT A LATER TIME, TO
RESTORE THE SAVED STATE OF MACHINE AND RESUME EXECUTION.
THEIR USE IS OUTLINED BELOW:

	'FILE WRCI	WRITE A CORE IMAGE INTO THE NAMED FILE

	'FILE RDCI	READ A CORE IMAGE FROM THE NAMED FILE

	THE CONTENTS OF THE I/O BUFFERS ARE NOT SAVED AS PART
OF THE CORE IMAGE FILE, BUT ALL OTHER VARIABLES USED BY THE KERNEL,
THE CONTENTS OF ALL STACKS, THE INTERRUPT DISPATCH TABLE, AND ALL
USER DEFINITIONS ARE TRANSFERRED.

	CORE IMAGE FILES MUST BE REGENERATED WHENEVER A NEW VERSION
OF THE KERNEL IS USED SINCE THE NEW USER DEFINITIONS REFERENCE
ABSOLUTE LOCATIONS WITHIN THE KERNEL.

	TO GENERATE A BOOTSTRAPPABLE FILE CONTAINING THE STOIC KERNEL
PLUS ALL CURRENT USER DEFINITIONS, THE FOLLOWING COMMAND IS USED:

	'FILE WRITE-BOOT	WRITES A BOOTSTRAP FILE.

THE BOOTSTRAP FILE CAN THEN BE LOADED DIRECTLY BY THE BOOTSTRAP BY
RESPONDING WITH THE FILENAME TO THE INITIAL PROMPT.


STRING HANDLING

	STOIC STRINGS ARE STORED IN MEMORY IN THE
	FOLLOWING FORMAT:

	<LENGTH>STRING<0>

	THE LENGTH BYTE DOES NOT INCLUDE THE TERMINATING
	NULL.  THE STRING MAY INCLUDE NULLS BEFORE THE
	FINAL ONE.  THE LENGTH FIELD MUST BE LESS THAN
	128 DECIMAL.

	EXAMPLE:

	<4>ABCD<0>

	THIS IS THE INTERNAL REPRESENTATION OF THE
	STRING "ABCD".

	EXECUTING A STRING LITERAL CAUSES A POINTER TO
THE FIRST BYTE OF THE STRING TO BE PUSHED ON THE STACK.
THIS POINTER MAY BE CONVERTED INTO BYTE-POINTER,
BYTE-COUNT FORM BY USING THE WORD "COUNT" DESCRIBED
BELOW.

COUNT

	"COUNT" TAKES A POINTER TO A STRING AS INPUT ON
THE STACK AND LEAVES THE LENGTH OF THE STRING ON THE TOP
OF THE STACK, AND A BYTE POINTER TO THE FIRST CHARACTER
FOLLOWING THE LENGTH BYTE AT TOP - 1.

MSG

	THE WORD "MSG" IS EQUIVALENT TO "COUNT TYPE".
	GIVEN A POINTER TO A STRING AT TOP, IT CAUSES
	THE STRING TO BE TYPED.

S,

	"S," TAKES A STRING ARGUMENT ON THE TOP OF THE STACK
	AND COPIES THE STRING ONTO THE END OF THE DICTIONARY.
	THE END OF THE DICTIONARY IS EXTENDED TO PERMANENTLY
	INCLUDE THE STRING.


EXAMPLES:

	'LARK : 'NONSENSE MSG ;

	EXECUTING "LARK" CAUSES "NONSENSE" TO BE TYPED.


NUMBER OUTPUT CONVERSION

	STOIC PREFORMS NUMBER CONVERSION USING A SMALL
BUT POWERFUL SET OF WORDS WHICH PERMIT A WIDE VARIETY OF
OUTPUT FORMATS TO BE GENERATED.  NUMBER CONVERSION
PROCEEDS FROM RIGHT TO LEFT, CONVERTING ONE DIGIT AT A TIME.
THE CONVERSION TAKES PLACE IN THE CURRENT RADIX.  DIGITS
ARE STORED IN A TEMPORARY AREA AT THE END OF THE DICTIONARY
SET UP BY "<#".

RADIX	VARIABLE WHICH CONTAINS CURRENT INPUT AND
	OUTPUT RADIX.

<#	INITIATE NUMBER CONVERSION.

#PUT	OUTPUT A CHARACTER FROM TOP OF STACK.

#A	CONVERT THE NUMBER ON THE TOP OF THE STACK
	TO AN ASCII DIGIT.

#	COMPUTE THE NEXT DIGIT AND OUTPUT IT.
	AN INTEGER IS INPUT FROM THE TOP OF THE STACK
	AND DIVIDED BY "RADIX".  THE REMAINDER IS
	CONVERTED TO A DIGIT AND OUTPUT; THE
	QUOTIENT REMAINS ON THE STACK.

#S	COMPUTE DIGITS AND OUTPUT THEM UNTIL THE
	REMAINING NUMBER IS ZERO.  "#S" ALWAYS OUTPUTS
	AT LEAST ONE DIGIT.

#>	TERMINATE THE NUMBER CONVERSION, LEAVING A
	BYTE COUNT ON TOP OF STACK, A BYTE POINTER AT
	TOP - 1.

HIGHER LEVEL WORDS ARE USED TO PROVIDE NUMBER OUTPUT
IN A DEFAULT FORMAT:

U<#>	CONVERT THE UNSIGNED NUMBER ON THE TOP OF THE STACK
	AND LEAVE BYTE COUNT AND BYTE POINTER ON THE STACK.
	"U<#>" IS DEFINED  AS:

	'U<#> : <# #S #> ;

<#>	CONVERT THE SIGNED NUMBER ON THE TOP OF THE STACK
	AND LEAVE BYTE COUNT AND BYTE POINTER ON THE STACK.
	"<#>" IS DEFINED AS:

	'<#> : DUP <L <# #S  L> LTZ IF 55 #PUT THEN #> ;

U=	CONVERT AND OUTPUT THE NUMBER ON THE TOP OF THE
	STACK. (UNSIGNED)

=	CONVERT AND OUTPUT THE NUMBER ON THE TOP OF THE
	STACK. (SIGNED)

U?	CONVERT AND OUTPUT THE NUMBER ADDRESSED BY THE
	TOP OF THE STACK.  (UNSIGNED)

?	CONVERT AND OUTPUT THE NUMBER ADDRESSED BY THE
	TOP OF THE STACK.  (SIGNED)


EXAMPLE:

	'$= : <# # # 56 #PUT #S 44 #PUT #> TYPE ;
	(RADIX IS ASSUMED TO BE OCTAL)

	0> 100 $=
	$1.00
	0> 1000 $=
	$10.00

	"$=" TYPES THE TOP OF THE STACK IN AN UNSIGNED
	DOLLAR AND CENTS FORMAT.  NUMBER CONVERSION IS
	INITIATED BY "<#", THE CENTS ARE OUTPUT BY THE
	TWO "#"'S, A PERIOD IS OUTPUT BY "56 #PUT", THE
	REMAINING DOLLARS ARE OUTPUT BY "#S", AND THE
	DOLLAR SIGN IS OUTPUT BY "44 #PUT".  "<# TERMINATES
	THE CONVERSION PROCESS AND LEAVES A BYTE POINTER
	AND BYTE COUNT FOR THE RESULTANT STRING ON THE STACK
	AS INPUT TO "TYPE" WHICH OUTPUTS THE STRING.

	JUSTIFICATION OF NUMERIC OUTPUT MAY BE ACHIEVED
	AS FOLLOWS:

	'4= : <#> 4 OVER - SPACES TYPE ;

	THE WORD "4=" WILL TYPE OUT NUMBERS RIGHT
	JUSTIFIED IN A FOUR COLUMN FIELD BY TYPING
	A VARIABLE NUMBER OF SPACES PRECEDING THE
	NUMBER.


TYI AND TYO

	"TYI" AND "TYO" PROVIDE A GENERALIZED CHARACTER
ORIENTED INPUT AND OUTPUT FACILITY.  "TYI" INPUTS A
CHARACTER BY EXECUTING THE WORD WHOSE ADDRESS IS
CONTAINED IN THE VARIABLE "IN".  "TYO", SIMILARLY
EXECUTES THE CONTENTS OF "OUT".  "IN" AND "OUT" ARE
INITIALIZED TO POINT TO "<TTI>", AND "<TTO>", WHICH ARE
TELETYPE INPUT AND OUTPUT WORDS.  ANY WORD WHICH USES
"TYO" FOR OUTPUT MAY BE MODIFIED TO OUTPUT ON ANOTHER
DEVICE OR PERHAPS INTO A CORE BUFFER BY CHANGING "OUT".
SIMILARLY, CHANGING "IN" WILL MODIFY THE INPUT OF ANY
WORD USING "TYI".  "TYPE", "MSG" AND ALL THE NUMBER
CONVERSION ROUTINES USE "TYO" TO PERFORM OUTPUT.


RECURSION

	SINCE STOIC IS A STACK ORIENTED LANGUAGE,
RECURSION IS HANDLED QUITE EASILY.  THE WORD "EXEC"
TAKES AS AN ARGUMENT ON THE STACK THE ADDRESS OF A WORD
TO BE EXECUTED AND CALLS IT.  BY PLACING THE ADDRESS OF
THE CALLING ROUTINE ITSELF ON THE STACK, A RECURSIVE
CALL IS GENERATED.

EXAMPLE:

0 'SELF VARIABLE
'FACTORIAL :  DUP 1 NE IF DUP 1- SELF @ EXEC * THEN ;
() FACTORIAL SELF !

THIS DEFINES A RECURSIVE FACTORIAL ROUTINE.


VOCABULARIES

	IN ADDITION TO THE PARAMETER STACK, STOIC USES
ANOTHER STACK CALLED THE VOCABULARY STACK.  THIS STACK
IS USED TO CONTROL DICTIONARY LOOKUP OPERATIONS.

	WHEN STOIC LOOKS UP A WORD IN THE DICTIONARY, IT
STARTS ITS SEARCH AT A LOCATION WHOSE ADDRESS IN STORED
ON THE TOP OF THE VOCABULARY STACK.  IF THE SEARCH
FAILS, IT SEARCHES AGAIN USING THE NEXT TO TOP OF THE
VOCABULARY STACK, ETC. UNTIL THE BOTTOM OF THE
VOCABULARY STACK IS REACHED.  IF THE NAME IS STILL
NOT FOUND, THE SEARCH FAILS.

	THE DICTIONARY MAY HAVE ANY NUMBER OF BRANCHES.
DIFFERENT WORDS HAVING EXACTLY THE SAME NAMES MAY BE
RESOLVED IF THEY ARE ON SEPARATE BRANCHES OF THE
DICTIONARY.  A BRANCH OF THE DICTIONARY IS CALLED A
VOCABULARY.

	WHEN STOIC DEFINES A NEW WORD, THE DICTIONARY
ENTRY IS APPENDED TO THE BRANCH POINTED TO BY THE
VARIABLE "CURRENT".

	THE KERNEL HAS TWO VOCABULARIES, CALLED "STOIC<",
AND "ASSEMBLER<".  INITIALLY, THE VOCABULARY STACK
CONTAINS ONLY THE ADDRESS OF "STOIC<".  "ASSEMBLER<" IS
USED WHEN MAKING CODE DEFINITIONS AND CONTAINS SPECIAL
WORDS USED ONLY BY THE STOIC ASSEMBLER.  "STOIC<" IS THE
MAIN BRANCH OF THE DICTIONARY, AND "ASSEMBLER<" IS A
SIDE-BRANCH.

	A NEW BRANCH OF THE DICTIONARY IS CREATED AS
	FOLLOWS:

	'NAME BRANCH

	REFERENCING A VOCABULARY CAUSES ITS ADDRESS TO
	BE PUSHED ON THE VOCABULARY STACK.  THE NEW
	BRANCH IS ATTACHED AT THE END OF THE EXISTING
	BRANCH POINTED TO BY "CURRENT".

	>	DISCARDS THE TOP OF THE VOCABULARY STACK

	ATTEMPTING TO POP THE LAST ENTRY OFF THE BOTTOM
	OF THE VOCABULARY STACK CAUSES THE ERROR:

	"VOCABULARY STACK EMPTY".

	TO SET "CURRENT" TO  POINT TO A NEW VOCABULARY,
	THE FOLLOWING WORD IS USED:

	DEFINITIONS	SETS "CURRENT" TO LINK NEW DEFINITIONS
			ONTO THE SAME BRANCH OF THE DICTIONARY
			AS IS POINTED TO BY THE TOP OF THE
			VOCABULARY STACK.


THE NORMAL PROCEDURE WHEN SETTING UP A NEW
VOCABULARY IS AS FOLLOWS:

	1) DEFINE THE VOCABULARY USING "BRANCH"

	2) PUSH THE ADDRESS OF THE VOCABULARY ON THE
	   VOCABULARY STACK BY REFERENCING THE VOCABULARY.

	3) SET "CURRENT" USING "DEFINITIONS".

	4) DEFINE ALL THE WORDS IN THE VOCABULARY.

	5) POP THE VOCABULARY STACK USING ">".

	6) RESET "CURRENT"

EXAMPLE:

	'VOCAB< BRANCH
	VOCAB< DEFINITIONS
	.
	.
	.
	> DEFINITIONS

	THIS DEFINES A NEW BRANCH OF THE DICTIONARY
	CALLED "VOCAB".

ENTIRE SECTIONS OF THE DICTIONARY MAY BE DELETED
BY USING THE FOLLOWING WORD:

	'NAME FORGET DISCARDS THE NAMED DICTIONARY
		     ENTRY AND ALL SUBSEQUENT
		     ENTRIES.

	FORGET IS USEFUL WHEN TRYING OUT DEFINITIONS
	FROM THE KEYBOARD.  THE USUAL PROCEDURE IS TO
	FIRST MAKE A DUMMY DEFINITION:

	'TEST : ;

	NEXT, TEST DEFINITIONS ARE MADE (TYPICALLY BY
	LOADING A PROGRAM).  IF THEY ARE UNSUCCESSFUL,
	"'TEST FORGET" WILL DELETE THEM FROM THE
	DICTIONARY, AND THE PROCESS IS REPEATED.
	FOR CONVENIENCE, THE DUMMY DEFINITION MAY BE
	PLACED AT THE BEGINNING OF THE PROGRAM.

	"FORGET" MAY ALSO BE USED TO PROVIDE AN OVERLAY
	FACILITY.  SAY THAT A PROGRAM HAS BEEN LOADED.
	IT MAY THEN BE DELETED BY FORGETTING THE
	FIRST DEFINITION OF THE PROGRAM AND THE DICTIONARY
	SPACE IS THEN FREE TO LOAD ANOTHER PROGRAM.


DEBUGGING TECHNIQUES

	THE FOLLOWING ARE TECHNIQUES WHICH MAY PROVE
USEFUL IN DEBUGGING NEW DEFINITIONS:

1) IT IS USUALLY MORE EFFICIENT TO MAKE A NEW
   DEFINITION IN A FILE USING THE EDITOR RATHER THAN
   FROM THE KEYBOARD IF IT IS MORE THAN ONE LINE LONG.
   "FORGET" IS THEN USED TO REMOVE THE LAST VERSION OF
   THE DEFINITION BEFORE TRYING AGAIN.

2) TO TEST A WORD, MERELY FEED IN ARGUMENTS ON THE
   STACK, EXECUTE THE WORD, AND EXAMINE THE RESULTS
   USING "=" AND "?".

3) IF A WORD FAILS, TYPE IN THE WORDS WHICH MAKE IT UP,
   ONE AT A TIME, EXAMINING THE STACK AS YOU GO ALONG AND
   RESTORING IT BY TYPING THE PARAMETERS BACK IN, IN
   REVERSE ORDER.

4) AFTER EXECUTING A WORD AND EXAMINING THE RESULTS ON
   THE STACK, TYPE AN EXTRA "=" TO MAKE SURE THE STACK
   IS EMPTY.  YOU SHOULD GET THE MESSAGE "STACK EMPTY".
   SIMILARLY, THE LOOP STACK SHOULD BE CHECKED BY TYPING
   "L>"; THIS SHOULD GENERATE THE MESSAGE "LOOP STACK
   EMPTY".

5) KEEP TRACK OF THE RADIX YOU ARE USING.  THIS IS THE
   SOURCE OF FREQUENT ERRORS.  WITHIN A FILE BEING
   EXECUTED, SAVE THE RADIX, SET IT TO THE VALUE THE
   PROGRAM EXPECTS, AND WHEN DONE, RESTORE THE SAVED
   VALUE.  FOR EXAMPLE:

	RADIX @ DECIMAL
	.
	.
	.
	RADIX !
	;F

	THIS SAVES THE CURRENT RADIX ON THE STACK, AND
	SETS THE RADIX TO DECIMAL.  UPON TERMINATION,
	THE OLD RADIX IS RESTORED (ASSUMING THE STACK
	HAS NOT BEEN DISTURBED).

6) THE PROPER SELECTION OF LOWER LEVEL WORDS HAS AN
   ENORMOUS EFFECT ON ALL SUBSEQUENT HIGHER LEVEL
   DEFINITIONS.  THUS IT PAYS TO DESIGN THE LOWER LEVEL
   WORDS VERY CAREFULLY.

7) WHEN DEBUGGING A PROGRAM, TEST ALL LOWER LEVEL WORDS
   THOROUGHLY BEFORE TESTING THE WORDS WHICH CALL THEM.

8) BE ESPECIALLY CAREFUL WITH ANY WORD WHICH MODIFIES
   MEMORY; MAKE SURE THE WORD IS MODIFYING ONLY THOSE
   LOCATIONS YOU INTEND, AND NOT PART OF THE PROGRAM.



***EOF***
   MEMORY; MAKE SURE THE WORD IS MODIFYING ONLY THOSE
   LOCATIONS YOU 