Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,3 @@
---
from: http://rosettacode.org/wiki/Exceptions/Catch_an_exception_thrown_in_a_nested_call
note: Control Structures

View file

@ -0,0 +1,12 @@
Show how to create a user-defined exception   and   show how to catch an exception raised from several nested calls away.
:#   Create two user-defined exceptions,   '''U0'''   and   '''U1'''.
:#   Have function   '''foo'''   call function   '''bar'''   twice.
:#   Have function   '''bar'''   call function   '''baz'''.
:#   Arrange for function   '''baz'''   to raise, or throw exception   '''U0'''   on its first call, then exception   '''U1'''   on its second.
:#   Function   '''foo'''   should catch only exception   '''U0''',   not   '''U1'''.
<br>
Show/describe what happens when the program is run.
<br><br>

View file

@ -0,0 +1,20 @@
T U0 {}
T U1 {}
F baz(i)
I i == 0
X U0()
E
X U1()
F bar(i)
baz(i)
F foo()
L(i) 0..1
X.try
bar(i)
X.catch U0
print(Function foo caught exception U0)
foo()

View file

@ -0,0 +1,56 @@
MODE OBJ = STRUCT(
INT value,
STRUCT(
STRING message,
FLEX[0]STRING args,
PROC(REF OBJ)BOOL u0, u1
) exception
);
PROC on u0 = (REF OBJ self, PROC (REF OBJ) BOOL mended)VOID:
u0 OF exception OF self := mended;
PROC on u1 = (REF OBJ self, PROC (REF OBJ) BOOL mended)VOID:
u1 OF exception OF self := mended;
PRIO INIT = 1, RAISE = 1;
OP INIT = (REF OBJ self, INT value)REF OBJ: (
value OF self := value;
u0 OF exception OF self := u1 OF exception OF self := (REF OBJ skip)BOOL: FALSE;
args OF exception OF self := message OF exception OF self := "OBJ Exception";
self
);
OP RAISE = (REF OBJ self, PROC (REF OBJ) BOOL mended)VOID:
IF NOT mended(self) THEN
put(stand error, (message OF exception OF self+" not caught - stop", new line));
stop
FI;
PROC (REF OBJ)VOID bar, baz; # early declaration is required by the ALGOL 68RS subset language #
PROC foo := VOID:(
FOR value FROM 0 TO 1 DO
REF OBJ i = LOC OBJ INIT value;
on u0(i, (REF OBJ skip)BOOL: (GO TO except u0; SKIP ));
bar(i);
GO TO end on u0;
except u0:
print(("Function foo caught exception u0", new line));
end on u0: SKIP
OD
);
# PROC # bar := (REF OBJ i)VOID:(
baz(i) # Nest those calls #
);
# PROC # baz := (REF OBJ i)VOID:
IF value OF i = 0 THEN
i RAISE u0 OF exception OF i
ELSE
i RAISE u1 OF exception OF i
FI;
foo

View file

@ -0,0 +1,21 @@
:Namespace Traps
⍝ Traps (exceptions) are just numbers
⍝ 500-999 are reserved for the user
U0 U1900 901
⍝ Catch
foo;i
:For i :In 2
:Trap U0
bar i
:Else
'foo caught U0'
:EndTrap
:EndFor
⍝ Throw
bar i
⎕SIGNAL U0 U1[i]
:EndNamespace

View file

@ -0,0 +1,31 @@
with Ada.Text_Io; use Ada.Text_Io;
procedure Exceptions_From_Nested_Calls is
U0 : exception;
U1 : exception;
Baz_Count : Natural := 0;
procedure Baz is
begin
Baz_Count := Baz_Count + 1;
if Baz_Count = 1 then
raise U0;
else
raise U1;
end if;
end Baz;
procedure Bar is
begin
Baz;
end Bar;
procedure Foo is
begin
Bar;
exception
when U0 =>
Put_Line("Procedure Foo caught exception U0");
end Foo;
begin
for I in 1..2 loop
Foo;
end loop;
end Exceptions_From_Nested_Calls;

View file

@ -0,0 +1,41 @@
void
baz(integer i)
{
error(cat("U", itoa(i)));
}
void
bar(integer i)
{
baz(i);
}
void
foo(void)
{
integer i;
i = 0;
while (i < 2) {
text e;
if (trap_d(e, bar, i)) {
o_form("Exception `~' thrown\n", e);
if (e != "U0") {
o_text("will not catch exception\n");
error(e);
}
}
i += 1;
}
o_text("Never reached.\n");
}
integer
main(void)
{
foo();
return 0;
}

View file

@ -0,0 +1,24 @@
global U0 := Exception("First Exception")
global U1 := Exception("Second Exception")
foo()
foo(){
try
bar()
catch e
MsgBox % "An exception was raised: " e.Message
bar()
}
bar(){
baz()
}
baz(){
static calls := 0
if ( ++calls = 1 )
throw U0
else if ( calls = 2 )
throw U1
}

View file

@ -0,0 +1,30 @@
foo()
Return
foo()
{
bar(0)
If InStr(ErrorLevel, "U0")
MsgBox caught error: U0
bar(1)
If InStr(ErrorLevel, "U0")
MsgBox caught error: U0
}
bar(i)
{
StringReplace, ErrorLevel, ErrorLevel, baz_error, , All ; clear baz_error(s)
If !baz(i)
ErrorLevel .= "baz_error" ; add baz_error to errorstack
}
baz(i)
{
StringReplace, ErrorLevel, ErrorLevel, U1, , All ; clear U1 errors
StringReplace, ErrorLevel, ErrorLevel, U0, , All ; clear U0 errors
If i
ErrorLevel .= "U1" ; add U1 errors to errorstack
Else
ErrorLevel .= "U0"
Return 1
}

View file

@ -0,0 +1,26 @@
REM Allocate error numbers:
U0& = 123
U1& = 124
PROCfoo
END
DEF PROCfoo
ON ERROR LOCAL IF ERR = U0& THEN PRINT "Exception U0 caught in foo" ELSE \
\ RESTORE ERROR : ERROR ERR, REPORT$
PROCbar
PROCbar
ENDPROC
DEF PROCbar
PROCbaz
ENDPROC
DEF PROCbaz
PRIVATE called%
called% += 1
CASE called% OF
WHEN 1: ERROR U0&, "Exception U0 thrown"
WHEN 2: ERROR U1&, "Exception U1 thrown"
ENDCASE
ENDPROC

View file

