% !TeX root = forth.tex
\annex{Test Suite} % F. (informative annex)
\label{annex:test}
\setwordlist{core}

\section{Introduction} % F.1
\label{test:intro}

After the publication of the original ANS Forth document
(ANSI X3.215-1994), John Hayes developed a test suite, which
included both a test harness and a suite of core tests.  The
harness was extended by Anton Ertl and David N. Williams to
allow the testing of floating point operations.
The current revision of the test harness is available from the
web site:
\begin{quote}
	\url{http://www.forth200x.org/tests/ttester.fs}
\end{quote}

% The primary changes from the original are the replacement of
% ``\texttt{\{}'' by ``\texttt{T\{}'' and ``\texttt{\}}'' by
% ``\texttt{\}T}''" (to avoid conflicts with existing systems),
%% the uses of { for locals and } for FSL arrays),
%% modifications so that the stack is allowed to be non-empty
%% before T{,
% and extensions for the handling of floating point tests.
% Code for testing equality of floating point values comes from
% David N. Williams, based on Dirk Zoller's implementation of
% approximate equality.

% Further revisions were provided by Anton Ertl, including the ability
% to handle either integrated or separate floating point stacks.
% Explanatory material by C. G. Montgomery, with helpful comments from
% David Williams and Krishna Myneni.

The teat harness can be used to define regression tests for a set of
application words.  It can also be used to define tests of words in
a standard-conforming implementation.
% An example is the test of the ANS Forth CORE word set.

Numerous people have contributed to the test cases given in section
\ref{test:core} onwards.  The majority of the test cases have been
taken from John Hayes' test suite\footnote{url{http://www.taygeta.com/forth.html}},
Gerry Jackson's test suite\footnote{\url{http://soton.mpeforth.com/flag/anstests/index.html}}
and David Williams with significant contributions from the committee.

\section{Test Harness}
\label{test:harness}

The tester defines functions that compare the results of a test with
a set of expected results.  The syntax for each test starts with
``\texttt{T\{}'' (T-open brace) followed by a code sequence to test.
This is followed by ``\texttt{->}'', the expected results, and
``\texttt{\}T}'' (close brace-T).  For example, the following:
\begin{quote}
	\test{1 1 \word{+}}{2}
\end{quote}
tests that one plus one indeed equals two.

The ``\texttt{T\{}'' records the stack depth prior to the test code
so that they can be eliminated from the test.
The ``\texttt{->}'' records the stack depth and moves the entire stack
contents to an array.  In the example test, the recorded stack depth
is one and the saved array contains one value, two.
The ``\texttt{\}T}'' compares the current stack depth to the saved
stack depth.  If they are equal each value on the stack is removed
from the stack and compared to its corresponding value in the array.
If the depths are not equal or if the stack comparison fails, an error
is reported.  For example:

\test{1 2 3 \word{SWAP}}{1 3 2} \\
\test{1 2 3 \word{SWAP}}{1 2 3}\ \texttt{INCORRECT RESULT:} \test{1 2 3 SWAP}{1 2 3} \\
\test{1 2 \word{SWAP}}{1}\   \texttt{WRONG NUMBER OF RESULTS:} \test{1 2 SWAP}{1} \\

\subsection{Floating-Point}
\setwordlist{floating}

Floating point testing can involve further complications.  The harness
attempts to determine whether floating-point support is present, and
if so, whether there is a separate floating-point stack, and behave
accordingly.  The \word{CONSTANT}s \texttt{HAS-FLOATING} and
\texttt{HAS-FLOATING-STACK} contain the results of its efforts, so
the behavior of the code can be modified by the user if necessary.

Then there are the perennial issues of floating point value
comparisons.  Exact equality is specified by \texttt{SET-EXACT}
(the default).  If approximate equality tests are desired, execute
\texttt{SET-NEAR}.  Then the \linebreak
\word{FVARIABLE}s \texttt{REL-NEAR} (default 1E-12) and
\texttt{ABS-NEAR} (default 0E) contain the values to be used in
comparisons by the (internal) word \texttt{FNEARLY=}.

When there is not a separate floating point stack, and you want to use
approximate equality for FP values, it is necessary to identify which
stack items are floating point quantities.  This can be done by
replacing the closing \texttt{\}T} with a version that specifies
this, such as \texttt{RRXR\}T} which identifies the stack picture
\linebreak (\param{r r x r}).  The harness provides such words for all
combinations of R and X with up to four stack items.  They can be
used with either an integrated or a separate floating point stacks.
Adding more if you need them is straightforward; see the examples in
the source.  Here is an example which also illustrates controlling
the precision of comparisons:

\begin{tt}
SET-NEAR \\
1E-6 REL-NEAR \word{F!} \\
\test[RX]{S" 3.14159E" \word{toFLOAT}}{-1E \word{FACOS} <TRUE>}
\end{tt}

\subsection{Error Processing}

The internal word \texttt{ERROR} is vectored, through the
\texttt{ERROR-XT} variable, so that its action can be changed by
the user (for example, to add a counter for the number of errors).
The default action \texttt{ERROR1} can be used as a factor in the
display of error reports.

\subsection{Source}

The following source code provides the test harness.

\setwordlist{floating}
\frenchspacing
\obeyspaces
\begin{tt}
\word{bs} This is the source for the ANS test harness, it is based on the\\
\word{bs} harness originally developed by John Hayes\\
\\
\word{bs} (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY\\
\word{bs} MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.\\
\word{bs} VERSION 1.1\\
\\
\word{bs} Revision history and possibly newer versions can be found at\\
\word{bs} http://www.forth200x/tests/ttester.fs\\
\\
\word{BASE} \word{@} \\
\word{HEX} \\
\\
\word{VARIABLE} ACTUAL-DEPTH         \word{bs} stack record \\
\word{CREATE} ACTUAL-RESULTS 20 CELLS ALLOT \\
\word{VARIABLE} START-DEPTH \\
\word{VARIABLE} XCURSOR              \word{bs} for ...\}T \\
\word{VARIABLE} ERROR-XT \\
\\
\word{:} ERROR ERROR-XT \word{@} \word{EXECUTE} \word{;}  \word{bs} for vectoring of error reporting \\
\\
\word{:} "FLOATING" \word{Sq} FLOATING" \word{;}   \word{bs} only compiled S" in CORE \\
\word{:} "FLOATING-STACK" \word{Sq} FLOATING-STACK" \word{;} \\
"FLOATING" \word{ENVIRONMENTq} \word[tools]{[IF]} \\
\tab \word[tools]{[IF]} \\
\tab[2] \word{TRUE} \\
\tab \word[tools]{[ELSE]} \\
\tab[2] \word{FALSE} \\
\tab \word[tools]{[THEN]} \\
\word[tools]{[ELSE]} \\
\tab \word{FALSE} \\
\word[tools]{[THEN]} \word{CONSTANT} HAS-FLOATING \\
\\
"FLOATING-STACK" \word{ENVIRONMENTq} \word[tools]{[IF]} \\
\tab \word[tools]{[IF]} \\
\tab[2] \word{TRUE} \\
\tab \word[tools]{[ELSE]} \\
\tab[2] \word{FALSE} \\
\tab \word[tools]{[THEN]} \\
\word[tools]{[ELSE]}            \word{bs} We don't know whether the FP stack is separate. \\
\tab HAS-FLOATING   \word{bs} If we have FLOATING, we assume it is. \\
\word[tools]{[THEN]} \word{CONSTANT} HAS-FLOATING-STACK \\
\\
HAS-FLOATING \word[tools]{[IF]} \\
\tab \word{bs} Set the following to the relative and absolute tolerances you \\
\tab \word{bs} want for approximate float equality, to be used with F~ in \\
\tab \word{bs} FNEARLY=.  Keep the signs, because F~ needs them. \\
\tab \word{FVARIABLE} REL-NEAR \word{DECIMAL} 1E-12 \word{HEX} REL-NEAR \word{F!} \\
\tab \word{FVARIABLE} ABS-NEAR \word{DECIMAL}    0E \word{HEX} ABS-NEAR \word{F!} \\
\\
\tab \word{bs} When EXACT? is TRUE, \}F uses FEXACTLY=, otherwise FNEARLY=. \\
\\
\tab \word{TRUE} \word{VALUE} EXACT? \\
\tab \word{:} SET-EXACT  \word{p} -{}- )   \word{TRUE} \word{TO} EXACT? \word{;} \\
\tab \word{:} SET-NEAR   \word{p} -{}- )  \word{FALSE} \word{TO} EXACT? \word{;} \\
\\
\tab \word{DECIMAL} \\
\tab \word{:} FEXACTLY=  \word{p} F: X Y -{}- S: FLAG ) \\
\tab[2] \word{p} \\
\tab[2] Leave TRUE if the two floats are identical. \\
\tab[2] ) \\
\tab[2] 0E \word{Ftilde} \word{;} \\
\tab \word{HEX} \\
\\
\tab \word{:} FABS=  \word{p} F: X Y -{}- S: FLAG ) \\
\tab[2] \word{p} \\
\tab[2] Leave TRUE if the two floats are equal within the tolerance \\
\tab[2] stored in ABS-NEAR. \\
\tab[2] ) \\
\tab[2] ABS-NEAR \word{F@} \word{Ftilde} \word{;} \\
\\
\tab \word{:} FREL=  \word{p} F: X Y -{}- S: FLAG ) \\
\tab[2] \word{p} \\
\tab[2] Leave TRUE if the two floats are relatively equal based on the \\
\tab[2] tolerance stored in ABS-NEAR. \\
\tab[2] ) \\
\tab[2] REL-NEAR \word{F@} \word{FNEGATE} \word{Ftilde} \word{;} \\
\\
\tab \word{:} F2DUP  \word{FOVER} \word{FOVER} \word{;} \\
\tab \word{:} F2DROP \word{FDROP} \word{FDROP} \word{;} \\
\\
\tab \word{:} FNEARLY=  \word{p} F: X Y -{}- S: FLAG ) \\
\tab[2] \word{p} \\
\tab[2] Leave TRUE if the two floats are nearly equal.  This is a  \\
\tab[2] refinement of Dirk Zoller's FEQ to also allow X = Y, including \\
\tab[2] both zero, or to allow approximately equality when X and Y are too \\
\tab[2] small to satisfy the relative approximation mode in the F\texttildelow \\
\tab[2] specification. \\
\tab[2] ) \\
\tab[2] F2DUP FEXACTLY= \word{IF} F2DROP \word{TRUE} \word{EXIT} \word{THEN} \\
\tab[2] F2DUP FREL=     \word{IF} F2DROP \word{TRUE} \word{EXIT} \word{THEN} \\
\tab[2] FABS= \word{;} \\
\\
\tab \word{:} FCONF= \word{p} R1 R2 -{}- F ) \\
\tab[2] EXACT? \word{IF} \\
\tab[3]  FEXACTLY= \\
\tab[2] \word{ELSE} \\
\tab[3]  FNEARLY= \\
\tab[2] \word{THEN} \word{;} \\
\word[tools]{[THEN]} \\
\\
HAS-FLOATING-STACK \word[tools]{[IF]} \\
\tab \word{VARIABLE} ACTUAL-FDEPTH \\
\tab \word{CREATE} ACTUAL-FRESULTS 20 \word{FLOATS} \word{ALLOT} \\
\tab \word{VARIABLE} START-FDEPTH \\
\tab \word{VARIABLE} FCURSOR \\
\\
\tab \word{:} EMPTY-FSTACK \word{p} \ldots -{}- \ldots ) \\
\tab[2] \word{FDEPTH} START-FDEPTH \word{@} \word{less} \word{IF} \\
\tab[3]   \word{FDEPTH} START-FDEPTH \word{@} \word{SWAP} \word{DO} 0E \word{LOOP} \\
\tab[2] \word{THEN} \\
\tab[2] \word{FDEPTH} START-FDEPTH \word{@} \word{more} \word{IF} \\
\tab[3]   \word{FDEPTH} START-FDEPTH \word{@} \word{DO} \word{FDROP} \word{LOOP} \\
\tab[2] \word{THEN} \word{;} \\
\\
\tab \word{:} F\{ \word{p} -{}- ) \\
\tab[2] \word{FDEPTH} START-FDEPTH \word{!} 0 FCURSOR \word{!} \word{;} \\
\\
\tab \word{:} F-> \word{p} \ldots -{}- \ldots ) \\
\tab[2] \word{FDEPTH} \word{DUP} ACTUAL-FDEPTH \word{!} \\
\tab[2] START-FDEPTH \word{@} \word{more} \word{IF} \\
\tab[2.5]   \word{FDEPTH} START-FDEPTH \word{@} \word{-} 0 \word{DO} ACTUAL-FRESULTS \word{I} \word{FLOATS} \word{+} \word{F!} \word{LOOP} \\
\tab[2] \word{THEN} \word{;} \\
\\
\tab \word{:} F\} \word{p} \ldots -{}- \ldots ) \\
\tab[2] \word{FDEPTH} ACTUAL-FDEPTH \word{@} \word{=} \word{IF} \\
\tab[3]  \word{FDEPTH} START-FDEPTH \word{@} \word{more} \word{IF} \\
\tab[4]   \word{FDEPTH} START-FDEPTH \word{@} \word{-} 0 \word{DO} \\
\tab[5]    ACTUAL-FRESULTS \word{I} \word{FLOATS} \word{+} \word{F@} FCONF= \word{INVERT} \word{IF} \\
\tab[6]     \word{Sq} INCORRECT FP RESULT: " ERROR \word{LEAVE} \\
\tab[5]    \word{THEN} \\
\tab[4]   \word{LOOP} \\
\tab[3]  \word{THEN} \\
\tab[2] \word{ELSE} \\
\tab[3]  \word{Sq} WRONG NUMBER OF FP RESULTS: " ERROR \\
\tab[2] \word{THEN} \word{;} \\
\\
\tab \word{:} F...\}T \word{p} -{}- ) \\
\tab[2] FCURSOR \word{@} START-FDEPTH \word{@} \word{+} ACTUAL-FDEPTH \word{@} \word{ne} \word{IF} \\
\tab[2]   \word{Sq} NUMBER OF FLOAT RESULTS BEFORE '->' DOES NOT MATCH ...\}T " \\
\tab[2]   \word{Sq} SPECIFICATION: " ERROR \\
\tab[2] \word{ELSE} \word{FDEPTH} START-FDEPTH \word{@} \word{=} \word{0=} \word{IF} \\
\tab[2]   \word{Sq} NUMBER OF FLOAT RESULTS BEFORE AND AFTER '->' DOES NOT MATCH: " \\
\tab[2]   ERROR \\
\tab[2] \word{THEN} \word{THEN} \word{;} \\
\\
\tab \word{:} FTESTER \word{p} R -{}- ) \\
\tab[2] \word{FDEPTH} \word{0=} ACTUAL-FDEPTH \word{@} FCURSOR \word{@} START-FDEPTH \word{@} \word{+} \word{1+} \word{less} \word{OR} \word{IF} \\
\tab[2]   \word{Sq} NUMBER OF FLOAT RESULTS AFTER '->' BELOW ...\}T SPECIFICATION: " \\
\tab[2]   ERROR  \\
\tab[2] \word{ELSE} ACTUAL-FRESULTS FCURSOR \word{@} \word{FLOATS} \word{+} \word{F@} FCONF= \word{0=} \word{IF} \\
\tab[2]   \word{Sq} INCORRECT FP RESULT: " ERROR \\
\tab[2] \word{THEN} \word{THEN} \\
\tab[2] 1 FCURSOR \word{+!} \word{;} \\
\\
\word[tools]{[ELSE]} \\
\tab \word{:} EMPTY-FSTACK \word{;} \\
\tab \word{:} F\{ \word{;} \\
\tab \word{:} F-> \word{;} \\
\tab \word{:} F\} \word{;} \\
\tab \word{:} F...\}T \word{;} \\
\\
\tab HAS-FLOATING \word[tools]{[IF]} \\
\tab[2] \word{DECIMAL} \\
\tab[2] \word{:} COMPUTE-CELLS-PER-FP \word{p} -{}- U ) \\
\tab[3]   \word{DEPTH} 0E \word{DEPTH} \word{1-} \word{toR} \word{FDROP} \word{Rfrom} \word{SWAP} \word{-} \word{;} \\
\tab[2] \word{HEX} \\
\\
\tab[2] COMPUTE-CELLS-PER-FP \word{CONSTANT} CELLS-PER-FP \\
\\
\tab[2] \word{:} FTESTER \word{p} R -{}- ) \\
\tab[3]  \word{DEPTH} CELLS-PER-FP \word{less} \\
\tab[3]  ACTUAL-DEPTH \word{@} XCURSOR \word{@} START-DEPTH \word{@} \word{+} CELLS-PER-FP \word{+} \word{less} \\
\tab[3]  \word{OR} \word{IF} \\
\tab[4]   \word{Sq} NUMBER OF RESULTS AFTER '->' BELOW ...\}T SPECIFICATION: " \\
\tab[4]   ERROR \word{EXIT} \\
\tab[3]  \word{ELSE} ACTUAL-RESULTS XCURSOR \word{@} \word{CELLS} \word{+} \word{F@} FCONF= \word{0=} \word{IF} \\
\tab[4]   \word{Sq} INCORRECT FP RESULT: " ERROR \\
\tab[3]  \word{THEN} \word{THEN} \\
\tab[3]  CELLS-PER-FP XCURSOR \word{+!} \word{;} \\
\tab \word[tools]{[THEN]} \\
\word[tools]{[THEN]} \\
\\
\word{:} EMPTY-STACK	\word{bs} ( \ldots -{}- ) empty stack; handles underflowed stack too. \\
\tab \word{DEPTH} START-DEPTH \word{@} \word{less} \word{IF} \\
\tab[2] \word{DEPTH} START-DEPTH \word{@} \word{SWAP} \word{DO} 0 \word{LOOP} \\
\tab \word{THEN} \\
\tab \word{DEPTH} START-DEPTH \word{@} \word{more} \word{IF} \\
\tab[2] \word{DEPTH} START-DEPTH \word{@} \word{DO} \word{DROP} \word{LOOP} \\
\tab \word{THEN} \\
\tab EMPTY-FSTACK \word{;} \\
\\
\word{:} ERROR1	\word{bs} ( C-ADDR U -{}- ) display an error message  \\
\tab[4.8] \word{bs} followed by the line that had the error. \\
\tab \word{TYPE} \word{SOURCE} \word{TYPE} \word{CR}			\word{bs} display line corresponding to error \\
\tab EMPTY-STACK         \word{bs} throw away everything else \\
\word{;} \\
\\
\word{'} ERROR1 ERROR-XT \word{!} \\
\\
\word{:} T\{		\word{bs} ( -{}- ) record the pre-test depth. \\
\tab \word{DEPTH} START-DEPTH \word{!} 0 XCURSOR \word{!} F\{ \word{;} \\
\\
\word{:} ->		\word{bs} ( \ldots -{}- ) record depth and contents of stack. \\
\tab \word{DEPTH} \word{DUP} ACTUAL-DEPTH \word{!}		\word{bs} record depth \\
\tab START-DEPTH \word{@} \word{more} \word{IF}		\word{bs} if there is something on the stack \\
\tab[2] \word{DEPTH} START-DEPTH \word{@} \word{-} 0 \word{DO} \word{bs} save them \\
\tab[3] 		ACTUAL-RESULTS \word{I} \word{CELLS} \word{+} \word{!} \\
\tab[2] \word{LOOP} \\
\tab \word{THEN} \\
\tab F-> \word{;} \\
\\
\word{:} \}T		\word{bs} ( \ldots -{}- ) comapre stack (expected) contents with saved \\
\tab   \word{bs} (actual) contents. \\
\tab \word{DEPTH} ACTUAL-DEPTH \word{@} \word{=} \word{IF}		\tab[4.0]	\word{bs} if depths match \\
\tab[2] \word{DEPTH} START-DEPTH \word{@} \word{more} \word{IF}	\tab[3.6]	\word{bs} if something on the stack \\
\tab[3] \word{DEPTH} START-DEPTH \word{@} \word{-} 0 \word{DO}	\tab[1.4]	\word{bs} for each stack item \\
\tab[4] ACTUAL-RESULTS \word{I} \word{CELLS} \word{+} \word{@}	\tab		\word{bs} compare actual with expected \\
\tab[4] \word{ne} \word{IF} \word{Sq} INCORRECT RESULT: " ERROR \word{LEAVE} \word{THEN} \\
\tab[3] \word{LOOP} \\
\tab[2] \word{THEN} \\
\tab \word{ELSE} \tab[16.6]	\word{bs} depth mismatch \\
\tab[2] \word{Sq} WRONG NUMBER OF RESULTS: " ERROR \\
\tab \word{THEN} \\
\tab F\} \word{;} \\
\\
\word{:} ...\}T \word{p} -{}- ) \\
\tab XCURSOR \word{@} START-DEPTH \word{@} \word{+} ACTUAL-DEPTH \word{@} \word{ne} \word{IF} \\
\tab[2] \word{Sq} NUMBER OF CELL RESULTS BEFORE '->' DOES NOT MATCH ...\}T " \\
\tab[2] \word{Sq} SPECIFICATION: " ERROR \\
\tab \word{ELSE} \word{DEPTH} START-DEPTH \word{@} \word{=} \word{0=} \word{IF} \\
\tab[2] \word{Sq} NUMBER OF CELL RESULTS BEFORE AND AFTER '->' DOES NOT MATCH: " \\
\tab[2] ERROR \\
\tab \word{THEN} \word{THEN} \\
\tab F...\}T \word{;} \\
\\
\word{:} XTESTER \word{p} X -{}- ) \\
\tab \word{DEPTH} \word{0=} ACTUAL-DEPTH \word{@} XCURSOR \word{@} START-DEPTH \word{@} \word{+} \word{1+} \word{less} \word{OR} \word{IF} \\
\tab[2] \word{Sq} NUMBER OF CELL RESULTS AFTER '->' BELOW ...\}T SPECIFICATION: " \\
\tab[2] ERROR \word{EXIT} \\
\tab \word{ELSE} ACTUAL-RESULTS XCURSOR \word{@} \word{CELLS} \word{+} \word{@} \word{ne} \word{IF} \\
\tab[2] \word{Sq} INCORRECT CELL RESULT: " ERROR \\
\tab \word{THEN} \word{THEN} \\
\tab 1 XCURSOR \word{+!} \word{;} \\
\\
\word{:} X\}T    XTESTER                         ...\}T \word{;} \\
\word{:} XX\}T   XTESTER XTESTER                 ...\}T \word{;} \\
\word{:} XXX\}T  XTESTER XTESTER XTESTER         ...\}T \word{;} \\
\word{:} XXXX\}T XTESTER XTESTER XTESTER XTESTER ...\}T \word{;} \\
\\
HAS-FLOATING \word[tools]{[IF]} \\
\tab \word{:} R\}T    FTESTER                         ...\}T \word{;} \\
\tab \word{:} XR\}T   FTESTER XTESTER                 ...\}T \word{;} \\
\tab \word{:} RX\}T   XTESTER FTESTER                 ...\}T \word{;} \\
\tab \word{:} RR\}T   FTESTER FTESTER                 ...\}T \word{;} \\
\tab \word{:} XXR\}T  FTESTER XTESTER XTESTER         ...\}T \word{;} \\
\tab \word{:} XRX\}T  XTESTER FTESTER XTESTER         ...\}T \word{;} \\
\tab \word{:} XRR\}T  FTESTER FTESTER XTESTER         ...\}T \word{;} \\
\tab \word{:} RXX\}T  XTESTER XTESTER FTESTER         ...\}T \word{;} \\
\tab \word{:} RXR\}T  FTESTER XTESTER FTESTER         ...\}T \word{;} \\
\tab \word{:} RRX\}T  XTESTER FTESTER FTESTER         ...\}T \word{;} \\
\tab \word{:} RRR\}T  FTESTER FTESTER FTESTER         ...\}T \word{;} \\
\tab \word{:} XXXR\}T FTESTER XTESTER XTESTER XTESTER ...\}T \word{;} \\
\tab \word{:} XXRX\}T XTESTER FTESTER XTESTER XTESTER ...\}T \word{;} \\
\tab \word{:} XXRR\}T FTESTER FTESTER XTESTER XTESTER ...\}T \word{;} \\
\tab \word{:} XRXX\}T XTESTER XTESTER FTESTER XTESTER ...\}T \word{;} \\
\tab \word{:} XRXR\}T FTESTER XTESTER FTESTER XTESTER ...\}T \word{;} \\
\tab \word{:} XRRX\}T XTESTER FTESTER FTESTER XTESTER ...\}T \word{;} \\
\tab \word{:} XRRR\}T FTESTER FTESTER FTESTER XTESTER ...\}T \word{;} \\
\tab \word{:} RXXX\}T XTESTER XTESTER XTESTER FTESTER ...\}T \word{;} \\
\tab \word{:} RXXR\}T FTESTER XTESTER XTESTER FTESTER ...\}T \word{;} \\
\tab \word{:} RXRX\}T XTESTER FTESTER XTESTER FTESTER ...\}T \word{;} \\
\tab \word{:} RXRR\}T FTESTER FTESTER XTESTER FTESTER ...\}T \word{;} \\
\tab \word{:} RRXX\}T XTESTER XTESTER FTESTER FTESTER ...\}T \word{;} \\
\tab \word{:} RRXR\}T FTESTER XTESTER FTESTER FTESTER ...\}T \word{;} \\
\tab \word{:} RRRX\}T XTESTER FTESTER FTESTER FTESTER ...\}T \word{;} \\
\tab \word{:} RRRR\}T FTESTER FTESTER FTESTER FTESTER ...\}T \word{;} \\
\word[tools]{[THEN]} \\
\\
\word{bs} Set the following flag to TRUE for more verbose output; this may \\
\word{bs} allow you to tell which test caused your system to hang. \\
\word{VARIABLE} VERBOSE \\\mbox{}
  \word{FALSE} VERBOSE \word{!} \\
 \\
