Fork of daniellemaywood.uk/gleam — Wasm codegen work
9.5 kB
362 lines
1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2020 The Gleam contributors
3
4use num_bigint::BigInt;
5use std::fmt;
6
7use ecow::EcoString;
8
9use crate::parse::LiteralFloatValue;
10
11#[derive(Clone, Debug, PartialEq, Eq)]
12pub enum Token {
13 Name {
14 name: EcoString,
15 },
16 UpName {
17 name: EcoString,
18 },
19 DiscardName {
20 name: EcoString,
21 },
22 Int {
23 value: EcoString,
24 int_value: BigInt,
25 },
26 Float {
27 value: EcoString,
28 float_value: LiteralFloatValue,
29 },
30 String {
31 value: EcoString,
32 },
33 CommentDoc {
34 content: EcoString,
35 },
36 // Groupings
37 LeftParen, // (
38 RightParen, // )
39 LeftSquare, // [
40 RightSquare, // ]
41 LeftBrace, // {
42 RightBrace, // }
43 // Int Operators
44 Plus,
45 Minus,
46 Star,
47 Slash,
48 Less,
49 Greater,
50 LessEqual,
51 GreaterEqual,
52 Percent,
53 // Float Operators
54 PlusDot, // '+.'
55 MinusDot, // '-.'
56 StarDot, // '*.'
57 SlashDot, // '/.'
58 LessDot, // '<.'
59 GreaterDot, // '>.'
60 LessEqualDot, // '<=.'
61 GreaterEqualDot, // '>=.'
62 // String Operators
63 Concatenate, // '<>'
64 // Other Punctuation
65 Colon,
66 Comma,
67 Hash, // '#'
68 Bang, // '!'
69 Equal,
70 EqualEqual, // '=='
71 NotEqual, // '!='
72 Vbar, // '|'
73 VbarVbar, // '||'
74 AmperAmper, // '&&'
75 LtLt, // '<<'
76 GtGt, // '>>'
77 Pipe, // '|>'
78 Dot, // '.'
79 RArrow, // '->'
80 LArrow, // '<-'
81 DotDot, // '..'
82 At, // '@'
83 EndOfFile,
84 // Extra
85 CommentNormal,
86 CommentModule,
87 NewLine,
88 // Keywords (alphabetically):
89 As,
90 Assert,
91 Auto,
92 Case,
93 Const,
94 Delegate,
95 Derive,
96 Echo,
97 Else,
98 Fn,
99 If,
100 Implement,
101 Import,
102 Let,
103 Macro,
104 Opaque,
105 Panic,
106 Pub,
107 Test,
108 Todo,
109 Type,
110 Use,
111}
112
113impl Token {
114 pub fn guard_precedence(&self) -> Option<u8> {
115 match self {
116 Self::VbarVbar => Some(1),
117
118 Self::AmperAmper => Some(2),
119
120 Self::EqualEqual | Self::NotEqual => Some(3),
121
122 Self::Less
123 | Self::LessEqual
124 | Self::LessDot
125 | Self::LessEqualDot
126 | Self::GreaterEqual
127 | Self::Greater
128 | Self::GreaterEqualDot
129 | Self::GreaterDot => Some(4),
130
131 Self::Concatenate => Some(5),
132
133 Self::Plus | Self::PlusDot | Self::Minus | Self::MinusDot => Some(6),
134
135 Self::Star | Self::StarDot | Self::Slash | Self::SlashDot | Self::Percent => Some(7),
136
137 Self::Name { .. }
138 | Self::UpName { .. }
139 | Self::DiscardName { .. }
140 | Self::Int { .. }
141 | Self::Float { .. }
142 | Self::String { .. }
143 | Self::CommentDoc { .. }
144 | Self::LeftParen
145 | Self::RightParen
146 | Self::LeftSquare
147 | Self::RightSquare
148 | Self::LeftBrace
149 | Self::RightBrace
150 | Self::Colon
151 | Self::Comma
152 | Self::Hash
153 | Self::Bang
154 | Self::Equal
155 | Self::Vbar
156 | Self::LtLt
157 | Self::GtGt
158 | Self::Pipe
159 | Self::Dot
160 | Self::RArrow
161 | Self::LArrow
162 | Self::DotDot
163 | Self::At
164 | Self::EndOfFile
165 | Self::CommentNormal
166 | Self::CommentModule
167 | Self::NewLine
168 | Self::As
169 | Self::Assert
170 | Self::Auto
171 | Self::Case
172 | Self::Const
173 | Self::Delegate
174 | Self::Derive
175 | Self::Echo
176 | Self::Else
177 | Self::Fn
178 | Self::If
179 | Self::Implement
180 | Self::Import
181 | Self::Let
182 | Self::Macro
183 | Self::Opaque
184 | Self::Panic
185 | Self::Pub
186 | Self::Test
187 | Self::Todo
188 | Self::Type
189 | Self::Use => None,
190 }
191 }
192
193 pub fn is_reserved_word(&self) -> bool {
194 match self {
195 Token::As
196 | Token::Assert
197 | Token::Case
198 | Token::Const
199 | Token::Fn
200 | Token::If
201 | Token::Import
202 | Token::Let
203 | Token::Opaque
204 | Token::Pub
205 | Token::Todo
206 | Token::Type
207 | Token::Use
208 | Token::Auto
209 | Token::Delegate
210 | Token::Derive
211 | Token::Echo
212 | Token::Else
213 | Token::Implement
214 | Token::Macro
215 | Token::Panic
216 | Token::Test => true,
217
218 Token::Name { .. }
219 | Token::UpName { .. }
220 | Token::DiscardName { .. }
221 | Token::Int { .. }
222 | Token::Float { .. }
223 | Token::String { .. }
224 | Token::CommentDoc { .. }
225 | Token::LeftParen
226 | Token::RightParen
227 | Token::LeftSquare
228 | Token::RightSquare
229 | Token::LeftBrace
230 | Token::RightBrace
231 | Token::Plus
232 | Token::Minus
233 | Token::Star
234 | Token::Slash
235 | Token::Less
236 | Token::Greater
237 | Token::LessEqual
238 | Token::GreaterEqual
239 | Token::Percent
240 | Token::PlusDot
241 | Token::MinusDot
242 | Token::StarDot
243 | Token::SlashDot
244 | Token::LessDot
245 | Token::GreaterDot
246 | Token::LessEqualDot
247 | Token::GreaterEqualDot
248 | Token::Concatenate
249 | Token::Colon
250 | Token::Comma
251 | Token::Hash
252 | Token::Bang
253 | Token::Equal
254 | Token::EqualEqual
255 | Token::NotEqual
256 | Token::Vbar
257 | Token::VbarVbar
258 | Token::AmperAmper
259 | Token::LtLt
260 | Token::GtGt
261 | Token::Pipe
262 | Token::Dot
263 | Token::RArrow
264 | Token::LArrow
265 | Token::DotDot
266 | Token::At
267 | Token::EndOfFile
268 | Token::CommentNormal
269 | Token::CommentModule
270 | Token::NewLine => false,
271 }
272 }
273}
274
275impl fmt::Display for Token {
276 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
277 let s = match self {
278 Token::Name { name } | Token::UpName { name } | Token::DiscardName { name } => {
279 name.as_str()
280 }
281 Token::Int {
282 value,
283 int_value: _,
284 }
285 | Token::Float {
286 value,
287 float_value: _,
288 }
289 | Token::String { value } => value.as_str(),
290 Token::AmperAmper => "&&",
291 Token::As => "as",
292 Token::Assert => "assert",
293 Token::At => "@",
294 Token::Auto => "auto",
295 Token::Bang => "!",
296 Token::Case => "case",
297 Token::Colon => ":",
298 Token::Comma => ",",
299 Token::CommentDoc { .. } => "///",
300 Token::CommentModule => "////",
301 Token::CommentNormal => "//",
302 Token::Const => "const",
303 Token::Delegate => "delegate",
304 Token::Derive => "derive",
305 Token::Dot => ".",
306 Token::DotDot => "..",
307 Token::Echo => "echo",
308 Token::Else => "else",
309 Token::NewLine => "NEWLINE",
310 Token::EndOfFile => "EOF",
311 Token::Equal => "=",
312 Token::EqualEqual => "==",
313 Token::Fn => "fn",
314 Token::Greater => ">",
315 Token::GreaterDot => ">.",
316 Token::GreaterEqual => ">=",
317 Token::GreaterEqualDot => ">=.",
318 Token::GtGt => ">>",
319 Token::Hash => "#",
320 Token::If => "if",
321 Token::Implement => "implement",
322 Token::Import => "import",
323 Token::LArrow => "<-",
324 Token::LeftBrace => "{",
325 Token::LeftParen => "(",
326 Token::LeftSquare => "[",
327 Token::Less => "<",
328 Token::LessDot => "<.",
329 Token::LessEqual => "<=",
330 Token::LessEqualDot => "<=.",
331 Token::Let => "let",
332 Token::Concatenate => "<>",
333 Token::LtLt => "<<",
334 Token::Macro => "macro",
335 Token::Minus => "-",
336 Token::MinusDot => "-.",
337 Token::NotEqual => "!=",
338 Token::Opaque => "opaque",
339 Token::Panic => "panic",
340 Token::Percent => "%",
341 Token::Pipe => "|>",
342 Token::Plus => "+",
343 Token::PlusDot => "+.",
344 Token::Pub => "pub",
345 Token::RArrow => "->",
346 Token::RightBrace => "}",
347 Token::RightParen => ")",
348 Token::RightSquare => "]",
349 Token::Slash => "/",
350 Token::SlashDot => "/.",
351 Token::Star => "*",
352 Token::StarDot => "*.",
353 Token::Test => "test",
354 Token::Todo => "todo",
355 Token::Type => "type",
356 Token::Use => "use",
357 Token::Vbar => "|",
358 Token::VbarVbar => "||",
359 };
360 write!(f, "`{s}`")
361 }
362}