@ -0,0 +1,28 @@
#include <iostream>
class U0 {};
class U1 {};
void baz(int i)
{
if (!i) throw U0();
else throw U1();
}
void bar(int i) { baz(i); }
void foo()
{
for (int i = 0; i < 2; i++)
{
try {
bar(i);
} catch(U0 e) {
std::cout<< "Exception U0 caught\n";
}
}
}
int main() {
foo();
std::cout<< "Should never get here!\n";
return 0;
}

View file

@ -0,0 +1,32 @@
using System; //Used for Exception and Console classes
class Exceptions
{
class U0 : Exception { }
class U1 : Exception { }
static int i;
static void foo()
{
for (i = 0; i < 2; i++)
try
{
bar();
}
catch (U0) {
Console.WriteLine("U0 Caught");
}
}
static void bar()
{
baz();
}
static void baz(){
if (i == 0)
throw new U0();
throw new U1();
}
public static void Main()
{
foo();
}
}

View file

@ -0,0 +1,119 @@
#include <stdio.h>
#include <stdlib.h>
typedef struct exception {
int extype;
char what[128];
} exception;
typedef struct exception_ctx {
exception * exs;
int size;
int pos;
} exception_ctx;
exception_ctx * Create_Ex_Ctx(int length) {
const int safety = 8; // alignment precaution.
char * tmp = (char*) malloc(safety+sizeof(exception_ctx)+sizeof(exception)*length);
if (! tmp) return NULL;
exception_ctx * ctx = (exception_ctx*)tmp;
ctx->size = length;
ctx->pos = -1;
ctx->exs = (exception*) (tmp + sizeof(exception_ctx));
return ctx;
}
void Free_Ex_Ctx(exception_ctx * ctx) {
free(ctx);
}
int Has_Ex(exception_ctx * ctx) {
return (ctx->pos >= 0) ? 1 : 0;
}
int Is_Ex_Type(exception_ctx * exctx, int extype) {
return (exctx->pos >= 0 && exctx->exs[exctx->pos].extype == extype) ? 1 : 0;
}
void Pop_Ex(exception_ctx * ctx) {
if (ctx->pos >= 0) --ctx->pos;
}
const char * Get_What(exception_ctx * ctx) {
if (ctx->pos >= 0) return ctx->exs[ctx->pos].what;
return NULL;
}
int Push_Ex(exception_ctx * exctx, int extype, const char * msg) {
if (++exctx->pos == exctx->size) {
// Use last slot and report error.
--exctx->pos;
fprintf(stderr, "*** Error: Overflow in exception context.\n");
}
snprintf(exctx->exs[exctx->pos].what, sizeof(exctx->exs[0].what), "%s", msg);
exctx->exs[exctx->pos].extype = extype;
return -1;
}
//////////////////////////////////////////////////////////////////////
exception_ctx * GLOBALEX = NULL;
enum { U0_DRINK_ERROR = 10, U1_ANGRYBARTENDER_ERROR };
void baz(int n) {
if (! n) {
Push_Ex(GLOBALEX, U0_DRINK_ERROR , "U0 Drink Error. Insufficient drinks in bar Baz.");
return;
}
else {
Push_Ex(GLOBALEX, U1_ANGRYBARTENDER_ERROR , "U1 Bartender Error. Bartender kicked customer out of bar Baz.");
return;
}
}
void bar(int n) {
fprintf(stdout, "Bar door is open.\n");
baz(n);
if (Has_Ex(GLOBALEX)) goto bar_cleanup;
fprintf(stdout, "Baz has been called without errors.\n");
bar_cleanup:
fprintf(stdout, "Bar door is closed.\n");
}
void foo() {
fprintf(stdout, "Foo entering bar.\n");
bar(0);
while (Is_Ex_Type(GLOBALEX, U0_DRINK_ERROR)) {
fprintf(stderr, "I am foo() and I deaall wrth U0 DriNk Errors with my own bottle... GOT oNE! [%s]\n", Get_What(GLOBALEX));
Pop_Ex(GLOBALEX);
}
if (Has_Ex(GLOBALEX)) return;
fprintf(stdout, "Foo left the bar.\n");
fprintf(stdout, "Foo entering bar again.\n");
bar(1);
while (Is_Ex_Type(GLOBALEX, U0_DRINK_ERROR)) {
fprintf(stderr, "I am foo() and I deaall wrth U0 DriNk Errors with my own bottle... GOT oNE! [%s]\n", Get_What(GLOBALEX));
Pop_Ex(GLOBALEX);
}
if (Has_Ex(GLOBALEX)) return;
fprintf(stdout, "Foo left the bar.\n");
}
int main(int argc, char ** argv) {
exception_ctx * ctx = Create_Ex_Ctx(5);
GLOBALEX = ctx;
foo();
if (Has_Ex(ctx)) goto main_ex;
fprintf(stdout, "No errors encountered.\n");
main_ex:
while (Has_Ex(ctx)) {
fprintf(stderr, "*** Error: %s\n", Get_What(ctx));
Pop_Ex(ctx);
}
Free_Ex_Ctx(ctx);
return 0;
}

View file

@ -0,0 +1,17 @@
(def U0 (ex-info "U0" {}))
(def U1 (ex-info "U1" {}))
(defn baz [x] (if (= x 0) (throw U0) (throw U1)))
(defn bar [x] (baz x))
(defn foo []
(dotimes [x 2]
(try
(bar x)
(catch clojure.lang.ExceptionInfo e
(if (= e U0)
(println "foo caught U0")
(throw e))))))
(defn -main [& args]
(foo))

View file

