Un-macro zero_or_more

This commit is contained in:
Jackson Wambolt 2024-04-15 20:39:29 -05:00
parent a9724dda5e
commit f88e46fc32
No known key found for this signature in database
GPG key ID: 76F29A42FEE8811C
5 changed files with 70 additions and 70 deletions

View file

@ -13,8 +13,8 @@ use crate::parser::{
self, and, backtrackable, between, byte, byte_indent, increment_min_indent, indented_seq, self, and, backtrackable, between, byte, byte_indent, increment_min_indent, indented_seq,
line_min_indent, loc, map, map_with_arena, optional, reset_min_indent, sep_by1, sep_by1_e, line_min_indent, loc, map, map_with_arena, optional, reset_min_indent, sep_by1, sep_by1_e,
set_min_indent, skip_first, skip_second, specialize_err, specialize_err_ref, then, two_bytes, set_min_indent, skip_first, skip_second, specialize_err, specialize_err_ref, then, two_bytes,
EClosure, EExpect, EExpr, EIf, EInParens, EList, ENumber, EPattern, ERecord, EString, EType, zero_or_more, EClosure, EExpect, EExpr, EIf, EInParens, EList, ENumber, EPattern, ERecord,
EWhen, Either, ParseResult, Parser, EString, EType, EWhen, Either, ParseResult, Parser,
}; };
use crate::pattern::{closure_param, loc_implements_parser}; use crate::pattern::{closure_param, loc_implements_parser};
use crate::state::State; use crate::state::State;
@ -158,15 +158,15 @@ fn loc_expr_in_parens_etc_help<'a>() -> impl Parser<'a, Loc<Expr<'a>>, EExpr<'a>
} }
fn record_field_access_chain<'a>() -> impl Parser<'a, Vec<'a, Accessor<'a>>, EExpr<'a>> { fn record_field_access_chain<'a>() -> impl Parser<'a, Vec<'a, Accessor<'a>>, EExpr<'a>> {
zero_or_more!(skip_first( zero_or_more(skip_first(
byte(b'.', EExpr::Access), byte(b'.', EExpr::Access),
specialize_err( specialize_err(
|_, pos| EExpr::Access(pos), |_, pos| EExpr::Access(pos),
one_of!( one_of!(
map(lowercase_ident(), Accessor::RecordField), map(lowercase_ident(), Accessor::RecordField),
map(integer_ident(), Accessor::TupleIndex), map(integer_ident(), Accessor::TupleIndex),
) ),
) ),
)) ))
} }

View file

