Abridged Glossary of Kernel Words			94-08-28
=================================

See the Standard for the complete semantics of ANS words.  The behaviors 
given here are reminders only.

The high-level and low-level Forth definitions are possibilities only.
The actual definitions may vary.

Just the execution behavior is given for control-flow words.

!	( x a-addr -- )
	Take x and put it into the cell at a-addr.
	
	Execution(`!')   data(top) = *S--, pop;			Done
	
#	( u . -- u' . )
	Convert a digit in pictured numeric output conversion.
	
	: #         0 BASE @ UM/MOD >R BASE @ UM/MOD SWAP >char HOLD R> ;

#>	( u . -- string . )
	End pictured numeric output conversion.

	: #>        2DROP BASE 1 CHARS - DUP C@ DUP CHARS NEGATE under+ ;

#S	( u . -- 0 0 )

	: #S        BEGIN   #   2DUP OR 0= UNTIL ;

$	( "rest-of-the-line" -- )
	Pass rest-of-the-line to the system shell.

	: $         get-line eol stack-char system abort" Failed. " ;

'	( "<name>" -- xt )
	Return the execution token of <name>.

	: '         BL WORD FIND 0= ABORT" Can't find " ;

(	( "<text><paren>" -- )
	Ignore text through next `)'.

(.)	( n -- string . )
	Convert a number into a character string.

	: (.)       dup >r abs 0 <# #s r> sign #> ;

