aboutsummaryrefslogtreecommitdiff
path: root/crates/mbe
diff options
context:
space:
mode:
Diffstat (limited to 'crates/mbe')
-rw-r--r--crates/mbe/src/expander/matcher.rs120
1 files changed, 57 insertions, 63 deletions
diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs
index 54db76d5d..2c69e8968 100644
--- a/crates/mbe/src/expander/matcher.rs
+++ b/crates/mbe/src/expander/matcher.rs
@@ -162,9 +162,9 @@ struct BindingsBuilder {
162impl BindingsBuilder { 162impl BindingsBuilder {
163 fn alloc(&mut self) -> BindingsIdx { 163 fn alloc(&mut self) -> BindingsIdx {
164 let idx = self.nodes.len(); 164 let idx = self.nodes.len();
165 self.nodes.push(Vec::with_capacity(8)); 165 self.nodes.push(Vec::new());
166 let nidx = self.nested.len(); 166 let nidx = self.nested.len();
167 self.nested.push(Vec::with_capacity(8)); 167 self.nested.push(Vec::new());
168 BindingsIdx(idx, nidx) 168 BindingsIdx(idx, nidx)
169 } 169 }
170 170
@@ -182,11 +182,8 @@ impl BindingsBuilder {
182 if len < 4 { 182 if len < 4 {
183 target.push(target[idx].clone()) 183 target.push(target[idx].clone())
184 } else { 184 } else {
185 let mut item = Vec::with_capacity(8); 185 target.push(vec![LinkNode::Parent { idx, len }]);
186 item.push(LinkNode::Parent { idx, len });
187 target.push(item);
188 } 186 }
189
190 new_idx 187 new_idx
191 } 188 }
192 } 189 }
@@ -212,19 +209,22 @@ impl BindingsBuilder {
212 fn push_default(&mut self, idx: &mut BindingsIdx) { 209 fn push_default(&mut self, idx: &mut BindingsIdx) {
213 self.nested[idx.1].push(LinkNode::Node(idx.0)); 210 self.nested[idx.1].push(LinkNode::Node(idx.0));
214 let new_idx = self.nodes.len(); 211 let new_idx = self.nodes.len();
215 self.nodes.push(Vec::with_capacity(8)); 212 self.nodes.push(Vec::new());
216 idx.0 = new_idx; 213 idx.0 = new_idx;
217 } 214 }
218 215
219 fn build(self, idx: &BindingsIdx) -> Bindings { 216 fn build(self, idx: &BindingsIdx) -> Bindings {
220 let mut bindings = Bindings::default(); 217 let mut bindings = Bindings::default();
221 self.build_recur(&mut bindings, self.nodes[idx.0].clone()); 218 self.build_inner(&mut bindings, &self.nodes[idx.0]);
222 bindings 219 bindings
223 } 220 }
224 221
225 fn build_recur(&self, bindings: &mut Bindings, nodes: Vec<LinkNode<Rc<BindingKind>>>) { 222 fn build_inner(&self, bindings: &mut Bindings, link_nodes: &Vec<LinkNode<Rc<BindingKind>>>) {
226 for cmd in self.flatten_nodes(nodes) { 223 let mut nodes = Vec::new();
227 match &*cmd { 224 self.collect_nodes(&link_nodes, &mut nodes);
225
226 for cmd in nodes {
227 match &**cmd {
228 BindingKind::Empty(name) => { 228 BindingKind::Empty(name) => {
229 bindings.push_empty(name); 229 bindings.push_empty(name);
230 } 230 }
@@ -234,10 +234,11 @@ impl BindingsBuilder {
234 BindingKind::Fragment(name, fragment) => { 234 BindingKind::Fragment(name, fragment) => {
235 bindings.inner.insert(name.clone(), Binding::Fragment(fragment.clone())); 235 bindings.inner.insert(name.clone(), Binding::Fragment(fragment.clone()));
236 } 236 }
237 BindingKind::Nested(idx, list) => { 237 BindingKind::Nested(idx, nested_idx) => {
238 let list = self.flatten_nested(*idx, *list); 238 let mut nested_nodes = Vec::new();
239 self.collect_nested(*idx, *nested_idx, &mut nested_nodes);
239 240
240 for (idx, iter) in list.enumerate() { 241 for (idx, iter) in nested_nodes.into_iter().enumerate() {
241 for (key, value) in &iter.inner { 242 for (key, value) in &iter.inner {
242 let bindings = bindings 243 let bindings = bindings
243 .inner 244 .inner
@@ -258,62 +259,55 @@ impl BindingsBuilder {
258 } 259 }
259 } 260 }
260 261
261 fn flatten_nested_ref(&self, id: usize, len: usize) -> Vec<Vec<LinkNode<Rc<BindingKind>>>> { 262 fn collect_nested_ref<'a>(
262 self.nested[id] 263 &'a self,
263 .iter() 264 id: usize,
264 .take(len) 265 len: usize,
265 .map(|it| match it { 266 nested_refs: &mut Vec<&'a Vec<LinkNode<Rc<BindingKind>>>>,
266 LinkNode::Node(id) => vec![self.nodes[*id].clone()], 267 ) {
267 LinkNode::Parent { idx, len } => self.flatten_nested_ref(*idx, *len), 268 self.nested[id].iter().take(len).for_each(|it| match it {
268 }) 269 LinkNode::Node(id) => nested_refs.push(&self.nodes[*id]),
269 .flatten() 270 LinkNode::Parent { idx, len } => self.collect_nested_ref(*idx, *len, nested_refs),
270 .collect() 271 });
271 } 272 }
272 273
273 fn flatten_nested<'a>( 274 fn collect_nested(&self, idx: usize, nested_idx: usize, nested: &mut Vec<Bindings>) {
274 &'a self, 275 let last = &self.nodes[idx];
275 idx: usize, 276 let mut nested_refs = Vec::new();
276 list: usize, 277 self.nested[nested_idx].iter().for_each(|it| match *it {
277 ) -> impl Iterator<Item = Bindings> + 'a { 278 LinkNode::Node(idx) => nested_refs.push(&self.nodes[idx]),
278 let last = self.nodes[idx].clone(); 279 LinkNode::Parent { idx, len } => self.collect_nested_ref(idx, len, &mut nested_refs),
279 self.nested[list] 280 });
280 .iter() 281 nested_refs.push(last);
281 .map(move |it| match *it { 282
282 LinkNode::Node(idx) => vec![self.nodes[idx].clone()], 283 nested_refs.into_iter().for_each(|iter| {
283 LinkNode::Parent { idx, len } => self.flatten_nested_ref(idx, len), 284 let mut child_bindings = Bindings::default();
284 }) 285 self.build_inner(&mut child_bindings, &iter);
285 .flatten() 286 nested.push(child_bindings)
286 .chain(std::iter::once(last)) 287 })
287 .map(move |iter| {
288 let mut child_bindings = Bindings::default();
289 self.build_recur(&mut child_bindings, iter);
290 child_bindings
291 })
292 } 288 }
293 289
294 fn flatten_nodes_ref(&self, id: usize, len: usize) -> Vec<Rc<BindingKind>> { 290 fn collect_nodes_ref<'a>(
295 self.nodes[id] 291 &'a self,
296 .iter() 292 id: usize,
297 .take(len) 293 len: usize,
298 .map(|it| match it { 294 nodes: &mut Vec<&'a Rc<BindingKind>>,
299 LinkNode::Node(it) => vec![it.clone()], 295 ) {
300 LinkNode::Parent { idx, len } => self.flatten_nodes_ref(*idx, *len), 296 self.nodes[id].iter().take(len).for_each(|it| match it {
301 }) 297 LinkNode::Node(it) => nodes.push(it),
302 .flatten() 298 LinkNode::Parent { idx, len } => self.collect_nodes_ref(*idx, *len, nodes),
303 .collect() 299 });
304 } 300 }
305 301
306 fn flatten_nodes<'a>( 302 fn collect_nodes<'a>(
307 &'a self, 303 &'a self,
308 nodes: Vec<LinkNode<Rc<BindingKind>>>, 304 link_nodes: &'a Vec<LinkNode<Rc<BindingKind>>>,
309 ) -> impl Iterator<Item = Rc<BindingKind>> + 'a { 305 nodes: &mut Vec<&'a Rc<BindingKind>>,
310 nodes 306 ) {
311 .into_iter() 307 link_nodes.into_iter().for_each(|it| match it {
312 .map(move |it| match it { 308 LinkNode::Node(it) => nodes.push(it),
313 LinkNode::Node(it) => vec![it], 309 LinkNode::Parent { idx, len } => self.collect_nodes_ref(*idx, *len, nodes),
314 LinkNode::Parent { idx, len } => self.flatten_nodes_ref(idx, len), 310 });
315 })
316 .flatten()
317 } 311 }
318} 312}
319 313