blob: 3638614c7ebef33ed03ae6903adeb54a736f5b43 (
plain) (
blame)
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
#| Copyright 2024 Peter McGoron
|
| Licensed under the Apache License, Version 2.0 (the "License");
| you may not use this file except in compliance with the License.
| You may obtain a copy of the License at
|
| http://www.apache.org/licenses/LICENSE-2.0
|
| Unless required by applicable law or agreed to in writing, software
| distributed under the License is distributed on an "AS IS" BASIS,
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
| See the License for the specific language governing permissions and
| limitations under the License.
|-------------------------------------------------------------------------
| This is a list iterator that allows for mutation of the list.
|
| The list iterator is made up of
| * the `signifier`: the head of the list.
| * the `previous` values, which is a list of all cons cells prior to the
| current cons cell, in reverse.
| * the index, which is the index of the current element in the list. This
| is updated internally but not used internally, so the root index does
| not have to be 0.
| * the `next` list, which is either empty or has as it's car the current
| item.
|#
(define (make-list-iterator signifier previous idx rest)
(when (not (or (pair? rest) (null? rest)))
(raise (improper-list-exception idx rest)))
(make-iterator
(lambda () (null? previous))
(lambda () (null? rest))
(lambda (num)
(cond
((not (integer?))
(raise (non-integer-movement-exception spaces)))
((negative? num)
(let loop ((cntr (- num))
(previous previous)
(rest rest))
(cond
((= num 0) (make-list-iterator signifier
previous
(+ total num)
rest))
((null? previous) #f)
(else (loop (- cntr 1)
(cdr previous)
(car previous))))))
(else
(let loop ((cntr num)
(previous previous)
(rest rest))
(cond
((= num 0) (make-list-iterator signifier
previous
(+ total num)
rest))
((null? rest) #f)
(else (loop (- 1 num)
(cons rest previous)
(cdr rest))))))))
(lambda ()
(if (null? rest)
(error "cannot ref end of list" previous rest)
(car rest)))
(lambda (predicate? other-iterators)
(let ((cmp (make-default-comparator)))
(iteratively-apply-predicate
(lambda (x y)
(predicate? cmp (get-private x) (get-private y)))
idx
other-iterators)))
idx))
(define (list-iterator-start rest)
(make-list-iterator rest '() 0 rest))
(define (list-iterator-to-end itr)
(if (iterator-end? itr)
itr
(list-iterator-to-end (iterator-advance itr 1))))
(define (list-iterator-end lst)
(list-iterator-to-end (list-iterator-start lst)))
|