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/patterns.rs | 92 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 4 deletions(-) (limited to 'src/grammar/patterns.rs') 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); -- cgit v1.2.3