chitselb wrote:
Things are progressing with PETTIL in spurts and starts, working toward a 1.0 release with a huge project coming in right behind it.
What would you call it? I am in need of a decent name for something case-like, and contemplating a design like this:
Code:
somewhere in the middle of some user code secondary word...
45F3 04 42 ; `helicopter`
45F5 E0 0F ; `@`
45F7 80 1A ; `+@EXECUTE`
; +@EXECUTE gets its arguments inline
45F9 05 ; number of cases
45FA E2 44 ; <-- 0/default various things that happen
45FC F6 44 ; <-- 1 for values 0..4 (CFA table)
45FE 03 45 ; <-- 2
4600 18 45 ; <-- 3
4602 C6 45 ; <-- 4
4604 B6 09 ; `dup` execution resumes here at NEXT
code for +@EXECUTE
1A80 20 F4 10 ; jsr enter
1A82 40 0B ; `2*` cfa
1A84 ... add tos*2 to ip, fetch the CFA there, execute that word,
add (2 * number of cases + 1) to IP and resume execution.
The IP trace at NEXT for the above example would look like:
45F3 45F5 45F7
4518 (assumes there was `3` stored in `helicopter` variable)
4604 4606 <-- we arrive here after `dup` executes
I dislike calling it `+@execute` but haven't come up with something better, or found a similar thing. PETTIL does have `?:` which works like IF/ELSE/THEN but only takes up 6 bytes per use, with the restriction that true/false options are limited to executing a CFA. This word does a thing like that, but with potentially more than two branches.
Since it looks like a mini case statement, you could call it
CASE# ( or
#CASE ), but how did you plan to use it? Like this?
Code:
... HEICOPTER @ CASE# [ 5 C, ] WORD0 WORD1 WORD2 WORD3 WORD4 DUP ...
If that's the case, ( no pun intended ) here is a suggestion. You could name it
(CASE#) or something you find more suitable and define some high level helper words
CASE[ and
]END-CASE.
CASE[ would compile
(CASE#) and reserve one byte of memory for the number of cases, leaving the address to be patched on the data stack.
]END-CASE would count the number of words compiled after
(CASE#) and do the patching. NOTE: I'm away from my desktop computer, which has the VICE Commodore simulator, so I haven't been able to test this yet.
Code:
// FOR SYSTEM WITH 16 BIT ADDRESSES LIKE PET AND C64
: CASE[ ( -- ADR ) COMPILE (CASE#) HERE 0 C, ; IMMEDIATE
: ]END-CASE ( ADR -- ) HERE OVER - 1- 2/ SWAP C! ; IMMEDIATE
The intervening words would be compiled normally so it would be used like this:
Code:
... HELICOPTER @ CASE[ WORD0 WORD1 WORD2 WORD3 WORD4 ]END-CASE DUP ...
Hope this helps.
BTW If you change
(CASE#) so instead of an inline count, it uses an inline address to branch past the different cases,
CASE[ and
]END-CASE become easier to define:
Code:
: CASE[ ( -- ADR ) COMPILE (CASE#) HERE 0 , ; IMMEDIATE
: ]END-CASE ( ADR -- ) HERE SWAP ! ; IMMEDIATE
Or with a little compiler security ( just to make sure
STATE is compiling ).
Code:
: CASE[ ( -- ADR CS.NUMBER ) COMPILE (CASE#) >MARK ; IMMEDIATE
: ]END-CASE ( ADR CS.NUMBER -- ) >RESOLVE ; IMMEDIATE
]END-CASE becomes an alias for
THEN in this last example. IIRC you were trying to keep the size down. To define fewer words:
Code:
: CASE# ( -- ADR CS.NUMBER ) COMPILE (CASE#) >MARK ; IMMEDIATE
And it would use
THEN to resolve the address:
Code:
... HELICOPTER @ CASE# WORD0 WORD1 WORD2 WORD3 WORD4 THEN DUP ...
Wether you use any of this or not, I hope it gives you food for thought.
Cheers,
Jim