I'm trying to reverse the stack using two loops one to send items from the data stack to return stack. And another to get them from return stack to data stack. Unfortunately, it doesn't work & gforth returns the stack underflow error. Below is the code:
: srev ( n n2 n3 n4 n5 -- n5 n4 n3 n2 n)
6 0 do >r loop
6 0 do r> loop ;
1 2 3 4 5 srev
The trouble you've got here is that DO ... LOOP
keeps the loop parameters (index and termination value) on the return stack and discards them at the end of the loop. That's why >R
and R>
must be in balanced pairs during a loop.
Your code puts a value on the return stack during the loop, which then gets discarded at the end of the loop, leaving a stray loop parameter still there and the whole thing goes haywire.
You can get the result you want like this ...
: REVERSE ( i*x i -- i*y ) 0 DO I ROLL LOOP ;
... though I'm a bit puzzled as to why you'd want to!
EDIT (after reading comments and ruvim's reply):
Your initial reversing the stack algorithm wouldn't have worked anyway, as a series of R>
s reverses the order onto the return stack, and the corresponding >R
s
reverses it again back to the parameter stack leaving the order as it was.
Alternative approach, similar to ruvim's but without recursion, is here
: APPLY ( n*x xt n -- n*x' )
DUP 1- -ROT ( n*x n-1 xt n )
0 DO ( n*x n-1 xt )
2>R \ park n-1 xt on return stack
2R@ DROP ROLL \ bring next item to top
2R@ NIP EXECUTE \ apply the function to it
2R> \ clear junk off return stack for now
LOOP ( n*x n-1 xt )
2DROP
;
It won't work (because of using ROLL
) with anything that affects the stack depth like DROP
or DUP
, but ' 2* 4 APPLY
works just fine!