SIMPLE Case statement 
Author Message
 SIMPLE Case statement

Have been reading the CASE arguments ... too deep for me.  Here's
something relating to SIMPLE in another sense.  Hope someone finds
this relevant.

Here's my version.  I can't comment
on standards since I don't use any.  But I have found this
structure quite flexible.  Maybe someone with standards-savy will too,
and can translate it.

( N ---> PRINTS DEPENDING ON NUMBER 'N')
: TESTIT
  OPTIONS
    DUP 3 <     ENDTEST  ." less than three" ENDEXEC
    4           TEST# DROP ." it's a four"   ENDEXEC
    5           TEST#D    ." you got five"   ENDEXEC
    DROP ." some number over 5"
  ENDOPTIONS ;

In the above definition, OPTIONS .... ENDOPTIONS define the
range of cases.  ENDTEST looks for a logical true.  It consumes
the top of stack, hence the DUP.  This leaves the item(s) tested
free for use between ENDTEST and ENDEXEC.

TEST# looks for a match between the number on stack and the
literal, preserving the TOS number -- because the TOS number might
be used for further processing.  This would be particularly true
if TEST# is closed out by ALLEXEC (see below).

TEST#D drops the TOS number if it matches the literal.
(I use TEST#D the most, since its value is usually not significant
 after the test.)

Other words I use are:

TILLTRUE ... jumps to ENDOPTIONS if it encounters "true".  No
               code executed after, so no ENDEXEC used.
               Works like ENDTEST ENDEXEC combined.
TILLFALSE .. jumps to ENDOPTIONS if it encounters "false", No
               code executed after, so no ENDEXEC used.
               Works like 0= ENDTEST ENDEXEC combined.
ALLEXEC .... continue on to next test if we arrive here.  Used
             instead of ENDEXEC.

Examples:

