#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TokenType {
Eof,
Word,
AssignmentWord,
Number,
Newline,
Pipe,
PipeBoth,
And,
Or,
Semi,
DoubleSemi,
SemiAnd,
SemiSemiAnd,
Ampersand,
LeftParen,
RightParen,
LeftBrace,
RightBrace,
DoubleLeftBracket,
DoubleRightBracket,
Less,
Greater,
DoubleLess,
DoubleGreater,
LessAnd,
GreaterAnd,
LessGreater,
DoubleLessDash,
TripleLess,
GreaterPipe,
AndGreater,
AndDoubleGreater,
Bang,
If,
Then,
Else,
Elif,
Fi,
Do,
Done,
Case,
Esac,
While,
Until,
For,
Select,
In,
Function,
Time,
Coproc,
}
impl TokenType {
pub fn reserved_word(s: &str) -> Option<Self> {
match s {
"if" => Some(Self::If),
"then" => Some(Self::Then),
"else" => Some(Self::Else),
"elif" => Some(Self::Elif),
"fi" => Some(Self::Fi),
"do" => Some(Self::Do),
"done" => Some(Self::Done),
"case" => Some(Self::Case),
"esac" => Some(Self::Esac),
"while" => Some(Self::While),
"until" => Some(Self::Until),
"for" => Some(Self::For),
"select" => Some(Self::Select),
"in" => Some(Self::In),
"function" => Some(Self::Function),
"time" => Some(Self::Time),
"coproc" => Some(Self::Coproc),
"!" => Some(Self::Bang),
"{" => Some(Self::LeftBrace),
"}" => Some(Self::RightBrace),
"[[" => Some(Self::DoubleLeftBracket),
"]]" => Some(Self::DoubleRightBracket),
_ => None,
}
}
pub const fn starts_command(self) -> bool {
matches!(
self,
Self::If
| Self::Case
| Self::While
| Self::Until
| Self::For
| Self::Select
| Self::LeftParen
| Self::LeftBrace
| Self::Function
| Self::Coproc
| Self::DoubleLeftBracket
| Self::Bang
| Self::Time
)
}
}
use crate::lexer::word_builder::WordSpan;
#[derive(Debug, Clone)]
pub struct Token {
pub kind: TokenType,
pub value: String,
pub pos: usize,
pub line: usize,
pub(crate) spans: Vec<WordSpan>,
}
impl Token {
pub fn new(kind: TokenType, value: impl Into<String>, pos: usize, line: usize) -> Self {
Self {
kind,
value: value.into(),
pos,
line,
spans: Vec::new(),
}
}
pub(crate) const fn with_spans(
kind: TokenType,
value: String,
pos: usize,
line: usize,
spans: Vec<WordSpan>,
) -> Self {
Self {
kind,
value,
pos,
line,
spans,
}
}
pub const fn adjacent_to(&self, other: &Self) -> bool {
self.pos + self.value.len() == other.pos
}
pub const fn eof(pos: usize, line: usize) -> Self {
Self {
kind: TokenType::Eof,
value: String::new(),
pos,
line,
spans: Vec::new(),
}
}
}