skullbrain_lexer/token.rs
1#![allow(missing_docs)]
2
3/// A single token in the stream, consisting of its kind and span.
4#[derive(Debug, Clone, Hash, PartialEq, Eq)]
5#[cfg_attr(test, derive(serde::Serialize, serde::Deserialize))]
6pub struct Token {
7 kind: TokenKind,
8 len: u16,
9}
10
11/// Different types of tokens in the language.
12#[derive(Debug, Clone, PartialEq, Eq, Hash, variantly::Variantly)]
13#[cfg_attr(test, derive(serde::Serialize, serde::Deserialize))]
14pub enum TokenKind {
15 /// Represents whitespace characters in `SkullScript`.
16 /// - Any space, tab, or newline.
17 Whitespace,
18
19 /// `yo fam`
20 SingleLineComment,
21
22 /// `chat ... thats real`
23 MultiLineComment {
24 /// Do i need to explain this?
25 is_terminated: bool,
26 },
27
28 /// Characters that do not fit any other cateor
29 Unknown,
30
31 /*/// Represents type keywords in `SkullScript`.
32 /// - `aura` for signed integers.
33 /// - `cringe` for unsigned integers.
34 /// - `gigachad` for strings.
35 /// - `chad` for characters.
36 /// - `clutch` for booleans.
37 /// - `vibing` for floating-point numbers.
38 Type,*/
39 /// Represents an identifier in `SkullScript`.
40 /// - Any valid identifier, including emojis.
41 Ident,
42
43 /// Represents literals such as numbers, strings, and booleans in `SkullScript`.
44 /// - Numeric literals: `42`, `3.14`.
45 /// - Boolean literals: `W` (true), `L` (false).
46 /// - String literals: `"..."`.
47 Literial(LiteralKind),
48
49 /// Represents control flow constructs in `SkullScript`.
50 ControlFlow(ControlFlowKind),
51
52 Punctuation(PunctuationKind),
53
54 /// Represents modifiers in `SkullScript`.
55 Modifier(ModifierKind),
56
57 Operator(OperatorKind),
58
59 Declaration(DeclarationKind),
60}
61
62#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, variantly::Variantly)]
63#[cfg_attr(test, derive(serde::Serialize, serde::Deserialize))]
64pub enum ModifierKind {
65
66 /// - `mew` for public visibility.
67 VisibilityPublic,
68
69 /// Represents that a function is non-static in an enum or class
70 InstanceAccess,
71}
72
73// https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_lexer/lib.rs.html
74
75/// Represents different types of literal values.
76#[derive(Debug, Clone, PartialEq, Eq, Hash, variantly::Variantly)]
77#[cfg_attr(test, derive(serde::Serialize, serde::Deserialize))]
78pub enum LiteralKind {
79 /// Integer literals, such as `42`, `0b1010`, `0o755`, or `0x1F`
80 Int {
81 /// The base of the integer literal (binary, octal, decimal, or hexadecimal).
82 base: Base,
83 /// Whether the integer literal is empty (invalid or uninitialized).
84 is_empty: bool,
85 },
86 /// Floating-point literals, such as `3.14` or `2e10`
87 Double {
88 /// The base of the floating-point literal.
89 base: Base,
90 /// Whether the exponent part of the floating-point literal is missing.
91 empty_exponent: bool,
92 },
93 /// String literals, such as `"hello"`
94 Str { is_terminated: bool },
95 /// Boolean literals, such as `true` or `false`
96 Boolean(bool),
97}
98
99// https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_lexer/lib.rs.html
100/// Base of numeric literal encoding according to its prefix.
101#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, variantly::Variantly)]
102#[cfg_attr(test, derive(serde::Serialize, serde::Deserialize))]
103pub enum Base {
104 /// Literal starts with "0b".
105 Binary = 2,
106 /// Literal starts with "0o".
107 Octal = 8,
108 /// Literal doesn't contain a prefix.
109 Decimal = 10,
110 /// Literal starts with "0x".
111 Hexadecimal = 16,
112}
113
114#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, variantly::Variantly)]
115#[cfg_attr(test, derive(serde::Serialize, serde::Deserialize))]
116pub enum PunctuationKind {
117 /// `uwu`
118 OpenParen,
119
120 /// `owo`
121 CloseParen,
122
123 /// `bussin`
124 OpenBrace,
125
126 /// `no cap`
127 CloseBrace,
128
129 /// `.` (acts like a semicolon)
130 Dot,
131
132 /// `n`
133 Comma,
134
135 /// `is`
136 Colon,
137
138 /// bustin
139 Arrow,
140}
141
142#[derive(Debug, Clone, PartialEq, Eq, Hash, variantly::Variantly)]
143#[cfg_attr(test, derive(serde::Serialize, serde::Deserialize))]
144pub enum OperatorKind {
145 /// `skibidi`
146 Assignment,
147
148 /// `valid`
149
150 #[variantly(rename = "equal")]
151 Eq,
152
153 /// `cap`
154
155 #[variantly(rename = "notequal")]
156 NotEq,
157
158 /// `lowkey`
159 Lt,
160
161 /// `flex`
162 Gt,
163
164 /// `lowkey valid`
165 LtEq,
166
167 /// `flex valid`
168 GtEq,
169
170 /// `cut`
171 Minus,
172
173 /// `frfr`
174 And,
175
176 /// `|`
177 Or,
178
179 /// `nah`
180 Not,
181
182 /// `boost`
183 Plus,
184
185 /// `drift`
186 Mul,
187
188 /// `dab`
189 Divide,
190
191 /// `skrrt`
192 Mod,
193
194 MethodChaining,
195}
196
197#[derive(Debug, Clone, PartialEq, Eq, Hash, variantly::Variantly)]
198#[cfg_attr(test, derive(serde::Serialize, serde::Deserialize))]
199pub enum DeclarationKind {
200 /// Represents a variable declaration in `SkullScript`.
201 VariableDeclaration {
202 /// - `gyatt` for mutable variables.
203 /// - `facts` for immutable (constant) variables.
204 is_mutable: bool,
205 },
206
207 /// Represents function declarations in `SkullScript`.
208 /// - `bop` for defining a function.
209 Function,
210
211 /// Represents class (struct) declarations and related constructs in `SkullScript`.
212 /// - `deadass` for defining a struct/class.
213 Class,
214
215 /// Represents trait declarations in `SkullScript`.
216 /// - `vibe` for defining a trait.
217 Trait,
218
219 /// Represents trait implementations in `SkullScript`.
220 /// - `trippin` for implementing a trait.
221 TraitImpl,
222
223 Enum,
224
225 EnumVariant,
226
227 /// Represents an alias declaration in `SkullScript`.
228 /// - `like` for type aliasing.
229 Alias,
230
231 /// Represents an import statement in `SkullScript`.
232 /// - `glizzy` for importing modules.
233 Import,
234}
235
236#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
237#[cfg_attr(test, derive(serde::Serialize, serde::Deserialize))]
238pub enum ControlFlowKind {
239 /// Represents control flow constructs in `SkullScript`.
240 /// - `edgin check` for `if` statements.
241 If,
242
243 /// Represents control flow constructs in `SkullScript`.
244 /// - `only in ohio` for `else` statements.
245 Else,
246
247 /// Represents control flow constructs in `SkullScript`.
248 /// - `goon` for `while` loops.
249 While,
250
251 ForLoopOpen,
252
253 ForLoopClose,
254
255 Match,
256 MatchArmDefault,
257 MatchArmCondition,
258
259 /// `bruh` - Breaks out of the current loop
260 Break,
261
262 /// `grind` - Continues to the next iteration of the loop
263 Continue,
264
265 /// Your return keyword (not sure of the actual keyword from what you provided)
266 Return,
267
268 /// `yeet` - Throws an error
269 Throw,
270
271 /// chill check
272 Try,
273
274 /// that l
275 Catch,
276}
277
278impl Token {
279 /// Creates a new `Token`.
280 pub const fn new(kind: TokenKind, len: u16) -> Self {
281 Token { kind, len }
282 }
283
284 /// Returns the kind of the token.
285 pub const fn kind(&self) -> &TokenKind {
286 &self.kind
287 }
288
289 /// Returns the kind of the token.
290 pub const fn into_kind(self) -> TokenKind {
291 self.kind
292 }
293
294 /// Returns the byte length of the source code token represented by this variant.
295 pub const fn len_repr(&self) -> u16 {
296 self.len
297 }
298}
299
300impl TokenKind {
301 pub fn is(&self, other: &Self) -> bool {
302 match (self, other) {
303 (TokenKind::Literial(a), TokenKind::Literial(b)) => {
304 std::mem::discriminant(a) == std::mem::discriminant(b)
305 }
306 (TokenKind::ControlFlow(a), TokenKind::ControlFlow(b)) => {
307 std::mem::discriminant(a) == std::mem::discriminant(b)
308 }
309 (TokenKind::Punctuation(a), TokenKind::Punctuation(b)) => {
310 std::mem::discriminant(a) == std::mem::discriminant(b)
311 }
312 (TokenKind::Modifier(a), TokenKind::Modifier(b)) => {
313 std::mem::discriminant(a) == std::mem::discriminant(b)
314 }
315 (TokenKind::Operator(a), TokenKind::Operator(b)) => {
316 std::mem::discriminant(a) == std::mem::discriminant(b)
317 }
318 (TokenKind::Declaration(a), TokenKind::Declaration(b)) => {
319 std::mem::discriminant(a) == std::mem::discriminant(b)
320 }
321 _ => std::mem::discriminant(self) == std::mem::discriminant(other),
322 }
323 }
324}