Alternate guard form - evaluate the guard clauses in the continuation of the raise.

We need to override the current-exception-handler and still pass a thunk to be
applied on return, but this allows us to print stack traces inside guards.
This commit is contained in:
Alex Shinn 2013-04-03 00:18:58 +09:00
parent af8aed4c5a
commit 0f723c17ea

View file

@ -923,22 +923,26 @@
(define-syntax guard (define-syntax guard
(syntax-rules () (syntax-rules ()
((guard (var clause ...) e1 e2 ...) ((guard (var clause ...) e1 e2 ...)
(let ((orig-handler (current-exception-handler)))
((call-with-current-continuation ((call-with-current-continuation
(lambda (guard-k) (lambda (guard-k)
(with-exception-handler (with-exception-handler
(lambda (condition) (lambda (condition)
((call-with-current-continuation ((call-with-current-continuation
(lambda (handler-k) (lambda (handler-k)
(guard-k (let* ((var condition) ; clauses may set! var
(res
(with-exception-handler
orig-handler
(lambda () (lambda ()
(let ((var condition)) (guard-aux
(guard-aux (handler-k (lambda () (handler-k (lambda ()
(raise-continuable condition))) (raise-continuable condition)))
clause ...)))))))) clause ...)))))
(guard-k (lambda () res)))))))
(lambda () (lambda ()
(call-with-values (lambda () e1 e2 ...) (let ((res (begin e1 e2 ...)))
(lambda args (guard-k (lambda () res))))))))))))
(guard-k (lambda () (apply values args)))))))))))))
(define-syntax guard-aux (define-syntax guard-aux
(syntax-rules (else =>) (syntax-rules (else =>)