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

(defparameter whitespace
  (many (unit #'char:whitespace?)))

(defparameter end-of-input
  (lambda (input)
    (if (cursed:has-data? input)
      (make-failure :place input :message "Didn't reach end of input.")
      (make-parsing :tree nil :start input :end input))))

(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)))

(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)))))

(defmacro within (left p right)
  `(comp ((_ ,left)
          (cell ,p)
          (_ ,right))
     cell))

(defmacro interlinked (p separator)
  `(many (comp ((cell ,p)
                (_ (optional ,separator)))
           cell)))