diff options
Diffstat (limited to 'modules/language/python/with.scm')
-rw-r--r-- | modules/language/python/with.scm | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/modules/language/python/with.scm b/modules/language/python/with.scm new file mode 100644 index 0000000..eab5c55 --- /dev/null +++ b/modules/language/python/with.scm @@ -0,0 +1,53 @@ +(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)))) + + + + + + |