summaryrefslogtreecommitdiff
path: root/modules/language/python/with.scm
diff options
context:
space:
mode:
Diffstat (limited to 'modules/language/python/with.scm')
-rw-r--r--modules/language/python/with.scm53
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))))
+
+
+
+
+
+