\chapter{The optional String word set} % 17
\wordlist{string}

\section{Introduction} % 17.1

\section{Additional terms and notation} % 17.2

None.

\section{Additional usage requirements} % 17.3

Append table \ref{string:env} to table \ref{table:env}.

See: \xref[3.2.6 Environmental queries]{usage:env}.

\begin{table}[ht]
  \begin{center}
	\caption{Environmental Query Strings}
	\label{string:env}
	\begin{tabular}{p{9em}rcp{0.42\textwidth}}
		\hline\hline
		\multicolumn{2}{l}{String \hfill Value data type} & Constant? & Meaning \\
		\hline
		\texttt{STRING}		& \emph{flag}	& no	&
			string word set present \\
		\texttt{STRING-EXT}	& \emph{flag}	& no	&
			string extensions word set present \\
		\hline\hline
	\end{tabular}
  \end{center}
\end{table}

\section{Additional documentation requirements} % 17.4

None.

\section{Compliance and labeling} % 17.5

\subsection{Compliance and labeling} % 17.5.1

The phrase ``Providing the String word set'' shall be appended to
the label of any Standard System that provides all of the String
word set.

The phrase ``Providing \emph{name(s)} from the String Extensions
word set'' shall be appended to the label of any Standard System
that provides portions of the String Extensions word set.

The phrase ``Providing the String Extensions word set'' shall be
appended to the label of any Standard System that provides all of
the String and String Extensions word sets.

\subsection{ANS Forth programs} % 17.5.2

The phrase ``Requiring the String word set'' shall be appended to
the label of Standard Programs that require the system to provide
the String word set.

The phrase ``Requiring \emph{name(s)} from the String Extensions
word set'' shall be appended to the label of Standard Programs that
require the system to provide portions of the String Extensions
word set.

The phrase ``Requiring the String Extensions word set'' shall be
appended to the label of Standard Programs that require the system
to provide all of the String and String Extensions word sets.


\section{Glossary} % 17.6

\subsection{String words} % 17.6.1