( ---> eat meal & return 1 if eaten, else 0)
: EAT-MEAL?
    0 ( flag: assume meal not eaten)
  OPTIONS
    DIRTY-PLATE?           TILLTRUE   ( don't eat)
    GOOD-LOOKING-WAITRESS? TILLFALSE  ( don't eat)
      SMILE ." Hi there"  ( complement waitress with smile)
    HUNGRY?                TILLFALSE  ( don't eat)
    NO-MONEY?       ENDTEST ." Sorry, gotta go!" CR ENDEXEC ( don't eat)
    ( -- we got through the tests ---)
    EXPENSIVE-MEAL? ENDTEST ." Ouch!" CR            ALLEXEC ( eat anyway)
  EAT-MEAL-NOW  ( we eat the meal)
      (  at this point we're sure meal was eaten)
      (  so we can switch the flag)
       DROP 1   ( indicate meal eaten)
       OPTIONS ( after we eat)
         SATISFIED?    ENDTEST ." BURP" BEEP     ALLEXEC
         STILL-HUNGRY? ENDTEST COMPLAIN-TO-OWNER ALLEXEC

          WINK-AT-WAITRESS
       ENDOPTIONS
  ENDOPTIONS ;

In the EAT-MEAL example, TILLTRUE and TILLFALSE execute
multiple tests & jump to the outer ENDOPTIONS if true or false is
returned from their corresponding XXX? words.

If EXPENSIVE-MEAL? is true, we print "Ouch" and continue
with the next test, instead of jumping to ENDOPTIONS.

After EAT-MEAL-NOW we use nested options with ALLEXEC.
"Burp" and COMPLAIN-TO-OWNER may be executed or not, each
based on its own test.  Granted, IF ... ENDIF
( sorry, IF ... THEN in now-standard Forth) could nave
been used here, but the ENDTEST or TEST#D... ALLEXEC sometimes
looks clearer if used, for example, to modify something for use
by the next test.

WINK-AT-WAITRESS will always be executed if we ate the meal and
could pay the bill.  Otherwise, we were too embarrassed from
having to wash dishes.

Options can be nested and combined any way they're needed.

( =====    the uncommented code ===== )
(  probably not anywhere near standard, but perhaps)
(  intelligible to some of you.)
(   BRANCH, 0BRANCH, (TEST#D) are all assy. code -- old FIG style)

( --- initiate set of options)
: OPTIONS 0 ; IMMEDIATE

( t/f --- if true execute code following, else branch past)
(         next ENDEXEC or ALLEXEC)
: ENDTEST COMPILE 0BRANCH HERE 0 , ; IMMEDIATE

( num1 num2 --->  compare Num1 & Num2.  If equal continue,)
(                otherwise branch to ENDEXEC or ALLEXEC)
(                Num2 is consumed, Num1 is left on stack)
: TEST# COMPILE OVER COMPILE = COMPILE 0BRANCH HERE 0 , ; IMMEDIATE

( num1 num2 --->  compare Num1 & Num2.  If equal continue,)
(                otherwise branch to ENDEXEC or ALLEXEC)
(                Num2 is consumed, Num1 is left on stack if)
(                not equal, otherwise both are consumed)
: TEST#D COMPILE (TEST#D) HERE 0 , ;   IMMEDIATE

( ---> Jumps to ENDOPTIONS)
: ENDEXEC COMPILE BRANCH HERE 0 , ; IMMEDIATE

( ---> Continue on to next test.  Close out option, but continue)
: ALLEXEC COMPILE BRANCH HERE 2 , ; IMMEDIATE

( t/f ---> if true, jump to ENDOPTIONS)
: TILLTRUE COMPILE 0= COMPILE 0BRANCH HERE DUP 0 , ; IMMEDIATE

( t/f ---> if false, jump to ENDOPTIONS)
: TILLFALSE COMPILE 0BRANCH HERE DUP 0 , ; IMMEDIATE

(  ---> end of OPTIONS structure)
: ENDOPTIONS HERE
   BEGIN OVER
   WHILE


        IF SWAP OVER - 2+ SWAP !
        ELSE
          DROP DROP
        ENDIF
   REPEAT DROP DROP ; IMMEDIATE

--
---------------------------------------------------------------------
Martel Firing                  

---------------------------------------------------------------------



Wed, 06 May 1998 03:00:00 GMT  
 SIMPLE Case statement

: TESTIT
      case  DUP 3 < IF DROP   ." less than three"
      ELSE  DUP 4 = IF DROP   ." it's a four"
      ELSE  5       of        ." you got five"
      ELSE  DROP    ." some number over 5"
      esac
;

: EAT-MEAL?
      0                           ( flag: assume meal not eaten)
      case
            DIRTY-PLATE?           IF   ( don't eat)
      ELSE
            GOOD-LOOKING-WAITRESS? 0= IF  ( don't eat)
      ELSE
            SMILE ." Hi there"  ( complement waitress with smile)
            HUNGRY?                0= IF  ( don't eat)
      ELSE
            NO-MONEY?       IF ." Sorry, gotta go!" CR ( don't eat)
      ELSE
            ( -- we got through the tests ---)
            EXPENSIVE-MEAL? IF ." Ouch!" CR THEN ( eat anyway)
            EAT-MEAL-NOW  ( we eat the meal)
            (  at this point we're sure meal was eaten)
            (  so we can switch the flag)
            DROP 1   ( indicate meal eaten)
            case
                  SATISFIED?    IF ." BURP" BEEP     THEN
                  STILL-HUNGRY? IF COMPLAIN-TO-OWNER THEN

            IF
                  WASH-DISHES
            ELSE
                  WINK-AT-WAITRESS
            esac
      esac
;



Wed, 06 May 1998 03:00:00 GMT  
 
 [ 2 post ] 

 Relevant Pages 

1. RFI: Simple CASE Statement

2. case statement flipflop statement

3. difference if statement with case statement?

4. [Fwd: Case statements, decision trees, and good OO design]

5. SUNOS NAWK - TOLOWER - In a print statement convert string to lower case

6. CASE STATEMENT

7. Case statements in parallel

8. Detecting Multiple Events (was: Case Statements...)

9. Case Statements...

10. Eaker CASE statement words ....

11. programatically add item to case statement

12. Controlling program flow and case statements

 

 
Powered by phpBB® Forum Software