pub use crate::lexer::TokenKind;
use crate::{lexer::Cursor, span::Span};
pub struct TokenStream<'i> {
cursor: Cursor<'i>,
consumed: usize,
}
impl<'i> TokenStream<'i> {
pub fn new(input: &'i str) -> Self {
Self {
cursor: Cursor::new(input),
consumed: 0,
}
}
pub fn offset(&mut self, offset: usize) {
self.consumed += offset;
}
}
impl Iterator for TokenStream<'_> {
type Item = Token;
fn next(&mut self) -> Option<Self::Item> {
let t = self.cursor.advance_token();
let start = self.consumed;
self.consumed += t.len as usize;
if t.kind == TokenKind::Eof && self.cursor.is_eof() {
None
} else {
Some(Token {
kind: t.kind,
span: Span::new(start, self.consumed),
})
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Token {
pub kind: TokenKind,
pub span: Span,
}
impl Token {
pub fn len(&self) -> usize {
self.span.len()
}
}
#[cfg(test)]
macro_rules! tokens {
($($kind:tt . $len:expr),*) => {{
let mut v = Vec::new();
let mut _len = 0;
$(
v.push($crate::parser::token_stream::Token { kind: $crate::lexer::T![$kind], span: $crate::span::Span::new(_len, _len + $len) });
_len += $len;
)*
v
}};
}
#[cfg(test)]
pub(crate) use tokens;
#[cfg(test)]
mod tests {
use crate::lexer::T;
use super::*;
#[test]
fn tokens_macro() {
let t = tokens![word.3, ws.1];
assert_eq!(
t,
vec![
Token {
kind: T![word],
span: Span::new(0, 3)
},
Token {
kind: T![ws],
span: Span::new(3, 4)
},
]
);
}
}