diff options
Diffstat (limited to 'crates/mbe')
-rw-r--r-- | crates/mbe/src/expander/matcher.rs | 120 |
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 { | |||
162 | impl BindingsBuilder { | 162 | impl 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 | ||