From 451b2c0ded6b177dda0b81284011010682213ddc Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Thu, 24 Nov 2022 07:34:53 -0800 Subject: [PATCH] Refactor collections --- crates/compiler/parse/src/expr.rs | 2 - crates/compiler/parse/src/ident.rs | 16 +++++ crates/compiler/parse/src/module.rs | 9 --- crates/compiler/parse/src/parser.rs | 66 +++++++++++--------- crates/compiler/parse/src/pattern.rs | 3 - crates/compiler/parse/src/type_annotation.rs | 9 +-- crates/reporting/src/error/parse.rs | 2 +- 7 files changed, 54 insertions(+), 53 deletions(-) diff --git a/crates/compiler/parse/src/expr.rs b/crates/compiler/parse/src/expr.rs index 08274a5b17..ec09ffc84e 100644 --- a/crates/compiler/parse/src/expr.rs +++ b/crates/compiler/parse/src/expr.rs @@ -87,7 +87,6 @@ fn loc_expr_in_parens_help<'a>() -> impl Parser<'a, Loc>, EInParens<'a> specialize_ref(EInParens::Expr, loc_expr_no_multi_backpassing()), word1(b',', EInParens::End), word1(b')', EInParens::End), - EInParens::Open, EInParens::IndentEnd, Expr::SpaceBefore )), @@ -2467,7 +2466,6 @@ fn list_literal_help<'a>() -> impl Parser<'a, Expr<'a>, EList<'a>> { specialize_ref(EList::Expr, loc_expr_no_multi_backpassing()), word1(b',', EList::End), word1(b']', EList::End), - EList::Open, EList::IndentEnd, Expr::SpaceBefore ), diff --git a/crates/compiler/parse/src/ident.rs b/crates/compiler/parse/src/ident.rs index ea79756d7a..0a4b772218 100644 --- a/crates/compiler/parse/src/ident.rs +++ b/crates/compiler/parse/src/ident.rs @@ -111,6 +111,22 @@ pub fn integer_ident<'a>() -> impl Parser<'a, &'a str, ()> { } } +/// Like `lowercase_ident`, but returns an error with MadeProgress if the +/// identifier is a keyword. +pub fn lowercase_ident_keyword_e<'a>() -> impl Parser<'a, &'a str, ()> { + move |_, state: State<'a>, _min_indent: u32| match chomp_lowercase_part(state.bytes()) { + Err(progress) => Err((progress, ())), + Ok(ident) => { + if crate::keyword::KEYWORDS.iter().any(|kw| &ident == kw) { + Err((MadeProgress, ())) + } else { + let width = ident.len(); + Ok((MadeProgress, ident, state.advance(width))) + } + } + } +} + pub fn tag_name<'a>() -> impl Parser<'a, &'a str, ()> { move |arena, state: State<'a>, min_indent: u32| { uppercase_ident().parse(arena, state, min_indent) diff --git a/crates/compiler/parse/src/module.rs b/crates/compiler/parse/src/module.rs index 5ca959cf00..82c37451fe 100644 --- a/crates/compiler/parse/src/module.rs +++ b/crates/compiler/parse/src/module.rs @@ -427,7 +427,6 @@ fn provides_without_to<'a>() -> impl Parser< exposes_entry(EProvides::Identifier), word1(b',', EProvides::ListEnd), word1(b']', EProvides::ListEnd), - EProvides::Open, EProvides::IndentListEnd, Spaced::SpaceBefore ), @@ -457,7 +456,6 @@ fn provides_types<'a>( provides_type_entry(EProvides::Identifier), word1(b',', EProvides::ListEnd), word1(b'}', EProvides::ListEnd), - EProvides::Open, EProvides::IndentListEnd, Spaced::SpaceBefore ) @@ -534,7 +532,6 @@ fn requires_rigids<'a>( ), word1(b',', ERequires::ListEnd), word1(b'}', ERequires::ListEnd), - ERequires::Open, ERequires::IndentListEnd, Spaced::SpaceBefore ) @@ -576,7 +573,6 @@ fn exposes_values<'a>() -> impl Parser< exposes_entry(EExposes::Identifier), word1(b',', EExposes::ListEnd), word1(b']', EExposes::ListEnd), - EExposes::Open, EExposes::IndentListEnd, Spaced::SpaceBefore ) @@ -622,7 +618,6 @@ fn exposes_modules<'a>() -> impl Parser< exposes_module(EExposes::Identifier), word1(b',', EExposes::ListEnd), word1(b']', EExposes::ListEnd), - EExposes::Open, EExposes::IndentListEnd, Spaced::SpaceBefore ) @@ -665,7 +660,6 @@ fn packages<'a>() -> impl Parser<'a, Packages<'a>, EPackages<'a>> { specialize(EPackages::PackageEntry, loc!(package_entry())), word1(b',', EPackages::ListEnd), word1(b'}', EPackages::ListEnd), - EPackages::Open, EPackages::IndentListEnd, Spaced::SpaceBefore ) @@ -724,7 +718,6 @@ fn generates_with<'a>() -> impl Parser< exposes_entry(EGeneratesWith::Identifier), word1(b',', EGeneratesWith::ListEnd), word1(b']', EGeneratesWith::ListEnd), - EGeneratesWith::Open, EGeneratesWith::IndentListEnd, Spaced::SpaceBefore ) @@ -752,7 +745,6 @@ fn imports<'a>() -> impl Parser< loc!(imports_entry()), word1(b',', EImports::ListEnd), word1(b']', EImports::ListEnd), - EImports::Open, EImports::IndentListEnd, Spaced::SpaceBefore ) @@ -833,7 +825,6 @@ fn imports_entry<'a>() -> impl Parser<'a, Spaced<'a, ImportsEntry<'a>>, EImports exposes_entry(EImports::Identifier), word1(b',', EImports::SetEnd), word1(b'}', EImports::SetEnd), - EImports::Open, EImports::IndentSetEnd, Spaced::SpaceBefore ) diff --git a/crates/compiler/parse/src/parser.rs b/crates/compiler/parse/src/parser.rs index a13c26848c..e55ec937d5 100644 --- a/crates/compiler/parse/src/parser.rs +++ b/crates/compiler/parse/src/parser.rs @@ -1330,33 +1330,38 @@ macro_rules! collection { #[macro_export] macro_rules! collection_trailing_sep_e { - ($opening_brace:expr, $elem:expr, $delimiter:expr, $closing_brace:expr, $open_problem:expr, $indent_problem:expr, $space_before:expr) => { - skip_first!( - $opening_brace, - |arena, state, min_indent| { - let (_, spaces, state) = space0_e($indent_problem) - .parse(arena, state, min_indent)?; - - let (_, (mut parsed_elems, mut final_comments), state) = - and!( - $crate::parser::trailing_sep_by0( - $delimiter, - $crate::blankspace::space0_before_optional_after( - $elem, - $indent_problem, - $indent_problem - ) - ), - $crate::parser::reset_min_indent($crate::blankspace::space0_e($indent_problem)) - ).parse(arena, state, min_indent)?; - - let (_,_, state) = - if parsed_elems.is_empty() { - one_of_with_error![$open_problem; $closing_brace].parse(arena, state, min_indent)? - } else { - $closing_brace.parse(arena, state, min_indent)? - }; - + ($opening_brace:expr, $elem:expr, $delimiter:expr, $closing_brace:expr, $indent_problem:expr, $space_before:expr) => { + map_with_arena!( + skip_first!( + $opening_brace, + and!( + and!( + space0_e($indent_problem), + $crate::parser::trailing_sep_by0( + $delimiter, + $crate::blankspace::space0_before_optional_after( + $elem, + $indent_problem, + $indent_problem + ) + ) + ), + skip_second!( + $crate::parser::reset_min_indent($crate::blankspace::space0_e( + $indent_problem + )), + $closing_brace + ) + ) + ), + |arena: &'a bumpalo::Bump, + ((spaces, mut parsed_elems), mut final_comments): ( + ( + &'a [$crate::ast::CommentOrNewline<'a>], + bumpalo::collections::vec::Vec<'a, Loc<_>> + ), + &'a [$crate::ast::CommentOrNewline<'a>] + )| { if !spaces.is_empty() { if let Some(first) = parsed_elems.first_mut() { first.value = $space_before(arena.alloc(first.value), spaces) @@ -1366,12 +1371,11 @@ macro_rules! collection_trailing_sep_e { } } - let collection = $crate::ast::Collection::with_items_and_comments( + $crate::ast::Collection::with_items_and_comments( arena, parsed_elems.into_bump_slice(), - final_comments); - - Ok((MadeProgress, collection, state)) + final_comments, + ) } ) }; diff --git a/crates/compiler/parse/src/pattern.rs b/crates/compiler/parse/src/pattern.rs index bf9db278f7..7366666cfc 100644 --- a/crates/compiler/parse/src/pattern.rs +++ b/crates/compiler/parse/src/pattern.rs @@ -135,7 +135,6 @@ fn loc_pattern_in_parens_help<'a>() -> impl Parser<'a, Loc>, PInPare specialize_ref(PInParens::Pattern, loc_pattern_help()), word1(b',', PInParens::End), word1(b')', PInParens::End), - PInParens::Open, PInParens::IndentOpen, Pattern::SpaceBefore )), @@ -209,7 +208,6 @@ fn list_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, PList<'a>> { list_element_pattern(), word1(b',', PList::End), word1(b']', PList::End), - PList::Open, PList::IndentEnd, Pattern::SpaceBefore ), @@ -380,7 +378,6 @@ fn record_pattern_help<'a>() -> impl Parser<'a, Pattern<'a>, PRecord<'a>> { record_pattern_field(), word1(b',', PRecord::End), word1(b'}', PRecord::End), - PRecord::Open, PRecord::IndentEnd, Pattern::SpaceBefore ), diff --git a/crates/compiler/parse/src/type_annotation.rs b/crates/compiler/parse/src/type_annotation.rs index e1f92e1b63..a965c7677f 100644 --- a/crates/compiler/parse/src/type_annotation.rs +++ b/crates/compiler/parse/src/type_annotation.rs @@ -6,7 +6,7 @@ use crate::blankspace::{ space0_around_ee, space0_before_e, space0_before_optional_after, space0_e, }; use crate::expr::record_value_field; -use crate::ident::lowercase_ident; +use crate::ident::{lowercase_ident, lowercase_ident_keyword_e}; use crate::keyword; use crate::parser::{ absolute_column_min_indent, increment_min_indent, then, ERecord, ETypeAbilityImpl, @@ -43,7 +43,6 @@ fn tag_union_type<'a>( loc!(tag_type(false)), word1(b',', ETypeTagUnion::End), word1(b']', ETypeTagUnion::End), - ETypeTagUnion::Open, ETypeTagUnion::IndentEnd, Tag::SpaceBefore ) @@ -216,7 +215,6 @@ fn loc_type_in_parens<'a>( specialize_ref(ETypeInParens::Type, expression(true, false)), word1(b',', ETypeInParens::End), word1(b')', ETypeInParens::End), - ETypeInParens::Open, ETypeInParens::IndentEnd, TypeAnnotation::SpaceBefore ), @@ -292,7 +290,7 @@ fn record_type_field<'a>() -> impl Parser<'a, AssignedField<'a, TypeAnnotation<' let pos = state.pos(); let (progress, loc_label, state) = loc!(specialize( move |_, _| ETypeRecord::Field(pos), - lowercase_ident() + lowercase_ident_keyword_e() )) .parse(arena, state, min_indent)?; debug_assert_eq!(progress, MadeProgress); @@ -358,7 +356,6 @@ fn record_type<'a>( loc!(record_type_field()), word1(b',', ETypeRecord::End), word1(b'}', ETypeRecord::End), - ETypeRecord::Open, ETypeRecord::IndentEnd, AssignedField::SpaceBefore ), @@ -507,7 +504,6 @@ pub fn has_abilities<'a>() -> impl Parser<'a, Loc>, EType<'a>> loc!(parse_has_ability()), word1(b',', EType::TEnd), word1(b']', EType::TEnd), - EType::TStart, EType::TIndentEnd, HasAbility::SpaceBefore ), @@ -531,7 +527,6 @@ fn parse_has_ability<'a>() -> impl Parser<'a, HasAbility<'a>, EType<'a>> { specialize(|e: ERecord<'_>, _| e.into(), loc!(record_value_field())), word1(b',', ETypeAbilityImpl::End), word1(b'}', ETypeAbilityImpl::End), - ETypeAbilityImpl::Open, ETypeAbilityImpl::IndentEnd, AssignedField::SpaceBefore ) diff --git a/crates/reporting/src/error/parse.rs b/crates/reporting/src/error/parse.rs index 17d554e3f8..2c739e739a 100644 --- a/crates/reporting/src/error/parse.rs +++ b/crates/reporting/src/error/parse.rs @@ -3832,7 +3832,7 @@ fn to_requires_report<'a>( } } - ERequires::Open(pos) => { + ERequires::ListEnd(pos) | ERequires::Open(pos) => { let surroundings = Region::new(start, pos); let region = LineColumnRegion::from_pos(lines.convert_pos(pos));