59
59
//! eof: [a $( a )* a b ·]
60
60
//! ```
61
61
62
+ use std:: rc:: Rc ;
63
+
62
64
use crate :: {
63
65
expander:: { Binding , Bindings , Fragment } ,
64
66
parser:: { Op , OpDelimited , OpDelimitedIter , RepeatKind , Separator } ,
@@ -76,43 +78,15 @@ impl Bindings {
76
78
// FIXME: Do we have a better way to represent an empty token ?
77
79
// Insert an empty subtree for empty token
78
80
let tt = tt:: Subtree :: default ( ) . into ( ) ;
79
- self . inner . push ( ( name. clone ( ) , Binding :: Fragment ( Fragment :: Tokens ( tt) ) ) ) ;
81
+ self . inner . insert ( name. clone ( ) , Binding :: Fragment ( Fragment :: Tokens ( tt) ) ) ;
80
82
}
81
83
82
84
fn push_empty ( & mut self , name : & SmolStr ) {
83
- self . inner . push ( ( name. clone ( ) , Binding :: Empty ) ) ;
84
- }
85
-
86
- fn push_nested ( & mut self , idx : usize , nested : Bindings ) -> Result < ( ) , ExpandError > {
87
- for ( key, value) in nested. inner {
88
- if self . get_mut ( & key) . is_none ( ) {
89
- self . inner . push ( ( key. clone ( ) , Binding :: Nested ( Vec :: new ( ) ) ) ) ;
90
- }
91
- match self . get_mut ( & key) {
92
- Some ( Binding :: Nested ( it) ) => {
93
- // insert empty nested bindings before this one
94
- while it. len ( ) < idx {
95
- it. push ( Binding :: Nested ( vec ! [ ] ) ) ;
96
- }
97
- it. push ( value) ;
98
- }
99
- _ => {
100
- return Err ( ExpandError :: BindingError ( format ! (
101
- "could not find binding `{}`" ,
102
- key
103
- ) ) ) ;
104
- }
105
- }
106
- }
107
- Ok ( ( ) )
108
- }
109
-
110
- fn get_mut ( & mut self , name : & str ) -> Option < & mut Binding > {
111
- self . inner . iter_mut ( ) . find_map ( |( n, b) | if n == name { Some ( b) } else { None } )
85
+ self . inner . insert ( name. clone ( ) , Binding :: Empty ) ;
112
86
}
113
87
114
88
fn bindings ( & self ) -> impl Iterator < Item = & Binding > {
115
- self . inner . iter ( ) . map ( | ( _ , b ) | b )
89
+ self . inner . values ( )
116
90
}
117
91
}
118
92
@@ -162,6 +136,187 @@ pub(super) fn match_(pattern: &MetaTemplate, input: &tt::Subtree) -> Match {
162
136
}
163
137
}
164
138
139
+ #[ derive( Debug , Clone ) ]
140
+ enum BindingKind {
141
+ Empty ( SmolStr ) ,
142
+ Optional ( SmolStr ) ,
143
+ Fragment ( SmolStr , Fragment ) ,
144
+ Nested ( usize , usize ) ,
145
+ }
146
+
147
+ #[ derive( Debug , Clone ) ]
148
+ struct BindingsIdx ( usize , usize ) ;
149
+
150
+ #[ derive( Debug , Clone ) ]
151
+ enum LinkNode < T > {
152
+ Node ( T ) ,
153
+ Parent { idx : usize , len : usize } ,
154
+ }
155
+
156
+ #[ derive( Default ) ]
157
+ struct BindingsBuilder {
158
+ nodes : Vec < Vec < LinkNode < Rc < BindingKind > > > > ,
159
+ nested : Vec < Vec < LinkNode < usize > > > ,
160
+ }
161
+
162
+ impl BindingsBuilder {
163
+ fn alloc ( & mut self ) -> BindingsIdx {
164
+ let idx = self . nodes . len ( ) ;
165
+ self . nodes . push ( Vec :: with_capacity ( 8 ) ) ;
166
+ let nidx = self . nested . len ( ) ;
167
+ self . nested . push ( Vec :: with_capacity ( 8 ) ) ;
168
+ BindingsIdx ( idx, nidx)
169
+ }
170
+
171
+ fn copy ( & mut self , bindings : & BindingsIdx ) -> BindingsIdx {
172
+ let idx = copy_parent ( bindings. 0 , & mut self . nodes ) ;
173
+ let nidx = copy_parent ( bindings. 1 , & mut self . nested ) ;
174
+ return BindingsIdx ( idx, nidx) ;
175
+
176
+ fn copy_parent < T > ( idx : usize , target : & mut Vec < Vec < LinkNode < T > > > ) -> usize
177
+ where
178
+ T : Clone ,
179
+ {
180
+ let new_idx = target. len ( ) ;
181
+ let len = target[ idx] . len ( ) ;
182
+ if len < 4 {
183
+ target. push ( target[ idx] . clone ( ) )
184
+ } else {
185
+ let mut item = Vec :: with_capacity ( 8 ) ;
186
+ item. push ( LinkNode :: Parent { idx, len } ) ;
187
+ target. push ( item) ;
188
+ }
189
+
190
+ new_idx
191
+ }
192
+ }
193
+
194
+ fn push_empty ( & mut self , idx : & mut BindingsIdx , var : & SmolStr ) {
195
+ self . nodes [ idx. 0 ] . push ( LinkNode :: Node ( Rc :: new ( BindingKind :: Empty ( var. clone ( ) ) ) ) ) ;
196
+ }
197
+
198
+ fn push_optional ( & mut self , idx : & mut BindingsIdx , var : & SmolStr ) {
199
+ self . nodes [ idx. 0 ] . push ( LinkNode :: Node ( Rc :: new ( BindingKind :: Optional ( var. clone ( ) ) ) ) ) ;
200
+ }
201
+
202
+ fn push_fragment ( & mut self , idx : & mut BindingsIdx , var : & SmolStr , fragment : Fragment ) {
203
+ self . nodes [ idx. 0 ]
204
+ . push ( LinkNode :: Node ( Rc :: new ( BindingKind :: Fragment ( var. clone ( ) , fragment) ) ) ) ;
205
+ }
206
+
207
+ fn push_nested ( & mut self , parent : & mut BindingsIdx , child : & BindingsIdx ) {
208
+ let BindingsIdx ( idx, nidx) = self . copy ( & child) ;
209
+ self . nodes [ parent. 0 ] . push ( LinkNode :: Node ( Rc :: new ( BindingKind :: Nested ( idx, nidx) ) ) ) ;
210
+ }
211
+
212
+ fn push_default ( & mut self , idx : & mut BindingsIdx ) {
213
+ self . nested [ idx. 1 ] . push ( LinkNode :: Node ( idx. 0 ) ) ;
214
+ let new_idx = self . nodes . len ( ) ;
215
+ self . nodes . push ( Vec :: with_capacity ( 8 ) ) ;
216
+ idx. 0 = new_idx;
217
+ }
218
+
219
+ fn build ( self , idx : & BindingsIdx ) -> Bindings {
220
+ let mut bindings = Bindings :: default ( ) ;
221
+ self . build_recur ( & mut bindings, self . nodes [ idx. 0 ] . clone ( ) ) ;
222
+ bindings
223
+ }
224
+
225
+ fn build_recur ( & self , bindings : & mut Bindings , nodes : Vec < LinkNode < Rc < BindingKind > > > ) {
226
+ for cmd in self . flatten_nodes ( nodes) {
227
+ match & * cmd {
228
+ BindingKind :: Empty ( name) => {
229
+ bindings. push_empty ( name) ;
230
+ }
231
+ BindingKind :: Optional ( name) => {
232
+ bindings. push_optional ( name) ;
233
+ }
234
+ BindingKind :: Fragment ( name, fragment) => {
235
+ bindings. inner . insert ( name. clone ( ) , Binding :: Fragment ( fragment. clone ( ) ) ) ;
236
+ }
237
+ BindingKind :: Nested ( idx, list) => {
238
+ let list = self . flatten_nested ( * idx, * list) ;
239
+
240
+ for ( idx, iter) in list. enumerate ( ) {
241
+ for ( key, value) in & iter. inner {
242
+ let bindings = bindings
243
+ . inner
244
+ . entry ( key. clone ( ) )
245
+ . or_insert_with ( || Binding :: Nested ( Vec :: new ( ) ) ) ;
246
+
247
+ if let Binding :: Nested ( it) = bindings {
248
+ // insert empty nested bindings before this one
249
+ while it. len ( ) < idx {
250
+ it. push ( Binding :: Nested ( Vec :: new ( ) ) ) ;
251
+ }
252
+ it. push ( value. clone ( ) ) ;
253
+ }
254
+ }
255
+ }
256
+ }
257
+ }
258
+ }
259
+ }
260
+
261
+ fn flatten_nested_ref ( & self , id : usize , len : usize ) -> Vec < Vec < LinkNode < Rc < BindingKind > > > > {
262
+ self . nested [ id]
263
+ . iter ( )
264
+ . take ( len)
265
+ . map ( |it| match it {
266
+ LinkNode :: Node ( id) => vec ! [ self . nodes[ * id] . clone( ) ] ,
267
+ LinkNode :: Parent { idx, len } => self . flatten_nested_ref ( * idx, * len) ,
268
+ } )
269
+ . flatten ( )
270
+ . collect ( )
271
+ }
272
+
273
+ fn flatten_nested < ' a > (
274
+ & ' a self ,
275
+ idx : usize ,
276
+ list : usize ,
277
+ ) -> impl Iterator < Item = Bindings > + ' a {
278
+ let last = self . nodes [ idx] . clone ( ) ;
279
+ self . nested [ list]
280
+ . iter ( )
281
+ . map ( move |it| match * it {
282
+ LinkNode :: Node ( idx) => vec ! [ self . nodes[ idx] . clone( ) ] ,
283
+ LinkNode :: Parent { idx, len } => self . flatten_nested_ref ( idx, len) ,
284
+ } )
285
+ . flatten ( )
286
+ . chain ( std:: iter:: once ( last) )
287
+ . map ( move |iter| {
288
+ let mut child_bindings = Bindings :: default ( ) ;
289
+ self . build_recur ( & mut child_bindings, iter) ;
290
+ child_bindings
291
+ } )
292
+ }
293
+
294
+ fn flatten_nodes_ref ( & self , id : usize , len : usize ) -> Vec < Rc < BindingKind > > {
295
+ self . nodes [ id]
296
+ . iter ( )
297
+ . take ( len)
298
+ . map ( |it| match it {
299
+ LinkNode :: Node ( it) => vec ! [ it. clone( ) ] ,
300
+ LinkNode :: Parent { idx, len } => self . flatten_nodes_ref ( * idx, * len) ,
301
+ } )
302
+ . flatten ( )
303
+ . collect ( )
304
+ }
305
+
306
+ fn flatten_nodes < ' a > (
307
+ & ' a self ,
308
+ nodes : Vec < LinkNode < Rc < BindingKind > > > ,
309
+ ) -> impl Iterator < Item = Rc < BindingKind > > + ' a {
310
+ nodes
311
+ . into_iter ( )
312
+ . map ( move |it| match it {
313
+ LinkNode :: Node ( it) => vec ! [ it] ,
314
+ LinkNode :: Parent { idx, len } => self . flatten_nodes_ref ( idx, len) ,
315
+ } )
316
+ . flatten ( )
317
+ }
318
+ }
319
+
165
320
#[ derive( Debug , Clone ) ]
166
321
struct MatchState < ' t > {
167
322
/// The position of the "dot" in this matcher
@@ -187,7 +342,7 @@ struct MatchState<'t> {
187
342
sep_parsed : Option < usize > ,
188
343
189
344
/// Matched meta variables bindings
190
- bindings : SmallVec < [ Bindings ; 4 ] > ,
345
+ bindings : BindingsIdx ,
191
346
192
347
/// Cached result of meta variable parsing
193
348
meta_result : Option < ( TtIter < ' t > , ExpandResult < Option < Fragment > > ) > ,
@@ -218,6 +373,7 @@ fn match_loop_inner<'t>(
218
373
src : TtIter < ' t > ,
219
374
stack : & [ TtIter < ' t > ] ,
220
375
res : & mut Match ,
376
+ bindings_builder : & mut BindingsBuilder ,
221
377
cur_items : & mut SmallVec < [ MatchState < ' t > ; 1 ] > ,
222
378
bb_items : & mut SmallVec < [ MatchState < ' t > ; 1 ] > ,
223
379
next_items : & mut Vec < MatchState < ' t > > ,
@@ -251,12 +407,10 @@ fn match_loop_inner<'t>(
251
407
if item. sep_parsed . is_none ( ) {
252
408
// Get the `up` matcher
253
409
let mut new_pos = * item. up . clone ( ) . unwrap ( ) ;
410
+ new_pos. bindings = bindings_builder. copy ( & new_pos. bindings ) ;
254
411
// Add matches from this repetition to the `matches` of `up`
255
- if let Some ( bindings) = new_pos. bindings . last_mut ( ) {
256
- for ( i, b) in item. bindings . iter_mut ( ) . enumerate ( ) {
257
- bindings. push_nested ( i, b. clone ( ) ) . unwrap ( ) ;
258
- }
259
- }
412
+ bindings_builder. push_nested ( & mut new_pos. bindings , & item. bindings ) ;
413
+
260
414
// Move the "dot" past the repetition in `up`
261
415
new_pos. dot . next ( ) ;
262
416
new_pos. is_error = new_pos. is_error || item. is_error ;
@@ -280,7 +434,7 @@ fn match_loop_inner<'t>(
280
434
else if item. sep_kind != Some ( RepeatKind :: ZeroOrOne ) {
281
435
item. dot = item. dot . reset ( ) ;
282
436
item. sep_parsed = None ;
283
- item. bindings . push ( Bindings :: default ( ) ) ;
437
+ bindings_builder . push_default ( & mut item. bindings ) ;
284
438
cur_items. push ( item) ;
285
439
}
286
440
} else {
@@ -298,12 +452,12 @@ fn match_loop_inner<'t>(
298
452
OpDelimited :: Op ( Op :: Repeat { tokens, kind, separator } ) => {
299
453
if matches ! ( kind, RepeatKind :: ZeroOrMore | RepeatKind :: ZeroOrOne ) {
300
454
let mut new_item = item. clone ( ) ;
455
+ new_item. bindings = bindings_builder. copy ( & new_item. bindings ) ;
301
456
new_item. dot . next ( ) ;
302
457
let mut vars = Vec :: new ( ) ;
303
- let bindings = new_item. bindings . last_mut ( ) . unwrap ( ) ;
304
458
collect_vars ( & mut vars, tokens) ;
305
459
for var in vars {
306
- bindings . push_empty ( & var) ;
460
+ bindings_builder . push_empty ( & mut new_item . bindings , & var) ;
307
461
}
308
462
cur_items. push ( new_item) ;
309
463
}
@@ -314,7 +468,7 @@ fn match_loop_inner<'t>(
314
468
sep : separator. clone ( ) ,
315
469
sep_kind : Some ( * kind) ,
316
470
sep_parsed : None ,
317
- bindings : smallvec ! [ Bindings :: default ( ) ] ,
471
+ bindings : bindings_builder . alloc ( ) ,
318
472
meta_result : None ,
319
473
is_error : false ,
320
474
} )
@@ -339,7 +493,7 @@ fn match_loop_inner<'t>(
339
493
item. meta_result = Some ( ( fork, match_res) ) ;
340
494
try_push ! ( bb_items, item) ;
341
495
} else {
342
- item . bindings . last_mut ( ) . unwrap ( ) . push_optional ( name) ;
496
+ bindings_builder . push_optional ( & mut item . bindings , & name) ;
343
497
item. dot . next ( ) ;
344
498
cur_items. push ( item) ;
345
499
}
@@ -348,11 +502,11 @@ fn match_loop_inner<'t>(
348
502
res. add_err ( err) ;
349
503
match match_res. value {
350
504
Some ( fragment) => {
351
- item . bindings
352
- . last_mut ( )
353
- . unwrap ( )
354
- . inner
355
- . push ( ( name . clone ( ) , Binding :: Fragment ( fragment ) ) ) ;
505
+ bindings_builder . push_fragment (
506
+ & mut item . bindings ,
507
+ & name ,
508
+ fragment ,
509
+ ) ;
356
510
}
357
511
_ => { }
358
512
}
@@ -394,14 +548,16 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
394
548
let mut res = Match :: default ( ) ;
395
549
let mut error_reover_item = None ;
396
550
551
+ let mut bindings_builder = BindingsBuilder :: default ( ) ;
552
+
397
553
let mut cur_items = smallvec ! [ MatchState {
398
554
dot: pattern. iter_delimited( None ) ,
399
555
stack: Default :: default ( ) ,
400
556
up: None ,
401
557
sep: None ,
402
558
sep_kind: None ,
403
559
sep_parsed: None ,
404
- bindings: smallvec! [ Bindings :: default ( ) ] ,
560
+ bindings: bindings_builder . alloc ( ) ,
405
561
is_error: false ,
406
562
meta_result: None ,
407
563
} ] ;
@@ -419,6 +575,7 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
419
575
src. clone ( ) ,
420
576
& stack,
421
577
& mut res,
578
+ & mut bindings_builder,
422
579
& mut cur_items,
423
580
& mut bb_items,
424
581
& mut next_items,
@@ -428,9 +585,9 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
428
585
stdx:: always!( cur_items. is_empty( ) ) ;
429
586
430
587
if error_items. len ( ) > 0 {
431
- error_reover_item = error_items. pop ( ) ;
588
+ error_reover_item = error_items. pop ( ) . map ( |it| it . bindings ) ;
432
589
} else if eof_items. len ( ) > 0 {
433
- error_reover_item = Some ( eof_items[ 0 ] . clone ( ) ) ;
590
+ error_reover_item = Some ( eof_items[ 0 ] . bindings . clone ( ) ) ;
434
591
}
435
592
436
593
// We need to do some post processing after the `match_loop_inner`.
@@ -440,11 +597,11 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
440
597
if eof_items. len ( ) == 1 {
441
598
// remove all errors, because it is the correct answer !
442
599
res = Match :: default ( ) ;
443
- res. bindings = eof_items[ 0 ] . bindings [ 0 ] . clone ( ) ;
600
+ res. bindings = bindings_builder . build ( & eof_items[ 0 ] . bindings ) ;
444
601
} else {
445
602
// Error recovery
446
603
if error_reover_item. is_some ( ) {
447
- res. bindings = error_reover_item. unwrap ( ) . bindings [ 0 ] . clone ( ) ;
604
+ res. bindings = bindings_builder . build ( & error_reover_item. unwrap ( ) ) ;
448
605
}
449
606
res. add_err ( ExpandError :: UnexpectedToken ) ;
450
607
}
@@ -467,8 +624,8 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
467
624
}
468
625
res. add_err ( err ! ( "leftover tokens" ) ) ;
469
626
470
- if let Some ( mut error_reover_item) = error_reover_item {
471
- res. bindings = error_reover_item . bindings . remove ( 0 ) ;
627
+ if let Some ( error_reover_item) = error_reover_item {
628
+ res. bindings = bindings_builder . build ( & error_reover_item ) ;
472
629
}
473
630
return res;
474
631
}
@@ -494,12 +651,13 @@ fn match_loop(pattern: &MetaTemplate, src: &tt::Subtree) -> Match {
494
651
495
652
if let Some ( OpDelimited :: Op ( Op :: Var { name, .. } ) ) = item. dot . peek ( ) {
496
653
let ( iter, match_res) = item. meta_result . take ( ) . unwrap ( ) ;
497
- let bindings = item. bindings . last_mut ( ) . unwrap ( ) ;
498
654
match match_res. value {
499
655
Some ( fragment) => {
500
- bindings. inner . push ( ( name. clone ( ) , Binding :: Fragment ( fragment) ) ) ;
656
+ bindings_builder. push_fragment ( & mut item. bindings , & name, fragment) ;
657
+ }
658
+ None if match_res. err . is_none ( ) => {
659
+ bindings_builder. push_optional ( & mut item. bindings , & name) ;
501
660
}
502
- None if match_res. err . is_none ( ) => bindings. push_optional ( name) ,
503
661
_ => { }
504
662
}
505
663
if let Some ( err) = match_res. err {
0 commit comments