home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
SIMTEL
/
CPMUG
/
CPMUG023.ARK
/
STOIC.DOC
< prev
next >
Wrap
Text File
|
1984-04-29
|
46KB
|
1,696 lines
***************************************************************************
** 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***