~ chicken-r7rs (master) 9569944c5b71dd2a476f72ee24dce17d3a3ab87c
commit 9569944c5b71dd2a476f72ee24dce17d3a3ab87c
Author: Evan Hanson <evhan@foldling.org>
AuthorDate: Thu May 30 08:43:45 2013 +0000
Commit: Evan Hanson <evhan@foldling.org>
CommitDate: Thu May 30 08:43:45 2013 +0000
First cut at exception semantics
diff --git a/r7rs.scm b/r7rs.scm
index 583817c..ae86f7b 100644
--- a/r7rs.scm
+++ b/r7rs.scm
@@ -1,7 +1,10 @@
(module r7rs
(
+ ;; Exception handling
+ guard
;; Exceptions
+ with-exception-handler
raise
raise-continuable
error-object?
@@ -9,7 +12,6 @@
error-object-irritants
read-error?
file-error?
- ; TODO guard
;; System interface
command-line
exit
@@ -37,12 +39,108 @@
#t)
(else (old-hook char port))))))
+;;;
+;;; 4.2.7. Exception handling
+;;;
+
+;; guard & guard-aux copied verbatim from the draft.
+(define-syntax guard
+ (syntax-rules ()
+ ((guard (var clause ...) e1 e2 ...)
+ ((call/cc
+ (lambda (guard-k)
+ (with-exception-handler
+ (lambda (condition)
+ ((call/cc
+ (lambda (handler-k)
+ (guard-k
+ (lambda ()
+ (let ((var condition))
+ (guard-aux
+ (handler-k
+ (lambda ()
+ (raise-continuable condition)))
+ clause ...))))))))
+ (lambda ()
+ (call-with-values
+ (lambda () e1 e2 ...)
+ (lambda args
+ (guard-k
+ (lambda ()
+ (apply values args)))))))))))))
+
+(define-syntax guard-aux
+ (syntax-rules (else =>)
+ ((guard-aux reraise (else result1 result2 ...))
+ (begin result1 result2 ...))
+ ((guard-aux reraise (test => result))
+ (let ((temp test))
+ (if temp
+ (result temp)
+ reraise)))
+ ((guard-aux reraise (test => result)
+ clause1 clause2 ...)
+ (let ((temp test))
+ (if temp
+ (result temp)
+ (guard-aux reraise clause1 clause2 ...))))
+ ((guard-aux reraise (test))
+ (or test reraise))
+ ((guard-aux reraise (test) clause1 clause2 ...)
+ (let ((temp test))
+ (if temp
+ temp
+ (guard-aux reraise clause1 clause2 ...))))
+ ((guard-aux reraise (test result1 result2 ...))
+ (if test
+ (begin result1 result2 ...)
+ reraise))
+ ((guard-aux reraise
+ (test result1 result2 ...)
+ clause1 clause2 ...)
+ (if test
+ (begin result1 result2 ...)
+ (guard-aux reraise clause1 clause2 ...)))))
+
;;;
;;; 6.11. Exceptions
;;;
-(define raise abort)
-(define raise-continuable signal)
+(define-values (with-exception-handler raise raise-continuable)
+ (let ((exception-handlers
+ (let ((lst (list ##sys#current-exception-handler)))
+ (set-cdr! lst lst)
+ lst)))
+ (values
+ ;; with-exception-handler
+ (lambda (handler thunk)
+ (dynamic-wind
+ (lambda ()
+ (set! exception-handlers (cons handler exception-handlers))
+ (set! ##sys#current-exception-handler handler))
+ thunk
+ (lambda ()
+ (set! exception-handlers (cdr exception-handlers))
+ (set! ##sys#current-exception-handler (car exception-handlers)))))
+ ;; raise
+ (lambda (obj)
+ (with-exception-handler
+ (cadr exception-handlers)
+ (lambda ()
+ ((cadr exception-handlers) obj)
+ ((car exception-handlers)
+ (make-property-condition
+ 'exn
+ 'message "exception handler returned"
+ 'arguments '()
+ 'location #f)))))
+ ;; raise-continuable
+ (lambda (obj)
+ (with-exception-handler
+ (cadr exception-handlers)
+ (lambda ()
+ ((cadr exception-handlers) obj)))))))
+
(define error-object? condition?)
(define error-object-message (condition-property-accessor 'exn 'message))
(define error-object-irritants (condition-property-accessor 'exn 'arguments))
Trap