Stack Manipulation
The Forth language is based on the concept of a stack.
A D V E R T I S E M E N T
Imagine a stack of
blocks with numbers on them. You can add or remove numbers from the top of the
stack. You can also rearrange the order of the numbers. Forth uses several
stacks. The DataStack is the one used for passing data between Forth
words so we will concentrate our attention there. The Return Stack is
another Forth stack that is primarily for internal system use. In this tutorial,
when we refer to the "stack," we will be referring to the Data Stack.
The stack is initially empty. To put some numbers on the stack, enter:
23 7 9182
Let's now print the number on top of the stack using the Forth word ' .
', which is pronounced " dot ". This is a hard word to write about in a manual
because it is a single period.
Enter: .
You should see the last number you entered, 9182 , printed. Forth has a very
handy word for showing you what's on the stack. It is .S , which is
pronounced "dot S". The name was constructed from "dot" for print, and "S" for
stack. (PForth will automatically print the stack after every line if the
TRACE-STACK variable is set to TRUE.) If you enter:
.S
you will see your numbers in a list. The number at the far right is the one on
top of the stack.
You will notice that the 9182 is not on the stack. The word ' . ' removes the
number on top of the stack before printing it. In contrast, ' .S ' leaves the
stack untouched.
We have a way of documenting the effect of words on the stack with a stack
diagram. A stack diagram is contained in parentheses. In Forth, the
parentheses indicate a comment. In the examples that follow, you do not need to
type in the comments. When you are programming, of course, we encourage the use
of comments and stack diagrams to make your code more readable. In this manual,
we often indicate stack diagrams in bold text like the one that follows.
Do not type these in. The stack diagram for a word like ' . ' would be:
. ( N -- , print number on top of stack )
The symbols to the left of -- describe the parameters that a word expects to
process. In this example, N stands for any integer number. To the right of --,
up to the comma, is a description of the stack parameters when the word is
finished, in this case there are none because 'dot' "eats" the N that was passed
in. (Note that the stack descriptions are not necessary, but they are a great
help when learning other peoples programs.)
The text following the comma is an English description of the word. You will
note that after the -- , N is gone. You may be concerned about the fact that
there were other numbers on the stack, namely 23 and 7 . The stack diagram,
however, only describes the portion of the stack that is affected by the word.
For a more detailed description of the stack diagrams, there is a special
section on them in this manual right before the main glossary section.
Between examples, you will probably want to clear the stack. If you enter
0SP, pronounced "zero S P", then the stack will be cleared.
Since the stack is central to Forth, it is important to be able to alter the
stack easily. Let's look at some more words that manipulate the stack. Enter:
0SP .S \ That's a 'zero' 0, not an 'oh' O.
777 DUP .S
You will notice that there are two copies of 777 on the stack. The word DUP
duplicates the top item on the stack. This is useful when you want to use the
number on top of the stack and still have a copy. The stack diagram for DUP
would be:
DUP ( n -- n n , DUPlicate top of stack )
Another useful word, is SWAP. Enter:
0SP
23 7 .S
SWAP .S
SWAP .S
The stack diagram for SWAP would be:
SWAP ( a b -- b a , swap top two items on stack )
Now enter:
OVER .S
OVER .S
The word OVER causes a copy of the second item on the stack to leapfrog
over the first. It's stack diagram would be:
OVER ( a b -- a b a , copy second item on stack )
Here is another commonly used Forth word:
DROP ( a -- , remove item from the stack )
Can you guess what we will see if we enter:
0SP 11 22 .S
DROP .S
Another handy word for manipulating the stack is ROT. Enter:
0SP
11 22 33 44 .S
ROT .S
The stack diagram for ROT is, therefore:
ROT ( a b c -- b c a , ROTate third item to top )
You have now learned the more important stack manipulation words. You will
see these in almost every Forth program. I should caution you that if you see
too many stack manipulation words being used in your code then you may want to
reexamine and perhaps reorganize your code. You will often find that you can
avoid excessive stack manipulations by using local or global VARIABLES
which will be discussed later.
If you want to grab any arbitrary item on the stack, use PICK . Try
entering:
0SP
14 13 12 11 10
3 PICK . ( prints 13 )
0 PICK . ( prints 10 )
4 PICK .
PICK makes a copy of the Nth item on the stack. The numbering starts with zero,
therefore:
0 PICK is equivalent to DUP
1 PICK is equivalent to OVER
PICK ( ... v3 v2 v1 v0 N -- ... v3 v2 v1 v0 vN )
(Warning. The Forth-79 and FIG Forth standards differ from the ANS and Forth
'83 standard in that their PICK numbering starts with one, not zero.)
I have included the stack diagrams for some other useful stack manipulation
words. Try experimenting with them by putting numbers on the stack and calling
them to get a feel for what they do. Again, the text in parentheses is just a
comment and need not be entered.
DROP ( n -- , remove top of stack )
?DUP ( n -- n n | 0 , duplicate only if non-zero, '|' means OR )
-ROT ( a b c -- c a b , rotate top to third position )
2SWAP ( a b c d -- c d a b , swap pairs )
2OVER ( a b c d -- a b c d a b , leapfrog pair )
2DUP ( a b -- a b a b , duplicate pair )
2DROP ( a b -- , remove pair )
NIP ( a b -- b , remove second item from stack )
TUCK ( a b -- b a b , copy top item to third position )
|