summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoutade <thegoofist@protonmail.com>2020-03-07 07:12:34 -0600
committerBoutade <thegoofist@protonmail.com>2020-03-07 07:12:34 -0600
commitdb9bab71b4660062c601ab527b1dfdbcc884cc21 (patch)
treee072fbb3a2a43c84cd64c8c0f6d16983fb364ef2
parent1181af61564962efcd3cfcfcb651371d86e86714 (diff)
added <<ignore-until
-rw-r--r--package.lisp1
-rw-r--r--parzival.asd2
-rw-r--r--parzival.lisp43
3 files changed, 30 insertions, 16 deletions
diff --git a/package.lisp b/package.lisp
index 9d8f654..dc26c34 100644
--- a/package.lisp
+++ b/package.lisp
@@ -14,6 +14,7 @@
#:<<when
#:<<plus
#:<<until
+ #:<<ignore-until
#:<<or
#:<<~
#:<<?
diff --git a/parzival.asd b/parzival.asd
index 168389c..c819f69 100644
--- a/parzival.asd
+++ b/parzival.asd
@@ -4,7 +4,7 @@
:description "Streaming parser language in Common Lisp."
:author "Boutade <thegoofist@protonmail.com>"
:license "GPLv3"
- :version "0.2.0"
+ :version "0.3.0"
:serial t
:depends-on (#:replay-streams)
:components ((:file "package")
diff --git a/parzival.lisp b/parzival.lisp
index d00a1d4..4c47c32 100644
--- a/parzival.lisp
+++ b/parzival.lisp
@@ -123,21 +123,34 @@ in then. If the parse fails the combinator else is run instead."
"Consumes the stream one character at a time until PARSER succeeds. The parse
value of (<<UNTIL PARSER) is a list of the characters consumed, ending in the
value parsed by PARSER."
- (lambda (stream)
- (let ((collected nil))
- (labels ((rec (stream)
- (let ((chkpt (replay-streams:checkpoint stream)))
- (<<if (result parser stream)
- (progn
- (replay-streams:free-checkpoint stream chkpt)
- (<<result (reverse (cons result collected))))
- (progn
- (replay-streams:rewind-to stream chkpt)
- (<<bind <item<
- (lambda (item)
- (push item collected)
- #'rec)))))))
- (rec stream)))))
+ (let ((collected nil))
+ (labels ((rec (stream)
+ (let ((chkpt (replay-streams:checkpoint stream)))
+ (<<if (result parser stream)
+ (progn
+ (replay-streams:free-checkpoint stream chkpt)
+ (<<result (reverse (cons result collected))))
+ (progn
+ (replay-streams:rewind-to stream chkpt)
+ (<<bind <item<
+ (lambda (item)
+ (push item collected)
+ #'rec)))))))
+ #'rec)))
+
+(defun <<ignore-until (parser)
+ "Just like <<UNTIL except it does not build up intermediate results. Results
+ in the result of PARSER."
+ (labels ((rec (stream)
+ (let ((chkpt (checkpoint stream)))
+ (<<if (result parser stream)
+ (progn
+ (free-checkpoint stream chkpt)
+ (<<result result))
+ (progn
+ (rewind-to stream chkpt)
+ (<<and <item< #'rec))))))
+ #'rec))
(defun <<or (&rest parsers)
"Tries each parser one after the other, rewinding the input stream after each