diff options
| author | Juan Manuel Tomás <jtomas1815@gmail.com> | 2026-03-17 17:48:03 -0300 |
|---|---|---|
| committer | Juan Manuel Tomás <jtomas1815@gmail.com> | 2026-03-17 17:48:03 -0300 |
| commit | d08d5b232d74f3a75a833b231c4ef5e80870c993 (patch) | |
| tree | c123d61d35a992f5ea460a96eb89d1550c646b25 /cursor.lisp | |
| parent | d78ef10ad3ffe0eeaee0cd2a8f6b58e403085d48 (diff) | |
| download | monparser-d08d5b232d74f3a75a833b231c4ef5e80870c993.tar.gz monparser-d08d5b232d74f3a75a833b231c4ef5e80870c993.zip | |
Diffstat (limited to 'cursor.lisp')
| -rw-r--r-- | cursor.lisp | 82 |
1 files changed, 58 insertions, 24 deletions
diff --git a/cursor.lisp b/cursor.lisp index 72d4c90..a4cc100 100644 --- a/cursor.lisp +++ b/cursor.lisp @@ -1,40 +1,74 @@ (in-package #:monparser) -(defclass cursor () - ((index :type (unsigned-byte 44) :initarg :index :accessor index :initform 0) - (data :type simple-string :initarg :data :reader data :initform ""))) +(defstruct cursor + (start 0 :type (unsigned-byte 44)) + (end 0 :type (unsigned-byte 44)) + (data "" :type simple-string)) -(defun has-data? (cursor) - (< (index cursor) (length (data cursor)))) +(declaim (ftype (function (cursor) boolean) cursor-has-data?)) +(defun cursor-has-data? (cursor) + (< (cursor-end cursor) (length (cursor-data cursor)))) -(defun peek (cursor) - (char (data cursor) - (index cursor))) +(declaim (ftype (function (cursor) boolean) cursor-at-start?)) +(defun cursor-at-start? (cursor) + (= (cursor-start cursor) (cursor-end cursor))) -(defun advance (cursor) - (make-instance 'cursor - :data (data cursor) - :index (+ (index cursor) 1))) +(declaim (ftype (function (cursor) standard-char) cursor-peek)) +(defun cursor-peek (cursor) + (char (cursor-data cursor) + (cursor-end cursor))) +(declaim (ftype (function (cursor) cursor) cursor-advance)) +(defun cursor-advance (cursor) + (make-cursor :data (cursor-data cursor) + :start (cursor-start cursor) + :end (+ (cursor-end cursor) 1))) + +(declaim (ftype (function (cursor) cursor) cursor-rebase)) +(defun cursor-rebase (cursor) + (make-cursor :data (cursor-data cursor) + :start (cursor-end cursor) + :end (cursor-end cursor))) + +(declaim (ftype (function (cursor cursor) cursor) cursor-merge)) +(defun cursor-merge (prev next) + (assert (eq (cursor-data prev) (cursor-data next))) + (make-cursor :data (cursor-data next) + :start (cursor-start prev) + :end (cursor-end next))) + +(declaim (ftype (function (cursor cursor) fixnum) distance)) (defun distance (from to) - (- (index to) - (index from))) + (assert (eq (cursor-data from) (cursor-data to))) + (- (cursor-end to) + (cursor-end from))) -(defun context-window (str index &key (side-length 20)) - (let ((begin (max (- index side-length) 0)) - (end (min (+ index side-length) (length str))) +(declaim (ftype (function (cursor &key (:side-length fixnum)) t) context-window)) +(defun context-window (cursor &key (side-length 20)) + (let ((begin (max (- (cursor-start cursor) side-length) 0)) + (end (min (+ (cursor-end cursor) side-length) (length (cursor-data cursor)))) (result '())) - (push (subseq str (1+ index) end) result) - (push (elt str index) result) - (push (subseq str begin index) result) + (push (subseq (cursor-data cursor) (cursor-end cursor) end) result) + (push (subseq (cursor-data cursor) (cursor-start cursor) (cursor-end cursor)) result) + (push (subseq (cursor-data cursor) begin (cursor-start cursor)) result) result)) +(declaim (ftype (function (cursor) (cons fixnum fixnum)) line-and-column)) +(defun line-and-column (cursor) + (let ((line 1) (column 1)) + (dotimes (i (cursor-end cursor)) + (let ((c (char (cursor-data cursor) i))) + (case c + (#\Newline + (incf line) + (setf column 1)) + (t (incf column))))) + (cons line column))) + (defmethod print-object ((obj cursor) stream) (print-unreadable-object (obj stream :type t) - (let ((str (if (has-data? obj) + (let ((str (if (cursor-has-data? obj) (format nil "~{~a[4;33m~a[m~a~}" - (context-window (data obj) - (index obj) - :side-length 10)) + (context-window obj :side-length 10)) "END OF DATA"))) (format stream "~s" (substitute #\~ #\Newline str))))) |
