Add a new special case to Parser::look_ahead
.
This new special case is simpler than the old special case because it only is used when `dist == 1`. But that's still enough to cover ~98% of cases. This results in equivalent performance to the old special case, and identical behaviour as the general case.
This commit is contained in:
parent
ebe1305b1e
commit
100f3fd133
@ -1118,6 +1118,35 @@ pub fn look_ahead<R>(&self, dist: usize, looker: impl FnOnce(&Token) -> R) -> R
|
||||
return looker(&self.token);
|
||||
}
|
||||
|
||||
// Typically around 98% of the `dist > 0` cases have `dist == 1`, so we
|
||||
// have a fast special case for that.
|
||||
if dist == 1 {
|
||||
// The index is zero because the tree cursor's index always points
|
||||
// to the next token to be gotten.
|
||||
match self.token_cursor.tree_cursor.look_ahead(0) {
|
||||
Some(tree) => {
|
||||
// Indexing stayed within the current token tree.
|
||||
return match tree {
|
||||
TokenTree::Token(token, _) => looker(token),
|
||||
TokenTree::Delimited(dspan, _, delim, _) => {
|
||||
looker(&Token::new(token::OpenDelim(*delim), dspan.open))
|
||||
}
|
||||
};
|
||||
}
|
||||
None => {
|
||||
// The tree cursor lookahead went (one) past the end of the
|
||||
// current token tree. Try to return a close delimiter.
|
||||
if let Some(&(_, span, _, delim)) = self.token_cursor.stack.last()
|
||||
&& delim != Delimiter::Invisible
|
||||
{
|
||||
// We are not in the outermost token stream, so we have
|
||||
// delimiters. Also, those delimiters are not skipped.
|
||||
return looker(&Token::new(token::CloseDelim(delim), span.close));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Just clone the token cursor and use `next`, skipping delimiters as
|
||||
// necessary. Slow but simple.
|
||||
let mut cursor = self.token_cursor.clone();
|
||||
|
Loading…
Reference in New Issue
Block a user