From 89e56c364f3d0a9d5a12ae488185abc1ea69df4a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 24 Aug 2018 11:45:14 +0300 Subject: Labeled expressions --- crates/libsyntax2/src/grammar/expressions/atom.rs | 61 +++++++++++++++++------ 1 file changed, 45 insertions(+), 16 deletions(-) (limited to 'crates/libsyntax2/src/grammar/expressions/atom.rs') diff --git a/crates/libsyntax2/src/grammar/expressions/atom.rs b/crates/libsyntax2/src/grammar/expressions/atom.rs index 9f470d561..9d98340af 100644 --- a/crates/libsyntax2/src/grammar/expressions/atom.rs +++ b/crates/libsyntax2/src/grammar/expressions/atom.rs @@ -30,7 +30,7 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet = token_set_union![ LITERAL_FIRST, token_set![L_PAREN, PIPE, MOVE_KW, IF_KW, WHILE_KW, MATCH_KW, UNSAFE_KW, L_CURLY, RETURN_KW, - IDENT, SELF_KW, SUPER_KW, COLONCOLON, BREAK_KW, CONTINUE_KW ], + IDENT, SELF_KW, SUPER_KW, COLONCOLON, BREAK_KW, CONTINUE_KW, LIFETIME ], ]; pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option { @@ -48,9 +48,24 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option lambda_expr(p), MOVE_KW if la == PIPE => lambda_expr(p), IF_KW => if_expr(p), - WHILE_KW => while_expr(p), - LOOP_KW => loop_expr(p), - FOR_KW => for_expr(p), + + LOOP_KW => loop_expr(p, None), + FOR_KW => for_expr(p, None), + WHILE_KW => while_expr(p, None), + LIFETIME if la == COLON => { + let m = p.start(); + label(p); + match p.current() { + LOOP_KW => loop_expr(p, Some(m)), + FOR_KW => for_expr(p, Some(m)), + WHILE_KW => while_expr(p, Some(m)), + _ => { + p.error("expected a loop"); + return None; + } + } + } + MATCH_KW => match_expr(p), UNSAFE_KW if la == L_CURLY => block_expr(p), L_CURLY => block_expr(p), @@ -164,39 +179,53 @@ fn if_expr(p: &mut Parser) -> CompletedMarker { m.complete(p, IF_EXPR) } -// test while_expr +// test label // fn foo() { -// while true {}; -// while let Some(x) = it.next() {}; +// 'a: loop {} +// 'b: while true {} +// 'c: for x in () {} // } -fn while_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(WHILE_KW)); +fn label(p: &mut Parser) { + assert!(p.at(LIFETIME) && p.nth(1) == COLON); let m = p.start(); p.bump(); - cond(p); - block(p); - m.complete(p, WHILE_EXPR) + p.bump(); + m.complete(p, LABEL); } // test loop_expr // fn foo() { // loop {}; // } -fn loop_expr(p: &mut Parser) -> CompletedMarker { +fn loop_expr(p: &mut Parser, m: Option) -> CompletedMarker { assert!(p.at(LOOP_KW)); - let m = p.start(); + let m = m.unwrap_or_else(|| p.start()); p.bump(); block(p); m.complete(p, LOOP_EXPR) } +// test while_expr +// fn foo() { +// while true {}; +// while let Some(x) = it.next() {}; +// } +fn while_expr(p: &mut Parser, m: Option) -> CompletedMarker { + assert!(p.at(WHILE_KW)); + let m = m.unwrap_or_else(|| p.start()); + p.bump(); + cond(p); + block(p); + m.complete(p, WHILE_EXPR) +} + // test for_expr // fn foo() { // for x in [] {}; // } -fn for_expr(p: &mut Parser) -> CompletedMarker { +fn for_expr(p: &mut Parser, m: Option) -> CompletedMarker { assert!(p.at(FOR_KW)); - let m = p.start(); + let m = m.unwrap_or_else(|| p.start()); p.bump(); patterns::pattern(p); p.expect(IN_KW); -- cgit v1.2.3