Forth/Manipulating the Stack

The Parameter Stack

A data structure common to many languages is the stack. A LIFO (last-in first-out) type of stack called the parameter stack (to distinguish it from the return stack) is frequently the implied source and destination for many of the data and arithmetic operations performed in FORTH.

Typical operations will find their input parameters on the stack, usually remove (pop) these inputs, and then place the new results back onto the stack (push).

While FORTH has variables, arrays, strings, and other data structures, the use of the stack is combined with the philosophy of the language to achieve a variety of advantages.

  • If a piece of code only uses the stack for its inputs, outputs, and intermediate values, it is inherently re-entrant in almost every case.
  • If a piece of code maintains stack parity, that is, neither removes or abandons values on the stack between its beginning and end, then a call to it can be inserted anywhere in a body of code.
  • The stack is like a switchyard that can get data to and from anywhere. Data can be switched between all parts of the system by reading it or writing it to the top element of the stack.
  • Op codes do not need to use bits to specify register values, instead, two RISC machine style instructions are used in sequence, analagous to LOAD then ADD. These simpler instructions allow efficient implementation.

When you type a number, it goes on the stack. When you type several numbers, they all go on the stack, with the most-recent number on the top of the stack. For example, immediately after typing 7 22 -8 14 9 and hitting ENTER, the stack appears like this:

            cell #   contents
              0         9        (TOS) 
              1        14        (NOS) 
              2        -8 
              3        22
              4         7

Many programmers document a word using a stack diagram, with two "pictures" of the stack (with the TOS furthest to the right), before and after the word executes.

SWAP ( ... a b -- ... b a )

DROP ( ... x y z -- ... x y )

DUP ( ... x y z -- ... x y z z )

ROT ( ... a b c d -- ... a c d b )