From 53485030dc49aa7cd66e36c8a1e1abf1bf08020c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 1 Aug 2018 10:51:42 +0300 Subject: block expr --- src/grammar.ron | 4 +-- src/grammar/expressions.rs | 66 ++++++++++++++++++++++++++----------------- src/grammar/items/mod.rs | 2 +- src/lib.rs | 1 + src/syntax_kinds/generated.rs | 8 +++--- 5 files changed, 48 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/grammar.ron b/src/grammar.ron index b4c121f4d..109556561 100644 --- a/src/grammar.ron +++ b/src/grammar.ron @@ -139,7 +139,7 @@ Grammar( "STRUCT_LIT_FIELD", "IF_EXPR", - "EXTERN_BLOCK", + "EXTERN_BLOCK_EXPR", "ENUM_VARIANT", "NAMED_FIELD", "POS_FIELD", @@ -155,7 +155,7 @@ Grammar( "ABI", "NAME", "NAME_REF", - "BLOCK", + "BLOCK_EXPR", "LET_STMT", "EXPR_STMT", diff --git a/src/grammar/expressions.rs b/src/grammar/expressions.rs index c0eb0e756..5c59843a4 100644 --- a/src/grammar/expressions.rs +++ b/src/grammar/expressions.rs @@ -53,31 +53,9 @@ pub(super) fn expr(p: &mut Parser) { pub(super) fn block(p: &mut Parser) { if !p.at(L_CURLY) { p.error("expected block"); + return; } - let m = p.start(); - p.bump(); - while !p.at(EOF) && !p.at(R_CURLY) { - match p.current() { - LET_KW => let_stmt(p), - c => { - // test block_items - // fn a() { fn b() {} } - if items::ITEM_FIRST.contains(c) { - items::item(p) - } else { - let expr_stmt = p.start(); - expressions::expr(p); - if p.eat(SEMI) { - expr_stmt.complete(p, EXPR_STMT); - } else { - expr_stmt.abandon(p); - } - } - } - } - } - p.expect(R_CURLY); - m.complete(p, BLOCK); + block_expr(p); } // test let_stmt; @@ -158,12 +136,14 @@ fn atom_expr(p: &mut Parser) -> Option { if paths::is_path_start(p) { return Some(path_expr(p)); } - + let la = p.nth(1); let done = match p.current() { L_PAREN => tuple_expr(p), PIPE => lambda_expr(p), - MOVE_KW if p.nth(1) == PIPE => lambda_expr(p), + MOVE_KW if la == PIPE => lambda_expr(p), IF_KW => if_expr(p), + UNSAFE_KW if la == L_CURLY => block_expr(p), + L_CURLY => block_expr(p), _ => { p.err_and_bump("expected expression"); return None; @@ -223,6 +203,40 @@ fn if_expr(p: &mut Parser) -> CompletedMarker { m.complete(p, IF_EXPR) } +// test block_expr +// fn foo() { +// {}; +// unsafe {}; +// } +fn block_expr(p: &mut Parser) -> CompletedMarker { + assert!(p.at(L_CURLY) || p.at(UNSAFE_KW) && p.nth(1) == L_CURLY); + let m = p.start(); + p.eat(UNSAFE_KW); + p.bump(); + while !p.at(EOF) && !p.at(R_CURLY) { + match p.current() { + LET_KW => let_stmt(p), + c => { + // test block_items + // fn a() { fn b() {} } + if items::ITEM_FIRST.contains(c) { + items::item(p) + } else { + let expr_stmt = p.start(); + expressions::expr(p); + if p.eat(SEMI) { + expr_stmt.complete(p, EXPR_STMT); + } else { + expr_stmt.abandon(p); + } + } + } + } + } + p.expect(R_CURLY); + m.complete(p, BLOCK_EXPR) +} + // test call_expr // fn foo() { // let _ = f(); diff --git a/src/grammar/items/mod.rs b/src/grammar/items/mod.rs index d5f75f13d..a1150e2ac 100644 --- a/src/grammar/items/mod.rs +++ b/src/grammar/items/mod.rs @@ -44,7 +44,7 @@ pub(super) fn item(p: &mut Parser) { // extern {} L_CURLY => { extern_block(p); - EXTERN_BLOCK + EXTERN_BLOCK_EXPR } // test extern_struct // extern struct Foo; diff --git a/src/lib.rs b/src/lib.rs index 611b87492..1cd45690a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,6 +45,7 @@ pub use { yellow::{SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot}, }; + pub fn parse(text: &str) -> SyntaxNode { let tokens = tokenize(&text); parser_impl::parse::(text, &tokens) diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs index cbcd0c4e1..5f26cbf0a 100644 --- a/src/syntax_kinds/generated.rs +++ b/src/syntax_kinds/generated.rs @@ -129,7 +129,7 @@ pub enum SyntaxKind { STRUCT_LIT, STRUCT_LIT_FIELD, IF_EXPR, - EXTERN_BLOCK, + EXTERN_BLOCK_EXPR, ENUM_VARIANT, NAMED_FIELD, POS_FIELD, @@ -145,7 +145,7 @@ pub enum SyntaxKind { ABI, NAME, NAME_REF, - BLOCK, + BLOCK_EXPR, LET_STMT, EXPR_STMT, TYPE_PARAM_LIST, @@ -336,7 +336,7 @@ impl SyntaxKind { STRUCT_LIT => &SyntaxInfo { name: "STRUCT_LIT" }, STRUCT_LIT_FIELD => &SyntaxInfo { name: "STRUCT_LIT_FIELD" }, IF_EXPR => &SyntaxInfo { name: "IF_EXPR" }, - EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, + EXTERN_BLOCK_EXPR => &SyntaxInfo { name: "EXTERN_BLOCK_EXPR" }, ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, POS_FIELD => &SyntaxInfo { name: "POS_FIELD" }, @@ -352,7 +352,7 @@ impl SyntaxKind { ABI => &SyntaxInfo { name: "ABI" }, NAME => &SyntaxInfo { name: "NAME" }, NAME_REF => &SyntaxInfo { name: "NAME_REF" }, - BLOCK => &SyntaxInfo { name: "BLOCK" }, + BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" }, LET_STMT => &SyntaxInfo { name: "LET_STMT" }, EXPR_STMT => &SyntaxInfo { name: "EXPR_STMT" }, TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" }, -- cgit v1.2.3