From 26892394d6999fca9be6975b0910158fdf8a9fff Mon Sep 17 00:00:00 2001 From: Ekaitz Zarraga Date: Tue, 23 Jan 2024 15:29:23 +0100 Subject: par: piece-table: add for-each --- par/piece-table.scm | 29 +++++++++++++++++++++++++++++ par/piece-table.sld | 3 ++- tests/piece-table.scm | 13 +++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/par/piece-table.scm b/par/piece-table.scm index 24608e3..21661e7 100644 --- a/par/piece-table.scm +++ b/par/piece-table.scm @@ -185,6 +185,35 @@ (define (piece-table-text-length piece-table) (reduce + 0 (map piece-length (piece-table-pieces piece-table)))) +(define (piece-table-for-each piece-table f from to) + ;; TODO: default from and to + "Calls `f` through the characters of the piece-table, like `string-for-each` + would do, but the `f` call also includes the piece (to expose extra data) and + the index of the character" + (let loop ((idx 0) + (start 0) + (pieces (piece-table-pieces piece-table))) + (let* ((piece (car pieces)) + (len (piece-length piece)) + (end (+ start len)) + (more? (not (null? (cdr pieces))))) + (when (< idx to) ;; Skip tail + (if (or (= idx end) (<= end from)) + ;; Current piece doesn't contain the section we need or finished + ;; Jump to next piece + (when more? (loop end end (cdr pieces))) + ;; Current piece contains part of the section we need, go char by + ;; char + (begin + (when (<= from idx) + (f + (string-ref (buffer->string (piece-buffer piece)) + (+ (piece-start piece) (- idx start))) + idx + piece)) + ;; There are chars to process in this piece + (loop (+ idx 1) start pieces))))))) + (define (piece-table-find-line-break piece-table idx) (let loop ((idx 0) (ps (piece-table-pieces piece-table)) diff --git a/par/piece-table.sld b/par/piece-table.sld index f867612..427b389 100644 --- a/par/piece-table.sld +++ b/par/piece-table.sld @@ -10,5 +10,6 @@ piece-table-substring string->piece-table add-buffer-length - piece-table-line) + piece-table-line + piece-table-for-each) (include "piece-table.scm")) diff --git a/tests/piece-table.scm b/tests/piece-table.scm index 19bd107..453229e 100644 --- a/tests/piece-table.scm +++ b/tests/piece-table.scm @@ -47,3 +47,16 @@ (piece-table-delete! table 12 1) (test-equal "OLASOY EKAIT" (piece-table->string table)) (test-end "delete") + +(test-begin "for-each") + (define table (make-piece-table "12346890")) + (piece-table-insert! table 4 "5" 'normal) + (test-equal "123456890" (piece-table->string table)) + (piece-table-insert! table 6 "7" 'normal) + (test-equal "1234567890" (piece-table->string table)) + (piece-table-for-each table + (lambda (c i p) + (test-equal c (string-ref "1234567890" i))) + 0 + 10) +(test-end) -- cgit v1.2.3