@ -10,9 +10,9 @@ use crate::ident::{self, lowercase_ident, unqualified_ident, uppercase, Uppercas
use crate::parser::Progress::{self, *}; use crate::parser::Progress::{self, *};
use crate::parser::{ use crate::parser::{
and, backtrackable, byte, increment_min_indent, loc, map, optional, reset_min_indent, and, backtrackable, byte, increment_min_indent, loc, map, optional, reset_min_indent,
skip_first, skip_second, specialize_err, two_bytes, EExposes, EGenerates, EGeneratesWith, skip_first, skip_second, specialize_err, two_bytes, zero_or_more, EExposes, EGenerates,
EHeader, EImports, EPackages, EProvides, ERequires, ETypedIdent, Parser, SourceError, EGeneratesWith, EHeader, EImports, EPackages, EProvides, ERequires, ETypedIdent, Parser,
SpaceProblem, SyntaxError, SourceError, SpaceProblem, SyntaxError,
}; };
use crate::state::State; use crate::state::State;
use crate::string_literal::{self, parse_str_literal}; use crate::string_literal::{self, parse_str_literal};
@ -284,12 +284,12 @@ fn provides_types<'a>(
// to be the design forever. Someday it will hopefully work like Elm, // to be the design forever. Someday it will hopefully work like Elm,
// where platform authors can provide functions like Browser.sandbox which // where platform authors can provide functions like Browser.sandbox which
// present an API based on ordinary-looking type variables. // present an API based on ordinary-looking type variables.
zero_or_more!(byte( zero_or_more(byte(
b' ', b' ',
// HACK: If this errors, EProvides::Provides is not an accurate reflection // HACK: If this errors, EProvides::Provides is not an accurate reflection
// of what went wrong. However, this is both skipped and zero_or_more, // of what went wrong. However, this is both skipped and zero_or_more,
// so this error should never be visible to anyone in practice! // so this error should never be visible to anyone in practice!
EProvides::Provides EProvides::Provides,
)), )),
collection_trailing_sep_e!( collection_trailing_sep_e!(
byte(b'{', EProvides::ListStart), byte(b'{', EProvides::ListStart),

View file

@ -2216,17 +2216,15 @@ pub fn map<'a, Output, MappedOutput, E: 'a>(
/// Applies the parser as many times as possible. /// Applies the parser as many times as possible.
/// This parser will only fail if the given parser makes partial progress. /// This parser will only fail if the given parser makes partial progress.
#[macro_export] pub fn zero_or_more<'a, Output, E: 'a>(
macro_rules! zero_or_more { parser: impl Parser<'a, Output, E>,
($parser:expr) => { ) -> impl Parser<'a, bumpalo::collections::Vec<'a, Output>, E> {
move |arena, state: State<'a>, min_indent: u32| { move |arena, state: State<'a>, min_indent: u32| {
use bumpalo::collections::Vec;
let original_state = state.clone(); let original_state = state.clone();
let start_bytes_len = state.bytes().len(); let start_bytes_len = state.bytes().len();
match $parser.parse(arena, state, min_indent) { match parser.parse(arena, state, min_indent) {
Ok((_, first_output, next_state)) => { Ok((_, first_output, next_state)) => {
let mut state = next_state; let mut state = next_state;
let mut buf = Vec::with_capacity_in(1, arena); let mut buf = Vec::with_capacity_in(1, arena);
@ -2235,7 +2233,7 @@ macro_rules! zero_or_more {
loop { loop {
let old_state = state.clone(); let old_state = state.clone();
match $parser.parse(arena, state, min_indent) { match parser.parse(arena, state, min_indent) {
Ok((_, next_output, next_state)) => { Ok((_, next_output, next_state)) => {
state = next_state; state = next_state;
buf.push(next_output); buf.push(next_output);
@ -2249,7 +2247,10 @@ macro_rules! zero_or_more {
NoProgress => { NoProgress => {
// the next element failed with no progress // the next element failed with no progress
// report whether we made progress before // report whether we made progress before
let progress = Progress::from_lengths(start_bytes_len, old_state.bytes().len()); let progress = Progress::from_lengths(
start_bytes_len,
old_state.bytes().len(),
);
return Ok((progress, buf, old_state)); return Ok((progress, buf, old_state));
} }
} }
@ -2272,7 +2273,6 @@ macro_rules! zero_or_more {
} }
} }
} }
};
} }
/// Creates a parser that matches one or more times. /// Creates a parser that matches one or more times.
@ -2285,7 +2285,7 @@ macro_rules! zero_or_more {
/// # use roc_parse::state::State; /// # use roc_parse::state::State;
/// # use crate::roc_parse::parser::{Parser, Progress, Progress::{MadeProgress, NoProgress}, word}; /// # use crate::roc_parse::parser::{Parser, Progress, Progress::{MadeProgress, NoProgress}, word};
/// # use roc_region::all::Position; /// # use roc_region::all::Position;
/// # use roc_parse::one_or_more; /// # use roc_parse::one_or_more!;
/// # use bumpalo::Bump; /// # use bumpalo::Bump;
/// # #[derive(Debug, PartialEq)] /// # #[derive(Debug, PartialEq)]
/// # enum Problem { /// # enum Problem {
@ -2293,7 +2293,7 @@ macro_rules! zero_or_more {
/// # } /// # }
/// # let arena = Bump::new(); /// # let arena = Bump::new();
/// # fn foo<'a>(arena: &'a Bump) { /// # fn foo<'a>(arena: &'a Bump) {
/// let parser = one_or_more!( /// let parser = one_or_more(
/// word("hello, ", Problem::NotFound), /// word("hello, ", Problem::NotFound),
/// Problem::NotFound /// Problem::NotFound
/// ); /// );

View file

@ -2,11 +2,11 @@ use crate::ast::{Implements, Pattern, PatternAs, Spaceable};
use crate::blankspace::{space0_e, spaces, spaces_before}; use crate::blankspace::{space0_e, spaces, spaces_before};
use crate::ident::{lowercase_ident, parse_ident, Accessor, Ident}; use crate::ident::{lowercase_ident, parse_ident, Accessor, Ident};
use crate::keyword; use crate::keyword;
use crate::parser::Progress::{self, *}; use crate::parser::Progress::*;
use crate::parser::{ use crate::parser::{
self, backtrackable, byte, fail_when, loc, map, map_with_arena, optional, skip_first, self, backtrackable, byte, fail_when, loc, map, map_with_arena, optional, skip_first,
specialize_err, specialize_err_ref, then, three_bytes, two_bytes, EPattern, PInParens, PList, specialize_err, specialize_err_ref, then, three_bytes, two_bytes, zero_or_more, EPattern,
PRecord, Parser, PInParens, PList, PRecord, Parser,
}; };
use crate::state::State; use crate::state::State;
use crate::string_literal::StrLikeLiteral; use crate::string_literal::StrLikeLiteral;
@ -125,13 +125,13 @@ fn pattern_as<'a>() -> impl Parser<'a, PatternAs<'a>, EPattern<'a>> {
} }
fn loc_tag_pattern_args_help<'a>() -> impl Parser<'a, Vec<'a, Loc<Pattern<'a>>>, EPattern<'a>> { fn loc_tag_pattern_args_help<'a>() -> impl Parser<'a, Vec<'a, Loc<Pattern<'a>>>, EPattern<'a>> {
zero_or_more!(loc_tag_pattern_arg(false)) zero_or_more(loc_tag_pattern_arg(false))
} }
/// Like `loc_tag_pattern_args_help`, but stops if a "implements" keyword is seen (indicating an ability). /// Like `loc_tag_pattern_args_help`, but stops if a "implements" keyword is seen (indicating an ability).
fn loc_type_def_tag_pattern_args_help<'a>( fn loc_type_def_tag_pattern_args_help<'a>(
) -> impl Parser<'a, Vec<'a, Loc<Pattern<'a>>>, EPattern<'a>> { ) -> impl Parser<'a, Vec<'a, Loc<Pattern<'a>>>, EPattern<'a>> {
zero_or_more!(loc_tag_pattern_arg(true)) zero_or_more(loc_tag_pattern_arg(true))
} }
fn loc_tag_pattern_arg<'a>( fn loc_tag_pattern_arg<'a>(

View file

@ -10,12 +10,12 @@ use crate::ident::{lowercase_ident, lowercase_ident_keyword_e};
use crate::keyword; use crate::keyword;
use crate::parser::{ use crate::parser::{
absolute_column_min_indent, and, increment_min_indent, loc, map, map_with_arena, skip_first, absolute_column_min_indent, and, increment_min_indent, loc, map, map_with_arena, skip_first,
skip_second, succeed, then, ERecord, ETypeAbilityImpl, skip_second, succeed, then, zero_or_more, ERecord, ETypeAbilityImpl,
}; };
use crate::parser::{ use crate::parser::{
allocated, backtrackable, byte, fail, optional, specialize_err, specialize_err_ref, two_bytes, allocated, backtrackable, byte, fail, optional, specialize_err, specialize_err_ref, two_bytes,
word, EType, ETypeApply, ETypeInParens, ETypeInlineAlias, ETypeRecord, ETypeTagUnion, Parser, word, EType, ETypeApply, ETypeInParens, ETypeInlineAlias, ETypeRecord, ETypeTagUnion, Parser,
Progress::{self, *}, Progress::*,
}; };
use crate::state::State; use crate::state::State;
use bumpalo::collections::vec::Vec; use bumpalo::collections::vec::Vec;
@ -426,7 +426,7 @@ fn applied_type<'a>(stop_at_surface_has: bool) -> impl Parser<'a, TypeAnnotation
fn loc_applied_args_e<'a>( fn loc_applied_args_e<'a>(
stop_at_surface_has: bool, stop_at_surface_has: bool,
) -> impl Parser<'a, Vec<'a, Loc<TypeAnnotation<'a>>>, EType<'a>> { ) -> impl Parser<'a, Vec<'a, Loc<TypeAnnotation<'a>>>, EType<'a>> {
zero_or_more!(loc_applied_arg(stop_at_surface_has)) zero_or_more(loc_applied_arg(stop_at_surface_has))
} }
// Hash & Eq & ... // Hash & Eq & ...
@ -438,13 +438,13 @@ fn ability_chain<'a>() -> impl Parser<'a, Vec<'a, Loc<TypeAnnotation<'a>>>, ETyp
EType::TIndentStart, EType::TIndentStart,
EType::TIndentEnd, EType::TIndentEnd,
), ),
zero_or_more!(skip_first( zero_or_more(skip_first(
byte(b'&', EType::TImplementsClause), byte(b'&', EType::TImplementsClause),
space0_before_optional_after( space0_before_optional_after(
specialize_err(EType::TApply, loc(concrete_type())), specialize_err(EType::TApply, loc(concrete_type())),
EType::TIndentStart, EType::TIndentStart,
EType::TIndentEnd, EType::TIndentEnd,
) ),
)), )),
), ),
|(first_ability, mut other_abilities): ( |(first_ability, mut other_abilities): (
@ -506,9 +506,9 @@ fn implements_clause_chain<'a>(
// Parse the first clause (there must be one), then the rest // Parse the first clause (there must be one), then the rest
let (_, first_clause, state) = implements_clause().parse(arena, state, min_indent)?; let (_, first_clause, state) = implements_clause().parse(arena, state, min_indent)?;
let (_, mut clauses, state) = zero_or_more!(skip_first( let (_, mut clauses, state) = zero_or_more(skip_first(
byte(b',', EType::TImplementsClause), byte(b',', EType::TImplementsClause),
implements_clause() implements_clause(),
)) ))
.parse(arena, state, min_indent)?; .parse(arena, state, min_indent)?;
@ -585,7 +585,7 @@ fn expression<'a>(
.parse(arena, state, min_indent)?; .parse(arena, state, min_indent)?;
let result = and( let result = and(
zero_or_more!(skip_first( zero_or_more(skip_first(
byte(b',', EType::TFunctionArgument), byte(b',', EType::TFunctionArgument),
one_of![ one_of![
space0_around_ee( space0_around_ee(
@ -594,7 +594,7 @@ fn expression<'a>(
EType::TIndentEnd EType::TIndentEnd
), ),
fail(EType::TFunctionArgument) fail(EType::TFunctionArgument)
] ],
)) ))
.trace("type_annotation:expression:rest_args"), .trace("type_annotation:expression:rest_args"),
skip_second( skip_second(