Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!rutgers!mit-eddie!genrad!decvax!tektronix!uw-beaver!tikal!bobc From: bobc@tikal.UUCP Newsgroups: comp.lang.modula2 Subject: Re: Exception handling anyone? Message-ID: <623@tikal.UUCP> Date: Wed, 11-Feb-87 13:56:09 EST Article-I.D.: tikal.623 Posted: Wed Feb 11 13:56:09 1987 Date-Received: Sat, 14-Feb-87 04:37:13 EST References: <354@esunix.UUCP> Reply-To: bobc@tikal.UUCP (Bob Campbell) Organization: Teltone Corp., Kirkland, WA Lines: 124 Summary: I would like to see a much more involved discussion on how to implement exceptions in the language as it exists now. I feel that something useful can be worked out. So I hope to inspire some creative discussion by submitting the following exception handling module. I have not yet had the chance to implement it, but I feel that all but the last three routines can be implemented in the language as it exists now, with out adding any new features. The last three routines are mostly the "C" setjmp/longjmp, or the LISP catch/throw, I used the LISP names to set them apart from the "C" routines. I believe that about a year ago someone else proposed something of this form, but I can't find the article. I also admit that there are some advantages to implementing the constructs in the language it's self. They mostly relate to scoping for example: With my module you could write: IMPORT StringOverFlow; (* An EXCEPTION defined and set up else where *) ... BEGIN ... Handle(StringOverFlow,MyHandler); ...call some string routines that use StringOverFlow... FreeHandler(StringOverFlow); ... With a Ada you could write: -- StringOverFlow is defined else where and imported USE/WITH??? begin ...call some strings routines that use StringOverFlow... exception when StringOverFlow => if not MyHandler(StringOverFlow) then raise; end if; end ...; I feel that both implementations do the same work, however the Ada method does many things automaticly for you based on the nesting factor. It in effect automaticly calls FreeHandler when you exit the current block. This note is getting a little bit long, so I will stop and let people flame at me as per usual. Then when I know what the complaints are I will correct/defend myself. Bob Campbell Teltone Corporation 18520 - 66th AVE NE P.O. Box 657 Seattle, WA 98155 Kirkland, WA 98033 bobc@tikal.teltone.com {amc,dataio,fluke,hplsla,sunup,uw-beaver}!tikal!bobc tikal!bobc@beaver.cs.washington.EDU Module Exceptions.DEF included below: -------------------------------------------------------------- DEFINITION MODULE Exceptions; TYPE EXCEPTION; ExceptionHandler = PROCEDURE (EXCEPTION):BOOLEAN; (* A exception handler is passed the exception as a argument * so that it can find out (via comparing) what exception was * caught *) PROCEDURE NewException(VAR X:EXCEPTION;DefaultHandler:ExceptionHandler); (* Create a new exception with a default handler * Should a default handler be do nothing or halt? *) (* Some optional Default handlers *) PROCEDURE Ingore(VAR X:EXCEPTION):BOOLEAN; (* always returns true causes exception to be ingored *) PROCEDURE Abort(VAR X:EXCEPTION):BOOLEAN; (* always calls HALT *) PROCEDURE Handle(X:EXCEPTION;Handler:ExceptionHandler); (* Set up a handler this pushes the previous handler onto a * Stack so that when FreeHandler is called it reverts to the * previous Handler. *) PROCEDURE FreeHandler(X:EXCEPTION); (* frees up the current handler, if the current handler is the * default handler nothing happens. *) PROCEDURE Raise(X:EXCEPTION); (* call the handlers for the passed exception. The handlers are * called in reverise order until one of the handlers return TRUE * to indicate that it has handled the exception. *) (* Now onto the optional low level routines a type of setjmp/longjmp * as in C, but I desided to use the LISP function names Catch, and * Throw *) TYPE Ball; (* Lets play catch with the ball :-) :-) *) (* This might be too cute a name :-) :-) *) PROCEDURE Catch(VAR what:Ball):BOOLEAN; (* This function returns TRUE when it is thrown to, FALSE * when it is first set up *) PROCEDURE Throw(what:Ball); (* jumps to that last call to Catch for this "Ball" restores * that stack frame, and causes it to apear that Catch returned * true *) PROCEDURE FreeCatcher(VAR what:Ball); (* sets up the Ball such that attempting to Throw it will cause * a halt *) END Exceptions.