1use std::fmt;
4
5use wolf_span::Span;
6
7#[derive(Clone, Debug, PartialEq)]
9pub enum TokenKind {
10 Ident,
12 Int(u64),
14 Float(f64),
16 Str(String),
19 FStr(Vec<FPart>),
21 DocOuter(String),
23 DocInner(String),
25 Newline,
27
28 Module,
30 Extern,
32 Impl,
34 Fn,
36 Pub,
38 Let,
40 Var,
42 Type,
44 Struct,
46 Enum,
48 Interface,
50 If,
52 Else,
54 Match,
56 While,
58 For,
60 In,
62 Return,
64 Break,
66 Continue,
68 Loop,
70 Mut,
72 Own,
74 SelfValue,
76 SelfType,
78 True,
80 False,
82 Async,
84 Await,
86
87 LParen,
89 RParen,
91 LBracket,
93 RBracket,
95 LBrace,
97 RBrace,
99 Comma,
101 Dot,
103 DotDot,
105 DotDotEq,
107 Colon,
109 Question,
111 Underscore,
113 Eq,
115 Arrow,
117 FatArrow,
119 Plus,
121 Minus,
123 Star,
125 Slash,
127 Percent,
129 EqEq,
131 NotEq,
133 Lt,
135 Le,
137 Gt,
139 Ge,
141 AndAnd,
143 OrOr,
145 Bang,
147 Amp,
149 Pipe,
151 Caret,
153 Tilde,
155 Shl,
157 Shr,
159 PlusEq,
161 MinusEq,
163 StarEq,
165 SlashEq,
167 PercentEq,
169 AmpEq,
171 PipeEq,
173 CaretEq,
175 ShlEq,
177 ShrEq,
179
180 Error,
182 Eof,
184}
185
186impl TokenKind {
187 pub fn keyword(text: &str) -> Option<TokenKind> {
189 Some(match text {
190 "module" => TokenKind::Module,
191 "extern" => TokenKind::Extern,
192 "impl" => TokenKind::Impl,
193 "fn" => TokenKind::Fn,
194 "pub" => TokenKind::Pub,
195 "let" => TokenKind::Let,
196 "var" => TokenKind::Var,
197 "type" => TokenKind::Type,
198 "struct" => TokenKind::Struct,
199 "enum" => TokenKind::Enum,
200 "interface" => TokenKind::Interface,
201 "if" => TokenKind::If,
202 "else" => TokenKind::Else,
203 "match" => TokenKind::Match,
204 "while" => TokenKind::While,
205 "for" => TokenKind::For,
206 "in" => TokenKind::In,
207 "return" => TokenKind::Return,
208 "break" => TokenKind::Break,
209 "continue" => TokenKind::Continue,
210 "loop" => TokenKind::Loop,
211 "mut" => TokenKind::Mut,
212 "own" => TokenKind::Own,
213 "self" => TokenKind::SelfValue,
214 "Self" => TokenKind::SelfType,
215 "true" => TokenKind::True,
216 "false" => TokenKind::False,
217 "async" => TokenKind::Async,
218 "await" => TokenKind::Await,
219 _ => return None,
220 })
221 }
222
223 pub fn spelling(&self) -> Option<&'static str> {
225 use TokenKind::*;
226 Some(match self {
227 Module => "module",
228 Extern => "extern",
229 Impl => "impl",
230 Fn => "fn",
231 Pub => "pub",
232 Let => "let",
233 Var => "var",
234 Type => "type",
235 Struct => "struct",
236 Enum => "enum",
237 Interface => "interface",
238 If => "if",
239 Else => "else",
240 Match => "match",
241 While => "while",
242 For => "for",
243 In => "in",
244 Return => "return",
245 Break => "break",
246 Continue => "continue",
247 Loop => "loop",
248 Mut => "mut",
249 Own => "own",
250 SelfValue => "self",
251 SelfType => "Self",
252 True => "true",
253 False => "false",
254 Async => "async",
255 Await => "await",
256 LParen => "(",
257 RParen => ")",
258 LBracket => "[",
259 RBracket => "]",
260 LBrace => "{",
261 RBrace => "}",
262 Comma => ",",
263 Dot => ".",
264 DotDot => "..",
265 DotDotEq => "..=",
266 Colon => ":",
267 Question => "?",
268 Underscore => "_",
269 Eq => "=",
270 Arrow => "->",
271 FatArrow => "=>",
272 Plus => "+",
273 Minus => "-",
274 Star => "*",
275 Slash => "/",
276 Percent => "%",
277 EqEq => "==",
278 NotEq => "!=",
279 Lt => "<",
280 Le => "<=",
281 Gt => ">",
282 Ge => ">=",
283 AndAnd => "&&",
284 OrOr => "||",
285 Bang => "!",
286 Amp => "&",
287 Pipe => "|",
288 Caret => "^",
289 Tilde => "~",
290 Shl => "<<",
291 Shr => ">>",
292 PlusEq => "+=",
293 MinusEq => "-=",
294 StarEq => "*=",
295 SlashEq => "/=",
296 PercentEq => "%=",
297 AmpEq => "&=",
298 PipeEq => "|=",
299 CaretEq => "^=",
300 ShlEq => "<<=",
301 ShrEq => ">>=",
302 Ident | Int(_) | Float(_) | Str(_) | FStr(_) | DocOuter(_) | DocInner(_) | Newline
303 | Error | Eof => return None,
304 })
305 }
306}
307
308impl fmt::Display for TokenKind {
309 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
310 if let Some(spelling) = self.spelling() {
311 return write!(f, "`{spelling}`");
312 }
313 match self {
314 TokenKind::Ident => write!(f, "identifier"),
315 TokenKind::Int(_) => write!(f, "integer literal"),
316 TokenKind::Float(_) => write!(f, "float literal"),
317 TokenKind::Str(_) | TokenKind::FStr(_) => write!(f, "string literal"),
318 TokenKind::DocOuter(_) | TokenKind::DocInner(_) => write!(f, "doc comment"),
319 TokenKind::Newline => write!(f, "new line"),
320 TokenKind::Error => write!(f, "invalid token"),
321 _ => write!(f, "end of file"),
322 }
323 }
324}
325
326#[derive(Clone, Debug, PartialEq)]
328pub struct Token {
329 pub kind: TokenKind,
331 pub span: Span,
333}
334
335#[derive(Clone, Debug, PartialEq)]
337pub enum FPart {
338 Text(String),
340 Expr(Vec<Token>, Span),
343}
344
345#[derive(Clone, Debug, PartialEq, Eq)]
347pub struct Comment {
348 pub span: Span,
350 pub block: bool,
352}