blob: 15b8e0876baa491478f5ecde9c499d4a90163139 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
(in-package #:monparser)
(defclass parser-input ()
((cursor :initarg :cursor :accessor input-cursor :initform 0)
(data :initarg :data :reader input-data :initform nil)))
(defun has-data? (input)
(< (input-cursor input) (length (input-data input))))
(defun peek (input)
(char (input-data input)
(input-cursor input)))
(defun advance (input)
(make-instance 'parser-input
:data (input-data input)
:cursor (+ (input-cursor input) 1)))
(defun cursor-distance (input1 input2)
(- (input-cursor input1) (input-cursor input2)))
(defun line-and-column (input)
(let ((line 1) (column 1))
(dotimes (i (input-cursor input))
(let ((c (char (input-data input) i)))
(case c
(#\Newline
(incf line)
(setf column 1))
(t (incf column)))))
(values line column)))
(defmethod print-object ((obj parser-input) stream)
(let ((context-length 10))
(let ((begin (max (- (input-cursor obj) context-length) 0))
(end (min (+ (input-cursor obj) context-length) (length (input-data obj)))))
(format stream "...~a[1;33m~a[m~a..."
(substitute #\¶ #\Newline (subseq (input-data obj) begin (input-cursor obj)))
(substitute #\¶ #\Newline (subseq (input-data obj) (input-cursor obj) (1+ (input-cursor obj))))
(substitute #\¶ #\Newline (subseq (input-data obj) (1+ (input-cursor obj)) end))))))
|