(define-module (language python with) #:use-module (language python try) #:use-module (language python exceptions) #:use-module (oop pf-objects) #:export (with)) (define-syntax-rule (aif it p x y) (let ((it p)) (if it x y))) (define-syntax with (syntax-rules () ((_ () . code) (begin . code)) ((_ (x . l) . code) (with0 x (with l . code))))) (define-syntax with0 (syntax-rules () ((_ (id exp) . code) (let ((type None) (value None) (trace None)) (aif exit (ref exp '__exit__) (aif enter (ref exp '__enter__) (try (lambda () (let ((id (enter))) . code)) (#:except #t => (lambda (tag l) (set! type (if (pyclass? tag) tag (aif it (ref tag '__class__) it tag))) (set! value (aif it (ref tag 'value) it (if (pair? l) (car l) None))))) #:finally (lambda () (exit type value trace))) (raise TypeError "no __enter__ member")) (raise TypeError "no __exit__ member")))) ((_ (exp) . code) (with0 (id exp) . code))))