summaryrefslogtreecommitdiff
path: root/extra.lisp
blob: 20a13b1c02bde9dc7b93a3402b50ddb2fb59c39f (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
(in-package #:monparser)

(defmacro literal (word)
  (when (not (stringp word))
    (error "Literal only accepts strings as input."))
  (let ((binding-list '())
        (name-list '()))
    (loop :for c :across word :do
          (when c
            (let ((name (gensym)))
              (push name name-list)
              (push `(,name (unit ,c)) binding-list))))
    `(comp ,(reverse binding-list)
       ,(cons 'list (reverse name-list)))))

(defparameter nothing
  (new nil))

(defun optional (p)
  (one-of p nothing))

(defun many (p &key all)
  (comp ((x p)
         (xs (if all
               (one-of end
                       (many p :all all))
               (optional (many p)))))
    (if x (cons x xs) xs)))

(defun repeat (p min &optional (max 0))
  (if (> min 0)
    (comp ((x p)
           (xs (repeat p (1- min) (1- max))))
      (cons x xs))
    (if (> max 0)
      (comp ((x (optional p))
             (xs (repeat p 0 (if x (1- max) 0))))
        (if x (cons x xs) x))
      nothing)))

(defun whitespace? (x)
  (or (char= x #\Space)
      (not (graphic-char-p x))))

(defun separated-list (p separator)
  (comp ((v p)
         (sep (optional separator))
         (vn (if sep
               (separated-list p separator)
               nothing)))
    (cons v vn)))