Match expr

This commit is contained in:
Aleksey Kladov 2018-08-04 13:39:03 +03:00
parent e919db3731
commit 8f1c645055
7 changed files with 165 additions and 2 deletions

View file

@ -141,6 +141,9 @@ Grammar(
"IF_EXPR", "IF_EXPR",
"BLOCK_EXPR", "BLOCK_EXPR",
"RETURN_EXPR", "RETURN_EXPR",
"MATCH_EXPR",
"MATCH_ARM",
"MATCH_GUARD",
"EXTERN_BLOCK_EXPR", "EXTERN_BLOCK_EXPR",
"ENUM_VARIANT", "ENUM_VARIANT",

View file

@ -27,6 +27,7 @@ pub(super) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
} }
const EXPR_FIRST: TokenSet = PREFIX_EXPR_FIRST; const EXPR_FIRST: TokenSet = PREFIX_EXPR_FIRST;
pub(super) fn expr(p: &mut Parser) { pub(super) fn expr(p: &mut Parser) {
let mut lhs = match prefix_expr(p) { let mut lhs = match prefix_expr(p) {
Some(lhs) => lhs, Some(lhs) => lhs,
@ -87,6 +88,7 @@ const PREFIX_EXPR_FIRST: TokenSet =
token_set![AMPERSAND, STAR, EXCL], token_set![AMPERSAND, STAR, EXCL],
ATOM_EXPR_FIRST, ATOM_EXPR_FIRST,
]; ];
fn prefix_expr(p: &mut Parser) -> Option<CompletedMarker> { fn prefix_expr(p: &mut Parser) -> Option<CompletedMarker> {
let done = match p.current() { let done = match p.current() {
AMPERSAND => ref_expr(p), AMPERSAND => ref_expr(p),
@ -140,6 +142,7 @@ const ATOM_EXPR_FIRST: TokenSet =
LITERAL_FIRST, LITERAL_FIRST,
token_set![L_PAREN, PIPE, MOVE_KW, IF_KW, UNSAFE_KW, L_CURLY, RETURN_KW], token_set![L_PAREN, PIPE, MOVE_KW, IF_KW, UNSAFE_KW, L_CURLY, RETURN_KW],
]; ];
fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> { fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> {
match literal(p) { match literal(p) {
Some(m) => return Some(m), Some(m) => return Some(m),
@ -154,6 +157,7 @@ fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> {
PIPE => lambda_expr(p), PIPE => lambda_expr(p),
MOVE_KW if la == PIPE => lambda_expr(p), MOVE_KW if la == PIPE => lambda_expr(p),
IF_KW => if_expr(p), IF_KW => if_expr(p),
MATCH_KW => match_expr(p),
UNSAFE_KW if la == L_CURLY => block_expr(p), UNSAFE_KW if la == L_CURLY => block_expr(p),
L_CURLY => block_expr(p), L_CURLY => block_expr(p),
RETURN_KW => return_expr(p), RETURN_KW => return_expr(p),
@ -202,8 +206,7 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
fn if_expr(p: &mut Parser) -> CompletedMarker { fn if_expr(p: &mut Parser) -> CompletedMarker {
assert!(p.at(IF_KW)); assert!(p.at(IF_KW));
let m = p.start(); let m = p.start();
p.bump(); if_head(p);
expr(p);
block(p); block(p);
if p.at(ELSE_KW) { if p.at(ELSE_KW) {
p.bump(); p.bump();
@ -216,6 +219,55 @@ fn if_expr(p: &mut Parser) -> CompletedMarker {
m.complete(p, IF_EXPR) m.complete(p, IF_EXPR)
} }
fn if_head(p: &mut Parser) {
assert!(p.at(IF_KW));
p.bump();
expr(p);
}
// test match_expr
// fn foo() {
// match () { };
// }
fn match_expr(p: &mut Parser) -> CompletedMarker {
assert!(p.at(MATCH_KW));
let m = p.start();
p.bump();
expr(p);
p.eat(L_CURLY);
while !p.at(EOF) && !p.at(R_CURLY) {
match_arm(p);
if !p.at(R_CURLY) {
p.expect(COMMA);
}
}
p.expect(R_CURLY);
m.complete(p, MATCH_EXPR)
}
// test match_arm
// fn foo() {
// match () {
// _ => (),
// X | Y if Z => (),
// };
// }
fn match_arm(p: &mut Parser) {
let m = p.start();
loop {
patterns::pattern(p);
if !p.eat(PIPE) {
break;
}
}
if p.at(IF_KW) {
if_head(p)
}
p.expect(FAT_ARROW);
expr(p);
m.complete(p, MATCH_ARM);
}
// test block_expr // test block_expr
// fn foo() { // fn foo() {
// {}; // {};

View file

@ -132,6 +132,9 @@ pub enum SyntaxKind {
IF_EXPR, IF_EXPR,
BLOCK_EXPR, BLOCK_EXPR,
RETURN_EXPR, RETURN_EXPR,
MATCH_EXPR,
MATCH_ARM,
MATCH_GUARD,
EXTERN_BLOCK_EXPR, EXTERN_BLOCK_EXPR,
ENUM_VARIANT, ENUM_VARIANT,
NAMED_FIELD, NAMED_FIELD,
@ -342,6 +345,9 @@ impl SyntaxKind {
IF_EXPR => &SyntaxInfo { name: "IF_EXPR" }, IF_EXPR => &SyntaxInfo { name: "IF_EXPR" },
BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" }, BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" },
RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" }, RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" },
MATCH_EXPR => &SyntaxInfo { name: "MATCH_EXPR" },
MATCH_ARM => &SyntaxInfo { name: "MATCH_ARM" },
MATCH_GUARD => &SyntaxInfo { name: "MATCH_GUARD" },
EXTERN_BLOCK_EXPR => &SyntaxInfo { name: "EXTERN_BLOCK_EXPR" }, EXTERN_BLOCK_EXPR => &SyntaxInfo { name: "EXTERN_BLOCK_EXPR" },
ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },
NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },

View file

@ -0,0 +1,6 @@
fn foo() {
match () {
_ => (),
X | Y if Z => (),
};
}

View file

@ -0,0 +1,65 @@
FILE@[0; 78)
FN_ITEM@[0; 78)
FN_KW@[0; 2)
NAME@[2; 6)
WHITESPACE@[2; 3)
IDENT@[3; 6) "foo"
PARAM_LIST@[6; 9)
L_PAREN@[6; 7)
R_PAREN@[7; 8)
WHITESPACE@[8; 9)
BLOCK_EXPR@[9; 78)
L_CURLY@[9; 10)
EXPR_STMT@[10; 76)
MATCH_EXPR@[10; 74)
WHITESPACE@[10; 15)
MATCH_KW@[15; 20)
TUPLE_EXPR@[20; 24)
WHITESPACE@[20; 21)
L_PAREN@[21; 22)
R_PAREN@[22; 23)
WHITESPACE@[23; 24)
L_CURLY@[24; 25)
MATCH_ARM@[25; 41)
PLACEHOLDER_PAT@[25; 36)
WHITESPACE@[25; 34)
UNDERSCORE@[34; 35)
WHITESPACE@[35; 36)
FAT_ARROW@[36; 38)
TUPLE_EXPR@[38; 41)
WHITESPACE@[38; 39)
L_PAREN@[39; 40)
R_PAREN@[40; 41)
COMMA@[41; 42)
MATCH_ARM@[42; 67)
BIND_PAT@[42; 53)
NAME@[42; 53)
WHITESPACE@[42; 51)
IDENT@[51; 52) "X"
WHITESPACE@[52; 53)
PIPE@[53; 54)
BIND_PAT@[54; 57)
NAME@[54; 57)
WHITESPACE@[54; 55)
IDENT@[55; 56) "Y"
WHITESPACE@[56; 57)
IF_KW@[57; 59)
PATH_EXPR@[59; 62)
PATH@[59; 62)
PATH_SEGMENT@[59; 62)
NAME_REF@[59; 62)
WHITESPACE@[59; 60)
IDENT@[60; 61) "Z"
WHITESPACE@[61; 62)
FAT_ARROW@[62; 64)
TUPLE_EXPR@[64; 67)
WHITESPACE@[64; 65)
L_PAREN@[65; 66)
R_PAREN@[66; 67)
COMMA@[67; 68)
WHITESPACE@[68; 73)
R_CURLY@[73; 74)
SEMI@[74; 75)
WHITESPACE@[75; 76)
R_CURLY@[76; 77)
WHITESPACE@[77; 78)

View file

@ -0,0 +1,3 @@
fn foo() {
match () { };
}

View file

@ -0,0 +1,28 @@
FILE@[0; 31)
FN_ITEM@[0; 31)
FN_KW@[0; 2)
NAME@[2; 6)
WHITESPACE@[2; 3)
IDENT@[3; 6) "foo"
PARAM_LIST@[6; 9)
L_PAREN@[6; 7)
R_PAREN@[7; 8)
WHITESPACE@[8; 9)
BLOCK_EXPR@[9; 31)
L_CURLY@[9; 10)
EXPR_STMT@[10; 29)
MATCH_EXPR@[10; 27)
WHITESPACE@[10; 15)
MATCH_KW@[15; 20)
TUPLE_EXPR@[20; 24)
WHITESPACE@[20; 21)
L_PAREN@[21; 22)
R_PAREN@[22; 23)
WHITESPACE@[23; 24)
L_CURLY@[24; 25)
WHITESPACE@[25; 26)
R_CURLY@[26; 27)
SEMI@[27; 28)
WHITESPACE@[28; 29)
R_CURLY@[29; 30)
WHITESPACE@[30; 31)