Home > Previous Page >  CASE construct by George Beckett
Archive Search  

CASE construct by George Beckett.

A new implementation of a CASE construct for the ACE. Original based from the version in Personal Computing World March 1984.
Its a new working version many thanks to George Beckett.

The code below is fully commented and is worth reading for a full understanding of how the FORTH code works on the Jupiter ACE.

A TAP/TZX file can be found here (CRC-32 57AB8211).




( CASE CONSTRUCT FOR JUPITER ACE / MINSTREL 4TH )
(                                               )
( ORIGINALLY PRINTED IN PERSONAL COMPUTER       )
( WORLD, MARCH 1985. IMPLEMENTATION TWEEKED BY  )
( GEORGE BECKETT, SEPT 2020, TO REMOVE          )
( POTENTIAL BUG.                                )
(                                               )
( SYNTAX:                                       )
( CASE                                          )
(   xx OF ... ENDOF                             )
(   xx OF ... ENDOF 				)
(   OTHERWISE ... 				)
( ENDCASE     					)
(                                               )
( NOTES: 					)
( - CAN BE LISTED, EDITED, AND REDEFINED.       )
( - MUST HAVE 'OTHERWISE' CLAUSE.		)
( - ERROR 5, IF SYNTAX ERROR.			)
( - CASE STATEMENTS MAY BE NESTED, SUBJECT TO   )
(   RESPECTING SYNTAX                           )

( CHECK SYNTAX GUIDES MATCH )
: ?PAIRS ( M N -- )
  = 0= ( ARE THEY NOT EQUAL? )
  IF
    ." ERROR 5" CR ABORT ( ABORT COMPILATION, IF NOT EQUAL )
  THEN
;

0 COMPILER CASE
  0 ( MARKER ON STACK, USED BY ENDCASE TO CHECK DONE )
  9 ( SYNTAX GUIDE, MUST MATCH WITH 'OF' )
RUNS>
  DROP ( NOTHING TO DO EXCEPT DROP ADDR OF PARAMETER FIELD )
;

2 COMPILER OF
  9 ?PAIRS ( CHECK PRECEDED BY CASE OR ENDOF )
  HERE ( SAVE CURRENT DICTIONARY LOCATION FOR ENDOF )
  0 , ( RESERVE TWO BYTES AT THAT LOCATION )
  7 ( SYNTAX GUIDE, MUST MATCH WITH 'ENDOF' )
RUNS>
  >R ( SAVE PARAMETER-FIELD ADDR )
  OVER = ( CHECK FOR MATCH WITH CASE VALUE, PRESERVING COPY OF INPUT )
  R> ( RECOVER PARAMETER-FIELD ADDR )
  SWAP ( BRING MATCH RESULT BACK TO TOP OF STACK )
  IF ( INDICATES MATCH )
    DROP DROP ( DROP PARAMETER-FIELD ADDR AND INPUT, AS DONE )
  ELSE
    @ ( RETRIEVE OFFSET TO NEXT 'OF' FROM PARAMETER FIELD )
    R> + >R ( ADVANCE TO NEXT 'OF' STATEMENT )
  THEN
;

( IF SYNTAX IS CORRECT, TOS = 7 AND 2OS = PARAM FIELD OF 'OF'
2 COMPILER ENDOF
  7 ?PAIRS ( CHECK PRECEDED BY 'OF' )
  HERE ( PUT CURRENT DICTIONARY LOCATION ON STACK )
  SWAP ( SWAP WITH ADDRESS OF PARAM FIELD FOR 'OF' )
  0 , ( RESERVE TWO BYTES IN DICTIONARY )
  OVER OVER - ( WORK OUT OFFSET FROM 'OF' TO 'HERE' )
  SWAP ! ( STORE IN PARAMETER FIELD OF 'OF' )
  9 ( SYNTAX GUIDE, MUST MATCH TO 'OF' OR 'OTHERWISE' )
RUNS>
  @ ( RETRIEVE OFFSET TO JUST AFTER 'ENDCASE' FROM PARAMETER FIELD )
  R> + 4 - >R ( APPLY TO RETURN ADDRESS, NEED TO BACKTRACK BY 4 )
;

0 COMPILER OTHERWISE
  9 ?PAIRS ( CHECK PRECEDED BY 'CASE' OR 'ENDOF' )
  8 ( SYNTAX GUIDE, MUST MATCH WITH 'ENDCASE' )
RUNS>
  DROP DROP ( DROP PARAMETER-FIELD ADDR AND INPUT, AS DONE )
;

0 COMPILER ENDCASE
  8 ?PAIRS ( CHECK PRECEDED BY 'OTHERWISE' )
  BEGIN
    ?DUP ( IF PARAMETER-FIELD ADDRESS NON-ZERO, DUPLICATE )
  WHILE ( OTHERWISE, ALL DONE )
    HERE OVER - ( WORK OUT OFFSET )
    SWAP ! ( STORE IN PARAMETER FIELD OF 'ENDOF' )
  REPEAT ( DO FOR EACH 'ENDOF' )
RUNS>
  DROP ( DROP PARAMETER FIELD, AS DONE )
;

: SILLY ( EXAMPLE USE OF CASE )
  CASE
    1 OF CR ." NUMBER ONE!" CR ENDOF
    6 OF CR ." NUMBER SIX!" CR ENDOF
    40 OF CR ." NUMBER FORTY!" CR ENDOF
    OTHERWISE CR ." NOT 1, NOT 6, NOT 40!" CR
  ENDCASE

  ." The end of a pointless word."

  CR
;