Skip to main content

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}