Un-macro collection_trailing_sep_e

This commit is contained in:
Jackson Wambolt 2024-04-15 22:18:10 -05:00
parent 1c916202e7
commit dd2c786eb9
No known key found for this signature in database
GPG key ID: 76F29A42FEE8811C
5 changed files with 63 additions and 58 deletions

View file

@ -10,11 +10,12 @@ use crate::blankspace::{
use crate::ident::{integer_ident, lowercase_ident, parse_ident, Accessor, Ident}; use crate::ident::{integer_ident, lowercase_ident, parse_ident, Accessor, Ident};
use crate::keyword; use crate::keyword;
use crate::parser::{ use crate::parser::{
self, and, backtrackable, between, byte, byte_indent, collection_inner, either, self, and, backtrackable, between, byte, byte_indent, collection_inner,
increment_min_indent, indented_seq, line_min_indent, loc, map, map_with_arena, optional, collection_trailing_sep_e, either, increment_min_indent, indented_seq, line_min_indent, loc,
reset_min_indent, sep_by1, sep_by1_e, set_min_indent, skip_first, skip_second, specialize_err, map, map_with_arena, optional, reset_min_indent, sep_by1, sep_by1_e, set_min_indent,
specialize_err_ref, then, two_bytes, zero_or_more, EClosure, EExpect, EExpr, EIf, EInParens, skip_first, skip_second, specialize_err, specialize_err_ref, then, two_bytes, zero_or_more,
EList, ENumber, EPattern, ERecord, EString, EType, EWhen, Either, ParseResult, Parser, EClosure, EExpect, EExpr, EIf, EInParens, EList, ENumber, EPattern, ERecord, 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;
@ -94,12 +95,12 @@ pub fn expr_help<'a>() -> impl Parser<'a, Expr<'a>, EExpr<'a>> {
fn loc_expr_in_parens_help<'a>() -> impl Parser<'a, Loc<Expr<'a>>, EInParens<'a>> { fn loc_expr_in_parens_help<'a>() -> impl Parser<'a, Loc<Expr<'a>>, EInParens<'a>> {
then( then(
loc(collection_trailing_sep_e!( loc(collection_trailing_sep_e(
byte(b'(', EInParens::Open), byte(b'(', EInParens::Open),
specialize_err_ref(EInParens::Expr, loc_expr(false)), specialize_err_ref(EInParens::Expr, loc_expr(false)),
byte(b',', EInParens::End), byte(b',', EInParens::End),
byte(b')', EInParens::End), byte(b')', EInParens::End),
Expr::SpaceBefore Expr::SpaceBefore,
)), )),
move |arena, state, _, loc_elements| { move |arena, state, _, loc_elements| {
let elements = loc_elements.value; let elements = loc_elements.value;
@ -2848,12 +2849,12 @@ fn ident_to_expr<'a>(arena: &'a Bump, src: Ident<'a>) -> Expr<'a> {
fn list_literal_help<'a>() -> impl Parser<'a, Expr<'a>, EList<'a>> { fn list_literal_help<'a>() -> impl Parser<'a, Expr<'a>, EList<'a>> {
map_with_arena( map_with_arena(
collection_trailing_sep_e!( collection_trailing_sep_e(
byte(b'[', EList::Open), byte(b'[', EList::Open),
specialize_err_ref(EList::Expr, loc_expr(false)), specialize_err_ref(EList::Expr, loc_expr(false)),
byte(b',', EList::End), byte(b',', EList::End),
byte(b']', EList::End), byte(b']', EList::End),
Expr::SpaceBefore Expr::SpaceBefore,
), ),
|arena, elements: Collection<'a, _>| { |arena, elements: Collection<'a, _>| {
let elements = elements.ptrify_items(arena); let elements = elements.ptrify_items(arena);

View file

@ -9,10 +9,10 @@ use crate::header::{
use crate::ident::{self, lowercase_ident, unqualified_ident, uppercase, UppercaseIdent}; use crate::ident::{self, lowercase_ident, unqualified_ident, uppercase, UppercaseIdent};
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, collection_trailing_sep_e, increment_min_indent, loc, map, optional,
skip_first, skip_second, specialize_err, two_bytes, zero_or_more, EExposes, EGenerates, reset_min_indent, skip_first, skip_second, specialize_err, two_bytes, zero_or_more, EExposes,
EGeneratesWith, EHeader, EImports, EPackages, EProvides, ERequires, ETypedIdent, Parser, EGenerates, EGeneratesWith, EHeader, EImports, EPackages, EProvides, ERequires, ETypedIdent,
SourceError, SpaceProblem, SyntaxError, Parser, 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};
@ -235,7 +235,7 @@ fn provides_to<'a>() -> impl Parser<'a, ProvidesTo<'a>, EProvides<'a>> {
EProvides::IndentProvides, EProvides::IndentProvides,
EProvides::IndentListStart EProvides::IndentListStart
), ),
entries: collection_trailing_sep_e!( entries: collection_trailing_sep_e(
byte(b'[', EProvides::ListStart), byte(b'[', EProvides::ListStart),
exposes_entry(EProvides::Identifier), exposes_entry(EProvides::Identifier),
byte(b',', EProvides::ListEnd), byte(b',', EProvides::ListEnd),
@ -266,7 +266,7 @@ fn provides_exposed<'a>() -> impl Parser<
EProvides::IndentProvides, EProvides::IndentProvides,
EProvides::IndentListStart EProvides::IndentListStart
), ),
item: collection_trailing_sep_e!( item: collection_trailing_sep_e(
byte(b'[', EProvides::ListStart), byte(b'[', EProvides::ListStart),
exposes_entry(EProvides::Identifier), exposes_entry(EProvides::Identifier),
byte(b',', EProvides::ListEnd), byte(b',', EProvides::ListEnd),
@ -291,12 +291,12 @@ fn provides_types<'a>(
// 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),
provides_type_entry(EProvides::Identifier), provides_type_entry(EProvides::Identifier),
byte(b',', EProvides::ListEnd), byte(b',', EProvides::ListEnd),
byte(b'}', EProvides::ListEnd), byte(b'}', EProvides::ListEnd),
Spaced::SpaceBefore Spaced::SpaceBefore,
), ),
) )
} }
@ -354,15 +354,15 @@ fn platform_requires<'a>() -> impl Parser<'a, PlatformRequires<'a>, ERequires<'a
#[inline(always)] #[inline(always)]
fn requires_rigids<'a>( fn requires_rigids<'a>(
) -> impl Parser<'a, Collection<'a, Loc<Spaced<'a, UppercaseIdent<'a>>>>, ERequires<'a>> { ) -> impl Parser<'a, Collection<'a, Loc<Spaced<'a, UppercaseIdent<'a>>>>, ERequires<'a>> {
collection_trailing_sep_e!( collection_trailing_sep_e(
byte(b'{', ERequires::ListStart), byte(b'{', ERequires::ListStart),
specialize_err( specialize_err(
|_, pos| ERequires::Rigid(pos), |_, pos| ERequires::Rigid(pos),
loc(map(ident::uppercase(), Spaced::Item)) loc(map(ident::uppercase(), Spaced::Item)),
), ),
byte(b',', ERequires::ListEnd), byte(b',', ERequires::ListEnd),
byte(b'}', ERequires::ListEnd), byte(b'}', ERequires::ListEnd),
Spaced::SpaceBefore Spaced::SpaceBefore,
) )
} }
@ -394,7 +394,7 @@ fn exposes_values<'a>() -> impl Parser<
EExposes::IndentExposes, EExposes::IndentExposes,
EExposes::IndentListStart EExposes::IndentListStart
), ),
item: collection_trailing_sep_e!( item: collection_trailing_sep_e(
byte(b'[', EExposes::ListStart), byte(b'[', EExposes::ListStart),
exposes_entry(EExposes::Identifier), exposes_entry(EExposes::Identifier),
byte(b',', EExposes::ListEnd), byte(b',', EExposes::ListEnd),
@ -445,7 +445,7 @@ fn exposes_modules<'a>() -> impl Parser<
EExposes::IndentExposes, EExposes::IndentExposes,
EExposes::IndentListStart EExposes::IndentListStart
), ),
item: collection_trailing_sep_e!( item: collection_trailing_sep_e(
byte(b'[', EExposes::ListStart), byte(b'[', EExposes::ListStart),
exposes_module(EExposes::Identifier), exposes_module(EExposes::Identifier),
byte(b',', EExposes::ListEnd), byte(b',', EExposes::ListEnd),
@ -482,7 +482,7 @@ fn packages<'a>() -> impl Parser<
EPackages::IndentPackages, EPackages::IndentPackages,
EPackages::IndentListStart EPackages::IndentListStart
), ),
item: collection_trailing_sep_e!( item: collection_trailing_sep_e(
byte(b'{', EPackages::ListStart), byte(b'{', EPackages::ListStart),
specialize_err(EPackages::PackageEntry, loc(package_entry())), specialize_err(EPackages::PackageEntry, loc(package_entry())),
byte(b',', EPackages::ListEnd), byte(b',', EPackages::ListEnd),
@ -519,7 +519,7 @@ fn generates_with<'a>() -> impl Parser<
EGeneratesWith::IndentWith, EGeneratesWith::IndentWith,
EGeneratesWith::IndentListStart EGeneratesWith::IndentListStart
), ),
item: collection_trailing_sep_e!( item: collection_trailing_sep_e(
byte(b'[', EGeneratesWith::ListStart), byte(b'[', EGeneratesWith::ListStart),
exposes_entry(EGeneratesWith::Identifier), exposes_entry(EGeneratesWith::Identifier),
byte(b',', EGeneratesWith::ListEnd), byte(b',', EGeneratesWith::ListEnd),
@ -542,7 +542,7 @@ fn imports<'a>() -> impl Parser<
EImports::IndentImports, EImports::IndentImports,
EImports::IndentListStart EImports::IndentListStart
), ),
item: collection_trailing_sep_e!( item: collection_trailing_sep_e(
byte(b'[', EImports::ListStart), byte(b'[', EImports::ListStart),
loc(imports_entry()), loc(imports_entry()),
byte(b',', EImports::ListEnd), byte(b',', EImports::ListEnd),
@ -623,7 +623,7 @@ fn imports_entry<'a>() -> impl Parser<'a, Spaced<'a, ImportsEntry<'a>>, EImports
// e.g. `.{ Task, after}` // e.g. `.{ Task, after}`
optional(skip_first( optional(skip_first(
byte(b'.', EImports::ExposingDot), byte(b'.', EImports::ExposingDot),
collection_trailing_sep_e!( collection_trailing_sep_e(
byte(b'{', EImports::SetStart), byte(b'{', EImports::SetStart),
exposes_entry(EImports::Identifier), exposes_entry(EImports::Identifier),
byte(b',', EImports::SetEnd), byte(b',', EImports::SetEnd),

View file

@ -1499,19 +1499,22 @@ pub fn collection_inner<'a, Elem: 'a + crate::ast::Spaceable<'a> + Clone, E: 'a
) )
} }
#[macro_export] pub fn collection_trailing_sep_e<
macro_rules! collection_trailing_sep_e { 'a,
($opening_brace:expr, $elem:expr, $delimiter:expr, $closing_brace:expr, $space_before:expr) => { Elem: 'a + crate::ast::Spaceable<'a> + Clone,
$crate::parser::between( E: 'a + SpaceProblem,
$opening_brace, >(
$crate::parser::reset_min_indent($crate::parser::collection_inner( opening_brace: impl Parser<'a, (), E>,
$elem, elem: impl Parser<'a, Loc<Elem>, E> + 'a,
$delimiter, delimiter: impl Parser<'a, (), E>,
$space_before, closing_brace: impl Parser<'a, (), E>,
)), space_before: impl Fn(&'a Elem, &'a [crate::ast::CommentOrNewline<'a>]) -> Elem,
$closing_brace, ) -> impl Parser<'a, crate::ast::Collection<'a, Loc<Elem>>, E> {
) between(
}; opening_brace,
reset_min_indent(collection_inner(elem, delimiter, space_before)),
closing_brace,
)
} }
/// Creates a parser that always succeeds with the given argument as output. /// Creates a parser that always succeeds with the given argument as output.

View file

@ -3,9 +3,9 @@ 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::{ use crate::parser::{
self, backtrackable, byte, fail_when, loc, map, map_with_arena, optional, skip_first, self, backtrackable, byte, collection_trailing_sep_e, fail_when, loc, map, map_with_arena,
specialize_err, specialize_err_ref, then, three_bytes, two_bytes, zero_or_more, EPattern, optional, skip_first, specialize_err, specialize_err_ref, then, three_bytes, two_bytes,
PInParens, PList, PRecord, Parser, zero_or_more, EPattern, PInParens, PList, PRecord, Parser,
}; };
use crate::parser::{either, Progress::*}; use crate::parser::{either, Progress::*};
use crate::state::State; use crate::state::State;
@ -200,12 +200,12 @@ pub fn loc_implements_parser<'a>() -> impl Parser<'a, Loc<Implements<'a>>, EPatt
fn loc_pattern_in_parens_help<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, PInParens<'a>> { fn loc_pattern_in_parens_help<'a>() -> impl Parser<'a, Loc<Pattern<'a>>, PInParens<'a>> {
then( then(
loc(collection_trailing_sep_e!( loc(collection_trailing_sep_e(
byte(b'(', PInParens::Open), byte(b'(', PInParens::Open),
specialize_err_ref(PInParens::Pattern, loc_pattern_help()), specialize_err_ref(PInParens::Pattern, loc_pattern_help()),
byte(b',', PInParens::End), byte(b',', PInParens::End),
byte(b')', PInParens::End), byte(b')', PInParens::End),
Pattern::SpaceBefore Pattern::SpaceBefore,
)), )),
move |_arena, state, _, loc_elements| { move |_arena, state, _, loc_elements| {
let elements = loc_elements.value; let elements = loc_elements.value;
@ -271,12 +271,12 @@ fn string_like_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, EPattern<'a>>
fn list_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, PList<'a>> { fn list_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, PList<'a>> {
map( map(
collection_trailing_sep_e!( collection_trailing_sep_e(
byte(b'[', PList::Open), byte(b'[', PList::Open),
list_element_pattern(), list_element_pattern(),
byte(b',', PList::End), byte(b',', PList::End),
byte(b']', PList::End), byte(b']', PList::End),
Pattern::SpaceBefore Pattern::SpaceBefore,
), ),
Pattern::List, Pattern::List,
) )
@ -518,12 +518,12 @@ fn lowercase_ident_pattern<'a>() -> impl Parser<'a, &'a str, EPattern<'a>> {
#[inline(always)] #[inline(always)]
fn record_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, PRecord<'a>> { fn record_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, PRecord<'a>> {
map( map(
collection_trailing_sep_e!( collection_trailing_sep_e(
byte(b'{', PRecord::Open), byte(b'{', PRecord::Open),
record_pattern_field(), record_pattern_field(),
byte(b',', PRecord::End), byte(b',', PRecord::End),
byte(b'}', PRecord::End), byte(b'}', PRecord::End),
Pattern::SpaceBefore Pattern::SpaceBefore,
), ),
Pattern::RecordDestructure, Pattern::RecordDestructure,
) )

View file

@ -9,8 +9,9 @@ use crate::expr::{record_field, FoundApplyValue};
use crate::ident::{lowercase_ident, lowercase_ident_keyword_e}; 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, either, increment_min_indent, loc, map, map_with_arena, absolute_column_min_indent, and, collection_trailing_sep_e, either, increment_min_indent, loc,
skip_first, skip_second, succeed, then, zero_or_more, ERecord, ETypeAbilityImpl, map, map_with_arena, skip_first, 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,
@ -39,12 +40,12 @@ fn tag_union_type<'a>(
stop_at_surface_has: bool, stop_at_surface_has: bool,
) -> impl Parser<'a, TypeAnnotation<'a>, ETypeTagUnion<'a>> { ) -> impl Parser<'a, TypeAnnotation<'a>, ETypeTagUnion<'a>> {
move |arena, state, min_indent| { move |arena, state, min_indent| {
let (_, tags, state) = collection_trailing_sep_e!( let (_, tags, state) = collection_trailing_sep_e(
byte(b'[', ETypeTagUnion::Open), byte(b'[', ETypeTagUnion::Open),
loc(tag_type(false)), loc(tag_type(false)),
byte(b',', ETypeTagUnion::End), byte(b',', ETypeTagUnion::End),
byte(b']', ETypeTagUnion::End), byte(b']', ETypeTagUnion::End),
Tag::SpaceBefore Tag::SpaceBefore,
) )
.parse(arena, state, min_indent)?; .parse(arena, state, min_indent)?;
@ -243,12 +244,12 @@ fn loc_type_in_parens<'a>(
) -> impl Parser<'a, Loc<TypeAnnotation<'a>>, ETypeInParens<'a>> { ) -> impl Parser<'a, Loc<TypeAnnotation<'a>>, ETypeInParens<'a>> {
then( then(
loc(and( loc(and(
collection_trailing_sep_e!( collection_trailing_sep_e(
byte(b'(', ETypeInParens::Open), byte(b'(', ETypeInParens::Open),
specialize_err_ref(ETypeInParens::Type, expression(true, false)), specialize_err_ref(ETypeInParens::Type, expression(true, false)),
byte(b',', ETypeInParens::End), byte(b',', ETypeInParens::End),
byte(b')', ETypeInParens::End), byte(b')', ETypeInParens::End),
TypeAnnotation::SpaceBefore TypeAnnotation::SpaceBefore,
), ),
optional(allocated(specialize_err_ref( optional(allocated(specialize_err_ref(
ETypeInParens::Type, ETypeInParens::Type,
@ -382,7 +383,7 @@ fn record_type<'a>(
stop_at_surface_has: bool, stop_at_surface_has: bool,
) -> impl Parser<'a, TypeAnnotation<'a>, ETypeRecord<'a>> { ) -> impl Parser<'a, TypeAnnotation<'a>, ETypeRecord<'a>> {
record!(TypeAnnotation::Record { record!(TypeAnnotation::Record {
fields: collection_trailing_sep_e!( fields: collection_trailing_sep_e(
byte(b'{', ETypeRecord::Open), byte(b'{', ETypeRecord::Open),
loc(record_type_field()), loc(record_type_field()),
byte(b',', ETypeRecord::End), byte(b',', ETypeRecord::End),
@ -531,12 +532,12 @@ pub fn implements_abilities<'a>() -> impl Parser<'a, Loc<ImplementsAbilities<'a>
// Parse "Hash"; this may be qualified from another module like "Hash.Hash" // Parse "Hash"; this may be qualified from another module like "Hash.Hash"
space0_before_e( space0_before_e(
loc(map( loc(map(
collection_trailing_sep_e!( collection_trailing_sep_e(
byte(b'[', EType::TStart), byte(b'[', EType::TStart),
loc(parse_implements_ability()), loc(parse_implements_ability()),
byte(b',', EType::TEnd), byte(b',', EType::TEnd),
byte(b']', EType::TEnd), byte(b']', EType::TEnd),
ImplementsAbility::SpaceBefore ImplementsAbility::SpaceBefore,
), ),
ImplementsAbilities::Implements, ImplementsAbilities::Implements,
)), )),
@ -552,7 +553,7 @@ fn parse_implements_ability<'a>() -> impl Parser<'a, ImplementsAbility<'a>, ETyp
loc(map( loc(map(
specialize_err( specialize_err(
EType::TAbilityImpl, EType::TAbilityImpl,
collection_trailing_sep_e!( collection_trailing_sep_e(
byte(b'{', ETypeAbilityImpl::Open), byte(b'{', ETypeAbilityImpl::Open),
specialize_err(|e: ERecord<'_>, _| e.into(), loc(ability_impl_field())), specialize_err(|e: ERecord<'_>, _| e.into(), loc(ability_impl_field())),
byte(b',', ETypeAbilityImpl::End), byte(b',', ETypeAbilityImpl::End),