OEP

163

Title

EXCEPTION TYPEs extensions

Summary

Provides a basic per-process exception mechanism for occam-pi

Owner

Fred Barnes <F.R.M.Barnes@kent.ac.uk>

Status

Proposed

Date-Proposed

2007-11-27

Last-Modified

2007-11-28

Keywords

language exceptions

The occam-pi language currently provides no mechanisms for exception handling, such as that found in Java and C++. This OEP describes a new exception handling mechanism for occam-pi, that works on single processes.

Exceptions exist in their own type-space, defined by "EXCEPTION TYPE"s. These may carry zero or more sub-types, for example:

   1 EXCEPTION TYPE EX.FOO:
   2 EXCEPTION TYPE EX.BAR IS INT, MOBILE []BYTE:

The extra information, where present, provides data carried with the exceptions.

In keeping with exception mechanisms in other languages, the occam-pi exception mechanism uses "TRY", "CATCH" blocks (and additionally, a "FINALLY" block). Exceptions that have additional data must have that data stored locally when handling the exception. For example:

   1 TRY
   2   SEQ
   3     do.something ()
   4     do.something.else ()
   5   CATCH
   6     EX.FOO
   7       out.string ("failed with FOO!*n", 0, scr!)
   8     INT v:
   9     MOBILE []BYTE d:
  10     EX.BAR v, d
  11       SEQ
  12         out.string ("failed with BAR: ", 0, scr!)
  13         out.string (d, 0, scr!)
  14         scr ! '*n'
  15   FINALLY
  16     out.string ("do some cleanup*n", 0, scr!)

To throw an exception:

   1 IF
   2   error1
   3     THROW EX.FOO
   4   TRUE
   5     THROW EX.BAR 42, "all okay!"

The FINALLY block is potentially necessary in the case where an existing CATCH block propagates an exception by throwing it again. For example:

   1 TRY
   2   do.stuff ()
   3   CATCH
   4     EX.FOO
   5       THROW EX.BAR 0, "got foo"
   6   FINALLY
   7     do.local.cleanup ()

In the case where "do.stuff()" throws an "EX.FOO" exception, caught in the above code, the FINALLY block will be executed before the "EX.BAR" exception is thrown.

Uncaught exceptions are propagated, but will execute code in FINALLY blocks as they do so. This provides a straightforward way of having (typically cleanup) code executed as an exception propagates through. For example:

   1 TRY
   2   SEQ
   3     local.initialise ()
   4     do.some.stuff ()
   5   FINALLY
   6     local.cleanup ()

Exceptions, as defined here, may not propagate across process boundaries. This includes "PAR" and "FORKING" structures, and "FORK"ed processes. Or looking at it another way, exceptions are restricted to sequential processes only. Additionally, exceptions may not cross "FUNCTION" call boundaries (as they are a side effect in any process calling that function).

In the implementation, the compiler will be explicitly aware of what PROCs throw which exceptions, and will use this information to ensure that the above rules are adhered to.

The exception mechanism here also provides a way of specifying a block of code through which no exceptions may propagate (that may be useful in certain situations). This is specified with "NOEXCEPTIONS", either as a structured block of code, or as a tag on a "PROC" definition. For example:

   1 NOEXCEPTIONS
   2   SEQ
   3     do.stuff ()
   4     do.other.stuff ()

and:

   1 PROC delta (CHAN INT in?, out0!, out1!) NOEXCEPTIONS
   2   ...  body of delta
   3 :

The semantics of exception throwing are one of communication.

OEP/163 (last edited 2007-11-28 07:13:32 by frmb)