@@ -245,6 +245,22 @@ enum PrevTokenKind {
245
245
Other ,
246
246
}
247
247
248
+ // Simple circular buffer used for keeping few next tokens.
249
+ #[ derive( Default ) ]
250
+ struct LookaheadBuffer {
251
+ buffer : [ TokenAndSpan ; LOOKAHEAD_BUFFER_CAPACITY ] ,
252
+ start : usize ,
253
+ end : usize ,
254
+ }
255
+
256
+ const LOOKAHEAD_BUFFER_CAPACITY : usize = 8 ;
257
+
258
+ impl LookaheadBuffer {
259
+ fn len ( & self ) -> usize {
260
+ ( LOOKAHEAD_BUFFER_CAPACITY + self . end - self . start ) % LOOKAHEAD_BUFFER_CAPACITY
261
+ }
262
+ }
263
+
248
264
/* ident is handled by common.rs */
249
265
250
266
pub struct Parser < ' a > {
@@ -258,9 +274,7 @@ pub struct Parser<'a> {
258
274
pub cfg : CrateConfig ,
259
275
/// the previous token kind
260
276
prev_token_kind : PrevTokenKind ,
261
- pub buffer : [ TokenAndSpan ; 4 ] ,
262
- pub buffer_start : isize ,
263
- pub buffer_end : isize ,
277
+ lookahead_buffer : LookaheadBuffer ,
264
278
pub tokens_consumed : usize ,
265
279
pub restrictions : Restrictions ,
266
280
pub quote_depth : usize , // not (yet) related to the quasiquoter
@@ -356,10 +370,6 @@ impl<'a> Parser<'a> {
356
370
_ => PathBuf :: from ( sess. codemap ( ) . span_to_filename ( span) ) ,
357
371
} ;
358
372
directory. pop ( ) ;
359
- let placeholder = TokenAndSpan {
360
- tok : token:: Underscore ,
361
- sp : span,
362
- } ;
363
373
364
374
Parser {
365
375
reader : rdr,
@@ -369,14 +379,7 @@ impl<'a> Parser<'a> {
369
379
span : span,
370
380
prev_span : span,
371
381
prev_token_kind : PrevTokenKind :: Other ,
372
- buffer : [
373
- placeholder. clone ( ) ,
374
- placeholder. clone ( ) ,
375
- placeholder. clone ( ) ,
376
- placeholder. clone ( ) ,
377
- ] ,
378
- buffer_start : 0 ,
379
- buffer_end : 0 ,
382
+ lookahead_buffer : Default :: default ( ) ,
380
383
tokens_consumed : 0 ,
381
384
restrictions : Restrictions :: empty ( ) ,
382
385
quote_depth : 0 ,
@@ -937,19 +940,13 @@ impl<'a> Parser<'a> {
937
940
_ => PrevTokenKind :: Other ,
938
941
} ;
939
942
940
- let next = if self . buffer_start == self . buffer_end {
943
+ let next = if self . lookahead_buffer . start == self . lookahead_buffer . end {
941
944
self . reader . real_token ( )
942
945
} else {
943
946
// Avoid token copies with `replace`.
944
- let buffer_start = self . buffer_start as usize ;
945
- let next_index = ( buffer_start + 1 ) & 3 ;
946
- self . buffer_start = next_index as isize ;
947
-
948
- let placeholder = TokenAndSpan {
949
- tok : token:: Underscore ,
950
- sp : self . span ,
951
- } ;
952
- mem:: replace ( & mut self . buffer [ buffer_start] , placeholder)
947
+ let old_start = self . lookahead_buffer . start ;
948
+ self . lookahead_buffer . start = ( old_start + 1 ) % LOOKAHEAD_BUFFER_CAPACITY ;
949
+ mem:: replace ( & mut self . lookahead_buffer . buffer [ old_start] , Default :: default ( ) )
953
950
} ;
954
951
self . span = next. sp ;
955
952
self . token = next. tok ;
@@ -982,21 +979,22 @@ impl<'a> Parser<'a> {
982
979
self . expected_tokens . clear ( ) ;
983
980
}
984
981
985
- pub fn buffer_length ( & mut self ) -> isize {
986
- if self . buffer_start <= self . buffer_end {
987
- return self . buffer_end - self . buffer_start ;
988
- }
989
- return ( 4 - self . buffer_start ) + self . buffer_end ;
990
- }
991
- pub fn look_ahead < R , F > ( & mut self , distance : usize , f : F ) -> R where
982
+ pub fn look_ahead < R , F > ( & mut self , dist : usize , f : F ) -> R where
992
983
F : FnOnce ( & token:: Token ) -> R ,
993
984
{
994
- let dist = distance as isize ;
995
- while self . buffer_length ( ) < dist {
996
- self . buffer [ self . buffer_end as usize ] = self . reader . real_token ( ) ;
997
- self . buffer_end = ( self . buffer_end + 1 ) & 3 ;
985
+ if dist == 0 {
986
+ f ( & self . token )
987
+ } else if dist < LOOKAHEAD_BUFFER_CAPACITY {
988
+ while self . lookahead_buffer . len ( ) < dist {
989
+ self . lookahead_buffer . buffer [ self . lookahead_buffer . end ] = self . reader . real_token ( ) ;
990
+ self . lookahead_buffer . end =
991
+ ( self . lookahead_buffer . end + 1 ) % LOOKAHEAD_BUFFER_CAPACITY ;
992
+ }
993
+ let index = ( self . lookahead_buffer . start + dist - 1 ) % LOOKAHEAD_BUFFER_CAPACITY ;
994
+ f ( & self . lookahead_buffer . buffer [ index] . tok )
995
+ } else {
996
+ self . bug ( "lookahead distance is too large" ) ;
998
997
}
999
- f ( & self . buffer [ ( ( self . buffer_start + dist - 1 ) & 3 ) as usize ] . tok )
1000
998
}
1001
999
pub fn fatal ( & self , m : & str ) -> DiagnosticBuilder < ' a > {
1002
1000
self . sess . span_diagnostic . struct_span_fatal ( self . span , m)
@@ -1118,7 +1116,6 @@ impl<'a> Parser<'a> {
1118
1116
Ok ( ast:: TyKind :: ImplTrait ( bounds) )
1119
1117
}
1120
1118
1121
-
1122
1119
pub fn parse_ty_path ( & mut self ) -> PResult < ' a , TyKind > {
1123
1120
Ok ( TyKind :: Path ( None , self . parse_path ( PathStyle :: Type ) ?) )
1124
1121
}
0 commit comments