Exception Mechanisms Back to the Win32 Shootout
Back to dada's perl lab

[The Original Shootout]   [NEWS]   [FAQ]   [Methodology]   [Platform Details]   [Acknowledgements]   [Scorecard]  
All Source For Exception Mechanisms
except.bcc
/* -*- mode: c -*-
 * $Id: except.gcc,v 1.1 2001/01/07 04:31:15 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 */

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>

int HI = 0, LO = 0;

static jmp_buf Hi_exception;
static jmp_buf Lo_exception;

void blowup (int n) {
    if (n & 1) {
    longjmp(Lo_exception, 1);
    } else {
    longjmp(Hi_exception, 1);
    }
}

void lo_function (volatile int n) {
    if (setjmp(Lo_exception) != 0) {
    LO++;
    } else {
    blowup(n);
    }
}

void hi_function (volatile int n) {
    if (setjmp(Hi_exception) != 0) {
    HI++;
    } else {
    lo_function(n);
    }
}

void some_function (int n) {
    hi_function(n);
}

int
main(int argc, char *argv[]) {
    int volatile N = ((argc == 2) ? atoi(argv[1]) : 1);

    while (N) {
    some_function(N--);
    }
    printf("Exceptions: HI=%d / LO=%d\n", HI, LO);
    return(0);
}
except.bigforth
\ -*- mode: forth -*-
\ $Id: except.bigforth,v 1.1 2001/06/20 19:04:07 doug Exp $
\ http://www.bagley.org/~doug/shootout/
\ from Anton Ertl

\ read NUM from last command line argument
0. argc @ 1- arg >number 2drop drop constant NUM

1 constant *hi*
2 constant *lo*

variable lo
variable hi

: blowup 
    1 and if
        *lo* throw
    else
        *hi* throw
    then ;

