From 1f1a18782e794b4ffbafbd6d905531473c492257 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 16 Dec 2022 00:21:13 -0500 Subject: [PATCH] Start of many1. --- src/parser/combinator.rs | 47 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/parser/combinator.rs b/src/parser/combinator.rs index 2daf5991..c281d483 100644 --- a/src/parser/combinator.rs +++ b/src/parser/combinator.rs @@ -40,6 +40,51 @@ use nom::sequence::tuple; use nom::IResult; use nom::InputLength; +pub fn context_many1<'r, 's, I, O, E, M>( + context: Context<'r, 's>, + mut many_matcher: M, +) -> impl FnMut(I) -> IResult>, E> + 'r +where + I: Clone + InputLength, + E: ParseError, + M: for<'x> Fn(Context<'x, 's>, I) -> IResult + 'r, + O: Into>, +{ + move |mut i: I| { + let mut err = None; + // TODO: Can I eliminate the clone? I think this is incrementing the reference count + let mut current_context = context.clone(); + // Despite the clone, the Rc should still point to the same value. + assert!(current_context.ptr_eq(context)); + loop { + match many_matcher(¤t_context, i.clone()) { + Ok((remaining, many_elem)) => { + current_context = current_context.with_additional_node( + ContextElement::PreviousElementNode(PreviousElementNode { + element: many_elem.into(), + }), + ); + i = remaining; + } + the_error @ Err(_) => { + err = Some(the_error); + break; + } + } + } + current_context + .iter_until(context) + .filter(|context_element| match context_element.get_data() { + ContextElement::PreviousElementNode(_) => true, + ContextElement::ExitMatcherNode(_) => false, + ContextElement::Context(_) => false, + ContextElement::StartOfParagraph => false, + }); + + // todo + todo!() + } +} pub fn context_many_till<'r, 's, I, O, E, F, M, T>( context: Context<'r, 's>, mut many_matcher: M, @@ -53,7 +98,7 @@ where O: Into>, { move |mut i: I| { - // TODO: Can I eliminate the clone? + // TODO: Can I eliminate the clone? I think this is incrementing the reference count let mut current_context = context.clone(); // Despite the clone, the Rc should still point to the same value, otherwise we'll get stuck in an endless loop. assert!(current_context.ptr_eq(context));