@@ -100,17 +100,39 @@ use std::collections::hash_map::{Vacant, Occupied};
100
100
// To avoid costly uniqueness checks, we require that `MatchSeq` always has
101
101
// a nonempty body.
102
102
103
+ #[ deriving( Clone ) ]
104
+ enum TokenTreeOrTokenTreeVec {
105
+ Tt ( ast:: TokenTree ) ,
106
+ TtSeq ( Rc < Vec < ast:: TokenTree > > ) ,
107
+ }
108
+
109
+ impl TokenTreeOrTokenTreeVec {
110
+ fn len ( & self ) -> uint {
111
+ match self {
112
+ & TtSeq ( ref v) => v. len ( ) ,
113
+ & Tt ( ref tt) => tt. len ( ) ,
114
+ }
115
+ }
116
+
117
+ fn get_tt ( & self , index : uint ) -> TokenTree {
118
+ match self {
119
+ & TtSeq ( ref v) => v[ index] . clone ( ) ,
120
+ & Tt ( ref tt) => tt. get_tt ( index) ,
121
+ }
122
+ }
123
+ }
124
+
103
125
/// an unzipping of `TokenTree`s
104
126
#[ deriving( Clone ) ]
105
127
struct MatcherTtFrame {
106
- elts : Rc < Vec < ast :: TokenTree > > ,
128
+ elts : TokenTreeOrTokenTreeVec ,
107
129
idx : uint ,
108
130
}
109
131
110
132
#[ deriving( Clone ) ]
111
133
pub struct MatcherPos {
112
134
stack : Vec < MatcherTtFrame > ,
113
- elts : Rc < Vec < ast :: TokenTree > > ,
135
+ top_elts : TokenTreeOrTokenTreeVec ,
114
136
sep : Option < Token > ,
115
137
idx : uint ,
116
138
up : Option < Box < MatcherPos > > ,
@@ -124,8 +146,8 @@ pub struct MatcherPos {
124
146
pub fn count_names ( ms : & [ TokenTree ] ) -> uint {
125
147
ms. iter ( ) . fold ( 0 , |count, elt| {
126
148
count + match elt {
127
- & TtSequence ( _, _ , _ , _ , advance_by ) => {
128
- advance_by
149
+ & TtSequence ( _, ref seq ) => {
150
+ seq . num_captures
129
151
}
130
152
& TtDelimited ( _, ref delim) => {
131
153
count_names ( delim. tts . as_slice ( ) )
@@ -144,7 +166,7 @@ pub fn initial_matcher_pos(ms: Rc<Vec<TokenTree>>, sep: Option<Token>, lo: ByteP
144
166
let matches = Vec :: from_fn ( match_idx_hi, |_i| Vec :: new ( ) ) ;
145
167
box MatcherPos {
146
168
stack : vec ! [ ] ,
147
- elts : ms ,
169
+ top_elts : TtSeq ( ms ) ,
148
170
sep : sep,
149
171
idx : 0 u,
150
172
up : None ,
@@ -183,8 +205,8 @@ pub fn nameize(p_s: &ParseSess, ms: &[TokenTree], res: &[Rc<NamedMatch>])
183
205
fn n_rec ( p_s : & ParseSess , m : & TokenTree , res : & [ Rc < NamedMatch > ] ,
184
206
ret_val : & mut HashMap < Ident , Rc < NamedMatch > > , idx : & mut uint ) {
185
207
match m {
186
- & TtSequence ( _, ref more_ms , _ , _ , _ ) => {
187
- for next_m in more_ms . iter ( ) {
208
+ & TtSequence ( _, ref seq ) => {
209
+ for next_m in seq . tts . iter ( ) {
188
210
n_rec ( p_s, next_m, res, ret_val, idx)
189
211
}
190
212
}
@@ -278,18 +300,18 @@ pub fn parse(sess: &ParseSess,
278
300
} ;
279
301
280
302
// When unzipped trees end, remove them
281
- while ei. idx >= ei. elts . len ( ) {
303
+ while ei. idx >= ei. top_elts . len ( ) {
282
304
match ei. stack . pop ( ) {
283
305
Some ( MatcherTtFrame { elts, idx } ) => {
284
- ei. elts = elts;
306
+ ei. top_elts = elts;
285
307
ei. idx = idx + 1 ;
286
308
}
287
309
None => break
288
310
}
289
311
}
290
312
291
313
let idx = ei. idx ;
292
- let len = ei. elts . len ( ) ;
314
+ let len = ei. top_elts . len ( ) ;
293
315
294
316
/* at end of sequence */
295
317
if idx >= len {
@@ -352,17 +374,16 @@ pub fn parse(sess: &ParseSess,
352
374
eof_eis. push ( ei) ;
353
375
}
354
376
} else {
355
- match ( * ei. elts ) [ idx ] . clone ( ) {
377
+ match ei. top_elts . get_tt ( idx ) {
356
378
/* need to descend into sequence */
357
- TtSequence ( _ , ref matchers , ref sep , kleene_op , match_num ) => {
358
- if kleene_op == ast:: ZeroOrMore {
379
+ TtSequence ( sp , seq ) => {
380
+ if seq . op == ast:: ZeroOrMore {
359
381
let mut new_ei = ei. clone ( ) ;
360
- new_ei. match_cur += match_num ;
382
+ new_ei. match_cur += seq . num_captures ;
361
383
new_ei. idx += 1 u;
362
384
//we specifically matched zero repeats.
363
- for idx in range ( ei. match_cur , ei. match_cur + match_num) {
364
- new_ei. matches [ idx]
365
- . push ( Rc :: new ( MatchedSeq ( Vec :: new ( ) , sp) ) ) ;
385
+ for idx in range ( ei. match_cur , ei. match_cur + seq. num_captures ) {
386
+ new_ei. matches [ idx] . push ( Rc :: new ( MatchedSeq ( Vec :: new ( ) , sp) ) ) ;
366
387
}
367
388
368
389
cur_eis. push ( new_ei) ;
@@ -372,15 +393,15 @@ pub fn parse(sess: &ParseSess,
372
393
let ei_t = ei;
373
394
cur_eis. push ( box MatcherPos {
374
395
stack : vec ! [ ] ,
375
- elts : matchers. clone ( ) ,
376
- sep : ( * sep) . clone ( ) ,
396
+ sep : seq. separator . clone ( ) ,
377
397
idx : 0 u,
378
398
matches : matches,
379
399
match_lo : ei_t. match_cur ,
380
400
match_cur : ei_t. match_cur ,
381
- match_hi : ei_t. match_cur + match_num ,
401
+ match_hi : ei_t. match_cur + seq . num_captures ,
382
402
up : Some ( ei_t) ,
383
- sp_lo : sp. lo
403
+ sp_lo : sp. lo ,
404
+ top_elts : Tt ( TtSequence ( sp, seq) ) ,
384
405
} ) ;
385
406
}
386
407
TtToken ( _, MatchNt ( ..) ) => {
@@ -395,11 +416,10 @@ pub fn parse(sess: &ParseSess,
395
416
return Error ( sp, "Cannot transcribe in macro LHS" . into_string ( ) )
396
417
}
397
418
seq @ TtDelimited ( ..) | seq @ TtToken ( _, DocComment ( ..) ) => {
398
- let tts = seq. expand_into_tts ( ) ;
399
- let elts = mem:: replace ( & mut ei. elts , tts) ;
419
+ let lower_elts = mem:: replace ( & mut ei. top_elts , Tt ( seq) ) ;
400
420
let idx = ei. idx ;
401
421
ei. stack . push ( MatcherTtFrame {
402
- elts : elts ,
422
+ elts : lower_elts ,
403
423
idx : idx,
404
424
} ) ;
405
425
ei. idx = 0 ;
@@ -433,7 +453,7 @@ pub fn parse(sess: &ParseSess,
433
453
if ( bb_eis. len ( ) > 0 u && next_eis. len ( ) > 0 u)
434
454
|| bb_eis. len ( ) > 1 u {
435
455
let nts = bb_eis. iter ( ) . map ( |ei| {
436
- match ( * ei. elts ) [ ei. idx ] {
456
+ match ei. top_elts . get_tt ( ei. idx ) {
437
457
TtToken ( _, MatchNt ( bind, name, _, _) ) => {
438
458
( format ! ( "{} ('{}')" ,
439
459
token:: get_ident( name) ,
@@ -458,7 +478,7 @@ pub fn parse(sess: &ParseSess,
458
478
let mut rust_parser = Parser :: new ( sess, cfg. clone ( ) , box rdr. clone ( ) ) ;
459
479
460
480
let mut ei = bb_eis. pop ( ) . unwrap ( ) ;
461
- match ( * ei. elts ) [ ei. idx ] {
481
+ match ei. top_elts . get_tt ( ei. idx ) {
462
482
TtToken ( _, MatchNt ( _, name, _, _) ) => {
463
483
let name_string = token:: get_ident ( name) ;
464
484
let match_cur = ei. match_cur ;
0 commit comments