: lo-function 
    ['] blowup catch           
    dup *lo* <> tuck and throw 
    1+ lo +! ;

: hi-function 
    ['] lo-function catch      
    dup *hi* <> tuck and throw 
    1+ hi +! ;

: some-function 
    ['] hi-function catch abort" We shouldn't get here" ;

: main 
    NUM 0 ?do
        i some-function drop
        loop
    ." Exceptions: HI=" hi ? ." / LO=" lo @ 1 u.r cr ;

main bye
except.csharp
// $Id: exceptions.csharp,v 1.0 2002/09/28 10:21:00 dada Exp $
// http://dada.perl.it/shootout/
// contributed by Erik Saltwell

using System;

namespace Exceptions
{
    class LoException : System.Exception
    {
        public LoException(){}
    }

    class HiException : System.Exception 
    {
        public HiException(){}
    }

    public class App 
    {
        static int Lo = 0;
        static int Hi = 0;
        static int count=0;
        public static void Main(string[] args)
        {
            int n = int.Parse(args[0]);
            for (count=0; count<n; count++) 
            {
                SomeFunction();
            }
            System.Text.StringBuilder bldr = new System.Text.StringBuilder(100);
            bldr.Append("Exceptions: HI=").Append(Hi).Append(" / LO=").Append(Lo);
            Console.WriteLine(bldr.ToString());
        }

        public static void SomeFunction() 
        {
            try 
            {
                HiFunction();
            } 
            catch (Exception e) 
            {
                Console.WriteLine("We shouldn't get here: " + e.Message);
            }
        }

        public static void HiFunction() 
        {
            try 
            {
                LoFunction();
            } 
            catch (HiException) 
            {
                Hi++;
            }
        }
        public static void LoFunction()
        {
            try 
            {
                BlowUp();
            } 
            catch (LoException) 
            {
                Lo++;
            }
        }
        public static void BlowUp() 
        {
            if ((count & 1) == 0) 
            {
                throw new LoException();
            } 
            else 
            {
                throw new HiException();
            }
        }
    }
}
except.cygperl
#!/usr/local/bin/perl
# $Id: except.perl,v 1.5 2001/05/27 00:23:52 doug Exp $
# http://www.bagley.org/~doug/shootout/

use integer;

my $HI = 0;
my $LO = 0;
my $NUM = $ARGV[0];
$NUM = 1 if ($NUM < 1);

package Lo_Exception;

sub new {
    bless({Val => shift}, __PACKAGE__);
}

package Hi_Exception;

sub new {
    bless({Val => shift}, __PACKAGE__);
}

package main;

sub some_function {
    my $num = shift;
    eval {
    &hi_function($num);
    };
    if ($@) {
    die "We shouldn't get here ($@)";
    }
}

sub hi_function {
    my $num = shift;
    eval {
    &lo_function($num);
    };
    if (ref($@) eq "Hi_Exception") {
    $HI++;        # handle
    } elsif ($@) {
    die $@;        # rethrow
    }
}

sub lo_function {
    my $num = shift;
    eval {
    &blowup($num);
    };
    if (ref($@) eq "Lo_Exception") {
    $LO++;        # handle
    } elsif ($@) {
    die $@;        # rethrow
    }
}

sub blowup {
    my $num = shift;
    if ($num % 2) {
    die Lo_Exception->new(Num => $num);
    } else {
    die Hi_Exception->new(Num => $num);
    }
}

$NUM = $ARGV[0];
while ($NUM--) {
    &some_function($NUM);
}
print "Exceptions: HI=$HI / LO=$LO\n";
except.erlang
%% Used destructive assignment in the process dictionary 
%% to keep count of handled exceptions.
%%
%% Usage: start from command line with
%%     erlc exceptions.erl
%%     erl -noinput -s exceptions main 200000

-module(except). 
-export([main/1]). 


blowup(N) when N rem 2 == 0 -> throw({lo_exception, N});
blowup(N) -> throw({hi_exception, N}).


lo_fun(N) ->
    case catch blowup(N) of
        {lo_exception, N1} -> put(lo_count, get(lo_count) + 1);
        {hi_exception, N2} -> throw({hi_exception, N2})
    end.


hi_fun(N) -> 
    case catch lo_fun(N) of
        {hi_exception, N1} -> put(hi_count, get(hi_count) + 1);
        _ -> true
    end.


some_fun(N) when N > 0 ->
    case catch hi_fun(N) of
        {lo_exception, N1} -> io:fwrite("~s~n", ["lo_exception should not get here."]);
        {hi_exception, N2} -> io:fwrite("~s~n", ["hi_exception should not get here."]);
        _ -> true
    end,
    some_fun(N - 1);
some_fun(0) -> true.


main([Arg]) ->
    Num = list_to_integer(atom_to_list(Arg)),
    put(hi_count, 0),
    put(lo_count, 0),
    some_fun(Num),
    io:fwrite("~s~w ~s~w~n", ["Exceptions: HI=", get(hi_count),"/ LO=", get(lo_count)]),
    halt(0).


except.gcc
/* -*- mode: c -*-
 * $Id: except.gcc,v 1.1 2001/01/07 04:31:15 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 */

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>

int HI = 0, LO = 0;

static jmp_buf Hi_exception;
static jmp_buf Lo_exception;

void blowup (int n) {
    if (n & 1) {
    longjmp(Lo_exception, 1);
    } else {
    longjmp(Hi_exception, 1);
    }
}

void lo_function (volatile int n) {
    if (setjmp(Lo_exception) != 0) {
    LO++;
    } else {
    blowup(n);
    }
}

void hi_function (volatile int n) {
    if (setjmp(Hi_exception) != 0) {
    HI++;
    } else {
    lo_function(n);
    }
}

void some_function (int n) {
    hi_function(n);
}

int
main(int argc, char *argv[]) {
    int volatile N = ((argc == 2) ? atoi(argv[1]) : 1);

    while (N) {
    some_function(N--);
    }
    printf("Exceptions: HI=%d / LO=%d\n", HI, LO);
    return(0);
}
except.gforth
\ -*- mode: forth -*-
\ $Id: except.gforth,v 1.3 2001/06/20 19:04:07 doug Exp $
\ http://www.bagley.org/~doug/shootout/
\ from Anton Ertl

\ read NUM from last command line argument
0. argc @ 1- arg >number 2drop drop constant NUM

1 constant *hi*
2 constant *lo*

variable lo
variable hi

: blowup 
    1 and if
        *lo* throw
    else
        *hi* throw
    endif ;

: lo-function 
    ['] blowup catch           
    dup *lo* <> tuck and throw 
    1+ lo +! ;

: hi-function 
    ['] lo-function catch      
    dup *hi* <> tuck and throw 
    1+ hi +! ;

: some-function 
    ['] hi-function catch abort" We shouldn't get here" ;

: main 
    NUM 0 ?do
        i some-function drop
        loop
    ." Exceptions: HI=" hi ? ." / LO=" lo @ 1 u.r cr ;

main bye
except.ghc
-- $Id: except.ghc,v 1.2 2001/05/20 00:21:36 doug Exp $
-- http://www.bagley.org/~doug/shootout/
-- from Simon Marlow

import System
import Exception
import IOExts

blowup n | even n    = throw (ErrorCall "H")
     | otherwise = throw (ErrorCall "L")

lo_function lo n = 
  Exception.catchAllIO (blowup n) 
    (\ex -> case ex of
        ErrorCall "L" -> do nlo <- readIORef lo
                    writeIORef lo (nlo + 1)
        _ -> throw ex
    )

hi_function hi lo n = 
  Exception.catchAllIO (lo_function lo n) 
    (\ex -> case ex of
        ErrorCall "H" -> do nhi <- readIORef hi
                    writeIORef hi (nhi + 1)
        _ -> throw ex
    )

some_function hi lo n = hi_function hi lo n

main = do
  [arg] <- getArgs
  let n = read arg :: Int
  hi <- newIORef (0 :: Int)
  lo <- newIORef (0 :: Int)
  mapM (some_function hi lo) [n,n-1..1]
  nhi <- readIORef hi
  nlo <- readIORef lo
  putStrLn ("Exceptions: HI=" ++ show nhi ++ " / LO=" ++ show nlo)
except.gnat
-- $Id: except.gnat,v 1.0 2003/06/11 12:06:00 dada Exp $
-- http://dada.perl.it/shootout/
-- Ada 95 code by C.C.

with Text_IO, Ada.Strings.Fixed, Ada.Command_Line;

procedure Except is
   High_Exception : exception;
   Low_Exception  : exception;
   Low            : Integer := 0;
   High           : Integer := 0;

   procedure Blowup (K : Integer) is
      pragma Inline (Blowup);
   begin
      case 1 = (K mod 2) is
         when False => raise High_Exception;
         when True  => raise Low_Exception;
      end case;
   end Blowup;

   procedure Low_Function (K : Integer) is
      pragma Inline (Low_Function);
   begin
      Blowup (K);
   exception
      when Low_Exception => Low := Low + 1;
   end Low_Function;

   procedure High_Function (K : Integer) is
      pragma Inline (High_Function);
   begin
      Low_Function (K);
   exception
      when High_Exception => High := High + 1;
   end High_Function;

   procedure Some_Function (K : Integer) is
      pragma Inline (Some_Function);
   begin
      High_Function (K);
   exception
      when others => Text_IO.Put_Line ("We shouldn't get here");
   end Some_Function;

   function L_Trim (Source : String; Side : Ada.Strings.Trim_End :=
               Ada.Strings.Left) return String renames Ada.Strings.Fixed.Trim;
   N        : Natural := 0;
begin
   begin
      N := Natural'Value (Ada.Command_Line.Argument (1));
   exception
      when Constraint_Error => null;
   end;
   for K in reverse 0 .. N - 1 loop
      Some_Function (K);
   end loop;
   Text_IO.Put_Line ("Exceptions: HI=" & L_Trim (Natural'Image (High)) &
            " / LO=" & L_Trim (Natural'Image (Low)));
end Except;

except.guile
#!/usr/local/bin/guile \
-e main -s
!#

;;; $Id: except.guile,v 1.3 2001/06/29 23:12:37 doug Exp $
;;; http://www.bagley.org/~doug/shootout/

(use-modules (ice-9 format))

(define HI 0)
(define LO 0)

(define (some_fun n)
  (catch #t
     (lambda () (hi_fun n))
     (lambda args #f)))

(define (hi_fun n)
  (catch 'Hi_Exception
     (lambda () (lo_fun n))
     (lambda args (set! HI (+ HI 1)))))

(define (lo_fun n)
  (catch 'Lo_Exception
     (lambda () (blowup n))
     (lambda args (set! LO (+ LO 1)))))

(define (blowup n)
  (if (= 0 (modulo n 2))
      (throw 'Hi_Exception)
      (throw 'Lo_Exception)))

(define (main args)
  (let* ((n (or (and (= (length args) 2) (string->;number (cadr args))) 1)))
    (do ((i 0 (+ i 1)))
    ((= i n))
      (some_fun i)))
  (display (format "Exceptions: HI=~D / LO=~D\n" HI LO)))

except.ici
// $Id: except.ici,v 1.0 2003/01/03 11:28:00 dada Exp $
// http://dada.perl.it/shootout
//
// contributed by Tim Long


N = argv[1] ? int(argv[1]) : 1;

static HI = 0;
static LO = 0;

static
blowup(n)
{
    fail(n & 1 ? "low" : "hi");
}

static
lo_function (n)
{
    try
        blowup(n);
    onerror
    {
        if (error !~ #low#)
            fail(error);
        ++LO;
    }
}

static
hi_function(n)
{
    try
        lo_function(n);
    onerror
        ++HI;
}

static
some_function(n)
{
    try
        hi_function(n);
    onerror
        fail(error + " -- we shouldn't get here");
}

while (N)
    some_function(N--);

printf("Exceptions: HI=%d / LO=%d\n", HI, LO);
except.java
// $Id: except.java,v 1.1 2000/12/17 17:58:23 doug Exp $
// http://www.bagley.org/~doug/shootout/
// Collection class code is from my friend Phil Chu, Thanks Phil!

import java.io.*;
import java.util.*;
import java.text.*;

class Lo_Exception extends Exception {
    int num = 0;
    public Lo_Exception(int num) {
    this.num = num;
    }
    public String toString() {
    return "Lo_Exception, num = " + this.num;
    }
}

class Hi_Exception extends Exception {
    int num = 0;
    public Hi_Exception(int num) {
    this.num = num;
    }
    public String toString() {
    return "Hi_Exception, num = " + this.num;
    }
}

public class except {
    static int Lo = 0;
    static int Hi = 0;

    public static void main(String args[]) throws IOException {
    int n = Integer.parseInt(args[0]);

    for (int i=0; i<n; i++) {
        some_function(i);
    }
    System.out.println("Exceptions: HI=" + Hi + " / LO=" + Lo);
    }

    public static void some_function(int n) {
    try {
        hi_function(n);
    } catch (Exception e) {
        System.out.println("We shouldn't get here: " + e);
    }
    }

    public static void hi_function(int n) throws Hi_Exception, Lo_Exception {
    try {
        lo_function(n);
    } catch (Hi_Exception e) {
        Hi++;
    }
    }

    public static void lo_function(int n) throws Hi_Exception, Lo_Exception {
    try {
        blowup(n);
    } catch (Lo_Exception e) {
        Lo++;
    }
    }

    public static void blowup(int n) throws Hi_Exception, Lo_Exception {
    if ((n % 2) == 0) {
        throw new Lo_Exception(n);
    } else {
        throw new Hi_Exception(n);
    }
    }
}
except.lcc
/* -*- mode: c -*-
 * $Id: except.gcc,v 1.1 2001/01/07 04:31:15 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 */

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>

int HI = 0, LO = 0;

static jmp_buf Hi_exception;
static jmp_buf Lo_exception;

void blowup (int n) {
    if (n & 1) {
    longjmp(Lo_exception, 1);
    } else {
    longjmp(Hi_exception, 1);
    }
}

void lo_function (volatile int n) {
    if (setjmp(Lo_exception) != 0) {
    LO++;
    } else {
    blowup(n);
    }
}

void hi_function (volatile int n) {
    if (setjmp(Hi_exception) != 0) {
    HI++;
    } else {
    lo_function(n);
    }
}

void some_function (int n) {
    hi_function(n);
}

int
main(int argc, char *argv[]) {
    int volatile N = ((argc == 2) ? atoi(argv[1]) : 1);

    while (N) {
    some_function(N--);
    }
    printf("Exceptions: HI=%d / LO=%d\n", HI, LO);
    return(0);
}
except.lua
-- $Id: except.lua,v 1.1 2001/01/16 14:27:55 doug Exp $
-- http://www.bagley.org/~doug/shootout/
-- from Roberto Ierusalimschy

-- uses `call' to catch errors; return the error message
-- (or nil if there are no errors)

function try (f, ...)
  call(f, arg, "x", function (msg) %arg.msg = msg end)
  return arg.msg
end


HI = 0
LO = 0

function some_function (n)
  local res = try(hi_function, n)
  if res then print("We shouldn't get here: " .. res) end
end


function hi_function (n)
  local res = try(lo_function, n)
  if res == "Hi_Exception" then HI = HI+1 
  elseif res then error(res)  -- rethrow
  end
end


function lo_function (n)
  local res = try(blowup, n)
  if res == "Lo_Exception" then LO = LO+1 
  elseif res then error(res)  -- rethrow
  end
end


function blowup (n)
  if mod(n,2) ~= 0 then error "Lo_Exception"
  else error "Hi_Exception"
  end
end


N = (arg and arg[1]) or 1
for i=1,N do
  some_function(i)
end

print(format("Exceptions: HI=%d / LO=%d", HI, LO))
except.lua5
-- $Id: except.lua,v 1.1 2001/01/16 14:27:55 doug Exp $
-- http://www.bagley.org/~doug/shootout/
-- contributed by Roberto Ierusalimschy

-- uses `call' to catch errors; return the error message
-- (or nil if there are no errors)

function try (f, arg)
  local status, err = pcall(f, arg)
  if not status then return err end
end


local HI = 0
local LO = 0

function some_function (n)
  local res = try(hi_function, n)
  if res then print("We shouldn't get here: " .. res) end
end


function hi_function (n)
  local res = try(lo_function, n)
  if res == "Hi_Exception" then HI = HI+1 
  elseif res then error(res, 0)  -- rethrow
  end
end


function lo_function (n)
  local res = try(blowup, n)
  if res == "Lo_Exception" then LO = LO+1 
  elseif res then error(res, 0)  -- rethrow
  end
end


function blowup (n)
  if math.mod(n,2) ~= 0 then error("Lo_Exception", 0)
  else error("Hi_Exception", 0)
  end
end


N = (arg and arg[1]) or 1
for i=1,N do
  some_function(i)
end

print(string.format("Exceptions: HI=%d / LO=%d", HI, LO))

except.mingw32
/* -*- mode: c -*-
 * $Id: except.gcc,v 1.1 2001/01/07 04:31:15 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 */

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>

int HI = 0, LO = 0;

static jmp_buf Hi_exception;
static jmp_buf Lo_exception;

void blowup (int n) {
    if (n & 1) {
    longjmp(Lo_exception, 1);
    } else {
    longjmp(Hi_exception, 1);
    }
}

void lo_function (volatile int n) {
    if (setjmp(Lo_exception) != 0) {
    LO++;
    } else {
    blowup(n);
    }
}

void hi_function (volatile int n) {
    if (setjmp(Hi_exception) != 0) {
    HI++;
    } else {
    lo_function(n);
    }
}

void some_function (int n) {
    hi_function(n);
}

int
main(int argc, char *argv[]) {
    int volatile N = ((argc == 2) ? atoi(argv[1]) : 1);

    while (N) {
    some_function(N--);
    }
    printf("Exceptions: HI=%d / LO=%d\n", HI, LO);
    return(0);
}
except.modula2
(* The Great Win32 Language Shootout http://dada.perl.it/shootout/

   contributed by Isaac Gouy (Modula2 novice)

   To build: xc =m except
   To run:   except 200000
*)

MODULE Except;
<* procinline + *>

(* Prefer unqualified procedures *)
FROM LanguageShootout IMPORT N;

IMPORT EXCEPTIONS;
FROM STextIO IMPORT WriteString, WriteLn;
FROM SWholeIO IMPORT WriteCard;


VAR lo, hi: CARDINAL;
    n, i: CARDINAL;
    source: EXCEPTIONS.ExceptionSource;

TYPE Exceptions = (Lo_Exception, Hi_Exception);


PROCEDURE Exception(): Exceptions;
BEGIN
   RETURN VAL(Exceptions, EXCEPTIONS.CurrentNumber(source));
END Exception;


PROCEDURE BlowUp(i: CARDINAL);
BEGIN
   IF ODD(i) THEN
      EXCEPTIONS.RAISE(source, ORD(Hi_Exception), "HI Exception");
   ELSE
      EXCEPTIONS.RAISE(source, ORD(Lo_Exception), "LO Exception");
   END;
END BlowUp;


PROCEDURE Lo_Function(i: CARDINAL);
BEGIN
   BlowUp(i);
EXCEPT
   IF Exception() = Lo_Exception THEN
      INC(lo);
      RETURN;
   END;
END Lo_Function;


PROCEDURE Hi_Function(i: CARDINAL);
BEGIN
   Lo_Function(i);
EXCEPT
   IF Exception() = Hi_Exception THEN
      INC(hi);
      RETURN;	
   END;
END Hi_Function;


PROCEDURE Some_Function(i: CARDINAL);
BEGIN
   Hi_Function(i);
EXCEPT
   WriteString("We shouldn't get here!");
   WriteLn;
   RETURN;
END Some_Function;


BEGIN
   n := N();
   lo := 0;
   hi := 0;
   EXCEPTIONS.AllocateSource(source);

   WHILE n > 0 DO
      DEC(n);
      Some_Function(i);
   END;  	

   WriteString("Exceptions: HI="); WriteCard(hi,1);
   WriteString(" / LO="); WriteCard(lo,1); WriteLn;
END Except.
except.nice
/* The Great Win32 Language Shootout http://dada.perl.it/shootout/ 
   contributed by Isaac Gouy (Nice novice)

To compile:	
   nicec --sourcepath=.. -d=. -a except.jar except

To run:
   java -jar except.jar 20000
*/


import ackermann; // reuse toSingleInt


void main(String[] args){
   let n = toSingleInt(args);

   for(var i=0; i
except.ocaml
(*
 * $Id: except.ocaml,v 1.6 2001/07/28 21:52:57 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 * with help from Markus Mottl
 * and Mark Baker
 *)

exception HiException of int
exception LoException of int

let hi = ref 0
let lo = ref 0

let blowup n =
  if n mod 2 = 0 then raise (LoException n)
  else raise (HiException n)

let lo_fun n = try blowup n with LoException _ -> incr lo
let hi_fun n = try lo_fun n with HiException _ -> incr hi

let some_fun n =
  try hi_fun n with exc -> print_endline "Should not get here."; raise exc

let _ =
  let n = if Array.length Sys.argv > 1 then int_of_string Sys.argv.(1) else 1 in
  for i = 1 to n do some_fun i done;
  Printf.printf "Exceptions: HI=%d / LO=%d\n" !hi !lo
except.ocamlb
(*
 * $Id: except.ocaml,v 1.6 2001/07/28 21:52:57 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 * with help from Markus Mottl
 * and Mark Baker
 *)

exception HiException of int
exception LoException of int

let hi = ref 0
let lo = ref 0

let blowup n =
  if n mod 2 = 0 then raise (LoException n)
  else raise (HiException n)

let lo_fun n = try blowup n with LoException _ -> incr lo
let hi_fun n = try lo_fun n with HiException _ -> incr hi

let some_fun n =
  try hi_fun n with exc -> print_endline "Should not get here."; raise exc

let _ =
  let n = if Array.length Sys.argv > 1 then int_of_string Sys.argv.(1) else 1 in
  for i = 1 to n do some_fun i done;
  Printf.printf "Exceptions: HI=%d / LO=%d\n" !hi !lo
except.oz
%%% $Id: except.oz,v 1.0 2002/08/19 16:19:00 dada Exp $
%%% http://dada.perl.it/shootout/
%%% 
%%% contributed by Isaac Gouy

%%  Usage: start from command line with
%%     ozc -x except.oz -o except.oz.exe
%%     except.oz.exe 2000

functor
import System Application

define

   LoCount
   HiCount
   
   proc {Blowup N}
      if N mod 2 == 0 then raise loException() end
      else raise hiException() end end
   end

   proc {LoFun N}
      try {Blowup N} catch
     loException then {Assign LoCount {Access LoCount}+1}
      end
   end

   proc {HiFun N}
      try {LoFun N} catch
     hiException then {Assign HiCount {Access HiCount}+1}
      end
   end

   proc {SomeFun N}
      if N > 0 then
     try {HiFun N} catch
        loException then {System.showInfo 'loException should not get here'}
        [] hiException then {System.showInfo 'hiException should not get here'}
     end
     {SomeFun N-1}
      end
   end
in
   local Args N in
      [Args] = {Application.getArgs plain}
      N = {String.toInt Args}

      LoCount = {NewCell 0}
      HiCount = {NewCell 0}
      {SomeFun N}

      {System.printInfo "Exceptions: HI="}
      {System.printInfo {Access HiCount}}
      {System.printInfo " / LO="}
      {System.showInfo {Access LoCount}}
   end
   {Application.exit 0}
end

except.perl
#!/usr/local/bin/perl
# $Id: except.perl,v 1.5 2001/05/27 00:23:52 doug Exp $
# http://www.bagley.org/~doug/shootout/

use integer;

my $HI = 0;
my $LO = 0;
my $NUM = $ARGV[0];
$NUM = 1 if ($NUM < 1);

package Lo_Exception;

sub new {
    bless({Val => shift}, __PACKAGE__);
}

package Hi_Exception;

sub new {
    bless({Val => shift}, __PACKAGE__);
}

package main;

sub some_function {
    my $num = shift;
    eval {
    &hi_function($num);
    };
    if ($@) {
    die "We shouldn't get here ($@)";
    }
}

sub hi_function {
    my $num = shift;
    eval {
    &lo_function($num);
    };
    if (ref($@) eq "Hi_Exception") {
    $HI++;        # handle
    } elsif ($@) {
    die $@;        # rethrow
    }
}

sub lo_function {
    my $num = shift;
    eval {
    &blowup($num);
    };
    if (ref($@) eq "Lo_Exception") {
    $LO++;        # handle
    } elsif ($@) {
    die $@;        # rethrow
    }
}

sub blowup {
    my $num = shift;
    if ($num % 2) {
    die Lo_Exception->new(Num => $num);
    } else {
    die Hi_Exception->new(Num => $num);
    }
}

$NUM = $ARGV[0];
while ($NUM--) {
    &some_function($NUM);
}
print "Exceptions: HI=$HI / LO=$LO\n";
except.pike
#!/usr/local/bin/pike// -*- mode: pike -*-
// $Id: except.pike,v 1.2 2000/12/05 16:04:06 doug Exp $
// http://www.bagley.org/~doug/shootout/
// from: Per Hedbor

// this version requires Pike 7.1

class HiException( mixed value ) { constant IsHi = 1; }
class LoException( mixed value ) { constant IsLo = 1; }

void some_function( int num )
{
    if( mixed e = catch(  hi_function( num ) ) )
    error( "We shouldn't get here (%s)", describe_error( e ) );
}
  
int HI, LO;

void hi_function(int num)
{
    if( mixed e = catch( lo_function( num ) ) )
    if( e->IsHi )
        HI++;
    else
        throw( e );
}
  
void lo_function(int num)
{
    if( mixed e = catch(  blowup(num) ) )
    if( e->IsLo )
        LO++;
    else
        throw( e );
}
  
  
void blowup(int num)
{
    if( num & 1 )
    throw( LoException(num) );
    else
    throw( HiException(num) );
}
  
void main(int argc, array argv)
{
    int num = (int)argv[-1];
    if( num < 1 )
    num = 1;
    while(num)
    some_function( num-- );
    write( "Exceptions: HI=%d / LO=%d\n" , HI, LO );
}
except.poplisp
;;; -*- mode: lisp -*-
;;; $Id: except.cmucl,v 1.2 2001/01/01 17:51:53 doug Exp $
;;; http://www.bagley.org/~doug/shootout/
;;; From: Friedrich Dominicus

(defparameter *hi* 0)
(defparameter *lo* 0)

(defun some-fun (n)
  (catch t
    (hi-fun n)))

(defun hi-fun (n)
  (catch 'Hi_Exception
    (lo-fun n)))
  
(defun lo-fun (n)
  (catch 'Lo_Exception
    (blow-up n))) 
  
(defun blow-up (n)
  (if (evenp n)
      (throw 'Hi_Exception (setf *hi* (1+ *hi*)))
    (throw 'Lo_Exception (setf *lo* (1+ *lo*)))))

  (let ((n (parse-integer (or (car pop11::poparglist) "1"))))
  (setf *hi* 0
    *lo* 0)
  (do ((i 0 (1+ i)))
      ((= i n))
    (some-fun i)))
  (format t "Exceptions: HI=~A / LO=~A~%" *hi* *lo*)
except.python
#!/usr/local/bin/python
# http://www.bagley.org/~doug/shootout/

import sys

HI = 0
LO = 0


class Hi_exception:
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return `self.value`


class Lo_exception:
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return `self.value`


def some_function(num):
    try:
        hi_function(num)
    except:
        raise "We shouldn't get here (%s)" % sys.exc_info()[0]


def hi_function(num):
    global HI
    try:
        lo_function(num)
    except Hi_exception, ex:
        HI += 1
        #print 'Hi_exception occurred, value:', ex.value


def lo_function(num):
    global LO
    try:
        blowup(num)
    except Lo_exception, ex:
        LO += 1
        #print 'Lo_exception occurred, value:', ex.value


def blowup(num): 
    raise (((num & 1) and Lo_exception) or Hi_exception)(num)

def main():
    global LO, HI
    NUM = int(sys.argv[1])
    if NUM < 1:
        NUM = 1
    for i in xrange(NUM-1,-1,-1):
        some_function(i)
    print "Exceptions: HI=%d / LO=%d" % (HI, LO)


main()
except.ruby
#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# $Id: except.ruby,v 1.3 2000/10/07 08:41:43 doug Exp $
# http://www.bagley.org/~doug/shootout/

$HI = 0
$LO = 0
NUM = Integer(ARGV[0] || 1)


class Lo_Exception < Exception
    def initialize(num)
        @value = num
        return self
    end
end

class Hi_Exception < Exception
    def initialize(num)
        @value = num
        return self
    end
end

def some_function(num)
    begin
    hi_function(num)
    rescue
        print "We shouldn't get here, exception is: #{$!.type}\n"
    end
end

def hi_function(num)
    begin
    lo_function(num)
    rescue Hi_Exception
    $HI = $HI + 1
    end
end

def lo_function(num)
    begin
    blowup(num)
    rescue Lo_Exception
    $LO = $LO + 1
    end
end

def blowup(num)
    if num % 2 == 0
    raise Lo_Exception.new(num)
    else
    raise Hi_Exception.new(num)
    end
end


for iter in 1 .. NUM
    some_function(iter)
end
print "Exceptions: HI=", $HI, " / LO=", $LO, "\n"
except.se
-- -*- mode: eiffel -*-
-- $Id: except.se,v 1.2 2001/05/23 18:26:02 doug Exp $
-- http://www.bagley.org/~doug/shootout/
-- from: Friedrich Dominicus

-- <LOC-OFF>
indexing
    description: "Eiffel implementation of the Exceptions "
                 "in the shootout examples";
    note: "Tested with SmallEiffel and ISE-Eiffel"
-- <LOC-ON>

class
    EXCEPT

inherit 
    ARGUMENTS
creation

    make

feature -- Initialization

    high: INTEGER;
    low: INTEGER;

    high_exception: STRING is "high_exception";
    low_exception: STRING is "low_exception";

    run_n, outer_i: INTEGER;
    

    exc: EXCEPTIONS;
    
    make is
        do
            create exc;
            if argument_count /= 1 then
                io.put_string("exception_test <integer>%N");
                exc.die(1);
            end;
            if argument(1).is_integer then
                run_n := argument(1).to_integer;
            else
                io.put_string("Argument wasn't an integer, giving up%N");
                exc.die(1);
            end;
            outer_i := 1;
            some_fun(run_n);
        end;
    
    some_fun(n: INTEGER) is
        do
            from 
            invariant
                i_in_bounds: outer_i >= 1 and then outer_i <= n + 1;
            variant
                really_decreasing: n - outer_i + 1
            until outer_i > run_n
            loop
                high_fun(outer_i);
                -- an exception should be raised somwehere below
                -- `high_fun' in the call chain
                exc.raise("should not come here%N")
                -- outer_i := outer_i + 1
            end;
            io.put_string("Exceptions: HI=");
            io.put_integer(high);
            io.put_string(" / LO=");
            io.put_integer(low);
            io.put_character('%N');
        rescue
            outer_i := outer_i + 1;
            retry;
        end;
    
    
    high_fun (i: INTEGER) is
        do
            low_fun(i);
        rescue
            if exc.developer_exception_name.is_equal(high_exception)
then
                high := high + 1;
            end
        end;
    
    
    low_fun (i: INTEGER) is
        do
            -- exc.catch(exc.Developer_exception);
            blow_up(i);
        rescue
            if exc.developer_exception_name.is_equal(low_exception) then
                low := low + 1;
            end
        end;
    

    blow_up (i : INTEGER) is
        do
            if ((i \\ 2) = 0) then
                exc.raise(low_exception);
            else
                exc.raise(high_exception);
            end;
        end;

end -- class EXCEPT
except.smlnj
(* -*- mode: sml -*-
 * $Id: except.smlnj,v 1.2 2001/07/09 00:25:27 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 * Translated from except.ocaml by Stephen Weeks
 *)

structure Test : sig
    val main : (string * string list) -> OS.Process.status
end = struct

fun incr r = r := !r + 1
fun print_endline s = (print s; print "\n")
fun for (start, stop, f) =
   let
      fun loop i =
     if i > stop
        then ()
     else (f i; loop (i + 1))
   in
      loop start
   end
   
exception HiException of int
exception LoException of int

val hi = ref 0
val lo = ref 0

fun blowup n =
  if n mod 2 = 0 then raise (LoException n)
  else raise (HiException n)

fun lo_fun n =
  blowup n
  handle LoException ex => incr lo

fun hi_fun n =
  lo_fun n
  handle HiException ex => incr hi

fun some_fun n =
  hi_fun n
  handle x =>
     (print_endline "Should not get here.";
      raise x)

fun atoi s = case Int.fromString s of SOME num => num | NONE => 0;
fun printl [] = print "\n" | printl(h::t) = ( print h ; printl t );
   
fun main (name, args) =
   let
      val n = atoi (hd (args @ ["1"]))
      val _ = for (1, n, some_fun)
   in
      printl ["Exceptions: HI=",
          Int.toString (!hi),
          " / LO=",
          Int.toString (!lo)];
      OS.Process.success
   end
end

val _ = SMLofNJ.exportFn("except", Test.main);
except.tcl
#!/usr/local/bin/tclsh
# $Id: except.tcl,v 1.5 2001/07/13 02:49:42 doug Exp $
# http://www.bagley.org/~doug/shootout/
# with help from Kristoffer Lawson
# modified by Miguel Sofer

set HI 0
set LO 0

proc some_function {num} {
    if {[catch {hi_function $num} result]} {
        puts stderr "We shouldn't get here ($result)"
    }
}

proc hi_function {num} {
    if {[set exc [catch {lo_function $num}]] == 11} {
        # handle
    incr ::HI
    } else {
        # rethrow
    return -code $exc
    }
}

proc lo_function {num} {
    if {[set exc [catch {blowup $num}]] == 10} {
        # handle
    incr ::LO
    } else {
        # rethrow
    return -code $exc
    }
}

proc blowup {num} {
    if {$num % 2} {
        #error "Lo_exception"
    return -code 10
    } else {
        #error "Hi_exception"
    return -code 11
    }
}

proc main {} {
    global argv HI LO
    set NUM [lindex $argv 0]
    if {$NUM < 1} {
        set NUM 1
    }
    incr NUM
    while {[incr NUM -1]} {
        some_function $NUM
    }
    puts "Exceptions: HI=$HI / LO=$LO"
}

main
except.vc
/* -*- mode: c -*-
 * $Id: except.gcc,v 1.1 2001/01/07 04:31:15 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 */

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>

int HI = 0, LO = 0;

static jmp_buf Hi_exception;
static jmp_buf Lo_exception;

void blowup (int n) {
    if (n & 1) {
    longjmp(Lo_exception, 1);
    } else {
    longjmp(Hi_exception, 1);
    }
}

void lo_function (volatile int n) {
    if (setjmp(Lo_exception) != 0) {
    LO++;
    } else {
    blowup(n);
    }
}

void hi_function (volatile int n) {
    if (setjmp(Hi_exception) != 0) {
    HI++;
    } else {
    lo_function(n);
    }
}

void some_function (int n) {
    hi_function(n);
}

int
main(int argc, char *argv[]) {
    int volatile N = ((argc == 2) ? atoi(argv[1]) : 1);

    while (N) {
    some_function(N--);
    }
    printf("Exceptions: HI=%d / LO=%d\n", HI, LO);
    return(0);
}
except.vc++
// -*- mode: c++ -*-
// $Id: except.g++,v 1.4 2001/06/20 03:20:02 doug Exp $
// http://www.bagley.org/~doug/shootout/
// from Bill Lear

#include <iostream>
#include <cstdlib>
#include <cstdio>

using namespace std;

size_t HI = 0;
size_t LO = 0;

class Hi_exception {
public:
    explicit Hi_exception(size_t _n) : n(_n) {}
    const char* what() { sprintf(N, "%d", n); return N; }
private:
    size_t n; char N[8];
};

class Lo_exception {
public:
    explicit Lo_exception(size_t _n) : n(_n) {}
    const char* what() { sprintf(N, "%d", n); return N; }
private:
    size_t n; char N[8];
};

void blowup(size_t num) {
    if (num % 2) {
        throw Lo_exception(num);
    }
    throw Hi_exception(num);
}

void lo_function(size_t num) {
    try {
        blowup(num);
    } catch(const Lo_exception& ex) {
        ++LO;
    }
}

void hi_function(size_t num) {
    try {
        lo_function(num);
    } catch(const Hi_exception& ex) {
        ++HI;
    }
}

void some_function(size_t num) {
    try {
        hi_function(num);
    } catch (...) {
        cerr << "We shouldn't get here\n"; exit(1);
    }
}

int
main(int argc, char* argv[]) {
    size_t NUM = (argc == 2 ? (atoi(argv[1]) < 1 ? 1 : atoi(argv[1])): 1);
    while (NUM--) {
        some_function(NUM);
    }
    cout << "Exceptions: HI=" << HI << " / " << "LO=" << LO << endl;
}