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 [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 2018-05-14 23:43:04

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 2018-05-15 08:09:08

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 2018-05-15 14:49:07

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 2018-06-10 19:02:54

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.


StephenPelcavatar of StephenPelc [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 2019-02-15 18:51:47

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 2019-02-16 07:59:01

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 2019-02-16 11:49:51

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).