GA144 note: stack node

A node can function as a dedicated push-down stack for a client. A few words of code are taken up by the stack functions, leaving up to 61 words as stack.

The stack node S uses a register to point to the stack top, and the stack grows down through memory. The b register of both nodes points to the other. The client can pop an item with:

@p !b @b !+ !p

Pushing an item is more complicated, so a subroutine on S is needed. From the client, pushing a value is:

@p !b !b @p call Rpush

On S, the subroutine Rpush must decrement a, then store the given value:

: Rpush @p a . + -1 a! ! ;

This is a 3 word program, so the total available storage is 61 words. At initialization a should be zero, for an empty stack.

To support dual stacks -- as in Forth's D and R stacks -- the node can keep one stack pointer in a and the other in T. Swapping a and T is:

a over a!

The subroutines to push and pop from the second stack, Dpush and Dpop are:

: Dpush a over a! \ switch to D stack call Rpush a over a! ; : Dpop a over a! \ switch to D stack !+ !b \ pop and send to client a over a! ;

With this 9 word program ( Rpush , Dpush` and Dpop ), the client can do the four operations.

Pushing on R:

@p !b !b @p call Rpush

Popping from R:

@p !b @b !+ !p

Pushing on D:

@p !b !b @p call Dpush

Popping from D:

@p !b @b call Dpop

Querying the D stack pointer value (as part of Forth's DEPTH word):

@p !b @b dup !p

The total storage is 64 words, so 27 words are available for each stack. To set up the two pointers for empty stacks, a should be zero and T* should be 36.