use crate::token::{EOFToken, Token};
pub struct TokenReader {
tokens: Vec<Token>,
index: usize,
eof: Token,
}
impl TokenReader {
pub fn new(mut tokens: Vec<Token>) -> Self {
if tokens.last().is_none() || !tokens.last().unwrap().is::<EOFToken>() {
tokens.push(Token::new(EOFToken));
}
Self {
tokens,
index: 0,
eof: Token::new(EOFToken),
}
}
#[inline]
pub fn peek(&self) -> &Token {
self.tokens.get(self.index).unwrap_or(&self.eof)
}
#[inline]
pub fn peek_is<T: 'static>(&self) -> bool {
self.peek().is::<T>()
}
#[inline]
pub fn peek_as<T: 'static>(&self) -> Option<&T> {
self.peek().try_as::<T>()
}
pub fn consume(&mut self) -> &Token {
self.index += 1;
self.tokens.get(self.index - 1).unwrap_or(&self.eof)
}
#[inline]
pub fn consume_as<T: 'static>(&mut self) -> Option<&T> {
self.consume().try_as::<T>()
}
#[inline]
pub fn seek(&mut self, to_index: usize) {
self.index = to_index
}
#[inline]
pub fn check_eof(&self) -> bool {
self.peek_is::<EOFToken>()
}
}