aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/grammar.ron2
-rw-r--r--src/grammar/expressions.rs35
-rw-r--r--src/syntax_kinds/generated.rs6
-rw-r--r--tests/data/lexer/0011_keywords.rs2
-rw-r--r--tests/data/lexer/0011_keywords.txt2
-rw-r--r--tests/data/parser/err/0008_item_block_recovery.txt2
-rw-r--r--tests/data/parser/inline/0065_if_expr.rs5
-rw-r--r--tests/data/parser/inline/0065_if_expr.txt73
8 files changed, 120 insertions, 7 deletions
diff --git a/src/grammar.ron b/src/grammar.ron
index a9a3847c9..9912f9698 100644
--- a/src/grammar.ron
+++ b/src/grammar.ron
@@ -60,6 +60,7 @@ Grammar(
60 "loop", 60 "loop",
61 "while", 61 "while",
62 "if", 62 "if",
63 "else",
63 "match", 64 "match",
64 "const", 65 "const",
65 "static", 66 "static",
@@ -134,6 +135,7 @@ Grammar(
134 "LAMBDA_EXPR", 135 "LAMBDA_EXPR",
135 "STRUCT_LIT", 136 "STRUCT_LIT",
136 "STRUCT_LIT_FIELD", 137 "STRUCT_LIT_FIELD",
138 "IF_EXPR",
137 139
138 "EXTERN_BLOCK", 140 "EXTERN_BLOCK",
139 "ENUM_VARIANT", 141 "ENUM_VARIANT",
diff --git a/src/grammar/expressions.rs b/src/grammar/expressions.rs
index e2be13a77..ed9236b02 100644
--- a/src/grammar/expressions.rs
+++ b/src/grammar/expressions.rs
@@ -145,14 +145,16 @@ fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> {
145 return Some(path_expr(p)); 145 return Some(path_expr(p));
146 } 146 }
147 147
148 match p.current() { 148 let done = match p.current() {
149 L_PAREN => Some(tuple_expr(p)), 149 L_PAREN => tuple_expr(p),
150 PIPE => Some(lambda_expr(p)), 150 PIPE => lambda_expr(p),
151 IF_KW => if_expr(p),
151 _ => { 152 _ => {
152 p.err_and_bump("expected expression"); 153 p.err_and_bump("expected expression");
153 None 154 return None;
154 } 155 }
155 } 156 };
157 Some(done)
156} 158}
157 159
158fn tuple_expr(p: &mut Parser) -> CompletedMarker { 160fn tuple_expr(p: &mut Parser) -> CompletedMarker {
@@ -182,6 +184,29 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
182 m.complete(p, LAMBDA_EXPR) 184 m.complete(p, LAMBDA_EXPR)
183} 185}
184 186
187// test if_expr
188// fn foo() {
189// if true {};
190// if true {} else {};
191// if true {} else if false {} else {}
192// }
193fn if_expr(p: &mut Parser) -> CompletedMarker {
194 assert!(p.at(IF_KW));
195 let m = p.start();
196 p.bump();
197 expr(p);
198 block(p);
199 if p.at(ELSE_KW) {
200 p.bump();
201 if p.at(IF_KW) {
202 if_expr(p);
203 } else {
204 block(p);
205 }
206 }
207 m.complete(p, IF_EXPR)
208}
209
185// test call_expr 210// test call_expr
186// fn foo() { 211// fn foo() {
187// let _ = f(); 212// let _ = f();
diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs
index 2f7c29008..35d9640fa 100644
--- a/src/syntax_kinds/generated.rs
+++ b/src/syntax_kinds/generated.rs
@@ -61,6 +61,7 @@ pub enum SyntaxKind {
61 LOOP_KW, 61 LOOP_KW,
62 WHILE_KW, 62 WHILE_KW,
63 IF_KW, 63 IF_KW,
64 ELSE_KW,
64 MATCH_KW, 65 MATCH_KW,
65 CONST_KW, 66 CONST_KW,
66 STATIC_KW, 67 STATIC_KW,
@@ -125,6 +126,7 @@ pub enum SyntaxKind {
125 LAMBDA_EXPR, 126 LAMBDA_EXPR,
126 STRUCT_LIT, 127 STRUCT_LIT,
127 STRUCT_LIT_FIELD, 128 STRUCT_LIT_FIELD,
129 IF_EXPR,
128 EXTERN_BLOCK, 130 EXTERN_BLOCK,
129 ENUM_VARIANT, 131 ENUM_VARIANT,
130 NAMED_FIELD, 132 NAMED_FIELD,
@@ -223,6 +225,7 @@ impl SyntaxKind {
223 LOOP_KW => &SyntaxInfo { name: "LOOP_KW" }, 225 LOOP_KW => &SyntaxInfo { name: "LOOP_KW" },
224 WHILE_KW => &SyntaxInfo { name: "WHILE_KW" }, 226 WHILE_KW => &SyntaxInfo { name: "WHILE_KW" },
225 IF_KW => &SyntaxInfo { name: "IF_KW" }, 227 IF_KW => &SyntaxInfo { name: "IF_KW" },
228 ELSE_KW => &SyntaxInfo { name: "ELSE_KW" },
226 MATCH_KW => &SyntaxInfo { name: "MATCH_KW" }, 229 MATCH_KW => &SyntaxInfo { name: "MATCH_KW" },
227 CONST_KW => &SyntaxInfo { name: "CONST_KW" }, 230 CONST_KW => &SyntaxInfo { name: "CONST_KW" },
228 STATIC_KW => &SyntaxInfo { name: "STATIC_KW" }, 231 STATIC_KW => &SyntaxInfo { name: "STATIC_KW" },
@@ -287,6 +290,7 @@ impl SyntaxKind {
287 LAMBDA_EXPR => &SyntaxInfo { name: "LAMBDA_EXPR" }, 290 LAMBDA_EXPR => &SyntaxInfo { name: "LAMBDA_EXPR" },
288 STRUCT_LIT => &SyntaxInfo { name: "STRUCT_LIT" }, 291 STRUCT_LIT => &SyntaxInfo { name: "STRUCT_LIT" },
289 STRUCT_LIT_FIELD => &SyntaxInfo { name: "STRUCT_LIT_FIELD" }, 292 STRUCT_LIT_FIELD => &SyntaxInfo { name: "STRUCT_LIT_FIELD" },
293 IF_EXPR => &SyntaxInfo { name: "IF_EXPR" },
290 EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, 294 EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" },
291 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, 295 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },
292 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, 296 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },
@@ -344,6 +348,7 @@ impl SyntaxKind {
344 "loop" => LOOP_KW, 348 "loop" => LOOP_KW,
345 "while" => WHILE_KW, 349 "while" => WHILE_KW,
346 "if" => IF_KW, 350 "if" => IF_KW,
351 "else" => ELSE_KW,
347 "match" => MATCH_KW, 352 "match" => MATCH_KW,
348 "const" => CONST_KW, 353 "const" => CONST_KW,
349 "static" => STATIC_KW, 354 "static" => STATIC_KW,
@@ -445,6 +450,7 @@ impl SyntaxKind {
445 LOOP_KW => "loop", 450 LOOP_KW => "loop",
446 WHILE_KW => "while", 451 WHILE_KW => "while",
447 IF_KW => "if", 452 IF_KW => "if",
453 ELSE_KW => "else",
448 MATCH_KW => "match", 454 MATCH_KW => "match",
449 CONST_KW => "const", 455 CONST_KW => "const",
450 STATIC_KW => "static", 456 STATIC_KW => "static",
diff --git a/tests/data/lexer/0011_keywords.rs b/tests/data/lexer/0011_keywords.rs
index 97ff3f954..2a78b5dd2 100644
--- a/tests/data/lexer/0011_keywords.rs
+++ b/tests/data/lexer/0011_keywords.rs
@@ -1,3 +1,3 @@
1fn use struct trait enum impl true false as extern crate 1fn use struct trait enum impl true false as extern crate
2mod pub self super in where for loop while if match const 2mod pub self super in where for loop while if match const
3static mut type ref let 3static mut type ref let else
diff --git a/tests/data/lexer/0011_keywords.txt b/tests/data/lexer/0011_keywords.txt
index 851a671f5..e25d7d4b4 100644
--- a/tests/data/lexer/0011_keywords.txt
+++ b/tests/data/lexer/0011_keywords.txt
@@ -53,4 +53,6 @@ WHITESPACE 1 " "
53REF_KW 3 "ref" 53REF_KW 3 "ref"
54WHITESPACE 1 " " 54WHITESPACE 1 " "
55LET_KW 3 "let" 55LET_KW 3 "let"
56WHITESPACE 1 " "
57ELSE_KW 4 "else"
56WHITESPACE 1 "\n" 58WHITESPACE 1 "\n"
diff --git a/tests/data/parser/err/0008_item_block_recovery.txt b/tests/data/parser/err/0008_item_block_recovery.txt
index 40ce2bc1a..81a5dd4c3 100644
--- a/tests/data/parser/err/0008_item_block_recovery.txt
+++ b/tests/data/parser/err/0008_item_block_recovery.txt
@@ -37,7 +37,7 @@ FILE@[0; 95)
37 WHITESPACE@[45; 50) 37 WHITESPACE@[45; 50)
38 R_CURLY@[50; 51) 38 R_CURLY@[50; 51)
39 WHITESPACE@[51; 52) 39 WHITESPACE@[51; 52)
40 IDENT@[52; 56) "else" 40 ELSE_KW@[52; 56)
41 WHITESPACE@[56; 57) 41 WHITESPACE@[56; 57)
42 L_CURLY@[57; 58) 42 L_CURLY@[57; 58)
43 WHITESPACE@[58; 67) 43 WHITESPACE@[58; 67)
diff --git a/tests/data/parser/inline/0065_if_expr.rs b/tests/data/parser/inline/0065_if_expr.rs
new file mode 100644
index 000000000..f1691c159
--- /dev/null
+++ b/tests/data/parser/inline/0065_if_expr.rs
@@ -0,0 +1,5 @@
1fn foo() {
2 if true {};
3 if true {} else {};
4 if true {} else if false {} else {}
5}
diff --git a/tests/data/parser/inline/0065_if_expr.txt b/tests/data/parser/inline/0065_if_expr.txt
new file mode 100644
index 000000000..5d9bdfb13
--- /dev/null
+++ b/tests/data/parser/inline/0065_if_expr.txt
@@ -0,0 +1,73 @@
1FILE@[0; 93)
2 FN_ITEM@[0; 93)
3 FN_KW@[0; 2)
4 NAME@[2; 6)
5 WHITESPACE@[2; 3)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 9)
8 L_PAREN@[6; 7)
9 R_PAREN@[7; 8)
10 WHITESPACE@[8; 9)
11 BLOCK@[9; 93)
12 L_CURLY@[9; 10)
13 EXPR_STMT@[10; 31)
14 IF_EXPR@[10; 25)
15 WHITESPACE@[10; 15)
16 IF_KW@[15; 17)
17 LITERAL@[17; 23)
18 WHITESPACE@[17; 18)
19 TRUE_KW@[18; 22)
20 WHITESPACE@[22; 23)
21 BLOCK@[23; 25)
22 L_CURLY@[23; 24)
23 R_CURLY@[24; 25)
24 SEMI@[25; 26)
25 WHITESPACE@[26; 31)
26 EXPR_STMT@[31; 55)
27 IF_EXPR@[31; 49)
28 IF_KW@[31; 33)
29 LITERAL@[33; 39)
30 WHITESPACE@[33; 34)
31 TRUE_KW@[34; 38)
32 WHITESPACE@[38; 39)
33 BLOCK@[39; 42)
34 L_CURLY@[39; 40)
35 R_CURLY@[40; 41)
36 WHITESPACE@[41; 42)
37 ELSE_KW@[42; 46)
38 BLOCK@[46; 49)
39 WHITESPACE@[46; 47)
40 L_CURLY@[47; 48)
41 R_CURLY@[48; 49)
42 SEMI@[49; 50)
43 WHITESPACE@[50; 55)
44 IF_EXPR@[55; 91)
45 IF_KW@[55; 57)
46 LITERAL@[57; 63)
47 WHITESPACE@[57; 58)
48 TRUE_KW@[58; 62)
49 WHITESPACE@[62; 63)
50 BLOCK@[63; 66)
51 L_CURLY@[63; 64)
52 R_CURLY@[64; 65)
53 WHITESPACE@[65; 66)
54 ELSE_KW@[66; 70)
55 IF_EXPR@[70; 91)
56 WHITESPACE@[70; 71)
57 IF_KW@[71; 73)
58 LITERAL@[73; 80)
59 WHITESPACE@[73; 74)
60 FALSE_KW@[74; 79)
61 WHITESPACE@[79; 80)
62 BLOCK@[80; 83)
63 L_CURLY@[80; 81)
64 R_CURLY@[81; 82)
65 WHITESPACE@[82; 83)
66 ELSE_KW@[83; 87)
67 BLOCK@[87; 91)
68 WHITESPACE@[87; 88)
69 L_CURLY@[88; 89)
70 R_CURLY@[89; 90)
71 WHITESPACE@[90; 91)
72 R_CURLY@[91; 92)
73 WHITESPACE@[92; 93)