use super::lexer_struct::Lexer;
use super::source_file::SourceFile;
use super::Token;
pub struct Tokens<'l, T> {
lexer: &'l Lexer<T>,
pub source: SourceFile,
position: usize,
eof: bool,
}
impl<'l, K> Tokens<'l, K> {
pub fn new(lexer: &'l Lexer<K>, source: &SourceFile) -> Self {
Self {
lexer,
source: source.clone(),
position: 0,
eof: false,
}
}
}
impl<'l, K> Iterator for Tokens<'l, K> {
type Item = Token<K>;
fn next(&mut self) -> Option<Token<K>> {
loop {
if self.eof {
return None;
}
if self.position == self.source.len() {
self.eof = true;
return Some(Token {
ty: self.lexer.eof().unwrap(),
loc: self
.source
.range_to_location(self.position..self.position + 1),
});
}
let string = self.source.remaining(self.position);
let match_set = self.lexer.regex_set().matches(string);
let result = match_set
.into_iter()
.map(|i: usize| {
let m = self.lexer.regexes()[i].find(string).unwrap();
assert!(m.start() == 0);
(m.end(), i)
})
.next_back();
let (len, i) = if let Some((a, b)) = result {
(a, b)
} else {
panic!("ERROR lexer");
};
let loc = self
.source
.range_to_location(self.position..self.position + len);
let text = self.source.span(self.position..self.position + len);
self.position += len;
if let Some(t) = self.lexer.make(i, text) {
return Some(Token { ty: t, loc });
}
}
}
}