Forth stack operators

Jump to: navigation, search

Forth has a set of primitive words which are used to reorder data on the stacks. They are similar to the register move assembly instructions found in microprocessor instruction sets. A goal of a good Forth programmer is to minimize the use of these words, since they are only moving data around instead of doing useful work. Reference implementations for the less basic operators are also given.

dup   ( a -- a a )
?dup  ( a -- a a | 0 ) dup if dup then ;
drop  ( a -- )
swap  ( a b -- b a )
over  ( a b -- a b a )
rot   ( a b c -- b c a )
-rot  ( a b c -- c a b ) rot rot ;
nip   ( a b -- b ) swap drop ;
tuck  ( a b -- b a b ) swap over ;

There are a few operators which move data between the data stack and the return stack. This can be useful for stashing data away temporarily in order to work on data deeper on the stack, or to make a single unnamed local variable. Use of these words must be balanced within a definition, since the return stack is also used for return addresses. Also, stashing data on the return stack cannot cross into a DO-LOOP construct, since the loop index is stored on the return stack.

>r    ( a -- R: a )
r>    ( R: a -- a )
r@    ( R: a -- a R: a )

Most of these operators also have a double-cell form with a "2" prefix, where the same operation is performed on pairs of cells. This is useful for operating on double-cell data, such as strings and double precision numbers. 2dup is often used for doing binary tests, for example ( a b ) 2dup > if swap then .

2dup  ( a b -- a b a b ) over over ;
2drop ( a b -- ) drop drop ;

Pick and Roll are the generic operators which treat the data stack as an array. If you find you need to use them, you are probably doing it wrong. Look for ways to refactor your code to be simpler instead.

pick ( a0 .. an n -- a0 .. an a0 )
roll ( a0 .. an n -- a1 .. an a0 )
// examples: reimplement primitives
: dup  0 pick ;
: over 1 pick ;
: swap 1 roll ;
: rot  2 roll ;

There are also stack debugging aids in Open Firmware. .s will print the current contents of the stack, and showstack changes the prompt to show the top items of the stack between each command.

clear ( [s] -- )
depth ( a1 .. an -- a1 .. an n )
.s    ( [s] -- [s] )