@@ -13,7 +13,6 @@ use ast::Ident;
13
13
use errors:: Handler ;
14
14
use ext:: tt:: macro_parser:: { NamedMatch , MatchedSeq , MatchedNonterminal } ;
15
15
use parse:: token:: { self , MatchNt , SubstNt , Token , NtIdent } ;
16
- use parse:: lexer:: TokenAndSpan ;
17
16
use syntax_pos:: { Span , DUMMY_SP } ;
18
17
use tokenstream:: { self , TokenTree } ;
19
18
use util:: small_vector:: SmallVector ;
@@ -32,33 +31,24 @@ struct TtFrame {
32
31
}
33
32
34
33
#[ derive( Clone ) ]
35
- pub struct TtReader < ' a > {
36
- pub sp_diag : & ' a Handler ,
34
+ struct TtReader < ' a > {
35
+ sp_diag : & ' a Handler ,
37
36
/// the unzipped tree:
38
37
stack : SmallVector < TtFrame > ,
39
38
/* for MBE-style macro transcription */
40
39
interpolations : HashMap < Ident , Rc < NamedMatch > > ,
41
40
42
41
repeat_idx : Vec < usize > ,
43
42
repeat_len : Vec < usize > ,
44
- /* cached: */
45
- pub cur_tok : Token ,
46
- pub cur_span : Span ,
47
- }
48
-
49
- impl < ' a > TtReader < ' a > {
50
- pub fn real_token ( & mut self ) -> TokenAndSpan {
51
- tt_next_token ( self )
52
- }
53
43
}
54
44
55
45
/// This can do Macro-By-Example transcription. On the other hand, if
56
46
/// `src` contains no `TokenTree::Sequence`s, `MatchNt`s or `SubstNt`s, `interp` can
57
47
/// (and should) be None.
58
- pub fn new_tt_reader ( sp_diag : & Handler ,
59
- interp : Option < HashMap < Ident , Rc < NamedMatch > > > ,
60
- src : Vec < tokenstream:: TokenTree > )
61
- -> TtReader {
48
+ pub fn transcribe ( sp_diag : & Handler ,
49
+ interp : Option < HashMap < Ident , Rc < NamedMatch > > > ,
50
+ src : Vec < tokenstream:: TokenTree > )
51
+ -> Vec < TokenTree > {
62
52
let mut r = TtReader {
63
53
sp_diag : sp_diag,
64
54
stack : SmallVector :: one ( TtFrame {
@@ -77,12 +67,15 @@ pub fn new_tt_reader(sp_diag: &Handler,
77
67
} ,
78
68
repeat_idx : Vec :: new ( ) ,
79
69
repeat_len : Vec :: new ( ) ,
80
- /* dummy values, never read: */
81
- cur_tok : token:: Eof ,
82
- cur_span : DUMMY_SP ,
83
70
} ;
84
- tt_next_token ( & mut r) ; /* get cur_tok and cur_span set up */
85
- r
71
+
72
+ let mut tts = Vec :: new ( ) ;
73
+ let mut prev_span = DUMMY_SP ;
74
+ while let Some ( tt) = tt_next_token ( & mut r, prev_span) {
75
+ prev_span = tt. span ( ) ;
76
+ tts. push ( tt) ;
77
+ }
78
+ tts
86
79
}
87
80
88
81
fn lookup_cur_matched_by_matched ( r : & TtReader , start : Rc < NamedMatch > ) -> Rc < NamedMatch > {
@@ -156,38 +149,24 @@ fn lockstep_iter_size(t: &TokenTree, r: &TtReader) -> LockstepIterSize {
156
149
157
150
/// Return the next token from the TtReader.
158
151
/// EFFECT: advances the reader's token field
159
- pub fn tt_next_token ( r : & mut TtReader ) -> TokenAndSpan {
160
- // FIXME(pcwalton): Bad copy?
161
- let ret_val = TokenAndSpan {
162
- tok : r. cur_tok . clone ( ) ,
163
- sp : r. cur_span . clone ( ) ,
164
- } ;
152
+ fn tt_next_token ( r : & mut TtReader , prev_span : Span ) -> Option < TokenTree > {
165
153
loop {
166
- let should_pop = match r. stack . last ( ) {
167
- None => {
168
- assert_eq ! ( ret_val. tok, token:: Eof ) ;
169
- return ret_val;
170
- }
171
- Some ( frame) => {
172
- if frame. idx < frame. forest . len ( ) {
173
- break ;
174
- }
175
- !frame. dotdotdoted ||
176
- * r. repeat_idx . last ( ) . unwrap ( ) == * r. repeat_len . last ( ) . unwrap ( ) - 1
154
+ let should_pop = if let Some ( frame) = r. stack . last ( ) {
155
+ if frame. idx < frame. forest . len ( ) {
156
+ break ;
177
157
}
158
+ !frame. dotdotdoted || * r. repeat_idx . last ( ) . unwrap ( ) == * r. repeat_len . last ( ) . unwrap ( ) - 1
159
+ } else {
160
+ return None ;
178
161
} ;
179
162
180
163
/* done with this set; pop or repeat? */
181
164
if should_pop {
182
165
let prev = r. stack . pop ( ) . unwrap ( ) ;
183
- match r. stack . last_mut ( ) {
184
- None => {
185
- r. cur_tok = token:: Eof ;
186
- return ret_val;
187
- }
188
- Some ( frame) => {
189
- frame. idx += 1 ;
190
- }
166
+ if let Some ( frame) = r. stack . last_mut ( ) {
167
+ frame. idx += 1 ;
168
+ } else {
169
+ return None ;
191
170
}
192
171
if prev. dotdotdoted {
193
172
r. repeat_idx . pop ( ) ;
@@ -197,8 +176,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
197
176
* r. repeat_idx . last_mut ( ) . unwrap ( ) += 1 ;
198
177
r. stack . last_mut ( ) . unwrap ( ) . idx = 0 ;
199
178
if let Some ( tk) = r. stack . last ( ) . unwrap ( ) . sep . clone ( ) {
200
- r. cur_tok = tk; // repeat same span, I guess
201
- return ret_val;
179
+ return Some ( TokenTree :: Token ( prev_span, tk) ) ; // repeat same span, I guess
202
180
}
203
181
}
204
182
}
@@ -234,7 +212,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
234
212
}
235
213
236
214
r. stack . last_mut ( ) . unwrap ( ) . idx += 1 ;
237
- return tt_next_token ( r) ;
215
+ return tt_next_token ( r, prev_span ) ;
238
216
}
239
217
r. repeat_len . push ( len) ;
240
218
r. repeat_idx . push ( 0 ) ;
@@ -252,9 +230,7 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
252
230
r. stack . last_mut ( ) . unwrap ( ) . idx += 1 ;
253
231
match lookup_cur_matched ( r, ident) {
254
232
None => {
255
- r. cur_span = sp;
256
- r. cur_tok = SubstNt ( ident) ;
257
- return ret_val;
233
+ return Some ( TokenTree :: Token ( sp, SubstNt ( ident) ) ) ;
258
234
// this can't be 0 length, just like TokenTree::Delimited
259
235
}
260
236
Some ( cur_matched) => if let MatchedNonterminal ( ref nt) = * cur_matched {
@@ -263,15 +239,11 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
263
239
// (a) idents can be in lots of places, so it'd be a pain
264
240
// (b) we actually can, since it's a token.
265
241
NtIdent ( ref sn) => {
266
- r. cur_span = sn. span ;
267
- r. cur_tok = token:: Ident ( sn. node ) ;
268
- return ret_val;
242
+ return Some ( TokenTree :: Token ( sn. span , token:: Ident ( sn. node ) ) ) ;
269
243
}
270
244
_ => {
271
- // FIXME(pcwalton): Bad copy.
272
- r. cur_span = sp;
273
- r. cur_tok = token:: Interpolated ( nt. clone ( ) ) ;
274
- return ret_val;
245
+ // FIXME(pcwalton): Bad copy
246
+ return Some ( TokenTree :: Token ( sp, token:: Interpolated ( nt. clone ( ) ) ) ) ;
275
247
}
276
248
}
277
249
} else {
@@ -292,11 +264,9 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
292
264
} ) ;
293
265
// if this could be 0-length, we'd need to potentially recur here
294
266
}
295
- TokenTree :: Token ( sp, tok) => {
296
- r. cur_span = sp;
297
- r. cur_tok = tok;
267
+ tt @ TokenTree :: Token ( ..) => {
298
268
r. stack . last_mut ( ) . unwrap ( ) . idx += 1 ;
299
- return ret_val ;
269
+ return Some ( tt ) ;
300
270
}
301
271
}
302
272
}
0 commit comments