[IF]

Compilation:

Perform the execution semantics given below.

Execution:

( flag | flag "<spaces>name ..." -- )

If flag is true, do nothing. Otherwise, skipping leading spaces, parse and discard space-delimited words from the parse area, including nested occurrences of [IF] ... [THEN] and [IF] ... [ELSE] ... [THEN], until either the word [ELSE] or the word [THEN] has been parsed and discarded. If the parse area becomes exhausted, it is refilled as with REFILL. [IF] is an immediate word.

An ambiguous condition exists if [IF] is POSTPONEd, or if the end of the input buffer is reached and cannot be refilled before the terminating [ELSE] or [THEN] is parsed.

See:

Rationale:

Typical use: ... flag [IF] ... [ELSE] ... [THEN] ...

Implementation:

: [IF] ( flag -- )
   0= IF POSTPONE [ELSE] THEN
; IMMEDIATE

ContributeContributions

ruvavatar of ruv POSTPONE [IF]Request for clarification2019-07-10 14:52:51

Why does an ambiguous condition exist if [IF] is POSTPONEd? And why does not it spread to[ELSE]?

What can be wrong with:

: [UNLESS] 0= POSTPONE [IF] ; IMMEDIATE

JennyBrienavatar of JennyBrien

[IF] ... [ELSE] ... [THEN] can be nested, in which case subsequent [IF]s all paste to a matching [THEN].

Consider what happens when [UNLESS] is placed within an [IF] ... [THEN] block.

AntonErtlavatar of AntonErtl

As far as I can see, the standard clearly specifies that [UNLESS] does not work as intended in the not-taken branch of an [IF], so this case may be worth a discussion in the rationale, but its not something where implementations would diverge. I just tried the following code on Gforth, SwiftForth, VFX, and iForth:

: [unless] 0= postpone [if] ; immediate 0 [if] 0 [unless] [else] .( t) [then]

and they all had the same behaviour (output "t"). It's unclear to me why the ambiguous condition exists.

ruvavatar of ruv

Yes, such [UNLESS] construction will break an outer [IF]. But it nothing to do with the possible ambiguity of POSTPONE [IF]. For example, the following definition is equivalent, has the same issue, but without any ambiguous condition:

: [UNLESS] ( flag -- ) IF POSTPONE [ELSE] THEN ; IMMEDIATE

As a contrived example, we can just redefine [IF] to count its top-level occurrences:

VARIABLE cnt  cnt 0!
VARIABLE lvl  lvl 0!

: [IF] ( flag -- )
  lvl @ 0= IF cnt 1+! THEN lvl 1+!
  POSTPONE [IF] lvl 1-!
; IMMEDIATE

This code works always correctly. Perhaps it is just a mistake that POSTPONE [IF] was specified as an ambiguous condition.

ruvavatar of ruv

Well, the example counts not only the top-level [IF]s. But it is beyond the discussed problem.

BerndPaysanavatar of BerndPaysan

I, (on behalf of the TC) suggest to remove the ambiguous condition, and change the rationale, to add information that defining some new [UNLESS] scanning words by just postponing [IF], [ELSE] or [THEN] is not enough. You also need to add the new word [UNLESS] to the scanner inside [IF], so that nesting works. That might be possible in high quality implementations, but it is outside the scope of this standard.

Reply New Version

AntonErtlavatar of AntonErtl Input values other than true and falseProposal2020-01-11 12:07:07

This contribution has been moved to the proposal section.

KrishnaMyneniavatar of KrishnaMyneni

This reply has been moved to the proposal section.

alextangentavatar of alextangent

This reply has been moved to the proposal section.

gnuarmavatar of gnuarm

This reply has been moved to the proposal section.

KrishnaMyneniavatar of KrishnaMyneni

This reply has been moved to the proposal section.

BerndPaysanavatar of BerndPaysan

This reply has been moved to the proposal section.

KrishnaMyneniavatar of KrishnaMyneni

This reply has been moved to the proposal section.

gnuarmavatar of gnuarm

This reply has been moved to the proposal section.

AntonErtlavatar of AntonErtl

This reply has been moved to the proposal section.
Accepted
Reply New Version