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.ron | 5 +- crates/libsyntax2/src/grammar/expressions/atom.rs | 61 +++++++++++++++++------ crates/libsyntax2/src/grammar/mod.rs | 2 +- crates/libsyntax2/src/syntax_kinds/generated.rs | 10 ++-- 4 files changed, 55 insertions(+), 23 deletions(-) (limited to 'crates/libsyntax2/src') diff --git a/crates/libsyntax2/src/grammar.ron b/crates/libsyntax2/src/grammar.ron index dff88cc4a..52764e664 100644 --- a/crates/libsyntax2/src/grammar.ron +++ b/crates/libsyntax2/src/grammar.ron @@ -161,11 +161,12 @@ Grammar( "PATH_EXPR", "LAMBDA_EXPR", "IF_EXPR", - "WHILE_EXPR", "LOOP_EXPR", + "FOR_EXPR", + "WHILE_EXPR", "CONTINUE_EXPR", "BREAK_EXPR", - "FOR_EXPR", + "LABEL", "BLOCK_EXPR", "RETURN_EXPR", "MATCH_EXPR", 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); diff --git a/crates/libsyntax2/src/grammar/mod.rs b/crates/libsyntax2/src/grammar/mod.rs index 0f168eb60..25887921b 100644 --- a/crates/libsyntax2/src/grammar/mod.rs +++ b/crates/libsyntax2/src/grammar/mod.rs @@ -32,7 +32,7 @@ mod type_params; mod types; use { - parser_api::{CompletedMarker, Parser, TokenSet}, + parser_api::{Marker, CompletedMarker, Parser, TokenSet}, SyntaxKind::{self, *}, }; diff --git a/crates/libsyntax2/src/syntax_kinds/generated.rs b/crates/libsyntax2/src/syntax_kinds/generated.rs index 82b6c89cf..61d527f93 100644 --- a/crates/libsyntax2/src/syntax_kinds/generated.rs +++ b/crates/libsyntax2/src/syntax_kinds/generated.rs @@ -157,11 +157,12 @@ pub enum SyntaxKind { PATH_EXPR, LAMBDA_EXPR, IF_EXPR, - WHILE_EXPR, LOOP_EXPR, + FOR_EXPR, + WHILE_EXPR, CONTINUE_EXPR, BREAK_EXPR, - FOR_EXPR, + LABEL, BLOCK_EXPR, RETURN_EXPR, MATCH_EXPR, @@ -406,11 +407,12 @@ impl SyntaxKind { PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" }, LAMBDA_EXPR => &SyntaxInfo { name: "LAMBDA_EXPR" }, IF_EXPR => &SyntaxInfo { name: "IF_EXPR" }, - WHILE_EXPR => &SyntaxInfo { name: "WHILE_EXPR" }, LOOP_EXPR => &SyntaxInfo { name: "LOOP_EXPR" }, + FOR_EXPR => &SyntaxInfo { name: "FOR_EXPR" }, + WHILE_EXPR => &SyntaxInfo { name: "WHILE_EXPR" }, CONTINUE_EXPR => &SyntaxInfo { name: "CONTINUE_EXPR" }, BREAK_EXPR => &SyntaxInfo { name: "BREAK_EXPR" }, - FOR_EXPR => &SyntaxInfo { name: "FOR_EXPR" }, + LABEL => &SyntaxInfo { name: "LABEL" }, BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" }, RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" }, MATCH_EXPR => &SyntaxInfo { name: "MATCH_EXPR" }, -- cgit v1.2.3