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.
PROC SQUARE_ROOT X
{ An ICL procedure to print the square root of a number }
PRINT The Square Root of (X) is (SQRT(X))
EXCEPTION SQUROONEG
{ Handle the imaginary case }
SQ = SQRT(ABS(X))
PRINT The Square Root of (X) is (SQ&'i')
END EXCEPTION
END PROC
Now running the TABLE procedure gives
ICL> TABLE
The Square Root of 5 is 2.236068
The Square Root of 4 is 2
The Square Root of 3 is 1.732051
The Square Root of 2 is 1.414214
The Square Root of 1 is 1
The Square Root of 0 is 0
The Square Root of -1 is 1i
The Square Root of -2 is 1.414214i
The Square Root of -3 is 1.732051i
The Square Root of -4 is 2i
The Square Root of -5 is 2.236068i
ICL>
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 ICLException 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.
PROC TABLE
{ Print a table of Square roots from 5 down to -5 }
LOOP FOR I = 5 TO -5 STEP -1
SQUARE_ROOT (I)
END LOOP
EXCEPTION SQUROONEG
PRINT 'Can''t handle negative numbers - TABLE Aborting'
END EXCEPTION
END PROC
giving:
ICL> TABLE
The Square Root of 5 is 2.236068
The Square Root of 4 is 2
The Square Root of 3 is 1.732051
The Square Root of 2 is 1.414214
The Square Root of 1 is 1
The Square Root of 0 is 0
Can't handle negative numbers - TABLE aborting
ICL>
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.
PROC LARGE START, FAC, L
{ Return in L the largest floating point number before }
{ overflow occurs when START is repeatedly multiplied by FAC }
L = START
LOOP
L = L * FAC
END LOOP
EXCEPTION FLTOVF
{ This exception handler doesn't have any code - it just }
{ causes the procedure to exit normally on overflow }
END EXCEPTION
END PROC
PROC LARGEST
{ A Procedure to find the largest allowed floating point }
{ number on the system }
FAC = 10.0
LARGE 1.0,(FAC),(L)
LOOP WHILE FAC > 0.00000001
LARGE (L),(1.0+FAC),(L)
FAC = FAC/10.0
END LOOP
PRINT The largest floating point number allowed is (L)
END PROC
ICL The Interactive Command Language for ADAM