JimBoyd wrote:
Has anyone else implemented an extra stack ( or more) in Forth? How did it affect your programming?
Well... now I have. I ended up with:
Code:
( Auxiliary Stack - 2020-10-05 SamCoVT )
( Based on 6502.org discussion. License: CC0 )
( Create the stack. AUXTOS points to just *after* TOS )
CREATE AUXSTACK 16 CELLS ALLOT
VARIABLE AUXTOS AUXSTACK AUXTOS ! ( Start with empty stack. )
: .AS ( Print the aux stack in Tali2 format )
( Print <#items> at the beginning. )
." <" AUXTOS @ AUXSTACK - 1 CELLS /
0 <# #S #> TYPE ( Number with no trailing space )
." > "
( Print the stack values with TOS on the right. )
AUXSTACK ( Start at the bottom of the stack. )
BEGIN DUP AUXTOS @ < WHILE
DUP @ . 1 CELLS + ( Print and move up the stack. )
REPEAT DROP ;
: >A ( S: n A: -- S: A: n )
AUXTOS @ ! 1 CELLS AUXTOS +! ;
: A> ( S: A: n -- S: n A: )
AUXTOS @ AUXSTACK = IF
." AUXSTACK EMPTY"
ELSE
-1 CELLS AUXTOS +! AUXTOS @ @
THEN ;
: A@ ( S: A: n -- S: n A: n )
AUXTOS @ AUXSTACK = IF
." AUXSTACK EMPTY"
ELSE
AUXTOS @ 1 CELLS - @
THEN ;
: DUP>A ( S: n A: -- S: n A: n )
DUP >A ;
: 2>A ( S: d A: -- S: A: d )
SWAP >A >A ;
: 2A> ( S: A: d -- S: d A: )
A> A> SWAP ;
I've tested this on Tali2 and Gforth and it looks like it works. I learned the following unrelated things about forth in the process:
>= isn't a standard word?!?! Once I realized I was printing my stack backards, I also discovered that I didn't need this word and < would do just fine. I'm not sure how I didn't run into this before.
. prints a space after the number. If you don't want that, you get to learn about <# and #S and #>
I think this will be handy for when I'm working on a new word that uses >R and R> and R@, like in JimBoyd's example, and I want to try it out a line at a time. I especially like how .AS lets you see what's going on in the pretend return stack. I don't know as I'll use it outside of this use case, but it certainly looks handy for debugging words that use the return stack.
Edit - uppercased all of the forth words in the code for readability