1 2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3;; 4;; MODULE : iterator.scm 5;; DESCRIPTION : abstract iterators 6;; COPYRIGHT : (C) 2007 Joris van der Hoeven 7;; 8;; This software falls under the GNU general public license version 3 or later. 9;; It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE 10;; in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>. 11;; 12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 13 14(texmacs-module (kernel library iterator)) 15 16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 17;; Construction of iterators 18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 19 20(define-macro (iterator val next) 21 "Primitive iterator constructor from value @val and next iterator @next." 22 `(lambda () (cons ,val ,next))) 23 24(define-public (range start end) 25 "Range iterator from @start to @end (not included)." 26 (and (< start end) 27 (iterator start (range (+ start 1) end)))) 28 29(define-public (list->iterator l) 30 "Convert the list @l to an iterator." 31 (and (nnull? l) 32 (iterator (car l) (list->iterator (cdr l))))) 33 34(define-public (iterator-append . its) 35 "Append the iterators @its." 36 (cond ((null? its) #f) 37 ((not (car its)) (apply iterator-append (cdr its))) 38 (else (let* ((next ((car its))) 39 (cont (cons (cdr next) (cdr its)))) 40 (iterator (car next) (apply iterator-append cont)))))) 41 42(define-public (iterator-filter it pred?) 43 "Get elements in iterator @it which match the predicate @pred?." 44 (with next #f 45 (while (and it (begin (set! next (it)) (not (pred? (car next))))) 46 (set! it (cdr next))) 47 (and it (lambda () next)))) 48 49(define-public-macro (extract var it prop?) 50 "Extract all values @var from iterator @it which match the property @prop?." 51 `(iterator-filter ,it (lambda (,var) ,prop?))) 52 53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 54;; Traversal of iterators 55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 56 57(define-public (iterator-value it) 58 "Get current value of iterator @it." 59 (and it (car (it)))) 60 61(define-public (iterator-next it) 62 "Get next iterator after @it." 63 (and it (cdr (it)))) 64 65(define-public-macro (iterator-read! it) 66 "Read one value from iterator @it." 67 `(and ,it 68 (with next (,it) 69 (set! ,it (cdr next)) 70 (car next)))) 71 72(define-public (iterator-apply it fun) 73 (while it 74 (with next (it) 75 (fun (car next)) 76 (set! it (cdr next))))) 77 78(define-public-macro (for-in var-it . body) 79 "Execute @body for values in an iterator." 80 (let* ((var (car var-it)) 81 (it (cadr var-it)) 82 (fun `(lambda (,var) ,@body))) 83 `(iterator-apply ,it ,fun))) 84 85(define-public (iterator->list it) 86 "Convert iterator @it into a list." 87 (if (not it) '() 88 (with next (it) 89 (cons (car next) (iterator->list (cdr next)))))) 90