summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Manuel Tomás <jtomas1815@gmail.com>2024-10-12 16:43:50 -0300
committerJuan Manuel Tomás <jtomas1815@gmail.com>2024-10-12 16:43:50 -0300
commitb196a5d56db31d6836c1ed028f38146cbb08436c (patch)
treeffe56d98484b4897b3c2be4a9d98cb87b6bba8f6
parent1b00d7b4b1eaa3b1ce2ea12e3bfa255450143cb5 (diff)
downloadmonparser-b196a5d56db31d6836c1ed028f38146cbb08436c.tar.gz
monparser-b196a5d56db31d6836c1ed028f38146cbb08436c.zip
Implement literal as a macro that chains unit
-rw-r--r--package.lisp1
-rw-r--r--parser.lisp28
2 files changed, 17 insertions, 12 deletions
diff --git a/package.lisp b/package.lisp
index c352bd4..035cf77 100644
--- a/package.lisp
+++ b/package.lisp
@@ -4,6 +4,7 @@
#:comp
#:one-of
#:unit
+ #:fail
#:literal
#:nothing
#:optional
diff --git a/parser.lisp b/parser.lisp
index d22ae81..c627af1 100644
--- a/parser.lisp
+++ b/parser.lisp
@@ -40,10 +40,6 @@
:message (format nil "Didn't reach expected limit: ~a." limit))
(make-parsing :tree tree :left input))))
-(defun fail (message)
- (lambda (input &key limit lazy)
- (make-failure :place input :message message)))
-
(defun bind (p f &key (greedy t))
(lambda (input &key limit lazy)
(let (r)
@@ -127,6 +123,10 @@
result))))
(one-of-rec (cons first-parser (cons second-parser other-parsers))))))
+(defun fail (message)
+ (lambda (input &key limit lazy)
+ (make-failure :place input :message message)))
+
(defmacro unit (&optional predicate)
(cond ((null predicate)
(setf predicate '(characterp it)))
@@ -151,14 +151,18 @@
:message (format nil "Expected: ~a, Got: ~a" ',predicate it))))
(make-failure :place input :message "Reached end of input.")))))
-(defun literal (target)
- (lambda (input &key limit lazy)
- (declare (ignore lazy limit))
- (if (has-data? input)
- (if (prefix? target input)
- (make-parsing :tree target :left (advance input (length target)))
- (make-failure :place input :message "Predicate not satisfied."))
- (make-failure :place input :message "Reached end of input."))))
+(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)
+ (coerce ,(cons 'list (reverse name-list)) 'string))))
(defparameter nothing
(new nil))