summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Turner <jturner.usa@gmail.com>2025-10-30 14:00:10 +0000
committerJohn Turner <jturner.usa@gmail.com>2025-10-30 14:00:10 +0000
commit3eb3db5bda48fa975e5651f3fd7122b86886783b (patch)
treedfd37a46933d7aabddaa1749380604d16d2fd2c5
parentce05562d7efd736c058daaa470fcddde45fb0fbd (diff)
downloadmon-3eb3db5bda48fa975e5651f3fd7122b86886783b.tar.gz
change sexpr function to return a closure, and give it a comment
-rw-r--r--tests/sexpr.rs24
1 files changed, 14 insertions, 10 deletions
diff --git a/tests/sexpr.rs b/tests/sexpr.rs
index 328d868..e5024ef 100644
--- a/tests/sexpr.rs
+++ b/tests/sexpr.rs
@@ -30,15 +30,19 @@ fn int<'a>() -> impl Parser<&'a str, Output = Sexpr> {
numeric1().map(|output: &str| Sexpr::Int(output.parse().unwrap()))
}
-fn sexpr<'a>(it: InputIter<&'a str>) -> ParserResult<&'a str, Sexpr> {
- sexpr
- .separated_list(whitespace(), 0..)
- .delimited_by(tag("("), tag(")"))
- .map(|output| Sexpr::List(output))
- .or(atom())
- .or(string())
- .or(int())
- .parse(it)
+// Recursive parsers must avoid an infinite loop, you can do this
+// by returning a closure that accepts an InputIter and returns ParserResult.
+fn sexpr<'a>() -> impl Parser<&'a str, Output = Sexpr> {
+ |it| {
+ sexpr()
+ .separated_list(whitespace(), 0..)
+ .delimited_by(tag("("), tag(")"))
+ .map(|output| Sexpr::List(output))
+ .or(atom())
+ .or(string())
+ .or(int())
+ .parse(it)
+ }
}
#[test]
@@ -62,5 +66,5 @@ fn test_sexpr() {
let input = r#"(let ((a "hello") (b 2)))"#;
let it = InputIter::new(input);
- dbg!(sexpr(it).unwrap());
+ dbg!(sexpr().parse_finished(it).unwrap());
}