@@ -245,6 +245,22 @@ enum PrevTokenKind {
245245 Other ,
246246}
247247
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+
248264/* ident is handled by common.rs */
249265
250266pub struct Parser < ' a > {
@@ -258,9 +274,7 @@ pub struct Parser<'a> {
258274 pub cfg : CrateConfig ,
259275 /// the previous token kind
260276 prev_token_kind : PrevTokenKind ,
261- pub buffer : [ TokenAndSpan ; 4 ] ,
262- pub buffer_start : isize ,
263- pub buffer_end : isize ,
277+ lookahead_buffer : LookaheadBuffer ,
264278 pub tokens_consumed : usize ,
265279 pub restrictions : Restrictions ,
266280 pub quote_depth : usize , // not (yet) related to the quasiquoter
@@ -356,10 +370,6 @@ impl<'a> Parser<'a> {
356370 _ => PathBuf :: from ( sess. codemap ( ) . span_to_filename ( span) ) ,
357371 } ;
358372 directory. pop ( ) ;
359- let placeholder = TokenAndSpan {
360- tok : token:: Underscore ,
361- sp : span,
362- } ;
363373
364374 Parser {
365375 reader : rdr,
@@ -369,14 +379,7 @@ impl<'a> Parser<'a> {
369379 span : span,
370380 prev_span : span,
371381 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 ( ) ,
380383 tokens_consumed : 0 ,
381384 restrictions : Restrictions :: empty ( ) ,
382385 quote_depth : 0 ,
@@ -937,19 +940,13 @@ impl<'a> Parser<'a> {
937940 _ => PrevTokenKind :: Other ,
938941 } ;
939942
940- let next = if self . buffer_start == self . buffer_end {
943+ let next = if self . lookahead_buffer . start == self . lookahead_buffer . end {
941944 self . reader . real_token ( )
942945 } else {
943946 // 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 ( ) )
953950 } ;
954951 self . span = next. sp ;
955952 self . token = next. tok ;
@@ -982,21 +979,22 @@ impl<'a> Parser<'a> {
982979 self . expected_tokens . clear ( ) ;
983980 }
984981
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
992983 F : FnOnce ( & token:: Token ) -> R ,
993984 {
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" ) ;
998997 }
999- f ( & self . buffer [ ( ( self . buffer_start + dist - 1 ) & 3 ) as usize ] . tok )
1000998 }
1001999 pub fn fatal ( & self , m : & str ) -> DiagnosticBuilder < ' a > {
10021000 self . sess . span_diagnostic . struct_span_fatal ( self . span , m)
@@ -1118,7 +1116,6 @@ impl<'a> Parser<'a> {
11181116 Ok ( ast:: TyKind :: ImplTrait ( bounds) )
11191117 }
11201118
1121-
11221119 pub fn parse_ty_path ( & mut self ) -> PResult < ' a , TyKind > {
11231120 Ok ( TyKind :: Path ( None , self . parse_path ( PathStyle :: Type ) ?) )
11241121 }
0 commit comments