use super::{
symbol::SymbolChar,
word::IsWord,
ByteLiteral,
Command,
Comment,
Cursor,
Error,
NumberLiteral,
State,
StringLiteral,
Symbol,
Token,
TokenKind,
Transition,
Word,
};
#[derive(Debug)]
pub(super) struct Root;
impl Root {
pub fn visit(self, cursor: &Cursor) -> Transition {
match cursor.peek() {
Some(c) if c.is_ascii_whitespace() => Transition::step(self),
Some(b'#') => Transition::step(Comment::from(self)),
Some(b'"') => Transition::step(StringLiteral::at(cursor)),
Some(b'\'') => Transition::step(ByteLiteral::at(cursor)),
Some(c) if c.is_ascii_digit() => Transition::step(NumberLiteral::at(cursor)),
Some(c) if c.is_word_start() => Transition::resume(Word::at(cursor)),
Some(c) => match SymbolChar::from_first(c) {
SymbolChar::None => Transition::error(self, Error::unexpected(c, cursor.pos())),
SymbolChar::Single(TokenKind::Command) => Transition::produce(
Command,
Token { kind: TokenKind::Command, pos: cursor.pos() },
),
SymbolChar::Single(token) => {
Transition::produce(self, Token { kind: token, pos: cursor.pos() })
}
SymbolChar::Double { first } => Transition::step(Symbol::from_first(first, cursor)),
},
None => Transition::step(self),
}
}
}
impl From<Root> for State {
fn from(state: Root) -> State {
Self::Root(state)
}
}