9.6.1.0875 CATCH EXCEPTION
Push an exception frame on the exception stack and then execute the execution token xt (as with EXECUTE) in such a way that control can be transferred to a point just after CATCH if THROW is executed during the execution of xt.
If the execution of xt completes normally (i.e., the exception frame pushed by this CATCH is not popped by an execution of THROW) pop the exception frame and return zero on top of the data stack, above whatever stack items would have been returned by xt EXECUTE. Otherwise, the remainder of the execution semantics are given by THROW.
See:
Implementation:
SP@
- ( -- addr )
returns the address corresponding to the top of data 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 executingSP@
. RP@
- ( -- addr )
returns the address corresponding to the top of return stack. 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 executingRP@
.
: CATCH ( xt -- exception# | 0 \ return addr on stack
SP@ >R ( xt ) \ save data stack pointer
HANDLER @ >R ( xt ) \ and previous handler
RP@ HANDLER ! ( xt ) \ set current handler
EXECUTE ( ) \ execute returns if no THROW
R> HANDLER ! ( ) \ restore previous handler
R> DROP ( ) \ discard saved stack ptr
0 ( 0 ) \ normal completion
;
HANDLER
variable should be in
the per-task variable area (i.e., a user variable).
This sample implementation does not explicitly handle the case in which CATCH has never been called (i.e., the ABORT behavior). One solution would be to execute a CATCH within QUIT, so that there is always an "exception handler of last resort" present, as shown in E.6.1.2050 QUIT.
Testing:
ContributeContributions
GerryJackson [97] The specification of CATCH Request for clarification2019-07-19 14:52:07
The specification for CATCH states:
"Push an exception frame on the exception stack and then execute the execution token xt (as with EXECUTE) in such a way that control can be transferred to a point just after CATCH if THROW is executed during the execution of xt."
Given: ' ' CATCH foo [if] : foo 1234 . ; foo [then]
where foo
is undefined. My system displays 1234
(as do GForth,SwiftForth, VFX Forth and Win32 Forth)
The 'undefined word' exception doesn't return to just after CATCH
. This is also true if the word executed by CATCH
parses the rest of the line.
This behaviour seems reasonable to me. Either the specification should be reworded or the above 5 systems are non-compliant. Which is it?