#| 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)))