From 4e4ad3d27cd662b790395b61f3cda560fd4e2146 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 4 Aug 2018 15:47:45 +0300 Subject: tuple patterns --- src/grammar.ron | 3 ++ src/grammar/patterns.rs | 92 +++++++++++++++++++++++++++++++++++++++++-- src/syntax_kinds/generated.rs | 6 +++ 3 files changed, 97 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/grammar.ron b/src/grammar.ron index 0239a3c1d..655ed2e40 100644 --- a/src/grammar.ron +++ b/src/grammar.ron @@ -126,6 +126,9 @@ Grammar( "REF_PAT", "BIND_PAT", "PLACEHOLDER_PAT", + "PATH_PAT", + "STRUCT_PAT", + "TUPLE_PAT", "TUPLE_EXPR", "PATH_EXPR", diff --git a/src/grammar/patterns.rs b/src/grammar/patterns.rs index 7216807fd..770274686 100644 --- a/src/grammar/patterns.rs +++ b/src/grammar/patterns.rs @@ -1,14 +1,98 @@ use super::*; pub(super) fn pattern(p: &mut Parser) { - match p.current() { + let la0 = p.nth(0); + let la1 = p.nth(1); + if la0 == REF_KW || la0 == MUT_KW + || (la0 == IDENT && !(la1 == COLONCOLON || la1 == L_PAREN || la1 == L_CURLY)) { + bind_pat(p, true); + return; + } + if paths::is_path_start(p) { + path_pat(p); + return; + } + + match la0 { UNDERSCORE => placeholder_pat(p), AMPERSAND => ref_pat(p), - IDENT | REF_KW | MUT_KW => bind_pat(p), _ => p.err_and_bump("expected pattern"), } } +// test path_part +// fn foo() { +// let foo::Bar = (); +// let ::Bar = (); +// let Bar { .. } = (); +// let Bar(..) = (); +// } +fn path_pat(p: &mut Parser) { + let m = p.start(); + paths::expr_path(p); + let kind = match p.current() { + L_PAREN => { + tuple_pat_fields(p); + TUPLE_PAT + } + L_CURLY => { + struct_pat_fields(p); + STRUCT_PAT + } + _ => PATH_PAT + }; + m.complete(p, kind); +} + +// test tuple_pat_fields +// fn foo() { +// let S() = (); +// let S(_) = (); +// let S(_,) = (); +// let S(_, .. , x) = (); +// } +fn tuple_pat_fields(p: &mut Parser) { + assert!(p.at(L_PAREN)); + p.bump(); + while !p.at(EOF) && !p.at(R_PAREN) { + match p.current() { + DOTDOT => p.bump(), + _ => pattern(p), + } + if !p.at(R_PAREN) { + p.expect(COMMA); + } + } + p.expect(R_PAREN); +} + +// test struct_pat_fields +// fn foo() { +// let S {} = (); +// let S { f, ref mut g } = (); +// let S { h: _, ..} = (); +// let S { h: _, } = (); +// } +fn struct_pat_fields(p: &mut Parser) { + assert!(p.at(L_CURLY)); + p.bump(); + while !p.at(EOF) && !p.at(R_CURLY) { + match p.current() { + DOTDOT => p.bump(), + IDENT if p.nth(1) == COLON => { + p.bump(); + p.bump(); + pattern(p); + } + _ => bind_pat(p, false), + } + if !p.at(R_CURLY) { + p.expect(COMMA); + } + } + p.expect(R_CURLY); +} + // test placeholder_pat // fn main() { let _ = (); } fn placeholder_pat(p: &mut Parser) { @@ -41,12 +125,12 @@ fn ref_pat(p: &mut Parser) { // let e @ _ = (); // let ref mut f @ g @ _ = (); // } -fn bind_pat(p: &mut Parser) { +fn bind_pat(p: &mut Parser, with_at: bool) { let m = p.start(); p.eat(REF_KW); p.eat(MUT_KW); name(p); - if p.eat(AT) { + if with_at && p.eat(AT) { pattern(p); } m.complete(p, BIND_PAT); diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs index 73b26b274..d7a57f4d0 100644 --- a/src/syntax_kinds/generated.rs +++ b/src/syntax_kinds/generated.rs @@ -118,6 +118,9 @@ pub enum SyntaxKind { REF_PAT, BIND_PAT, PLACEHOLDER_PAT, + PATH_PAT, + STRUCT_PAT, + TUPLE_PAT, TUPLE_EXPR, PATH_EXPR, CALL_EXPR, @@ -331,6 +334,9 @@ impl SyntaxKind { REF_PAT => &SyntaxInfo { name: "REF_PAT" }, BIND_PAT => &SyntaxInfo { name: "BIND_PAT" }, PLACEHOLDER_PAT => &SyntaxInfo { name: "PLACEHOLDER_PAT" }, + PATH_PAT => &SyntaxInfo { name: "PATH_PAT" }, + STRUCT_PAT => &SyntaxInfo { name: "STRUCT_PAT" }, + TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" }, TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" }, CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" }, -- cgit v1.2.3