Quote:
It does require CASE nesting. I can dimly see a way to make that happen.
My ideas for the structures came mostly from Forth which allows endless nesting as long as you don't run out of data stack space during compilation (which would be hard to do on a 6502). It also adds "compiler security" which stops you if you have unmatched pairs, for example an OF...END_OF interrupted by an IF in an incomplete IF structure. That requires stack space too, where the OF puts a compiler-security number on the stack, and the END_OF compares to make sure it's the right one. If it sees the one for IF instead, it gives the error message.
What I did in the assembler macros mimics what I did in my '816 Forth kernel except that the CASE statement in macros uses its own variables instead of taking a ton of assembler stack space, which I figured would be fine since I've never needed to nest CASE statements. I did not go to the extent of the "compiler security" in my macros (would that be called "assembler security"? hmmm...maybe it needs a better name), but so far I have not had any errors in that department, mostly I suppose because the indentation keeps them straight, and because the assembler prohibits having more than one instruction or macro per line anyway.
What you could do if you want to nest CASE structures is to have CASE put a number on the assembler stack which is the initialized number of cases, and then each case that is encountered increments that number. This number keeps getting moved to the top of the stack so that END_CASE knows how deep to go in the stack as it collects addresses to fill in with the end-of-structure address for each END_OF to jump to.
It has been argued that the internals of the CASE structure could use a mass of nested IF structures, which is true, but doing it that way in Forth it's not as efficient in either speed or memory as having true CASE-structure internals. But for assembly, I can't think of any differences right now.
Other accompanying words you might be interested in are RANGE_OF and SET_OF. I haven't done them in macros yet since that would really escalate the internal complexity and they're not often needed, but here's an example of the usage: Suppose you have various cases that are an individual number, but then one case is a
range of numbers, and another case is a special
set of numbers that don't particularly meet a function you could spell out; so you have for example:
Code:
CASE
CASE_OF 1
bla bla bla
bla bla bla
END_OF
CASE_OF 2
bla bla bla
bla bla bla
END_OF
RANGE_OF 3 to 11
bla bla bla
bla bla bla
END_OF
SET_OF {13, 16, 20, 25, 33, 151} ; The list can be constants, expressions to be evaluated at assembly time, etc..
bla bla bla
bla bla bla
END_OF
default actions used for
any case not specified above
END_CASE