Merge branch 'precompiled-legacy' into https-packages

This commit is contained in:
Richard Feldman 2022-11-24 04:25:54 -05:00
commit f5cb2d73a1
No known key found for this signature in database
GPG key ID: F1F21AA5B1D9E43B
96 changed files with 4063 additions and 1334 deletions

View file

@ -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)),
}
}