wmb@MITCH.ENG.SUN.COM (Mitch Bradley) (08/05/90)
> Well, thanks to Mitch Bradley, I now have an implementation of CATCH and > THROW to look at... Now I have a question to pose to the net... > How are they exactly used? I get the general idea of it but I'd like to > be told the exact behavior so I don't make any wrong assumptions in thier use > as I intend to implement them in the Forth kernels I have source on hand for... I'll address this issue after I comment on your other point... > BTW- Whomever it was who said that he could count all the successful Forth > projects on one hand a while back, had better look around again... Actually, I believe it was me that made this point. As I recall, though, I was not talking about successful applications, but instead about portable Forth programs (ones that run with little or no modification on a variety of different Forth implementations from different vendors). There are indeed a number of successful Forth programs, and I can name numerous others beyond the ones you listed. On the other hand, there are relatively few portable Forth programs in the sense that I am speaking of. In contrast, there are literally hundreds of portable C programs that have been posted to various networks, encompassing everything from games to spreadsheets to editors to utilities to you name it. I did not mean to imply that Forth cannot be used to write successful programs (on the contrary, my Forth-based boot firmware is shipping on the largest-selling Unix workstation in the industry; over 100,000 have been sold to date). I meant to imply that present Forth standards are missing features that are necessary to write many popular classes of program, e.g. file access and floating point. Many Forth implementations include those features, but their lack of prior standardization prevents the use of such features from being portable. Now, back to the real issue of CATCH/THROW. If you intend to put it in your kernel (which is an excellent thing to do), the best way is to hook it into ABORT and QUIT . For example: : ABORT ( -- ) 1 THROW ; : (ABORT") ( flag -- ) IF <print in-line string> ABORT ELSE <skip in-line string> THEN ; \ In F-PC, ABORT and ABORT" are factored differently. F-PC implements \ (ABORT") in terms of a deferred word ERROR? . The default implementation \ of ERROR? , named (?ERROR) , could be modified to use THROW instead of \ QUIT as follows: : (?ERROR) ( addr len f -- ) IF PRINTING OFF SPACE TYPE SPACE 1 THROW ELSE 2DROP THEN ; ... \ The following implementation of QUIT will probably work for F-PC; \it was written by looking at the F-PC source code for QUIT, but has \ not been tested (however, similar code is known to work on other systems). : INTERACT ( -- ) BEGIN STATUS QUERY RUN STATE @ NOT UNTIL ; : QUIT ( -- ) \ Derived from the F-PC version SP0 @ 'TIB ! BEGIN [COMPILE] [ ['] INTERACT CATCH IF ." Aborted" ELSE ." ok" THEN CR AGAIN ; Several things to note: 1) The use of CATCH/THROW eliminates the need to clear the data stack in ABORT" ; CATCH/THROW automatically restores the data stack depth to its original state, which presumably is "empty" when QUIT is first called. 2) This simplifies the implementation of (?ERROR) by eliminating the following code: 2>R SP0 @ SP! 2R> 3) The use of CATCH/THROW eliminates the need to clear the return stack in QUIT ; CATCH/THROW automatically restores the return stack to the correct value. 4) With ABORT implemented in terms of THROW instead of calling QUIT , the one previously-unavoidable forward reference in the kernel source code is eliminated. 5) All this goes a long way toward making it possible to recursively call the text interpreter! Left to do: save and restore the contents of TIB and >IN , add a controlled exit from the BEGIN .. AGAIN loop in QUIT . The controlled exit could even be done using CATCH/THROW , e.g. CREATE DONE-SIGNAL : DONE DONE-SIGNAL THROW ; : QUIT ( -- ) SAVE-OLD-TIB BEGIN [COMPILE] [ ['] INTERACT CATCH ( 0 or error-code) CASE 0 OF ." ok" FALSE ENDOF DONE-SIGNAL OF ." Exiting" TRUE ENDOF ( error# ) ." Aborted." FALSE SWAP ENDCASE CR UNTIL RESTORE-TIB ; Mitch Bradley