use compact_str::CompactString;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Span {
pub start: u32,
pub end: u32,
}
impl Span {
pub fn new(start: u32, end: u32) -> Self {
Self { start, end }
}
pub fn len(&self) -> u32 {
self.end - self.start
}
pub fn is_empty(&self) -> bool {
self.start == self.end
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Token {
pub kind: TokenKind,
pub span: Span,
pub text: CompactString,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TokenKind {
Word,
SingleQuoted,
DoubleQuoted,
DollarSingleQuoted,
Number,
Pipe,
PipeAmpersand,
OrOr,
AndAnd,
Ampersand,
Disown,
Semi,
DoubleSemi,
SemiAnd,
SemiPipe,
Newline,
Less,
Greater,
DoubleGreater,
GreaterPipe,
GreaterBang,
AmpGreater,
AmpDoubleGreater,
DoubleLess,
TripleLess,
DoubleLessDash,
LessGreater,
ProcessSubIn,
ProcessSubOut,
FdGreater,
FdLess,
FdDoubleGreater,
FdDup,
LeftParen,
RightParen,
LeftBrace,
RightBrace,
DoubleLeftBracket,
DoubleRightBracket,
Dollar,
DollarBrace,
DollarParen,
DollarDoubleParen,
Backtick,
Equals,
Tilde,
Comment,
Bang,
At,
Star,
Question,
If,
Then,
Elif,
Else,
Fi,
For,
In,
While,
Until,
Do,
Done,
Case,
Esac,
Select,
Repeat,
Function,
Time,
Coproc,
CondStart,
CondEnd,
Eof,
Error,
}
impl TokenKind {
pub fn is_reserved_word(&self) -> bool {
matches!(
self,
Self::If
| Self::Then
| Self::Elif
| Self::Else
| Self::Fi
| Self::For
| Self::In
| Self::While
| Self::Until
| Self::Do
| Self::Done
| Self::Case
| Self::Esac
| Self::Select
| Self::Repeat
| Self::Function
| Self::Time
| Self::Coproc
)
}
pub fn is_separator(&self) -> bool {
matches!(
self,
Self::Semi
| Self::Newline
| Self::Ampersand
| Self::Pipe
| Self::PipeAmpersand
| Self::OrOr
| Self::AndAnd
| Self::Eof
)
}
}