@ -0,0 +1,18 @@
(define-condition user-condition-1 (error) ())
(define-condition user-condition-2 (error) ())
(defun foo ()
(dolist (type '(user-condition-1 user-condition-2))
(handler-case
(bar type)
(user-condition-1 (c)
(format t "~&foo: Caught: ~A~%" c)))))
(defun bar (type)
(baz type))
(defun baz (type)
(error type)) ; shortcut for (error (make-condition type))
(trace foo bar baz)
(foo)

View file

@ -0,0 +1,6 @@
0: (FOO)
1: (BAR USER-CONDITION-1)
2: (BAZ USER-CONDITION-1)
foo: Caught: Condition USER-CONDITION-1 was signalled.
1: (BAR USER-CONDITION-2)
2: (BAZ USER-CONDITION-2)

View file

@ -0,0 +1,26 @@
class U0 < Exception
end
class U1 < Exception
end
def foo
2.times do |i|
begin
bar(i)
rescue e : U0
puts "rescued #{e}"
end
end
end
def bar(i : Int32)
baz(i)
end
def baz(i : Int32)
raise U0.new("this is u0") if i == 0
raise U1.new("this is u1") if i == 1
end
foo

View file

@ -0,0 +1,31 @@
class U0 : Exception {
this() @safe pure nothrow { super("U0 error message"); }
}
class U1 : Exception {
this() @safe pure nothrow { super("U1 error message"); }
}
void foo() {
import std.stdio;
foreach (immutable i; 0 .. 2) {
try {
i.bar;
} catch (U0) {
"Function foo caught exception U0".writeln;
}
}
}
void bar(in int i) @safe pure {
i.baz;
}
void baz(in int i) @safe pure {
throw i ? new U1 : new U0;
}
void main() {
foo;
}

View file

@ -0,0 +1,30 @@
type Exception1 = class (Exception) end;
type Exception2 = class (Exception) end;
procedure Baz(i : Integer);
begin
if i=0 then
raise new Exception1('Error message 1')
else raise new Exception2('Error message 2');
end;
procedure Bar(i : Integer);
begin
Baz(i);
end;
procedure Foo;
var
i : Integer;
begin
for i:=0 to 2 do begin
try
Bar(i);
except
on E : Exception1 do
PrintLn(E.ClassName+' caught');
end;
end;
end;
Foo;

View file

@ -0,0 +1,43 @@
program ExceptionsInNestedCall;
{$APPTYPE CONSOLE}
uses SysUtils;
type
U0 = class(Exception)
end;
U1 = class(Exception)
end;
procedure Baz(i: Integer);
begin
if i = 0 then
raise U0.Create('U0 Error message')
else
raise U1.Create('U1 Error message');
end;
procedure Bar(i: Integer);
begin
Baz(i);
end;
procedure Foo;
var
i: Integer;
begin
for i := 0 to 1 do
begin
try
Bar(i);
except
on E: U0 do
Writeln('Exception ' + E.ClassName + ' caught');
end;
end;
end;
begin
Foo;
end.

View file

@ -0,0 +1,28 @@
var bazCallCount = 0
func baz() {
bazCallCount += 1
if bazCallCount == 1 {
throw @BazCall1()
} else if bazCallCount == 2 {
throw @BazCall2()
}
}
func bar() {
baz()
}
func foo() {
var calls = 2
while calls > 0 {
try {
bar()
} catch {
@BazCall1() => print("BazzCall1 caught.")
}
calls -= 1
}
}
foo()

View file

@ -0,0 +1,35 @@
record U0 type Exception
end
record U1 type Exception
end
program Exceptions
function main()
foo();
end
function foo()
try
bar();
onException(ex U0)
SysLib.writeStdout("Caught a U0 with message: '" :: ex.message :: "'");
end
bar();
end
function bar()
baz();
end
firstBazCall boolean = true;
function baz()
if(firstBazCall)
firstBazCall = false;
throw new U0{message = "This is the U0 exception"};
else
throw new U1{message = "This is the U1 exception"};
end
end
end

View file

@ -0,0 +1,21 @@
(define (foo)
(for ((i 2))
(try
(bar i)
(catch (id message)
(if (= id 'U0)
(writeln message 'catched)
(error id "not catched"))))))
(define (bar i)
(baz i))
(define (baz i)
(if (= i 0)
(throw 'U0 "U0 raised")
(throw 'U1 "U1 raised")))
(foo) →
"U0 raised" catched
👓 error: U1 not catched

View file

@ -0,0 +1,38 @@
class MAIN
inherit EXCEPTIONS
creation foo
feature {ANY}
baz_calls: INTEGER
feature foo is
do
Current.bar
rescue
if is_developer_exception_of_name("U0") then
baz_calls := 1
print("Caught U0 exception.%N")
retry
end
if is_developer_exception then
print("Won't catch ")
print(developer_exception_name)
print(" exception...%N")
end
end
feature bar is
do
Current.baz
end
feature baz is
do
if baz_calls = 0 then
raise("U0")
else
raise("U1")
end
end
end

View file

@ -0,0 +1,53 @@
import extensions;
class U0 : Exception
{
constructor new()
<= new();
}
class U1 : Exception
{
constructor new()
<= new();
}
singleton Exceptions
{
static int i;
bar()
<= baz();
baz()
{
if (i == 0)
{
U0.raise()
}
else
{
U1.raise()
}
}
foo()
{
for(i := 0, i < 2, i += 1)
{
try
{
self.bar()
}
catch(U0 e)
{
console.printLine("U0 Caught")
}
}
}
}
public program()
{
Exceptions.foo()
}

View file

@ -0,0 +1,21 @@
defmodule U0, do: defexception [:message]
defmodule U1, do: defexception [:message]
defmodule ExceptionsTest do
def foo do
Enum.each([0,1], fn i ->
try do
bar(i)
rescue
U0 -> IO.puts "U0 rescued"
end
end)
end
def bar(i), do: baz(i)
def baz(0), do: raise U0
def baz(1), do: raise U1
end
ExceptionsTest.foo

View file

@ -0,0 +1,19 @@
-module( exceptions_catch ).
-export( [task/0] ).
task() -> [foo(X) || X<- lists:seq(1, 2)].
baz( 1 ) -> erlang:throw( u0 );
baz( 2 ) -> erlang:throw( u1 ).
foo( N ) ->
try
baz( N )
catch
_:u0 -> io:fwrite( "Catched ~p~n", [u0] )
end.

View file

@ -0,0 +1,21 @@
USING: combinators.extras continuations eval formatting kernel ;
IN: rosetta-code.nested-exceptions
ERROR: U0 ;
ERROR: U1 ;
: baz ( -- )
"IN: rosetta-code.nested-exceptions : baz ( -- ) U1 ;"
( -- ) eval U0 ;
: bar ( -- ) baz ;
: foo ( -- )
[
[ bar ] [
dup T{ U0 } =
[ "%u recovered\n" printf ] [ rethrow ] if
] recover
] twice ;
foo

View file

@ -0,0 +1,48 @@
const class U0 : Err
{
new make () : super ("U0") {}
}
const class U1 : Err
{
new make () : super ("U1") {}
}
class Main
{
Int bazCalls := 0
Void baz ()
{
bazCalls += 1
if (bazCalls == 1)
throw U0()
else
throw U1()
}
Void bar ()
{
baz ()
}
Void foo ()
{
2.times
{
try
{
bar ()
}
catch (U0 e)
{
echo ("Caught U0")
}
}
}
public static Void main ()
{
Main().foo
}
}

View file

@ -0,0 +1,48 @@
' FB 1.05.0 Win64
Enum ErrorTypes
U0 = 1000
U1
End Enum
Function errorName(ex As ErrorTypes) As String
Select Case As Const ex
Case U0
Return "U0"
Case U1
Return "U1"
End Select
End Function
Sub catchError(ex As ErrorTypes)
Dim e As Integer = Err '' cache the error number
If e = ex Then
Print "Error "; errorName(ex); ", number"; ex; " caught"
End If
End Sub
Sub baz()
Static As Integer timesCalled = 0 '' persisted between procedure calls
timesCalled += 1
If timesCalled = 1 Then
err = U0
Else
err = U1
End if
End Sub
Sub bar()
baz
End Sub
Sub foo()
bar
catchError(U0) '' not interested in U1, assumed non-fatal
bar
catchError(U0)
End Sub
Foo
Print
Print "Press any key to quit"
Sleep

View file

@ -0,0 +1,103 @@
// Outline for a try/catch-like exception mechanism in Go
//
// As all Go programmers should know, the Go authors are sharply critical of
// the try/catch idiom and consider it bad practice in general.
// See http://golang.org/doc/go_faq.html#exceptions
package main
import (
"fmt"
"runtime"
"strings"
)
// trace is for pretty output for the Rosetta Code task.
// It would have no place in a practical program.
func trace(s string) {
nc := runtime.Callers(2, cs)
f := runtime.FuncForPC(cs[0])
fmt.Print(strings.Repeat(" ", nc-3), f.Name()[5:], ": ", s, "\n")
}
var cs = make([]uintptr, 10)
type exception struct {
name string
handler func()
}
// try implents the try/catch-like exception mechanism. It takes a function
// to be called, and a list of exceptions to catch during the function call.
// Note that for this simple example, f has no parameters. In a practical
// program it might, of course. In this case, the signature of try would
// have to be modified to take these parameters and then supply them to f
// when it calls f.
func try(f func(), exs []exception) {
trace("start")
defer func() {
if pv := recover(); pv != nil {
trace("Panic mode!")
if px, ok := pv.(exception); ok {
for _, ex := range exs {
if ex.name == px.name {
trace("handling exception")
px.handler()
trace("panic over")
return
}
}
}
trace("can't recover this one!")
panic(pv)
}
}()
f()
trace("complete")
}
func main() {
trace("start")
foo()
trace("complete")
}
// u0, u1 declared at package level so they can be accessed by any function.
var u0, u1 exception
// foo. Note that function literals u0, u1 here in the lexical scope
// of foo serve the purpose of catch blocks of other languages.
// Passing u0 to try serves the purpose of the catch condition.
// While try(bar... reads much like the try statement of other languages,
// this try is an ordinary function. foo is passing bar into try,
// not calling it directly.
func foo() {
trace("start")
u0 = exception{"U0", func() { trace("U0 handled") }}
u1 = exception{"U1", func() { trace("U1 handled") }}
try(bar, []exception{u0})
try(bar, []exception{u0})
trace("complete")
}
func bar() {
trace("start")
baz()
trace("complete")
}
var bazCall int
func baz() {
trace("start")
bazCall++
switch bazCall {
case 1:
trace("panicking with execption U0")
panic(u0)
case 2:
trace("panicking with execption U1")
panic(u1)
}
trace("complete")
}

View file

@ -0,0 +1,59 @@
package main
import "fmt"
type U0 struct {
error
s string
}
type U1 int
func foo2() {
defer func() {
// We can't just "catch" U0 and ignore U1 directly but ...
if e := recover(); e != nil {
// e can be of any type, check for type U0
if x, ok := e.(*U0); ok {
// we can only execute code here,
// not return to the body of foo2
fmt.Println("Recovered U0:", x.s)
// We could cheat and call bar the second time
// from here, if it paniced again (even with U0)
// it wouldn't get recovered.
// Instead we've split foo into two calls to foo2.
} else {
// ... if we don't want to handle it we can
// pass it along.
fmt.Println("passing on:", e)
panic(e) // like a "re-throw"
}
}
}()
bar()
}
func foo() {
// Call bar twice via foo2
foo2()
foo2()
fmt.Println("not reached")
}
func bar() int {
return baz()
}
var done bool
func baz() int {
if !done {
done = true
panic(&U0{nil, "a message"})
}
panic(U1(42))
}
func main() {
foo()
fmt.Println("No panic")
}

View file

@ -0,0 +1,38 @@
import Control.Monad.Error
import Control.Monad.Trans (lift)
-- Our "user-defined exception" tpe
data MyError = U0 | U1 | Other deriving (Eq, Read, Show)
-- Required for any error type
instance Error MyError where
noMsg = Other
strMsg _ = Other
-- Throwing and catching exceptions implies that we are working in a monad. In
-- this case, we use ErrorT to support our user-defined exceptions, wrapping
-- IO to be able to report the happenings. ('lift' converts ErrorT e IO a
-- actions into IO a actions.)
foo = do lift (putStrLn "foo")
mapM_ (\toThrow -> bar toThrow -- the protected call
`catchError` \caught -> -- the catch operation
-- ↓ what to do with it
case caught of U0 -> lift (putStrLn "foo caught U0")
_ -> throwError caught)
[U0, U1] -- the two exceptions to throw
bar toThrow = do lift (putStrLn " bar")
baz toThrow
baz toThrow = do lift (putStrLn " baz")
throwError toThrow
-- We cannot use exceptions without at some outer level choosing what to do
-- if an exception propagates all the way up. Here we just print the exception
-- if there was one.
main = do result <- runErrorT foo
case result of
Left e -> putStrLn ("Caught error at top level: " ++ show e)
Right v -> putStrLn ("Return value: " ++ show v)

View file

@ -0,0 +1,45 @@
import Exceptions
class U0 : Exception()
method getMessage()
return "U0: " || (\message | "unknown")
end
end
class U1 : Exception()
method getMessage()
return "U1: " || (\message | "unknown")
end
end
procedure main()
# (Because Exceptions are not built into Unicon, uncaught
# exceptions are ignored. This clause will catch any
# exceptions not caught farther down in the code.)
case Try().call{ foo() } of {
Try().catch(): {
ex := Try().getException()
write(ex.getMessage(), ":\n", ex.getLocation())
}
}
end
procedure foo()
every 1|2 do {
case Try().call{ bar() } of {
Try().catch("U0"): {
ex := Try().getException()
write(ex.getMessage(), ":\n", ex.getLocation())
}
}
}
end
procedure bar()
return baz()
end
procedure baz()
initial U0().throw("First exception")
U1().throw("Second exception")
end

View file

@ -0,0 +1,20 @@
U0 := Exception clone
U1 := Exception clone
foo := method(
for(i,1,2,
try(
bar(i)
)catch( U0,
"foo caught U0" print
)pass
)
)
bar := method(n,
baz(n)
)
baz := method(n,
if(n == 1,U0,U1) raise("baz with n = #{n}" interpolate)
)
foo

View file

@ -0,0 +1,22 @@
main=: monad define
smoutput 'main'
try. foo ''
catcht. smoutput 'main caught ',type_jthrow_
end.
)
foo=: monad define
smoutput ' foo'
for_i. 0 1 do.
try. bar i
catcht. if. type_jthrow_-:'U0' do. smoutput ' foo caught ',type_jthrow_ else. throw. end.
end.
end.
)
bar=: baz [ smoutput bind ' bar'
baz=: monad define
smoutput ' baz'
type_jthrow_=: 'U',":y throw.
)

View file

@ -0,0 +1,9 @@
main ''
main
foo
bar
baz
foo caught U0
bar
baz
main caught U1

View file

@ -0,0 +1,29 @@
class U0 extends Exception { }
class U1 extends Exception { }
public class ExceptionsTest {
public static void foo() throws U1 {
for (int i = 0; i <= 1; i++) {
try {
bar(i);
} catch (U0 e) {
System.out.println("Function foo caught exception U0");
}
}
}
public static void bar(int i) throws U0, U1 {
baz(i); // Nest those calls
}
public static void baz(int i) throws U0, U1 {
if (i == 0)
throw new U0();
else
throw new U1();
}
public static void main(String[] args) throws U1 {
foo();
}
}

View file

@ -0,0 +1,35 @@
function U() {}
U.prototype.toString = function(){return this.className;}
function U0() {
this.className = arguments.callee.name;
}
U0.prototype = new U();
function U1() {
this.className = arguments.callee.name;
}
U1.prototype = new U();
function foo() {
for (var i = 1; i <= 2; i++) {
try {
bar();
}
catch(e if e instanceof U0) {
print("caught exception " + e);
}
}
}
function bar() {
baz();
}
function baz() {
// during the first call, redefine the function for subsequent calls
baz = function() {throw(new U1());}
throw(new U0());
}
foo();

View file

@ -0,0 +1,14 @@
# n is assumed to be the number of times baz has been previously called:
def baz(n):
if n==0 then error("U0")
elif n==1 then error("U1")
else "Goodbye"
end;
def bar(n): baz(n);
def foo:
(try bar(0) catch if . == "U0" then "We caught U0" else error(.) end),
(try bar(1) catch if . == "U0" then "We caught U0" else error(.) end);
foo

View file

@ -0,0 +1,28 @@
struct U0 <: Exception end
struct U1 <: Exception end
function foo()
for i in 1:2
try
bar()
catch err
if isa(err, U0) println("catched U0")
else rethrow(err) end
end
end
end
function bar()
baz()
end
function baz()
if isdefined(:_called) && _called
throw(U1())
else
global _called = true
throw(U0())
end
end
foo()

View file

@ -0,0 +1,29 @@
// version 1.0.6
class U0 : Throwable("U0 occurred")
class U1 : Throwable("U1 occurred")
fun foo() {
for (i in 1..2) {
try {
bar(i)
} catch(e: U0) {
println(e.message)
}
}
}
fun bar(i: Int) {
baz(i)
}
fun baz(i: Int) {
when (i) {
1 -> throw U0()
2 -> throw U1()
}
}
fun main(args: Array<String>) {
foo()
}

View file

@ -0,0 +1,20 @@
val .U0 = h{"msg": "U0"}
val .U1 = h{"msg": "U1"}
val .baz = f(.i) throw if(.i==0: .U0; .U1)
val .bar = f(.i) .baz(.i)
val .foo = f() {
for .i in [0, 1] {
.bar(.i)
catch {
if _err["msg"] == .U0["msg"] {
writeln "caught .U0 in .foo()"
} else {
throw
}
}
}
}
.foo()

View file

@ -0,0 +1,40 @@
define try(exception) => {
local(
gb = givenblock,
error
)
handle => {
// Only relay error if it's not the specified exception
if(#error) => {
if(#error->get(2) == #exception) => {
stdoutnl('Handled exception: '+#error->get(2))
else
stdoutnl('Throwing exception: '+#error->get(2))
fail(:#error)
}
}
}
protect => {
handle_error => {
#error = (:error_code,error_msg,error_stack)
}
#gb()
}
}
define foo => {
stdoutnl('foo')
try('U0') => { bar }
try('U0') => { bar }
}
define bar => {
stdoutnl('- bar')
baz()
}
define baz => {
stdoutnl(' - baz')
var(bazzed) ? fail('U1') | $bazzed = true
fail('U0')
}

View file

@ -0,0 +1,33 @@
local baz_counter=1
function baz()
if baz_counter==1 then
baz_counter=baz_counter+1
error("U0",3)--3 sends it down the call stack.
elseif baz_counter==2 then
error("U1",3)--3 sends it down the call stack.
end
end
function bar()
baz()
end
function foo()
function callbar()
local no_err,result = pcall(bar)
--pcall is a protected call which catches errors.
if not no_err then
--If there are no errors, pcall returns true.
if not result:match("U0") then
--If the error is not a U0 error, rethrow it.
error(result,2)
--2 is the distance down the call stack to send
--the error. We want it to go back to the callbar() call.
end
end
end
callbar()
callbar()
end
foo()

View file

@ -0,0 +1,31 @@
function exceptionsCatchNestedCall()
function foo()
try
bar(1);
bar(2);
catch
disp(lasterror);
rethrow(lasterror);
end
end
function bar(i)
baz(i);
end
function baz(i)
switch i
case 1
error('BAZ:U0','HAHAHAH');
case 2
error('BAZ:U1','AWWWW');
otherwise
disp 'I can''t do that Dave.';
end
end
foo();
end

View file

@ -0,0 +1,10 @@
>> exceptionsCatchNestedCall()
message: [1x177 char]
identifier: 'BAZ:U0'
stack: [4x1 struct]
??? Error using ==> exceptionsCatchNestedCall>baz at 21
HAHAHAH
Error in ==> exceptionsCatchNestedCall at 29
foo();

View file

@ -0,0 +1,23 @@
baz := proc( which )
if ( which = 0 ) then
error "U0";
else
error "U1";
end;
end proc:
bar := proc( which )
baz( which );
end proc:
foo := proc()
local i;
for i from 0 to 1 do
try
bar(i);
catch "U0":
end;
end do;
end proc:
foo();

View file

@ -0,0 +1,7 @@
foo[] := Catch[ bar[1]; bar[2]; ]
bar[i_] := baz[i];
baz[i_] := Switch[i,
1, Throw["Exception U0 in baz"];,
2, Throw["Exception U1 in baz"];]

View file

@ -0,0 +1,51 @@
using System;
using System.Console;
namespace NestedExceptions
{
public class U0 : Exception
{
public this() {base()}
}
public class U1 : Exception
{
public this() {base()}
}
module NestedExceptions
{
Foo () : void
{
mutable call = 0;
repeat(2) {
try {
Bar(call);
}
catch {
|e is U0 => WriteLine("Exception U0 caught.")
}
finally {
call++;
}
}
}
Bar (call : int) : void
{
Baz(call)
}
Baz (call : int) : void // throw U0() on first call, U1() on second
{
unless (call > 0) throw U0();
when (call > 0) throw U1();
}
Main () : void
{
Foo()
}
}
}

View file

@ -0,0 +1,18 @@
type U0 = object of Exception
type U1 = object of Exception
proc baz(i) =
if i > 0: raise newException(U1, "Some error")
else: raise newException(U0, "Another error")
proc bar(i) =
baz(i)
proc foo() =
for i in 0..1:
try:
bar(i)
except U0:
echo "Function foo caught exception U0"
foo()

View file

@ -0,0 +1,17 @@
exception U0
exception U1
let baz i =
raise (if i = 0 then U0 else U1)
let bar i = baz i (* Nest those calls *)
let foo () =
for i = 0 to 1 do
try
bar i
with U0 ->
print_endline "Function foo caught exception U0"
done
let () = foo ()

View file

@ -0,0 +1,43 @@
@interface U0 : NSObject { }
@end
@interface U1 : NSObject { }
@end
@implementation U0
@end
@implementation U1
@end
void foo();
void bar(int i);
void baz(int i);
void foo() {
for (int i = 0; i <= 1; i++) {
@try {
bar(i);
} @catch (U0 *e) {
NSLog(@"Function foo caught exception U0");
}
}
}
void bar(int i) {
baz(i); // Nest those calls
}
void baz(int i) {
if (i == 0)
@throw [U0 new];
else
@throw [U1 new];
}
int main (int argc, const char * argv[]) {
@autoreleasepool {
foo();
}
return 0;
}

View file

@ -0,0 +1,11 @@
Exception Class new: U0
Exception Class new: U1
: baz ifZero: [ "First call" U0 throw ] else: [ "Second call" U1 throw ] ;
: bar baz ;
: foo
| e |
try: e [ 0 bar ] when: [ e isKindOf(U0) ifTrue: [ "Catched" .cr ] else: [ e throw ] ]
try: e [ 1 bar ] when: [ e isKindOf(U0) ifTrue: [ "Catched" .cr ] else: [ e throw ] ]
"Done" . ;

View file

@ -0,0 +1,21 @@
declare
proc {Foo}
for I in 1..2 do
try
{Bar I}
catch u0 then {System.showInfo "Procedure Foo caught exception u0"}
end
end
end
proc {Bar I} {Baz I} end
proc {Baz I}
if I == 1 then
raise u0 end
else
raise u1 end
end
end
in
{Foo}

View file

@ -0,0 +1,7 @@
call = 0;
U0() = error("x = ", 1, " should not happen!");
U1() = error("x = ", 2, " should not happen!");
baz(x) = if(x==1, U0(), x==2, U1());x;
bar() = baz(call++);
foo() = if(!call, iferr(bar(), E, printf("Caught exception, call=%d",call)), bar())

View file

@ -0,0 +1,30 @@
/* Exceptions: Catch an exception thrown in a nested call */
test: proc options (main);
/* 8/1/2011 */
declare (m, n) fixed initial (2);
declare (U0, U1) condition;
foo: procedure () returns (fixed);
on condition(U0) snap begin;
put list ('Raised condition U0 in function <bar>.'); put skip;
end;
m = bar();
m = bar();
return (m);
end foo;
bar: procedure () returns (fixed);
n = n + 1;
return (baz());
return (n);
end bar;
baz: procedure () returns (fixed);
declare first bit(1) static initial ('1'b);
n = n + 1;
if first then do; first = '0'b; signal condition(U0); end;
else signal condition(U1);
return (n);
end baz;
m = foo();
end test;

View file

@ -0,0 +1,18 @@
sub foo {
foreach (0..1) {
eval { bar($_) };
if ($@ =~ /U0/) { print "Function foo caught exception U0\n"; }
else { die; } # propagate the exception
}
}
sub bar {
baz(@_); # Nest those calls
}
sub baz {
my $i = shift;
die ($i ? "U1" : "U0");
}
foo();

View file

@ -0,0 +1,37 @@
-->
<span style="color: #008080;">constant</span> <span style="color: #000000;">U0</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0<span style="color: #0000FF;">,</span>
<span style="color: #000000;">U1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">baz<span style="color: #0000FF;">(<span style="color: #0000FF;">)</span>
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">count<span style="color: #0000FF;">=<span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">throw<span style="color: #0000FF;">(<span style="color: #000000;">U0<span style="color: #0000FF;">,<span style="color: #0000FF;">{<span style="color: #0000FF;">{<span style="color: #008000;">"any"<span style="color: #0000FF;">,<span style="color: #0000FF;">{<span style="color: #0000FF;">{<span style="color: #008000;">"thing"<span style="color: #0000FF;">}<span style="color: #0000FF;">,<span style="color: #008000;">"you"<span style="color: #0000FF;">}<span style="color: #0000FF;">}<span style="color: #0000FF;">,<span style="color: #008000;">"like"<span style="color: #0000FF;">}<span style="color: #0000FF;">)</span>
<span style="color: #008080;">else</span>
<span style="color: #008080;">throw<span style="color: #0000FF;">(<span style="color: #000000;">U1<span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">bar<span style="color: #0000FF;">(<span style="color: #0000FF;">)</span>
<span style="color: #000000;">baz<span style="color: #0000FF;">(<span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">foo<span style="color: #0000FF;">(<span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i<span style="color: #0000FF;">=<span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">2</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">try</span>
<span style="color: #000000;">bar<span style="color: #0000FF;">(<span style="color: #0000FF;">)</span>
<span style="color: #008080;">catch</span> <span style="color: #000000;">e</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">e<span style="color: #0000FF;">[<span style="color: #000000;">E_CODE<span style="color: #0000FF;">]<span style="color: #0000FF;">=<span style="color: #000000;">U0</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">?<span style="color: #000000;">e<span style="color: #0000FF;">[<span style="color: #000000;">E_USER<span style="color: #0000FF;">]</span>
<span style="color: #008080;">else</span>
<span style="color: #008080;">throw<span style="color: #0000FF;">(<span style="color: #000000;">e<span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (terminates)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">try</span>
<span style="color: #7060A8;">puts<span style="color: #0000FF;">(<span style="color: #000000;">1<span style="color: #0000FF;">,<span style="color: #008000;">"still running...\n"<span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">puts<span style="color: #0000FF;">(<span style="color: #000000;">1<span style="color: #0000FF;">,<span style="color: #008000;">"not still running...\n"<span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">foo<span style="color: #0000FF;">(<span style="color: #0000FF;">)
<!--

View file

@ -0,0 +1,13 @@
(de foo ()
(for Tag '(U0 U1)
(catch 'U0
(bar Tag) ) ) )
(de bar (Tag)
(baz Tag) )
(de baz (Tag)
(throw Tag) )
(mapc trace '(foo bar baz))
(foo)

View file

@ -0,0 +1,17 @@
class U0(Exception): pass
class U1(Exception): pass
def foo():
for i in range(2):
try:
bar(i)
except U0:
print("Function foo caught exception U0")
def bar(i):
baz(i) # Nest those calls
def baz(i):
raise U1 if i else U0
foo()

View file

@ -0,0 +1,23 @@
[ this ] is U0
[ this ] is U1
[ 0 = iff U0 else U1
message put bail ] is baz ( n --> )
[ baz ] is bar ( n --> )
[ 2 times
[ i^
1 backup
bar
bailed if
[ message share
U0 oats iff
[ say "Exception U0 raised." cr
echostack
$ "Press enter to continue"
input drop
message release
drop ]
else [ drop bail ] ] ] ] is foo

View file

@ -0,0 +1,15 @@
number_of_calls_to_baz <- 0
foo <- function()
{
for(i in 1:2) tryCatch(bar())
}
bar <- function() baz()
baz <- function()
{
e <- simpleError(ifelse(number_of_calls_to_baz > 0, "U1", "U0"))
assign("number_of_calls_to_baz", number_of_calls_to_baz + 1, envir=globalenv())
stop(e)
}

View file

@ -0,0 +1,22 @@
/*REXX program creates two exceptions and demonstrates how to handle (catch) them. */
call foo /*invoke the FOO function (below). */
say 'The REXX mainline program has completed.' /*indicate that Elroy was here. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
foo: call bar; call bar /*invoke BAR function twice. */
return 0 /*return a zero to the invoker. */
/*the 1st U0 in REXX program is used.*/
U0: say 'exception U0 caught in FOO' /*handle the U0 exception. */
return -2 /*return to the invoker. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
bar: call baz /*have BAR function invoke BAZ function*/
return 0 /*return a zero to the invoker. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
baz: if symbol('BAZ#')=='LIT' then baz#=0 /*initialize the first BAZ invocation #*/
baz# = baz#+1 /*bump the BAZ invocation number by 1. */
if baz#==1 then signal U0 /*if first invocation, then raise U0 */
if baz#==2 then signal U1 /* " second " " " U1 */
return 0 /*return a 0 (zero) to the invoker.*/
/* [↓] this U0 subroutine is ignored.*/
U0: return -1 /*handle exception if not caught. */
U1: return -1 /* " " " " " */

View file

@ -0,0 +1,19 @@
#lang racket
(define-struct (exn:U0 exn) ())
(define-struct (exn:U1 exn) ())
(define (foo)
(for ([i 2])
(with-handlers ([exn:U0? (λ(_) (displayln "Function foo caught exception U0"))])
(bar i))))
(define (bar i)
(baz i))
(define (baz i)
(if (= i 0)
(raise (make-exn:U0 "failed 0" (current-continuation-marks)))
(raise (make-exn:U1 "failed 1" (current-continuation-marks)))))
(foo)

View file

@ -0,0 +1,2 @@
Function foo caught exception U0
. . failed 1

View file

@ -0,0 +1,14 @@
sub foo() {
for 0..1 -> $i {
bar $i;
CATCH {
when /U0/ { say "Function foo caught exception U0" }
}
}
}
sub bar($i) { baz $i }
sub baz($i) { die "U$i" }
foo;

View file

@ -0,0 +1,23 @@
def foo
2.times do |i|
begin
bar(i)
rescue U0
$stderr.puts "captured exception U0"
end
end
end
def bar(i)
baz(i)
end
def baz(i)
raise i == 0 ? U0 : U1
end
class U0 < StandardError; end
class U1 < StandardError; end
foo

View file

@ -0,0 +1,32 @@
#[derive(Debug)]
enum U {
U0(i32),
U1(String),
}
fn baz(i: u8) -> Result<(), U> {
match i {
0 => Err(U::U0(42)),
1 => Err(U::U1("This will be returned from main".into())),
_ => Ok(()),
}
}
fn bar(i: u8) -> Result<(), U> {
baz(i)
}
fn foo() -> Result<(), U> {
for i in 0..2 {
match bar(i) {
Ok(()) => {},
Err(U::U0(n)) => eprintln!("Caught U0 in foo: {}", n),
Err(e) => return Err(e),
}
}
Ok(())
}
fn main() -> Result<(), U> {
foo()
}

View file

@ -0,0 +1,19 @@
object ExceptionsTest extends App {
class U0 extends Exception
class U1 extends Exception
def foo {
for (i <- 0 to 1)
try {
bar(i)
} catch { case e: U0 => println("Function foo caught exception U0") }
}
def bar(i: Int) {
def baz(i: Int) = { if (i == 0) throw new U0 else throw new U1 }
baz(i) // Nest those calls
}
foo
}

View file

@ -0,0 +1,36 @@
$ include "seed7_05.s7i";
const EXCEPTION: U0 is enumlit;
const EXCEPTION: U1 is enumlit;
const proc: baz (in integer: num) is func
begin
if num = 1 then
raise U0;
else
raise U1;
end if;
end func;
const proc: bar (in integer: num) is func
begin
baz(num);
end func;
const proc: foo is func
local
var integer: num is 0;
begin
for num range 1 to 2 do
block
bar(num);
exception
catch U0: writeln("U0 catched");
end block;
end for;
end func;
const proc: main is func
begin
foo;
end func;

View file

@ -0,0 +1,14 @@
func baz(i) { die "U#{i}" };
func bar(i) { baz(i) };
func foo {
[0, 1].each { |i|
try { bar(i) }
catch { |_, msg|
msg ~~ /^U0/ ? say "Function foo() caught exception U0"
: die msg; # re-raise the exception
};
}
}
foo();

View file

@ -0,0 +1,25 @@
Exception subclass: #U0.
Exception subclass: #U1.
Object subclass: Foo [
bazCount := 0.
foo
[2 timesRepeat:
[ "==>" [self bar] "<=="
on: U0
do:
[:sig |
'Call to bar was aborted by exception U0' printNl.
sig return]]]
bar
[self baz]
baz
[bazCount := bazCount + 1.
bazCount = 1 ifTrue: [U0 new signal].
bazCount = 2 ifTrue: [U1 new signal].
"Thirds time's a charm..."]
]

View file

@ -0,0 +1,11 @@
st> Foo new foo
'Call to bar was aborted by exception U0'
Object: Foo new "<-0x4c9a7960>" error: An exception has occurred
U1(Exception)>>signal (ExcHandling.st:254)
Foo>>baz (catch_exception.st:32)
Foo>>bar (catch_exception.st:27)
optimized [] in Foo>>foo (catch_exception.st:19)
BlockClosure>>on:do: (BlkClosure.st:193)
Foo>>foo (catch_exception.st:20)
UndefinedObject>>executeStatements (a String:1)
nil

View file

@ -0,0 +1,28 @@
enum MyException : ErrorType {
case U0
case U1
}
func foo() throws {
for i in 0 ... 1 {
do {
try bar(i)
} catch MyException.U0 {
print("Function foo caught exception U0")
}
}
}
func bar(i: Int) throws {
try baz(i) // Nest those calls
}
func baz(i: Int) throws {
if i == 0 {
throw MyException.U0
} else {
throw MyException.U1
}
}
try foo()

View file

@ -0,0 +1,28 @@
@(defex u0)
@(defex u1)
@(define baz (x))
@ (cases)
@ (bind x "0")
@ (throw u0 "text0")
@ (or)
@ (bind x "1")
@ (throw u1 "text1")
@ (end)
@(end)
@(define bar (x))
@ (baz x)
@(end)
@(define foo ())
@ (next :list @'("0" "1"))
@ (collect)
@num
@ (try)
@ (bar num)
@ (catch u0 (arg))
@ (output)
caught u0: @arg
@ (end)
@ (end)
@ (end)
@(end)
@(foo)

View file

@ -0,0 +1,26 @@
package require Tcl 8.5
proc foo {} {
set code [catch {bar} ex options]
if {$code == 1} {
switch -exact -- $ex {
U0 {puts "caught exception U0"}
default {return -options $options $ex ;# re-raise exception}
}
}
}
proc bar {} {baz}
# create an alias to pass the initial exception U0 to the baz proc
interp alias {} baz {} _baz U0
proc _baz {exception} {
# re-set the alias so subsequent invocations will use exception U1
interp alias {} baz {} _baz U1
# throw
return -code error $exception
}
foo
foo

View file

@ -0,0 +1,19 @@
#import std
baz =
~&?(
~&h?(
:/'baz succeeded with this input:',
<'baz threw a user-defined empty string exception','U1'>!%),
<'baz threw a user-defined empty file exception','U0'>!%)
bar = :/'bar received this result from normal termination of baz:'+ baz
#executable&
foo =
guard(
:/'foo received this result from normal termination of bar:'+ bar,
'U0'?=z/~& :/'foo caught an exception with this error message:')

View file

@ -0,0 +1,37 @@
Class U0
Inherits Exception
End Class
Class U1
Inherits Exception
End Class
Module Program
Sub Main()
Foo()
End Sub
Sub Foo()
Try
Bar()
Bar()
Catch ex As U0
Console.WriteLine(ex.GetType.Name & " caught.")
End Try
End Sub
Sub Bar()
Baz()
End Sub
Sub Baz()
' Static local variable is persisted between calls of the method and is initialized only once.
Static firstCall As Boolean = True
If firstCall Then
firstCall = False
Throw New U0()
Else
Throw New U1()
End If
End Sub
End Module

View file

@ -0,0 +1,9 @@
Sub Foo()
For i = 1 To 2
Try
Bar()
Catch ex As U0
Console.WriteLine(ex.GetType().Name & " caught.")
End Try
Next
End Sub

View file

@ -0,0 +1,28 @@
var U0 = "U0"
var U1 = "U1"
var bazCalled = 0
var baz = Fn.new {
bazCalled = bazCalled + 1
Fiber.abort( (bazCalled == 1) ? U0 : U1 )
}
var bar = Fn.new {
baz.call()
}
var foo = Fn.new {
for (i in 1..2) {
var f = Fiber.new { bar.call() }
f.try()
var err = f.error
if (err == U0) {
System.print("Caught exception %(err)")
} else if (err == U1) {
Fiber.abort("Uncaught exception %(err) rethrown") // re-throw
}
}
}
foo.call()

View file

@ -0,0 +1,37 @@
func U0; \Exception caused by square root of negative value
real X;
X:= Sqrt(-42.);
func U1; \Exception caused by opening a non-existent file for input
int F;
F:= FOpen("unobtainium.txt", 0);
func Baz;
int CallNo;
[CallNo:= [1]; \static-like variable
if CallNo(0) = 1 then \first time Baz is called
[CallNo(0):= 2;
Text(0, "Calling U0^m^j");
Trap(false); \turn off error trapping to prevent program abort
U0;
Restart;
]
else \second time Baz is called
[Text(0, "Calling U1^m^j");
U1; \error trapping is still disabled
];
];
func Bar;
Baz;
func Foo;
Bar;
int Err;
[Err:= GetErr; \get the exception error after the program is restarted
if Err then \reading GetErr resets any error number to 0, = no error
[Text(0, "Error "); IntOut(0, Err); Text(0, " detected^m^j")];
Foo;
Text(0, "Finished^m^j");
] \second exception is pending, and it will be displayed

View file

@ -0,0 +1,7 @@
class U0(Exception.Exception){fcn init{Exception.init("U0")}}
class U1(Exception.Exception){fcn init{Exception.init("U1")}}
fcn foo{try{bar(U0)}catch(U0){} bar(U1)}
fcn bar(e){baz(e)}
fcn baz(e){throw(e)}
foo()