\word{:} TESTING	\word{bs} ( -{}- ) TALKING COMMENT. \\
\tab \word{SOURCE} VERBOSE \word{@} \\
\tab \word{IF} \word{DUP} \word{toR} \word{TYPE} \word{CR} \word{Rfrom} \word{toIN} \word{!} \\
\tab \word{ELSE} \word{toIN} \word{!} \word{DROP} \\
\tab \word{THEN} \word{;} \\
\\
% : TESTING  \ ( -- ) Talking Comment
%   POSTPONE \
%   VERBOSE @ IF
%     SOURCE TYPE CR
%   THEN
% ;
\word{BASE} \word{!}
\end{tt}
\nonfrenchspacing
\catcode`\ =10

\section{Core Tests}
\label{test:core}

The test cases in John Hayes' original test suite were designed to
test features before they were used in later tests.  Due to the
structure of this annex the progressive testing has been lost.  This
section attempts to retain the integrity of the original test suite
by laying out the test progression for the core word set.

While this suite does test many aspects of the core word set, it is
not comprehensive.  A standard system \emph{should} pass all of the
tests within this suite.  A system cannot claim to be standard simply
because it passes this test suite.

The test starts by verifying basic assumptions about number
representation.  It then builds on this with tests of boolean logic,
shifting, and comparisons.  It then tests the basic stack manipulations
and arithmetic.  Ultimately, it tests the Forth interpreter and
compiler.

Note that all of the tests in this suite assume the current base is
\emph{hexadecimal}.

\subsection{Basic Assumptions}

These test assume a two's complement implementation where the range of
signed numbers is $-2^{n-1}$ $\cdots$ $2^{n-1}-1$ and the range of
unsinged numbers is $0$ $\cdots$ $2^n-1$.

A method for testing \word{KEY}, \word{QUIT}, \word{ABORT},
\word{ABORTq}, \word{ENVIRONMENTq}, etc has yet to be proposed.

\test{}{} \tab[10] \texttt{\word{p} Start with a clean slate )} \\
\texttt{\word{p} Test if any bits are set; Answer in base 1 )} \\
\test{\word{:} BITSSET? \word{IF} 0 0 \word{ELSE} 0 \word{THEN} \word{;}}{} \\
\test{ 0 BITSSET?}{0}	\tab[2.8] \texttt{\word{p} Zero is all bits clear )} \\
\test{ 1 BITSSET?}{0 0}	\tab[1.6] \texttt{\word{p} Other numbers have at least one bit )} \\
\test{-1 BITSSET?}{0 0}

\subsection{Booleans}

To test the booleans it is first neccessary to test
\tref{core:AND}{AND}, and \tref{core:INVERT}{INVERT}.  Before moving
on to the test \tref{core:CONSTANT}{CONSTANT}.  The latter defines
two constants (\texttt{0S} and \texttt{1S}) which will be used in the
further test.

It is now possible to complete the testing of
	\tref{core:AND}{AND},
	\tref{core:OR}{OR}, and
	\tref{core:XOR}{XOR}.

\subsection{Shifts}

To test the shift operators it is necessary to calculate the most
significant bit of a cell:

\begin{quote}
	\texttt{1S 1 \word{RSHIFT} \word{INVERT} \word{CONSTANT} MSB}
\end{quote}

\word{RSHIFT} is tested later.
\texttt{MSB} must have at least one bit set:

\begin{quote}
	\test{MSB BITSSET?}{0 0}
\end{quote}

The test \tref{core:2*}{2*}, \tref{core:2/}{2/},
\tref{core:LSHIFT}{LSHIFT}, and \tref{core:RSHIFT}{RSHIFT}
can now be performed.

\subsection{Numeric notation}% A.3.4.1.3
\label{test:numeric}

The numeric representation can be tested with the following test cases:

\begin{tt}
	\word{DECIMAL} \\
	\test{\#1289      }{1289       } \\
	\test{\#12346789. }{12346789.  } \\
	\test{\#-1289     }{-1289      } \\
	\test{\#-12346789.}{-12346789. } \\
	\test{\$12eF      }{4847       } \\
	\test{\$12aBcDeF. }{313249263. } \\
	\test{\$-12eF     }{-4847      } \\
	\test{\$-12AbCdEf.}{-313249263.} \\
	\test{\%10010110  }{150        } \\
	\test{\%10010110. }{150.       } \\
	\test{\%-10010110 }{-150       } \\
	\test{\%-10010110.}{-150.      } \\
	\test{'z' \       }{122        }
\end{tt}

\subsection{Comparisons}

Before testing the comparison operators it is necessary to define
a few constants to allow the testing of the upper and lower bounds.

\begin{tt}\frenchspacing\obeyspaces
0 \word{INVERT}                					\word{CONSTANT} MAX-UINT \\
0 \word{INVERT} 1 \word{RSHIFT}       			\word{CONSTANT} MAX-INT \\
0 \word{INVERT} 1 \word{RSHIFT} \word{INVERT}	\word{CONSTANT} MIN-INT \\
0 \word{INVERT} 1 \word{RSHIFT}       			\word{CONSTANT} MID-UINT \\
0 \word{INVERT} 1 \word{RSHIFT} \word{INVERT}	\word{CONSTANT} MID-UINT+1 \\
\\
0S \word{CONSTANT} <FALSE> \\
1S \word{CONSTANT} <TRUE>
\end{tt}
\nonfrenchspacing\catcode`\ =10

With these constants defined, it is now possible to perferom the
	\tref{core:0=}{0=},
	\tref{core:=}{=},
	\tref{core:0less}{0<},
	\tref{core:less}{<},
	\tref{core:more}{>},
	\tref{core:Uless}{U<},
	\tref{core:MIN}{MIN}, and
	\tref{core:MAX}{MAX} test.

\subsection{Stack Operators}

The stack operators can be tested without any prepatory work.  The
``normal'' operators
	(\tref{core:DROP}{DROP},
	 \tref{core:DUP}{DUP},
	 \tref{core:OVER}{OVER},
	 \tref{core:ROT}{ROT}, and
	 \tref{core:SWAP}{SWAP})
should be tested first, followed by the two-cell variants
	(\tref{core:2DROP}{2DROP},
	 \tref{core:2DUP}{2DUP},
	 \tref{core:2OVER}{2OVER} and \linebreak
	 \tref{core:2SWAP}{2SWAP})
with \tref{core:qDUP}{?DUP} and \tref{core:DEPTH}{DEPTH} being
performed last.

\subsection{Return Stack Operators}

The test \tref{core:toR}{>R} will test all three basic return
stack operators (\word{toR}, \word{Rfrom}, and \word{R@}).

\subsection{Addition and Subtraction}

Basic addition and subtraction should be tested in the order:
	\tref{core:+}{+},
	\tref{core:-}{-},
	\tref{core:1+}{1+},
	\tref{core:1-}{1-},
	\tref{core:ABS}{ABS} and
	\tref{core:NEGATE}{NEGATE}.

\subsection{Multiplication}

