From d5d98b67a83944d72a5c0f8e8e2f43aeee667122 Mon Sep 17 00:00:00 2001 From: Marmare314 <49279081+Marmare314@users.noreply.github.com> Date: Tue, 25 Apr 2023 11:22:12 +0200 Subject: Destructuring assign (#703) --- src/syntax/parser.rs | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) (limited to 'src/syntax/parser.rs') diff --git a/src/syntax/parser.rs b/src/syntax/parser.rs index 389cf026..0bbf77e2 100644 --- a/src/syntax/parser.rs +++ b/src/syntax/parser.rs @@ -725,7 +725,16 @@ fn with_paren(p: &mut Parser) { p.assert(SyntaxKind::Arrow); code_expr(p); kind = SyntaxKind::Closure; + } else if p.at(SyntaxKind::Eq) && kind != SyntaxKind::Parenthesized { + // TODO: add warning if p.at(SyntaxKind::Eq) && kind == SyntaxKind::Parenthesized + + validate_destruct_pattern(p, m, false); + p.wrap(m, SyntaxKind::Destructuring); + p.assert(SyntaxKind::Eq); + code_expr(p); + kind = SyntaxKind::DestructAssignment; } + match kind { SyntaxKind::Array => validate_array(p, m), SyntaxKind::Dict => validate_dict(p, m), @@ -866,7 +875,7 @@ fn pattern(p: &mut Parser) -> PatternKind { let m = p.marker(); if p.at(SyntaxKind::LeftParen) { let kind = collection(p, false); - validate_destruct_pattern(p, m); + validate_destruct_pattern(p, m, true); if kind == SyntaxKind::Parenthesized { PatternKind::Ident @@ -1184,7 +1193,7 @@ fn validate_args(p: &mut Parser, m: Marker) { } } -fn validate_destruct_pattern(p: &mut Parser, m: Marker) { +fn validate_destruct_pattern(p: &mut Parser, m: Marker, forbid_expressions: bool) { let mut used_spread = false; let mut used = HashSet::new(); for child in p.post_process(m) { @@ -1206,7 +1215,7 @@ fn validate_destruct_pattern(p: &mut Parser, m: Marker) { if within.kind() == SyntaxKind::Dots { continue; - } else if within.kind() != SyntaxKind::Ident { + } else if forbid_expressions && within.kind() != SyntaxKind::Ident { within.convert_to_error(eco_format!( "expected identifier, found {}", within.kind().name(), @@ -1231,15 +1240,17 @@ fn validate_destruct_pattern(p: &mut Parser, m: Marker) { child.make_erroneous(); } - let Some(within) = child.children_mut().last_mut() else { return }; - if within.kind() != SyntaxKind::Ident - && within.kind() != SyntaxKind::Underscore - { - within.convert_to_error(eco_format!( - "expected identifier, found {}", - within.kind().name(), - )); - child.make_erroneous(); + if forbid_expressions { + let Some(within) = child.children_mut().last_mut() else { return }; + if within.kind() != SyntaxKind::Ident + && within.kind() != SyntaxKind::Underscore + { + within.convert_to_error(eco_format!( + "expected identifier, found {}", + within.kind().name(), + )); + child.make_erroneous(); + } } } SyntaxKind::LeftParen @@ -1247,10 +1258,12 @@ fn validate_destruct_pattern(p: &mut Parser, m: Marker) { | SyntaxKind::Comma | SyntaxKind::Underscore => {} kind => { - child.convert_to_error(eco_format!( - "expected identifier or destructuring sink, found {}", - kind.name() - )); + if forbid_expressions { + child.convert_to_error(eco_format!( + "expected identifier or destructuring sink, found {}", + kind.name() + )); + } } } } -- cgit v1.2.3