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: