1use cove_diag::Span;
4
5#[derive(Clone, Debug, PartialEq)]
7pub struct Token {
8 pub kind: TokenKind,
9 pub span: Span,
10 pub preceded_by_newline: bool,
17}
18
19#[derive(Clone, Copy, Debug, PartialEq, Eq)]
21pub enum Keyword {
22 Async,
23 Await,
24 Break,
25 Continue,
26 Dyn,
27 Else,
28 Enum,
29 Export,
30 Fn,
31 For,
32 If,
33 Impl,
34 In,
35 Is,
36 Let,
37 Match,
38 Opaque,
39 Return,
40 Scope,
41 SelfValue,
42 Struct,
43 Test,
44 Trait,
45 Type,
46 Use,
47 Var,
48 While,
49}
50
51impl Keyword {
52 pub fn from_text(text: &str) -> Option<Keyword> {
53 Some(match text {
54 "async" => Keyword::Async,
55 "await" => Keyword::Await,
56 "break" => Keyword::Break,
57 "continue" => Keyword::Continue,
58 "dyn" => Keyword::Dyn,
59 "else" => Keyword::Else,
60 "enum" => Keyword::Enum,
61 "export" => Keyword::Export,
62 "fn" => Keyword::Fn,
63 "for" => Keyword::For,
64 "if" => Keyword::If,
65 "impl" => Keyword::Impl,
66 "in" => Keyword::In,
67 "is" => Keyword::Is,
68 "let" => Keyword::Let,
69 "match" => Keyword::Match,
70 "opaque" => Keyword::Opaque,
71 "return" => Keyword::Return,
72 "scope" => Keyword::Scope,
73 "self" => Keyword::SelfValue,
74 "struct" => Keyword::Struct,
75 "test" => Keyword::Test,
76 "trait" => Keyword::Trait,
77 "type" => Keyword::Type,
78 "use" => Keyword::Use,
79 "var" => Keyword::Var,
80 "while" => Keyword::While,
81 _ => return None,
82 })
83 }
84
85 pub fn as_str(self) -> &'static str {
86 match self {
87 Keyword::Async => "async",
88 Keyword::Await => "await",
89 Keyword::Break => "break",
90 Keyword::Continue => "continue",
91 Keyword::Dyn => "dyn",
92 Keyword::Else => "else",
93 Keyword::Enum => "enum",
94 Keyword::Export => "export",
95 Keyword::Fn => "fn",
96 Keyword::For => "for",
97 Keyword::If => "if",
98 Keyword::Impl => "impl",
99 Keyword::In => "in",
100 Keyword::Is => "is",
101 Keyword::Let => "let",
102 Keyword::Match => "match",
103 Keyword::Opaque => "opaque",
104 Keyword::Return => "return",
105 Keyword::Scope => "scope",
106 Keyword::SelfValue => "self",
107 Keyword::Struct => "struct",
108 Keyword::Test => "test",
109 Keyword::Trait => "trait",
110 Keyword::Type => "type",
111 Keyword::Use => "use",
112 Keyword::Var => "var",
113 Keyword::While => "while",
114 }
115 }
116}
117
118#[derive(Clone, Debug, PartialEq)]
122pub enum StringPart {
123 Text(String),
125 Interpolation { source: String, span: Span },
127}
128
129#[derive(Clone, Debug, PartialEq)]
130pub enum TokenKind {
131 Ident(String),
132 Keyword(Keyword),
133 Bool(bool),
135 Int(i64),
136 Float(f64),
137 Duration(i64),
139 Str(Vec<StringPart>),
140 DocComment(String),
142
143 LParen,
145 RParen,
146 LBrace,
147 RBrace,
148 LBracket,
149 RBracket,
150
151 Comma,
153 Colon,
154 Dot,
155 DotDot,
156 DotDotLt,
157 Ellipsis,
158 Arrow,
159 FatArrow,
160 Question,
161 Underscore,
162
163 Eq,
165 EqEq,
166 Bang,
167 BangEq,
168 Lt,
169 LtEq,
170 Gt,
171 GtEq,
172 Plus,
173 Minus,
174 Star,
175 Slash,
176 Percent,
177 AmpAmp,
178 PipePipe,
179 PlusEq,
180 MinusEq,
181 StarEq,
182 SlashEq,
183 PercentEq,
184
185 Eof,
186}
187
188impl TokenKind {
189 pub fn describe(&self) -> String {
191 match self {
192 TokenKind::Ident(name) => format!("identifier `{name}`"),
193 TokenKind::Keyword(k) => format!("keyword `{}`", k.as_str()),
194 TokenKind::Bool(b) => format!("`{b}`"),
195 TokenKind::Int(_) => "integer literal".into(),
196 TokenKind::Float(_) => "float literal".into(),
197 TokenKind::Duration(_) => "duration literal".into(),
198 TokenKind::Str(_) => "string literal".into(),
199 TokenKind::DocComment(_) => "doc comment".into(),
200 TokenKind::Eof => "end of file".into(),
201 other => format!("`{}`", other.symbol().unwrap_or("?")),
202 }
203 }
204
205 pub fn symbol(&self) -> Option<&'static str> {
207 Some(match self {
208 TokenKind::LParen => "(",
209 TokenKind::RParen => ")",
210 TokenKind::LBrace => "{",
211 TokenKind::RBrace => "}",
212 TokenKind::LBracket => "[",
213 TokenKind::RBracket => "]",
214 TokenKind::Comma => ",",
215 TokenKind::Colon => ":",
216 TokenKind::Dot => ".",
217 TokenKind::DotDot => "..",
218 TokenKind::DotDotLt => "..<",
219 TokenKind::Ellipsis => "...",
220 TokenKind::Arrow => "->",
221 TokenKind::FatArrow => "=>",
222 TokenKind::Question => "?",
223 TokenKind::Underscore => "_",
224 TokenKind::Eq => "=",
225 TokenKind::EqEq => "==",
226 TokenKind::Bang => "!",
227 TokenKind::BangEq => "!=",
228 TokenKind::Lt => "<",
229 TokenKind::LtEq => "<=",
230 TokenKind::Gt => ">",
231 TokenKind::GtEq => ">=",
232 TokenKind::Plus => "+",
233 TokenKind::Minus => "-",
234 TokenKind::Star => "*",
235 TokenKind::Slash => "/",
236 TokenKind::Percent => "%",
237 TokenKind::AmpAmp => "&&",
238 TokenKind::PipePipe => "||",
239 TokenKind::PlusEq => "+=",
240 TokenKind::MinusEq => "-=",
241 TokenKind::StarEq => "*=",
242 TokenKind::SlashEq => "/=",
243 TokenKind::PercentEq => "%=",
244 _ => return None,
245 })
246 }
247}