From 8df5d5c13ce9c18ed9b2d4ebf6985bbb34aad14a Mon Sep 17 00:00:00 2001 From: rvcas Date: Tue, 17 Nov 2020 21:53:49 -0500 Subject: [PATCH] feat(parse): support capturing a str in Pattern::Underscore --- compiler/can/src/pattern.rs | 2 +- compiler/fmt/src/pattern.rs | 4 ++-- compiler/parse/src/ast.rs | 5 +++-- compiler/parse/src/expr.rs | 6 ++++-- compiler/parse/tests/test_parse.rs | 10 +++++----- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/compiler/can/src/pattern.rs b/compiler/can/src/pattern.rs index 43e76963d2..c5cd46b202 100644 --- a/compiler/can/src/pattern.rs +++ b/compiler/can/src/pattern.rs @@ -197,7 +197,7 @@ pub fn canonicalize_pattern<'a>( ptype => unsupported_pattern(env, ptype, region), }, - Underscore => match pattern_type { + Underscore(_) => match pattern_type { WhenBranch | FunctionArg => Pattern::Underscore, ptype => unsupported_pattern(env, ptype, region), }, diff --git a/compiler/fmt/src/pattern.rs b/compiler/fmt/src/pattern.rs index 547ccf19c1..ad0982138d 100644 --- a/compiler/fmt/src/pattern.rs +++ b/compiler/fmt/src/pattern.rs @@ -37,7 +37,7 @@ impl<'a> Formattable<'a> for Pattern<'a> { | Pattern::NonBase10Literal { .. } | Pattern::FloatLiteral(_) | Pattern::StrLiteral(_) - | Pattern::Underscore + | Pattern::Underscore(_) | Pattern::Malformed(_) | Pattern::QualifiedIdentifier { .. } => false, } @@ -128,7 +128,7 @@ impl<'a> Formattable<'a> for Pattern<'a> { StrLiteral(literal) => { todo!("Format string literal: {:?}", literal); } - Underscore => buf.push('_'), + Underscore(name) => buf.push_str(name), // Space SpaceBefore(sub_pattern, spaces) => { diff --git a/compiler/parse/src/ast.rs b/compiler/parse/src/ast.rs index 1d15acba21..6abdac6439 100644 --- a/compiler/parse/src/ast.rs +++ b/compiler/parse/src/ast.rs @@ -437,7 +437,7 @@ pub enum Pattern<'a> { }, FloatLiteral(&'a str), StrLiteral(StrLiteral<'a>), - Underscore, + Underscore(&'a str), // Space SpaceBefore(&'a Pattern<'a>, &'a [CommentOrNewline<'a>]), @@ -554,7 +554,8 @@ impl<'a> Pattern<'a> { ) => string_x == string_y && base_x == base_y && is_negative_x == is_negative_y, (FloatLiteral(x), FloatLiteral(y)) => x == y, (StrLiteral(x), StrLiteral(y)) => x == y, - (Underscore, Underscore) => true, + // TODO do we want to compare anything here? + (Underscore(_), Underscore(_)) => true, // Space (SpaceBefore(x, _), SpaceBefore(y, _)) => x.equivalent(y), diff --git a/compiler/parse/src/expr.rs b/compiler/parse/src/expr.rs index df2fe8017f..5de9a4c121 100644 --- a/compiler/parse/src/expr.rs +++ b/compiler/parse/src/expr.rs @@ -666,7 +666,7 @@ fn annotation_or_alias<'a>( NumLiteral(_) | NonBase10Literal { .. } | FloatLiteral(_) | StrLiteral(_) => { Def::NotYetImplemented("TODO gracefully handle trying to annotate a litera") } - Underscore => { + Underscore(_) => { Def::NotYetImplemented("TODO gracefully handle trying to give a type annotation to an undrscore") } Malformed(_) => { @@ -1086,7 +1086,9 @@ fn string_pattern<'a>() -> impl Parser<'a, Pattern<'a>> { } fn underscore_pattern<'a>() -> impl Parser<'a, Pattern<'a>> { - map!(ascii_char(b'_'), |_| Pattern::Underscore) + map_with_arena!(ascii_char(b'_'), |_arena, _thing| { + Pattern::Underscore(&"_") + }) } fn record_destructure<'a>(min_indent: u16) -> impl Parser<'a, Pattern<'a>> { diff --git a/compiler/parse/tests/test_parse.rs b/compiler/parse/tests/test_parse.rs index 82d1818d9d..473c4a4c97 100644 --- a/compiler/parse/tests/test_parse.rs +++ b/compiler/parse/tests/test_parse.rs @@ -1414,7 +1414,7 @@ mod test_parse { #[test] fn single_underscore_closure() { let arena = Bump::new(); - let pattern = Located::new(0, 0, 1, 2, Underscore); + let pattern = Located::new(0, 0, 1, 2, Underscore(&"_")); let patterns = &[pattern]; let expected = Closure(patterns, arena.alloc(Located::new(0, 0, 6, 8, Num("42")))); let actual = parse_expr_with(&arena, "\\_ -> 42"); @@ -1464,8 +1464,8 @@ mod test_parse { #[test] fn closure_with_underscores() { let arena = Bump::new(); - let underscore1 = Located::new(0, 0, 1, 2, Underscore); - let underscore2 = Located::new(0, 0, 4, 5, Underscore); + let underscore1 = Located::new(0, 0, 1, 2, Underscore(&"_")); + let underscore2 = Located::new(0, 0, 4, 5, Underscore(&"_")); let patterns = bumpalo::vec![in &arena; underscore1, underscore2]; let expected = Closure( arena.alloc(patterns), @@ -2477,7 +2477,7 @@ mod test_parse { guard: None, }); let newlines = &[Newline]; - let pattern2 = Pattern::SpaceBefore(arena.alloc(Underscore), newlines); + let pattern2 = Pattern::SpaceBefore(arena.alloc(Underscore(&"_")), newlines); let loc_pattern2 = Located::new(2, 2, 4, 5, pattern2); let expr2 = Num("4"); let loc_expr2 = Located::new(2, 2, 9, 10, expr2); @@ -2522,7 +2522,7 @@ mod test_parse { guard: None, }); let newlines = &[Newline]; - let pattern2 = Pattern::SpaceBefore(arena.alloc(Underscore), newlines); + let pattern2 = Pattern::SpaceBefore(arena.alloc(Underscore(&"_")), newlines); let loc_pattern2 = Located::new(2, 2, 4, 5, pattern2); let expr2 = Num("4"); let loc_expr2 = Located::new(2, 2, 9, 10, expr2);