use std::fmt;
use wolf_span::Span;
#[derive(Clone, Debug, PartialEq)]
pub enum TokenKind {
Ident,
Int(u64),
Float(f64),
Str(String),
FStr(Vec<FPart>),
DocOuter(String),
DocInner(String),
Newline,
Module,
Extern,
Impl,
Fn,
Pub,
Let,
Var,
Type,
Struct,
Enum,
Interface,
If,
Else,
Match,
While,
For,
In,
Return,
Break,
Continue,
Loop,
Mut,
Own,
SelfValue,
SelfType,
True,
False,
Async,
Await,
LParen,
RParen,
LBracket,
RBracket,
LBrace,
RBrace,
Comma,
Dot,
DotDot,
DotDotEq,
Colon,
Question,
Underscore,
Eq,
Arrow,
FatArrow,
Plus,
Minus,
Star,
Slash,
Percent,
EqEq,
NotEq,
Lt,
Le,
Gt,
Ge,
AndAnd,
OrOr,
Bang,
Amp,
Pipe,
Caret,
Tilde,
Shl,
Shr,
PlusEq,
MinusEq,
StarEq,
SlashEq,
PercentEq,
AmpEq,
PipeEq,
CaretEq,
ShlEq,
ShrEq,
Error,
Eof,
}
impl TokenKind {
pub fn keyword(text: &str) -> Option<TokenKind> {
Some(match text {
"module" => TokenKind::Module,
"extern" => TokenKind::Extern,
"impl" => TokenKind::Impl,
"fn" => TokenKind::Fn,
"pub" => TokenKind::Pub,
"let" => TokenKind::Let,
"var" => TokenKind::Var,
"type" => TokenKind::Type,
"struct" => TokenKind::Struct,
"enum" => TokenKind::Enum,
"interface" => TokenKind::Interface,
"if" => TokenKind::If,
"else" => TokenKind::Else,
"match" => TokenKind::Match,
"while" => TokenKind::While,
"for" => TokenKind::For,
"in" => TokenKind::In,
"return" => TokenKind::Return,
"break" => TokenKind::Break,
"continue" => TokenKind::Continue,
"loop" => TokenKind::Loop,
"mut" => TokenKind::Mut,
"own" => TokenKind::Own,
"self" => TokenKind::SelfValue,
"Self" => TokenKind::SelfType,
"true" => TokenKind::True,
"false" => TokenKind::False,
"async" => TokenKind::Async,
"await" => TokenKind::Await,
_ => return None,
})
}
pub fn spelling(&self) -> Option<&'static str> {
use TokenKind::*;
Some(match self {
Module => "module",
Extern => "extern",
Impl => "impl",
Fn => "fn",
Pub => "pub",
Let => "let",
Var => "var",
Type => "type",
Struct => "struct",
Enum => "enum",
Interface => "interface",
If => "if",
Else => "else",
Match => "match",
While => "while",
For => "for",
In => "in",
Return => "return",
Break => "break",
Continue => "continue",
Loop => "loop",
Mut => "mut",
Own => "own",
SelfValue => "self",
SelfType => "Self",
True => "true",
False => "false",
Async => "async",
Await => "await",
LParen => "(",
RParen => ")",
LBracket => "[",
RBracket => "]",
LBrace => "{",
RBrace => "}",
Comma => ",",
Dot => ".",
DotDot => "..",
DotDotEq => "..=",
Colon => ":",
Question => "?",
Underscore => "_",
Eq => "=",
Arrow => "->",
FatArrow => "=>",
Plus => "+",
Minus => "-",
Star => "*",
Slash => "/",
Percent => "%",
EqEq => "==",
NotEq => "!=",
Lt => "<",
Le => "<=",
Gt => ">",
Ge => ">=",
AndAnd => "&&",
OrOr => "||",
Bang => "!",
Amp => "&",
Pipe => "|",
Caret => "^",
Tilde => "~",
Shl => "<<",
Shr => ">>",
PlusEq => "+=",
MinusEq => "-=",
StarEq => "*=",
SlashEq => "/=",
PercentEq => "%=",
AmpEq => "&=",
PipeEq => "|=",
CaretEq => "^=",
ShlEq => "<<=",
ShrEq => ">>=",
Ident | Int(_) | Float(_) | Str(_) | FStr(_) | DocOuter(_) | DocInner(_) | Newline
| Error | Eof => return None,
})
}
}
impl fmt::Display for TokenKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(spelling) = self.spelling() {
return write!(f, "`{spelling}`");
}
match self {
TokenKind::Ident => write!(f, "identifier"),
TokenKind::Int(_) => write!(f, "integer literal"),
TokenKind::Float(_) => write!(f, "float literal"),
TokenKind::Str(_) | TokenKind::FStr(_) => write!(f, "string literal"),
TokenKind::DocOuter(_) | TokenKind::DocInner(_) => write!(f, "doc comment"),
TokenKind::Newline => write!(f, "new line"),
TokenKind::Error => write!(f, "invalid token"),
_ => write!(f, "end of file"),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct Token {
pub kind: TokenKind,
pub span: Span,
}
#[derive(Clone, Debug, PartialEq)]
pub enum FPart {
Text(String),
Expr(Vec<Token>, Span),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Comment {
pub span: Span,
pub block: bool,
}