The multiplication operators should be tested in the order:
	\tref{core:StoD}{S>D},
	\tref{core:*}{*},
	\tref{core:M*}{M*}, and
	\tref{core:UM*}{UM*}.

\subsection{Division}

Due to the complexity of the division operators they are tested
separately from the multiplication operators.  The basic division
operators are tested first:
	\tref{core:FM/MOD}{FM/MOD},
	\tref{core:SM/REM}{SM/REM}, and
	\tref{core:UM/MOD}{UM/MOD}.

As the standard allows a system to provide either floored or symmetric
division, the remaining operators have to be tested depending on the
system behaviour.  Two words are defined that provide a form of
conditional compilation.

\begin{tt}
\word{:} IFFLOORED 
	\word{[} -3 2 \word{/} -2 = \word{INVERT} \word{]}
	\word{LITERAL} \word{IF} \word{POSTPONE} \word{bs} \word{THEN}
\word{;} \\
\word{:} IFSYM \tab[1.8]
	\word{[} -3 2 \word{/} -1 = \word{INVERT} \word{]}
	\word{LITERAL} \word{IF} \word{POSTPONE} \word{bs} \word{THEN}
\word{;}
\end{tt}

\texttt{IFSYM} will ignore the rest of the line when it is performed
on a system with floored division and perform the line on a system
with symmetric division.  \texttt{IFFLOORED} is the direct inverse,
ignoring the rest of the line on systems with symmetric division and
processing it on systems with floored division.

The remaining division operators are tested by defining a version of
the operator using words which have already been tested (\word{StoD},
\word{M*}, \word{FM/MOD} and \word{SM/REM}).  The test definition
handles the special case of differing signes.  As the test definitions
use the words which have just been tested, the tests must be performed
in the order:
	\tref{core:/MOD}{/MOD},
	\tref{core:/}{/},
	\tref{core:MOD}{MOD},
	\tref{core:*/}{*/}, and
	\tref{core:*/MOD}{*/MOD}.

\subsection{Memory}

As with the other sections, the tests for the memory access words
build on previously tested words and thus require an order to the
testing.

The first test (\tref{core:,}{,} (comma)) tests \word{HERE}, the
signle cell memory access words \word{@}, \word{!} and \word{CELL+}
as well as the double cell access words \word{2@} and \word{2!}.  The
tests \tref{core:+!}{+!} and \tref{core:CELLS}{CELLS} should then be
performed.

The test (\tref{core:C,}{C,}) also tests the single character memory
words \word{C@}, \word{C!}, and \word{CHAR+}, leaving the test
\tref{core:CHARS}{CHARS} to be performed seperatly.

Finally, the memory access alignment test \tref{core:ALIGN}{ALIGN}
includes a test of \word{ALIGNED}, leaving \linebreak \tref{core:ALLOT}{ALLOT}
as the final test in this group.

\subsection{Characters}