\begin{worddef}{0170}{-TRAILING}[dash-trailing]
\item \stack{c-addr u_1}{c-addr u_2}

	If \param{u_1} is greater than zero, \param{u_2} is equal to
	\param{u_1} less the number of spaces at the end of the
	character string specified by \param{c-addr u_1}. If \param{u_1}
	is zero or the entire string consists of spaces, \param{u_2} is
	zero.

	\begin{testing}
		\test{\word{:}  s8 \word{Sq} abc  " \word{;}}{} \\
		\test{\word{:}  s9 \word{Sq}      " \word{;}}{} \\
		\test{\word{:} s10 \word{Sq}    a " \word{;}}{}

		\test{ s1 \word{-TRAILING}}{s1}		\tab \word{bs} ``\texttt{abcdefghijklmnopqrstuvwxyz}'' \\
		\test{ s8 \word{-TRAILING}}{s8 2 -} 			\tab[2.5] \word{bs} ``\texttt{abc~~}'' \\
		\test{ s7 \word{-TRAILING}}{s7}					\tab[5.2] \word{bs} ``\texttt{~}'' \\
		\test{ s9 \word{-TRAILING}}{s9 \word{DROP} 0}	\tab[1] \word{bs} ``\texttt{~~~~~}'' \\
		\test{s10 \word{-TRAILING}}{s10 1-}				\tab[2.8] \word{bs} ``\texttt{~~~a~}''
	\end{testing}
\end{worddef}


\begin{worddef}{0245}{/STRING}[slash-string]
\item \stack{c-addr_1 u_1 n}{c-addr_2 u_2}

	Adjust the character string at \param{c-addr_1} by \param{n}
	characters. The resulting character string, specified by
	\param{c-addr_2 u_2}, begins at \param{c-addr_1} plus \param{n}
	characters and is \param{u_1} minus \param{n} characters long.

\see \place{ed09b}{\rref{string:/STRING}{}.}

	\begin{rationale} % A.17.6.1.0245 /STRING
		\word{/STRING} is used to remove or add characters relative
		to the ``left'' end of the character string. Positive values
		of \param{n} will exclude characters from the string while
		negative values of \param{n} will include characters to the
		left of the string. \word{/STRING} is a natural factor of
		\word[core]{WORD} and commonly available.
	\end{rationale}

	\begin{testing}
		\test{s1  5 \word{/STRING}}{s1 \word{SWAP} 5 \word{+} \word{SWAP} 5 \word{-}} \\
		\test{s1 10 \word{/STRING} -4 \word{/STRING}}{s1 6 \word{/STRING}} \\
		\test{s1  0 \word{/STRING}}{s1}
	\end{testing}
\end{worddef}


\begin{worddef}{0780}{BLANK}
\item \stack{c-addr u}{}

	If \param{u} is greater than zero, store the character value for
	space in \param{u} consecutive character positions beginning at
	\param{c-addr}.

	\begin{testing} \ttfamily
		\word{:} s13 \word{Sq} aaaaa~~~~~~a" \word{;}						\tab[4.5] \word{bs} \textdf{Six spaces}

		\test{\word{PAD} 25 \word{CHAR} a \word{FILL}}{}					\tab[2.8] \word{bs} \textdf{Fill PAD with 25 'a's} \\
		\test{\word{PAD} 5 \word{CHARS} \word{+} 6 \word{BLANK}}{}	\tab[1] \word{bs} \textdf{Put 6 spaced from character 5} \\
		\test{\word{PAD} 12 s13 \word{COMPARE}}{0}							\tab[2.2] \word{bs} \textdf{PAD Should now be same as s13}
	\end{testing}
\end{worddef}


\begin{worddef}{0910}{CMOVE}[c-move]
\item \stack{c-addr_1 c-addr_2 u}{}

	If \param{u} is greater than zero, copy \param{u} consecutive
	characters from the data space starting at \param{c-addr_1} to
	that starting at \param{c-addr_2}, proceeding character-by-character
	from lower addresses to higher addresses.

\item[\sout{Contrast with}]
	\remove{ed09b}{\wref{string:CMOVEtop}{CMOVE>}.}

\see \place{ed09b}{\wref{string:CMOVEtop}{}, \rref{string:CMOVE}{}.}

	\begin{rationale} % A.17.6.1.0910 CMOVE
		If \param{c-addr_2} lies within the source region (i.e., when
		\param{c-addr_2} is not less than \param{c-addr_1} and
		\param{c-addr_2} is less than the quantity \param{c-addr_1 u}
		\word[core]{CHARS} \word[core]{+}), memory propagation occurs.

		Typical use: Assume a character string at address
		100: ``ABCD''. Then after
		\begin{quote}\ttfamily
			100 \word[core]{DUP} ~ \word[core]{CHAR+} ~ 3 \word{CMOVE}
		\end{quote}
		the string at address 100 is ``AAAA''.

		Rationale for \word{CMOVE} and \word{CMOVEtop} follows
		\word[core]{MOVE}.
	\end{rationale}
\end{worddef}


\begin{worddef}[CMOVEtop]{0920}{CMOVE>}[c-move-up]
\item \stack{c-addr_1 c-addr_2 u}{}

	If \param{u} is greater than zero, copy \param{u} consecutive
	characters from the data space starting at \param{c-addr_1} to
	that starting at \param{c-addr_2}, proceeding character-by-character
	from higher addresses to lower addresses.

\item[\sout{Contrast with:}]
	\remove{ed09b}{\wref{string:CMOVE}{CMOVE}.}

\see \place{ed09b}{\wref{string:CMOVE}{}, \rref{string:CMOVEtop}{}.}

	\begin{rationale} % A.17.6.1.0920 CMOVE>
		If \param{c-addr_1} lies within the destination region (i.e.,
		when \param{c-addr_1} is greater than or equal to
		\param{c-addr_2} and \param{c-addr_2} is less than the
		quantity \param{c-addr_1 u} \word[core]{CHARS}
		\word[core]{+}), memory propagation	occurs.

		Typical use: Assume a character string at address
		100: ``ABCD''. Then after
		\begin{quote}\ttfamily
			100 \word[core]{DUP} \word[core]{CHAR+} \word[core]{SWAP}
			3 \word{CMOVEtop}
		\end{quote}
		the string at address 100 is ``DDDD''.
	\end{rationale}
\end{worddef}


\begin{worddef}{0935}{COMPARE}
\item \stack{c-addr_1 u_1 c-addr_2 u_2}{n}

	Compare the string specified by \param{c-addr_1 u_1} to the
	string specified by \param{c-addr_2 u_2}. The strings are
	compared, beginning at the given addresses, character by
	character, up to the length of the shorter string or until a
	difference is found. If the two strings are identical, \param{n}
	is zero. If the two strings are identical up to the length of
	the shorter string, \param{n} is minus-one (-1) if \param{u_1}
	is less than \param{u_2} and one (1) otherwise. If the two
	strings are not identical up to the length of the shorter string,
	\param{n} is minus-one (-1) if the first non-matching character
	in the string specified by \param{c-addr_1 u_1} has a lesser
	numeric value than the corresponding character in the string
	specified by \param{c-addr_2 u_2} and one (1) otherwise.

\see \place{ed09b}{\rref{string:COMPARE}{}.}

	\begin{rationale} % A.17.6.1.0935 COMPARE
		Existing Forth systems perform string comparison operations
		using words that differ in spelling, input and output
		arguments, and case sensitivity. One in widespread use
		was chosen.
	\end{rationale}

	\begin{testing}\ttfamily
		\test{s1        s1 \word{COMPARE}}{ 0 } \\
		\test{s1  PAD SWAP \word{CMOVE}  }{   } \tab \word{bs} \textdf{Copy s1 to PAD} \\
		\test{s1  PAD OVER \word{COMPARE}}{ 0 } \\
		\test{s1     PAD 6 \word{COMPARE}}{ 1 } \\
		\test{PAD 10    s1 \word{COMPARE}}{-1 } \\
		\test{s1     PAD 0 \word{COMPARE}}{ 1 } \\
		\test{PAD  0    s1 \word{COMPARE}}{-1 } \\
		\test{s1        s6 \word{COMPARE}}{ 1 } \\
		\test{s6        s1 \word{COMPARE}}{-1 }

		\word{:} "abdde"~ \word{Sq} abdde"~ \word{;} \\
		\word{:} "abbde"~ \word{Sq} abbde"~ \word{;} \\
		\word{:} "abcdf"~ \word{Sq} abcdf"~ \word{;} \\
		\word{:} "abcdee" \word{Sq} abcdee" \word{;}

		\test{s1 "abdde"  \word{COMPARE}}{-1} \\
		\test{s1 "abbde"  \word{COMPARE}}{ 1} \\
		\test{s1 "abcdf"  \word{COMPARE}}{-1} \\
		\test{s1 "abcdee" \word{COMPARE}}{ 1}

		\word{:} s11 \word{Sq} 0abc" \word{;} \\
		\word{:} s12 \word{Sq} 0aBc" \word{;}

		\test{s11 s12 \word{COMPARE}}{ 1} \\
		\test{s12 s11 \word{COMPARE}}{-1}
	\end{testing}
\end{worddef}


\begin{worddef}{2191}{SEARCH}
\item \stack{c-addr_1 u_1 c-addr_2 u_2}{c-addr_3 u_3 flag}

	Search the string specified by \param{c-addr_1 u_1} for the
	string specified by \param{c-addr_2 u_2}. If \param{flag} is
	true, a match was found at \param{c-addr_3} with \param{u_3}
	characters remaining. If \param{flag} is false there was no
	match and \param{c-addr_3} is \param{c-addr_1} and \param{u_3}
	is \param{u_1}.

\see \place{ed09b}{\rref{string:SEARCH}{}.}

	\begin{rationale} % A.17.6.1.2191 SEARCH
		Existing Forth systems perform string searching operations
		using words that differ in spelling, input and output
		arguments, and case sensitivity. One in widespread use was
		chosen.
	\end{rationale}

	\begin{testing}
		\test{\word{:} s2 \word{Sq} abc"   \word{;}}{} \\
		\test{\word{:} s3 \word{Sq} jklmn" \word{;}}{} \\
		\test{\word{:} s4 \word{Sq} z"     \word{;}}{} \\
		\test{\word{:} s5 \word{Sq} mnoq"  \word{;}}{} \\
		\test{\word{:} s6 \word{Sq} 12345" \word{;}}{} \\
		\test{\word{:} s7 \word{Sq} "      \word{;}}{}

		\test{s1 s2 \word{SEARCH}}{s1 <TRUE> } \\
		\test{s1 s3 \word{SEARCH}}{s1  9 \word{/STRING} <TRUE> } \\
		\test{s1 s4 \word{SEARCH}}{s1 25 \word{/STRING} <TRUE> } \\
		\test{s1 s5 \word{SEARCH}}{s1 <FALSE>} \\
		\test{s1 s6 \word{SEARCH}}{s1 <FALSE>} \\
		\test{s1 s7 \word{SEARCH}}{s1 <TRUE> } 
	\end{testing}
\end{worddef}


\begin{worddef}{2212}{SLITERAL}
\interpret
	Interpretation semantics for this word are undefined.

\compile
	\stack{c-addr_1 u}{}

	Append the run-time semantics given below to the current
	definition.

\runtime
	\stack{}{c-addr_2 u}

	Return \param{c-addr_2 u} describing a string consisting of
	the characters specified by \param{c-addr_1 u} during
	compilation. A program shall not alter the returned string.

\see \place{ed09b}{\rref{string:SLITERAL}{}.}

	\begin{rationale} % A.17.6.1.2212 SLITERAL
		The current functionality of \wref{core:Sq}{S"} may be
		provided by the following definition:
		\setwordlist{core}
		\begin{quote}\ttfamily
			\word{:} \word{Sq} \word{p} "ccc<quote>" -{}- ) \\
			\tab \word{[CHAR]} " \word{PARSE} ~
				\word{POSTPONE} \word[string]{SLITERAL} \\
			\word{;} \word{IMMEDIATE}
		\end{quote}
		\setwordlist{string}
	\end{rationale}

	\begin{testing}
		\test{\word{:} s14 \word{[} s1 \word{]} \word{SLITERAL} \word{;}}{} \\
		\test{s1 s14 \word{COMPARE}}{0} \\
		\test{s1 s14 \word{ROT} \word{=} \word{ROT} \word{ROT} \word{=}}{<TRUE> <FALSE>}
	\end{testing}
\end{worddef}


\subsection{String extension words} % 17.6.2

None.
