5

In Forth, is there a common word to conditionally exit a procedure (return) if the top of the stack is zero? I was thinking of using this in recursive procedures instead of IF.

Anthony
  • 410
  • 1
  • 4
  • 8

2 Answers2

5

There is a commonly implemented word called "?exit" which will exit if not zero. You will have to do:

0= ?exit

To get what you want. If your Forth lacks this, you can define it yourself, but it requires knowledge of the implementation details of the Forth to implement correctly strictly speaking. On most Forths however, the following code will work:

   : ?exit if rdrop exit then ;
   : ?exit if r> drop exit then ; ( if "rdrop" is not available )
   : -?exit 0= if rdrop exit then ; ( what you want )

Most Forth implementations just have a single value used for each function call, so this will work on the majority of them.

And a more portable version:

: ?exit postpone if postpone exit postpone then ; immediate
: -?exit postpone 0= postpone if postpone exit postpone then ; immediate

Although I have noticed not all Forth implementations have implemented "postpone", and may instead use a word like "[compile]".

howerj
  • 86
  • 5
  • The `?exit` exists in GNU Forth (`gforth`). :) – lurker Feb 20 '21 at 14:12
  • Some Forth systems keep locals on the return stack, and some use peephole optimization or auto inlining. In such cases this implementation does not work. It uses carnal knowledge. – ruvim Feb 22 '21 at 16:12
  • Concerning `postpone` word — without this word a Forth system cannot be compliant with Forth-1994 and later standards, since this word is a part of the [CORE word set](https://forth-standard.org/standard/core) that is [not optional](https://forth-standard.org/standard/usage). – ruvim Feb 23 '21 at 15:32
  • That doesn't stop many Forth implementations from not implementing it, there are far more Forth implementations that are not standards compliant than there are Forths that are. – howerj Feb 23 '21 at 15:43
2

A portable implementation:

: ?exit ( x -- ) postpone if postpone exit postpone then ; immediate
: 0?exit ( x -- ) postpone 0= postpone ?exit ; immediate

This implementation works on any standard Forth system.

ruvim
  • 7,151
  • 2
  • 27
  • 36
  • 2
    I've updated my answer to add this, because it is the accepted one, I should've added this in the beginning. Thanks. – howerj Feb 23 '21 at 13:21