use crate::token::TokenType;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TokenClass {
Keyword,
Type,
Function,
Variable,
String,
Number,
Operator,
Namespace,
Modifier,
Property,
Comment,
Parameter,
EnumMember,
}
pub fn classify(kind: &TokenType) -> Option<TokenClass> {
classify_inner(kind, 0)
}
const MAX_AMBIGUOUS_DEPTH: usize = 3;
fn classify_inner(kind: &TokenType, depth: usize) -> Option<TokenClass> {
match kind {
TokenType::All | TokenType::No | TokenType::Some | TokenType::Any
| TokenType::Both | TokenType::Most | TokenType::Few | TokenType::Many
| TokenType::Cardinal(_) | TokenType::AtLeast(_) | TokenType::AtMost(_) => {
Some(TokenClass::Keyword) }
TokenType::And | TokenType::Or | TokenType::Not
| TokenType::If | TokenType::Then | TokenType::Iff | TokenType::Because
| TokenType::Although
| TokenType::Until | TokenType::Release | TokenType::WeakUntil
| TokenType::Implies => {
Some(TokenClass::Operator) }
TokenType::Must | TokenType::Shall | TokenType::Should | TokenType::Can
| TokenType::May | TokenType::Cannot | TokenType::Would | TokenType::Could
| TokenType::Might | TokenType::Had => {
Some(TokenClass::Keyword) }
TokenType::Let | TokenType::Set | TokenType::Return | TokenType::Break | TokenType::Be
| TokenType::While | TokenType::Repeat | TokenType::For | TokenType::In
| TokenType::From | TokenType::Assert | TokenType::Trust
| TokenType::Require | TokenType::Requires | TokenType::Ensures
| TokenType::Otherwise | TokenType::Else | TokenType::Elif
| TokenType::Call | TokenType::New | TokenType::Either | TokenType::Inspect
| TokenType::Native | TokenType::Escape | TokenType::Given | TokenType::Prove
| TokenType::Auto | TokenType::Read | TokenType::Write | TokenType::Console
| TokenType::File | TokenType::Give | TokenType::Show | TokenType::Push
| TokenType::Pop | TokenType::Copy | TokenType::Through | TokenType::Length
| TokenType::At | TokenType::Add | TokenType::Remove | TokenType::Contains
| TokenType::Union | TokenType::Intersection | TokenType::Inside
| TokenType::Zone | TokenType::Called | TokenType::Size | TokenType::Mapped
| TokenType::Attempt | TokenType::Following | TokenType::Simultaneously
| TokenType::Spawn | TokenType::Send | TokenType::Await | TokenType::Portable
| TokenType::Manifest | TokenType::Chunk | TokenType::Shared | TokenType::Merge
| TokenType::Increase | TokenType::Decrease | TokenType::Tally
| TokenType::SharedSet | TokenType::SharedSequence | TokenType::CollaborativeSequence
| TokenType::SharedMap | TokenType::Divergent | TokenType::Append
| TokenType::Resolve | TokenType::RemoveWins | TokenType::AddWins
| TokenType::YATA | TokenType::Values | TokenType::Check | TokenType::Listen
| TokenType::NetConnect | TokenType::Sleep | TokenType::Sync | TokenType::Mount
| TokenType::Persistent | TokenType::Combined | TokenType::Followed | TokenType::Launch | TokenType::Task
| TokenType::Pipe | TokenType::Receive | TokenType::Stop | TokenType::Try
| TokenType::Into | TokenType::First | TokenType::After | TokenType::Mut => {
Some(TokenClass::Keyword) }
TokenType::Noun(_) => Some(TokenClass::Type),
TokenType::Verb { .. } => Some(TokenClass::Function),
TokenType::Adjective(_) | TokenType::NonIntersectiveAdjective(_) => {
Some(TokenClass::Modifier) }
TokenType::ProperName(_) => Some(TokenClass::Variable),
TokenType::Pronoun { .. } => Some(TokenClass::Variable),
TokenType::Article(_) => Some(TokenClass::Keyword),
TokenType::Is | TokenType::Are | TokenType::Was | TokenType::Were => {
Some(TokenClass::Keyword)
}
TokenType::That | TokenType::Who | TokenType::Whose | TokenType::What | TokenType::Where
| TokenType::When | TokenType::Why | TokenType::Does | TokenType::Do => {
Some(TokenClass::Keyword)
}
TokenType::Identity | TokenType::Equals | TokenType::Reflexive
| TokenType::Reciprocal | TokenType::Respectively => {
Some(TokenClass::Keyword)
}
TokenType::StringLiteral(_) | TokenType::InterpolatedString(_) | TokenType::CharLiteral(_) => Some(TokenClass::String),
TokenType::Number(_) | TokenType::MoneyLiteral { .. } | TokenType::DurationLiteral { .. }
| TokenType::DateLiteral { .. } | TokenType::TimeLiteral { .. } => {
Some(TokenClass::Number)
}
TokenType::Plus | TokenType::Minus | TokenType::Star | TokenType::Slash
| TokenType::Percent | TokenType::Lt | TokenType::Gt | TokenType::LtEq
| TokenType::GtEq | TokenType::EqEq | TokenType::NotEq | TokenType::Arrow
| TokenType::Assign | TokenType::Xor | TokenType::Shifted
| TokenType::Amp | TokenType::VBar | TokenType::Tilde | TokenType::Caret
| TokenType::Dot | TokenType::StarStar | TokenType::SlashSlash
| TokenType::PlusEq | TokenType::MinusEq | TokenType::StarEq
| TokenType::SlashEq | TokenType::PercentEq => {
Some(TokenClass::Operator)
}
TokenType::BlockHeader { .. } => Some(TokenClass::Namespace),
TokenType::Preposition(_) => Some(TokenClass::Keyword),
TokenType::Identifier => Some(TokenClass::Variable),
TokenType::Comparative(_) | TokenType::Superlative(_) | TokenType::Than => {
Some(TokenClass::Modifier)
}
TokenType::CalendarUnit(_) | TokenType::Ago | TokenType::Hence
| TokenType::Before | TokenType::TemporalAdverb(_) => {
Some(TokenClass::Keyword)
}
TokenType::Item | TokenType::Items => Some(TokenClass::Keyword),
TokenType::Adverb(_) | TokenType::ScopalAdverb(_) => Some(TokenClass::Modifier),
TokenType::Focus(_) | TokenType::PresupTrigger(_) | TokenType::Measure(_) => {
Some(TokenClass::Keyword)
}
TokenType::Auxiliary(_) => Some(TokenClass::Keyword),
TokenType::EscapeBlock(_) => Some(TokenClass::String),
TokenType::Performative(_) => Some(TokenClass::Keyword),
TokenType::Exclamation => Some(TokenClass::Keyword),
TokenType::Anything | TokenType::Anyone | TokenType::Nothing
| TokenType::Nobody | TokenType::NoOne | TokenType::Nowhere
| TokenType::Ever | TokenType::Never => {
Some(TokenClass::Keyword)
}
TokenType::Ambiguous { primary, .. } => {
if depth >= MAX_AMBIGUOUS_DEPTH {
return None;
}
classify_inner(primary, depth + 1)
}
TokenType::Particle(_) => Some(TokenClass::Keyword),
TokenType::To => Some(TokenClass::Keyword),
TokenType::Possessive => Some(TokenClass::Operator),
TokenType::Period | TokenType::Comma | TokenType::Colon => Some(TokenClass::Operator),
TokenType::LParen | TokenType::RParen | TokenType::LBracket | TokenType::RBracket
| TokenType::LBrace | TokenType::RBrace => {
Some(TokenClass::Operator)
}
TokenType::Indent | TokenType::Dedent | TokenType::Newline | TokenType::EOF => {
None
}
}
}