Core Words
forth macro
Switch the active dictionary for compilation
Take: --
Return: --
find mfind
Find a word in either the forth (find) or macro (mfind) dictionaries.
Take: a #
Return: xt (if found)
Return: a # (if not found)
The flag is set to true if found, false if not found.
>number
Convert a string to an integer on the stack
Takes: a #
Returns: n (if a valid number in the current base)
Returns: a # (if not a valid number in this base)
The flag is set to true if the conversion worked; false if not found.
interpret
Get and process input from the TIB
Takes: --
Return: -- (results of evaluation)
eval
Evaluate a string
Take: a #
Return: -- (the results of the evaluation are left on the stack)
1, 2, 3, ,
Inline 1, 2, 3, or 4 bytes to the heap
Take: n
Return: --
entry
Create a new dictionary entry from a string
Take: a #
Return: --
This does not define a body for the entry, it just creates an entry pointed to HERE
]
The compiler
Take: --
Return: --
This is where compilation actually takes place
compile
Compile a CALL to a word
Take: a
Return: --
[
Stop a compile, drop back to the interpreter
Take: --
Return: --
This does not terminate the compile process, use ] to restart the compiler.
;;
Compile an exit to a definition
Take: --
Return: --
If the last thing compiled was a call, change to a jmp. Otherwise just compiles in a ret.
;
End a definition
Take: --
Return: --
:
Main compiler wrapper
Takes: --
Return: --
Creates an entry (saving the old state of HERE and LAST), then jumps to ]
literal
Compiles a literal into a definition
Take: n
Return: --
#
Display the unsigned value of the TOS
Take: n
Return: --
. and u. are written around this. # does not leave a trailing space.
parse
Parse input stream
Take: <char>
Return: a #
Parses TIB until it encounters <char> or the end of a line.
reset
Reset the stack to the default starting point
Take: --
Return: --
Also replaces all values on the stack with 0's
create
create a variable
Take: --
Return: --
parses the input stream for the name
does>
Modify the runtime behavor of a 'create'd word
Take: --
Return: addr
Changes 'call dovar' to 'call <code after does>' Adds some code to push the address of the data part to the stack.
last
Returns the address of the last dictionary entry
Take: --
Return: addr
offset
Returns the address of the block buffer
Take: --
Return: addr
tib
Push the address of the TIB
Take: --
Return: addr
CORE Variables
h0
Pointer to HERE
base
The current numeric base
>in
Pointer to the current location in the input stream
word?
Pointer to a word that handles errors when words aren't found
Macros
1+ 1-
Increment (1+) or Decrement (1-) the TOS.
Take: n
Return: n+1
Inlines to "inc eax" or "dec eax"
swap
swap the top two items on the stack
Take: x y
Return: y x
inlined to "xchg eax, [esi]"
drop
drop the tos, setting nos as the new tos
Take: ... n
Return: ...
inlines to "lodsd"
nip
drop the nos
Take: ... x y
Return: ... y
true false
Use: set or clear the flag
Take:
Return:
On x86 this uses the carry flag and can be used with ?if
f: m:
Force the compiler to compile a call to a forth word (f:) or macro (m:).
Take:
Return:
This can be useful if you need to call a macro at runtime, or if you have a forth word with the same name as a macro.
These words parse the input stream
[']
Compile the address of a word into the definition
Take:
Return:
This only searches the forth dictionary, not macros.
This is a parsing word
s"
Compile a string into a definition
Take:
Return: a #
The string is placed in a special memory buffer and the address/count is stored in the definition.
This is a parsing word.
."
Use: Same as s" but also compiles in a call to 'type'
Take:
Return:
Basically this is provided to make displaing strings easier. It is a parsing word.
:
Define a new entry point
Take:
Return:
Define a new entry point into a definition.
This is a parsing word
(
Comments in definitions
Take:
Return:
Allow things like stack comments. Comments are terminiated by a ) character.
This is a parsing word
>r
Place a value on the return stack
Take: x
Return:
Notes: Drops the TOS
r>
Take the top of the return stack and place on data stack
Take:
Return: x
Drops the TORS
r
Place a copy of the TORS on the data stack
Take:
Return: x
Does not drop the TORS
repeat
Start a structured loop
Take:
Return:
again
Repeat an unconditional loop
Take:
Return:
until
Repeat a counted loop
Take: x
Return: x-1 (see notes)
When x=0 the loop exits. The counter is the TOS.
for
Start a counted loop
Take:
Return:
This is the same as 'repeat >r'
next
Repeat a counted loop
Take:
Return:
The counter is on the return stack, not the data stack. This is the same as 'r> until'
=if
Conditional
Take: x y
Return:
Continue execution if x and y are equal, otherwise skip to after 'then'
<>if
Conditional
Take: x y
Return:
Continue execution if x and y are not equal, else skip to after 'then'
>if
Conditional
Take: x y
Return:
Continue execution if x is greater than y, otherwise skip to after 'then'
<if
Conditional
Take: x y
Return:
Continue execution if x is less than y, otherwise skip to after 'then'
?if
Conditional
Take:
Return:
Continue execution if the flag is true, otherwise skip to after 'then'
(if)
Conditional (not to be called directly!)
Take: x
Return:
This is used to implement other conditionals.
Forth Words
swap
Swap the TOS and NOS
Take: x y
Return: y x
drop
Drop the TOS
Take: ... x
Return: ...
nip
Drop the NOS
Take: ... x y
Return: ... y
dup
Duplicate the TOS
Take: x
Return: x x
and
Bitwise AND
Take: x y
Return: z
or
Bitwise OR
Take: x y
Return: z
xor
Bitwise XOR
Take: x y
Return: z
not
Bitwise NOT
Take: x
Return: y
@ c@
Fetch a value
Take: a
Return: n
Fetch a cell (@) or byte (c@) from the address provided
! c!
Store a value
Take: a n
Return:
Stores a cell (!) or byte (c!) to the provided address
hex decimal octal binary
Change the base
Take:
Return:
+
Add TOS and NOS
Take: x y
Return: z
-
Subtract NOS from TOS
Take: x y
Return: z
*
Multiply TOS and NOS
Take: x y
Return: z
/mod
Divide and determine remainder
Take: x y
Return: d r
/
Divide NOS by TOS
Take: x y
Return: z
mod
Divide NOS by TOS and return the remainder
Take: x y
Return: z
negate
Negate the TOS
Take: x
Return: x
The same as doing -1 *
1+
Add 1 to TOS
Take: x
Return: x+1
1-
Subtract 1 from TOS
Take: x
Return: x-1
(
Comments
Take:
Return:
This parses until a ) is encounted and ignores the parsed code.
This is a parsing word
|
Comments
Take:
Return:
This parses until the end of the line and ignores the parsed code.
This is a parsing word
This type of comment does not work in definitions
wsparse
Parse ahead until the next whitespace
Take:
Return: a #
Whitespace is either a space, tab, or EOL character
This is a parsing word
lnparse
Parse ahead until the end of the line
Take:
Return: a #
EOL can be a cr or lf character
This is a parsing word
>>
Shift right
Take: x y
Return:
<<
Shift left
Take:
Return:
here
Return the top of the heap
Take:
Return: a
h0 is a variable pointing to the top of the heap. So 'here' is the same as doing 'h0 @'
allot
Allocate memory on the heap
Take: x
Return:
cells
Convert a number of cells to the size in bytes
Take: x
Return: x*4
Cells are 4 bytes (a dword on x86) in size
cell+
Increase TOS by the size of a cell
Take: x
Return: x+4
later
Delay execution of a word until the caller finishes
Take:
Return:
This is tricky to learn, but a very powerful tool
exit,
Compile an exit instruction
Take:
Return:
create:
Create a new dictionary entry
Take:
Return:
Does a 'wsparse entry' to create the entry
This is a parsing word
variable
Create a variable
Take:
Return:
This creates a variable with an initial value of 0
This is a parsing word
variable:
Create a variable
Take: x
Return:
This creates a variable with an initial value of 'x'
This is a parsing word
rot
Rotate the stack
Take: x y z
Return: y z x
-rot
Rotate the stack twice
Take: x y z
Return: z x y
tuck
Tuck a copy of the TOS under the NOS
Take: ... x y
Return: ... y x y
over
Place a copy of the NOS over the TOS
Take: ... x y
Return: ... x y x
2drop
Drop the top two entries on the stack
Take: ... x y
Return: ...
2dup
Duplicate the top two entries on the stack
Take: ... x y
Return: ... x y x y
'
Obtain the address of a word
Take:
Return: a
This does not recognize macros
This is a parsing word
alias
Bind an address to a name
Take: a
Return:
Using this with loc: and ;loc allows localized factoring
This is a parsing word
execute
Execute the provided address
Take: a
Return:
The address is passed on the stack. No validation is performed, so be careful when using this
literal,
Compile a literal to HERE
Take: x
Return:
0;
Exit a word if the TOS is 0
Take: x
Return: x (if not zero, drops tos if it is 0)
This is often useful in loops
(loc)
Variable holding the address of 'last' during a loc: and ;loc pairing
Take:
Return: a
Not intended for use by words other than loc: and ;loc
loc:
Start a locally factored definition
Take:
Return:
;loc
End a locally factored definition
Take:
Return:
fill
Fill memory with a specified byte
Take:
Return:
move
Copy a region of memory from one location to another
Take:
Return:
pad
Return the address of the PAD
Take:
Return: a
>pad
Copy a string to the PAD
Take: a #
Return: a #
st0
Pointer to the top of the string space
Take:
Return: a
"
Create a temporary string
Take:
Return: a #
."
Display a string
Take:
Return:
$,
Copy a temporary string to the string buffer.
Take: a #
Return:
zt
Make a temporary zero-terminated string
Take: a #
Return: a
This replaces zt-make and zt-free from the 7.x series
cr
Next output will be on the next line
Take:
Return:
space
Display a space
Take:
Return:
.
Display a signed number
Take: n
Return:
u.
Display an unsigned number
Take: n
Return:
words
Display all currently defined words in the current dictionary
Take:
Return:
ok
The custom interpreter loop
Take:
Return: