;; -*- Mode: Irken -*- (include "lib/core.scm") (include "lib/random.scm") (define (base-exception-handler exn) : ((rsum 'a) -> 'b) (error1 "uncaught exception" exn)) (define *the-exception-handler* base-exception-handler) (define (raise exn) (*the-exception-handler* exn) ) (defmacro try ;; done accumulating body parts, finish up. (try (begin body0 ...) exn-match ...) -> (let/cc $exn-k (let (($old-hand *the-exception-handler*)) (set! *the-exception-handler* (lambda ($exn) (set! *the-exception-handler* $old-hand) ($exn-k (match $exn with exn-match ... _ -> (raise $exn))))) (let (($result (begin body0 ...))) (set! *the-exception-handler* $old-hand) $result))) ;; accumulating body parts... (try (begin body0 ...) body1 body2 ...) -> (try (begin body0 ... body1) body2 ...) ;; begin to accumulate... (try body0 body1 ...) -> (try (begin body0) body1 ...) ) (define (random-barf) (if (= (logand (random) 1) 1) (raise (:OtherException #t #t)) 7)) (define (thing) (try (let loop ((n 0)) (if (= n 100) (raise (:MyException 12)) (begin (random-barf) (loop (+ n 1))))) except (:MyException value) -> value (:OtherException x) -> (+ x 9) )) (thing)