mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-18 02:50:17 +00:00
Merge branch 'precompiled-legacy' into https-packages
This commit is contained in:
commit
f5cb2d73a1
96 changed files with 4063 additions and 1334 deletions
|
@ -12,8 +12,7 @@ pub enum Either<First, Second> {
|
|||
|
||||
impl<F: Copy, S: Copy> Copy for Either<F, S> {}
|
||||
|
||||
pub type ParseResult<'a, Output, Error> =
|
||||
Result<(Progress, Output, State<'a>), (Progress, Error, State<'a>)>;
|
||||
pub type ParseResult<'a, Output, Error> = Result<(Progress, Output, State<'a>), (Progress, Error)>;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Progress {
|
||||
|
@ -853,7 +852,7 @@ where
|
|||
|
||||
let (progress, value, state) = match &res {
|
||||
Ok((progress, result, state)) => (progress, Ok(result), state),
|
||||
Err((progress, error, state)) => (progress, Err(error), state),
|
||||
Err((progress, error)) => (progress, Err(error), state),
|
||||
};
|
||||
|
||||
println!(
|
||||
|
@ -926,7 +925,7 @@ where
|
|||
let width = keyword.len();
|
||||
|
||||
if !state.bytes().starts_with(keyword.as_bytes()) {
|
||||
return Err((NoProgress, if_error(state.pos()), state));
|
||||
return Err((NoProgress, if_error(state.pos())));
|
||||
}
|
||||
|
||||
// the next character should not be an identifier character
|
||||
|
@ -940,7 +939,7 @@ where
|
|||
state = state.advance(width);
|
||||
Ok((MadeProgress, (), state))
|
||||
}
|
||||
Some(_) => Err((NoProgress, if_error(state.pos()), state)),
|
||||
Some(_) => Err((NoProgress, if_error(state.pos()))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -957,6 +956,8 @@ where
|
|||
Error: 'a,
|
||||
{
|
||||
move |arena, state: State<'a>, min_indent: u32| {
|
||||
let original_state = state.clone();
|
||||
|
||||
let start_bytes_len = state.bytes().len();
|
||||
|
||||
match parser.parse(arena, state, min_indent) {
|
||||
|
@ -970,10 +971,10 @@ where
|
|||
buf.push(first_output);
|
||||
|
||||
loop {
|
||||
match delimiter.parse(arena, state, min_indent) {
|
||||
match delimiter.parse(arena, state.clone(), min_indent) {
|
||||
Ok((_, (), next_state)) => {
|
||||
// If the delimiter passed, check the element parser.
|
||||
match parser.parse(arena, next_state, min_indent) {
|
||||
match parser.parse(arena, next_state.clone(), min_indent) {
|
||||
Ok((element_progress, next_output, next_state)) => {
|
||||
// in practice, we want elements to make progress
|
||||
debug_assert_eq!(element_progress, MadeProgress);
|
||||
|
@ -981,28 +982,28 @@ where
|
|||
state = next_state;
|
||||
buf.push(next_output);
|
||||
}
|
||||
Err((_, fail, state)) => {
|
||||
Err((_, fail)) => {
|
||||
// If the delimiter parsed, but the following
|
||||
// element did not, that's a fatal error.
|
||||
let progress = Progress::from_lengths(
|
||||
start_bytes_len,
|
||||
state.bytes().len(),
|
||||
next_state.bytes().len(),
|
||||
);
|
||||
|
||||
return Err((progress, fail, state));
|
||||
return Err((progress, fail));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err((delim_progress, fail, old_state)) => match delim_progress {
|
||||
MadeProgress => return Err((MadeProgress, fail, old_state)),
|
||||
NoProgress => return Ok((NoProgress, buf, old_state)),
|
||||
Err((delim_progress, fail)) => match delim_progress {
|
||||
MadeProgress => return Err((MadeProgress, fail)),
|
||||
NoProgress => return Ok((NoProgress, buf, state)),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
Err((element_progress, fail, new_state)) => match element_progress {
|
||||
MadeProgress => Err((MadeProgress, fail, new_state)),
|
||||
NoProgress => Ok((NoProgress, Vec::new_in(arena), new_state)),
|
||||
Err((element_progress, fail)) => match element_progress {
|
||||
MadeProgress => Err((MadeProgress, fail)),
|
||||
NoProgress => Ok((NoProgress, Vec::new_in(arena), original_state)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -1020,6 +1021,7 @@ where
|
|||
Error: 'a,
|
||||
{
|
||||
move |arena, state: State<'a>, min_indent: u32| {
|
||||
let original_state = state.clone();
|
||||
let start_bytes_len = state.bytes().len();
|
||||
|
||||
match parser.parse(arena, state, min_indent) {
|
||||
|
@ -1032,10 +1034,10 @@ where
|
|||
buf.push(first_output);
|
||||
|
||||
loop {
|
||||
match delimiter.parse(arena, state, min_indent) {
|
||||
match delimiter.parse(arena, state.clone(), min_indent) {
|
||||
Ok((_, (), next_state)) => {
|
||||
// If the delimiter passed, check the element parser.
|
||||
match parser.parse(arena, next_state, min_indent) {
|
||||
match parser.parse(arena, next_state.clone(), min_indent) {
|
||||
Ok((element_progress, next_output, next_state)) => {
|
||||
// in practice, we want elements to make progress
|
||||
debug_assert_eq!(element_progress, MadeProgress);
|
||||
|
@ -1043,27 +1045,27 @@ where
|
|||
state = next_state;
|
||||
buf.push(next_output);
|
||||
}
|
||||
Err((_, _fail, old_state)) => {
|
||||
Err((_, _fail)) => {
|
||||
// If the delimiter parsed, but the following
|
||||
// element did not, that means we saw a trailing comma
|
||||
let progress = Progress::from_lengths(
|
||||
start_bytes_len,
|
||||
old_state.bytes().len(),
|
||||
next_state.bytes().len(),
|
||||
);
|
||||
return Ok((progress, buf, old_state));
|
||||
return Ok((progress, buf, next_state));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err((delim_progress, fail, old_state)) => match delim_progress {
|
||||
MadeProgress => return Err((MadeProgress, fail, old_state)),
|
||||
NoProgress => return Ok((NoProgress, buf, old_state)),
|
||||
Err((delim_progress, fail)) => match delim_progress {
|
||||
MadeProgress => return Err((MadeProgress, fail)),
|
||||
NoProgress => return Ok((NoProgress, buf, state)),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
Err((element_progress, fail, new_state)) => match element_progress {
|
||||
MadeProgress => Err((MadeProgress, fail, new_state)),
|
||||
NoProgress => Ok((NoProgress, Vec::new_in(arena), new_state)),
|
||||
Err((element_progress, fail)) => match element_progress {
|
||||
MadeProgress => Err((MadeProgress, fail)),
|
||||
NoProgress => Ok((NoProgress, Vec::new_in(arena), original_state)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -1092,6 +1094,7 @@ where
|
|||
buf.push(first_output);
|
||||
|
||||
loop {
|
||||
let old_state = state.clone();
|
||||
match delimiter.parse(arena, state, min_indent) {
|
||||
Ok((_, (), next_state)) => {
|
||||
// If the delimiter passed, check the element parser.
|
||||
|
@ -1100,16 +1103,16 @@ where
|
|||
state = next_state;
|
||||
buf.push(next_output);
|
||||
}
|
||||
Err((_, fail, state)) => {
|
||||
return Err((MadeProgress, fail, state));
|
||||
Err((_, fail)) => {
|
||||
return Err((MadeProgress, fail));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err((delim_progress, fail, old_state)) => {
|
||||
Err((delim_progress, fail)) => {
|
||||
match delim_progress {
|
||||
MadeProgress => {
|
||||
// fail if the delimiter made progress
|
||||
return Err((MadeProgress, fail, old_state));
|
||||
return Err((MadeProgress, fail));
|
||||
}
|
||||
NoProgress => {
|
||||
let progress = Progress::from_lengths(
|
||||
|
@ -1123,7 +1126,7 @@ where
|
|||
}
|
||||
}
|
||||
}
|
||||
Err((fail_progress, fail, new_state)) => Err((fail_progress, fail, new_state)),
|
||||
Err((fail_progress, fail)) => Err((fail_progress, fail)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1142,6 +1145,7 @@ where
|
|||
Error: 'a,
|
||||
{
|
||||
move |arena, state: State<'a>, min_indent: u32| {
|
||||
let original_state = state.clone();
|
||||
let start_bytes_len = state.bytes().len();
|
||||
|
||||
match parser.parse(arena, state, min_indent) {
|
||||
|
@ -1153,27 +1157,28 @@ where
|
|||
buf.push(first_output);
|
||||
|
||||
loop {
|
||||
let old_state = state.clone();
|
||||
match delimiter.parse(arena, state, min_indent) {
|
||||
Ok((_, (), next_state)) => {
|
||||
// If the delimiter passed, check the element parser.
|
||||
match parser.parse(arena, next_state, min_indent) {
|
||||
match parser.parse(arena, next_state.clone(), min_indent) {
|
||||
Ok((_, next_output, next_state)) => {
|
||||
state = next_state;
|
||||
buf.push(next_output);
|
||||
}
|
||||
Err((MadeProgress, fail, state)) => {
|
||||
return Err((MadeProgress, fail, state));
|
||||
Err((MadeProgress, fail)) => {
|
||||
return Err((MadeProgress, fail));
|
||||
}
|
||||
Err((NoProgress, _fail, state)) => {
|
||||
return Err((NoProgress, to_element_error(state.pos()), state));
|
||||
Err((NoProgress, _fail)) => {
|
||||
return Err((NoProgress, to_element_error(next_state.pos())));
|
||||
}
|
||||
}
|
||||
}
|
||||
Err((delim_progress, fail, old_state)) => {
|
||||
Err((delim_progress, fail)) => {
|
||||
match delim_progress {
|
||||
MadeProgress => {
|
||||
// fail if the delimiter made progress
|
||||
return Err((MadeProgress, fail, old_state));
|
||||
return Err((MadeProgress, fail));
|
||||
}
|
||||
NoProgress => {
|
||||
let progress = Progress::from_lengths(
|
||||
|
@ -1188,10 +1193,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
Err((MadeProgress, fail, state)) => Err((MadeProgress, fail, state)),
|
||||
Err((NoProgress, _fail, state)) => {
|
||||
Err((NoProgress, to_element_error(state.pos()), state))
|
||||
}
|
||||
Err((MadeProgress, fail)) => Err((MadeProgress, fail)),
|
||||
Err((NoProgress, _fail)) => Err((NoProgress, to_element_error(original_state.pos()))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1203,7 +1206,7 @@ pub fn fail_when_progress<T, E>(
|
|||
state: State<'_>,
|
||||
) -> ParseResult<'_, T, E> {
|
||||
match progress {
|
||||
MadeProgress => Err((MadeProgress, fail, state)),
|
||||
MadeProgress => Err((MadeProgress, fail)),
|
||||
NoProgress => Ok((NoProgress, value, state)),
|
||||
}
|
||||
}
|
||||
|
@ -1220,7 +1223,7 @@ where
|
|||
|
||||
match parser.parse(arena, state, min_indent) {
|
||||
Ok((progress, out1, state)) => Ok((progress, Some(out1), state)),
|
||||
Err((_, _, _)) => {
|
||||
Err((_, _)) => {
|
||||
// NOTE this will backtrack
|
||||
// TODO can we get rid of some of the potential backtracking?
|
||||
Ok((NoProgress, None, original_state))
|
||||
|
@ -1259,16 +1262,14 @@ macro_rules! loc {
|
|||
#[macro_export]
|
||||
macro_rules! skip_first {
|
||||
($p1:expr, $p2:expr) => {
|
||||
move |arena, state: $crate::state::State<'a>, min_indent: u32| {
|
||||
let original_state = state.clone();
|
||||
|
||||
match $p1.parse(arena, state, min_indent) {
|
||||
Ok((p1, _, state)) => match $p2.parse(arena, state, min_indent) {
|
||||
Ok((p2, out2, state)) => Ok((p1.or(p2), out2, state)),
|
||||
Err((p2, fail, _)) => Err((p1.or(p2), fail, original_state)),
|
||||
},
|
||||
Err((progress, fail, _)) => Err((progress, fail, original_state)),
|
||||
}
|
||||
move |arena, state: $crate::state::State<'a>, min_indent: u32| match $p1
|
||||
.parse(arena, state, min_indent)
|
||||
{
|
||||
Ok((p1, _, state)) => match $p2.parse(arena, state, min_indent) {
|
||||
Ok((p2, out2, state)) => Ok((p1.or(p2), out2, state)),
|
||||
Err((p2, fail)) => Err((p1.or(p2), fail)),
|
||||
},
|
||||
Err((progress, fail)) => Err((progress, fail)),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1278,16 +1279,14 @@ macro_rules! skip_first {
|
|||
#[macro_export]
|
||||
macro_rules! skip_second {
|
||||
($p1:expr, $p2:expr) => {
|
||||
move |arena, state: $crate::state::State<'a>, min_indent: u32| {
|
||||
let original_state = state.clone();
|
||||
|
||||
match $p1.parse(arena, state, min_indent) {
|
||||
Ok((p1, out1, state)) => match $p2.parse(arena, state, min_indent) {
|
||||
Ok((p2, _, state)) => Ok((p1.or(p2), out1, state)),
|
||||
Err((p2, fail, _)) => Err((p1.or(p2), fail, original_state)),
|
||||
},
|
||||
Err((progress, fail, _)) => Err((progress, fail, original_state)),
|
||||
}
|
||||
move |arena, state: $crate::state::State<'a>, min_indent: u32| match $p1
|
||||
.parse(arena, state, min_indent)
|
||||
{
|
||||
Ok((p1, out1, state)) => match $p2.parse(arena, state, min_indent) {
|
||||
Ok((p2, _, state)) => Ok((p1.or(p2), out1, state)),
|
||||
Err((p2, fail)) => Err((p1.or(p2), fail)),
|
||||
},
|
||||
Err((progress, fail)) => Err((progress, fail)),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1383,6 +1382,23 @@ macro_rules! succeed {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn fail_when<'a, T, T2, E, F, P>(f: F, p: P) -> impl Parser<'a, T, E>
|
||||
where
|
||||
T: 'a,
|
||||
T2: 'a,
|
||||
E: 'a,
|
||||
F: Fn(Position) -> E,
|
||||
P: Parser<'a, T2, E>,
|
||||
{
|
||||
move |arena: &'a bumpalo::Bump, state: State<'a>, min_indent: u32| {
|
||||
let original_state = state.clone();
|
||||
match p.parse(arena, state, min_indent) {
|
||||
Ok((_, _, _)) => Err((MadeProgress, f(original_state.pos()))),
|
||||
Err((progress, err)) => Err((progress, err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fail<'a, T, E, F>(f: F) -> impl Parser<'a, T, E>
|
||||
where
|
||||
T: 'a,
|
||||
|
@ -1390,25 +1406,21 @@ where
|
|||
F: Fn(Position) -> E,
|
||||
{
|
||||
move |_arena: &'a bumpalo::Bump, state: State<'a>, _min_indent: u32| {
|
||||
Err((NoProgress, f(state.pos()), state))
|
||||
Err((NoProgress, f(state.pos())))
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! and {
|
||||
($p1:expr, $p2:expr) => {
|
||||
move |arena: &'a bumpalo::Bump, state: $crate::state::State<'a>, min_indent: u32| {
|
||||
// We have to clone this because if the first parser passes and then
|
||||
// the second one fails, we need to revert back to the original state.
|
||||
let original_state = state.clone();
|
||||
|
||||
match $p1.parse(arena, state, min_indent) {
|
||||
Ok((p1, out1, state)) => match $p2.parse(arena, state, min_indent) {
|
||||
Ok((p2, out2, state)) => Ok((p1.or(p2), (out1, out2), state)),
|
||||
Err((p2, fail, _)) => Err((p1.or(p2), fail, original_state)),
|
||||
},
|
||||
Err((progress, fail, state)) => Err((progress, fail, state)),
|
||||
}
|
||||
move |arena: &'a bumpalo::Bump, state: $crate::state::State<'a>, min_indent: u32| match $p1
|
||||
.parse(arena, state, min_indent)
|
||||
{
|
||||
Ok((p1, out1, state)) => match $p2.parse(arena, state, min_indent) {
|
||||
Ok((p2, out2, state)) => Ok((p1.or(p2), (out1, out2), state)),
|
||||
Err((p2, fail)) => Err((p1.or(p2), fail)),
|
||||
},
|
||||
Err((progress, fail)) => Err((progress, fail)),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1430,16 +1442,12 @@ macro_rules! indented_seq {
|
|||
let p1_indent = start_indent;
|
||||
let p2_indent = p1_indent + 1;
|
||||
|
||||
// We have to clone this because if the first parser passes and then
|
||||
// the second one fails, we need to revert back to the original state.
|
||||
let original_state = state.clone();
|
||||
|
||||
match $p1.parse(arena, state, p1_indent) {
|
||||
Ok((p1, (), state)) => match $p2.parse(arena, state, p2_indent) {
|
||||
Ok((p2, out2, state)) => Ok((p1.or(p2), out2, state)),
|
||||
Err((p2, fail, _)) => Err((p1.or(p2), fail, original_state)),
|
||||
Err((p2, fail)) => Err((p1.or(p2), fail)),
|
||||
},
|
||||
Err((progress, fail, state)) => Err((progress, fail, state)),
|
||||
Err((progress, fail)) => Err((progress, fail)),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1456,16 +1464,12 @@ macro_rules! absolute_indented_seq {
|
|||
let p1_indent = start_indent;
|
||||
let p2_indent = p1_indent + 1;
|
||||
|
||||
// We have to clone this because if the first parser passes and then
|
||||
// the second one fails, we need to revert back to the original state.
|
||||
let original_state = state.clone();
|
||||
|
||||
match $p1.parse(arena, state, p1_indent) {
|
||||
Ok((p1, out1, state)) => match $p2.parse(arena, state, p2_indent) {
|
||||
Ok((p2, out2, state)) => Ok((p1.or(p2), (out1, out2), state)),
|
||||
Err((p2, fail, _)) => Err((p1.or(p2), fail, original_state)),
|
||||
Err((p2, fail)) => Err((p1.or(p2), fail)),
|
||||
},
|
||||
Err((progress, fail, state)) => Err((progress, fail, state)),
|
||||
Err((progress, fail)) => Err((progress, fail)),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1479,8 +1483,8 @@ macro_rules! one_of {
|
|||
|
||||
match $p1.parse(arena, state, min_indent) {
|
||||
valid @ Ok(_) => valid,
|
||||
Err((MadeProgress, fail, state)) => Err((MadeProgress, fail, state)),
|
||||
Err((NoProgress, _, _)) => $p2.parse(arena, original_state, min_indent),
|
||||
Err((MadeProgress, fail)) => Err((MadeProgress, fail)),
|
||||
Err((NoProgress, _)) => $p2.parse(arena, original_state, min_indent),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1496,12 +1500,14 @@ macro_rules! one_of {
|
|||
#[macro_export]
|
||||
macro_rules! maybe {
|
||||
($p1:expr) => {
|
||||
move |arena: &'a bumpalo::Bump, state: $crate::state::State<'a>, min_indent: u32| match $p1
|
||||
.parse(arena, state, min_indent)
|
||||
{
|
||||
Ok((progress, value, state)) => Ok((progress, Some(value), state)),
|
||||
Err((MadeProgress, fail, state)) => Err((MadeProgress, fail, state)),
|
||||
Err((NoProgress, _, state)) => Ok((NoProgress, None, state)),
|
||||
move |arena: &'a bumpalo::Bump, state: $crate::state::State<'a>, min_indent: u32| {
|
||||
let original_state = state.clone();
|
||||
|
||||
match $p1.parse(arena, state, min_indent) {
|
||||
Ok((progress, value, state)) => Ok((progress, Some(value), state)),
|
||||
Err((MadeProgress, fail)) => Err((MadeProgress, fail)),
|
||||
Err((NoProgress, _)) => Ok((NoProgress, None, original_state)),
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1510,11 +1516,12 @@ macro_rules! maybe {
|
|||
macro_rules! one_of_with_error {
|
||||
($toerror:expr; $p1:expr) => {
|
||||
move |arena: &'a bumpalo::Bump, state: $crate::state::State<'a>, min_indent: u32| {
|
||||
let original_state = state.clone();
|
||||
|
||||
match $p1.parse(arena, state, min_indent) {
|
||||
valid @ Ok(_) => valid,
|
||||
Err((MadeProgress, fail, state)) => Err((MadeProgress, fail, state )),
|
||||
Err((NoProgress, _, state)) => Err((MadeProgress, $toerror(state.pos()), state)),
|
||||
Err((MadeProgress, fail)) => Err((MadeProgress, fail)),
|
||||
Err((NoProgress, _)) => Err((MadeProgress, $toerror(original_state.pos()))),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1571,24 +1578,11 @@ where
|
|||
P: Parser<'a, T, X>,
|
||||
Y: 'a,
|
||||
{
|
||||
move |a, s, min_indent| match parser.parse(a, s, min_indent) {
|
||||
Ok(t) => Ok(t),
|
||||
Err((p, error, s)) => Err((p, map_error(error, s.pos()), s)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Like `specialize`, except the error function receives a Region representing the begin/end of the error
|
||||
pub fn specialize_region<'a, F, P, T, X, Y>(map_error: F, parser: P) -> impl Parser<'a, T, Y>
|
||||
where
|
||||
F: Fn(X, Region) -> Y,
|
||||
P: Parser<'a, T, X>,
|
||||
Y: 'a,
|
||||
{
|
||||
move |a, s: State<'a>, min_indent: u32| {
|
||||
let start = s.pos();
|
||||
match parser.parse(a, s, min_indent) {
|
||||
move |a, state: State<'a>, min_indent| {
|
||||
let original_state = state.clone();
|
||||
match parser.parse(a, state, min_indent) {
|
||||
Ok(t) => Ok(t),
|
||||
Err((p, error, s)) => Err((p, map_error(error, Region::new(start, s.pos())), s)),
|
||||
Err((p, error)) => Err((p, map_error(error, original_state.pos()))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1600,9 +1594,12 @@ where
|
|||
Y: 'a,
|
||||
X: 'a,
|
||||
{
|
||||
move |a, s, min_indent| match parser.parse(a, s, min_indent) {
|
||||
Ok(t) => Ok(t),
|
||||
Err((p, error, s)) => Err((p, map_error(a.alloc(error), s.pos()), s)),
|
||||
move |a, state: State<'a>, min_indent| {
|
||||
let original_state = state.clone();
|
||||
match parser.parse(a, state, min_indent) {
|
||||
Ok(t) => Ok(t),
|
||||
Err((p, error)) => Err((p, map_error(a.alloc(error), original_state.pos()))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1618,7 +1615,7 @@ where
|
|||
let state = state.advance(1);
|
||||
Ok((MadeProgress, (), state))
|
||||
}
|
||||
_ => Err((NoProgress, to_error(state.pos()), state)),
|
||||
_ => Err((NoProgress, to_error(state.pos()))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1631,7 +1628,7 @@ where
|
|||
|
||||
move |_arena: &'a Bump, state: State<'a>, min_indent: u32| {
|
||||
if min_indent > state.column() {
|
||||
return Err((NoProgress, to_error(state.pos()), state));
|
||||
return Err((NoProgress, to_error(state.pos())));
|
||||
}
|
||||
|
||||
match state.bytes().first() {
|
||||
|
@ -1639,7 +1636,7 @@ where
|
|||
let state = state.advance(1);
|
||||
Ok((MadeProgress, (), state))
|
||||
}
|
||||
_ => Err((NoProgress, to_error(state.pos()), state)),
|
||||
_ => Err((NoProgress, to_error(state.pos()))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1659,7 +1656,7 @@ where
|
|||
let state = state.advance(2);
|
||||
Ok((MadeProgress, (), state))
|
||||
} else {
|
||||
Err((NoProgress, to_error(state.pos()), state))
|
||||
Err((NoProgress, to_error(state.pos())))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1685,7 +1682,7 @@ where
|
|||
let state = state.advance(3);
|
||||
Ok((MadeProgress, (), state))
|
||||
} else {
|
||||
Err((NoProgress, to_error(state.pos()), state))
|
||||
Err((NoProgress, to_error(state.pos())))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1730,6 +1727,8 @@ macro_rules! zero_or_more {
|
|||
move |arena, state: State<'a>, min_indent: u32| {
|
||||
use bumpalo::collections::Vec;
|
||||
|
||||
let original_state = state.clone();
|
||||
|
||||
let start_bytes_len = state.bytes().len();
|
||||
|
||||
match $parser.parse(arena, state, min_indent) {
|
||||
|
@ -1740,16 +1739,17 @@ macro_rules! zero_or_more {
|
|||
buf.push(first_output);
|
||||
|
||||
loop {
|
||||
let old_state = state.clone();
|
||||
match $parser.parse(arena, state, min_indent) {
|
||||
Ok((_, next_output, next_state)) => {
|
||||
state = next_state;
|
||||
buf.push(next_output);
|
||||
}
|
||||
Err((fail_progress, fail, old_state)) => {
|
||||
Err((fail_progress, fail)) => {
|
||||
match fail_progress {
|
||||
MadeProgress => {
|
||||
// made progress on an element and then failed; that's an error
|
||||
return Err((MadeProgress, fail, old_state));
|
||||
return Err((MadeProgress, fail));
|
||||
}
|
||||
NoProgress => {
|
||||
// the next element failed with no progress
|
||||
|
@ -1762,16 +1762,16 @@ macro_rules! zero_or_more {
|
|||
}
|
||||
}
|
||||
}
|
||||
Err((fail_progress, fail, new_state)) => {
|
||||
Err((fail_progress, fail)) => {
|
||||
match fail_progress {
|
||||
MadeProgress => {
|
||||
// made progress on an element and then failed; that's an error
|
||||
Err((MadeProgress, fail, new_state))
|
||||
Err((MadeProgress, fail))
|
||||
}
|
||||
NoProgress => {
|
||||
// the first element failed (with no progress), but that's OK
|
||||
// because we only need to parse 0 elements
|
||||
Ok((NoProgress, Vec::new_in(arena), new_state))
|
||||
Ok((NoProgress, Vec::new_in(arena), original_state))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1794,15 +1794,16 @@ macro_rules! one_or_more {
|
|||
buf.push(first_output);
|
||||
|
||||
loop {
|
||||
let old_state = state.clone();
|
||||
match $parser.parse(arena, state, min_indent) {
|
||||
Ok((_, next_output, next_state)) => {
|
||||
state = next_state;
|
||||
buf.push(next_output);
|
||||
}
|
||||
Err((NoProgress, _, old_state)) => {
|
||||
Err((NoProgress, _)) => {
|
||||
return Ok((MadeProgress, buf, old_state));
|
||||
}
|
||||
Err((MadeProgress, fail, old_state)) => {
|
||||
Err((MadeProgress, fail)) => {
|
||||
return Err((MadeProgress, fail, old_state));
|
||||
}
|
||||
}
|
||||
|
@ -1828,19 +1829,22 @@ macro_rules! debug {
|
|||
#[macro_export]
|
||||
macro_rules! either {
|
||||
($p1:expr, $p2:expr) => {
|
||||
move |arena: &'a bumpalo::Bump, state: $crate::state::State<'a>, min_indent: u32| match $p1
|
||||
.parse(arena, state, min_indent)
|
||||
{
|
||||
Ok((progress, output, state)) => {
|
||||
Ok((progress, $crate::parser::Either::First(output), state))
|
||||
}
|
||||
Err((NoProgress, _, state)) => match $p2.parse(arena, state, min_indent) {
|
||||
move |arena: &'a bumpalo::Bump, state: $crate::state::State<'a>, min_indent: u32| {
|
||||
let original_state = state.clone();
|
||||
match $p1.parse(arena, state, min_indent) {
|
||||
Ok((progress, output, state)) => {
|
||||
Ok((progress, $crate::parser::Either::Second(output), state))
|
||||
Ok((progress, $crate::parser::Either::First(output), state))
|
||||
}
|
||||
Err((progress, fail, state)) => Err((progress, fail, state)),
|
||||
},
|
||||
Err((MadeProgress, fail, state)) => Err((MadeProgress, fail, state)),
|
||||
Err((NoProgress, _)) => {
|
||||
match $p2.parse(arena, original_state.clone(), min_indent) {
|
||||
Ok((progress, output, state)) => {
|
||||
Ok((progress, $crate::parser::Either::Second(output), state))
|
||||
}
|
||||
Err((progress, fail)) => Err((progress, fail)),
|
||||
}
|
||||
}
|
||||
Err((MadeProgress, fail)) => Err((MadeProgress, fail)),
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1902,12 +1906,10 @@ where
|
|||
P: Parser<'a, Val, Error>,
|
||||
Error: 'a,
|
||||
{
|
||||
move |arena: &'a Bump, state: State<'a>, min_indent: u32| {
|
||||
let old_state = state.clone();
|
||||
|
||||
match parser.parse(arena, state, min_indent) {
|
||||
Ok((_, a, s1)) => Ok((NoProgress, a, s1)),
|
||||
Err((_, f, _)) => Err((NoProgress, f, old_state)),
|
||||
}
|
||||
move |arena: &'a Bump, state: State<'a>, min_indent: u32| match parser
|
||||
.parse(arena, state, min_indent)
|
||||
{
|
||||
Ok((_, a, s1)) => Ok((NoProgress, a, s1)),
|
||||
Err((_, f)) => Err((NoProgress, f)),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue