Copyright 2007, 2024 Anthony Howe. All rights reserved.
( x
aaddr
-- )
Store x
at aaddr
.
( ud1
-- ud2
)
Divide ud1
by the number in BASE
giving the quotient ud2
and the remainder n
. (n
is the least significant digit of ud1
.) Convert n
to external form and append the resulting character to the pictured numeric output string.
( xd
-- caddr
u
)
Drop xd
. Make the pictured numeric output string available as a character string. caddr
and u
specify the resulting character string. A program may replace characters within the string.
( ud1
-- 0
)
Convert one digit of ud1
according to the rule for #
. Continue conversion until the quotient is zero (0).
( <spaces>name
-- xt
)
Find name
and place its execution token on the stack. Throw undefined word (-13) if not found.
( ccc<paren>
-- ) immediate
Parse and ignore characters up to the closing right parenthesis, which an empty string or span multiple lines.
( ccc<paren>
-- ) immediate
Parse and ignore characters up to the closing right parenthesis, which an empty string or span multiple lines. Note a backslash followed by any other character escapes that character, ie. \\
is a literal backslash, \)
is a literal closing parenthesis.
( n1|u1
n2|u2
-- n3|u3
)
Multiply the top two stack values.
( n1
n2
dsor
-- quot
)
Multiply n1
by n2
then divide by divisor dsor
giving the quotient quot
.
( n1
n2
dsor
-- rem
quot
)
Multiply n1
by n2
then divide by divisor dsor
giving the remainder rem
and quotient quot
.
( n1|u1
n2|u2
-- n3|u3
)
Add the top two stack values.
( n|u
aaddr
-- )
Add n|u
to the cell at aaddr
.
( addr
<spaces>name
-- addr'
)
Define unaligned structure field name
, which when executed adds the field offset to addr
giving addr'
.
Structure name defined last:
0 \ initial total byte count
1 CELLS +FIELD p.x \ single cell field named p.x
1 CELLS +FIELD p.y \ single cell field named p.y
CONSTANT point \ save structure size
Structure name defined first:
BEGIN-STRUCTURE point \ create the named structure
1 CELLS +FIELD p.x \ A single cell field named p.x
1 CELLS +FIELD p.y \ A single cell field named p.y
END-STRUCTURE
( step
-- ) immediate
Add step
to the loop index. If the loop index did not cross the boundary between the loop limit minus one and the loop limit, continue execution at the beginning of the loop. Otherwise, end the current loop and continue execution immediately following the loop.
: SOMEWORD ... limit first DO ... step +LOOP ... ;
( x
-- )
Align and reserve one cell of data-space and store x
there.
( n1|u1
n2|u2
-- n3|u3
)
Subtract the top two stack values.
( n
-- )
Display n
in free field format.
( n1
n2
-- )
Display n1
right aligned in a field n2
characters wide. If the number of characters required to display n1
is
greater than n2
, all digits are displayed with no leading spaces in a field as wide as necessary.
( ccc<quote>
-- ) immediate
Display ccc
.
( ccc<paren>
-- ) immediate
Parse and display text until an unescaped closing parenthesis.
( ccc<paren>
-- ) immediate
Parse and display text until an unescaped closing parenthesis. Note a backslash followed by any other character escapes that character, ie. \\
is a literal backslash, \)
is a literal closing parenthesis.
( dend
dsor
-- quot
)
Divide the dividend dend
by the divisor dsor
leaving the symmetric quotient quot
on top of the stack..
( dend
dsor
-- rem
quot
)
Divide the dividend dend
by the divisor dsor
leaving the remainder rem
and quotient quot
on top the stack.
( n
-- bool
)
bool
is true if and only if n
is less than zero (0).
( nu
-- bool
)
bool
is true if nu
is not equal to zero (0).
( nu
-- bool
)
bool
is true if nu
is greater to zero (0).
( x
-- bool
)
bool
is true if and only if x
is equal to zero (0).
( n1|u1
-- n2|u2
)
Add one (1) to n1|u1
giving the sum n2|u2
.
( n1|u1
-- n2|u2
)
Subtract one (1) from n1|u1
giving the difference n2|u2
.
( lo
hi
aaddr
-- )
Store the cell pair lo hi
at aaddr
as hi lo
.
( x1
-- x2
)
x2
is the result of shifting x1
one bit toward the most-significant bit, filling the vacated least-significant bit with zero (0).
( x1
-- x2
)
x2
is the result of shifting x1
one bit toward the least-significant bit, leaving the most-significant bit unchanged, .ie arithmetic right shift.
( aaddr
-- lo
hi
)
Fetch the cell pair hi lo
stored at aaddr
and place on the stack as lo hi
.
( x1
x2
-- )
Drop cell pair x1 x2
from the stack.
( x1
x2
-- x1
x2
x1
x2
)
Duplicate cell pair x1 x2
.
( x1
x2
x3
x4
-- x1
x2
x3
x4
x1
x2
)
Copy cell pair x1 x2
to the top of the stack.
( x1
x2
x3
x4
-- x3
x4
x1
x2
)
Exchange the top two cell pairs.
(C: <spaces>name
-- colon-sys
)
Start definition of word name
. The current definition shall not be findable in the dictionary until it is ended (or until the execution of DOES>
). See also ;
, CREATE
, DOES>
, :NONAME
, [: and ;].
: SOMENAME words that do stuff ;
(C: -- colon-sys
)(S: -- xt
)
Create a nameless word definition, which when terminated by ;
leaves xt
on the data stack. The nameless word cannot be found with '
nor FIND-NAME
. See also [: and ;].
\ Create forward reference.
DEFER print
\ Define the implementation.
:NONAME ( n -- ) . ; IS print
\ Alternative to : temp_word some words ;
:NONAME some words ; CONSTANT temp_word
: foo ... temp_word ... ;
(C: colon-sys
-- ) immediate
End definition of word.
(C: quotation-sys
colon-sys
-- )(S: -- xt
) immediate
Ends the current nested definition started by [:
, leaving xt
on the data stack, and resumes compilation of the previous enclosing definition.
: foo 123 [: ." wave " ;] execute . ;
( n1
n2
-- bool
)
bool
is true if and only if n1
is less than n2
.
( -- )
Initialise the pictured numeric output conversion process.
( x1
x2
-- bool
)
bool
is true if and only if x1
is bit-for-bit the same as x2
.
( n1
n2
-- bool
)
bool
is true if and only if n1
is greater than n2
.
( xt
-- aaddr
| ⊥ )
aaddr
is the data-field address corresponding to xt
. Will throw not created (-31) if xt
is not a word defined by CREATE
.
( -- aaddr
)
aaddr
is the address of a cell containing the offset in characters from the start of the
input buffer to the start of the parse area.
( acc
caddr
len
-- acc'
caddr'
len'
)
acc'
is the unsigned result of converting the characters within the string specified by caddr
len
into digits according to the number in BASE
, and adding each into acc
after multiplying acc
by the number in BASE
. Conversion continues left-to-right until a character that is not convertible, including any "+" or "-", is encountered or the string is entirely converted. caddr'
is the location of the first unconverted character or the first character past the end of the string if the string was entirely converted. len'
is the number of unconverted characters in the string. An ambiguous condition exists if acc'
overflows during the conversion.
( x
-- )(R: -- x
)
Move top of the data stack to the return stack.
( n1|u1
n2|u2
-- ) (R: -- loop-sys
) immediate
Mark the start of ?DO ... +LOOP
or ?DO ... LOOP
.
( x
-- x
x
)
Duplicate x
if it is non-zero.
( aaddr
-- x
)
Fetch from aaddr
the value x
stored there.
( i*x
-- ⊥ ) ( R: j*x
-- )
Throw abort (-1). Clear the data stack and perform a QUIT
, which clears the return stack too. Never returns to caller.
( i*x
x1
-- i*x
| ⊥ ) ( R: j*x
-- j*x
| ⊥ )
If x1
is not equal to zero (0), display the message that follows up to the closing double-quote and perform an ABORT
. Never returns to caller.
( n
-- u
)
Return the absolute value of n
.
( <spaces>name
-- xt
) immediate
Return the execution token xt
of a deferred name
. See DEFER
.
( caddr
+n1
-- +n2
)
Accept up to +n1
(between 1 and +32767) characters into the buffer given by caddr
; the number of characters actually received, +n2
, is pushed.
( -- ) immediate
Loop back to matching BEGIN
indefinitely.
BEGIN
\ loop body
AGAIN
( -- )
If the data-space pointer is not aligned, reserve
enough space to align it.
( addr
-- aaddr
)
aaddr
is the first cell aligned address greater than or equal to addr
.
( n
-- )
If n
is greater than zero (0), reserve n
address units of data space. If n
is less than zero (0), release |n|
address units of data space. If n
is zero (0), leave the data-space pointer unchanged.
( x1
x2
-- x3
)
Bit-wise and of the top two stack values.
( col
row
-- )
Position cursor on the terminal, row
and col
are zero (0) based.
( -- aaddr
)
aaddr
is the address of a cell containing the current number conversion radix, between 2..36.
( -- ) immediate
Mark the start of BEGIN ... AGAIN
or BEGIN ... WHILE ... REPEAT
loops.
( <spaces>name
-- addr
0
)
Parse name
delimited by a space and create a definition for name
. Return a struct-sys (zero or more implementation dependent items) that will be used by END-STRUCTURE
and an initial offset of zero (0). When name
is executed the size of the structure in address units is pushed to the stack. See also +FIELD
, CFIELD:
, and FIELD:
.
( -- char
) constant
char
is the character value for a space, since Forth words are delimited by space. A space can also be specified with '\s'
.
( char
caddr
-- )
Store char
at caddr
.
( ccc<quote>
-- caddr
) immediate
Compile the string ccc
as-is into the current word so when executed it leaves the counted string caddr
on the stack. See also S"
.
( char
-- )
Reserve one character of data space and store char
there.
( caddr
-- char
)
Fetch from caddr
the character char
stored there.
( -- ) immediate
CASE
test1 OF ... ENDOF
...
testN OF ... ENDOF
default action
ENDCASE
( i*x
xt
-- j*x
0
| i*x
n
)
Push an exception frame on the exception stack and then execute the execution token xt
(as with EXECUTE
) in such a way that control can be transferred to a point just after CATCH
if THROW
is executed during the execution of xt
.
If the execution of xt
completes normally (ie. the exception frame pushed by this CATCH
is not popped by an execution of THROW
) pop the exception frame and return zero (0) on top of the data stack, above whatever stack items would have been returned by xt EXECUTE
. Otherwise, the remainder of the execution semantics are given by THROW
.
( aaddr1
-- aaddr2
)
Add the size in address units of a cell to aaddr1
giving aaddr2
.
( n1
-- n2
)
n2
is the size in address units of n1
cells.
( n1
<spaces>name
-- n2
)
Skip leading space delimiters. Parse name delimited by a space. Offset is the first float aligned value greater than or equal to n1
. n2 = offset + 1
float.
( <spaces>ccc
-- char
)
Parse ccc
placing the first character of text on the stack.
( caddr1
-- caddr2
)
Add the size in address units of a character.
( n1
-- n2
)
n2
is the size in address units of n1
characters.
( xt
-- )
Append the execution semantics of the definition represented by xt
to the execution semantics of the current definition.
( x
<spaces>name
-- )
Define the word name
to represent the constant value x
. When name
is executed, the value x
is pushed on to the stack.
377 CONSTANT monaco
( caddr1
-- caddr2
u
)
Return the character string caddr2 u
specification for the counted string caddr1
.
( -- )
Write a newline to standard output.
( <spaces>name
-- )
Create a new word definition. When name
is executed, the aaddr
of its data space is pushed onto the stack. CREATE
can be used to define new data structure, eg.
\ Define how to make an array.
: array ( n "<spaces>name" -- ) CREATE CELLS ALLOT ;
\ Define a new array of 3 cells.
3 array fred
\ Store 123 into fred[1].
123 fred 1 CELLS + !
Or when combined with DOES>
make new "defining" words, eg.
\ General structure:
: word1 CREATE ( build data space of word2 ) DOES> ( actions applied to data of word2 ) ;
\ Make a new defining word CONSTANT.
: CONSTANT CREATE , DOES> @ ;
\ Use CONSTANT to define a word representing a value.
377 CONSTANT monaco
\ Use the new word.
monaco ( -- 377 )
( -- )
Set the numeric conversion radix to ten (decimal).
( <spaces>name
-- )
Create a definition for name
, which when executed will execute the saved execution token; default ABORT
. (Think indirect word execution.)
ok DEFER foo
ok foo
-1 thrown: ABORT
ok : hello S\" Hello world! woot woot\n" TYPE ;
ok ' hello IS foo
ok foo
Hello world! woot woot
ok ACTION-OF foo EXECUTE
Hello world! woot woot
ok
( xt2
xt1
-- )
Set the deferred word xt1
to execute xt2
when called.
( xt1
-- xt2
)
Get the execute token xt2
stored by deferred word xt1
.
( -- u
)
Number of cells on the data stack before u
was placed there.
(C: -- do-sys
) ( n1|u1
n2|u2
-- ) (R: -- loop-sys
) immediate
Mark the start of DO ... +LOOP
or DO ... LOOP
.
Define the execution semantics for the most recently defined word by CREATE
. Throws not created (-31) if DOES>
is applied to a word not defined by CREATE
.
\ General structure:
: word1 CREATE ( build data space of word2 ) DOES> ( actions applied to data of word2 ) ;
\ Make a new defining word CONSTANT.
: CONSTANT CREATE , DOES> @ ;
\ Use CONSTANT to define a word representing a value.
377 CONSTANT monaco
\ Use the new word.
monaco ( -- 377 )
( x
-- )
Remove the top of the stack.
( x
-- x
x
)
Duplicate x
.
( -- ) immediate
test IF
\ execute for true
ELSE
\ execute for false
THEN
\ continue
( char
-- )
Write the character octet to standard output.
( addr
0
-- )
Terminate definition of a structure started by BEGIN-STRUCTURE
.
( x
--- ) immediate
Discard the case selector x
and continue execution.
CASE
test1 OF ... ENDOF
...
testN OF ... ENDOF
default action
ENDCASE
( -- ) immediate
CASE
test1 OF ... ENDOF
...
testN OF ... ENDOF
default action
ENDCASE
( i*x
caddr
u
-- j*x
)
Save the current input source specification and make the string described by caddr
and u
both the input source and buffer, reset >IN
to zero (0), and interpret. When the parse area is empty, restore the prior input source specification.
( i*x
xt
-- j*x
)
Remove the execution token xt
from the stack and perform the semantics identified by it.
( -- )(R: ip
-- )
Return control from the currently executing word to its caller. Before executing EXIT
within a do-loop, a program shall discard the loop-control parameters by executing UNLOOP
.
( -- false
) constant
Return false value, equivalent to zero (0).
( addr
<spaces>name
-- addr'
)
Define cell aligned structure field name
, which when executed adds the field offset to addr
giving addr'
.
BEGIN-STRUCTURE point \ create the named structure
FIELD: p.x \ A single cell field named p.x
FIELD: p.y \ A single cell field named p.y
END-STRUCTURE
( caddr
u
char
-- )
Fill memory at address caddr
with u
consecutive characters char
.
( caddr
-- caddr
0 | xt
1 | xt
-1 )
Given the counted string caddr
, find its execution token xt
. If found and xt
is an immediate, return xt 1
; if not immediate, return xt -1
; otherwise not found, return caddr 0
. See FIND-NAME.
... BL WORD FIND DUP 0= -13 AND THROW ...
( d
dsor
-- mod
quot
)
Floored division of the double-cell dividend d
(lo
hi
) by the divisor dsor
leaving the modulus mod
and quotient quot
. In floored division the modulus mod
carries the sign of the divisor dsor
.
Dividend Divisor Remainder Quotient
10 7 3 1
-10 7 4 -2
10 -7 -4 -2
-10 -7 -3 1
( -- addr
)
addr
is the data-space pointer that will next be assigned by ,
, ALIGN
, ALLOT
, C,
, COMPILE,
. See RESERVE
below.
( -- )
Set the numeric conversion radix to sixteen (hexadecimal).
( char
-- )
Append char
to the picture numeric output string.
( caddr
u
-- )
Append string caddr
u
to the pictured numeric output string.
( -- n|u
)
n|u
is a copy of the current (innermost) loop index.
( bool
-- ) immediate
If bool
is zero (0) (FALSE
), continue execution following the matching ELSE
or THEN
.
test IF
\ execute for true
THEN
\ continue
test IF
\ execute for true
ELSE
\ execute for false
THEN
\ continue
( -- )
Make the most recent definition an immediate word.
( <spaces>filepath
-- )
Skip leading white space and parse filepath
delimited by a white space character. Push the address and length of the filepath
on the stack and perform the function of INCLUDED
. See also INCLUDE-PATH
below.
ok INCLUDE ../examples/wumpus.p4
( caddr
u
-- )
Save the current input source specification, including the current value of SOURCE-ID
. Open the file specified by caddr
u
, store the resulting file-id in SOURCE-ID
, and make it the input source. Store zero (0) in BLK
. Interpret the file line by line until end of file. Other stack effects are due to the words included. The input source specification is restored after the file is closed. See also INCLUDED-PATH
below.
( x1
-- x2
)
Take the one's complement of x1
.
( xt
<spaces>name
-- ) immediate
Set deferred word name
to the execution token xt
. See DEFER
.
( -- n|u
)
n|u
is a copy of the next-outer loop index.
( -- char
)
Receive one character char
. Characters received by KEY
are not displayed.
( -- bool
)
If a character is available, return true. Otherwise, return false. The character shall be returned by the next execution of KEY.
( -- ) (R: loop-sys
-- ) immediate
Leave the current loop, resume execution following the +LOOP
or LOOP
.
( x
-- ) immediate
Compile x
into the definition so that it is later pushed onto the stack during execution of the definition.
: SOMEWORD ... [ x ] LITERAL ... ;
(C: do-sys
-- ) immediate
Add n
to the loop index. If the loop index did not cross the boundary between the loop limit minus one and the loop limit, continue execution at the beginning of the loop. Otherwise, end the current loop and continue execution immediately following the loop.
: SOMEWORD ... limit first DO ... LOOP ... ;
Or
: SOMEWORD ... limit first ?DO ... LOOP ... ;
( x1
u
-- x2
)
Logical left shift of x1
by u
bits, putting u
zeroes into the least significant bits.
( n1
n2
-- d
)
The double-cell d
(lo
hi
) is the signed product of n1
times n2
.
( n1
n2
-- n3
)
n3
is the greater of n1
and n2
.
( n1
n2
-- n3
)
n3
is the lesser of n1
and n2
.
( dend
dsor
-- rem
)
Divide the dividend dend
by the divisor dsor
leaving the remainder rem
.
( src
dst
u
-- )
If u
is greater than zero (0), copy from src
the contents of u
consecutive address units to dst
.
( u
-- )
Wait at least u
milliseconds.
( n1
-- n2
)
Negate n1
, giving its arithmetic inverse n2
.
( x1
x2
-- x2
)
Drop the first item below the top of stack.
( x1
x2
-- | x1
) immediate
CASE
test1 OF ... ENDOF
...
testN OF ... ENDOF
default action
ENDCASE
( x1
x2
-- x3
)
Bit-wise or of the top two stack values.
( x1
x2
-- x1
x2
x1
)
Copy the second value x1
below the stack to the top.
( -- aaddr
)
A character buffer space available to developers and not used by standard words.
( -- )
Clear the terminal (advance next page).
( char
ccc<char>
-- caddr
u
)
Parse ccc
delimited by the delimiter char
. caddr
and u
are the address and length within the input buffer of the parsed string. If the parse area was empty, the resulting string has a zero (0) length.
( <spaces>name<space>
-- caddr
u
)
Skip leading space delimiters. Parse name delimited by a space.
( xu
xu-1
... x1
x0
u
-- xu
xu-1
... x1
x0
xu
)
Remove u
. Copy the xu
to the top of the stack. 0 PICK
equivalent to DUP
, 1 PICK
equivalent to OVER
.
( <spaces>name
-- ) immediate
Parse and find name
appending the compilation semantics of name
to the current definition. For an immediate word, it is compiled into the definition, instead of executed. Otherwise compile the word during the definition of another word.
An example:
: [CHAR] CHAR POSTPONE LITERAL ; IMMEDIATE
( -- ⊥ )(R: i*x
-- ⊥ )
Empty the return stack (never returns to caller), reset SOURCE-ID
to zero (0), set the console as the input source, enter interpretation state, and start REPL:
- Accept a line from the input source into the input buffer, set
>IN
to zero (0), and interpret. - Display the prompt if in interpretation state, all processing has been completed, and no ambiguous condition exists.
( -- x
)(R: x
-- )
Move top of the return stack to the data stack.
( -- x
)(R: x
-- x
)
Copy top of return stack to the data stack.
( -- ) immediate
Call the current definition. The behaviour of RECURSE
following a DOES>
is undefined.
: FACTORIAL ( +n1 -- +n2)
DUP 2 < IF DROP 1 EXIT THEN DUP 1- RECURSE *
;
( -- bool
)
Attempt to fill the input buffer from the input source, returning true if successful.
When the input source is the user input device, attempt to receive input into the terminal input buffer. If successful, make the result the input buffer, set >IN
to zero (0), and return true. Receipt of a line containing no characters is considered successful. If there is no input available from the current input source, return false.
When the input source is a string from EVALUATE
, return false and perform no other action.
When the input source is a block, make the next block the input source and current input buffer by adding one to the value of BLK
and setting >IN
to zero (0). Return true if the new value of BLK
is a valid block number, otherwise false.
( -- ) immediate
Loop back to matching BEGIN
.
BEGIN
\ test expression
WHILE
\ loop body while true
REPEAT
\ continue once test is false
( xu
xu-1
... x0
u
-- xu-1
... x0
xu
)
Left rotate the stack u
cells.
( x1
x2
x3
-- x2
x3
x1
)
Left rotate the top three stack entries.
( x1
u
-- x2
)
Logical right shift of x1
by u
bits, putting u
zeroes into the most significant bits.
( ccc<quote>
-- caddr
u
) immediate
When interpreting, copy the string ccc
as-is to a transient buffer and return caddr u
. When compiling, append the string ccc
as-is to the current word so when executed it leaves caddr u
of the string on the stack. Note as an extension strings are also NUL
terminated to facilitate use of host environment functions.
( n
-- d
)
Convert the number n
to the double-cell number d
(lo
hi
) with the same numerical value.
( ccc<quote>
-- caddr
u
) immediate
When interpreting, copy the escaped string ccc
to a transient buffer and return caddr u
. When compiling, append the escaped string ccc
to the current word so when executed it leaves caddr u
of the string on the stack. Note as an extension strings are also NUL
terminated to facilitate use of host environment functions.
( n
-- )
If n
is negative, add a minus sign to the beginning of the pictured numeric output string. An ambiguous condition exists if SIGN
executes outside of a <# #>
delimited number conversion.
( d
dsor
-- rem
quot
)
Symmetric division of the double-cell dividend d
(lo
hi
) by the divisor dsor
leaving the remainder rem
and quotient quot
. In symmetric division the remainder rem
carries the sign of the dividend d
.
Dividend Divisor Remainder Quotient
10 7 3 1
-10 7 -3 -1
10 -7 3 -1
-10 -7 -3 1
( -- caddr
u
)
Push the string address caddr
and the number of characters u
in the input buffer.
( -- )
Display a space.
( n
-- )
If n
is greater than zero (0), display n
spaces.
( -- aaddr
)
Return the aaddr
address of the compilation state; true when compiling, otherwise false when interpreting. See also words [
and ]
.
( x1
x2
-- x2
x1
)
Exchange the top two stack items.
( -- sec
min
hour
day
month
year
)
Time current local system time. sec
{0..59}, min
{0..59}, hour
{0..23}, day
{1..31}, month
{1..12}, year
eg. 1970.
( -- ) immediate
See IF
.
AHEAD
\ not executed
THEN
\ continue
test IF
\ execute for true
THEN
\ continue
test IF
\ execute for true
ELSE
\ execute for false
THEN
\ continue
( k*x
n
-- k*x
| i*x
n
)
If n
is non-zero, pop the top most exception frame from the exception stack, along with everything on the return stack above that frame. Then restore the input source specification in use before the corresponding CATCH
and adjust the depths of all stacks so that they are the same as the depths saved in the exception frame (i
is the same number as the i
in the input arguments to the corresponding CATCH
), put n
on top of the data stack, and transfer control to a point just after the CATCH
that pushed that exception frame.
If the top of the stack is non-zero and there is no exception frame on the exception stack the system may display an implementation-dependent message giving information about the condition associated with the THROW
code n
. Subsequently, the system shall perform the function of ABORT
.
( i*x
<spaces>name
-- )
See VALUE
and 2VALUE.
( -- true
) constant
Return a true flag, a single-cell value with all bits set.
( x1
x2
-- x2
x1
x2
)
Copy the first (top) stack item below the second stack item.
( caddr
u
-- )
If u
is greater than zero (0), display the character string specified by caddr
and u
.
( u
-- )
Display u
in free field format.
( u
n
-- )
Display u
right aligned in a field n
characters wide. If the number of characters required to display u
is
greater than n
, all digits are displayed with no leading spaces in a field as wide as necessary.
( u1
u2
-- bool
)
bool
is true if and only if n1
is less than n2
.
( u1
u2
-- bool
)
bool
is true if and only if n1
is greater than n2
.
( u1
u2
-- ud
)
ud
(lo
hi
on the stack) is the unsigned product of u1
times u2
.
( d
dsor
-- mod
quot
)
Divide the double-cell dividend d
(lo
hi
) by divisor dsor
, giving the quotient quot
and the remainder mod
. All values and arithmetic are unsigned.
( -- ) ( R: loop-sys
-- )
Drop the loop control for the current loop. An UNLOOP
is needed for each nesting level before a definition may leave by means of EXIT
.
limit first DO
\ stuff
\ test expression
IF
\ other stuff
UNLOOP EXIT
THEN
\ more stuff
LOOP
\ continue
( x
-- ) immediate
Loop back to BEGIN
until x
equals zero (0).
BEGIN
\ loop body
\ test expression
UNTIL
( -- u
)
u
is the amount of data space remaining in the region addressed by HERE
, in address units.
( x
<spaces>name
-- )
Create name
with one cell of data assigned x
. When name
is executed, the value x
is pushed to the stack. See TO
.
ok 69 VALUE position
ok position .
69 ok
ok 66 TO position
ok position .
66 ok
( <spaces>name
-- )
Create name
with one cell of data. When name
is executed push the aaddr
of the data cell.
VARIABLE name \ define name
123 name ! \ store value to variable
name @ \ fetch value from variable
( x
-- ) immediate
If x
equals zero (0), continue execution following REPEAT
.
BEGIN
\ test expression
WHILE
\ loop body while true
REPEAT
\ continue
( char
<chars>ccc<char>
-- caddr
)
Skip leading delimiters. Parse characters ccc
delimited by char
and return caddr
of the counted string. See PARSE-NAME
.
... BL WORD FIND DUP 0= -13 AND THROW ...
( x1
x2
-- x3
)
Bit-wise exclusive-or of the top two stack values.
( -- ) immediate
Enter interpretation state.
( <spaces>name
-- xt
) immediate
Place name's execution token xt on the stack. Throw undefined word (-13) if not found.
( <spaces>ccc
-- char
) immediate
Place char, the value of the first character of ccc
, on the stack.
( ccc<LF>
-- ) immediate
Parse and discard the remainder of the parse area, ie. comment line.
( -- )
Enter compilation state.
( x1
x2
x3
-- x3
x1
x2
)
Right rotate the top three stack entries.
( ccc<quote>
-- ) immediate
Display the escaped string ccc
.
( -- u
) constant
Size of a cell in octets.
( -- u
) constant
Size of a character in octets.
( -- u
) constant
Maximum size of a counted string in characters. This is a deviation from ENVIRONMENT?
queries.
( -- u
) constant
Size of a numeric picture buffer in characters. This is a deviation from ENVIRONMENT?
queries.
( -- u
) constant
Size of a pad buffer in characters. This is a deviation from ENVIRONMENT?
queries.
( n1
n2
-- bool
)
bool
is true if and only if n1
is less than or equal to n2
.
( n1
n2
-- bool
)
bool
is true if and only if n1
is greater than or equal n2
.
( -- u
)
Offset into the current data-space for the word being compiled. Similar to the word HERE
, except expressed as an offset from the start of the data-space when the current word was created.
( -- argv
argc
)
Return the number of arguments on the command line argc
and the NULL terminated array of C string pointers argv
. See example dumpargs.p4
.
( -- u
) constant
Size of one address unit in bits. This is a deviation from ENVIRONMENT?
queries.
( -- )
Set the numeric conversion radix to 2 (binary).
( ccc<quote>
-- caddr
) immediate
Compile the escaped string ccc
into the current word so when executed it leaves the counted string caddr
on the stack. See also S\"
.
( caddr1
-- caddr2
)
Subtract the size in address units of a character.
( aaddr1
-- aaddr2
)
Subtract the size in address units of a cell from aaddr1
giving aaddr2
.
( -- u )
Size of a cell in bits.
( -- )
Make the most recent definition as compile-only. See NAME>INTERPRET.
( xt
-- bool
)
Return TRUE
if xt
references a compile-only word; otherwise FALSE
.
( caddr
-- )
Print the counted string. See also puts
.
( -- u
)
System clock time in seconds from the epoch.
( i*x -- )
Empty the data stack.
( ix nx n -- i*x )
Drop the top n
data stack elements.
( aaddr
-- )
Store aaddr
into the data stack pointer.
( -- aaddr
)
Fetch the data stack pointer.
( -- caddr
u
)
The current working directory string caddr
u
; otherwise 0
0
. Its the caller's responsibility to FREE
caddr
when done.
( key
k
-- value
v
)
Lookup the environment variable string key
k
and return string value
v
. If the environment variable is undefined value
and v
will both be zero.
S" HOME" getenv TYPE CR
S" USER" getenv TYPE CR
( -- false
) constant
True if floored division is the default. This is a deviation from ENVIRONMENT?
queries.
( xt
-- bool
)
Return TRUE
if xt
references an immediate word; otherwise FALSE
.
( <spaces>filepath
-- )
Skip leading white space and parse filepath
delimited by a white space character. Push the
address and length of the filepath
on the stack and perform the function of included-path
.
ok INCLUDE-PATH ed.p4
( file
f
-- )
Save the current input source specification, including the current value of SOURCE-ID
. Search the colon (:) separated path list given by the environment variable POST4_PATH
for the first file, file
f
, found & open, store the resulting file-id in SOURCE-ID
, and make it the input source. Store zero (0) in BLK
. Interpret the file line by line until end of file. Other stack effects are due to the words included. The input source specification is restored after the file is closed.
ok S" ed.p4" INCLUDED-PATH
( -- u
) constant
Maximum value of any character. Currently Post4 only supports ASCII and addressable units are octets. This is a deviation from ENVIRONMENT?
queries.
( -- n
) constant
Largest usable signed integer. This is a deviation from ENVIRONMENT?
queries.
( -- u
) constant
Largest usable unsigned integer. This is a deviation from ENVIRONMENT?
queries.
( -- n
) constant
Smallest usable signed integer.
( i*x
aaddr
-- )
( i*x
i
-- )
( aaddr
-- i*x
)
( -- )
Set the numeric conversion radix to eight (octal).
( char
ccc<char>
-- caddr
u
)
Parse ccc
delimited by the delimiter char
. caddr
and u
are the address and length within the input buffer of the parsed C-style escaped string. If the parse area was empty, the resulting string has a zero (0) length. Supported escapes:
\? delete
\\ backslash
\a bell
\b backspace
\e escape
\f formfeed
\n linefeed
\r carriage-return
\s space
\t tab
\v vertical tab
\0 nul
Backslash followed by any other character escapes that character, ie. \\
is a literal backslash, \"
is a literal double quote. Note that alpha-numeric characters are reserved for future extensions.
( -- )
A defined word for the implementation. Currently does nothing but subject to change.
( -- caddr
u
)
The Git commit string of the compiled version.
( -- caddr
u
)
The path search list from the POST4_PATH
environment variable if defined; otherwise the default given by P4_CORE_PATH
.
( caddr
-- )
Print a NUL terminated string.
CREATE greet S\" Hello world.\n"
greet drop puts
( n
-- addr
)
Similar to ALLOT
, reserve n
address-units of data-space and return its start address.
( -- u
) constant
Push the return stack's size.
( a
b
c
-- b
a
c` )
( aaddr
-- )
Store aaddr
into the return stack pointer.
( -- aaddr
)
Fetch the return stack pointer.
( <spaces>rest_of_line
-- )
Pass a command line to the shell. See HAVE_HOOKS
and HAVE_SHELL
.
( caddr
u
-- n
)
Pass a NUL terminate string caddr
u
to the shell and return the exit status code n
. See HAVE_HOOKS
and HAVE_SHELL
.
( a
b
c
-- c
b
a` )
( -- u
) constant
Push the data stack's size.
( a
b
-- a
a
b
)
( u1
u2
-- u3
)
u3
is the greater of u1
and u2
.
( u1
u2
-- u3
)
u3
is the lesser of u1
and u2
.
( x
-- ) immediate
Loop back to BEGIN
while x
is non-zero; opposite of UNTIL
.
BEGIN
\ loop body
\ test expression
WHILST
( -- )
Branch relative. The integer that immediately follows is the relative distance in address units from the integer's address. Used in the definition of flow control words, like AGAIN
and AHEAD
, ELSE
, REPEAT
.
( bool
-- )
Branch relative if zero (0). The integer that immediately follows is the relative distance in address units from the integer's address. Used in the definition of flow control words, like IF
, WHILE
, UNTIL
.
( bool
-- )
Branch relative if non-zero. The integer that immediately follows is the relative distance in address units from the integer's address. Used in the definition of flow control words, like WHILST
.
( -- )
Call relative. The integer that immediately follows is the relative distance in address units from the integer's address. Used in the definition of flow control words, like RECURSE
.
( -- aaddr
)
The base address of the Post4 current machine context.
( -- aaddr
n
s
)
Push the data stack base aaddr
address, depth n
, and size s
(before executing _ds
). This stack is a fixed size and grows upward.
( n
-- )
Return to the context saved at the start of the REPL (QUIT
) passing n
. Values of n
from -1 to -255 are the Forth 200x standard THROW
codes. Passing -256 is equivalent to BYE
.
( char
bool
-- caddr
u
)
Parse ccc
delimited by the delimiter char
. When bool
is false, behaviour like PARSE
, otherwise when true parse the escaped string like PARSE-ESCAPE
. caddr
and u
are the address and length within the input buffer of the parsed (escaped) string. If the parse area was empty, the resulting string has a zero (0) length.
( -- aaddr
n
s
)
Push the return stack base address, depth n
, and size s
. This stack is a fixed size and grows upward. Some Forth systems implement the return stack using the CPU's return stack, growing down from top of memory and without limit (well until it hits something important); Post4 uses an independent return stack.
( -- rows
cols
)
Return the terminal window dimensions.