diff --git a/lib/chibi/parse.sld b/lib/chibi/parse.sld index 6e762869..f8adb36c 100644 --- a/lib/chibi/parse.sld +++ b/lib/chibi/parse.sld @@ -8,6 +8,7 @@ parse->list parse-fully->list file->parse-stream string->parse-stream parse-stream-substring parse-stream-start? parse-stream-end? parse-stream-ref + parse-stream-file-index parse-anything parse-nothing parse-epsilon parse-seq parse-and parse-or parse-not list->parse-seq parse-repeat parse-repeat+ parse-optional diff --git a/lib/chibi/parse/parse.scm b/lib/chibi/parse/parse.scm index defc6cfa..9165fb4e 100644 --- a/lib/chibi/parse/parse.scm +++ b/lib/chibi/parse/parse.scm @@ -10,12 +10,15 @@ (define-record-type Parse-Stream (%make-parse-stream - filename port buffer cache offset prev-char line column tail) + filename port file-offset buffer cache offset prev-char line column tail) parse-stream? ;; The file the data came from, for debugging and error reporting. (filename parse-stream-filename) ;; The underlying port. (port parse-stream-port) + ;; The offset of the first character of this chunk from the beginning of the + ;; file. + (file-offset parse-stream-file-offset) ;; A vector of characters read from the port. We use a vector ;; rather than a string for guaranteed O(1) access. (buffer parse-stream-buffer) @@ -50,7 +53,7 @@ (let ((port (if (pair? o) (car o) (open-input-file filename))) (len (if (and (pair? o) (pair? (cdr o))) (cadr o) default-buffer-size))) (%make-parse-stream - filename port (make-vector len #f) (make-vector len '()) 0 #f 0 0 #f))) + filename port 0 (make-vector len #f) (make-vector len '()) 0 #f 0 0 #f))) ;;> Open \var{filename} and create a parse stream on it. @@ -74,6 +77,7 @@ (cadr line-info))) (tail (%make-parse-stream (parse-stream-filename source) (parse-stream-port source) + (+ (parse-stream-file-offset source) len) (make-vector len #f) (make-vector len '()) 0 @@ -112,6 +116,12 @@ (parse-stream-fill! source i) (vector-ref (parse-stream-buffer source) i)) +;;> Returns the position, relative to the beginning of the file, of the +;;> character in parse stream \var{source} indexed by \var{i}. + +(define (parse-stream-file-index source i) + (+ (parse-stream-file-offset source) i)) + (define (parse-stream-last-char source) (let ((buf (parse-stream-buffer source))) (let lp ((i (min (- (vector-length buf) 1) (parse-stream-offset source))))