| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | ;; iterators.scm - iterators for goof-loop.  | 
					
						
							|  |  |  | ;; | 
					
						
							| 
									
										
										
										
											2021-03-18 12:41:39 +01:00
										 |  |  | ;; Copyright 2020-2021 Linus Björnstam | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | ;; Copyright 2000-2015 Alex Shinn (original author of chibi-loop) | 
					
						
							|  |  |  | ;; All rights reserved. | 
					
						
							|  |  |  | ;; | 
					
						
							|  |  |  | ;; Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  | ;; modification, are permitted provided that the following conditions | 
					
						
							|  |  |  | ;; are met: | 
					
						
							|  |  |  | ;; 1. Redistributions of source code must retain the above copyright | 
					
						
							|  |  |  | ;;    notice, this list of conditions and the following disclaimer. | 
					
						
							|  |  |  | ;; 2. Redistributions in binary form must reproduce the above copyright | 
					
						
							|  |  |  | ;;    notice, this list of conditions and the following disclaimer in the | 
					
						
							|  |  |  | ;;    documentation and/or other materials provided with the distribution. | 
					
						
							|  |  |  | ;; 3. The name of the author(s) may not be used to endorse or promote products | 
					
						
							|  |  |  | ;;    derived from this software without specific prior written permission. | 
					
						
							|  |  |  | ;; | 
					
						
							|  |  |  | ;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 
					
						
							|  |  |  | ;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 
					
						
							|  |  |  | ;; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 
					
						
							|  |  |  | ;; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 
					
						
							|  |  |  | ;; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 
					
						
							|  |  |  | ;; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
					
						
							|  |  |  | ;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
					
						
							|  |  |  | ;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
					
						
							|  |  |  | ;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 
					
						
							|  |  |  | ;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ;; TODO iterators | 
					
						
							|  |  |  | ;; in-stream | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-09 13:30:02 +01:00
										 |  |  | (define-syntax in | 
					
						
							|  |  |  |   (syntax-rules ()  | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |     ((in :for ((var) (init)) n . rest) | 
					
						
							|  |  |  |      (n () ((var init var)) () () () . rest)) | 
					
						
							|  |  |  |     ((in :for ((var) (init step)) n . rest) | 
					
						
							|  |  |  |      (n () ((var init step)) () () () . rest)) | 
					
						
							|  |  |  |     ((in :for ((var) (init step stop)) n . rest) | 
					
						
							|  |  |  |      (n () ((var init step)) (stop) () () . rest)))) | 
					
						
							| 
									
										
										
										
											2020-11-09 13:30:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | (define-syntax in-list | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |   (syntax-rules (:for) | 
					
						
							| 
									
										
										
										
											2021-03-22 19:29:16 +01:00
										 |  |  |     ((in-list :for ((var) source) next . rest) | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |      (in-list :for ((var cursor) source) next . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-22 19:29:16 +01:00
										 |  |  |     ((in-list :for ((var cursor) source) next . rest) | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |      (in-list :for ((var cursor succ) source) next . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-22 19:29:16 +01:00
										 |  |  |     ((in-list :for ((var cursor succ) (source)) next . rest) | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |      (in-list :for ((var cursor succ) (source cdr)) next . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-22 19:29:16 +01:00
										 |  |  |     ((in-list :for ((var cursor succ) (source step)) next . rest) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  |      (next | 
					
						
							|  |  |  |       ;; outer let bindings, bound outside the loop, unchanged during the loop | 
					
						
							|  |  |  |       () | 
					
						
							|  |  |  |       ;; iterator, init, step | 
					
						
							|  |  |  |       ((cursor source succ)) | 
					
						
							|  |  |  |       ;; tests to check whether the iterator is exhausted. | 
					
						
							|  |  |  |       ((not (pair? cursor))) | 
					
						
							|  |  |  |       ;; loop variables (called refs) and updates. | 
					
						
							|  |  |  |       ((var (car cursor)) | 
					
						
							|  |  |  |        (succ (step cursor))) | 
					
						
							|  |  |  |       ;; final bindings: things bound in the final function. | 
					
						
							|  |  |  |       () | 
					
						
							|  |  |  |       ;; the continuation. | 
					
						
							| 
									
										
										
										
											2020-11-09 22:57:18 +01:00
										 |  |  |       . rest)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ;; Generator-clauses | 
					
						
							| 
									
										
										
										
											2021-03-22 19:29:16 +01:00
										 |  |  |     ((in-list lst) | 
					
						
							| 
									
										
										
										
											2020-11-09 22:57:18 +01:00
										 |  |  |      (gen-list lst)) | 
					
						
							| 
									
										
										
										
											2021-03-22 19:29:16 +01:00
										 |  |  |     ((in-list (var) (expr step)) | 
					
						
							| 
									
										
										
										
											2020-11-09 22:57:18 +01:00
										 |  |  |      (gen-list lst step)))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define gen-list | 
					
						
							|  |  |  |   (case-lambda | 
					
						
							|  |  |  |     ((lst) | 
					
						
							|  |  |  |      (gen-list lst cdr)) | 
					
						
							|  |  |  |     ((lst by) | 
					
						
							|  |  |  |      (lambda () | 
					
						
							|  |  |  |        (if (null? lst) | 
					
						
							|  |  |  |            (eof-object) | 
					
						
							|  |  |  |            (let ((res (car lst))) | 
					
						
							|  |  |  |              (set! lst (by lst)) | 
					
						
							|  |  |  |              res)))))) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define-syntax in-lists | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |   (syntax-rules (:for) | 
					
						
							|  |  |  |     ((in-lists :for ((elts) lol) next . rest) | 
					
						
							|  |  |  |      (in-lists :for ((elts pairs) lol) next . rest)) | 
					
						
							|  |  |  |     ((in-lists :for ((elts pairs) lol) next . rest) | 
					
						
							|  |  |  |      (in-lists :for ((elts pairs succ) lol) next . rest)) | 
					
						
							|  |  |  |     ((in-lists :for ((elts pairs succ) (lol)) next . rest) | 
					
						
							|  |  |  |      (in-lists :for ((elts pairs succ) (lol cdr)) next . rest)) | 
					
						
							|  |  |  |     ((in-lists :for ((elts pairs succ) (lol)) next . rest) | 
					
						
							|  |  |  |      (in-lists :for ((elts pairs succ) (lol cdr)) next . rest)) | 
					
						
							|  |  |  |     ((in-lists :for ((elts pairs succ) (lol step)) next . rest) | 
					
						
							|  |  |  |      (in-lists :for ((elts pairs succ) (lol step null?)) next . rest)) | 
					
						
							|  |  |  |     ((in-lists :for ((elts pairs succ) (lol step done?)) next . rest) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  |      (next () | 
					
						
							|  |  |  |            ((pairs lol succ)) | 
					
						
							|  |  |  |            ((let lp ((ls pairs)) ; an in-lined ANY | 
					
						
							|  |  |  |               (and (pair? ls) (if (done? (car ls)) #t (lp (cdr ls)))))) | 
					
						
							|  |  |  |            ((elts (map car pairs)) | 
					
						
							|  |  |  |             (succ (map step pairs))) | 
					
						
							|  |  |  |            () | 
					
						
							| 
									
										
										
										
											2021-02-18 22:06:59 +01:00
										 |  |  |            . rest)) | 
					
						
							|  |  |  |     ;; Generator clause | 
					
						
							|  |  |  |     ((in-lists lists ...) | 
					
						
							|  |  |  |      (gen-lists lists ...)))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  | ;; TODO: make this not slow. | 
					
						
							|  |  |  | (define (gen-lists . lists) | 
					
						
							|  |  |  |   (lambda () | 
					
						
							|  |  |  |     (if (any null? lists) | 
					
						
							|  |  |  |         (eof-object) | 
					
						
							|  |  |  |         (let ((cars (map car lists)) | 
					
						
							|  |  |  |               (cdrs (map cdr lists))) | 
					
						
							|  |  |  |           (set! lists cdrs) | 
					
						
							|  |  |  |           (values cars))))) | 
					
						
							|  |  |  |            | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | (define-syntax define-in-indexed | 
					
						
							|  |  |  |   (syntax-rules () | 
					
						
							|  |  |  |     ((define-in-indexed in-type in-type-reverse length ref) | 
					
						
							|  |  |  |      (begin | 
					
						
							|  |  |  |        (define-syntax in-type | 
					
						
							|  |  |  |          (syntax-rules () | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |            ((in-type :for seq next . rest) | 
					
						
							| 
									
										
										
										
											2021-03-11 14:37:20 +01:00
										 |  |  |             (%in-idx >= (lambda (x i) (+ i 1)) (lambda (x) 0) length ref tmp seq next . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |            ((in-type coll) | 
					
						
							| 
									
										
										
										
											2021-03-11 14:37:20 +01:00
										 |  |  |             (in-indexed-generator coll length ref)))) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  |        (define-syntax in-type-reverse | 
					
						
							|  |  |  |          (syntax-rules () | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |            ((in-type-reverse :for seq next . rest) | 
					
						
							| 
									
										
										
										
											2021-03-11 14:37:20 +01:00
										 |  |  |             (%in-idx < | 
					
						
							|  |  |  |                      (lambda (x i) (- i 1)) | 
					
						
							|  |  |  |                      (lambda (x) (- (length x) 1)) | 
					
						
							|  |  |  |                      (lambda (x) 0) ref tmp seq next . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |            ((in-type coll) | 
					
						
							| 
									
										
										
										
											2021-03-11 14:37:20 +01:00
										 |  |  |             (in-indexed-generator-reverse coll length ref)))))))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define (in-indexed-generator coll len ref) | 
					
						
							|  |  |  |   (let ((index -1) | 
					
						
							|  |  |  |         (length (len coll))) | 
					
						
							|  |  |  |     (lambda () | 
					
						
							|  |  |  |       (set! index (+ index 1)) | 
					
						
							|  |  |  |       (if (>= index length) | 
					
						
							|  |  |  |           (eof-object) | 
					
						
							|  |  |  |           (ref coll index))))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define (in-indexed-generator-reverse coll len ref) | 
					
						
							|  |  |  |   (let ((index (len coll))) | 
					
						
							|  |  |  |     (lambda () | 
					
						
							|  |  |  |       (set! index (- index 1)) | 
					
						
							|  |  |  |       (if (< index 0) | 
					
						
							|  |  |  |           (eof-object) | 
					
						
							|  |  |  |           (ref coll index))))) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | (define-in-indexed in-vector in-vector-reverse vector-length vector-ref) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define-in-indexed in-string in-string-reverse string-length string-ref) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ;; helper for the above string and vector iterators | 
					
						
							|  |  |  | (define-syntax %in-idx | 
					
						
							|  |  |  |   (syntax-rules () | 
					
						
							|  |  |  |     ;;   cmp inc start end ref | 
					
						
							|  |  |  |     ((%in-idx ge + s e r tmp ((var) (seq ...)) next . rest) | 
					
						
							|  |  |  |      (%in-idx ge + s e r tmp ((var seq-index) (seq ...)) next . rest)) | 
					
						
							|  |  |  |     ((%in-idx ge + s e r tmp ((var index) (seq)) next . rest) | 
					
						
							|  |  |  |      (%in-idx ge + s e r tmp ((var index) (seq (s tmp) (e tmp))) next . rest)) | 
					
						
							|  |  |  |     ((%in-idx ge + s e r tmp ((var index) (seq from)) next . rest) | 
					
						
							|  |  |  |      (%in-idx ge + s e r tmp ((var index) (seq from (e tmp))) next . rest)) | 
					
						
							|  |  |  |     ((%in-idx ge + s e r tmp ((var index) (seq from to)) next . rest) | 
					
						
							|  |  |  |      (next ((tmp seq) (end to)) | 
					
						
							|  |  |  |            ((index from (+ tmp index))) | 
					
						
							|  |  |  |            ((ge index end)) | 
					
						
							|  |  |  |            ((var (r tmp index))) | 
					
						
							|  |  |  |            () | 
					
						
							| 
									
										
										
										
											2021-05-12 12:54:29 +02:00
										 |  |  |        . rest)))) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | (define-syntax in-port | 
					
						
							|  |  |  |   (syntax-rules () | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |     ((in-port :for ((var) source) next . rest) | 
					
						
							|  |  |  |      (in-port :for ((var p) source) next . rest)) | 
					
						
							|  |  |  |     ((in-port :for ((var p) ()) next . rest) | 
					
						
							|  |  |  |      (in-port :for ((var p) ((current-input-port))) next . rest)) | 
					
						
							|  |  |  |     ((in-port :for ((var p) (port)) next . rest) | 
					
						
							|  |  |  |      (in-port :for ((var p) (port read-char)) next . rest)) | 
					
						
							|  |  |  |     ((in-port :for ((var p) (port read-char)) next . rest) | 
					
						
							|  |  |  |      (in-port :for ((var p) (port read-char eof-object?)) next . rest)) | 
					
						
							|  |  |  |     ((in-port :for ((var p) (port reader eof?)) next . rest) | 
					
						
							| 
									
										
										
										
											2020-12-01 20:54:42 +01:00
										 |  |  |      (next ((p port)) | 
					
						
							|  |  |  |            ((var (reader p) (reader p))) | 
					
						
							|  |  |  |            ((eof? var)) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  |            () | 
					
						
							|  |  |  |            () | 
					
						
							| 
									
										
										
										
											2021-02-18 22:06:59 +01:00
										 |  |  |            . rest)) | 
					
						
							|  |  |  |     ;; generator clauses | 
					
						
							|  |  |  |     ((in-port port) | 
					
						
							|  |  |  |      (gen-port port read-char eof-object?)) | 
					
						
							|  |  |  |     ((in-port port reader) | 
					
						
							|  |  |  |      (gen-port port reader eof-object?)) | 
					
						
							|  |  |  |     ((in-port port reader eof?) | 
					
						
							|  |  |  |      (gen-port port reader eof?)))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define (gen-port port read eof?) | 
					
						
							|  |  |  |   (lambda () | 
					
						
							|  |  |  |     (let ((res (read port))) | 
					
						
							|  |  |  |       (if (eof? res) | 
					
						
							|  |  |  |           (eof-object) | 
					
						
							|  |  |  |           res)))) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-25 20:40:48 +01:00
										 |  |  | (define-syntax in-file | 
					
						
							| 
									
										
										
										
											2021-02-18 22:06:59 +01:00
										 |  |  |   (syntax-rules () | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |     ((in-file :for ((var) source) next . rest) | 
					
						
							|  |  |  |      (in-file :for ((var p) source) next . rest)) | 
					
						
							|  |  |  |     ((in-file :for ((var p) (file)) next . rest) | 
					
						
							|  |  |  |      (in-file :for ((var p) (file read-char)) next . rest)) | 
					
						
							|  |  |  |     ((in-file :for ((var p) (file reader)) next . rest) | 
					
						
							|  |  |  |      (in-file :for ((var p) (file reader eof-object?)) next . rest)) | 
					
						
							|  |  |  |     ((in-file :for ((var p) (file reader eof?)) next . rest) | 
					
						
							| 
									
										
										
										
											2021-02-18 22:06:59 +01:00
										 |  |  |      (next ((p (open-input-file file)) (r reader) (e? eof?)) | 
					
						
							|  |  |  |            ((var (r p) (r p))) | 
					
						
							|  |  |  |            ((e? var)) | 
					
						
							|  |  |  |            () | 
					
						
							|  |  |  |            ((close-input-port p)) . rest)) | 
					
						
							|  |  |  |     ;; generator clauses | 
					
						
							|  |  |  |     ((in-file path) | 
					
						
							|  |  |  |      (gen-file path read-char eof-object?)) | 
					
						
							|  |  |  |     ((in-file path read) | 
					
						
							|  |  |  |      (gen-file path read eof-object?)) | 
					
						
							|  |  |  |     ((in-file path read eof?) | 
					
						
							|  |  |  |      (gen-file path read eof?)))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define (gen-file path read eof?) | 
					
						
							|  |  |  |   (let ((file (open-input-file path))) | 
					
						
							|  |  |  |     (lambda () | 
					
						
							|  |  |  |       (let ((res (read file))) | 
					
						
							|  |  |  |         (cond ((eof? res) | 
					
						
							|  |  |  |                (close-port file) | 
					
						
							|  |  |  |                (eof-object)) | 
					
						
							|  |  |  |               (else res)))))) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | (define-syntax in-generator | 
					
						
							|  |  |  |   (syntax-rules () | 
					
						
							| 
									
										
										
										
											2021-05-11 09:48:21 +02:00
										 |  |  |     ((_ :for ((var) source) next . rest) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  |      (next ((gen source)) | 
					
						
							|  |  |  |            ((var (gen) (gen))) | 
					
						
							|  |  |  |            ((eof-object? var)) | 
					
						
							|  |  |  |            () | 
					
						
							|  |  |  |            () | 
					
						
							| 
									
										
										
										
											2021-02-18 22:06:59 +01:00
										 |  |  |            . rest)) | 
					
						
							|  |  |  |     ;; yes, generator clause | 
					
						
							|  |  |  |     ((in-generator gen) | 
					
						
							|  |  |  |      (let ((g gen)) | 
					
						
							|  |  |  |        (lambda () | 
					
						
							|  |  |  |          (g)))))) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-12 12:54:29 +02:00
										 |  |  | (define (make-up-from-generator/bounded start limit step) | 
					
						
							|  |  |  |   (lambda () | 
					
						
							|  |  |  |     (if (>= start limit) | 
					
						
							|  |  |  |         (eof-object) | 
					
						
							|  |  |  |         (let ((res start)) | 
					
						
							|  |  |  |           (set! start (+ start step)) | 
					
						
							|  |  |  |           res)))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define (make-up-from-generator/unbounded start step) | 
					
						
							|  |  |  |   (lambda () | 
					
						
							|  |  |  |     (let ((res start)) | 
					
						
							|  |  |  |       (set! start (+ start step)) | 
					
						
							|  |  |  |       res))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | (define-syntax up-from | 
					
						
							| 
									
										
										
										
											2021-03-18 12:41:39 +01:00
										 |  |  |   (syntax-rules (:to :by) | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |     ((up-from :for (() . args) next . rest) | 
					
						
							|  |  |  |      (up-from :for ((var) . args) next . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-18 12:41:39 +01:00
										 |  |  |     ((up-from :for ((var) (start (:to limit) (:by step))) next . rest) | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |      (next ((s start) (l limit) (e step)) | 
					
						
							|  |  |  |            ((var s (+ var e))) | 
					
						
							|  |  |  |            ((>= var l)) | 
					
						
							|  |  |  |            () () . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-18 12:41:39 +01:00
										 |  |  |     ((up-from :for ((var) (start (:to limit))) next . rest) | 
					
						
							| 
									
										
										
										
											2021-01-06 21:24:15 +01:00
										 |  |  |      (next ((s start) (l limit)) ((var s (+ var 1))) | 
					
						
							| 
									
										
										
										
											2020-11-09 13:30:02 +01:00
										 |  |  |            ((>= var l)) () () . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-18 12:41:39 +01:00
										 |  |  |     ((up-from :for ((var) (start (:by step))) next . rest) | 
					
						
							| 
									
										
										
										
											2021-01-06 21:24:15 +01:00
										 |  |  |      (next ((s start) (e step)) | 
					
						
							| 
									
										
										
										
											2020-11-09 13:30:02 +01:00
										 |  |  |            ((var s (+ var e))) () () () . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |     ((up-from :for ((var) (start)) next . rest) | 
					
						
							| 
									
										
										
										
											2021-01-06 21:24:15 +01:00
										 |  |  |      (next ((s start)) ((var s (+ var 1))) | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |            () () () . rest)) | 
					
						
							| 
									
										
										
										
											2020-11-09 13:30:02 +01:00
										 |  |  |     ;; Extra convenience, make it act like (in-range ...) from racket, but only for positive numbers. | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |     ((up-from :for ((var) (start limit step)) next . rest) | 
					
						
							| 
									
										
										
										
											2021-01-06 21:24:15 +01:00
										 |  |  |      (next ((s start) (l limit) (e step)) ((var s (+ var e))) ((>= var l)) () () . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |     ((up-from :for ((var) (start limit)) next . rest) | 
					
						
							| 
									
										
										
										
											2021-05-12 12:54:29 +02:00
										 |  |  |      (up-from :for ((var) (start limit 1)) next . rest)) | 
					
						
							|  |  |  |     ;; Generator clauses | 
					
						
							|  |  |  |     ((up-from start (:to limit) (:by step)) | 
					
						
							|  |  |  |      (make-up-from-generator/bounded start limit step)) | 
					
						
							|  |  |  |     ((up-from start (:to limit)) | 
					
						
							|  |  |  |      (make-up-from-generator/bounded start limit 1)) | 
					
						
							|  |  |  |     ((up-from start (:by step)) | 
					
						
							|  |  |  |      (make-up-from-generator/unbounded start step)) | 
					
						
							|  |  |  |     ((up-from start) | 
					
						
							|  |  |  |      (make-up-from-generator/unbounded start 1)) | 
					
						
							|  |  |  |     ((up-from start limit step) | 
					
						
							|  |  |  |      (make-up-from-generator/bounded start limit step)) | 
					
						
							|  |  |  |     ((up-from start limit) (make-up-from-generator/bounded start limit 1)))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define (make-down-from-generator/bounded start end step) | 
					
						
							|  |  |  |   (lambda () | 
					
						
							|  |  |  |     (if (< start end) | 
					
						
							|  |  |  |         (eof-object) | 
					
						
							|  |  |  |         (let ((res start)) | 
					
						
							|  |  |  |           (set! start (- start step)) | 
					
						
							|  |  |  |           res)))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define (make-down-from-generator/unbounded start step) | 
					
						
							|  |  |  |   (lambda () | 
					
						
							|  |  |  |     (let ((res start)) | 
					
						
							|  |  |  |       (set! start (- start step)) | 
					
						
							|  |  |  |       res))) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | (define-syntax down-from | 
					
						
							| 
									
										
										
										
											2021-03-18 12:41:39 +01:00
										 |  |  |   (syntax-rules (:to :by) | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |     ((down-from :for (() . args) next . rest) | 
					
						
							|  |  |  |      (down-from :for ((var) . args) next . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-18 12:41:39 +01:00
										 |  |  |     ((down-from :for ((var) (start (:to limit) (:by step))) next . rest) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  |      (next ((s start) (l limit) (e step)) | 
					
						
							|  |  |  |            ((var (- s e) (- var e))) | 
					
						
							|  |  |  |            ((< var l)) | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |            () () . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-18 12:41:39 +01:00
										 |  |  |     ((down-from :for ((var) (start (:to limit))) next . rest) | 
					
						
							| 
									
										
										
										
											2021-01-06 21:24:15 +01:00
										 |  |  |      (next ((s start) (l limit)) ((var (- s 1) (- var 1))) | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |            ((< var l)) () () . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-18 12:41:39 +01:00
										 |  |  |     ((down-from :for ((var) (start (:by step))) next . rest) | 
					
						
							| 
									
										
										
										
											2021-01-06 21:24:15 +01:00
										 |  |  |      (next ((s start) (e step)) ((var (- s e) (- var e))) | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |            () () () . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |     ((down-from :for ((var) (start)) next . rest) | 
					
						
							| 
									
										
										
										
											2021-01-06 21:24:15 +01:00
										 |  |  |      (next ((s start)) ((var (- s 1) (- var 1))) | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |            () () () . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |     ((down-from :for ((var) (start limit step)) next . rest) | 
					
						
							| 
									
										
										
										
											2021-01-06 21:24:15 +01:00
										 |  |  |      (next ((s start) (l limit) (e step)) ((var (- s e) (- var e))) ((< var l)) () () . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |     ((down-from :for ((var) (start limit)) next . rest) | 
					
						
							| 
									
										
										
										
											2021-05-12 12:54:29 +02:00
										 |  |  |      (down-from :for ((var) (start limit 1)) next . rest)) | 
					
						
							|  |  |  |     ;;generator clauses | 
					
						
							|  |  |  |     ((down-from start (:to limit) (:by step)) | 
					
						
							|  |  |  |      (make-down-from-generator/bounded start limit step)) | 
					
						
							|  |  |  |     ((down-from start (:to limit)) | 
					
						
							|  |  |  |      (make-down-from-generator/bounded start limit 1)) | 
					
						
							|  |  |  |     ((down-from start (:by step)) | 
					
						
							|  |  |  |      (make-down-from-generator/unbounded start step)) | 
					
						
							|  |  |  |     ((down-from start limit step) | 
					
						
							|  |  |  |      (make-down-from-generator/bounded start limit step)) | 
					
						
							|  |  |  |     ((down-from start limit) (make-down-from-generator/bounded start limit 1)) | 
					
						
							|  |  |  |     ((down-from start) (make-down-from-generator/unbounded start 1)))) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-02 12:03:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | (define-syntax in-hash | 
					
						
							|  |  |  |   (syntax-rules () | 
					
						
							| 
									
										
										
										
											2021-05-11 09:48:21 +02:00
										 |  |  |     ((in-hash :for ((bindings) expr) n . rest) | 
					
						
							| 
									
										
										
										
											2021-01-02 12:03:03 +01:00
										 |  |  |      (n | 
					
						
							|  |  |  |       () | 
					
						
							|  |  |  |       ((cursor (hash-map->list cons expr) (cdr cursor))) | 
					
						
							|  |  |  |       ((not (pair? cursor))) | 
					
						
							|  |  |  |       ((bindings (car cursor))) | 
					
						
							|  |  |  |       () | 
					
						
							| 
									
										
										
										
											2021-03-11 14:37:20 +01:00
										 |  |  |       . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-16 19:30:08 +01:00
										 |  |  |     ((in-hash hash-expr) | 
					
						
							| 
									
										
										
										
											2021-05-12 12:54:29 +02:00
										 |  |  |      (in-list (hash-map->list cons hash-expr))))) | 
					
						
							| 
									
										
										
										
											2021-01-02 12:03:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | (define-syntax accumulating | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |   (syntax-rules (initial if :acc) | 
					
						
							|  |  |  |     ((accumulating :acc (kons final init) ((var) . x) next . rest) | 
					
						
							|  |  |  |      (accumulating :acc (kons final init) ((var cursor) . x) next . rest)) | 
					
						
							|  |  |  |     ((accumulating :acc (kons final init) ((var cursor) ((initial i) . x)) n . rest) | 
					
						
							|  |  |  |      (accumulating :acc (kons final i) ((var cursor) x) n . rest)) | 
					
						
							|  |  |  |     ((accumulating :acc (kons final init) ((var cursor) (expr (if check))) n . rest) | 
					
						
							| 
									
										
										
										
											2020-12-16 19:54:55 +01:00
										 |  |  |      (n ((tmp-kons kons)) | 
					
						
							| 
									
										
										
										
											2020-11-04 11:58:58 +01:00
										 |  |  |         ((cursor init (if check (tmp-kons expr cursor) cursor))) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  |         () | 
					
						
							|  |  |  |         () | 
					
						
							|  |  |  |         ((var (final cursor))) | 
					
						
							|  |  |  |         . rest)) | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |     ((accumulating :acc (kons final init) ((var cursor) (expr)) n . rest) | 
					
						
							| 
									
										
										
										
											2020-12-16 19:54:55 +01:00
										 |  |  |      (n ((tmp-kons kons)) | 
					
						
							| 
									
										
										
										
											2020-11-04 11:58:58 +01:00
										 |  |  |         ((cursor init (tmp-kons expr cursor))) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  |         () | 
					
						
							|  |  |  |         () | 
					
						
							|  |  |  |         ((var (final cursor))) | 
					
						
							|  |  |  |         . rest)))) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-09 13:30:02 +01:00
										 |  |  | (define-syntax folding | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |   (syntax-rules (if :acc) | 
					
						
							| 
									
										
										
										
											2020-12-16 19:54:55 +01:00
										 |  |  |     ((_ :acc ((var) (init update (if guard))) n . rest) | 
					
						
							| 
									
										
										
										
											2020-11-09 13:30:02 +01:00
										 |  |  |      (n () | 
					
						
							|  |  |  |         ((var init (if guard update var))) | 
					
						
							| 
									
										
										
										
											2021-01-06 21:24:15 +01:00
										 |  |  |         () () | 
					
						
							| 
									
										
										
										
											2020-11-09 13:30:02 +01:00
										 |  |  |         ((var var)) | 
					
						
							|  |  |  |         . rest)) | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |     ((_ :acc ((var) (init update)) n . rest) | 
					
						
							| 
									
										
										
										
											2020-12-16 19:54:55 +01:00
										 |  |  |      (folding :acc ((var) (init update (if #t))) n . rest)) | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |     ((_ :acc ((var) (init)) n . rest) | 
					
						
							| 
									
										
										
										
											2020-12-16 19:54:55 +01:00
										 |  |  |      (folding :acc ((var) (init var (if #t))) n . rest)))) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | (define-syntax listing | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |   (syntax-rules (:acc) | 
					
						
							|  |  |  |     ((listing :acc args next . rest) | 
					
						
							|  |  |  |      (accumulating :acc (cons reverse '()) args next . rest)))) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | (define-syntax listing-reverse | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |   (syntax-rules (:acc) | 
					
						
							|  |  |  |     ((listing-reverse :acc args next . rest) | 
					
						
							|  |  |  |      (accumulating :acc (cons (lambda (x) x) '()) args next . rest)))) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | (define (append-reverse rev tail) | 
					
						
							|  |  |  |   (if (null? rev) tail (append-reverse (cdr rev) (cons (car rev) tail)))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define-syntax appending | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |   (syntax-rules (:acc) | 
					
						
							|  |  |  |     ((appending :acc args next . rest) | 
					
						
							|  |  |  |      (accumulating :acc (append-reverse reverse '()) args next . rest)))) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | (define-syntax appending-reverse | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |   (syntax-rules (:acc) | 
					
						
							|  |  |  |     ((appending-reverse :acc args next . rest) | 
					
						
							|  |  |  |      (accumulating :acc (append-reverse (lambda (x) x) '()) args next . rest)))) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | (define-syntax summing | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |   (syntax-rules (:acc) | 
					
						
							|  |  |  |     ((summing :acc args next . rest) | 
					
						
							|  |  |  |      (accumulating :acc (+ (lambda (x) x) 0) args next . rest)))) | 
					
						
							| 
									
										
										
										
											2020-11-02 22:11:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | (define-syntax multiplying | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |   (syntax-rules (:acc) | 
					
						
							|  |  |  |     ((multiplying :acc args next . rest) | 
					
						
							| 
									
										
										
										
											2020-12-01 20:54:42 +01:00
										 |  |  |      (accumulating :acc (* (lambda (x) x) 1) args next . rest)))) | 
					
						
							| 
									
										
										
										
											2020-11-09 22:57:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-02 12:03:03 +01:00
										 |  |  | (define-syntax define-hashing | 
					
						
							|  |  |  |   (syntax-rules () | 
					
						
							|  |  |  |     ((_ name default-make setter) | 
					
						
							|  |  |  |      (define-syntax name | 
					
						
							|  |  |  |        (syntax-rules (:acc if initial) | 
					
						
							|  |  |  |          ((_ :acc ((var) (key value)) n . rest) | 
					
						
							| 
									
										
										
										
											2021-05-12 12:54:29 +02:00
										 |  |  |           (name :acc ((var) (key value (if #t) (initial default-make))) n . rest)) | 
					
						
							| 
									
										
										
										
											2021-01-02 12:03:03 +01:00
										 |  |  |          ;; either init or if | 
					
						
							|  |  |  |          ((_ :acc ((var) (key value (if guard))) n . rest) | 
					
						
							|  |  |  |           (name :acc ((var) (key value (if guard) (initial default-make))) n . rest)) | 
					
						
							|  |  |  |          ((_ :acc ((var) (key value (initial init))) n . rest) | 
					
						
							|  |  |  |           (name :acc ((var) (key value (if #t) (initial init))) n . rest)) | 
					
						
							|  |  |  |          ;; both init and if | 
					
						
							|  |  |  |          ((_ :acc ((var) (key value (initial init) (if guard))) n . rest) | 
					
						
							|  |  |  |           (name ((var) (key value (if guard) (initial init))) n . rest)) | 
					
						
							|  |  |  |          ((_ :acc ((var) (key value (if guard) (initial init))) n . rest) | 
					
						
							|  |  |  |           (n | 
					
						
							| 
									
										
										
										
											2021-05-12 12:54:29 +02:00
										 |  |  |            ((var init)) | 
					
						
							|  |  |  |            ((dummy (if #f #f) (if guard (setter var key value) (if #f #f)))) | 
					
						
							| 
									
										
										
										
											2021-01-02 12:03:03 +01:00
										 |  |  |            () | 
					
						
							|  |  |  |            () | 
					
						
							| 
									
										
										
										
											2021-05-12 12:54:29 +02:00
										 |  |  |            ((var var)) | 
					
						
							| 
									
										
										
										
											2021-01-02 12:03:03 +01:00
										 |  |  |            . rest))))))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define-hashing hashing (make-hash-table) hash-set!) | 
					
						
							|  |  |  | (define-hashing hashving (make-hash-table) hashv-set!) | 
					
						
							|  |  |  | (define-hashing hashqing (make-hash-table) hashq-set!) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-02 21:43:10 +01:00
										 |  |  | (define (vector-grow v factor len) | 
					
						
							|  |  |  |   (define newlen (* len factor)) | 
					
						
							|  |  |  |   (define new (make-vector newlen)) | 
					
						
							|  |  |  |   (vector-copy! new 0 v 0 len) | 
					
						
							|  |  |  |   new) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define (vector-set!? vec index value) | 
					
						
							|  |  |  |   (cond ((= index (vector-length vec)) | 
					
						
							|  |  |  |          (let ((newvec (vector-grow vec 2 (vector-length vec)))) | 
					
						
							|  |  |  |            (vector-set! newvec index value) | 
					
						
							|  |  |  |            newvec)) | 
					
						
							|  |  |  |         (else | 
					
						
							|  |  |  |          (vector-set! vec index value) | 
					
						
							|  |  |  |          vec))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define (vector-shrink? vec index) | 
					
						
							|  |  |  |   (if (= index (vector-length vec)) | 
					
						
							|  |  |  |       vec | 
					
						
							|  |  |  |       (vector-copy vec 0 index))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define-syntax vectoring | 
					
						
							|  |  |  |   (syntax-rules (:acc :length :fill) | 
					
						
							|  |  |  |     ((_ :acc ((var) expr) n . rest) | 
					
						
							|  |  |  |      (vectoring :acc ((var index) expr) n . rest)) | 
					
						
							|  |  |  |     ((_ :acc ((var index) (expr)) n . rest) | 
					
						
							|  |  |  |      (n () | 
					
						
							|  |  |  |         ((index 0 (+ index 1)) (var (make-vector 32) (vector-set!? var index expr))) | 
					
						
							|  |  |  |         () | 
					
						
							|  |  |  |         () | 
					
						
							|  |  |  |         ((var (vector-shrink? var index))) | 
					
						
							|  |  |  |         . rest)) | 
					
						
							|  |  |  |     ((_ :acc ((var index) (expr (:length len))) n . rest) | 
					
						
							|  |  |  |      (vectoring  :acc ((var index) (expr (:length len) (:fill (if #f #f)))) n . rest)) | 
					
						
							| 
									
										
										
										
											2021-03-11 22:18:29 +01:00
										 |  |  |     ((_ :acc ((var index) (expr (:length len) (:fill f))) next . rest) | 
					
						
							| 
									
										
										
										
											2021-01-02 21:43:10 +01:00
										 |  |  |      (next ((var (make-vector len f))) | 
					
						
							|  |  |  |            ((index 0 (begin (vector-set! var index expr) (+ index 1)))) | 
					
						
							| 
									
										
										
										
											2021-03-11 22:18:29 +01:00
										 |  |  |            ((= index len)) | 
					
						
							| 
									
										
										
										
											2021-01-02 21:43:10 +01:00
										 |  |  |            () | 
					
						
							|  |  |  |            ((var var)) | 
					
						
							|  |  |  |            . rest)))) | 
					
						
							| 
									
										
										
										
											2020-11-09 22:57:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-18 18:12:01 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | ;; this is an internal "accumulator". It is used for final tests | 
					
						
							|  |  |  | ;; :final in goof differs from in racket. It is lexical, meaning it | 
					
						
							|  |  |  | ;; is tested where it is placed in the clauses, and any subloop is | 
					
						
							|  |  |  | ;; executed completely. | 
					
						
							|  |  |  | (define-syntax final | 
					
						
							|  |  |  |   (syntax-rules (:acc) | 
					
						
							|  |  |  |     ((_ :acc ((var) (test)) n . rest) | 
					
						
							|  |  |  |      (n () | 
					
						
							|  |  |  |         ((final #f test)) | 
					
						
							|  |  |  |         (final) | 
					
						
							|  |  |  |         () | 
					
						
							|  |  |  |         () | 
					
						
							|  |  |  |         . rest)))) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-09 22:57:18 +01:00
										 |  |  | ;;; Here starts generator clauses. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define (generator->list gen) | 
					
						
							|  |  |  |   (let ((res (gen))) | 
					
						
							|  |  |  |     (if (eof-object? res) | 
					
						
							|  |  |  |         '() | 
					
						
							|  |  |  |         (cons res (generator->list gen))))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define (generator-cycle gen) | 
					
						
							|  |  |  |   (let ((circle (apply circular-list (generator->list gen)))) | 
					
						
							|  |  |  |     (lambda () | 
					
						
							|  |  |  |       (let ((res (car circle))) | 
					
						
							|  |  |  |         (set! circle (cdr circle)) | 
					
						
							|  |  |  |         res)))) | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  | (define-syntax in-cycle | 
					
						
							|  |  |  |   (syntax-rules () | 
					
						
							| 
									
										
										
										
											2021-05-11 09:48:21 +02:00
										 |  |  |     ((_ :for ((id) (source)) n . rest) | 
					
						
							| 
									
										
										
										
											2020-11-09 22:57:18 +01:00
										 |  |  |      (n ((gen (generator-cycle source))) | 
					
						
							|  |  |  |         () | 
					
						
							|  |  |  |         () | 
					
						
							| 
									
										
										
										
											2020-11-22 21:47:48 +01:00
										 |  |  |         ((id (gen))) | 
					
						
							|  |  |  |         () | 
					
						
							| 
									
										
										
										
											2020-11-09 22:57:18 +01:00
										 |  |  |         . rest)))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define (generator-indexed gen) | 
					
						
							|  |  |  |   (let ((i 0)) | 
					
						
							|  |  |  |     (lambda () | 
					
						
							|  |  |  |       (let ((res (gen)) (index i)) | 
					
						
							|  |  |  |         (if (eof-object? res) | 
					
						
							|  |  |  |             (values res res) | 
					
						
							|  |  |  |             (begin | 
					
						
							|  |  |  |               (set! i (+ i 1)) | 
					
						
							| 
									
										
										
										
											2021-01-06 21:24:15 +01:00
										 |  |  |               (cons index res))))))) | 
					
						
							| 
									
										
										
										
											2020-11-09 22:57:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | (define-syntax in-indexed | 
					
						
							| 
									
										
										
										
											2021-05-11 09:48:21 +02:00
										 |  |  |   (syntax-rules (:for) | 
					
						
							|  |  |  |     ((_ :for ((binding) (source)) n . rest) | 
					
						
							| 
									
										
										
										
											2020-11-09 22:57:18 +01:00
										 |  |  |      (n ((gen (generator-indexed source))) | 
					
						
							| 
									
										
										
										
											2021-01-06 21:24:15 +01:00
										 |  |  |         ((i (gen) (gen))) | 
					
						
							| 
									
										
										
										
											2020-11-09 22:57:18 +01:00
										 |  |  |         ((eof-object? i)) | 
					
						
							| 
									
										
										
										
											2021-01-06 21:24:15 +01:00
										 |  |  |         ((binding i)) | 
					
						
							| 
									
										
										
										
											2020-11-09 22:57:18 +01:00
										 |  |  |         () | 
					
						
							|  |  |  |         . rest)))) | 
					
						
							| 
									
										
										
										
											2021-05-11 09:48:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | (define (stop-before-generator gen pred) | 
					
						
							|  |  |  |   (lambda () | 
					
						
							|  |  |  |     (let ((v (gen))) | 
					
						
							|  |  |  |       (if (pred v) | 
					
						
							|  |  |  |           (eof-object) | 
					
						
							|  |  |  |           v)))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define (stop-after-generator gen pred) | 
					
						
							|  |  |  |   (let ((done? #f)) | 
					
						
							|  |  |  |     (lambda () | 
					
						
							|  |  |  |       (if done? | 
					
						
							|  |  |  |           (eof-object) | 
					
						
							|  |  |  |           (let ((v (gen))) | 
					
						
							|  |  |  |             (when (pred v) | 
					
						
							|  |  |  |               (set! done? #t)) | 
					
						
							|  |  |  |             v))))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define-syntax stop-before | 
					
						
							|  |  |  |   (syntax-rules (:for) | 
					
						
							|  |  |  |     ((_ :for ((binding) (source pred)) n . rest) | 
					
						
							|  |  |  |      (in-generator :for ((binding) (stop-before-generator source pred)) n . rest)) | 
					
						
							|  |  |  |     ((_ expr pred) | 
					
						
							|  |  |  |      (stop-before-generator expr pred)))) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (define-syntax stop-after | 
					
						
							|  |  |  |   (syntax-rules (:for) | 
					
						
							|  |  |  |     ((_ :for ((binding) (source pred)) n . rest) | 
					
						
							|  |  |  |      (in-generator :for ((binding) (stop-after-generator source pred)) n . rest)) | 
					
						
							|  |  |  |     ((_ expr pred) (stop-after-generator expr pred)))) |