summaryrefslogtreecommitdiff
path: root/input.lisp
blob: 4edf6aaee19813f2d9a6c3a91fe46f8d2261e2b7 (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
41
42
43
44
45
46
47
48
49
50
51
52
53
(in-package #:monparser)

(defclass input ()
  ((cursor :initarg :cursor :accessor cursor :initform 0)
   (file :initarg :file :reader file :initform nil)
   (data :initarg :data :reader data :initform nil)))

(defun has-data? (input)
  (< (cursor input) (length (data input))))

(defun prefix? (target input)
  (string= target
           (data input)
           :start2 (cursor input)
           :end2 (min (+ (cursor input) (length target))
                      (length (data input)))))

(defun peek (input)
  (char (data input)
        (cursor input)))

(defun advance (input &optional (amount 1))
  (make-instance 'input
                 :data (data input)
                 :file (file input)
                 :cursor (+ (cursor input) amount)))

(defun input-sub (input1 input2)
  (- (cursor input1) (cursor input2)))

(defun from-string (str)
  (make-instance 'input :data str))

(defun read-file (path)
  (with-open-file (file path)
    (let* ((size (file-length file))
           (buf (make-string size)))
      (read-sequence buf file)
      buf)))

(defun from-file (filename)
  (make-instance 'input :file filename :data (read-file filename)))

(defun line-and-column (input)
  (let ((line 1) (column 1))
    (dotimes (i (cursor input))
      (let ((c (char (data input) i)))
        (case c
          (#\Newline
           (incf line)
           (setf column 1))
          (t (incf column)))))
    (values line column)))