summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoutade <thegoofist@protonmail.com>2020-03-06 13:33:23 -0600
committerBoutade <thegoofist@protonmail.com>2020-03-06 13:33:23 -0600
commitf448fcdb3319e74644d66c671c30c232d770615f (patch)
treee53a4aaa4621fb10e0fe93ef7a106d6ba8c404e0
parentedf93e1b1b942d3f0967597c3d13375e1805fb83 (diff)
added <<first combinator
-rw-r--r--package.lisp1
-rw-r--r--parzival.lisp12
2 files changed, 12 insertions, 1 deletions
diff --git a/package.lisp b/package.lisp
index ed0cee9..8b33dac 100644
--- a/package.lisp
+++ b/package.lisp
@@ -22,6 +22,7 @@
#:<<bind
#:<<let
#:<<and
+ #:<<first
#:<<ending
#:<<sat
#:<<~sat
diff --git a/parzival.lisp b/parzival.lisp
index 85a6632..35d6304 100644
--- a/parzival.lisp
+++ b/parzival.lisp
@@ -176,7 +176,7 @@ in then. If the parse fails the combinator else is run instead."
(defun <<and (parser1 parser2 &rest parsers)
- "Just like <<AND-THEN but where parse results are ignored. I.e. Applies each
+ "Just like <<BIND but where parse results are ignored. I.e. Applies each
parser in sequence, ignoring any intermediate results. The result (<<AND P1
P2 ... PN) is the result of PN."
(if parsers
@@ -184,6 +184,16 @@ in then. If the parse fails the combinator else is run instead."
(<<bind parser1 (returning parser2))))
+(defun <<first (parser other &rest others-still)
+ "A bit like <<AND in reverse. Returns the parse result of the first parser,
+ but only if the other parsers all succeed."
+ (<<bind parser
+ (lambda (first)
+ (apply #'<<and (append (list other)
+ others-still
+ (list (<<result first)))))))
+
+
(defun <<ending (parser)
"Creates a parser that succeeds if PARSER succeeds and the end of the input has been reached."
(<<bind parser