(define-module (language python for) #:use-module (language python yield) #:use-module (oop pf-objects) #:use-module (language python exceptions) #:use-module (oop goops) #:use-module (ice-9 control) #:export (for break next wrap-in)) (define-syntax-rule (aif it p x y) (let ((it p)) (if it x y))) (eval-when (compile eval load) (define (generate-temporaries2 x) (map (lambda (x) (generate-temporaries x)) x))) (define-syntax-parameter break (lambda (x) #f)) (define-syntax for (syntax-rules (:) ((for ((x ... : E) ...) ((c n) ...) code ... #:final fin) (for-work #f ((x ... : E) ...) ((c n) ...) (code ...) fin)) ((for lp ((x ... : E) ...) ((c n) ...) code ... #:final fin) (for-work lp ((x ... : E) ...) ((c n) ...) (code ...) fin)) ((for ((x ... : E) ...) ((c n) ...) code ...) (for-work #f ((x ... : E) ...) ((c n) ...) (code ...) (values))) ((for lp ((x ... : E) ...) ((c n) ...) code ...) (for-work lp ((x ... : E) ...) ((c n) ...) (code ...) (values))))) (define-syntax for-work (lambda (x) (define (wrap-continue lp code) (if (syntax->datum lp) #`(lambda () (let/ec #,lp #,@code)) #`(lambda () #,@code))) (syntax-case x () ((for lp ((x ... : E) ...) ((c n) ...) (code ...) fin) (with-syntax (((It ...) (generate-temporaries #'(E ...))) ((cc ...) (generate-temporaries #'(c ...))) (((x1 ...) ...) (generate-temporaries2 #'((x ...) ...))) (((x2 ...) ...) (generate-temporaries2 #'((x ...) ...))) (llp (if (syntax->datum #'lp) #'lp #'lpu))) #`(let/ec lp-break (syntax-parameterize ((break (lambda (z) (syntax-case z () ((_ . l) #'(lp-break . l)) (_ #'lp-break))))) (let ((It (wrap-in E)) ... (c n ) ... (x 'None ) ... ... (x1 #f ) ... ...) (catch StopIteration (lambda () (let llp ((cc c) ...) (set! c cc) ... (call-with-values (lambda () (next It)) (lambda (x2 ...) (set! x1 x2) ...)) ... (set! x x1) ... ... (call-with-values #,(wrap-continue #'lp #'(code ...)) (lambda (cc ... . q) (llp cc ...))))) (lambda q fin)))))))))) (define-class () l) (define-class () s i) (define-method (next (l )) (let ((ll (slot-ref l 'l))) (if (pair? ll) (begin (slot-set! l 'l (cdr ll)) (car ll)) (throw StopIteration)))) (define-method (next (l )) (let ((s (slot-ref l 's)) (i (slot-ref l 'i))) (if (= i (string-length s)) (throw StopIteration) (begin (slot-set! l 'i (+ i 1)) (string-ref s i))))) (define-method (next (l )) (let ((k (slot-ref l 'k)) (s (slot-ref l 's))) (if k (k (lambda () 'None)) (s)))) (define-method (next (l

)) ((ref l '__next__))) (define-method (wrap-in (x

)) (aif it (ref x '__iter__ #f) (it) x)) (define-method (wrap-in x) (cond ((pair? x) (let ((o (make ))) (slot-set! o 'l x) o)) ((string? x) (let ((o (make ))) (slot-set! o 's x) (slot-set! o 'i 0) o)) (else x))) #; (pk (for c ((x : (gen '(1 2 3)))) ((s 0)) (pk x) (if (> x 2) (c s)) (+ s x) #:final s))