aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe/src/mbe_expander.rs
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2019-04-24 16:01:32 +0100
committerEdwin Cheng <[email protected]>2019-04-25 19:03:55 +0100
commit299d97b6d98cec673ff056c188ac45a17febc7d4 (patch)
treecaec1cdbcd6350d26ebe984b3eca177079aa02b3 /crates/ra_mbe/src/mbe_expander.rs
parentdfab545d5df974d4a50325695a25f763b7613baf (diff)
Add handling `token` seperator in mbe
Diffstat (limited to 'crates/ra_mbe/src/mbe_expander.rs')
-rw-r--r--crates/ra_mbe/src/mbe_expander.rs49
1 files changed, 39 insertions, 10 deletions
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs
index 91b6db522..7411dd8b1 100644
--- a/crates/ra_mbe/src/mbe_expander.rs
+++ b/crates/ra_mbe/src/mbe_expander.rs
@@ -196,6 +196,7 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings,
196 "literal" => { 196 "literal" => {
197 let literal = 197 let literal =
198 input.eat_literal().ok_or(ExpandError::UnexpectedToken)?.clone(); 198 input.eat_literal().ok_or(ExpandError::UnexpectedToken)?.clone();
199
199 res.inner.insert( 200 res.inner.insert(
200 text.clone(), 201 text.clone(),
201 Binding::Simple(tt::Leaf::from(literal).into()), 202 Binding::Simple(tt::Leaf::from(literal).into()),
@@ -210,7 +211,7 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings,
210 } 211 }
211 } 212 }
212 crate::Leaf::Punct(punct) => { 213 crate::Leaf::Punct(punct) => {
213 if input.eat_punct() != Some(punct) { 214 if !input.eat_punct().map(|p| p.char == punct.char).unwrap_or(false) {
214 return Err(ExpandError::UnexpectedToken); 215 return Err(ExpandError::UnexpectedToken);
215 } 216 }
216 } 217 }
@@ -246,8 +247,23 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings,
246 } 247 }
247 } 248 }
248 249
249 if let Some(separator) = *separator { 250 if let Some(separator) = separator {
250 if input.eat_punct().map(|p| p.char) != Some(separator) { 251 use crate::Separator::*;
252
253 if !input
254 .eat_seperator()
255 .map(|sep| match (sep, separator) {
256 (Ident(ref a), Ident(ref b)) => a.text == b.text,
257 (Literal(ref a), Literal(ref b)) => a.text == b.text,
258 (Puncts(ref a), Puncts(ref b)) if a.len() == b.len() => {
259 let a_iter = a.iter().map(|a| a.char);
260 let b_iter = b.iter().map(|b| b.char);
261 a_iter.eq(b_iter)
262 }
263 _ => false,
264 })
265 .unwrap_or(false)
266 {
251 input.rollback(memento); 267 input.rollback(memento);
252 break; 268 break;
253 } 269 }
@@ -328,7 +344,7 @@ fn expand_tt(
328 // Dirty hack to make macro-expansion terminate. 344 // Dirty hack to make macro-expansion terminate.
329 // This should be replaced by a propper macro-by-example implementation 345 // This should be replaced by a propper macro-by-example implementation
330 let mut limit = 128; 346 let mut limit = 128;
331 let mut has_sep = false; 347 let mut has_seps = 0;
332 348
333 while let Ok(t) = expand_subtree(&repeat.subtree, bindings, nesting) { 349 while let Ok(t) = expand_subtree(&repeat.subtree, bindings, nesting) {
334 limit -= 1; 350 limit -= 1;
@@ -339,15 +355,28 @@ fn expand_tt(
339 nesting.push(idx + 1); 355 nesting.push(idx + 1);
340 token_trees.push(reduce_single_token(t).into()); 356 token_trees.push(reduce_single_token(t).into());
341 357
342 if let Some(sep) = repeat.separator { 358 if let Some(ref sep) = repeat.separator {
343 let punct = 359 match sep {
344 tt::Leaf::from(tt::Punct { char: sep, spacing: tt::Spacing::Alone }); 360 crate::Separator::Ident(ident) => {
345 token_trees.push(punct.into()); 361 has_seps = 1;
346 has_sep = true; 362 token_trees.push(tt::Leaf::from(ident.clone()).into());
363 }
364 crate::Separator::Literal(lit) => {
365 has_seps = 1;
366 token_trees.push(tt::Leaf::from(lit.clone()).into());
367 }
368
369 crate::Separator::Puncts(puncts) => {
370 has_seps = puncts.len();
371 for punct in puncts {
372 token_trees.push(tt::Leaf::from(*punct).into());
373 }
374 }
375 }
347 } 376 }
348 } 377 }
349 nesting.pop().unwrap(); 378 nesting.pop().unwrap();
350 if has_sep { 379 for _ in 0..has_seps {
351 token_trees.pop(); 380 token_trees.pop();
352 } 381 }
353 382