⭐️ A friendly language for building type-safe, scalable systems!
1use num_bigint::BigInt;
2use std::fmt;
3
4use ecow::EcoString;
5
6#[derive(Clone, Debug, PartialEq, Eq)]
7pub enum Token {
8 Name { name: EcoString },
9 UpName { name: EcoString },
10 DiscardName { name: EcoString },
11 Int { value: EcoString, int_value: BigInt },
12 Float { value: EcoString },
13 String { value: EcoString },
14 CommentDoc { content: EcoString },
15 // Groupings
16 LeftParen, // (
17 RightParen, // )
18 LeftSquare, // [
19 RightSquare, // ]
20 LeftBrace, // {
21 RightBrace, // }
22 // Int Operators
23 Plus,
24 Minus,
25 Star,
26 Slash,
27 Less,
28 Greater,
29 LessEqual,
30 GreaterEqual,
31 Percent,
32 // Float Operators
33 PlusDot, // '+.'
34 MinusDot, // '-.'
35 StarDot, // '*.'
36 SlashDot, // '/.'
37 LessDot, // '<.'
38 GreaterDot, // '>.'
39 LessEqualDot, // '<=.'
40 GreaterEqualDot, // '>=.'
41 // String Operators
42 LtGt, // '<>'
43 // Other Punctuation
44 Colon,
45 Comma,
46 Hash, // '#'
47 Bang, // '!'
48 Equal,
49 EqualEqual, // '=='
50 NotEqual, // '!='
51 Vbar, // '|'
52 VbarVbar, // '||'
53 AmperAmper, // '&&'
54 LtLt, // '<<'
55 GtGt, // '>>'
56 Pipe, // '|>'
57 Dot, // '.'
58 RArrow, // '->'
59 LArrow, // '<-'
60 DotDot, // '..'
61 At, // '@'
62 EndOfFile,
63 // Extra
64 CommentNormal,
65 CommentModule,
66 NewLine,
67 // Keywords (alphabetically):
68 As,
69 Assert,
70 Auto,
71 Case,
72 Const,
73 Delegate,
74 Derive,
75 Echo,
76 Else,
77 Fn,
78 If,
79 Implement,
80 Import,
81 Let,
82 Macro,
83 Opaque,
84 Panic,
85 Pub,
86 Test,
87 Todo,
88 Type,
89 Use,
90}
91
92impl Token {
93 pub fn guard_precedence(&self) -> Option<u8> {
94 match self {
95 Self::VbarVbar => Some(1),
96
97 Self::AmperAmper => Some(2),
98
99 Self::EqualEqual | Self::NotEqual => Some(3),
100
101 Self::Less
102 | Self::LessEqual
103 | Self::LessDot
104 | Self::LessEqualDot
105 | Self::GreaterEqual
106 | Self::Greater
107 | Self::GreaterEqualDot
108 | Self::GreaterDot => Some(4),
109
110 Self::Plus | Self::PlusDot | Self::Minus | Self::MinusDot => Some(5),
111
112 Self::Star | Self::StarDot | Self::Slash | Self::SlashDot | Self::Percent => Some(6),
113
114 _ => None,
115 }
116 }
117
118 pub fn is_reserved_word(&self) -> bool {
119 match self {
120 Token::As
121 | Token::Assert
122 | Token::Case
123 | Token::Const
124 | Token::Fn
125 | Token::If
126 | Token::Import
127 | Token::Let
128 | Token::Opaque
129 | Token::Pub
130 | Token::Todo
131 | Token::Type
132 | Token::Use
133 | Token::Auto
134 | Token::Delegate
135 | Token::Derive
136 | Token::Echo
137 | Token::Else
138 | Token::Implement
139 | Token::Macro
140 | Token::Panic
141 | Token::Test => true,
142
143 Token::Name { .. }
144 | Token::UpName { .. }
145 | Token::DiscardName { .. }
146 | Token::Int { .. }
147 | Token::Float { .. }
148 | Token::String { .. }
149 | Token::CommentDoc { .. }
150 | Token::LeftParen
151 | Token::RightParen
152 | Token::LeftSquare
153 | Token::RightSquare
154 | Token::LeftBrace
155 | Token::RightBrace
156 | Token::Plus
157 | Token::Minus
158 | Token::Star
159 | Token::Slash
160 | Token::Less
161 | Token::Greater
162 | Token::LessEqual
163 | Token::GreaterEqual
164 | Token::Percent
165 | Token::PlusDot
166 | Token::MinusDot
167 | Token::StarDot
168 | Token::SlashDot
169 | Token::LessDot
170 | Token::GreaterDot
171 | Token::LessEqualDot
172 | Token::GreaterEqualDot
173 | Token::LtGt
174 | Token::Colon
175 | Token::Comma
176 | Token::Hash
177 | Token::Bang
178 | Token::Equal
179 | Token::EqualEqual
180 | Token::NotEqual
181 | Token::Vbar
182 | Token::VbarVbar
183 | Token::AmperAmper
184 | Token::LtLt
185 | Token::GtGt
186 | Token::Pipe
187 | Token::Dot
188 | Token::RArrow
189 | Token::LArrow
190 | Token::DotDot
191 | Token::At
192 | Token::EndOfFile
193 | Token::CommentNormal
194 | Token::CommentModule
195 | Token::NewLine => false,
196 }
197 }
198}
199
200impl fmt::Display for Token {
201 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202 let s = match self {
203 Token::Name { name } | Token::UpName { name } | Token::DiscardName { name } => {
204 name.as_str()
205 }
206 Token::Int {
207 value,
208 int_value: _,
209 }
210 | Token::Float { value }
211 | Token::String { value } => value.as_str(),
212 Token::AmperAmper => "&&",
213 Token::As => "as",
214 Token::Assert => "assert",
215 Token::At => "@",
216 Token::Auto => "auto",
217 Token::Bang => "!",
218 Token::Case => "case",
219 Token::Colon => ":",
220 Token::Comma => ",",
221 Token::CommentDoc { .. } => "///",
222 Token::CommentModule => "////",
223 Token::CommentNormal => "//",
224 Token::Const => "const",
225 Token::Delegate => "delegate",
226 Token::Derive => "derive",
227 Token::Dot => ".",
228 Token::DotDot => "..",
229 Token::Echo => "echo",
230 Token::Else => "else",
231 Token::NewLine => "NEWLINE",
232 Token::EndOfFile => "EOF",
233 Token::Equal => "=",
234 Token::EqualEqual => "==",
235 Token::Fn => "fn",
236 Token::Greater => ">",
237 Token::GreaterDot => ">.",
238 Token::GreaterEqual => ">=",
239 Token::GreaterEqualDot => ">=.",
240 Token::GtGt => ">>",
241 Token::Hash => "#",
242 Token::If => "if",
243 Token::Implement => "implement",
244 Token::Import => "import",
245 Token::LArrow => "<-",
246 Token::LeftBrace => "{",
247 Token::LeftParen => "(",
248 Token::LeftSquare => "[",
249 Token::Less => "<",
250 Token::LessDot => "<.",
251 Token::LessEqual => "<=",
252 Token::LessEqualDot => "<=.",
253 Token::Let => "let",
254 Token::LtGt => "<>",
255 Token::LtLt => "<<",
256 Token::Macro => "macro",
257 Token::Minus => "-",
258 Token::MinusDot => "-.",
259 Token::NotEqual => "!=",
260 Token::Opaque => "opaque",
261 Token::Panic => "panic",
262 Token::Percent => "%",
263 Token::Pipe => "|>",
264 Token::Plus => "+",
265 Token::PlusDot => "+.",
266 Token::Pub => "pub",
267 Token::RArrow => "->",
268 Token::RightBrace => "}",
269 Token::RightParen => ")",
270 Token::RightSquare => "]",
271 Token::Slash => "/",
272 Token::SlashDot => "/.",
273 Token::Star => "*",
274 Token::StarDot => "*.",
275 Token::Test => "test",
276 Token::Todo => "todo",
277 Token::Type => "type",
278 Token::Use => "use",
279 Token::Vbar => "|",
280 Token::VbarVbar => "||",
281 };
282 write!(f, "`{s}`")
283 }
284}