From 7c67612b8a894187fa3b64725531a5459f9211bf Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 10 Aug 2018 22:33:29 +0300 Subject: organizize --- crates/libsyntax2/src/grammar/patterns.rs | 204 ++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 crates/libsyntax2/src/grammar/patterns.rs (limited to 'crates/libsyntax2/src/grammar/patterns.rs') diff --git a/crates/libsyntax2/src/grammar/patterns.rs b/crates/libsyntax2/src/grammar/patterns.rs new file mode 100644 index 000000000..436f3b26d --- /dev/null +++ b/crates/libsyntax2/src/grammar/patterns.rs @@ -0,0 +1,204 @@ +use super::*; + +pub(super) fn pattern(p: &mut Parser) { + if let Some(lhs) = atom_pat(p) { + // test range_pat + // fn main() { + // match 92 { 0 ... 100 => () } + // } + if p.at(DOTDOTDOT) { + let m = lhs.precede(p); + p.bump(); + atom_pat(p); + m.complete(p, RANGE_PAT); + } + } +} + +fn atom_pat(p: &mut Parser) -> Option { + 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)) { + return Some(bind_pat(p, true)); + } + if paths::is_path_start(p) { + return Some(path_pat(p)); + } + + // test literal_pattern + // fn main() { + // match () { + // 92 => (), + // 'c' => (), + // "hello" => (), + // } + // } + match expressions::literal(p) { + Some(m) => return Some(m), + None => (), + } + + let m = match la0 { + UNDERSCORE => placeholder_pat(p), + AMP => ref_pat(p), + L_PAREN => tuple_pat(p), + L_BRACK => slice_pat(p), + _ => { + p.err_and_bump("expected pattern"); + return None; + } + }; + Some(m) +} + +// test path_part +// fn foo() { +// let foo::Bar = (); +// let ::Bar = (); +// let Bar { .. } = (); +// let Bar(..) = (); +// } +fn path_pat(p: &mut Parser) -> CompletedMarker { + let m = p.start(); + paths::expr_path(p); + let kind = match p.current() { + L_PAREN => { + tuple_pat_fields(p); + TUPLE_STRUCT_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) -> CompletedMarker { + assert!(p.at(UNDERSCORE)); + let m = p.start(); + p.bump(); + m.complete(p, PLACEHOLDER_PAT) +} + +// test ref_pat +// fn main() { +// let &a = (); +// let &mut b = (); +// } +fn ref_pat(p: &mut Parser) -> CompletedMarker { + assert!(p.at(AMP)); + let m = p.start(); + p.bump(); + p.eat(MUT_KW); + pattern(p); + m.complete(p, REF_PAT) +} + +// test tuple_pat +// fn main() { +// let (a, b, ..) = (); +// } +fn tuple_pat(p: &mut Parser) -> CompletedMarker { + assert!(p.at(L_PAREN)); + let m = p.start(); + tuple_pat_fields(p); + m.complete(p, TUPLE_PAT) +} + +// test slice_pat +// fn main() { +// let [a, b, ..] = []; +// } +fn slice_pat(p: &mut Parser) -> CompletedMarker { + assert!(p.at(L_BRACK)); + let m = p.start(); + p.bump(); + while !p.at(EOF) && !p.at(R_BRACK) { + match p.current() { + DOTDOT => p.bump(), + _ => pattern(p), + } + if !p.at(R_BRACK) { + p.expect(COMMA); + } + } + p.expect(R_BRACK); + + m.complete(p, SLICE_PAT) +} + +// test bind_pat +// fn main() { +// let a = (); +// let mut b = (); +// let ref c = (); +// let ref mut d = (); +// let e @ _ = (); +// let ref mut f @ g @ _ = (); +// } +fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker { + let m = p.start(); + p.eat(REF_KW); + p.eat(MUT_KW); + name(p); + if with_at && p.eat(AT) { + pattern(p); + } + m.complete(p, BIND_PAT) +} -- cgit v1.2.3