aboutsummaryrefslogtreecommitdiff
path: root/src/grammar/expressions/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/grammar/expressions/mod.rs')
-rw-r--r--src/grammar/expressions/mod.rs33
1 files changed, 28 insertions, 5 deletions
diff --git a/src/grammar/expressions/mod.rs b/src/grammar/expressions/mod.rs
index 55e965ff4..ce709dbb2 100644
--- a/src/grammar/expressions/mod.rs
+++ b/src/grammar/expressions/mod.rs
@@ -5,14 +5,14 @@ pub(super) use self::atom::literal;
5 5
6const EXPR_FIRST: TokenSet = LHS_FIRST; 6const EXPR_FIRST: TokenSet = LHS_FIRST;
7 7
8pub(super) fn expr(p: &mut Parser) { 8pub(super) fn expr(p: &mut Parser) -> BlockLike {
9 let r = Restrictions { forbid_structs: false }; 9 let r = Restrictions { forbid_structs: false };
10 expr_bp(p, r, 1) 10 expr_bp(p, r, 1)
11} 11}
12 12
13fn expr_no_struct(p: &mut Parser) { 13fn expr_no_struct(p: &mut Parser) {
14 let r = Restrictions { forbid_structs: true }; 14 let r = Restrictions { forbid_structs: true };
15 expr_bp(p, r, 1) 15 expr_bp(p, r, 1);
16} 16}
17 17
18// test block 18// test block
@@ -85,10 +85,14 @@ fn current_op(p: &Parser) -> (u8, Op) {
85} 85}
86 86
87// Parses expression with binding power of at least bp. 87// Parses expression with binding power of at least bp.
88fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) { 88fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> BlockLike {
89 let mut block: bool;
89 let mut lhs = match lhs(p, r) { 90 let mut lhs = match lhs(p, r) {
90 Some(lhs) => lhs, 91 Some(lhs) => {
91 None => return, 92 block = is_block(lhs.kind());
93 lhs
94 },
95 None => return BlockLike::NotBlock,
92 }; 96 };
93 97
94 loop { 98 loop {
@@ -97,6 +101,7 @@ fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) {
97 if op_bp < bp { 101 if op_bp < bp {
98 break; 102 break;
99 } 103 }
104 block = false;
100 let m = lhs.precede(p); 105 let m = lhs.precede(p);
101 match op { 106 match op {
102 Op::Simple => p.bump(), 107 Op::Simple => p.bump(),
@@ -107,6 +112,24 @@ fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) {
107 expr_bp(p, r, op_bp + 1); 112 expr_bp(p, r, op_bp + 1);
108 lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR }); 113 lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR });
109 } 114 }
115 if block { BlockLike::Block } else { BlockLike::NotBlock }
116}
117
118// test no_semi_after_block
119// fn foo() {
120// if true {}
121// loop {}
122// match () {}
123// while true {}
124// for _ in () {}
125// {}
126// {}
127// }
128fn is_block(kind: SyntaxKind) -> bool {
129 match kind {
130 IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR => true,
131 _ => false,
132 }
110} 133}
111 134
112const LHS_FIRST: TokenSet = 135const LHS_FIRST: TokenSet =