*	( multiplicand multiplier -- product )
	Multiple multiplicand by multiplier.
	
	Execution(`*') top *= *S--;				Done

*/	( factor multiplier divisor -- scaled-factor )
	Calculate factor times multiplier divided by divisor.

	: */MOD NIP ;

*/MOD	( factor multiplier divisor -- remainder scaled-factor )

+	( augend addend -- sum )
	Add addend to augend.
	
	Execution(`+') top += *S--;				Done

+!	( increment a-addr -- )
	Add increment to cell at a-addr.

	Execution(`+!') data(top) += *S--, pop;			Done

+LOOP ( increment -- )
	Add increment to loop-index, and then jump back to the matching
	DO (or ?DO), or terminate the loop.
	
,	( x -- )
	Append x to data space.

	: ,         ALIGN    HERE !    1 CELLS ALLOT ;

-	( minuend subtrahend -- difference )
	Subtract subtrahend from minuend.
	
	Execution(`-') top = *S-- - top;			Done

-->	( "<file-name><space> -- )
	Load elective "<electivepath><file-name>.fo".
	
	Note: `ELECTIVE' must be defined before `-->' can be used.

-TRAILING	( string . -- string . )

	: -TRAILING BEGIN DUP 0= ?? EXIT 1- 2DUP CHARS + C@ graph? UNTIL 1+ ;

.	( n -- )
	Display number and trailing space.
	
	: .	(.) TYPE   SPACE ;

."	( "<text><quote> -- )
	Display <text>.

	: ."        [CHAR] " PARSE PLEASE 'c" ~" count type ' ; IMMEDIATE 

	Note: Allowed in interpreting state.

.(	( "<text><paren> -- )
	Immediate: Display <text>

..	( xN ... x1 -- )
	Display stack and clear it.
	
	: ..        .S    begin depth while drop repeat ;
	
.0r	( n w -- )
	Display n right justified in field w wide with leading zeroes.
	
	: .0r       >r (.) r> over - 0 max 0 ?do ." 0" loop type ;

.R	( n w -- )
	Display n right justified in field w wide with leading spaces.
	
	: .R        >R (.) R> OVER - SPACES TYPE ;
	
.S	( xN ... x1 -- same )
	Display stack.
	
	: .S        DEPTH  BEGIN  ?DUP WHILE  DUP PICK x.  1-  REPEAT ;

/	( dividend divisor -- quotient )
	Divide dividend by divisor.
	
	Execution(`/')    top = top ? *S-- / top : (S--, 0) ; Done

/MOD	( dividend divisor -- remainder quotient )

	Execution(`/MOD')
    		if (top != 0)
        		w = *S / top, *S -= w * top, top = w;
	Done

/STRING	( a b c -- a+c*chars b-c )

	: /STRING   DUP  NEGATE under+  CHARS under+ ;

0x	( "<word>" -- n )

	: 0x        ~please "hex ~ decimal " ; immediate

2!	( x . a-addr -- )

	Store x . in double cell at a-addr.
	
	: 2!        SWAP OVER ! CELL+ ! ;

2/	( n -- n' )
	Arithmetic right shift.
	
	Execution(`2/')     top = (signed long) top >> 1;   Done

2>R	( x . -- ; R: -- x . )
	Move x . from data stack onto return stack.
	
	: 2>R       SWAP >R >R ; inline

2@	( a-addr -- x . )
	Copy x . from double cell at a-addr onto data stack.
	
	: 2@        DUP CELL+ @ SWAP @ ;
	
2DROP	( a b -- )
	Discard the two top stack elements.
	
	Execution(`2DROP')  S--, pop;                               Done

2DUP	( a b -- a b a b )
	Copy the top pair of stack elements onto data stack.

	Execution(`2DUP')   w = *S, *++S = top, *++S = w;           Done

2OVER	( a b c d -- a b c d a b )
	Copy the next-to-top pair of stack elements onto data stack.
	
	Execution(`2OVER')  push S[-2], w = S[-3], *++S = w;        Done

2R>	( -- x . ; R: x . -- same )
	Move x . from return stack onto data stack.
	
	: 2R>       R> R> SWAP ; inline

2R@	( -- x . ; R: x . -- same )
	Copy x . from return stack onto data stack.

	: 2R@       R> R@ SWAP DUP >R ; inline

2ROT	( a b c d e f -- c d e f a b )
	Move second-next-to-top pair of stack elements onto top of data stack.
	
	: 2rot      5 roll 5 roll ;

2SWAP	( a b c d -- c d a b )
	Interchange top two pairs of stack elements.
	
	Execution(`2SWAP')  
	    w = S[-1], S[-1] = top, top = w;
	    w = S[-2], S[-2] = *S, *S = w;
	Done

3drop	( a b c -- )
	Discard the top three stack elements.
	
	: 3drop     2drop drop ; inline

3dup	( a b c -- a b c a b c )
	Copy the top three stack elements onto the top of data stack.
	
	: 3dup      2 pick 2 pick 2 pick ;

4drop	( a b c d -- )
	Discard the top four stack elements.
	
	: 4drop     2drop 2drop ; inline

4dup	( a b c d -- a b c d a b c d )
	Copy the top four stack elements onto the top of data stack.
	
	: 4dup      2over 2over ; inline

:	( "<spaces><name>" -- )
	Begin a colon definition.
	
:NONAME	( -- xt )
	Begin a nameless definition.

;	( -- )
	End a definition.

end-of-file	( -- )
	Close current source file.
	
	: END-OF-FILE	SOURCE-ID unstream closed ;

<	( this that -- flag )
	Compare this less than that.
	
	Execution(`<') op = *S-- < top LOGICAL;       Done

<#	( -- )
	Start pictured numeric output conversion.
	
	: <#        0 BASE 1 CHARS - C! ;

<=	( this that -- flag )
	Compare this less-or-equal that.
	
	: <= please "> 0= " ; immediate

<>	( this that -- flag )
	Compare this unequal to that.
	
	: <> please "0= 0= " ; immediate

=	( this that -- flag )
	Compare this equal to that.
	
	Execution(`=') top = *S-- == top LOGICAL;      Done

>=	( this that -- flag )
	Compare this greater-or-equal that.

	: >= please "< 0= " ; immediate

>BODY	( xt -- a-addr )
	Convert execution token to data field address.

>char	( n -- char )
	Convert number to character.

	: >char   dup 10 < not if 10 - [char] A + [char] 0 - then [char] 0 + ;
	          --- ---- ------ --------------------------      ----------

>digit	( char -- n )
	Convert character to digit.
	
>IN	( -- a-addr )

	: >IN SOURCE NIP [here] ! [here] ; 0 ,

	Note: Not applicable in This Forth.

>NUMBER	( n . string . -- n' . string' . )
	Convert string to a number and then add it to n . .

>R	( x -- ; R: -- x )
	Move top stack element onto return stack.
	
	Execution(`>R')    *++R = top, pop;			Done

>upper	( char -- CHAR )
	Convert character to uppercase.
	
	: >UPPER    dup  [char] a -  26 U< if   [char] a - [char] A +   then ;
	            ---  ----------  ----- --   ---------------------

?	( a-addr -- )
	Display number at address a-addr.
	
	: ? @ . ;

??	Macro: `?? word' becomes `IF word THEN'.

	: ??        ~please "if ~ then " ; immediate

?DO	( limit initial -- )
	Like DO but don't execute loop if limit is equal to initial.

	Note: ?DO is self-compiling.
	
?DUP	( x -- x x | 0 )
	If top stack element is not false, copy it onto top of stack.

	Execution(`?DUP')   if (top) *++S = top ;               Done

@	( a-addr -- x )
	Copy contents of cell at a-addr onto stack.
	
	Execution(`@')    top = data(top);            		Done

[	( -- )
	Immediate: Enter interpreting state.
	
	Immediate(`[')	state = FALSE;				Done

[']	( "<spaces><name>" -- xt )
	Get execution token of <name>.
	
	: [']       ~PLEASE "[ ' ~ ] LITERAL " ; IMMEDIATE

	Or:

	: [']       state @ if
	                    ~please "[ ' ~ ] LITERAL "
	            else ' then
	; IMMEDIATE	

[0x]	Macro: `[0x] word' becomes `[ HEX ] word [ DECIMAL ]'.

	: [0x]      ~please "[ hex ] ~ [ decimal ] " ; immediate

[CHAR]	( C: "<spaces><word>" -- ; -- char )
	First character of next word in input source.
	
	: [CHAR]    ~PLEASE "[ CHAR ~ ] LITERAL " ; IMMEDIATE

[COMPILE]	( "<name>" -- )
	Compile <name> at execution time.

	: [COMPILE] BL WORD FIND ?DUP 0= ABORT" CAN'T FIND "
	        0< IF COMPILE, ELSE POSTPONE LITERAL POSTPONE EXECUTE THEN
	; IMMEDIATE

[ctrl]	( C: "<char>" -- ; -- <char> )
	Control character.  Such as `[ctrl] J' or `[ctrl] j' for linefeed,
	`[ctrl] ?' for delete.
	
	: [CTRL]    char  >upper  64 -  127 and  postpone literal ; immediate

[exit]	( C: -- )
	Immediate: Exit from text interpreter.
	
[here]	( -- a-addr )
	Compile-time value of `HERE'.
	
	: [HERE]    please "[ align here ] literal " ; immediate

\	( "<rest-of-line>" -- )
	Immediate: Ignore the rest of the line.

]	( -- )
	Enter compiling state.
	
	Execution(`]') state = TRUE;			Done

ABORT	( -- )
	Clear data stack and return stack, and then restart.
	
ABORT"	( n "<text><quote>" -- )
	Take top of stack and if it is not false, display <text> and abort.
	
	: ABORT"    [CHAR] " PARSE PLEASE 'IF ." ~" ABORT THEN ' ; IMMEDIATE

ABS	( n -- n' )
	The magnitude of n.
	
	: ABS       DUP 0< ?? NEGATE ;

ACCEPT	( c-addr length -- count )
	Read a line from standard input.
	
AGAIN	( -- )
	Jump back to the balancing BEGIN.
	
	: AGAIN PLEASE "FALSE UNTIL " ; IMMEDIATE

ALIGN	( -- )
	Reserve data space to leave HERE a multiple of cell size.
	
	: ALIGN     HERE ALIGNED HERE - ALLOT ;

ALIGNED	( n -- n')
	Increase n as necessary to leave it a multiple of cell size.
	
	/* Assumes sizeof(cell) is a power of 2. */
	# define aligned(x) ((x) + (sizeof(cell) - 1) & ~(sizeof(cell) - 1))
	Execution(`ALIGNED') top = aligned(top);		Done

ALLOT	( n -- )
	Reserve n address units in data space.
	
	Execution(`ALLOT')      here += top, pop;         	Done

AND	( x y -- z )
	Bitwise `and' of x and y.
	
	Execution(`AND') top &= *S--;				Done

andif	Macro: `DUP IF DROP'

	: ANDIF     please "dup if drop " ; immediate
	
	Note: This is a short circuit.  With `ANDIF mumble THEN'
	`mumble' will not be evaluated if the top stack element
	was false.

argument	( -- string . )
	Next argument from the command line invocation.

BASE	( -- a-addr )
	Address of number conversion radix.
	
BEGIN	( -- )
	Begin a conditional or infinite loop.

	Note: BEGIN is self-compiling.
	
BL	( -- n )
	The value of the space character.
	
	GET-CHAR   CONSTANT BL

bounds	( a n -- a+n*chars a )
	Prepare arguments for DO or ?DO loop.
	
	: BOUNDS over + swap ;

BYE	( -- )
	Return to operating system.

	Execution(`BYE') exit(0);			Done

C!	( k c-addr -- )
	Put k as a character in character-sized storage at c-addr.
	
	Execution(`C!')     data[top] = *S--, pop;      Done

C"	( C: "<text><quote>" -- ; -- c-addr )
	Address of counted string.

c+!	( k c-addr -- )
	Add k as a character to character-sized storage at c-addr.
	
	: C+!	DUP C@ under+ C! ;

C,	( n -- )
	Append k as a character to data space.
	
	: C,	HERE C!   1 CHARS ALLOT ;

C@	( c-addr -- char )
	Copy character at c-addr onto data stack.

	Execution(`C@')     top = data[top];                    Done
	
CASE	( -- )
	Immediate: Mark control-flow stack.

	Note: This includes Standard behavior.
	
	Note: CASE is self-compiling.
	
CELL+	( n -- n' )
	Add cell size in address units.

	: CELL+     PLEASE "1 cells + " ; IMMEDIATE

CELLS	( n -- n' )
	Multiply by cell size in address units.
	
	Execution(`CELLS')    top *= sizeof(cell);		Done

CHAR	( -- char )
	Get first character of the next word.
	
	: CHAR      GET-WORD DROP C@ ;

CHAR+	( n -- n')
	Add character size in address units.

	: CHAR+     PLEASE "1 chars + " ; IMMEDIATE

CHARS	( n -- n')
	Multiply by character size in address units.
	
	: CHARS     PLEASE "" ; IMMEDIATE

closed	( file-id -- )
	Close file identified by file-id.

	: CLOSED    ?dup if FCLOSE abort" Can't close. " then ;

COMPARE	( string1 . string2 . -- -1|01 )
	Compare string1 with string2.
	
COMPILE,	( xt -- )
	Compile the behavior of the word given by xt.

CONSTANT	( n -- )
	Create named literal

copy	( file-id -- )
	Display text file identified by file-id.
	
	: COPY filter get-char emit unfilter ;

COUNT	( c-addr -- string . )
	Convert counted string to character string.
	
	Execution(`COUNT') *++S = top + 1; top = data[top]; Done

CR	( -- )
	Subsequent output goes to the next line.
	
	Execution(`CR')         emit(EOL);              Done

CREATE	( "<spaces><name>" -- )
	Create constant of aligned value of HERE.

	: CREATE    ALIGN    HERE CONSTANT ;

D+	( augend . addend . -- sum . )
	Add addend . to augend . .

D-	( minuend . subtrahend . -- difference . )
	Subtract subtrahend from minuend.

DABS	( n . -- n' . )
	Magnitude of n . .

	: DABS    DUP 0< ?? DNEGATE ;

DECIMAL	( -- )
	Set numeric conversion radix to ten.
	
	: DECIMAL 10 BASE ! ;

DEPTH	( -- k )
	Number of elements on data stack.

	Execution(`DEPTH')      push S - stack - 1;             Done

display	( file-id | 0 -- )
	Reassign file identity of output device.

	Execution(`DISPLAY')
		usrout = top ? (FILE *) top : stdout; pop;
	Done

DNEGATE	( n . -- n' . )
	Negative of n . .

	: DNEGATE 0. 2SWAP D- ;

DO	( limit initial -- )
	Begin a counted loop starting at initial.

	Note: DO is self-compiling.

DOES>	( -- )
	Change the behavior of the word just defined by `CREATE'.

	Note: In This Forth the word may be just defined by `CONSTANT'.

DROP	( x -- )
	Discard the top stack element.
	
	Execution(`DROP')   pop;   Done

DUP	( a -- a a )
	Copy the top stack element onto the top of the data stack.
	
	Execution(`DUP')    *++S = top;   Done

elective	( "name" -- string . )
	Convert name to the qualified name of the file in the
	elective directory.
	
	Note: Because different platforms have different syntax
	for directories, and users have different ideas about
	where to put stuff, this must be defined for each user
	specially.  For example, in Unix it might be:
	
	: ELECTIVE ~please 's" ../lib/~.fo" ' ; immediate

	See file `path'.
	
	Adapt this definition if you don't like `.fo' as a
	suffix for source files.

ELSE	( -- )
	Execution path when all tests so far have failed.
	
EMIT	( k -- )
	Display k as a character.

	# define emit(c)	putc(c, usrout)
	Execution(`EMIT')       emit(top); pop;         Done

empty	( -- )
	Restore data space, name space, code space, and word lists to what
	they had been.

	: EMPTY     C" ------" find if execute else drop then
                    s" marker ------" evaluate ;

end-of-file	( -- )
	Close current source file.
	
	: END-OF-FILE	SOURCE-ID unstream CLOSED ;

ENDCASE	( x -- )
	End multiple selection logical structure.
	
	: ENDCASE PLEASE "DROP ESAC " ; IMMEDIATE
	
ENDOF	( -- )
	Equivalent of ELSE used in a multiple selection logical structure.
	
	: ENDOF PLEASE "ELSE " ; IMMEDIATE

eof	( -- k )
	The `character' that is read at end of a file.
	
	-1 CONSTANT EOF

eol	( -- k )
	The character that is read at end of a line.
	
	GET-CHAR
	CONSTANT EOL

ERASE	( addr len -- )
	Set len address units beginning at addr to zero.
	
	When the character size is one address unit it can be defined
	: ERASE 0 FILL ;

error?	( -- n )
	Get Standard C library errno and clear it.

	Execution(`ERROR?') push errno, errno = 0; Done

ESAC	( -- )
	Resolve control-flow stack with THEN's back to CASE.

EVALUATE	( ... string . -- ??? )
	Interpret text from the string.

	: EVALUATE  WILL PLEASE "~" EXPOUND ;

EXECUTE	( ... xt -- ??? )
	Execute word given by execution token xt.
	
	Execution(`EXECUTE')    xt = top, pop; recurse; Done

EXIT	( -- ) 
	Unnest.
	
	Execution(`EXIT') I = *R--; Done

expound	( -- )
	The input source interpreter/compiler loop.

	Pseudo-definition:
	: EXPOUND   BEGIN get-word evaluate AGAIN ;

FALSE	( -- 0 )
	Canonical false

	0 CONSTANT FALSE

fclose	( file-id -- flag )
	Standard C library function.

fflush	( file-id | 0 -- flag )
	Standard C library function.

FILL	( c-addr len char -- )
	Set len characters beginning at c-addr to char.

	Execution(`FILL')   
		memset(data + S[-1], top, *S), S -= 2, pop;
	Done

filter	( file-id -- )
	Begin file filter.
	
	`FILTER' becomes
	
	STREAM
	BEGIN
		NEXT-CHAR EOF <>
	WHILE

FIND	( c-addr  -- c-addr 0 | xt -1|1|0 )
	Lookup word at c-addr.

flushed	( file-id | 0 -- )
	
	: FLUSHED   FFLUSH abort" Can't flush. " ;

FM/MOD	( dividend . divisor -- remainder quotient )
	Floored division.

fopen	( file-name . mode . -- file-id | 0 )
	Standard C library function.

fseek	( file-id offset whence -- 0 | -1 )
	Standard C library function.

ftell	( file-id -- offset | -1 )
	Standard C library function.

get-char	( -- char )
	Get and remove next character from input source.
	
	# define char()	(cp != cpp ? *--cp : getc(usrin))
	Execution(`GET-CHAR')   push char();   Done

get-line	( "rest-of-the-line" -- c-addr len )
	Parse to end of line.
	
	: GET-LINE EOL PARSE ;

get-word	( "<spaces><text>" -- c-addr len )
	Parse text delimited by white space.
	
	: GET-WORD BL WORD COUNT ;
	
	Note: Known in some systems as `PARSE-WORD'.

graph?	( char -- flag )
	Test for a visible character.
	
	: GRAPH?    BL 1+ -  94 u< ;

has	( n -- k )
	What location n in code space has.

	Execution(`HAS')     top = code[top]; Done

have	( "name" -- -1|1|0 )
	
	: HAVE      ~please 'c" ~" find nip ' ; immediate

HERE	( -- n )
	Next available location in data space.
	
	Execution(`HERE')       push here;		Done

HEX	( -- )
	Set numeric conversion radix to sixteen.

	: HEX 16 BASE ! ;

HOLD	( char -- )
	Insert char at beginning of pictured numeric output string.	
	
	: HOLD      1 BASE 1 CHARS - C+! BASE 1 CHARS - DUP C@ CHARS  - C! ;
	            - -------------- --- -------------- --- --        - --

	Note: Trust me on this.

I	( -- i )
	Current value of loop-index.
	
	Execution(`I')      push R[0] + R[-1];          Done

IF	( n -- )
	Begin IF statement.
	
	Note: IF is self-compiling.

IMMEDIATE	( -- )
	Make the immediate behavior of the word just defined the same
	as the execution behavior.

INCLUDED	( file-name . -- )
	Open and interpret text file.
	
	: INCLUDED  INPUT S" stream" EVALUATE ;

inline	( -- )
	Used like IMMEDIATE after a definition to revise the
	behavior to copy the compiled code rather than nest.
	 
input	( file-name -- file-id )
	Open file-name for input returning a file-id for it.

	: INPUT     s" r" OPENED ;

INVERT	( x -- x' )
	Invert all bits of x.
	
	: INVERT    PLEASE "TRUE XOR " ; IMMEDIATE

J	( -- j )
	Current value of next outer loop-index.

	Execution(`J')      push R[-2] + R[-3];         Done

k	( n -- n' )
	Multiply by 1024, implemented as `10 LSHIFT'
	
	: K PLEASE "5 LSHIFT 5 LSHIFT " ; immediate
	
	Note: Written this way to be independent of HEX or DECIMAL.

KEY	( -- char )
	Read a character from standard input.
	
	: KEY 0 stream get-char unstream ;

LEAVE	( -- )
	Break out of counted loop (DO or ?DO).

LITERAL	( C: n -- ; -- n )
	Interpretation: Do nothing.
	Compilation: Compile literal n.
	Execution: Copy n onto data stack.
	
LOOP	( -- )
	Add 1 to loop-index, and then jump back to the matching DO
	(or ?DO), or terminate the loop.
	
LSHIFT	( x k -- x' )
	Shift x left by k bits with zero fill.

	Execution(`LSHIFT') top = *S-- << top; Done

M*	( multiplicand multiplier -- product . )
	Multiply multiplicand by multiplier.

MARKER	( "<name>" -- )
	Define <name> as a word which will restore data space, name space,
	code space, and wordlists, to their current status.

MAX	( x y -- z )
	The greater of x and y.
	
	: MAX       2DUP < ?? SWAP DROP ;

MIN	( x y -- z )
	The lesser of x and y.
	
	: MIN       2DUP > ?? SWAP DROP ;

MOD	( dividend divisor -- remainder )
	The remainder from dividend divided by divisor.
	
	Execution(`MOD') top = top ? *S-- % top: *S--;   Done

MOVE	( c-add1 c-addr2 len -- )
	Copy len address units from c-addr1 to c-addr2.

	Execution(`MOVE')
		memmove(&data[*S], &data[S[-1]], top), S -= 2, pop;
	Done

NEGATE	( x -- x' )
	The negative of x.

	Execution(`NEGATE') top = -top; Done

nesting	( -- n )
	The depth of the return stack.

	Execution(`NESTING')    push R - rack;		Done

next-char	( -- char )
	Get character from input source without removing it.

	Execution(`NEXT-CHAR')
	    *++S = top, top = char();
	    if (top != EOF) unchar(top) ;
	Done

NIP	( x y -- y )
	Discard next-to-top stack element.
	
	Execution(`NIP')    S--; Done

not	( x -- x' )
	Equal to false.
	
	: NOT       PLEASE "FALSE = " ; IMMEDIATE

OF	Macro: `OVER = IF DROP'

	: OF        PLEASE "OVER = IF DROP " ; IMMEDIATE
	
	Note: When used after a literal, `n OVER =' becomes a
	primitive Forth instruction; otherwise `= IF' becomes
	a primitive Forth instruction.

opened	( file-name . mode . -- file-id )
	Open file-name with mode, leaving file-id.

	: OPENED    FOPEN dup 0= abort" Can't open " ;

OR	( x y -- z )
	Bitwise `and' x with y.

	Execution(`OR') top |= *S--; Done

orif	Macro: `?DUP 0= IF'

	: ORIF please "?DUP 0= IF" ; immediate

	Note: This is a short circuit.  With `ORIF mumble THEN'
	`mumble' will not be evaluated if the top stack element
	was unfalse.
	
	Note: `?DUP 0= IF' is a single primitive instruction.

output	( "<file-name>" -- file-id )
	Open <file-name> for output, leaving a file identifier.
	
	: OUTPUT    s" w" OPENED ;

outside	( -- n )
	The depth of the compile-time stack within the data stack.
	
	Execution(`OUTSIDE')    push S - stack - 1 - level;     Done

OVER	( a b -- a b a )
	Copy the next-to-top stack element onto the top of the data stack.
	
	Execution(`OVER')   push S[-1]; 			Done

PAD	( -- c-addr )
	An 84-character scratch area for users.
	
	CREATE PAD   84 CHARS ALLOT

	Note: You can't be sure of more than 84 characters, so live with it.

PARSE	( char "<text><char>" -- c-addr len )
	Parse text delimited by char.
	
patch	( x n -- )
	Patch location n of code space with x.

	Execution(`PATCH')  code[top] = *S--, pop; Done

PICK	( xN ... x1 x0 N -- xN ... x1 x0 xN )
	Copy xN onto top of stack.
	
	Execution(`PICK')    top = S[-top];		Done

place	( string . c-addr -- )
	Move character string to counted string.

	: PLACE     2dup >R >R    char+  swap MOVE    R> R> C! ;

	Note: PLACE is the inverse of COUNT.

please	( "<spaces><char><text><char>" -- )
	or
	( string . "<spaces><char><text><char>" -- )
	Insert text into input source, replacing occurrences of
	`~' with string.

POSTPONE	( C: "name" -- ; ... -- ??? )
	Delay immediate behavior of name.

	: POSTPONE  ~PLEASE "['] ~ EXECUTE " ; IMMEDIATE

	Note: This works because all words have immediate behavior.

print?	( char -- flag )
	Test for a printable character.

	: PRINT?    BL - 95 u< ;

QUIT	( ... -- same )
	Reset the return stack and restart.

r!	( x -- ; R: y -- x )
	Move the top stack element into the top return stack element.
	
	: R!	R> DROP >R ; INLINE

r+!	( x -- ; R: y -- x+y )
	Take and add the top stack element to the top return stack element.
	
	: R+!	R> + >R ; INLINE

R>	( -- x ; R: x -- )
	Move the top return stack element onto the top of the data stack.

	Execution(`R>')	push *R--; Done

R@	( -- x ; R: x -- same )
	Copy the top return stack element onto the top of the data stack.

	Execution(`R>')	push *R; Done

RECURSE	( ... -- ??? )
	Compile call to the word being defined.

REPEAT	( -- )
	Jump back to the balancing BEGIN.

REWIND	( file-id -- )
	Reposition file to its beginning.

	: REWIND    0 0 FSEEK drop  ERROR? drop ;

ROLL	( x0 x1 ... xN N -- x1 ... xN x0 )
	Rotate N+1 stack elements

ROT	( a b c -- b c a )
	Move second-next-to-top stack element onto the top of the stack.

	Execution(`ROT')    
	        w = S[-1], S[-1] = *S, *S = top, top = w;
	Done

RSHIFT	( x n -- x' )
	Shift x right by n bits with zero fill.

	Execution(`RSHIFT') top = (unsigned long) *S-- >> top;   Done

S"	( "<text><quote>" -- c-addr len )
	Character string.

	: S"        [CHAR] " PARSE PLEASE 'c" ~" count ' ; IMMEDIATE 

s=	Macro: `COMPARE 0='

	: S= please "COMPARE 0=" ; immediate

S>D	( n -- n . )
	Convert a number to a double number.
	
	: S>D	DUP 0< ;

SEARCH-WORDLIST	( name . wid -- 0 | xt 1 | xt -1 )
	Search wordlist wid for name.

	Note: Defined in kernel to support optional Search Order
	word set.

SIGN	( n -- )
	If n is negative insert `-' in pictured numeric output.

	: SIGN      0< IF   [CHAR] - HOLD   THEN ;

SLITERAL	( C: c-addr len -- ; -- c-addr len )
	Compile string literal.

SM/REM	( dividend . divisor -- remainder quotient )
	So-called `symmetric' division.

sought	( file-id offset whence -- )
	Reposition file.

	: SOUGHT    FSEEK abort" Can't seek. " ;

SOURCE	( -- c-addr span )
	Location and size of the input buffer.

	: SOURCE 1 HAS COUNT ;

	Note: Not applicable in This Forth.

SOURCE-ID	( -- file-id | 0 )
	The file identity being used by the user input device.

SPACE	( -- )
	Display a single space.
	
	: SPACE BL EMIT ;
	
SPACES	( n -- )
	Display n spaces.
	
	Execution(`SPACES')
	    while (top-- > 0) emit(SPACE) ;
	    pop;
	Done

stack-char	( char -- )
	Insert character in input source.

	# define unchar(c)	*cp++ = (c)
	Execution(`STACK-CHAR') unchar(top), pop;           Done

STATE	( -- a-addr )
	Address containing current compilation state.
	
	Note: Changing STATE does not change compilation state.

stream	( file-id -- )
	Assign file identity to input device.

SWAP	( a b -- b a )
	Interchange the top two stack elements.

	Execution(`SWAP')  w = top, top = *S, *S = w; Done

system	( string . -- flag )
	Standard C library function.

th	Macro: `TH address' becomes `CELLS address +'

	: TH get-word please "CELLS ~ + " ; immediate
	
	Note: `n TH address', `n TH address @', and
	`n TH address !' become single Forth instructions.

THEN	( -- )
	End IF statement.

TIME&DATE	( -- second minute hour day month year )
	Return current time and date.

	# include	<time.h>

	Execution(`TIME&DATE')
	{
	    struct tm * broken_down_time;
	    time_t time_now;
	
	    time_now = time(NULL);
	    broken_down_time = localtime(&time_now);
	    push broken_down_time->tm_sec;
	    push broken_down_time->tm_min;
	    push broken_down_time->tm_hour;
	    push broken_down_time->tm_mday;
	    push broken_down_time->tm_mon + 1;
	    push broken_down_time->tm_year + 1900;
	}
	Done

TO	( n "<value-name>" -- )
	Assign n to value-name.
	
	: TO        ~PLEASE "['] ~ >BODY ! " ; IMMEDIATE

told	( file-id -- offset )
	The current position in the file.

	: TOLD      FTELL dup 0< abort" Can't tell. " ;

tr	Macro: `TR foo bar' becomes `bar foo'.
	Interchange the next two words in the input stream.
	
	: TR  get-word get-word 2swap please "~ " please "~ " ; immediate

	Note: For an example of use, see `tab.fo'.

TRUE	( -- n )
	Canonical true -- all bits on.

TUCK	( a b -- b a b )
	Copy top of stack under next-to-top of stack.

	: TUCK please "SWAP OVER " ; immediate

TYPE	( c-addr len -- )
	Display len characters at c-addr.

U.	( u -- )
	Display u as an unsigned number.
	
	: U.        0 <# #S #> TYPE   SPACE ;

U<	( this that -- flag ) 
	Compare this lower than that.
	
U>	( this that -- flag )
	Compare this higher than that.

UM*	( multiplicand multiplier -- product . )
	Multiply multiplicand by multiplier as unsigned numbers.

UM/MOD	( dividend . divisor -- remainder quotient )
	Divide unsigned double dividend by unsigned divisor.

under+      ( a b c -- a+c b )
	Take the top of stack and add it to what is now the
	next-to-top of stack.

	Execution(`UNDER+') S[-1] += top, pop;   Done

unfilter	( --  ) 
	Macro to end a filter.
	
	`UNFILTER' becomes
	
	REPEAT
	SOURCE-ID UNSTREAM REWIND

UNLOOP	( -- ; R: x y -- )
	Discard loop-limit and loop-index.

unstream	( -- )
	Restore previous file identity of input source.

UNTIL	( n -- )
	Take top of stack and if it is false, jump back to the balancing
	BEGIN.
	
UNUSED	( -- n )
	Amount of space remaining in data space, in address units.

	Execution(`UNUSED')     push DATAROOM - here;           Done

VALUE	( n "<name>" -- )
	Define value-name name initialized to n.

	: VALUE     CREATE , IMMEDIATE DOES> (.) PLEASE "~ @ " ;
	
	Note: There is no performance penalty in using value-names.
	
VARIABLE	( "<name>" -- )
	Define variable name.
	
	: VARIABLE  CREATE   0 , ;

version		( -- )
	Display version information.

WHILE	( n -- )
	If n is false jump forward to balancing REPEAT or THEN.

will	( -- )
	Insert something in the input source that will break out of the 
	text interpreter/compiler.
	
	Note: Used like
	WILL PLEASE "..." ... EXPOUND
	This gives parameter substitution for EVALUATE.

WITHIN	( x initial limit -- flag )
	Return true if x is in range [initial, limit).
	
	: WITHIN    OVER - >R - R> U< ;

WORD	( char "<chars><text><char>" -- c-addr )
	Parse text delimited by char.
	
x.	( n -- )
	Display x signed if numeric radix is 10, unsigned otherwise.
	
	: X.        base @ 10 = if    . else    u. then ;

XOR	( x y -- z )
	Bitwise `xor' of x with y.

	Execution(`XOR') top ^= *S--;         Done

|       ( -- )
	Mark the next definition as one to be disowned.

||     	( --  )
	Disown marked definitions.

~PLEASE	Macro: `GET-WORD PLEASE'

	: ~PLEASE "GET-WORD PLEASE " ; IMMEDIATE

	
