break&continue

This commit is contained in:
Aleksey Kladov 2018-08-24 11:21:13 +03:00
parent a66c94af1b
commit 719710a132
8 changed files with 156 additions and 13 deletions

View file

@ -75,6 +75,8 @@ Grammar(
"for",
"loop",
"while",
"continue",
"break",
"if",
"else",
"match",
@ -161,6 +163,8 @@ Grammar(
"IF_EXPR",
"WHILE_EXPR",
"LOOP_EXPR",
"CONTINUE_EXPR",
"BREAK_EXPR",
"FOR_EXPR",
"BLOCK_EXPR",
"RETURN_EXPR",

View file

@ -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 ],
IDENT, SELF_KW, SUPER_KW, COLONCOLON, BREAK_KW, CONTINUE_KW ],
];
pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> {
@ -55,6 +55,8 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMark
UNSAFE_KW if la == L_CURLY => block_expr(p),
L_CURLY => block_expr(p),
RETURN_KW => return_expr(p),
CONTINUE_KW => continue_expr(p),
BREAK_KW => break_expr(p),
_ => {
p.err_and_bump("expected expression");
return None;
@ -346,3 +348,38 @@ fn return_expr(p: &mut Parser) -> CompletedMarker {
}
m.complete(p, RETURN_EXPR)
}
// test continue_expr
// fn foo() {
// loop {
// continue;
// continue 'l;
// }
// }
fn continue_expr(p: &mut Parser) -> CompletedMarker {
assert!(p.at(CONTINUE_KW));
let m = p.start();
p.bump();
p.eat(LIFETIME);
m.complete(p, CONTINUE_EXPR)
}
// test break_expr
// fn foo() {
// loop {
// break;
// break 'l;
// break 92;
// break 'l 92;
// }
// }
fn break_expr(p: &mut Parser) -> CompletedMarker {
assert!(p.at(BREAK_KW));
let m = p.start();
p.bump();
p.eat(LIFETIME);
if EXPR_FIRST.contains(p.current()) {
expr(p);
}
m.complete(p, BREAK_EXPR)
}

View file

@ -82,6 +82,8 @@ pub enum SyntaxKind {
FOR_KW,
LOOP_KW,
WHILE_KW,
CONTINUE_KW,
BREAK_KW,
IF_KW,
ELSE_KW,
MATCH_KW,
@ -157,6 +159,8 @@ pub enum SyntaxKind {
IF_EXPR,
WHILE_EXPR,
LOOP_EXPR,
CONTINUE_EXPR,
BREAK_EXPR,
FOR_EXPR,
BLOCK_EXPR,
RETURN_EXPR,
@ -232,6 +236,8 @@ impl SyntaxKind {
| FOR_KW
| LOOP_KW
| WHILE_KW
| CONTINUE_KW
| BREAK_KW
| IF_KW
| ELSE_KW
| MATCH_KW
@ -325,6 +331,8 @@ impl SyntaxKind {
FOR_KW => &SyntaxInfo { name: "FOR_KW" },
LOOP_KW => &SyntaxInfo { name: "LOOP_KW" },
WHILE_KW => &SyntaxInfo { name: "WHILE_KW" },
CONTINUE_KW => &SyntaxInfo { name: "CONTINUE_KW" },
BREAK_KW => &SyntaxInfo { name: "BREAK_KW" },
IF_KW => &SyntaxInfo { name: "IF_KW" },
ELSE_KW => &SyntaxInfo { name: "ELSE_KW" },
MATCH_KW => &SyntaxInfo { name: "MATCH_KW" },
@ -400,6 +408,8 @@ impl SyntaxKind {
IF_EXPR => &SyntaxInfo { name: "IF_EXPR" },
WHILE_EXPR => &SyntaxInfo { name: "WHILE_EXPR" },
LOOP_EXPR => &SyntaxInfo { name: "LOOP_EXPR" },
CONTINUE_EXPR => &SyntaxInfo { name: "CONTINUE_EXPR" },
BREAK_EXPR => &SyntaxInfo { name: "BREAK_EXPR" },
FOR_EXPR => &SyntaxInfo { name: "FOR_EXPR" },
BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" },
RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" },
@ -475,6 +485,8 @@ impl SyntaxKind {
"for" => FOR_KW,
"loop" => LOOP_KW,
"while" => WHILE_KW,
"continue" => CONTINUE_KW,
"break" => BREAK_KW,
"if" => IF_KW,
"else" => ELSE_KW,
"match" => MATCH_KW,