mod result;
mod state;
mod transition;
mod with_pos;
use mylang_token::{Pos, Token};
use with_pos::WithPosExt;
use crate::{result::LexResult, state::State, transition::transition};
pub use result::LexErr;
struct Lex<I>
where
I: Iterator<Item = (Pos, char)> + Sized,
{
iter: I,
state: Option<State>,
}
impl<I> Iterator for Lex<I>
where
I: Iterator<Item = (Pos, char)>,
{
type Item = Vec<LexResult<Token>>;
fn next(&mut self) -> Option<Self::Item> {
let state = self.state.as_ref()?.clone();
if let Some((pos, c)) = self.iter.next() {
let (next_state, results) = transition(&state, (pos, c));
self.state = Some(next_state);
return Some(results);
}
match state {
State::Initial => {
self.state = None;
None
}
State::I32(i32_state) => {
self.state = None;
Some(vec![Ok(i32_state.tokenize())])
}
State::Str(str_state) => {
self.state = None;
Some(vec![Err(LexErr::MissingClosingQuoteForStr(str_state.end))])
}
State::Symbol(symbol_state) => {
self.state = None;
Some(vec![Ok(symbol_state.tokenize())])
}
}
}
}
trait LexExt: Iterator<Item = (Pos, char)> + Sized {
fn lex(self) -> Lex<Self>;
}
impl<I> LexExt for I
where
I: Iterator<Item = (Pos, char)> + Sized,
{
fn lex(self) -> Lex<Self> {
Lex {
iter: self,
state: Some(State::Initial),
}
}
}
pub fn lex<'a, T>(src: T) -> impl Iterator<Item = LexResult<Token>> + 'a
where
T: Iterator<Item = char> + 'a,
{
src.with_pos().lex().flatten()
}