Code: Select all
: PAUSE ( -- F )
?KEY DUP IF
DUP 3 <> IF
DROP KEY THEN
3 = THEN
;Yes, but I like the factoring where both THEN's are one after the other followed by the semicolon. I'll show why.
In Fleet Forth it's ( -- c | 0 ) because that is what the C64 kernal supports.
PAUSE is the name of Fleet Forth's task switcher (which is set to a no-op when not multitasking), so I'm just going to call this word DONE? , which is what it is called in Fleet Forth.
Code: Select all
: DONE? ( -- F )
?KEY ?DUP
IF
3 <>
IF KEY 3 = ELSE TRUE THEN
ELSE
FALSE
THEN ;
Notice the ELSE clause at the end of the word?
Code: Select all
ELSE
FALSE
THEN ;
If ?DUP is replaced with DUP , that clause is no longer needed.
Code: Select all
: DONE? ( -- F )
?KEY DUP
IF
3 <>
IF KEY 3 = ELSE TRUE THEN
THEN ;
In my ITC Forth, this saves 3 cells.
The next improvement is a little harder to see.
3 <> is equivalent to 3 = 0=
At first glance, this doesn't seem to save memory. if ?DUP is inserted between = and 0= the final ELSE clause is no longer needed.
Code: Select all
: DONE? ( -- F )
?KEY DUP
IF
3 = ?DUP 0=
IF KEY 3 = THEN
THEN ;
A savings of another cell.
Fleet Forth also has the primitives ?EXIT and 0EXIT .
Both consume the top stack item.
?EXIT exits the word if the top stack item is TRUE (any non-zero value).
0EXIT exits the word if the top stack item is zero.
Using these two words, some more memory savings can be had, as well as a performance boost. Both IF's branch to the exit at the end of the word. They can both be replaced with 0EXIT and the THEN's removed.
Code: Select all
: DONE? ( -- F )
?KEY DUP
0EXIT
3 = ?DUP 0=
0EXIT KEY 3 = ;
A little reformatting.
Code: Select all
: DONE? ( -- F )
?KEY DUP 0EXIT
3 = ?DUP 0= 0EXIT
KEY 3 = ;
Finally, 0= 0EXIT can be replaced with ?EXIT
Code: Select all
: DONE? ( -- F )
?KEY DUP 0EXIT
3 = ?DUP ?EXIT
KEY 3 = ;