[ELSE] bracket-else TOOLS EXT


Perform the execution semantics given below.


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

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



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


: [ELSE] ( -- )
    1 BEGIN                                          \ level
       BEGIN BL WORD COUNT DUP WHILE                  \ level adr len
         2DUP S" [IF]" COMPARE 0= IF                  \ level adr len
             2DROP 1+                                 \ level'
          ELSE                                        \ level adr len
            2DUP S" [ELSE]" COMPARE 0= IF             \ level adr len
                2DROP 1- DUP IF 1+ THEN               \ level'
            ELSE                                      \ level adr len
                S" [THEN]" COMPARE 0= IF              \ level
                   1-                                 \ level'
          THEN ?DUP 0= IF EXIT THEN                   \ level'
       REPEAT 2DROP                                   \ level
   REFILL 0= UNTIL                                   \ level


MitchBradleyavatar of MitchBradley [54] [ELSE] without preceding [IF]Comment2018-05-13 18:36:50

There has been some discussion around the use of [ELSE] .. [THEN] without a preceding [IF]

As the culprit responsible for ANS Forth's [IF] [ELSE] [THEN], I can state that omitting [IF] was not one of my goals, and I don't recall even considering the possibility.

That said, I think it's nice that it happens to work, and it certainly seems useful, if a bit surprising to the naive user.

StephenPelcavatar of StephenPelc

The idea that IF ... ELSE ... THEN can morph to ELSE ... THEN is repulsive.

For [ELSE] ... [THEN] it's an artefact of the implementation. Implementation artefacts have no place in a standard.

JennyBrienavatar of JennyBrien

It's a natural consequence of the spec, and slightly more elegant than the common 0 [IF] but it will break if you ever put an [IF] in front.

StephenPelcavatar of StephenPelc

We (MPE) use [IF] and friends a great deal to configure cross-compiled targets. We noticed that [IF] ... [ELSE] ... [THEN] is unchecked, so we recently implemented a check at the end of each source file to see if we actually use it correctly. Oops! Lots of errors. So [ELSE] without [IF] is a total no no for us. It's amusing that it works, but let's just leave it that way.

GerryJacksonavatar of GerryJackson

I've only just realised that comments on this topic were here. Here is a post I made on the Yahoo Forth 200X group on 13 May copied here for completeness.

I've just realised what you were probably referring to with the [ELSE] ... [THEN]. That is specifically tested in the toolstest.fth file.I'd be surprised if it occurred in any other file.

That is just testing [ELSE] as written in the standard and I don't see any reason to remove it unless the specification for [ELSE] is rewritten to forbid it. Another silly thing is tested, [THEN] is a noop, so a lone [THEN] is valid and tested.

There are other dubious things tested in the test suite e.g. in coreplustest.fth multiple ELSE's in IF statements are tested e.g. ... IF...ELSE ... ELSE... ELSE...THEN ... which is perfectly valid standard Forth according to the specification for ELSE.

I believe test programs should test what's written in the standard, corner cases and sillinesses as well as usual usage.

BerndPaysanavatar of BerndPaysan

Add to the Rationale:

An isolated [ELSE] ... [THEN] will skip the code up to the [THEN]. Wrapping this later into an [IF] ... [THEN] will break that, so don't do that.

Reply New Version

StephenPelcavatar of StephenPelc [74] [if] and [else] parse white space - including commentsRequest for clarification2019-02-08 15:23:02

What is supposed to happen for

0 [if] text text \ [else] words [then]

In many systems WORDS will be executed. This surprises users because [else] is commented out. If this is the expected behaviour, then at the very least some clarification is required. I have sympathy with my user's surprise.


BerndPaysanavatar of BerndPaysan

We had that in Gforth, but removed it, because it was too smart. Example: postpone (. You can't really know what some Forth code actually does unless you actually interpret it, which the [ELSE] scanner doesn't.

\ The following was too smart for its own good; consider "postpone (".
\ Moreover, ANS Forth specifies that the next [THEN] ends an [IF]
\ (even if its in a '( ... )').

\ ' ( Alias (                          immediate ( keep fontify happy)
\ ' \ Alias \                          immediate

Yes, if I uncomment these two aliases, you can comment out an [ELSE].

AntonErtlavatar of AntonErtl

The specification of [IF] is clear:

parse and discard space-delimited words from the parse area [...], until either the word [ELSE] or the word [THEN] has been parsed and discarded.

So \ and ( and everything else except [ELSE] and [THEN] will just be discarded (with [IF] increasing a nesting counter in addition). No clarification for \ needed in the normative text. If you think that users need a clarification, you can put it in your system's documentation, in a contribution here, or you can propose a change to the Rationale of [IF], [ELSE], and/or [THEN]

GerryJacksonavatar of GerryJackson

When 0 [IF] is scanning for [ELSE] then a string containing [IF] [ELSE] or [THEN] will cause a problem e.g.

0 [if] s" [else] or [then] follow [if]"

will either underflow due to the OR or fail to recognise FOLLOW (unless FOLLOW is defined. of course).

Reply New Version

ruvavatar of ruv [121] Case-sensitivity independent implementationSuggested reference implementation2019-10-03 14:30:28

If a Forth system can optionally turn on case-insensitivity, it does not affect by default [IF] ... [ELSE] ...[THEN] control structure in the provided reference implementation. The following implementation variant obeys the system's case sensitivity mode.

: [IF]   ( level1 -- level2 ) 1+ ;
: [ELSE] ( level1 -- level2 ) DUP 1 = IF 1- THEN ;
: [THEN] ( level1 -- level2 ) 1- ;

: [ELSE] ( -- )

: [THEN] ( -- ) ; IMMEDIATE

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

tolichavatar of tolich

I LOVE this implementation not because of its case sensitivity awareness. You can define any parsing words in addition to [IF] [THEN] [ELSE] thus to avoid them in commentaries, string literals, etc.


You got the idea. It must be in the standard.

BerndPaysanavatar of BerndPaysan

We accepted your improved reference implementation 10/0/0.

Reply New Version

rrtavatar of rrt [134] Reference implementation does not seem to cope with changes to the stackRequest for clarification2020-04-10 23:20:57

I just noticed, having used the reference implementation of [IF]/[ELSE]/[THEN] in my own Forth system, that it keeps markers on the data stack, and hence does not work correctly if you write e.g. 1 [IF] 2 [ELSE] 3 [THEN]. I have stared at the standard text, and it does not seem to forbid this usage; also I see that e.g. GForth makes use of [IF]...[ELSE]....[THEN] to put values on the stack in exactly this way (and GForth has its own rather different implementation.

Assuming I've not misunderstood something here, could a warning about this limitation be added to the reference implementation until such time as it is improved?

rrtavatar of rrt

This is my misreading, and an unfortunate combination of circumstances in my own code that caused me to leap to this conclusion. So please delete my previous query!

GeraldWodniavatar of GeraldWodni

Closed as withdrawn.

Reply New Version