Error conditions and other unexpected events are referred to as Exceptions in ICL. When such a condition is detected in direct mode a message is output. For example, if we enter a statement which results in an error
We get a message consisting of the name of the exception (SQUROONEG) and a description of the nature of the exception. A full list of ICL exceptions is given in appendix C.
If the error occurs within a procedure the message contains a little more information. As an example, if we use our square root procedure of Section 3.11 with an invalid value we get the following messages:
If one procedure is called by another, the second procedure will also be listed in the error message. If we run the following procedure
we get
It is often useful to be able to modify the default behaviour on an error condition. We may not want to output an error message and return to the ICL prompt, but rather to handle the condition in some other way. This can be done by writing an exception handler. Here is an example of an exception handler in the SQUARE_ROOT procedure.
Now running the TABLE procedure gives
The Exception handler has two effects. First the code contained in the exception handler is executed when the exception occurs. Second, the procedure exits normally to its caller (in this case TABLE) rather than aborting execution completely and returning to the ICL prompt.
Exception handlers are included in a procedure following the normal code of the procedure but before the END PROC statement. There may be any number of exception handlers in a procedure, each for a different exception. The exception handler begins with an EXCEPTION statement specifying the exception name, and finishes with an END EXCEPTION statement. Between these may be any ICL statements, including calls to other procedures.
An exception handler does not have to be in the same procedure in which the exception occurred, but could be in a procedure further up in the chain of calls. In our example we could put an exception handler for SQUROONEG in TABLE rather than in SQUARE_ROOT.
giving:
Below is an example of a pair of procedures which use an exception handler for floating point overflow in order to locate the largest floating point number allowed on the system. Starting with a value of 1 this is multiplied by 10 repeatedly until floating point overflow occurs. The highest value found in this way is then multiplied by 1.1 repeatedly until overflow occurs. Then by 1.01 etc.
One exception which is commonly encountered is that which results when a Control-C is entered on the terminal. This results in the exception CTRLC and may therefore be used to abort execution of a procedure and return ICL to direct mode. However, an exception handler for CTRLC may be added to a procedure to modify the behaviour when a control-C is typed.
The exceptions described up to now have all been generated internally by the ICL system, or in the case of CTRLC are initiated by the user. It is also possible for ICL procedures to generate exceptions, which may be used to indicate error conditions. This is done by using the SIGNAL command. This has the form
where name is the name of the exception, and text is the message text associated with the exception. The exception name may be any valid ICL identifier. Exceptions generated by SIGNAL work in exactly the same way as the standard exceptions listed in appendix C. An exception handler will be executed if one exists, otherwise an error message will be output and ICL will return to direct mode.
One use of the SIGNAL command is as a means of escaping from deeply nested loops. The BREAK statement can be used to exit from a single loop but is not applicable if two or more loops are nested. In these cases the following structure could be used
where the exception handler again contains no statements, but simply exists to cause normal procedure exit, rather than an error message when the exception is signalled.