///|
fn[T, A] bounded_repeat(
parser : Parser[T, A],
max_count : Int,
stop_on_unconsumed_failure : Bool,
) -> Parser[T, Array[A]] {
{
execute: initial => {
let values = []
let mut current = initial
let mut consumed = false
let mut committed = false
for index = 0; index < max_count; index = index + 1 {
match (parser.execute)(current) {
Success(value, next, child_consumed, child_committed) => {
values.push(value)
current = next
consumed = consumed || child_consumed
committed = committed || child_committed
}
Failure(error, false, false) =>
if stop_on_unconsumed_failure {
break Success(values, current, consumed, committed)
} else {
break Failure(error, consumed, committed)
}
Failure(error, child_consumed, child_committed) =>
break Failure(
error,
consumed || child_consumed,
committed || child_committed,
)
}
} nobreak {
Success(values, current, consumed, committed)
}
},
}
}
///|
/// Parses exactly `count` occurrences. Non-positive counts succeed with no
/// values and consume no input.
pub fn[T, A] Parser::count(
self : Parser[T, A],
count : Int,
) -> Parser[T, Array[A]] {
bounded_repeat(self, count, false)
}
///|
/// Parses at most `max_count` occurrences. It stops at an unconsumed failure.
/// Non-positive bounds succeed with no values and consume no input.
pub fn[T, A] Parser::repeat_0_to_n(
self : Parser[T, A],
max_count : Int,
) -> Parser[T, Array[A]] {
bounded_repeat(self, max_count, true)
}