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.
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
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.
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.
ruv 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.
WORDLIST DUP CONSTANT BRACKET-FLOW-WL GET-CURRENT SWAP SET-CURRENT : [IF] ( level1 -- level2 ) 1+ ; : [ELSE] ( level1 -- level2 ) DUP 1 = IF 1- THEN ; : [THEN] ( level1 -- level2 ) 1- ; SET-CURRENT : [ELSE] ( -- ) 1 BEGIN BEGIN PARSE-NAME DUP WHILE BRACKET-FLOW-WL SEARCH-WORDLIST IF EXECUTE DUP 0= IF DROP EXIT THEN THEN REPEAT 2DROP REFILL 0= UNTIL DROP ; IMMEDIATE : [THEN] ( -- ) ; IMMEDIATE : [IF] ( flag -- ) 0= IF POSTPONE [ELSE] THEN ; IMMEDIATE
rrt 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?