SamCoVT wrote:
I just wanted to point out that forth-standard.org has reference implementations (for the Forth 2012 standard) for many words. You might be interested in their [IF]/[ELSE]/[THEN] implementation as they did it a little differently, but also handle nested [IF]s. Their [IF] is very short and all of the work is done in [ELSE]. [THEN] is an empty word, just like in your implementation.
https://forth-standard.org/standard/tools/BracketIFhttps://forth-standard.org/standard/tools/BracketELSEhttps://forth-standard.org/standard/tools/BracketTHENThese are just example reference implementations. You're welcome to solve things your own way, of course - that's part of the fun of using Forth!
Well look at that! This was my first attempt with [ELSE] and I was thinking it looked a LOT like [IF]. Just needed to think about it more. Mine also handles nested [IF]s, I just use the return stack to track the nesting level, I wasn't too sure about other interactions using the data stack. So, with simplified [IF]...
Code:
: [THEN] ; IMMEDIATE ( PLACE HOLDER TO RESUME EXECUTION )
DEFER [ELSE] ( SKIP UNTIL [THEN] IF EXECUTED )
: [IF] ( F -- )
NOT IF ( SKIP CODE IN BETWEEN [ELSE] OR [THEN] )
[ELSE]
THEN
; IMMEDIATE
:NONAME ( [ELSE] )
1 >R
BEGIN
BL WORD FIND IF
CASE
' [ELSE] OF
R@ 1 = IF ( RESUME EXECUTING AT MATCHING [ELSE] )
R> DROP DROP EXIT
THEN
ENDOF
' [THEN] OF
R> 1- ?DUP 0= IF ( EXIT AT FINAL [THEN] )
DROP EXIT
THEN
>R
ENDOF
' [IF] OF ( CHECK FOR NESTED [IF] )
R> 1+ >R
ENDOF
ENDCASE
ELSE
DROP
THEN
AGAIN
; IMMEDIATE IS [ELSE]
What I don't understand is why they POSTPONED the [ELSE] in the reference implementation of [IF]. Still one of those things I don't quite get.
[edit] Ah, I think I get it - [ELSE] is IMMEDIATE. Since mine was DEFERed, it doesn't show up as IMMEDIATE until IS, otherwise it would have been executed during compilation of [IF]
I suppose I should also switch over to string compares instead of the dictionary search - no need to DEFER in that case.