Basic character handling:
	\tref{core:BL}{BL},
	\tref{core:CHAR}{CHAR},
	\tref{core:[CHAR]}{[CHAR]},
	\tref{core:[}{[} which also tests \word{]}, and
	\tref{core:Sq}{S\"}.

\subsection{Dictionary}

The dictionary tests define a number of words as part of the test,
these are included in the approperate test:
	\tref{core:'}{'},
	\tref{core:[']}{[']} both of which also test \word{EXECUTE},
	\tref{core:FIND}{FIND},
	\tref{core:LITERAL}{LITERAL},
	\tref{core:COUNT}{COUNT},
	\tref{core:POSTPONE}{POSTPONE},
	\tref{core:STATE}{STATE}

\subsection{Flow Control}

The flow control words have to be tested in matching groups.
First test \tref{core:IF}{IF}, \word{ELSE}, \word{THEN} group.
Followed by the \word{BEGIN}, \tref{core:WHILE}{WHILE},
\word{REPEAT} group, and the \word{BEGIN}, \tref{core:UNTIL}{UNTIL}
pairing.  Finally the \tref{core:RECURSE}{RECURSE} function should
be tested.

\subsection{Counted Loops}

Counted loops have a set of special condition that require testing.
As with the flow control words, these words have to be tested as
a group.
First the basic counted loop: \word{DO}; \word{I};
	\tref{core:LOOP}{LOOP},
followed by loops with a non regular increment:
	\tref{core:+LOOP}{+LOOP},
loops within loops:
	\tref{core:J}{J},
and aborted loops:
	\tref{core:LEAVE}{LEAVE};
	\tref{core:UNLOOP}{UNLOOP} which includes a test for \word{EXIT}.

\subsection{Defining Words}

Although most of the defining words have already been used within the
test suite, they still need to be tested fully.  The tests include
	\tref{core::}{:} which also tests \word{;},
	\tref{core:CONSTANT}{CONSTANT},
	\tref{core:VARIABLE}{VARIABLE},
	\tref{core:DOES}{DOES} which includes tests \word{CREATE}, and
	\tref{core:toBODY}{toBODY} which also tests \word{CREATE}.

\subsection{Evaluate}

As with the defining words, \tref{core:EVALUATE}{EVALUATE} has
already been used, but it must still be tested fully.

\subsection{Parser Input Source Control}

Testing of the input source can be quit dificult.  The tests
require line breaks within the test:
	\tref{core:SOURCE}{SOURCE},
	\tref{core:toIN}{>IN}, and
	\tref{core:WORD}{WORD}.

\subsection{Number Patterns}

The number formatting words produce a string, a word that compares
two strings is required.  This test suite assumes that the optional
String word set is unavailable.  Thus a string comparison word is
defined, using only trusted words:

\begin{tt}
\word{:} S=  \word{bs} ( ADDR1 C1 ADDR2 C2 -{}- T/F ) Compare two strings. \\
\tab  \word{toR} \word{SWAP} \word{R@} \word{=} \word{IF}	\tab[4.8] \word{bs} Make sure strings have same length \\
\tab[2]   \word{Rfrom} \word{qDUP} \word{IF}				\tab[6.2] \word{bs} If non-empty strings \\
\tab[3]     0 \word{DO} \\
\tab[4]       \word{OVER} \word{C@} \word{OVER} \word{C@} \word{-}
				\word{IF} \word{2DROP} <FALSE> \word{UNLOOP} \word{EXIT} \word{THEN} \\
\tab[4]       \word{SWAP} \word{CHAR+} \word{SWAP} \word{CHAR+} \\
\tab[3]     \word{LOOP} \\
\tab[2]   \word{THEN} \\
\tab[2]   \word{2DROP} <TRUE>								\tab[5] \word{bs} If we get here, strings match \\
\tab  \word{ELSE} \\
\tab[2]   \word{Rfrom} \word{DROP} \word{2DROP} <FALSE>		\tab[-0.4] \word{bs} Lengths mismatch \\
\tab  \word{THEN} \word{;}
\end{tt}

The number formatting words have to be tested as a group with
	\tref{core:HOLD}{HOLD},
	\tref{core:SIGN}{SIGN}, and
	\tref{core:num}{num} all including tests for
	\word{num-start} and \word{num-end}.

Before the \tref{core:numS}{numS} test can be performed it is
necessary to calculate the number of bits required to store the
largest double value.

\begin{tt}
24 \word{CONSTANT} MAX-BASE							\tab[7.6] \word{bs} BASE 2 {\ldots} 36 \\
\word{:} COUNT-BITS \\
\tab 0 0 \word{INVERT}
	\word{BEGIN} \word{DUP} \word{WHILE} \word{toR} \word{1+} \word{Rfrom} \word{2*} \word{REPEAT}
	\word{DROP} \word{;} \\
COUNT-BITS \word{2*} \word{CONSTANT} \#BITS-UD		\tab \word{bs} NUMBER OF BITS IN UD
\end{tt}

The \tref{core:toNUMBER}{toNUMBER} test can now be performed.
Finally, the \tref{core:BASE}{BASE} test, which includes tests for
\word{HEX} and \word{DECIMAL}, can be performed.

\subsection{Memory Movement}

Frist two memory buffers are defined:

\begin{tt}
\word{CREATE} FBUF 00 \word{C,} 00 \word{C,} 00 \word{C,} \\
\word{CREATE} SBUF 12 \word{C,} 34 \word{C,} 56 \word{C,} \\
\word{:} SEEBUF FBUF \word{C@}  FBUF \word{CHAR+} \word{C@}  FBUF \word{CHAR+} \word{CHAR+} \word{C@} \word{;}
\end{tt}

As the content of \texttt{FBUF} is changed by the
\tref{core:FILL}{FILL} test, this must be executed before the
\linebreak \tref{core:MOVE}{MOVE} test.

\subsection{Output}

As there is no provision for capturing the output stream so that it
can be compared to an expected result there is not automatic method
of testing the output generation words.  The user is required to
validate the output for the \tref{core:EMIT}{EMIT} test.  This tests
the selection of output words \word{d}, \word{.q}, \word{CR},
\word{SPACE}, \word{SPACES}, \word{TYPE}, and \word{Ud}.

\subsection{Input}

To test the input word (\tref{core:ACCEPT}{ACCEPT}) the user is
required to type up to 80 characters.  The system will buffer the
input sequence and output it to the user for inspection.

\subsection{Dictionary Search Rules}

The final test in this suite is included with \tref{core::}{:} and
tests the search order of the dictionary.  It asserts that a
definition that uses its own name in the definition is not recursive
but rather refers to the previous definition of the word.

\test{\word{:} GDX     123 \word{;}}{}	\tab \texttt{\word{bs} First defintion} \\
\test{\word{:} GDX GDX 234 \word{;}}{}	\tab \texttt{\word{bs} Second defintion} \\
\test{GDX}{123 234}


\ifinline
	\newcommand{\readtest}[1]{% {<file>}
		\begin{editor}
			In the \emph{review} (r) version of the document the
			test cases for a word are given in with the main
			defintion of the word.  The test cases for the words
			in the \textbf{#1} word set will appear here in the
			final document.
		\end{editor}
	}

	\newcommand{\testsection}[2]{% {<file>}{<Wordlist>}
		\section{The optional #2 word set}
		\readtest{#1}
	}

	\newcommand{\defersection}{}
\else
	\namespace{test}
	\defersection{}

	\newcommand{\readtest}[2]{%
		\input{t-#1.sub}
	}

	\newcommand{\testsection}[2]{%
		\defersection{#2}
		\setwordlist{#1}
		\input{t-#1.sub}
		\stepsection
	}
\fi


\setcounter{section}{5}
\section{The Core word set} % T.6
\readtest{core}

% ===================================================================

\testsection{block}{Block}						% T.7

% ===================================================================

\section{The optional Double-Number word set} % T.8
\setwordlist{double}
\defersection{}
\label{test:double}

Two additional constants are defined to assist tests in this word set:

\begin{tt}\frenchspacing\obeyspaces
MAX-INT \word{2/}  \word{CONSTANT} HI-INT   \word{bs} 001...1 \\
MIN-INT \word{2/}  \word{CONSTANT} LO-INT   \word{bs} 110...1
\end{tt}
\nonfrenchspacing\catcode`\ =10

Before anything can be tested, the text interpreter must be
tested (\ref{test:dbl:in}).
Once the \linebreak \tref{double:2CONSTANT}{2CONSTANT} test has been preformed
we can also define a number of double constants:

\begin{tt}\frenchspacing\obeyspaces
~     1S MAX-INT \word{2CONSTANT} MAX-2INT   \word{bs} 01...1 \\\mbox{}
      0 MIN-INT \word{2CONSTANT} MIN-2INT   \word{bs} 10...0 \\
MAX-2INT      \word{2/} \word{2CONSTANT} HI-2INT    \word{bs} 001...1 \\
MIN-2INT      \word{2/} \word{2CONSTANT} LO-2INT    \word{bs} 110...0
\end{tt}
\nonfrenchspacing\catcode`\ =10

The rest of the word set can be tesed:
\tref{double:DNEGATE}{},
\tref{double:D+}{}, \tref{double:D-}{},
\tref{double:D0less}{}, \tref{double:D0=}{},
\tref{double:D2*}{}, \tref{double:D2/}{},
\tref{double:Dless}{}, \tref{double:D=}{},
\tref{double:2LITERAL}{}, \tref{double:2VARIABLE}{},
\tref{double:DMAX}{}, \tref{double:DMIN}{}, \linebreak
\tref{double:DtoS}{}, \tref{double:DABS}{},
\tref{double:M+}{}, \tref{double:M*/}{} and
\tref{double:D.R}{} which also tests \word{Dd} before moving on
to the existion words with the
\tref{double:2ROT}{} and \tref{double:DUless}{} tests.

\setcounter{subsection}{3}
\setcounter{subsubsection}{1}
\subsubsection{Text interpreter input number conversion}
\label{test:dbl:in}

\test{ 1.}{ 1  0} \\
\test{-2.}{-2 -1} \\
\test{\word{:} rdl1  3.\ \word{;} rdl1}{ 3  0} \\
\test{\word{:} rdl2 -4.\ \word{;} rdl2}{-4 -1}

\readtest{double}

% ===================================================================

\section{The optional Exception word set} % T.9
\setwordlist{exception}
\defersection{}

The test \tref{exception:CATCH}{} also test \word{THROW}.  This should
be followed by the test \tref{exception:ABORTq}{} which also test
\word{ABORT}.  Finally, the general exception handling is tested in
\ref{test:throw}.

\setcounter{subsection}{3}
\setcounter{subsubsection}{5}
\subsubsection{Exception handling}
\label{test:throw}

Ideally all of the throw codes should be tested.  Here only the
thow code for an ``Undefined Word'' exception is tested, assuming
that the word \texttt{\$\$UndefedWord\$\$} is undefined.

\begin{tt}
\word{DECIMAL} \\
\word{:} t7 \word{Sq} 333 \$\$UndefedWord\$\$ 334" \word{EVALUATE} 335 \word{;} \\
\word{:} t8 \word{Sq} 222 t7 223" \word{EVALUATE} 224 \word{;} \\
\word{:} t9 \word{Sq} 111 112 t8 113" \word{EVALUATE} 114 \word{;}
\end{tt}

\test{6 7 \word{'} t9 c6 3}{6 7 13 3}

\readtest{exception}

% ===================================================================

\testsection{facility}{Facility}		% T.10

% ===================================================================

\section{The optional File-Access word set} % T.11
\setwordlist{file}
\defersection{}

These tests create files in the current directory, if all goes well
these will be deleted.  If something fails they may not be deleted.
If this is a problem ensure you set a suitable directory before
running this test.  Currently, there is no ANS standard way of doing
this.  the file names used in these test are:
``\texttt{fatest1.txt}'', ``\texttt{fatest2.txt}'' and
``\texttt{fatest3.txt}''.

The test \tref{file:CREATE-FILE}{} also tests \word{CLOSE-FILE},
\tref{file:WRITE-LINE}{} \linebreak also tests \word{W/O} and \word{OPEN-FILE},
\tref{file:READ-LINE}{} includes a test for \word{R/O}, \linebreak
\tref{file:REPOSITION-FILE}{} includes tests for \word{R/W},
\word{WRITE-FILE}, \word{READ-FILE}, \linebreak
\word{FILE-POSITION}, and \word{Sq}.
The \tref{file:FILE-SIZE}{} test includes a test for \word{BIN}.
The test \linebreak \tref{file:RESIZE-FILE}{} should then be run followed by
the \tref{file:DELETE-FILE}{} test.

The \tref{file:p}{} test should be next, followed by
\tref{file:SOURCE-ID}{} the test which test the extended versions of
\word{p} and \word{SOURCE-ID} respectively.

Finally \tref{file:RENAME-FILE}{} tests the extended words
\word{RENAME-FILE}, \word{FILE-STATUS}, and \word{FLUSH-FILE}.

\readtest{file}

% ===================================================================

\testsection{floating}{Floating-Point}	% T.12
\testsection{local}{Locals}				% T.13

% ===================================================================

\section{The optional Memory-Allocation word set} % T.14
\label{test:memory}
\setwordlist{memory}
\defersection{}

These test require a new variable to hold the address of the allocated
memory.  Two helper words are defined to populate the allocated memory
and to check the memory:

\begin{tt}\frenchspacing\obeyspaces
\word{VARIABLE} addr

\word{:} write-cell-mem \word{p} addr n -{}- ) \\
\tab \word{1+} 1 \word{DO} \word{I} \word{OVER} \word{!} \word{CELL+} \word{LOOP} \word{DROP} \\
\word{;}

\word{:} check-cell-mem \word{p} addr n -{}- ) \\
\tab \word{1+} 1 \word{DO} \\
\tab[2] \word{I} \word{SWAP} \word{toR} \word{toR} \\
\tab[2] \test{\word{Rfrom} \word{p} \word{I} )}{\word{R@} \word{p} addr ) \word{@}} \\
\tab[2] \word{Rfrom} \word{CELL+} \\
\tab \word{LOOP} \word{DROP} \\
\word{;}

\word{:} write-char-mem \word{p} addr n -{}- ) \\
\tab \word{1+} 1 \word{DO} \word{I} \word{OVER} \word{C!} \word{CHAR+} \word{LOOP} \word{DROP} \\
\word{;}

\word{:} check-char-mem \word{p} addr n -{}- ) \\
\tab \word{1+} 1 \word{DO} \\
\tab[2] \word{I} \word{SWAP} \word{toR} \word{toR} \\
\tab[2] \test{\word{Rfrom} \word{p} \word{I} )}{\word{R@} \word{p} addr ) \word{C@}} \\
\tab[2] \word{Rfrom} \word{CHAR+} \\
\tab \word{LOOP} \word{DROP} \\
\word{;}
\end{tt}
\nonfrenchspacing\catcode`\ =10

The test \tref{memory:ALLOCATE}{} includes a test for \word{FREE}.

\readtest{memory}

% ===================================================================

\testsection{tools}{Programming-Tools}	% T.15

% ===================================================================

\section{The optional Search-Order word set} % T.16
\setwordlist{search}
\defersection{}

The search order is reset to a known state before the tests can be
run.

\begin{tt}
\word{ONLY} \word{FORTH} \word{DEFINITIONS}
\end{tt}

Define two word list (wid) variables used by the tests.

\begin{tt}
\word{VARIABLE} wid1 \\
\word{VARIABLE} wid2
\end{tt}

In order to test the search order it in necessary to remember the
existing search order before modifying it.  The existing search order
is saved and the \texttt{get-orderlist} defined to access it.

\begin{tt}
\word{:} save-orderlist \word{p} widn {\ldots} wid1 n -{}- ) \\
\tab \word{DUP} \word{,} 0 \word{qDO} \word{,} \word{LOOP} \\
\word{;}

\word{CREATE} order-list \\
\test{\word{GET-ORDER} save-orderlist}{}

\word{:} get-orderlist  ( -{}- widn {\ldots} wid1 n ) \\
\tab order-list \word{DUP} \word{@} \word{CELLS}	\tab[1] ( -{}- ad n ) \\
\tab \word{OVER} \word{+}							\tab[10.5] ( -{}- AD AD' ) \\
\tab \word{qDO} \word{I} \word{@} -1 \word{CELLS} \word{+LOOP} \tab[1]  ( -{}- ) \\
\word{;}
\end{tt}

Having obtained a copy of the current wordlist, the testing of the
wordlist can begin with test \tref{search:FORTH-WORDLIST}{} followed
by \tref{search:SET-ORDER}{} which also test \word{GET-ORDER}, then
\linebreak
\tref{search:ALSO}{} and \tref{search:ONLY}{} before moving on to
\tref{search:SET-CURRENT}{} which also test \word{GET-CURRENT} and
\word{WORDLIST}.  This should be followed by the test
\linebreak
\tref{search:DEFINITIONS}{} which also tests \word{PREVIOUS} and the
\tref{search:SEARCH-WORDLIST}{} and \tref{search:FIND}{} tests.
Finally the \tref{search:ORDER}{} test can be performed.

\readtest{search}

% ===================================================================

\section{The optional String word set} % T.17
\setwordlist{string}
\defersection{}

Most of the tests in this wordlist require a known string which is
defined as:

\test{\word{:} s1 \word{Sq} abcdefghijklmnopqrstuvwxyz" \word{;}}{}

The tests should be carried out in the order:
\tref{string:/STRING}{},
\tref{string:SEARCH}{}, \linebreak
\tref{string:-TRAILING}{},
\tref{string:COMPARE}{},
\tref{string:BLANK}{} and \linebreak
\tref{string:SLITERAL}{}.

\readtest{string}

% ===================================================================

\section{The optional Extended Character word set} % T.18
\setwordlist{xchar}
\defersection{}

These test assume the UTF-8 character encoding is being used.

\readtest{xchar}

% ===================================================================



\endinput %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Test Harness} % John Hayes' original test harness

\begin{tt}
\word{bs} From: ~ John Hayes S1I \\
\word{bs} Subject: core.fr \\
\word{bs} Date: ~ Mon, 27 Nov 95 13:10:09 PST \\
\word{bs} (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY\\
\word{bs} MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS.\\
\word{bs} VERSION 1.1\\
\word{HEX} \\
\\
\word{bs} SET THE FOLLOWING FLAG TO TRUE FOR MORE VERBOSE OUTPUT; THIS MAY \\
\word{bs} ALLOW YOU TO TELL WHICH TEST CAUSED YOUR SYSTEM TO HANG. \\
\\
\word{VARIABLE} VERBOSE \\
\tab[1.2] \word{FALSE} VERBOSE \word{!} \\
\\
\word{:} EMPTY-STACK \tab \word{bs} ( ... -{}- ) EMPTY STACK: HANDLES UNDERFLOWED STACK TOO. \\
\tab \word{DEPTH} \word{qDUP} \word{IF} \word{DUP} \word{0less} \word{IF} \word{NEGATE} 0 \word{DO} 0 \word{LOOP} \word{ELSE} 0 \word{DO} \word{DROP} \word{LOOP} \word{THEN} \word{THEN} \word{;} \\
\\
\word{:} ERROR \tab \word{bs} ( C-ADDR U -{}- ) DISPLAY AN ERROR MESSAGE FOLLOWED BY\\
\tab[5.2] \word{bs} THE LINE THAT HAD THE ERROR.\\
\tab \word{TYPE} \word{SOURCE} \word{TYPE} \word{CR}		\tab[3] \word{bs} DISPLAY LINE CORRESPONDING TO ERROR\\
\tab EMPTY-STACK											\tab[7.8] \word{bs} THROW AWAY EVERY THING ELSE\\
\word{;} \\
\\
\word{VARIABLE} ACTUAL-DEPTH \tab[3] \word{bs} STACK RECORD\\
\tab[.7] \word{CREATE} ACTUAL-RESULTS 20 \word{CELLS} \word{ALLOT} \\
\\
\word{:} \{ \tab[2.8] \word{bs} ( -{}- ) SYNTACTIC SUGAR.\\
\tab \word{;} \\
\\
\word{:} -> \tab[2.2] \word{bs} ( ... -{}- ) RECORD DEPTH AND CONTENT OF STACK.\\
\tab \word{DEPTH} \word{DUP} ACTUAL-DEPTH \word{!}				\tab[5.9]  \word{bs} RECORD DEPTH\\
\tab \word{qDUP} \word{IF}										\tab[16.1] \word{bs} IF THERE IS SOMETHING ON STACK\\
\tab[2] 0 \word{DO} ACTUAL-RESULTS \word{I} \word{CELLS} \word{+} \word{!} \word{LOOP} \tab[.6] \word{bs} SAVE THEM\\
\tab \word{THEN} \word{;} \\
\\
\word{:} \} \tab[2.8] \word{bs} ( ... -{}- ) COMPARE STACK (EXPECTED) CONTENTS WITH SAVED\\
\tab[5.2] \word{bs} (ACTUAL) CONTENTS.\\
\tab \word{DEPTH} ACTUAL-DEPTH \word{@} \word{=} \word{IF}		\tab[4.85]  \word{bs} IF DEPTHS MATCH\\
\tab[2] \word{DEPTH} \word{qDUP} \word{IF}						\tab[9.05] \word{bs} IF THERE IS SOMETHING ON THE STACK\\
\tab[3]		0 \word{DO}											\tab[14.8] \word{bs} FOR EACH STACK ITEM\\
\tab[4]			 ACTUAL-RESULTS \word{I} \word{CELLS} \word{+} \word{@}	\tab[.6] \word{bs} COMPARE ACTUAL WITH EXPECTED\\
\tab[4]			\word{ne} \word{IF} \word{Sq} INCORRECT RESULT: " ERROR \word{LEAVE} \word{THEN}\\
\tab[3]		\word{LOOP}\\
\tab[2] \word{THEN}\\
\tab \word{ELSE}												\tab[17.4] \word{bs} DEPTH MISMATCH\\
\tab[2] \word{Sq} WRONG NUMBER OF RESULTS: " ERROR\\
\tab \word{THEN} \word{;} \\
\\
\word{:} TESTING \tab[.65] \word{bs} ( -{}- ) TALKING COMMENT.\\
\tab \word{SOURCE} VERBOSE \word{@} \\
\tab \word{IF} \word{DUP} \word{toR} \word{TYPE} \word{CR} \word{Rfrom} \word{toIN} \word{!}\\
\tab \word{ELSE} \word{toIN} \word{!} \word{DROP}\\
\tab \word{THEN} \word{;}
\end{tt}

\section{Core Tests} % John Hayes' original Core Tests

The test starts by verifying basic assumptions about number
representation. It then builds on this with tests of boolean logic,
shifting, and comparisons. It then tests basic stack manipulations
and arithmetic. Ultimately, it tests the Forth interpreter and
compiler.

The tests presented here are John Hayes' original test which
accompany the tester package. Additional test have been given in
the rationale for individual words.

\begin{tt}
\word{bs} From: ~ John Hayes S1I \\
\word{bs} Subject: core.fr \\
\word{bs} Date: ~ Mon, 27 Nov 95 13:10 \\
\\
\word{bs} (C) 1995 JOHNS HOPKINS UNIVERSITY / APPLIED PHYSICS LABORATORY \\
\word{bs} MAY BE DISTRIBUTED FREELY AS LONG AS THIS COPYRIGHT NOTICE REMAINS. \\
\word{bs} VERSION 1.2 \\
\word{bs} THIS PROGRAM TESTS THE CORE WORDS OF AN ANS FORTH SYSTEM. \\
\word{bs} THE PROGRAM ASSUMES A TWO'S COMPLEMENT IMPLEMENTATION WHERE \\
\word{bs} THE RANGE OF SIGNED NUMBERS IS -2\textasciicircum(N-1) ... 2\textasciicircum(N-1)-1 AND \\
\word{bs} THE RANGE OF UNSIGNED NUMBERS IS 0 ... 2\textasciicircum(N)-1. \\
\word{bs} I HAVEN'T FIGURED OUT HOW TO TEST KEY, QUIT, ABORT, OR ABORT"... \\
\word{bs} I ALSO HAVEN'T THOUGHT OF A WAY TO TEST ENVIRONMENT?... \\
\\
TESTING CORE WORDS \\
\word{HEX} \\
\end{tt}

\subsection{Basic Assumptions}

\begin{tt}
TESTING BASIC ASSUMPTIONS \\
\\
\{ -> \} \tab[8] \word{bs} START WITH CLEAN SLATE \\
( TEST IF ANY BITS ARE SET; ANSWER IN BASE 1 ) \\
\{ \word{:} BITSSET? \word{IF} 0 0 \word{ELSE} 0 \word{THEN} \word{;} -> \} \\
\{ ~0 BITSSET? -> 0 \}		\tab[2.2] \word{p} ZERO IS ALL BITS CLEAR ) \\
\{ ~1 BITSSET? -> 0 0 \}	\tab[1.0] \word{p} OTHER NUMBER HAVE AT LEAST ONE BIT ) \\
\{ -1 BITSSET? -> 0 0 \}
\end{tt}

\subsection{Booleans}

\begin{tt}
TESTING BOOLEANS: \word{INVERT} \word{AND} \word{OR} \word{XOR}

\{ 0 0 \word{AND} -> 0 \} \\
\{ 0 1 \word{AND} -> 0 \} \\
\{ 1 0 \word{AND} -> 0 \} \\
\{ 1 1 \word{AND} -> 1 \}

\{ 0 \word{INVERT} 1 \word{AND} -> 1 \} \\
\{ 1 \word{INVERT} 1 \word{AND} -> 0 \}

0 \tab[3.6] \word{CONSTANT} 0S \\
0 \word{INVERT} \word{CONSTANT} 1S

\{ 0S \word{INVERT} -> 1S \} \\
\{ 1S \word{INVERT} -> 0S \}

\{ 0S 0S \word{AND} -> 0S \} \\
\{ 0S 1S \word{AND} -> 0S \} \\
\{ 1S 0S \word{AND} -> 0S \} \\
\{ 1S 1S \word{AND} -> 1S \}

\{ 0S 0S \word{OR} -> 0S \} \\
\{ 0S 1S \word{OR} -> 1S \} \\
\{ 1S 0S \word{OR} -> 1S \} \\
\{ 1S 1S \word{OR} -> 1S \}

\{ 0S 0S \word{XOR} -> 0S \} \\
\{ 0S 1S \word{XOR} -> 1S \} \\
\{ 1S 0S \word{XOR} -> 1S \} \\
\{ 1S 1S \word{XOR} -> 0S \}
\end{tt}

\subsection{Shifts}

\begin{tt}
TESTING \word{2*} \word{2/} \word{LSHIFT} \word{RSHIFT}

\word{p} WE TRUST 1S, \word{INVERT}, AND BITSSET?; WE WILL CONFIRM \word{RSHIFT} LATER ) \\
1S 1 \word{RSHIFT} \word{INVERT} \word{CONSTANT} MSB \\
\{ MSB BITSSET? -> 0 0 \}

\{ 0S	\word{2*} -> 0S \} \\
\{ 1	\word{2*} -> 2 \} \\
\{ 4000 \word{2*} -> 8000 \} \\
\{ 1S	\word{2*} 1 \word{XOR} -> 1S \} \\
\{ MSB	\word{2*} -> 0S \}

\{ 0S		\word{2/} -> 0S \} \\
\{ 1		\word{2/} -> 0 \} \\
\{ 4000		\word{2/} -> 2000 \} \\
\{ 1S		\word{2/} -> 1S \} \tab[4] \word{bs} MSB PROPOGATED \\
\{ 1S 1 \word{XOR} \word{2/} -> 1S \} \\
\{ MSB \word{2/} MSB \word{AND} -> MSB \}

\{   1 0 \word{LSHIFT} -> 1 \} \\
\{   1 1 \word{LSHIFT} -> 2 \} \\
\{   1 2 \word{LSHIFT} -> 4 \} \\
\{   1 F \word{LSHIFT} -> 8000 \} \tab[4] \word{bs} BIGGEST GUARANTEED SHIFT \\
\{  1S 1 \word{LSHIFT} 1 \word{XOR} -> 1S \} \\
\{ MSB 1 \word{LSHIFT} -> 0 \}

\{ 1 0 \word{RSHIFT} -> 1 \} \\
\{ 1 1 \word{RSHIFT} -> 0 \} \\
\{ 2 1 \word{RSHIFT} -> 1 \} \\
\{ 4 2 \word{RSHIFT} -> 1 \} \\
\{ 8000 F \word{RSHIFT} -> 1 \}					\tab[6.6] \word{bs} BIGGEST \\
\{ MSB 1 \word{RSHIFT} MSB \word{AND} -> 0 \}	\tab[2.5] \word{bs} \word{RSHIFT} ZERO FILLS MSBS \\
\{ MSB 1 \word{RSHIFT} \word{2*} -> MSB \}
\end{tt}

\subsection{Comparisons}

\begin{tt}
TESTING COMPARISONS: \word{0=} \word{=} \word{0less} \word{less} \word{more} \word{Uless} \word{MIN} \word{MAX}

0 \word{INVERT} 				\tab[7.9]		\word{CONSTANT} MAX-UINT \\
0 \word{INVERT} 1 \word{RSHIFT} \tab[3.15]		\word{CONSTANT} MAX-INT \\
0 \word{INVERT} 1 \word{RSHIFT} \word{INVERT}	\word{CONSTANT} MIN-INT \\
0 \word{INVERT} 1 \word{RSHIFT} \tab[3.15]		\word{CONSTANT} MID-UINT \\
0 \word{INVERT} 1 \word{RSHIFT} \word{INVERT}	\word{CONSTANT} MID-UINT+1

0S \word{CONSTANT} <FALSE> \\
1S \word{CONSTANT} <TRUE>

\{  0 \word{0=} -> <TRUE>  \} \\
\{  1 \word{0=} -> <FALSE> \} \\
\{  2 \word{0=} -> <FALSE> \} \\
\{ -1 \word{0=} -> <FALSE> \} \\
\{ MAX-UINT \word{0=} -> <FALSE> \} \\
\{ MIN-INT  \word{0=} -> <FALSE> \} \\
\{ MAX-INT  \word{0=} -> <FALSE> \}

\{  0  0 \word{=} -> <TRUE>  \} \\
\{  1  1 \word{=} -> <TRUE>  \} \\
\{ -1 -1 \word{=} -> <TRUE>  \} \\
\{  1  0 \word{=} -> <FALSE> \} \\
\{ -1  0 \word{=} -> <FALSE> \} \\
\{  0  1 \word{=} -> <FALSE> \} \\
\{  0 -1 \word{=} -> <FALSE> \} \\

\{       0 \word{0less} -> <FALSE> \} \\
\{      -1 \word{0less} -> <TRUE>  \} \\
\{ MIN-INT \word{0less} -> <TRUE>  \} \\
\{       1 \word{0less} -> <FALSE> \} \\
\{ MAX-INT \word{0less} -> <FALSE> \}

\{       0       1 \word{less} -> <TRUE>  \} \\
\{       1       2 \word{less} -> <TRUE>  \} \\
\{      -1       0 \word{less} -> <TRUE>  \} \\
\{      -1       1 \word{less} -> <TRUE>  \} \\
\{ MIN-INT       0 \word{less} -> <TRUE>  \} \\
\{ MIN-INT MAX-INT \word{less} -> <TRUE>  \} \\
\{       0 MAX-INT \word{less} -> <TRUE>  \} \\
\{       0       0 \word{less} -> <FALSE> \} \\
\{       1       1 \word{less} -> <FALSE> \} \\
\{       1       0 \word{less} -> <FALSE> \} \\
\{       2       1 \word{less} -> <FALSE> \} \\
\{       0      -1 \word{less} -> <FALSE> \} \\
\{       1      -1 \word{less} -> <FALSE> \} \\
\{       0 MIN-INT \word{less} -> <FALSE> \} \\
\{ MAX-INT MIN-INT \word{less} -> <FALSE> \} \\
\{ MAX-INT       0 \word{less} -> <FALSE> \}


\{       0       1 \word{more} -> <FALSE> \} \\
\{       1       2 \word{more} -> <FALSE> \} \\
\{      -1       0 \word{more} -> <FALSE> \} \\
\{      -1       1 \word{more} -> <FALSE> \} \\
\{ MIN-INT       0 \word{more} -> <FALSE> \} \\
\{ MIN-INT MAX-INT \word{more} -> <FALSE> \} \\
\{       0 MAX-INT \word{more} -> <FALSE> \} \\
\{       0       0 \word{more} -> <FALSE> \} \\
\{       1       1 \word{more} -> <FALSE> \} \\
\{       1       0 \word{more} -> <TRUE>  \} \\
\{       2       1 \word{more} -> <TRUE>  \} \\
\{       0      -1 \word{more} -> <TRUE>  \} \\
\{       1      -1 \word{more} -> <TRUE>  \} \\
\{       0 MIN-INT \word{more} -> <TRUE>  \} \\
\{ MAX-INT MIN-INT \word{more} -> <TRUE>  \} \\
\{ MAX-INT       0 \word{more} -> <TRUE>  \}

\{        0        1 \word{Uless} -> <TRUE>  \} \\
\{        1        2 \word{Uless} -> <TRUE>  \} \\
\{        0 MID-UINT \word{Uless} -> <TRUE>  \} \\
\{        0 MAX-UINT \word{Uless} -> <TRUE>  \} \\
\{ MID-UINT MAX-UINT \word{Uless} -> <TRUE>  \} \\
\{        0        0 \word{Uless} -> <FALSE> \} \\
\{        1        1 \word{Uless} -> <FALSE> \} \\
\{        1        0 \word{Uless} -> <FALSE> \} \\
\{        2        1 \word{Uless} -> <FALSE> \} \\
\{ MID-UINT        0 \word{Uless} -> <FALSE> \} \\
\{ MAX-UINT        0 \word{Uless} -> <FALSE> \} \\
\{ MAX-UINT MID-UINT \word{Uless} -> <FALSE> \}

\{       0       1 \word{MIN} ->       0 \} \\
\{       1       2 \word{MIN} ->       1 \} \\
\{      -1       0 \word{MIN} ->      -1 \} \\
\{      -1       1 \word{MIN} ->      -1 \} \\
\{ MIN-INT       0 \word{MIN} -> MIN-INT \} \\
\{ MIN-INT MAX-INT \word{MIN} -> MIN-INT \} \\
\{       0 MAX-INT \word{MIN} ->       0 \} \\
\{       0       0 \word{MIN} ->       0 \} \\
\{       1       1 \word{MIN} ->       1 \} \\
\{       1       0 \word{MIN} ->       0 \} \\
\{       2       1 \word{MIN} ->       1 \} \\
\{       0      -1 \word{MIN} ->      -1 \} \\
\{       1      -1 \word{MIN} ->      -1 \} \\
\{       0 MIN-INT \word{MIN} -> MIN-INT \} \\
\{ MAX-INT MIN-INT \word{MIN} -> MIN-INT \} \\
\{ MAX-INT       0 \word{MIN} ->       0 \} \\

\{       0       1 \word{MAX} ->       1 \} \\
\{       1       2 \word{MAX} ->       2 \} \\
\{      -1       0 \word{MAX} ->       0 \} \\
\{      -1       1 \word{MAX} ->       1 \} \\
\{ MIN-INT       0 \word{MAX} ->       0 \} \\
\{ MIN-INT MAX-INT \word{MAX} -> MAX-INT \} \\
\{       0 MAX-INT \word{MAX} -> MAX-INT \} \\
\{       0       0 \word{MAX} ->       0 \} \\
\{       1       1 \word{MAX} ->       1 \} \\
\{       1       0 \word{MAX} ->       1 \} \\
\{       2       1 \word{MAX} ->       2 \} \\
\{       0      -1 \word{MAX} ->       0 \} \\
\{       1      -1 \word{MAX} ->       1 \} \\
\{       0 MIN-INT \word{MAX} ->       0 \} \\
\{ MAX-INT MIN-INT \word{MAX} -> MAX-INT \} \\
\{ MAX-INT       0 \word{MAX} -> MAX-INT \} \\
\end{tt}

\subsection{Stack Operators}

\begin{tt}
TESTING STACK OPS: \small \word{2DROP} \word{2DUP} \word{2OVER} \word{2SWAP} \word{qDUP} \word{DEPTH} \word{DROP} \word{DUP} \word{OVER} \word{ROT} \word{SWAP}

\{      1 2 \word{2DROP} ->               \} \\
\{      1 2 \word{2DUP}  ->     1 2  1  2 \} \\
\{  1 2 3 4 \word{2OVER} -> 1 2 3 4  1  2 \} \\
\{  1 2 3 4 \word{2SWAP} ->     3 4  1  2 \} \\
\{        0 \word{qDUP}  ->             0 \} \\
\{        1 \word{qDUP}  ->          1  1 \} \\
\{       -1 \word{qDUP}  ->         -1 -1 \} \\
\{          \word{DEPTH} ->             0 \} \\
\{        0 \word{DEPTH} ->          0  1 \} \\
\{      0 1 \word{DEPTH} ->       0  1  2 \} \\
\{        0 \word{DROP}  ->               \} \\
\{      1 2 \word{DROP}  ->             1 \} \\
\{        1 \word{DUP}   ->          1  1 \} \\
\{      1 2 \word{OVER}  ->       1  2  1 \} \\
\{    1 2 3 \word{ROT}   ->       2  3  1 \} \\
\{      1 2 \word{SWAP}  ->          2  1 \}
\end{tt}

\subsection{Return Stack Operators}

\begin{tt}
TESTING \word{toR} \word{Rfrom} \word{R@}

\{ : GR1 \word{toR} \word{Rfrom} ; -> \} \\
\{ : GR2 \word{toR} \word{R@} \word{Rfrom} \word{DROP} ; -> \} \\
\{ 123 GR1 -> 123 \} \\
\{ 123 GR2 -> 123 \} \\
\{ 1S GR1 -> 1S \} \tab[2] \word{p} RETURN STACK HOLDS CELLS )
\end{tt}

\subsection{Addition and Subtraction}

\begin{tt}
TESTING ADD/SUBTRACT: \word{+} \word{-} \word{1+} \word{1-} \word{ABS} \word{NEGATE}

\{        0  5 \word{+} ->          5 \} \\
\{        5  0 \word{+} ->          5 \} \\
\{        0 -5 \word{+} ->         -5 \} \\
\{       -5  0 \word{+} ->         -5 \} \\
\{        1  2 \word{+} ->          3 \} \\
\{        1 -2 \word{+} ->         -1 \} \\
\{       -1  2 \word{+} ->          1 \} \\
\{       -1 -2 \word{+} ->         -3 \} \\
\{       -1  1 \word{+} ->          0 \} \\
\{ MID-UINT  1 \word{+} -> MID-UINT+1 \}

\{          0  5 \word{-} ->       -5 \} \\
\{          5  0 \word{-} ->        5 \} \\
\{          0 -5 \word{-} ->        5 \} \\
\{         -5  0 \word{-} ->       -5 \} \\
\{          1  2 \word{-} ->       -1 \} \\
\{          1 -2 \word{-} ->        3 \} \\
\{         -1  2 \word{-} ->       -3 \} \\
\{         -1 -2 \word{-} ->        1 \} \\
\{          0  1 \word{-} ->       -1 \} \\
\{ MID-UINT+1  1 \word{-} -> MID-UINT \}

\{        0 \word{1+} ->          1 \} \\
\{       -1 \word{1+} ->          0 \} \\
\{        1 \word{1+} ->          2 \} \\
\{ MID-UINT \word{1+} -> MID-UINT+1 \}

\{          2 \word{1-} ->        1 \} \\
\{          1 \word{1-} ->        0 \} \\
\{          0 \word{1-} ->       -1 \} \\
\{ MID-UINT+1 \word{1-} -> MID-UINT \}

\{  0 \word{NEGATE} ->  0 \} \\
\{  1 \word{NEGATE} -> -1 \} \\
\{ -1 \word{NEGATE} ->  1 \} \\
\{  2 \word{NEGATE} -> -2 \} \\
\{ -2 \word{NEGATE} ->  2 \}

\{       0 \word{ABS} ->          0 \} \\
\{       1 \word{ABS} ->          1 \} \\
\{      -1 \word{ABS} ->          1 \} \\
\{ MIN-INT \word{ABS} -> MID-UINT+1 \}
\end{tt}

\subsection{Multiplication}

\begin{tt}
TESTING MULTIPLY: \word{StoD} * M* UM*

\{       0 \word{StoD} ->       0  0 \} \\
\{       1 \word{StoD} ->       1  0 \} \\
\{       2 \word{StoD} ->       2  0 \} \\
\{      -1 \word{StoD} ->      -1 -1 \} \\
\{      -2 \word{StoD} ->      -2 -1 \} \\
\{ MIN-INT \word{StoD} -> MIN-INT -1 \} \\
\{ MAX-INT \word{StoD} -> MAX-INT  0 \}

\{       0       0 \word{M*} ->       0 \word{StoD} \} \\
\{       0       1 \word{M*} ->       0 \word{StoD} \} \\
\{       1       0 \word{M*} ->       0 \word{StoD} \} \\
\{       1       2 \word{M*} ->       2 \word{StoD} \} \\
\{       2       1 \word{M*} ->       2 \word{StoD} \} \\
\{       3       3 \word{M*} ->       9 \word{StoD} \} \\
\{      -3       3 \word{M*} ->      -9 \word{StoD} \} \\
\{       3      -3 \word{M*} ->      -9 \word{StoD} \} \\
\{      -3      -3 \word{M*} ->       9 \word{StoD} \} \\
\{       0 MIN-INT \word{M*} ->       0 \word{StoD} \} \\
\{       1 MIN-INT \word{M*} -> MIN-INT \word{StoD} \} \\
\{       2 MIN-INT \word{M*} ->       0          1S \} \\
\{       0 MAX-INT \word{M*} ->       0 \word{StoD} \} \\
\{       1 MAX-INT \word{M*} -> MAX-INT \word{StoD} \} \\
\{       2 MAX-INT \word{M*} -> MAX-INT     1 \word{LSHIFT} 0 \} \\
\{ MIN-INT MIN-INT \word{M*} ->       0 MSB 1 \word{RSHIFT}   \} \\
\{ MAX-INT MIN-INT \word{M*} ->     MSB MSB \word{2/} \} \\
\{ MAX-INT MAX-INT \word{M*} ->       1 MSB \word{2/} \word{INVERT} \}

\{  0  0 \word{*} ->  0 \} \tab[4] \word{bs} TEST IDENTITIES \\
\{  0  1 \word{*} ->  0 \} \\
\{  1  0 \word{*} ->  0 \} \\
\{  1  2 \word{*} ->  2 \} \\
\{  2  1 \word{*} ->  2 \} \\
\{  3  3 \word{*} ->  9 \} \\
\{ -3  3 \word{*} -> -9 \} \\
\{  3 -3 \word{*} -> -9 \} \\
\{ -3 -3 \word{*} ->  9 \}

\{ MID-UINT+1 1 \word{RSHIFT} 2 \word{*} -> MID-UINT+1 \} \\
\{ MID-UINT+1 2 \word{RSHIFT} 4 \word{*} -> MID-UINT+1 \} \\
\{ MID-UINT+1 1 \word{RSHIFT} MID-UINT+1 \word{OR} 2 \word{*} -> MID-UINT+1 \} \\

\{ 0 0 \word{UM*} -> 0 0 \} \\
\{ 0 1 \word{UM*} -> 0 0 \} \\
\{ 1 0 \word{UM*} -> 0 0 \} \\
\{ 1 2 \word{UM*} -> 2 0 \} \\
\{ 2 1 \word{UM*} -> 2 0 \} \\
\{ 3 3 \word{UM*} -> 9 0 \}

\{ MID-UINT+1 1 \word{RSHIFT} 2 \word{UM*} -> MID-UINT+1 0 \} \\
\{ MID-UINT+1 2                 \word{UM*} -> 0 1 \} \\
\{ MID-UINT+1 4                 \word{UM*} -> 0 2 \} \\
\{ 1S 2                         \word{UM*} -> 1S 1 \word{LSHIFT} 1 \} \\
\{ MAX-UINT MAX-UINT            \word{UM*} -> 1 1 \word{INVERT} \}
\end{tt}

\subsection{Division}

\begin{tt}
TESTING DIVIDE: \word{FM/MOD} \word{SM/REM} \word{UM/MOD} \word{/MOD} \word{/} \word{MOD} \word{*/} \word{*/MOD}

\{       0 \word{StoD}             1 \word{FM/MOD} ->  0       0 \} \\
\{       1 \word{StoD}             1 \word{FM/MOD} ->  0       1 \} \\
\{       2 \word{StoD}             1 \word{FM/MOD} ->  0       2 \} \\
\{      -1 \word{StoD}             1 \word{FM/MOD} ->  0      -1 \} \\
\{      -2 \word{StoD}             1 \word{FM/MOD} ->  0      -2 \} \\
\{       0 \word{StoD}            -1 \word{FM/MOD} ->  0       0 \} \\
\{       1 \word{StoD}            -1 \word{FM/MOD} ->  0      -1 \} \\
\{       2 \word{StoD}            -1 \word{FM/MOD} ->  0      -2 \} \\
\{      -1 \word{StoD}            -1 \word{FM/MOD} ->  0       1 \} \\
\{      -2 \word{StoD}            -1 \word{FM/MOD} ->  0       2 \} \\
\{       2 \word{StoD}             2 \word{FM/MOD} ->  0       1 \} \\
\{      -1 \word{StoD}            -1 \word{FM/MOD} ->  0       1 \} \\
\{      -2 \word{StoD}            -2 \word{FM/MOD} ->  0       1 \} \\
\{       7 \word{StoD}             3 \word{FM/MOD} ->  1       2 \} \\
\{       7 \word{StoD}            -3 \word{FM/MOD} -> -2      -3 \} \\
\{      -7 \word{StoD}             3 \word{FM/MOD} ->  2      -3 \} \\
\{      -7 \word{StoD}            -3 \word{FM/MOD} -> -1       2 \} \\
\{ MAX-INT \word{StoD}             1 \word{FM/MOD} ->  0 MAX-INT \} \\
\{ MIN-INT \word{StoD}             1 \word{FM/MOD} ->  0 MIN-INT \} \\
\{ MAX-INT \word{StoD}       MAX-INT \word{FM/MOD} ->  0       1 \} \\
\{ MIN-INT \word{StoD}       MIN-INT \word{FM/MOD} ->  0       1 \} \\
\{    1S 1                         4 \word{FM/MOD} ->  3 MAX-INT \} \\
\{       1 MIN-INT \word{M*}       1 \word{FM/MOD} ->  0 MIN-INT \} \\
\{       1 MIN-INT \word{M*} MIN-INT \word{FM/MOD} ->  0       1 \} \\
\{       2 MIN-INT \word{M*}       2 \word{FM/MOD} ->  0 MIN-INT \} \\
\{       2 MIN-INT \word{M*} MIN-INT \word{FM/MOD} ->  0       2 \} \\
\{       1 MAX-INT \word{M*}       1 \word{FM/MOD} ->  0 MAX-INT \} \\
\{       1 MAX-INT \word{M*} MAX-INT \word{FM/MOD} ->  0       1 \} \\
\{       2 MAX-INT \word{M*}       2 \word{FM/MOD} ->  0 MAX-INT \} \\
\{       2 MAX-INT \word{M*} MAX-INT \word{FM/MOD} ->  0       2 \} \\
\{ MIN-INT MIN-INT \word{M*} MIN-INT \word{FM/MOD} ->  0 MIN-INT \} \\
\{ MIN-INT MAX-INT \word{M*} MIN-INT \word{FM/MOD} ->  0 MAX-INT \} \\
\{ MIN-INT MAX-INT \word{M*} MAX-INT \word{FM/MOD} ->  0 MIN-INT \} \\
\{ MAX-INT MAX-INT \word{M*} MAX-INT \word{FM/MOD} ->  0 MAX-INT \}

\{       0 \word{StoD}             1 \word{SM/REM} ->  0       0 \} \\
\{       1 \word{StoD}             1 \word{SM/REM} ->  0       1 \} \\
\{       2 \word{StoD}             1 \word{SM/REM} ->  0       2 \} \\
\{      -1 \word{StoD}             1 \word{SM/REM} ->  0      -1 \} \\
\{      -2 \word{StoD}             1 \word{SM/REM} ->  0      -2 \} \\
\{       0 \word{StoD}            -1 \word{SM/REM} ->  0       0 \} \\
\{       1 \word{StoD}            -1 \word{SM/REM} ->  0      -1 \} \\
\{       2 \word{StoD}            -1 \word{SM/REM} ->  0      -2 \} \\
\{      -1 \word{StoD}            -1 \word{SM/REM} ->  0       1 \} \\
\{      -2 \word{StoD}            -1 \word{SM/REM} ->  0       2 \} \\
\{       2 \word{StoD}             2 \word{SM/REM} ->  0       1 \} \\
\{      -1 \word{StoD}            -1 \word{SM/REM} ->  0       1 \} \\
\{      -2 \word{StoD}            -2 \word{SM/REM} ->  0       1 \} \\
\{       7 \word{StoD}             3 \word{SM/REM} ->  1       2 \} \\
\{       7 \word{StoD}            -3 \word{SM/REM} ->  1      -2 \} \\
\{      -7 \word{StoD}             3 \word{SM/REM} -> -1      -2 \} \\
\{      -7 \word{StoD}            -3 \word{SM/REM} -> -1       2 \} \\
\{ MAX-INT \word{StoD}             1 \word{SM/REM} ->  0 MAX-INT \} \\
\{ MIN-INT \word{StoD}             1 \word{SM/REM} ->  0 MIN-INT \} \\
\{ MAX-INT \word{StoD}       MAX-INT \word{SM/REM} ->  0       1 \} \\
\{ MIN-INT \word{StoD}       MIN-INT \word{SM/REM} ->  0       1 \} \\
\{      1S       1                 4 \word{SM/REM} ->  3 MAX-INT \} \\
\{       2 MIN-INT \word{M*}       2 \word{SM/REM} ->  0 MIN-INT \} \\
\{       2 MIN-INT \word{M*} MIN-INT \word{SM/REM} ->  0       2 \} \\
\{       2 MAX-INT \word{M*}       2 \word{SM/REM} ->  0 MAX-INT \} \\
\{       2 MAX-INT \word{M*} MAX-INT \word{SM/REM} ->  0       2 \} \\
\{ MIN-INT MIN-INT \word{M*} MIN-INT \word{SM/REM} ->  0 MIN-INT \} \\
\{ MIN-INT MAX-INT \word{M*} MIN-INT \word{SM/REM} ->  0 MAX-INT \} \\
\{ MIN-INT MAX-INT \word{M*} MAX-INT \word{SM/REM} ->  0 MIN-INT \} \\
\{ MAX-INT MAX-INT \word{M*} MAX-INT \word{SM/REM} ->  0 MAX-INT \}

\{        0                   0        1 \word{UM/MOD} -> 0        0 \} \\
\{        1                   0        1 \word{UM/MOD} -> 0        1 \} \\
\{        1                   0        2 \word{UM/MOD} -> 1        0 \} \\
\{        3                   0        2 \word{UM/MOD} -> 1        1 \} \\
\{ MAX-UINT        2 \word{UM*}        2 \word{UM/MOD} -> 0 MAX-UINT \} \\
\{ MAX-UINT        2 \word{UM*} MAX-UINT \word{UM/MOD} -> 0        2 \} \\
\{ MAX-UINT MAX-UINT \word{UM*} MAX-UINT \word{UM/MOD} -> 0 MAX-UINT \}

\word{:} IFFLOORED \\
\tab \word{[} -3 2 \word{/} -2 = \word{INVERT} \word{]}
	\word{LITERAL} \word{IF} \word{POSTPONE} \word{bs} \word{THEN}
\word{;} \\
\word{:} IFSYM \\
\tab \word{[} -3 2 \word{/} -1 = \word{INVERT} \word{]}
	\word{LITERAL} \word{IF} \word{POSTPONE} \word{bs} \word{THEN}
\word {;}

\word{bs} THE SYSTEM MIGHT DO EITHER FLOORED OR SYMMETRIC DIVISION. \\
\word{bs} SINCE WE HAVE ALREADY TESTED \word{M*}, \word{FM/MOD}, AND \word{SM/REM} WE CAN USE THEM \\
\word{bs} IN TEST.

IFFLOORED \tab  \word{:} T/MOD  \word{toR} \word{StoD} \word{Rfrom} \word{FM/MOD} \word{;} \\
IFFLOORED \tab	\word{:} T/ T/MOD \word{SWAP} \word{DROP} \word{;} \\
IFFLOORED \tab 	\word{:} TMOD T/MOD \word{DROP} \word{;} \\
IFFLOORED \tab	\word{:} T*/MOD \word{toR} \word{M*} \word{Rfrom} \word{FM/MOD} \word{;} \\
IFFLOORED \tab	\word{:} T*/ T*/MOD \word{SWAP} \word{DROP} \word{;}

IFSYM \tab[2.6] \word{:} T/MOD  \word{toR} \word{StoD} \word{Rfrom} \word{SM/REM} \word{;} \\
IFSYM \tab[2.6] \word{:} T/ T/MOD \word{SWAP} \word{DROP} \word{;} \\
IFSYM \tab[2.6]	\word{:} TMOD T/MOD \word{DROP} \word{;} \\
IFSYM \tab[2.6]	\word{:} T*/MOD \word{toR} \word{M*} \word{Rfrom} \word{SM/REM} \word{;} \\
IFSYM \tab[2.6]	\word{:} T*/ T*/MOD \word{SWAP} \word{DROP} \word{;}

\{       0       1 \word{/MOD} ->       0       1 T/MOD \} \\
\{       1       1 \word{/MOD} ->       1       1 T/MOD \} \\
\{       2       1 \word{/MOD} ->       2       1 T/MOD \} \\
\{      -1       1 \word{/MOD} ->      -1       1 T/MOD \} \\
\{      -2       1 \word{/MOD} ->      -2       1 T/MOD \} \\
\{       0      -1 \word{/MOD} ->       0      -1 T/MOD \} \\
\{       1      -1 \word{/MOD} ->       1      -1 T/MOD \} \\
\{       2      -1 \word{/MOD} ->       2      -1 T/MOD \} \\
\{      -1      -1 \word{/MOD} ->      -1      -1 T/MOD \} \\
\{      -2      -1 \word{/MOD} ->      -2      -1 T/MOD \} \\
\{       2       2 \word{/MOD} ->       2       2 T/MOD \} \\
\{      -1      -1 \word{/MOD} ->      -1      -1 T/MOD \} \\
\{      -2      -2 \word{/MOD} ->      -2      -2 T/MOD \} \\
\{       7       3 \word{/MOD} ->       7       3 T/MOD \} \\
\{       7      -3 \word{/MOD} ->       7      -3 T/MOD \} \\
\{      -7       3 \word{/MOD} ->      -7       3 T/MOD \} \\
\{      -7      -3 \word{/MOD} ->      -7      -3 T/MOD \} \\
\{ MAX-INT       1 \word{/MOD} -> MAX-INT       1 T/MOD \} \\
\{ MIN-INT       1 \word{/MOD} -> MIN-INT       1 T/MOD \} \\
\{ MAX-INT MAX-INT \word{/MOD} -> MAX-INT MAX-INT T/MOD \} \\
\{ MIN-INT MIN-INT \word{/MOD} -> MIN-INT MIN-INT T/MOD \}

\{       0       1 \word{/} ->       0       1 T/ \} \\
\{       1       1 \word{/} ->       1       1 T/ \} \\
\{       2       1 \word{/} ->       2       1 T/ \} \\
\{      -1       1 \word{/} ->      -1       1 T/ \} \\
\{      -2       1 \word{/} ->      -2       1 T/ \} \\
\{       0      -1 \word{/} ->       0      -1 T/ \} \\
\{       1      -1 \word{/} ->       1      -1 T/ \} \\
\{       2      -1 \word{/} ->       2      -1 T/ \} \\
\{      -1      -1 \word{/} ->      -1      -1 T/ \} \\
\{      -2      -1 \word{/} ->      -2      -1 T/ \} \\
\{       2       2 \word{/} ->       2       2 T/ \} \\
\{      -1      -1 \word{/} ->      -1      -1 T/ \} \\
\{      -2      -2 \word{/} ->      -2      -2 T/ \} \\
\{       7       3 \word{/} ->       7       3 T/ \} \\
\{       7      -3 \word{/} ->       7      -3 T/ \} \\
\{      -7       3 \word{/} ->      -7       3 T/ \} \\
\{      -7      -3 \word{/} ->      -7      -3 T/ \} \\
\{ MAX-INT       1 \word{/} -> MAX-INT       1 T/ \} \\
\{ MIN-INT       1 \word{/} -> MIN-INT       1 T/ \} \\
\{ MAX-INT MAX-INT \word{/} -> MAX-INT MAX-INT T/ \} \\
\{ MIN-INT MIN-INT \word{/} -> MIN-INT MIN-INT T/ \}

\{       0       1 \word{MOD} ->       0       1 TMOD \} \\
\{       1       1 \word{MOD} ->       1       1 TMOD \} \\
\{       2       1 \word{MOD} ->       2       1 TMOD \} \\
\{      -1       1 \word{MOD} ->      -1       1 TMOD \} \\
\{      -2       1 \word{MOD} ->      -2       1 TMOD \} \\
\{       0      -1 \word{MOD} ->       0      -1 TMOD \} \\
\{       1      -1 \word{MOD} ->       1      -1 TMOD \} \\
\{       2      -1 \word{MOD} ->       2      -1 TMOD \} \\
\{      -1      -1 \word{MOD} ->      -1      -1 TMOD \} \\
\{      -2      -1 \word{MOD} ->      -2      -1 TMOD \} \\
\{       2       2 \word{MOD} ->       2       2 TMOD \} \\
\{      -1      -1 \word{MOD} ->      -1      -1 TMOD \} \\
\{      -2      -2 \word{MOD} ->      -2      -2 TMOD \} \\
\{       7       3 \word{MOD} ->       7       3 TMOD \} \\
\{       7      -3 \word{MOD} ->       7      -3 TMOD \} \\
\{      -7       3 \word{MOD} ->      -7       3 TMOD \} \\
\{      -7      -3 \word{MOD} ->      -7      -3 TMOD \} \\
\{ MAX-INT       1 \word{MOD} -> MAX-INT       1 TMOD \} \\
\{ MIN-INT       1 \word{MOD} -> MIN-INT       1 TMOD \} \\
\{ MAX-INT MAX-INT \word{MOD} -> MAX-INT MAX-INT TMOD \} \\
\{ MIN-INT MIN-INT \word{MOD} -> MIN-INT MIN-INT TMOD \}

\{       0 2       1 \word{*/} ->       0 2       1 T*/ \} \\
\{       1 2       1 \word{*/} ->       1 2       1 T*/ \} \\
\{       2 2       1 \word{*/} ->       2 2       1 T*/ \} \\
\{      -1 2       1 \word{*/} ->      -1 2       1 T*/ \} \\
\{      -2 2       1 \word{*/} ->      -2 2       1 T*/ \} \\
\{       0 2      -1 \word{*/} ->       0 2      -1 T*/ \} \\
\{       1 2      -1 \word{*/} ->       1 2      -1 T*/ \} \\
\{       2 2      -1 \word{*/} ->       2 2      -1 T*/ \} \\
\{      -1 2      -1 \word{*/} ->      -1 2      -1 T*/ \} \\
\{      -2 2      -1 \word{*/} ->      -2 2      -1 T*/ \} \\
\{       2 2       2 \word{*/} ->       2 2       2 T*/ \} \\
\{      -1 2      -1 \word{*/} ->      -1 2      -1 T*/ \} \\
\{      -2 2      -2 \word{*/} ->      -2 2      -2 T*/ \} \\
\{       7 2       3 \word{*/} ->       7 2       3 T*/ \} \\
\{       7 2      -3 \word{*/} ->       7 2      -3 T*/ \} \\
\{      -7 2       3 \word{*/} ->      -7 2       3 T*/ \} \\
\{      -7 2      -3 \word{*/} ->      -7 2      -3 T*/ \} \\
\{ MAX-INT 2 MAX-INT \word{*/} -> MAX-INT 2 MAX-INT T*/ \} \\
\{ MIN-INT 2 MIN-INT \word{*/} -> MIN-INT 2 MIN-INT T*/ \}

\{       0 2       1 \word{*/MOD} ->       0 2       1 T*/MOD \} \\
\{       1 2       1 \word{*/MOD} ->       1 2       1 T*/MOD \} \\
\{       2 2       1 \word{*/MOD} ->       2 2       1 T*/MOD \} \\
\{      -1 2       1 \word{*/MOD} ->      -1 2       1 T*/MOD \} \\
\{      -2 2       1 \word{*/MOD} ->      -2 2       1 T*/MOD \} \\
\{       0 2      -1 \word{*/MOD} ->       0 2      -1 T*/MOD \} \\
\{       1 2      -1 \word{*/MOD} ->       1 2      -1 T*/MOD \} \\
\{       2 2      -1 \word{*/MOD} ->       2 2      -1 T*/MOD \} \\
\{      -1 2      -1 \word{*/MOD} ->      -1 2      -1 T*/MOD \} \\
\{      -2 2      -1 \word{*/MOD} ->      -2 2      -1 T*/MOD \} \\
\{       2 2       2 \word{*/MOD} ->       2 2       2 T*/MOD \} \\
\{      -1 2      -1 \word{*/MOD} ->      -1 2      -1 T*/MOD \} \\
\{      -2 2      -2 \word{*/MOD} ->      -2 2      -2 T*/MOD \} \\
\{       7 2       3 \word{*/MOD} ->       7 2       3 T*/MOD \} \\
\{       7 2      -3 \word{*/MOD} ->       7 2      -3 T*/MOD \} \\
\{      -7 2       3 \word{*/MOD} ->      -7 2       3 T*/MOD \} \\
\{      -7 2      -3 \word{*/MOD} ->      -7 2      -3 T*/MOD \} \\
\{ MAX-INT 2 MAX-INT \word{*/MOD} -> MAX-INT 2 MAX-INT T*/MOD \} \\
\{ MIN-INT 2 MIN-INT \word{*/MOD} -> MIN-INT 2 MIN-INT T*/MOD \} \\
\end{tt}

\subsection{Memory}

\begin{tt}
TESTING \small \word{HERE} \word{,} \word{@} \word{!} \word{CELL+} \word{CELLS} \word{C,} \word{C@} \word{C!} \word{CHAR+} \word{CHARS} \word{2@} \word{2!} \word{ALIGN} \word{ALIGNED} \word{+!} \word{ALLOT}

\word{HERE} 1 \word{ALLOT} \\
\word{HERE} \\
\word{CONSTANT} 2NDA \\
\word{CONSTANT} 1STA \\
\{ 1STA 2NDA \word{Uless} -> <TRUE> \}	\tab \word{bs} HERE MUST GROW WITH ALLOT \\
\{ 1STA \word{1+} -> 2NDA \}			\tab[4.2] \word{bs} {\ldots} BY ONE ADDRESS UNIT \\
\word{p} MISSING TEST: NEGATIVE ALLOT )

\word{HERE} 1 \word{,} \\
\word{HERE} 2 \word{,} \\
\word{CONSTANT} 2ND \\
\word{CONSTANT} 1ST \\
\{ 1ST 2ND \word{Uless} -> <TRUE> \}	\tab \word{bs} HERE MUST GROW WITH ALLOT \\
\{ 1ST \word{CELL+} -> 2ND \}			\tab[2.6] \word{bs} {\ldots} BY ONE CELL \\
\{ 1ST 1 \word{CELLS} \word{+} -> 2ND \} \\
\{ 1ST \word{@} 2ND \word{@} -> 1 2 \} \\
\{ 5 1ST \word{!} -> \} \\
\{ 1ST \word{@} 2ND \word{@} -> 5 2 \} \\
\{ 6 2ND \word{!} -> \} \\
\{ 1ST \word{@} 2ND \word{@} -> 5 6 \} \\
\{ 1ST \word{2@} -> 6 5 \} \\
\{ 2 1 1ST \word{2!} -> \} \\
\{ 1ST \word{2@} -> 2 1 \} \\
\{ 1S 1ST \word{!}  1ST \word{@} -> 1S \} \tab \word{bs} CAN STORE CELL-WIDE VALUE

\word{HERE} 1 \word{C,} \\
\word{HERE} 2 \word{C,} \\
\word{CONSTANT} 2NDC \\
\word{CONSTANT} 1STC \\
\{ 1STC 2NDC \word{Uless} -> <TRUE> \}	\tab \word{bs} HERE MUST GROW WITH ALLOT \\
\{ 1STC \word{CHAR+} -> 2NDC \}			\tab[2.6] \word{bs} {\ldots} BY ONE CHAR \\
\{ 1STC 1 \word{CHARS} \word{+} -> 2NDC \} \\
\{ 1STC \word{C@} 2NDC \word{C@} -> 1 2 \} \\
\{ 3 1STC \word{C!} -> \} \\
\{ 1STC \word{C@} 2NDC \word{C@} -> 3 2 \} \\
\{ 4 2NDC \word{C!} -> \} \\
\{ 1STC \word{C@} 2NDC \word{C@} -> 3 4 \}

\word{ALIGN}  1 \word{ALLOT} \word{HERE}  \word{ALIGN} \word{HERE} 3 \word{CELLS} \word{ALLOT} \\
\word{CONSTANT} A-ADDR  \word{CONSTANT} UA-ADDR \\
\{ UA-ADDR \word{ALIGNED} -> A-ADDR \} \\
\{       1 A-ADDR \word{C!}                A-ADDR              \word{C@} ->       1 \} \\
\{    1234 A-ADDR \word{!}                 A-ADDR              \word{@}  ->    1234 \} \\
\{ 123 456 A-ADDR \word{2!}                A-ADDR              \word{2@} -> 123 456 \} \\
\{       2 A-ADDR \word{CHAR+} \word{C!}   A-ADDR \word{CHAR+} \word{C@} ->       2 \} \\
\{       3 A-ADDR \word{CELL+} \word{C!}   A-ADDR \word{CELL+} \word{C@} ->       3 \} \\
\{    1234 A-ADDR \word{CELL+} \word{!}    A-ADDR \word{CELL+} \word{@}  ->    1234 \} \\
\{ 123 456 A-ADDR \word{CELL+} \word{2!}   A-ADDR \word{CELL+} \word{2@} -> 123 456 \}

\word{:} BITS \word{p} X -{}- U ) \\
\tab 0 \word{SWAP} \word{BEGIN} \word{DUP} \word{WHILE} \word{DUP} MSB \word{AND}
	\word{IF} \word{toR} \word{1+} \word{Rfrom} \word{THEN} \word{2*} \word{REPEAT} \word{DROP}
\word{;} \\
\word{p} CHARACTERS >= 1 AU, <= SIZE OF CELL, >= 8 BITS ) \\
\{ 1 \word{CHARS} 1 \word{less} -> <FALSE> \} \\
\{ 1 \word{CHARS} 1 \word{CELLS} \word{more} -> <FALSE> \} \\
\word{p} TBD: HOW TO FIND NUMBER OF BITS? )

\word{p} CELLS >= 1 AU, INTEGRAL MULTIPLE OF CHAR SIZE, >= 16 BITS ) \\
\{ 1 \word{CELLS} 1 \word{less} -> <FALSE> \} \\
\{ 1 \word{CELLS} 1 \word{CHARS} \word{MOD} -> 0 \} \\
\{ 1S BITS 10 \word{less} -> <FALSE> \}

\{  0 1ST \word{!}  -> \} \\
\{  1 1ST \word{+!} -> \} \\
\{    1ST \word{@}  -> 1 \} \\
\{ -1 1ST \word{+!} 1ST \word{@} -> 0 \}
\end{tt}

\subsection{Characters}

\begin{tt}
TESTING \word{CHAR} \word{[CHAR]} \word{[} \word{]} \word{BL} \word{Sq}

\{ \word{BL} -> 20 \} \\
\{ \word{CHAR} X     -> 58 \} \\
\{ \word{CHAR} HELLO -> 48 \} \\
\{ : GC1 \word{[CHAR]} X     ; -> \} \\
\{ : GC2 \word{[CHAR]} HELLO ; -> \} \\
\{ GC1 -> 58 \} \\
\{ GC2 -> 48 \} \\
\{ \word{:} GC3 \word{[} GC1 \word{]} \word{LITERAL} \word{;} -> \} \\
\{ GC3 -> 58 \} \\
\{ \word{:} GC4 \word{Sq} XY" \word{;} -> \} \\
\{ GC4 \word{SWAP} \word{DROP} -> 2 \} \\
\{ GC4 \word{DROP} \word{DUP} \word{C@} \word{SWAP} \word{CHAR+} \word{C@} -> 58 59 \}
\end{tt}

\subsection{Dictionary}

\begin{tt}
TESTING \word{'} \word{[']} \word{FIND} \word{EXECUTE} \word{IMMEDIATE} \word{COUNT} \word{LITERAL} \word{POSTPONE} \word{STATE}

\{ \word{:} GT1 123 \word{;} -> \} \\
\{ \word{'} GT1 \word{EXECUTE} -> 123 \}
\{ \word{:} GT2 \word{[']} GT1 \word{;} \word{IMMEDIATE} -> \} \\
\{ GT2 \word{EXECUTE} -> 123 \}
\word{HERE}
	3 \word{C,}
	\word{CHAR} G \word{C,}
	\word{CHAR} T \word{C,}
	\word{CHAR} 1 \word{C,}
	\word{CONSTANT} GT1STRING \\
\word{HERE}
	3 \word{C,}
	\word{CHAR} G \word{C,}
	\word{CHAR} T \word{C,}
	\word{CHAR} 2 \word{C,}
	\word{CONSTANT} GT2STRING \\
\{ GT1STRING \word{FIND} -> \word{'} GT1 -1 \} \\
\{ GT2STRING \word{FIND} -> \word{'} GT2 1  \} \\
\word{p} HOW TO SEARCH FOR NON-EXISTENT WORD? )
\{ \word{:} GT3 GT2 \word{LITERAL} \word{;} -> \} \\
\{ GT3 -> \word{'} GT1 \}
\{ GT1STRING \word{COUNT} -> GT1STRING \word{CHAR+} 3 \}

\{ \word{:} GT4 \word{POSTPONE} GT1 \word{;} \word{IMMEDIATE} -> \} \\
\{ \word{:} GT5 GT4 \word{;} -> \} \\
\{ GT5 -> 123 \}
\{ \word{:} GT6 345 \word{;} \word{IMMEDIATE} -> \} \\
\{ \word{:} GT7 \word{POSTPONE} GT6 \word{;} -> \} \\
\{ GT7 -> 345 \}

\{ \word{:} GT8 \word{STATE} \word{@} \word{;} \word{IMMEDIATE} -> \} \\
\{ GT8 -> 0 \} \\
\{ \word{:} GT9 GT8 \word{LITERAL} \word{;} -> \} \\
\{ GT9 \word{0=} -> <FALSE> \}
\end{tt}

\subsection{Flow Control}

\begin{tt}
TESTING \word{IF} \word{ELSE} \word{THEN} \word{BEGIN} \word{WHILE} \word{REPEAT} \word{UNTIL} \word{RECURSE}

\{ \word{:} GI1 \word{IF} 123 \word{THEN} \word{;} -> \} \\
\{ \word{:} GI2 \word{IF} 123 \word{ELSE} 234 \word{THEN} \word{;} -> \} \\
\{  0 GI1 ->     \} \\
\{  1 GI1 -> 123 \} \\
\{ -1 GI1 -> 123 \} \\
\{  0 GI2 -> 234 \} \\
\{  1 GI2 -> 123 \} \\
\{ -1 GI1 -> 123 \}

\{ \word{:} GI3 \word{BEGIN} \word{DUP} 5 \word{less} \word{WHILE} \word{DUP} \word{1+} \word{REPEAT} \word{;} -> \} \\
\{ 0 GI3 -> 0 1 2 3 4 5 \} \\
\{ 4 GI3 -> 4 5 \} \\
\{ 5 GI3 -> 5 \} \\
\{ 6 GI3 -> 6 \}

\{ \word{:} GI4 \word{BEGIN} \word{DUP} \word{1+} \word{DUP} 5 \word{more} \word{UNTIL} \word{;} -> \} \\
\{ 3 GI4 -> 3 4 5 6 \} \\
\{ 5 GI4 -> 5 6 \} \\
\{ 6 GI4 -> 6 7 \}

\{ \word{:} GI5 \word{BEGIN} \word{DUP} 2 \word{more} \word{WHILE} \\
\tab \word{DUP} 5 \word{less} \word{WHILE} \word{DUP} \word{1+} \word{REPEAT} \\
\tab 123 \word{ELSE} 345 \word{THEN} \word{;} -> \} \\
\{ 1 GI5 -> 1 345 \} \\
\{ 2 GI5 -> 2 345 \} \\
\{ 3 GI5 -> 3 4 5 123 \} \\
\{ 4 GI5 -> 4 5 123 \} \\
\{ 5 GI5 -> 5 123 \}

\{ \word{:} GI6 \word{p} N -{}- 0,1,..,N ) \word{DUP} \word{IF}
	\word{DUP} \word{toR} \word{1-} \word{RECURSE} \word{Rfrom}
	\word{THEN} \word{;} -> \} \\
\{ 0 GI6 -> 0 \} \\
\{ 1 GI6 -> 0 1 \} \\
\{ 2 GI6 -> 0 1 2 \} \\
\{ 3 GI6 -> 0 1 2 3 \} \\
\{ 4 GI6 -> 0 1 2 3 4 \}
\end{tt}

\subsection{Counted Loops}

\begin{tt}
TESTING \word{DO} \word{LOOP} \word{+LOOP} \word{I} \word{J} \word{UNLOOP} \word{LEAVE} \word{EXIT}

\{ \word{:} GD1 \word{DO} \word{I} \word{LOOP} \word{;} -> \} \\
\{          4        1 GD1 ->  1 2 3 \} \\
\{          2       -1 GD1 -> -1 0 1 \} \\
\{ MID-UINT+1 MID-UINT GD1 -> MID-UINT \}

\{ \word{:} GD2 \word{DO} \word{I} -1 \word{+LOOP} \word{;} -> \} \\
\{        1          4 GD2 -> 4 3 2 1 \} \\
\{       -1          2 GD2 -> 2 1 0 -1 \} \\
\{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT \}

\{ \word{:} GD3 \word{DO} 1 0 \word{DO} \word{J} \word{LOOP} \word{LOOP} \word{;} -> \} \\
\{          4        1 GD3 -> 1 2 3    \} \\
\{          2       -1 GD3 -> -1 0 1   \} \\
\{ MID-UINT+1 MID-UINT GD3 -> MID-UINT \}

\{ \word{:} GD4 \word{DO} 1 0 \word{DO} \word{J} \word{LOOP} -1 \word{+LOOP} \word{;} -> \} \\
\{        1          4 GD4 -> 4 3 2 1             \} \\
\{       -1          2 GD4 -> 2 1 0 -1            \} \\
\{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT \}

\{ \word{:} GD5 123 \word{SWAP} 0 \word{DO}
	\word{I} 4 \word{more} \word{IF} \word{DROP} 234 \word{LEAVE} \word{THEN} \word{LOOP}
	\word{;} -> \} \\
\{ 1 GD5 -> 123 \} \\
\{ 5 GD5 -> 123 \} \\
\{ 6 GD5 -> 234 \}

\{ \word{:} GD6 \word{p} PAT: {\small \{0 0\},\{0 0\}\{1 0\}\{1 1\},\{0 0\}\{1 0\}\{1 1\}\{2 0\}\{2 1\}\{2 2\}} ) \\
	\tab[2] 0 \word{SWAP} 0 \word{DO} \\
		\tab[3] \word{I} \word{1+} 0 \word{DO}
				\word{I} \word{J} \word{+} 3 \word{=} \word{IF}
				\word{I} \word{UNLOOP} \word{I} \word{UNLOOP} \word{EXIT} \word{THEN} \word{1+} \\
		\tab[2] \word{LOOP} \\
	\tab	\word{LOOP} \word{;} -> \} \\
\{ 1 GD6 -> 1 \} \\
\{ 2 GD6 -> 3 \} \\
\{ 3 GD6 -> 4 1 2 \}
\end{tt}

\subsection{Defining Words}

\begin{tt}
TESTING DEFINING WORDS: \word{:} \word{;} \word{CONSTANT} \word{VARIABLE} \word{CREATE} \word{DOES} \word{toBODY}

\{ 123 \word{CONSTANT} X123 -> \} \\
\{ X123 -> 123 \} \\
\{ \word{:} EQU \word{CONSTANT} \word{;} -> \} \\
\{ X123 EQU Y123 -> \} \\
\{ Y123 -> 123 \}

\{ \word{VARIABLE} V1 ->     \} \\
\{    123 V1 \word{!} ->     \} \\
\{        V1 \word{@} -> 123 \}

\{ \word{:} NOP \word{:} \word{POSTPONE} \word{;} \word{;} -> \} \\
\{ NOP NOP1		NOP NOP2 -> \} \\
\{ 					NOP1 -> \} \\
\{ 					NOP2 -> \}

\{ \word{:} DOES1 \word{DOES} \word{@} 1 \word{+} \word{;} -> \} \\
\{ \word{:} DOES2 \word{DOES} \word{@} 2 \word{+} \word{;} -> \} \\
\{ \word{CREATE} CR1 -> \} \\
\{ CR1 -> \word{HERE}  \} \\
\{ \word{'} CR1 \word{toBODY} -> \word{HERE} \} \\
\{ 1 \word{,} -> \} \\
\{ CR1 \word{@} -> 1 \} \\
\{ DOES1 -> \} \\
\{ CR1 -> 2 \} \\
\{ DOES2 -> \} \\
\{ CR1 -> 3 \}

\{ \word{:} WEIRD: \word{CREATE} \word{DOES} 1 \word{+} \word{DOES} 2 \word{+} \word{;} -> \} \\
\{ WEIRD: W1 -> \} \\
\{ \word{'} W1 \word{toBODY} -> \word{HERE} \} \\
\{ W1 -> \word{HERE} 1 \word{+} \} \\
\{ W1 -> \word{HERE} 2 \word{+} \}
\end{tt}

\subsection{Evaluate}

\begin{tt}
TESTING EVALUATE

\word{:} GE1 \word{Sq} 123" \word{;} \word{IMMEDIATE} \\
\word{:} GE2 \word{Sq} 123 1+" \word{;} \word{IMMEDIATE} \\
\word{:} GE3 \word{Sq} \word{:} GE4 345 \word{;}" \word{;} \\
\word{:} GE5 \word{EVALUATE} \word{;} \word{IMMEDIATE}

\{ GE1 \word{EVALUATE} -> 123 \} \tab[3] \word{p} TEST EVALUATE IN INTERP. STATE ) \\
\{ GE2 \word{EVALUATE} -> 124 \} \\
\{ GE3 \word{EVALUATE} ->     \} \\
\{ GE4                 -> 345 \}

\{ \word{:} GE6 GE1 GE5 \word{;} -> \} \tab[3.4] \word{p} TEST EVALUATE IN COMPILE STATE ) \\
\{ GE6 -> 123 \} \\
\{ \word{:} GE7 GE2 GE5 \word{;} -> \} \\
\{ GE7 -> 124 \} \\
\end{tt}

\subsection{Parser Input Source Control}

\begin{tt}
TESTING \word{SOURCE} \word{toIN} \word{WORD}

\word{:} GS1 \word{Sq} \word{SOURCE}" \word{2DUP} \word{EVALUATE} \\
\tab \word{toR} \word{SWAP} \word{toR} \word{=} \word{Rfrom} \word{Rfrom} \word{=} \word{;} \\
\{ GS1 -> <TRUE> <TRUE> \}

\word{VARIABLE} SCANS \\
\word{:} RESCAN?  -1 SCANS \word{+!} SCANS \word{@} \word{IF} 0 \word{toIN} \word{!} \word{THEN} \word{;}

\{ 2 SCANS \word{!} \\
345 RESCAN? \\
-> 345 345 \}

\word{:} GS2  5 SCANS \word{!} \word{Sq} 123 RESCAN?" \word{EVALUATE} \word{;} \\
\{ GS2 -> 123 123 123 123 123 \}

\word{:} GS3 \word{WORD} \word{COUNT} \word{SWAP} \word{C@} \word{;} \\
\{ \word{BL} GS3 HELLO -> 5 \word{CHAR} H \} \\
\{ \word{CHAR} " GS3 GOODBYE" -> 7 \word{CHAR} G \} \\
\{ BL GS3 \\
\word{DROP} -> 0 \} \tab[4] \word{bs} BLANK LINE RETURN ZERO-LENGTH STRING

\word{:} GS4 \word{SOURCE} \word{toIN} \word{!} \word{DROP} \word{;} \\
\{ GS4 123 456 \\
-> \}
\end{tt}

\subsection{Number Patterns}

\begin{tt}
TESTING \word{num-start} \word{num} \word{numS} \word{num-end} HOLD SIGN \word{BASE} \word{toNUMBER} \word{HEX} \word{DECIMAL}

\word{:} S=  \word{bs} ( ADDR1 C1 ADDR2 C2 -{}- T/F ) COMPARE TWO STRINGS. \\
\tab	\word{toR} \word{SWAP} \word{R@} \word{=} \word{IF}	\tab[4.9] \word{bs} MAKE SURE STRINGS HAVE SAME LENGTH \\
\tab[2]   \word{Rfrom} \word{qDUP} \word{IF}				\tab[6] \word{bs} IF NON-EMPTY STRINGS \\
\tab[3]     0 \word{DO} \\
\tab[4]       \word{OVER} \word{C@} \word{OVER} \word{C@} \word{-}
				\word{IF} \word{2DROP} <FALSE> \word{UNLOOP} \word{EXIT} \word{THEN} \\
\tab[4]       \word{SWAP} \word{CHAR+} \word{SWAP} \word{CHAR+} \\
\tab[3]     \word{LOOP} \\
\tab[2]   \word{THEN} \\
\tab[2]   \word{2DROP} <TRUE>								\tab[5.2] \word{bs} IF WE GET HERE, STRINGS MATCH \\
\tab    \word{ELSE} \\
\tab[2]   \word{Rfrom} \word{DROP} \word{2DROP} <FALSE>		\tab \word{bs} LENGTHS MISMATCH \\
\tab    \word{THEN} \word{;}

\word{:} GP1  \word{num-start} 41 \word{HOLD} 42 \word{HOLD} 0 0 \word{num-end} \word{Sq} BA" S= \word{;} \\
\{ GP1 -> <TRUE> \}

\word{:} GP2  \word{num-start} -1 \word{SIGN} 0 \word{SIGN} -1 \word{SIGN} 0 0 \word{num-end} \word{Sq} -{}-" S= \word{;} \\
\{ GP2 -> <TRUE> \}

\word{:} GP3  \word{num-start} 1 0 \word{num} \word{num} \word{num-end} \word{Sq} 01" S= \word{;} \\
\{ GP3 -> <TRUE> \}

24 \word{CONSTANT} MAX-BASE							\tab[6.2] \word{bs} BASE 2 {\ldots} 36 \\
\word{:} COUNT-BITS \\
\tab 0 0 \word{INVERT}
	\word{BEGIN} \word{DUP} \word{WHILE} \word{toR} \word{1+} \word{Rfrom} \word{2*} \word{REPEAT}
	\word{DROP} \word{;} \\
COUNT-BITS \word{2*} \word{CONSTANT} \#BITS-UD		\tab \word{bs} NUMBER OF BITS IN UD \\

\word{:} GP4  \word{num-start} 1 0 \word{numS} \word{num-end} \word{Sq} 1" S= \word{;} \\
\{ GP4 -> <TRUE> \}

\word{:} GP5 \\
\tab \word{BASE} \word{@} <TRUE> \\
\tab MAX-BASE \word{1+} 2 \word{DO}		\tab[2] \word{bs} FOR EACH POSSIBLE BASE \\
\tab[2] \word{I} \word{BASE} \word{!}	\tab[4.7] \word{bs} TBD: ASSUMES BASE WORKS \\
\tab[3] \word{I} 0 \word{num-start} \word{numS} \word{num-end} \word{Sq} 10" S= \word{AND} \\
\tab    \word{LOOP} \\
\tab    \word{SWAP} \word{BASE} \word{!} \word{;} \\
\{ GP5 -> <TRUE> \}

\word{:} GP6 \\
\tab	\word{BASE} \word{@} \word{toR}  2 \word{BASE} \word{!} \\
\tab	MAX-UINT MAX-UINT \word{num-start} \word{numS} \word{num-end}	\tab[2]	  \word{bs} MAXIMUM UD TO BINARY \\
\tab	\word{Rfrom} \word{BASE} \word{!}								\tab[10.9] \word{bs} S: C-ADDR U \\
\tab	\word{DUP} \#BITS-UD \word{=} \word{SWAP} \\
\tab	0 \word{DO}														\tab[13.4]  \word{bs} S: C-ADDR FLAG \\
\tab[2]		\word{OVER} \word{C@} \word{[CHAR]} 1 \word{=} \word{AND}	\tab[2.5] \word{bs} ALL ONES \\
\tab[2]		\word{toR} \word{CHAR+} \word{Rfrom} \\
\tab	\word{LOOP} \word{SWAP} \word{DROP} \word{;} \\
\{ GP6 -> <TRUE> \}

\word{:} GP7 \\
\tab	\word{BASE} \word{@} \word{toR}		MAX-BASE \word{BASE} \word{!} \\
\tab	<TRUE> \\
\tab	A 0 \word{DO} \\
\tab[2]		\word{I} 0 \word{num-start} \word{numS} \word{num-end} \\
\tab[2]		1 \word{=} \word{SWAP} \word{C@} \word{I} 30 \word{+} \word{=} \word{AND} \word{AND} \\
\tab	\word{LOOP} \\
\tab	MAX-BASE A \word{DO} \\
\tab[2]		\word{I} 0 \word{num-start} \word{numS} \word{num-end} \\
\tab[2]		1 \word{=} \word{SWAP} \word{C@} 41 \word{I} A \word{-} \word{+} \word{=} \word{AND} \word{AND} \\
\tab	\word{LOOP} \\
\tab	\word{Rfrom} \word{BASE} \word{!} \word{;} \\
\{ GP7 -> <TRUE> \}

\word{bs} \word{toNUMBER} TESTS \\

\word{CREATE} GN-BUF 0 \word{C,} \\
\word{:} GN-STRING	 GN-BUF 1 \word{;} \\
\word{:} GN-CONSUMED GN-BUF \word{CHAR+} 0 \word{;} \\
\word{:} GN'		 \word{[CHAR]} ' \word{WORD} \word{CHAR+} \word{C@} GN-BUF \word{C!}  GN-STRING \word{;}

\{ 0 0 GN' 0' \word{toNUMBER} ->         0 0 GN-CONSUMED \} \\
\{ 0 0 GN' 1' \word{toNUMBER} ->         1 0 GN-CONSUMED \} \\
\{ 1 0 GN' 1' \word{toNUMBER} -> BASE @ 1+ 0 GN-CONSUMED \} \\
\{ 0 0 GN' -' \word{toNUMBER} ->         0 0 GN-STRING   \} \tab \word{bs} SHOULD FAIL TO CONVERT THESE \\
\{ 0 0 GN' +' \word{toNUMBER} ->         0 0 GN-STRING   \} \\
\{ 0 0 GN' .' \word{toNUMBER} ->         0 0 GN-STRING   \}

\word{:} >NUMBER-BASED \\
\tab \word{BASE} \word{@} \word{toR} \word{BASE} \word{!} \word{toNUMBER} \word{Rfrom} \word{BASE} \word{!} \word{;}

\{ 0 0 GN' 2'       10 >NUMBER-BASED ->  2 0 GN-CONSUMED \} \\
\{ 0 0 GN' 2'        2 >NUMBER-BASED ->  0 0 GN-STRING   \} \\
\{ 0 0 GN' F'       10 >NUMBER-BASED ->  F 0 GN-CONSUMED \} \\
\{ 0 0 GN' G'       10 >NUMBER-BASED ->  0 0 GN-STRING   \} \\
\{ 0 0 GN' G' MAX-BASE >NUMBER-BASED -> 10 0 GN-CONSUMED \} \\
\{ 0 0 GN' Z' MAX-BASE >NUMBER-BASED -> 23 0 GN-CONSUMED \}

\word{:} GN1 \word{bs} ( UD BASE -{}- UD' LEN ) UD SHOULD EQUAL UD' AND LEN SHOULD BE ZERO. \\
\tab	\word{BASE} \word{@} \word{toR} \word{BASE} \word{!} \\
\tab	\word{num-start} \word{numS} \word{num-end} \\
\tab	0 0 \word{2SWAP} \word{toNUMBER} \word{SWAP} \word{DROP} \tab \word{bs} RETURN LENGTH ONLY \\
\tab	\word{Rfrom} \word{BASE} \word{!} \word{;}

\{        0   0        2 GN1 ->        0   0 0 \} \\
\{ MAX-UINT   0        2 GN1 -> MAX-UINT   0 0 \} \\
\{ MAX-UINT DUP        2 GN1 -> MAX-UINT DUP 0 \} \\
\{        0   0 MAX-BASE GN1 ->        0   0 0 \} \\
\{ MAX-UINT   0 MAX-BASE GN1 -> MAX-UINT   0 0 \} \\
\{ MAX-UINT DUP MAX-BASE GN1 -> MAX-UINT DUP 0 \}

\word{:} GN2	\word{bs} ( -{}- 16 10 ) \\
\tab \word{BASE} \word{@} \word{toR}
	\word{HEX} \word{BASE} \word{@}
	\word{DECIMAL} \word{BASE} \word{@}
	\word{Rfrom} \word{BASE} \word{!} \word{;} \\
\{ GN2 -> 10 A \}
\end{tt}

\subsection{Memory Movement}

\begin{tt}
TESTING \word{FILL} \word{MOVE}

\word{CREATE} FBUF 00 \word{C,} 00 \word{C,} 00 \word{C,} \\
\word{CREATE} SBUF 12 \word{C,} 34 \word{C,} 56 \word{C,} \\
\word{:} SEEBUF FBUF \word{C@}  FBUF \word{CHAR+} \word{C@}  FBUF \word{CHAR+} \word{CHAR+} \word{C@} \word{;}

\{ FBUF 0 20 \word{FILL} -> \} \\
\{ SEEBUF -> 00 00 00 \}

\{ FBUF 1 20 \word{FILL} -> \} \\
\{ SEEBUF -> 20 00 00 \}

\{ FBUF 3 20 \word{FILL} -> \} \\
\{ SEEBUF -> 20 20 20 \}

\{ FBUF FBUF 3 \word{CHARS} \word{MOVE} -> \} \tab[3] \word{bs} BIZARRE SPECIAL CASE \\
\{ SEEBUF -> 20 20 20 \}

\{ SBUF FBUF 0 \word{CHARS} \word{MOVE} -> \} \\
\{ SEEBUF -> 20 20 20 \}

\{ SBUF FBUF 1 \word{CHARS} \word{MOVE} -> \} \\
\{ SEEBUF -> 12 20 20 \}

\{ SBUF FBUF 3 \word{CHARS} \word{MOVE} -> \} \\
\{ SEEBUF -> 12 34 56 \}

\{ FBUF FBUF \word{CHAR+} 2 \word{CHARS} \word{MOVE} -> \} \\
\{ SEEBUF -> 12 12 34 \}

\{ FBUF \word{CHAR+} FBUF 2 \word{CHARS} \word{MOVE} -> \} \\
\{ SEEBUF -> 12 34 34 \}
\end{tt}

\subsection{Output}

\begin{tt}
TESTING OUTPUT: \word{d} \word{.q} \word{CR} \word{EMIT} \word{SPACE} \word{SPACES} \word{TYPE} \word{Ud}

\word{:} OUTPUT-TEST \\[1ex]
\tab   \word{.q} YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" \word{CR} \\
\tab   41 \word{BL} \word{DO} \word{I} \word{EMIT} \word{LOOP} \word{CR} \\
\tab   61 41 \word{DO} \word{I} \word{EMIT} \word{LOOP} \word{CR} \\
\tab   7F 61 \word{DO} \word{I} \word{EMIT} \word{LOOP} \word{CR} \\[1ex]
\tab   \word{.q} YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" \word{CR} \\
\tab   9 \word{1+} 0 \word{DO} \word{I} \word{d} \word{LOOP} \word{CR} \\[1ex]
\tab   \word{.q} YOU SHOULD SEE 0-9 (WITH NO SPACES):" \word{CR} \\
\tab   \word{[CHAR]} 9 \word{1+} \word{[CHAR]} 0
	\word{DO} \word{I} 0 \word{SPACES} \word{EMIT} \word{LOOP} \word{CR} \\[1ex]
\tab   \word{.q} YOU SHOULD SEE A-G SEPARATED BY A SPACE:" \word{CR} \\
\tab   \word{[CHAR]} G \word{1+} \word{[CHAR]} A
	\word{DO} \word{I} \word{EMIT} \word{SPACE} \word{LOOP} \word{CR} \\[1ex]
\tab   \word{.q} YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" \word{CR} \\
\tab   5 \word{1+} 0
	\word{DO} \word{I} \word{[CHAR]} 0 \word{+} \word{EMIT} 2 \word{SPACES} \word{LOOP} \word{CR} \\[1ex]
\tab   \word{.q} YOU SHOULD SEE TWO SEPARATE LINES:" \word{CR} \\
\tab   \word{Sq} LINE 1" \word{TYPE} \word{CR} \word{Sq} LINE 2" \word{TYPE} \word{CR} \\[1ex]
\tab   \word{.q} {\small YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:}" \word{CR} \\
\tab   \word{.q} ~~SIGNED: " MIN-INT \word{d} MAX-INT \word{d} \word{CR} \\
\tab   \word{.q} UNSIGNED: " 0 \word{Ud} MAX-UINT \word{Ud} \word{CR} \\
\word{;}

\{ OUTPUT-TEST -> \}
\end{tt}

\subsection{Input}

\begin{tt}
TESTING INPUT: \word{ACCEPT}

\word{CREATE} ABUF 80 \word{CHARS} \word{ALLOT}

\word{:} ACCEPT-TEST \\
\tab \word{CR} \word{.q} PLEASE TYPE UP TO 80 CHARACTERS:" \word{CR} \\
\tab ABUF 80 \word{ACCEPT} \\
\tab \word{CR} \word{.q} RECEIVED: " \word{[CHAR]} " \word{EMIT} \\
\tab ABUF \word{SWAP} \word{TYPE} \word{[CHAR]} " \word{EMIT} \word{CR} \\
\word{;}

\{ ACCEPT-TEST -> \}
\end{tt}

\subsection{Dictionary Search Rules}

\begin{tt}
TESTING DICTIONARY SEARCH RULES

\{ \word{:} GDX   123 \word{;} \tab \word{:} GDX   GDX 234 \word{;} -> \} \\
\{ GDX -> 123 234 \}
\end{tt}
