diff options
-rw-r--r-- | par/buffers.scm | 50 | ||||
-rw-r--r-- | par/buffers.sld | 12 | ||||
-rw-r--r-- | par/piece-table.scm | 50 | ||||
-rw-r--r-- | par/piece-table.sld | 1 |
4 files changed, 63 insertions, 50 deletions
diff --git a/par/buffers.scm b/par/buffers.scm new file mode 100644 index 0000000..2a2028e --- /dev/null +++ b/par/buffers.scm @@ -0,0 +1,50 @@ +;; INTERNAL BUFFERS: The indirection level of the buffer records is cool, so we +;; can resize the underlying strings and keep all the pieces untouched and +;; pointing to the correct thing. + +;; There's nothing preventing the programmer from writing in the ro-buffer... +;; but it will be hidden under the piece-table interface so nothing should +;; happen +(define-record-type <ro-buffer> + (make-ro-buffer string) + ro-buffer? + (string ro-buffer-string)) + +;; This is where things are added, it's able to grow to handle new additions +(define-record-type <add-buffer> + (%make-add-buffer string used) + add-buffer? + (string add-buffer-string set-add-buffer-string!) + (used add-buffer-used set-add-buffer-used!)) + +;; TODO think about a way to make all this polymorphism automagic +(define (buffer->string buffer) + "Returns the underlying string of the buffer" + (cond + ((add-buffer? buffer) (add-buffer-string buffer)) + ((ro-buffer? buffer) (ro-buffer-string buffer)))) +;; + +(define add-buffer-length (make-parameter 100)) + +(define (make-add-buffer) + (%make-add-buffer (make-string (add-buffer-length)) 0)) + +(define (enlarge-add-buffer! add-buffer at-least) + (let* ((str (add-buffer-string add-buffer)) + (len (string-length str)) + ; TODO: Better algo here? + (new (make-string (+ len at-least (add-buffer-length))))) + (set-add-buffer-string! add-buffer new) + (string-copy! new 0 str))) + +(define (add-buffer-append! add-buffer str) + "Appends to add buffer, growing if necessary" + (let ((append-len (string-length str)) + (buffer-used (add-buffer-used add-buffer)) + (buffer-size (string-length (add-buffer-string add-buffer)))) + (when (>= (+ append-len buffer-used) buffer-size) + (enlarge-add-buffer! add-buffer append-len)) + (string-copy! (add-buffer-string add-buffer) buffer-used str) + (set-add-buffer-used! add-buffer (+ append-len buffer-used)))) + diff --git a/par/buffers.sld b/par/buffers.sld new file mode 100644 index 0000000..86f07d8 --- /dev/null +++ b/par/buffers.sld @@ -0,0 +1,12 @@ +(define-library (par buffers) + (import (scheme base) + (srfi 11)) + (export buffer->string + + make-ro-buffer + make-add-buffer + + add-buffer-used + add-buffer-length + add-buffer-append!) + (include "buffers.scm")) diff --git a/par/piece-table.scm b/par/piece-table.scm index c1688a2..8e6fa82 100644 --- a/par/piece-table.scm +++ b/par/piece-table.scm @@ -127,56 +127,6 @@ -;; INTERNAL BUFFERS: The indirection level of the buffer records is cool, so we -;; can resize the underlying strings and keep all the pieces untouched and -;; pointing to the correct thing. - -;; There's nothing preventing the programmer from writing in the ro-buffer... -;; but it will be hidden under the piece-table interface so nothing should -;; happen -(define-record-type <ro-buffer> - (make-ro-buffer string) - ro-buffer? - (string ro-buffer-string)) - -;; This is where things are added, it's able to grow to handle new additions -(define-record-type <add-buffer> - (%make-add-buffer string used) - add-buffer? - (string add-buffer-string set-add-buffer-string!) - (used add-buffer-used set-add-buffer-used!)) - -;; TODO think about a way to make all this polymorphism automagic -(define (buffer->string buffer) - "Returns the underlying string of the buffer" - (cond - ((add-buffer? buffer) (add-buffer-string buffer)) - ((ro-buffer? buffer) (ro-buffer-string buffer)))) -;; - -(define add-buffer-length (make-parameter 100)) - -(define (make-add-buffer) - (%make-add-buffer (make-string (add-buffer-length)) 0)) - -(define (enlarge-add-buffer! add-buffer at-least) - (let* ((str (add-buffer-string add-buffer)) - (len (string-length str)) - ; TODO: Better algo here? - (new (make-string (+ len at-least (add-buffer-length))))) - (set-add-buffer-string! add-buffer new) - (string-copy! new 0 str))) - -(define (add-buffer-append! add-buffer str) - "Appends to add buffer, growing if necessary" - (let ((append-len (string-length str)) - (buffer-used (add-buffer-used add-buffer)) - (buffer-size (string-length (add-buffer-string add-buffer)))) - (when (>= (+ append-len buffer-used) buffer-size) - (enlarge-add-buffer! add-buffer append-len)) - (string-copy! (add-buffer-string add-buffer) buffer-used str) - (set-add-buffer-used! add-buffer (+ append-len buffer-used)))) - ;; The piece table itself; diff --git a/par/piece-table.sld b/par/piece-table.sld index 7209baf..18556d2 100644 --- a/par/piece-table.sld +++ b/par/piece-table.sld @@ -1,5 +1,6 @@ (define-library (par piece-table) (import (scheme base) + (par buffers) (srfi 11)) (export make-piece-table piece-table-index |