Friday, July 07, 2017

CASE-Based Control Structures

Eaker's CASE structure is at heart a set of  IF ... ELSE clauses that are resolved at a common point. That's a generally useful thing to have, but it is too specialised. ENDCASE not only does the resolving, but drops an item from the stack, and OF may not (in Standard code) be paired with ELSE/THEN nor IF with ENDOF/ENDCASE. Some FORTHS have ?OF to perform the function of IF in that context.

But it's fairly easy to remove those restrictions for a particular Forth.

The simplest example assumes that the control stack is the data stack and that THEN does some stack-checking to ensure it is paired correctly:

 0 CONSTANT CASE IMMEDIATE 
: OF   POSTPONE OVER POSTPONE = POSTPONE IF POSTPONE DROP ;        IMMEDIATE
    : ENDOF  POSTPONE ELSE ; IMMEDIATE

    : END  BEGIN ?DUP WHILE POSTPONE THEN REPEAT DROP ; IMMEDIATE 
          
    : ENDCASE   POSTPONE DROP POSTPONE END ; IMMEDIATE



That is perfectly Standard, but also allows you to avoid writing multiple adjacent THENs


        Nested conditions:    CASE ... IF   ... IF  ... IF  do-this END
     
        and alternatives:       CASE   ... IF do-this ELSE
                         ... IF do-that ELSE
                                do-other END
        are much clearer.

It also allows this technique for combining multiple tests in one flag while ensuring that none are executed needlessly:

     CASE 
         ... TRUE OF
         ... FALSE OF
         ... END IF

TRUE OF  is an and-if' -  if the test is false the rest of the block need not be tested, 
                     and a FALSE flag is returned

FALSE OF  is an or-if' -  if the test is true the rest of the block need not be tested, 
                     and a TRUE flag is returned.

That's not a bad result for the addition of one new word. 

Next time: Integrating Iteration.