aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/grammar.ron4
-rw-r--r--src/grammar/expressions.rs66
-rw-r--r--src/grammar/items/mod.rs2
-rw-r--r--src/lib.rs1
-rw-r--r--src/syntax_kinds/generated.rs8
5 files changed, 48 insertions, 33 deletions
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(
139 "STRUCT_LIT_FIELD", 139 "STRUCT_LIT_FIELD",
140 "IF_EXPR", 140 "IF_EXPR",
141 141
142 "EXTERN_BLOCK", 142 "EXTERN_BLOCK_EXPR",
143 "ENUM_VARIANT", 143 "ENUM_VARIANT",
144 "NAMED_FIELD", 144 "NAMED_FIELD",
145 "POS_FIELD", 145 "POS_FIELD",
@@ -155,7 +155,7 @@ Grammar(
155 "ABI", 155 "ABI",
156 "NAME", 156 "NAME",
157 "NAME_REF", 157 "NAME_REF",
158 "BLOCK", 158 "BLOCK_EXPR",
159 159
160 "LET_STMT", 160 "LET_STMT",
161 "EXPR_STMT", 161 "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) {
53pub(super) fn block(p: &mut Parser) { 53pub(super) fn block(p: &mut Parser) {
54 if !p.at(L_CURLY) { 54 if !p.at(L_CURLY) {
55 p.error("expected block"); 55 p.error("expected block");
56 return;
56 } 57 }
57 let m = p.start(); 58 block_expr(p);
58 p.bump();
59 while !p.at(EOF) && !p.at(R_CURLY) {
60 match p.current() {
61 LET_KW => let_stmt(p),
62 c => {
63 // test block_items
64 // fn a() { fn b() {} }
65 if items::ITEM_FIRST.contains(c) {
66 items::item(p)
67 } else {
68 let expr_stmt = p.start();
69 expressions::expr(p);
70 if p.eat(SEMI) {
71 expr_stmt.complete(p, EXPR_STMT);
72 } else {
73 expr_stmt.abandon(p);
74 }
75 }
76 }
77 }
78 }
79 p.expect(R_CURLY);
80 m.complete(p, BLOCK);
81} 59}
82 60
83// test let_stmt; 61// test let_stmt;
@@ -158,12 +136,14 @@ fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> {
158 if paths::is_path_start(p) { 136 if paths::is_path_start(p) {
159 return Some(path_expr(p)); 137 return Some(path_expr(p));
160 } 138 }
161 139 let la = p.nth(1);
162 let done = match p.current() { 140 let done = match p.current() {
163 L_PAREN => tuple_expr(p), 141 L_PAREN => tuple_expr(p),
164 PIPE => lambda_expr(p), 142 PIPE => lambda_expr(p),
165 MOVE_KW if p.nth(1) == PIPE => lambda_expr(p), 143 MOVE_KW if la == PIPE => lambda_expr(p),
166 IF_KW => if_expr(p), 144 IF_KW => if_expr(p),
145 UNSAFE_KW if la == L_CURLY => block_expr(p),
146 L_CURLY => block_expr(p),
167 _ => { 147 _ => {
168 p.err_and_bump("expected expression"); 148 p.err_and_bump("expected expression");
169 return None; 149 return None;
@@ -223,6 +203,40 @@ fn if_expr(p: &mut Parser) -> CompletedMarker {
223 m.complete(p, IF_EXPR) 203 m.complete(p, IF_EXPR)
224} 204}
225 205
206// test block_expr
207// fn foo() {
208// {};
209// unsafe {};
210// }
211fn block_expr(p: &mut Parser) -> CompletedMarker {
212 assert!(p.at(L_CURLY) || p.at(UNSAFE_KW) && p.nth(1) == L_CURLY);
213 let m = p.start();
214 p.eat(UNSAFE_KW);
215 p.bump();
216 while !p.at(EOF) && !p.at(R_CURLY) {
217 match p.current() {
218 LET_KW => let_stmt(p),
219 c => {
220 // test block_items
221 // fn a() { fn b() {} }
222 if items::ITEM_FIRST.contains(c) {
223 items::item(p)
224 } else {
225 let expr_stmt = p.start();
226 expressions::expr(p);
227 if p.eat(SEMI) {
228 expr_stmt.complete(p, EXPR_STMT);
229 } else {
230 expr_stmt.abandon(p);
231 }
232 }
233 }
234 }
235 }
236 p.expect(R_CURLY);
237 m.complete(p, BLOCK_EXPR)
238}
239
226// test call_expr 240// test call_expr
227// fn foo() { 241// fn foo() {
228// let _ = f(); 242// 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) {
44 // extern {} 44 // extern {}
45 L_CURLY => { 45 L_CURLY => {
46 extern_block(p); 46 extern_block(p);
47 EXTERN_BLOCK 47 EXTERN_BLOCK_EXPR
48 } 48 }
49 // test extern_struct 49 // test extern_struct
50 // extern struct Foo; 50 // 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 {
45 yellow::{SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot}, 45 yellow::{SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot},
46}; 46};
47 47
48
48pub fn parse(text: &str) -> SyntaxNode { 49pub fn parse(text: &str) -> SyntaxNode {
49 let tokens = tokenize(&text); 50 let tokens = tokenize(&text);
50 parser_impl::parse::<yellow::GreenBuilder>(text, &tokens) 51 parser_impl::parse::<yellow::GreenBuilder>(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 {
129 STRUCT_LIT, 129 STRUCT_LIT,
130 STRUCT_LIT_FIELD, 130 STRUCT_LIT_FIELD,
131 IF_EXPR, 131 IF_EXPR,
132 EXTERN_BLOCK, 132 EXTERN_BLOCK_EXPR,
133 ENUM_VARIANT, 133 ENUM_VARIANT,
134 NAMED_FIELD, 134 NAMED_FIELD,
135 POS_FIELD, 135 POS_FIELD,
@@ -145,7 +145,7 @@ pub enum SyntaxKind {
145 ABI, 145 ABI,
146 NAME, 146 NAME,
147 NAME_REF, 147 NAME_REF,
148 BLOCK, 148 BLOCK_EXPR,
149 LET_STMT, 149 LET_STMT,
150 EXPR_STMT, 150 EXPR_STMT,
151 TYPE_PARAM_LIST, 151 TYPE_PARAM_LIST,
@@ -336,7 +336,7 @@ impl SyntaxKind {
336 STRUCT_LIT => &SyntaxInfo { name: "STRUCT_LIT" }, 336 STRUCT_LIT => &SyntaxInfo { name: "STRUCT_LIT" },
337 STRUCT_LIT_FIELD => &SyntaxInfo { name: "STRUCT_LIT_FIELD" }, 337 STRUCT_LIT_FIELD => &SyntaxInfo { name: "STRUCT_LIT_FIELD" },
338 IF_EXPR => &SyntaxInfo { name: "IF_EXPR" }, 338 IF_EXPR => &SyntaxInfo { name: "IF_EXPR" },
339 EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, 339 EXTERN_BLOCK_EXPR => &SyntaxInfo { name: "EXTERN_BLOCK_EXPR" },
340 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, 340 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },
341 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, 341 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },
342 POS_FIELD => &SyntaxInfo { name: "POS_FIELD" }, 342 POS_FIELD => &SyntaxInfo { name: "POS_FIELD" },
@@ -352,7 +352,7 @@ impl SyntaxKind {
352 ABI => &SyntaxInfo { name: "ABI" }, 352 ABI => &SyntaxInfo { name: "ABI" },
353 NAME => &SyntaxInfo { name: "NAME" }, 353 NAME => &SyntaxInfo { name: "NAME" },
354 NAME_REF => &SyntaxInfo { name: "NAME_REF" }, 354 NAME_REF => &SyntaxInfo { name: "NAME_REF" },
355 BLOCK => &SyntaxInfo { name: "BLOCK" }, 355 BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" },
356 LET_STMT => &SyntaxInfo { name: "LET_STMT" }, 356 LET_STMT => &SyntaxInfo { name: "LET_STMT" },
357 EXPR_STMT => &SyntaxInfo { name: "EXPR_STMT" }, 357 EXPR_STMT => &SyntaxInfo { name: "EXPR_STMT" },
358 TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" }, 358 TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" },