diff options
author | Aleksey Kladov <[email protected]> | 2018-08-05 16:07:06 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-05 16:07:06 +0100 |
commit | b0291cd8c2ec1d6d164caaa743f7484416e9b3f5 (patch) | |
tree | 57a2b21085bf0996d37c3f8d757f0332c5055a5a /src | |
parent | 80fa861cd688c8e7c92e27feaf6623ecfaa4901e (diff) |
Range expr
Diffstat (limited to 'src')
-rw-r--r-- | src/grammar.ron | 1 | ||||
-rw-r--r-- | src/grammar/expressions/mod.rs | 37 | ||||
-rw-r--r-- | src/syntax_kinds/generated.rs | 2 |
3 files changed, 32 insertions, 8 deletions
diff --git a/src/grammar.ron b/src/grammar.ron index 1eb76abdd..9e122091b 100644 --- a/src/grammar.ron +++ b/src/grammar.ron | |||
@@ -163,6 +163,7 @@ Grammar( | |||
163 | "DEREF_EXPR", | 163 | "DEREF_EXPR", |
164 | "NOT_EXPR", | 164 | "NOT_EXPR", |
165 | 165 | ||
166 | "RANGE_EXPR", // just weird | ||
166 | "BIN_EXPR", | 167 | "BIN_EXPR", |
167 | 168 | ||
168 | 169 | ||
diff --git a/src/grammar/expressions/mod.rs b/src/grammar/expressions/mod.rs index 7f3bc78f2..0312a757a 100644 --- a/src/grammar/expressions/mod.rs +++ b/src/grammar/expressions/mod.rs | |||
@@ -44,6 +44,13 @@ enum Op { | |||
44 | // *x = 1 + 1; | 44 | // *x = 1 + 1; |
45 | // } | 45 | // } |
46 | 46 | ||
47 | // test range_binding_power | ||
48 | // fn foo() { | ||
49 | // .. 1 + 1; | ||
50 | // .. z = 2; | ||
51 | // x = false .. 1 == 1; | ||
52 | // } | ||
53 | |||
47 | // test compound_ops | 54 | // test compound_ops |
48 | // fn foo() { | 55 | // fn foo() { |
49 | // x += 1; | 56 | // x += 1; |
@@ -52,10 +59,10 @@ enum Op { | |||
52 | // } | 59 | // } |
53 | fn current_op(p: &Parser) -> (u8, Op) { | 60 | fn current_op(p: &Parser) -> (u8, Op) { |
54 | if p.at_compound2(L_ANGLE, EQ) { | 61 | if p.at_compound2(L_ANGLE, EQ) { |
55 | return (2, Op::Composite(LTEQ, 2)); | 62 | return (3, Op::Composite(LTEQ, 2)); |
56 | } | 63 | } |
57 | if p.at_compound2(R_ANGLE, EQ) { | 64 | if p.at_compound2(R_ANGLE, EQ) { |
58 | return (2, Op::Composite(GTEQ, 2)); | 65 | return (3, Op::Composite(GTEQ, 2)); |
59 | } | 66 | } |
60 | if p.at_compound2(PLUS, EQ) { | 67 | if p.at_compound2(PLUS, EQ) { |
61 | return (1, Op::Composite(PLUSEQ, 2)); | 68 | return (1, Op::Composite(PLUSEQ, 2)); |
@@ -66,9 +73,10 @@ fn current_op(p: &Parser) -> (u8, Op) { | |||
66 | 73 | ||
67 | let bp = match p.current() { | 74 | let bp = match p.current() { |
68 | EQ => 1, | 75 | EQ => 1, |
69 | EQEQ | NEQ => 2, | 76 | DOTDOT => 2, |
70 | MINUS | PLUS => 3, | 77 | EQEQ | NEQ => 3, |
71 | STAR | SLASH => 4, | 78 | MINUS | PLUS => 4, |
79 | STAR | SLASH => 5, | ||
72 | _ => 0, | 80 | _ => 0, |
73 | }; | 81 | }; |
74 | (bp, Op::Simple) | 82 | (bp, Op::Simple) |
@@ -76,7 +84,7 @@ fn current_op(p: &Parser) -> (u8, Op) { | |||
76 | 84 | ||
77 | // Parses expression with binding power of at least bp. | 85 | // Parses expression with binding power of at least bp. |
78 | fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) { | 86 | fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) { |
79 | let mut lhs = match unary_expr(p, r) { | 87 | let mut lhs = match lhs(p, r) { |
80 | Some(lhs) => lhs, | 88 | Some(lhs) => lhs, |
81 | None => return, | 89 | None => return, |
82 | }; | 90 | }; |
@@ -102,7 +110,7 @@ const UNARY_EXPR_FIRST: TokenSet = | |||
102 | atom::ATOM_EXPR_FIRST, | 110 | atom::ATOM_EXPR_FIRST, |
103 | ]; | 111 | ]; |
104 | 112 | ||
105 | fn unary_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> { | 113 | fn lhs(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> { |
106 | let m; | 114 | let m; |
107 | let kind = match p.current() { | 115 | let kind = match p.current() { |
108 | // test ref_expr | 116 | // test ref_expr |
@@ -134,12 +142,18 @@ fn unary_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> { | |||
134 | p.bump(); | 142 | p.bump(); |
135 | NOT_EXPR | 143 | NOT_EXPR |
136 | } | 144 | } |
145 | DOTDOT => { | ||
146 | m = p.start(); | ||
147 | p.bump(); | ||
148 | expr_bp(p, r, 2); | ||
149 | return Some(m.complete(p, RANGE_EXPR)); | ||
150 | } | ||
137 | _ => { | 151 | _ => { |
138 | let lhs = atom::atom_expr(p, r)?; | 152 | let lhs = atom::atom_expr(p, r)?; |
139 | return Some(postfix_expr(p, lhs)); | 153 | return Some(postfix_expr(p, lhs)); |
140 | } | 154 | } |
141 | }; | 155 | }; |
142 | unary_expr(p, r); | 156 | expr_bp(p, r, 255); |
143 | Some(m.complete(p, kind)) | 157 | Some(m.complete(p, kind)) |
144 | } | 158 | } |
145 | 159 | ||
@@ -154,6 +168,13 @@ fn postfix_expr(p: &mut Parser, mut lhs: CompletedMarker) -> CompletedMarker { | |||
154 | field_expr(p, lhs) | 168 | field_expr(p, lhs) |
155 | }, | 169 | }, |
156 | DOT if p.nth(1) == INT_NUMBER => field_expr(p, lhs), | 170 | DOT if p.nth(1) == INT_NUMBER => field_expr(p, lhs), |
171 | // test postfix_range | ||
172 | // fn foo() { let x = 1..; } | ||
173 | DOTDOT if !EXPR_FIRST.contains(p.nth(1)) => { | ||
174 | let m = lhs.precede(p); | ||
175 | p.bump(); | ||
176 | m.complete(p, RANGE_EXPR) | ||
177 | } | ||
157 | QUESTION => try_expr(p, lhs), | 178 | QUESTION => try_expr(p, lhs), |
158 | _ => break, | 179 | _ => break, |
159 | } | 180 | } |
diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs index 8855e980e..8db006e54 100644 --- a/src/syntax_kinds/generated.rs +++ b/src/syntax_kinds/generated.rs | |||
@@ -148,6 +148,7 @@ pub enum SyntaxKind { | |||
148 | REF_EXPR, | 148 | REF_EXPR, |
149 | DEREF_EXPR, | 149 | DEREF_EXPR, |
150 | NOT_EXPR, | 150 | NOT_EXPR, |
151 | RANGE_EXPR, | ||
151 | BIN_EXPR, | 152 | BIN_EXPR, |
152 | EXTERN_BLOCK_EXPR, | 153 | EXTERN_BLOCK_EXPR, |
153 | ENUM_VARIANT, | 154 | ENUM_VARIANT, |
@@ -375,6 +376,7 @@ impl SyntaxKind { | |||
375 | REF_EXPR => &SyntaxInfo { name: "REF_EXPR" }, | 376 | REF_EXPR => &SyntaxInfo { name: "REF_EXPR" }, |
376 | DEREF_EXPR => &SyntaxInfo { name: "DEREF_EXPR" }, | 377 | DEREF_EXPR => &SyntaxInfo { name: "DEREF_EXPR" }, |
377 | NOT_EXPR => &SyntaxInfo { name: "NOT_EXPR" }, | 378 | NOT_EXPR => &SyntaxInfo { name: "NOT_EXPR" }, |
379 | RANGE_EXPR => &SyntaxInfo { name: "RANGE_EXPR" }, | ||
378 | BIN_EXPR => &SyntaxInfo { name: "BIN_EXPR" }, | 380 | BIN_EXPR => &SyntaxInfo { name: "BIN_EXPR" }, |
379 | EXTERN_BLOCK_EXPR => &SyntaxInfo { name: "EXTERN_BLOCK_EXPR" }, | 381 | EXTERN_BLOCK_EXPR => &SyntaxInfo { name: "EXTERN_BLOCK_EXPR" }, |
380 | ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, | 382 | ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, |