On Sun, Jul 17, 2016 at 08:21:58PM +0100, Mark Cave-Ayland wrote:
+: >r state @ if ['] >r , exit then r> swap prstack-push >r ; immediate +: r> state @ if ['] r> , exit then r> prstack-pop swap >r ; immediate +: r@ state @ if ['] r@ , exit then r> prstack-pop dup prstack-push swap >r ; immediate
Btw, why do you need those r> ... smth ... >r gymnastics?
Hrm, okay, coffee helps thinking... Could use some documenting ;-)
As you've already worked out, the reason is that : calls the primitive docol which always pushes the caller onto the r-stack when calling another Forth word. Hence there's an extra parameter on the r-stack that needs to be juggled to make sure the >r primword and the resulting parameter are placed back correctly on the r-stack.
Regarding the documentation, I wasn't too worried about this since it's fairly obvious that calling another word is going to involve another r-stack push from the caller (and indeed it was the first thing that stood out when I tried your code in the debugger).
It surprises me every. single. time.
If you would like to suggest something suitable in a maximum of a couple of lines you think would help then I don't mind adding it in a v2, however compared to other undocumented gotchas in the Forth code I've come across whilst working on OpenBIOS this was very easy to figure out so I can't get too excited about it.
\ WARNING: Deep magic ahead!
Segher