summaryrefslogtreecommitdiff
path: root/input.lisp
blob: 2cdfd84741fe31183b227ac5c9a0a8d945e58527 (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
54
55
(in-package #:input)

(defstruct input
  (cursor 0)
  (file nil :read-only t)
  (data nil :read-only t))

(defun has-data? (input &optional (window-size 1))
  (<= (+ window-size (input-cursor input))
      (length (input-data input))))

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

(defun peek-n (input window-size)
  (subseq (input-data input)
          (input-cursor input)
          (+ window-size (input-cursor input))))

(defun peek-rest (input)
  (subseq (input-data input)
          (input-cursor input)
          (length (input-data input))))

(defun advance (input &optional (amount 1))
  (let ((new-input (copy-structure input)))
    (incf (input-cursor new-input) amount)
    new-input))

(defun advance-to-end (input)
  (let ((new-input (copy-structure input)))
    (setf (input-cursor new-input) (length (input-data input)))
    new-input))

(declaim (ftype (function (simple-string) (values input &optional)) from-string))
(defun from-string (str)
  (make-input :data str))

(declaim (ftype (function (simple-string) (values input &optional)) from-file))
(defun from-file (filename)
  (make-input :file filename :data (str:read-file filename)))

(defun generate-report (input message)
  (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)))))
    (if (input-file input)
      (format nil "~a:~a:~a: ~a" (input-file input) line column message)
      (format nil "~a:~a: ~a" line column message))))