1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
= Nickle Exceptions
Nickle has first-class exceptions for error handling and quick escapes
from recursive algorithms. A number of exceptions are builtin to
Nickle that it throws for various errors, including:
`exception uninitialized_value(string msg)`::
Attempt to use an uninitialized value.
`exception invalid_argument(string msg, int arg, poly val)`::
The argument with index `arg` to a builtin function had invalid value `val`.
`exception readonly_box(string msg, poly val)`::
Attempt to change the value of a read-only quantity to `val`.
`exception invalid_array_bounds(string msg, poly a, poly i)`::
Attempt to access array `a` at index `i` is out of bounds.
`exception divide_by_zero(string msg, real num, real den)`::
Attempt to divide `num` by `den` when `den` is zero.
`exception invalid_struct_member(string msg, poly str, string name)`::
Attempt to refer to member `name` of the object `str`, which does
not exist.
`exception invalid_binop_values(string msg, poly arg1, poly arg2)`::
Attempt to evaluate a binary operator with arguments `arg1` and
`arg2`, where at least one of these values is invalid.
`exception invalid_unop_values(string msg,poly arg)`::
Attempt to evaluate a unary operator with invalid argument `arg`.
The following syntax may be used to declare a new exception:
`exception` _name_ `(` _type_ _name_ `,` ... `)`
For example,
----
exception my_exception ( string msg, int a, int b, int c );
----
== Raise
`raise` _name_ `(` _value_ `,` ... `)`
Raises the named exception with the given arguments, e.g.
----
raise my_exception ( "message", 0, 1, 2 );
----
Execution is broken and `my_exception` travels up the stack until it
is caught by a try-catch block or it reaches the top level, where it
prints an error message such as:
----
Unhandled exception "my_exception"
3
2
1
"message"
----
== Try - catch
`try` _statement_ +
`catch` _name_ `(` _type_ _name_ `,` ... `)` _statement_
`try` executes `statement`; if it raises an exception whose name
matches that of a succeeding `catch` block, the arguments are placed
in the names specified and the associated `statement-list` is
executed. Control continues after the catch without continuing up the
stack; if further propagation is desired, `statement-list` should
re-raise the exception. Any number of catch blocks may be associated
with a try statement. For example:
----
exception my_exception(string msg,int a,int b,int c);
try raise my_exception("blah",1,2,3);
catch my_exception(string msg,int a,int b,int c) {
printf("%s: exception successfully caught (%d,%d,%d).\n",msg,a,b,c);
}
----
This example tries to execute a function that raises an exception;
since that exception matches the catch block, "blah", 1, 2, and 3 (the
arguments) are put into `msg`, `a`, `b`, and `c` and the statement
list is executed, which in this case merely prints out the arguments
received and continues:
----
blah: exception successfully caught (1,2,3).
----
== Twixt
`twixt (` _expr_enter_ `;` _expr_leave_ `)` _statement_
Nickle does not provide a `finally` clause to a `try-catch`. In order
to ensure the order of some expressions, it provides `twixt` (See the
section on Statements). For example,
----
exception my_exception(string msg, int a, int b, int c);
void foo(string msg, int a, int b, int c) {
twixt(printf("entering twixt..."); printf("leaving twixt.\n"))
raise my_exception(msg, a, b, c);
}
try foo("blah", 1, 2, 3);
catch my_exception(string msg,int a,int b,int c) {
printf("%s: exception successfully caught (%d,%d,%d).\n",msg,a,b,c);
}
----
Will produce the output:
----
entering twixt...leaving twixt.
blah: exception successfully caught (1,2,3).
----
Notice the order of the printed messages: `twixt` finished up before
the exception was handled by the `catch`. This is an elegant way to
accomplish something that should be done finally, in this case
printing the message `leaving twixt` for demonstration.
|