From 1446d620c5a8865708b238550e4c0457577a0cd1 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Thu, 2 May 2019 23:23:14 +0800 Subject: Add empty bindings and some refactoring --- crates/ra_mbe/src/lib.rs | 20 +++++++++++++++++- crates/ra_mbe/src/mbe_expander.rs | 43 ++++++++++++++++++++------------------- 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs index be9ea3ebb..08bb89a6a 100644 --- a/crates/ra_mbe/src/lib.rs +++ b/crates/ra_mbe/src/lib.rs @@ -99,13 +99,31 @@ pub(crate) struct Subtree { pub(crate) token_trees: Vec, } -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, Eq)] pub(crate) enum Separator { Literal(tt::Literal), Ident(tt::Ident), Puncts(SmallVec<[tt::Punct; 3]>), } +// Note that when we compare a Separator, we just care about its textual value. +impl PartialEq for crate::Separator { + fn eq(&self, other: &crate::Separator) -> bool { + use crate::Separator::*; + + match (self, other) { + (Ident(ref a), Ident(ref b)) => a == b, + (Literal(ref a), Literal(ref b)) => a == b, + (Puncts(ref a), Puncts(ref b)) if a.len() == b.len() => { + let a_iter = a.iter().map(|a| a.char); + let b_iter = b.iter().map(|b| b.char); + a_iter.eq(b_iter) + } + _ => false, + } + } +} + #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) struct Repeat { pub(crate) subtree: Subtree, diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs index 1b579f319..087a0cd63 100644 --- a/crates/ra_mbe/src/mbe_expander.rs +++ b/crates/ra_mbe/src/mbe_expander.rs @@ -107,13 +107,19 @@ impl Bindings { } } - fn push_nested(&mut self, nested: Bindings) -> Result<(), ExpandError> { + fn push_nested(&mut self, idx: usize, nested: Bindings) -> Result<(), ExpandError> { for (key, value) in nested.inner { if !self.inner.contains_key(&key) { self.inner.insert(key.clone(), Binding::Nested(Vec::new())); } match self.inner.get_mut(&key) { - Some(Binding::Nested(it)) => it.push(value), + Some(Binding::Nested(it)) => { + // insert empty nested bindings before this one + while it.len() < idx { + it.push(Binding::Nested(vec![])); + } + it.push(value); + } _ => { return Err(ExpandError::BindingError(format!( "could not find binding `{}`", @@ -178,10 +184,6 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result { let token = input.eat().ok_or(ExpandError::UnexpectedToken)?.clone(); res.inner.insert(text.clone(), Binding::Simple(token.into())); @@ -252,7 +254,6 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result { - counter += 1; limit -= 1; if limit == 0 { log::warn!("match_lhs excced in repeat pattern exceed limit => {:#?}\n{:#?}\n{:#?}\n{:#?}", subtree, input, kind, separator); @@ -260,7 +261,8 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result Result a.text == b.text, - (Literal(ref a), Literal(ref b)) => a.text == b.text, - (Puncts(ref a), Puncts(ref b)) if a.len() == b.len() => { - let a_iter = a.iter().map(|a| a.char); - let b_iter = b.iter().map(|b| b.char); - a_iter.eq(b_iter) - } - _ => false, - }) + .map(|sep| sep == *separator) .unwrap_or(false) { input.rollback(memento); @@ -372,7 +363,13 @@ fn expand_tt( let mut has_seps = 0; let mut counter = 0; + // We store the old var expaned value, and restore it later + // It is because before this `$repeat`, + // it is possible some variables already expanad in the same subtree + // + // `some_var_expanded` keep check if the deeper subtree has expanded variables let mut some_var_expanded = false; + let old_var_expanded = ctx.var_expanded; ctx.var_expanded = false; while let Ok(t) = expand_subtree(&repeat.subtree, ctx) { @@ -380,6 +377,9 @@ fn expand_tt( if !ctx.var_expanded { break; } + + // Reset `ctx.var_expaneded` to see if there is other expaned variable + // in the next matching some_var_expanded = true; ctx.var_expanded = false; @@ -423,7 +423,8 @@ fn expand_tt( } } - ctx.var_expanded = some_var_expanded; + // Restore the `var_expanded` by combining old one and the new one + ctx.var_expanded = some_var_expanded || old_var_expanded; ctx.nesting.pop().unwrap(); for _ in 0..has_seps { -- cgit v1.2.3 From 91745c62f82e8e7aef214edb898497f853bf9c93 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Thu, 2 May 2019 23:59:13 +0800 Subject: Compare text instead --- crates/ra_mbe/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs index 08bb89a6a..a2dce9c8a 100644 --- a/crates/ra_mbe/src/lib.rs +++ b/crates/ra_mbe/src/lib.rs @@ -112,8 +112,8 @@ impl PartialEq for crate::Separator { use crate::Separator::*; match (self, other) { - (Ident(ref a), Ident(ref b)) => a == b, - (Literal(ref a), Literal(ref b)) => a == b, + (Ident(ref a), Ident(ref b)) => a.text == b.text, + (Literal(ref a), Literal(ref b)) => a.text == b.text, (Puncts(ref a), Puncts(ref b)) if a.len() == b.len() => { let a_iter = a.iter().map(|a| a.char); let b_iter = b.iter().map(|b| b.char); -- cgit v1.2.3 From ab91050d49e538568f0be1f9f5b8fe90e20e2ac0 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Fri, 3 May 2019 00:01:48 +0800 Subject: Fix typo --- crates/ra_mbe/src/mbe_expander.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs index 087a0cd63..361b1e404 100644 --- a/crates/ra_mbe/src/mbe_expander.rs +++ b/crates/ra_mbe/src/mbe_expander.rs @@ -363,7 +363,7 @@ fn expand_tt( let mut has_seps = 0; let mut counter = 0; - // We store the old var expaned value, and restore it later + // We store the old var expanded value, and restore it later // It is because before this `$repeat`, // it is possible some variables already expanad in the same subtree // @@ -373,12 +373,12 @@ fn expand_tt( ctx.var_expanded = false; while let Ok(t) = expand_subtree(&repeat.subtree, ctx) { - // if no var expaned in the child, we count it as a fail + // if no var expanded in the child, we count it as a fail if !ctx.var_expanded { break; } - // Reset `ctx.var_expaneded` to see if there is other expaned variable + // Reset `ctx.var_expandeded` to see if there is other expanded variable // in the next matching some_var_expanded = true; ctx.var_expanded = false; -- cgit v1.2.3 From 11d6a1449de1ae4284fe73d9955d29ae6eea2356 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Fri, 3 May 2019 00:20:27 +0800 Subject: Fixed old incorrect test --- crates/ra_mbe/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ra_mbe/src/lib.rs b/crates/ra_mbe/src/lib.rs index a2dce9c8a..ea2104b1c 100644 --- a/crates/ra_mbe/src/lib.rs +++ b/crates/ra_mbe/src/lib.rs @@ -1288,6 +1288,6 @@ cfg_if ! { } } "#, - "__cfg_if_items ! {() ; (() (mod libunwind ; pub use libunwind :: * ;)) ,}"); + "__cfg_if_items ! {() ; ((target_env = \"msvc\") ()) , ((all (target_arch = \"wasm32\" , not (target_os = \"emscripten\"))) ()) , (() (mod libunwind ; pub use libunwind :: * ;)) ,}"); } } -- cgit v1.2.3