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.