summaryrefslogtreecommitdiff
path: root/modules/language/python/with.scm
blob: 0193189a2185137a9355ac81b5c5eadd093a145e (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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))))