Table of Contents

catch throw

sp@ ( – addr ) returns the address corresponding to the top of data stack.

rp@ ( – addr ) returns the address corresponding to the top of return stack.

sp! ( addr – ) sets the stack pointer to addr, thus restoring the stack depth to the same depth that existed just before addr was acquired by executing sp@.

rp! ( addr – ) sets the return stack pointer to addr. thus restoring the return stack depth to the same depth that existed just before addr was acquired by executing rp@.

Legend:

Step by step explanation of CATCH

variable handler \ Most recent exception handler

\                                    Put catchframe on return stack.
\                                    v  v
: CATCH ( xt -- exc# | 0 )               ( 1)  ( 2)
    sp@ >r         ( -- xt) ( RS: -- sp     )  ( 3)
    handler @ >r   ( -- xt) ( RS: -- sp hlr )  ( 4)
    rp@ handler !  ( -- xt) ( RS: -- sp hlr )  ( 5)
    execute        ( --   ) ( RS: -- sp hlr )  ( 6) 
    r> handler !   ( --   ) ( RS: -- sp     )  ( 7)
    r> drop        ( --   ) ( RS: --        )  ( 8)
    0              ( -- 0 )                    ( 9)  ;

Step by step explanation of THROW

\ TROW exits to saved context if exc# <> 0 
: THROW     ( i*x exc# -- i*x exc# | i*x exc# ) ( RS: -- sp hlr i*adr ) ( 1)
    dup 0=                 ( -- i*x exc# f  ) ( RS: -- sp hlr i*adr )   ( 2)
    if drop exit then      ( -- i*x         ) ( RS: -- sp hlr i*adr )   ( 3)
    handler @ rp!          ( -- i*x exc#    ) ( RS: -- sp hlr       )   ( 4) 
    r> handler !           ( -- i*x exc#    ) ( RS: -- sp           )   ( 5)
    r>                     ( -- i*x exc# sp ) ( RS: --              )   ( 6)
    swap                   ( -- i*x sp exc# ) ( RS: --              )   ( 7)
    >r                     ( -- i*x sp      ) ( RS: -- exc#         )   ( 8)
    sp!                    ( -- xt          ) ( RS: -- exc#         )   ( 9)
    drop r>                ( -- exc#        ) ( RS: --              )   ( 10) ;

Intended use is:

\ enable "spam" to THROW an exeption number in case of exeption.
: spam ( -- ) ... #exc THROW ;

\ put "spam" into exception handling frame using CATCH
: sapm-exc ( i*x -- )
  ...
  ['] spam CATCH  ( -- #exc )
  dup 0= IF drop exit then \ = NOOP
  dup #exc = IF
    ...  \ known error code, do execption handling 
  else
    ... throw  \ unknown error code; re-throw system code
  then ;            

( finis)