diff options
| author | 2024-12-23 22:48:22 -0500 | |
|---|---|---|
| committer | 2024-12-23 22:48:22 -0500 | |
| commit | 4586e1dee2c15d3cfbcdd0429d494932341b4cc5 (patch) | |
| tree | 31746b9a0e2044e3d380dafc337108895c6e3ea6 /string-iterator.scm | |
| parent | string iterator (diff) | |
refactor iterator to be simpler
Diffstat (limited to '')
| -rw-r--r-- | string-iterator.scm | 192 |
1 files changed, 68 insertions, 124 deletions
diff --git a/string-iterator.scm b/string-iterator.scm index 8589bdf..6a7730a 100644 --- a/string-iterator.scm +++ b/string-iterator.scm @@ -14,40 +14,16 @@ |# (define-record-type <fat-cursor> - (make-fat-cursor str srfi-130-cursor) + (raw-fat-cursor str cursor) fat-cursor? (str get-str) - (srfi-130-cursor get-srfi-130-cursor)) + (cursor get-cursor)) -(define-syntax lambda-fat-cursor - (syntax-rules () - ((lambda-fat-cursor (str cursor rest ...) body ...) - (lambda (fat-cursor rest ...) - (let ((str (get-str fat-cursor)) - (cursor (get-srfi-130-cursor fat-cursor))) - body ...))))) - -(define (recursively-compare predicate?) - (letrec ((cmp - (case-lambda - ((_) #t) - ((fc1 fc2) - (and (eq? (get-str fc1) (get-str fc2)) - (predicate? (get-srfi-130-cursor fc1) - (get-srfi-130-cursor fc2)))) - ((fc1 fc2 . fc-rest) - (and (cmp fc1 fc2) - (apply cmp fc2 fc-rest)))))) - cmp)) - -(define fat-cursor=? (recursively-compare string-cursor=?)) -(define fat-cursor<? (recursively-compare string-cursor<?)) - -(define fat-cursor-comparator +(define string-cursor-comparator (make-comparator - fat-cursor? - fat-cursor=? - fat-cursor<? + string-cursor? + string-cursor=? + string-cursor<? #f)) (define (string-cursor-valid-movement? str cursor spaces) @@ -62,99 +38,67 @@ (string-cursor-diff str cursor (string-cursor-end str)))) (else #t))) -(define string-iterator-implementation - (letrec* ((make-string-iterator - (lambda (str cursor) - (make-iterator impl - (make-fat-cursor str cursor)))) - (start - (lambda (object) - (cond - ((string? object) - (make-string-iterator object - (string-cursor-start object))) - ((fat-cursor? object) - (make-string-iterator (get-str object) - (string-cursor-start - (get-str object)))) - (else (error "invalid object for start" object))))) - (end - (lambda (object) - (cond - ((string? object) - (make-string-iterator object - (string-cursor-end object))) - ((fat-cursor? object) - (make-string-iterator (get-str object) - (string-cursor-end - (get-str object)))) - (else (error "invalid object for end" object))))) - (start? - (lambda-fat-cursor (str cursor) - (string-cursor=? cursor (string-cursor-start str)))) - (end? - (lambda-fat-cursor (str cursor) - (string-cursor=? cursor (string-cursor-end str)))) - (advance - (lambda-fat-cursor (str cursor spaces) - (cond - ((not (string-cursor-valid-movement? str cursor spaces)) - #f) - ((negative? spaces) - (make-string-iterator str - (string-cursor-back str - cursor - (- spaces)))) - (else - (make-string-iterator str - (string-cursor-forward str - cursor - spaces)))))) - (ref - (lambda (fat-cursor) - (if (end? fat-cursor) - (error "cannot ref one past the end of the sequence" - fat-cursor) - (string-ref/cursor (get-str fat-cursor) - (get-srfi-130-cursor fat-cursor))))) - (to-index - (lambda-fat-cursor (str cursor) - (string-cursor->index str cursor))) - (from-index%string - (lambda (str index) - (make-string-iterator str - (string-index->cursor str index)))) - (from-index - (lambda (obj index) - (cond - ((string? obj) (from-index%string obj index)) - ((fat-cursor? obj) - (from-index%string (get-str obj) index)) - (else (error "invalid object for from-index" obj index))))) - (impl - (make-iterator-implementation - start end - start? end? - advance ref - to-index from-index - fat-cursor-comparator))) - impl)) +(define (cursor->iterator str cursor) + (make-iterator + (lambda () + (string-cursor=? cursor (string-cursor-start str))) + (lambda () + (string-cursor=? cursor (string-cursor-end str))) + (lambda (spaces) + (cond + ((not (string-cursor-valid-movement? str cursor spaces)) + #f) + ((negative? spaces) + (cursor->iterator str + (string-cursor-back str + cursor + (- spaces)))) + (else + (cursor->iterator str + (string-cursor-forward str + cursor + spaces))))) + (lambda () + (string-ref/cursor str cursor)) + (lambda () + (string-cursor->index str cursor)) + (lambda (predicate? other-iterators) + (let loop ((rest other-iterators) + (current cursor)) + (if (null? rest) + #t + (let* ((next-private (iterator-get-private (car rest))) + (next-str (get-str next-private)) + (next (get-cursor next-private))) + ;; All comparisons are to STR, the string in the first + ;; iterator, since they all must be equal. + (if (or (not (eq? next-str str)) + (not (predicate? string-cursor-comparator + current + next))) + #f + (loop (cdr rest) next)))))) + (raw-fat-cursor str cursor))) + +(define-syntax define-for-iterator-or-string + (syntax-rules () + ((_ (name str args ...) body ...) + (define (name object args ...) + (define (internal str args ...) + body ...) + (cond + ((string? object) (internal object args ...)) + ((iterator? object) (internal (get-str (iterator-get-private + object)) + args ...)) + (else (error "invalid type of object" object))))))) + +(define-for-iterator-or-string (string-iterator-start str) + (cursor->iterator str (string-cursor-start str))) + +(define-for-iterator-or-string (string-iterator-end str) + (cursor->iterator str (string-cursor-end str))) -(define (constructor-for-iterator-or-string procedure) - (lambda (object . rest) - (cond - ((string? object) (apply procedure - string-iterator-implementation - object - rest)) - ((iterator? object) (apply procedure - object - rest)) - (else (error "invalid object" object rest))))) +(define-for-iterator-or-string (string-index->iterator str idx) + (cursor->iterator str (string-index->cursor str idx))) -(define string-iterator-start - (constructor-for-iterator-or-string iterator-at-start)) -(define string-iterator-end - (constructor-for-iterator-or-string iterator-at-end)) -(define string-index->iterator - (constructor-for-iterator-or-string index->iterator)) |
