use std::{
fmt::{Debug, Display},
rc::Rc,
};
pub type Literal = Rc<str>;
#[derive(Debug, PartialEq, Default, Clone)]
pub enum Token {
#[default]
Unknown,
Illegal(Literal),
Ident(Literal),
#[allow(clippy::upper_case_acronyms)]
EOF,
NewLine,
ThinArrow,
FatArrow,
String(Literal),
Char(Literal),
Int(Literal),
Float(Literal),
Assign,
Bang,
Pipe,
Ampersant,
Hash,
AtSign,
QuestionMark,
Caret,
Tilde,
ShiftRight,
ShiftLeft,
Equal,
NotEqual,
Plus,
Minus,
Slash,
Asterisk,
Percent,
Increase,
Decrease,
LessThan,
GreaterThan,
LessEqual,
GreatEqual,
Comma,
Dot,
TwoDots,
SemiColon,
Colon,
LParen,
RParen,
LBrace,
RBrace,
LBracket,
RBracket,
Namespace,
Null,
If,
Else,
Function,
Const,
Return,
True,
False,
While,
For,
Continue,
Break,
Match,
Struct,
Interface,
Out,
Get,
As,
Not,
And,
Or,
Type,
TypeOf,
Let,
TyInt,
TyFloat,
TyString,
TyChar,
TyBool,
TyArr,
TyMap,
}
impl Token {
pub fn keyword(keyword: &str) -> Token {
match keyword {
"null" => Token::Null,
"fn" => Token::Function,
"true" => Token::True,
"false" => Token::False,
"if" => Token::If,
"else" => Token::Else,
"const" => Token::Const,
"while" => Token::While,
"for" => Token::For,
"return" => Token::Return,
"continue" => Token::Continue,
"break" => Token::Break,
"match" => Token::Match,
"struct" => Token::Struct,
"interface" => Token::Interface,
"get" => Token::Get,
"as" => Token::As,
"out" => Token::Out,
"and" => Token::And,
"or" => Token::Or,
"not" => Token::Not,
"int" => Token::TyInt,
"float" => Token::TyFloat,
"str" => Token::TyString,
"char" => Token::TyChar,
"bool" => Token::TyBool,
"type" => Token::Type,
"typeof" => Token::TypeOf,
"map" => Token::TyMap,
"arr" => Token::TyArr,
"let" => Token::Let,
lit => Token::Ident(Literal::from(lit)),
}
}
pub fn literal(&self) -> Literal {
use Token as T;
match self {
T::Ident(lit) => lit.clone(),
T::Illegal(lit) => lit.clone(),
T::String(lit) => lit.clone(),
T::Char(lit) => lit.clone(),
T::Int(lit) => lit.clone(),
T::Float(lit) => lit.clone(),
T::True => Literal::from("true"),
T::False => Literal::from("false"),
t => Literal::from(t.to_string()),
}
.clone()
}
}
impl Display for Token {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use Token as T;
f.write_str(match self {
T::Ident(_) => "identifier",
T::Illegal(lit) => lit,
T::Unknown => "unknown",
T::EOF => "EOF",
T::TyInt | T::Int(_) => "int",
T::TyFloat | T::Float(_) => "float",
T::TyBool | T::True | T::False => "bool",
T::TyChar | T::Char(_) => "char",
T::TyString | T::String(_) => "str",
T::ThinArrow => "->",
T::FatArrow => "=>",
T::NewLine => "\n",
T::Assign => "=",
T::Bang => "!",
T::Pipe => "|",
T::Ampersant => "&",
T::Hash => "#",
T::AtSign => "@",
T::QuestionMark => "?",
T::Caret => "^",
T::Tilde => "~",
T::Equal => "==",
T::NotEqual => "!=",
T::Plus => "+",
T::Minus => "-",
T::Slash => "/",
T::Percent => "%",
T::ShiftRight => ">>",
T::ShiftLeft => "<<",
T::Asterisk => "*",
T::Increase => "++",
T::Decrease => "--",
T::LessThan => "<",
T::GreaterThan => ">",
T::LessEqual => "<=",
T::GreatEqual => ">=",
T::Comma => ",",
T::Dot => ".",
T::TwoDots => "..",
T::SemiColon => ";",
T::Colon => ":",
T::LParen => "(",
T::RParen => ")",
T::LBrace => "{",
T::RBrace => "}",
T::LBracket => "[",
T::RBracket => "]",
T::Namespace => "::",
T::Null => "null",
T::If => "if",
T::Else => "else",
T::Function => "fn",
T::Const => "const",
T::Return => "return",
T::While => "while",
T::For => "for",
T::Continue => "continue",
T::Break => "break",
T::Match => "match",
T::Struct => "struct",
T::Interface => "interface",
T::Out => "out",
T::Get => "get",
T::As => "as",
T::Not => "not",
T::And => "and",
T::Or => "or",
T::Type => "type",
T::TypeOf => "typeof",
T::TyArr => "arr",
T::TyMap => "map",
T::Let => "let",
})
}
}