Skip to main content

oak_haskell/lexer/
token_type.rs

1use oak_core::Token;
2#[cfg(feature = "serde")]
3use serde::{Deserialize, Serialize};
4
5/// A token in the Haskell language.
6pub type HaskellToken = Token<HaskellTokenType>;
7
8/// Token types for the Haskell language.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11pub enum HaskellTokenType {
12    /// Whitespace characters.
13    Whitespace,
14    /// Newline characters.
15    Newline,
16    /// Comments.
17    Comment,
18
19    // Keywords
20    /// `case` keyword.
21    Case,
22    /// `class` keyword.
23    Class,
24    /// `data` keyword.
25    Data,
26    /// `default` keyword.
27    Default,
28    /// `deriving` keyword.
29    Deriving,
30    /// `do` keyword.
31    Do,
32    /// `else` keyword.
33    Else,
34    /// `foreign` keyword.
35    Foreign,
36    /// `if` keyword.
37    If,
38    /// `import` keyword.
39    Import,
40    /// `in` keyword.
41    In,
42    /// `infix` keyword.
43    Infix,
44    /// `infixl` keyword.
45    Infixl,
46    /// `infixr` keyword.
47    Infixr,
48    /// `instance` keyword.
49    Instance,
50    /// `let` keyword.
51    Let,
52    /// `module` keyword.
53    Module,
54    /// `newtype` keyword.
55    Newtype,
56    /// `of` keyword.
57    Of,
58    /// `then` keyword.
59    Then,
60    /// `type` keyword.
61    Type,
62    /// `where` keyword.
63    Where,
64    /// `_` keyword.
65    Underscore,
66    /// `as` keyword.
67    As,
68    /// `qualified` keyword.
69    Qualified,
70    /// `hiding` keyword.
71    Hiding,
72
73    // Identifiers and Literals
74    /// An identifier.
75    Identifier,
76    /// A constructor identifier.
77    Constructor,
78    /// A number literal.
79    Number,
80    /// An integer literal.
81    Integer,
82    /// A float literal.
83    Float,
84    /// A string literal.
85    String,
86    /// A string literal.
87    StringLiteral,
88    /// A char literal.
89    Char,
90    /// A char literal.
91    CharLiteral,
92
93    // Operators and Punctuation
94    /// `+` operator.
95    Plus,
96    /// `-` operator.
97    Minus,
98    /// `*` operator.
99    Star,
100    /// `/` operator.
101    Slash,
102    /// `%` operator.
103    Percent,
104    /// `=` operator (assignment).
105    Assign,
106    /// `==` operator.
107    Equal,
108    /// `/=` operator.
109    NotEqual,
110    /// `<` operator.
111    Less,
112    /// `>` operator.
113    Greater,
114    /// `<=` operator.
115    LessEqual,
116    /// `>=` operator.
117    GreaterEqual,
118    /// `&&` operator.
119    And,
120    /// `||` operator.
121    Or,
122    /// `->` operator.
123    Arrow,
124    /// `<-` operator.
125    LeftArrow,
126    /// `=>` operator.
127    DoubleArrow,
128    /// `|` operator.
129    Pipe,
130    /// `&` operator.
131    Ampersand,
132    /// `!` operator.
133    Bang,
134    /// `!` operator.
135    Exclamation,
136    /// `?` operator.
137    Question,
138    /// `:` operator.
139    Colon,
140    /// `::` operator.
141    DoubleColon,
142    /// `;` punctuation.
143    Semicolon,
144    /// `,` punctuation.
145    Comma,
146    /// `.` operator.
147    Dot,
148    /// `..` operator.
149    DoubleDot,
150    /// `..` operator.
151    DotDot,
152    /// `$` operator.
153    Dollar,
154    /// `@` operator.
155    At,
156    /// `~` operator.
157    Tilde,
158    /// `\` operator.
159    Backslash,
160    /// `++` operator.
161    Append,
162    /// `(` punctuation.
163    LeftParen,
164    /// `)` punctuation.
165    RightParen,
166    /// `[` punctuation.
167    LeftBracket,
168    /// `]` punctuation.
169    RightBracket,
170    /// `{` punctuation.
171    LeftBrace,
172    /// `}` punctuation.
173    RightBrace,
174    /// `'` punctuation.
175    Quote,
176    /// `` ` `` punctuation.
177    Backquote,
178    /// `` ` `` punctuation.
179    Backtick,
180
181    // Elements
182    /// A function.
183    Function,
184    /// A data declaration.
185    DataDeclaration,
186    /// A module declaration.
187    ModuleDeclaration,
188    /// An import declaration.
189    ImportDeclaration,
190    /// A type alias declaration.
191    TypeAliasDeclaration,
192    /// A type signature.
193    TypeSignature,
194    /// A function equation.
195    Equation,
196    /// A pattern.
197    Pattern,
198    /// A literal expression.
199    LiteralExpression,
200    /// An identifier expression.
201    IdentifierExpression,
202    /// A prefix expression.
203    PrefixExpression,
204    /// An infix expression.
205    InfixExpression,
206    /// A function application.
207    ApplicationExpression,
208    /// A lambda expression.
209    LambdaExpression,
210    /// A let expression.
211    LetExpression,
212    /// A case expression.
213    CaseExpression,
214    /// A case arm.
215    CaseArm,
216    /// Root element.
217    Root,
218
219    /// Error token.
220    Error,
221    /// End of file token.
222    Eof,
223}
224
225impl HaskellTokenType {
226    /// Returns true if the token type is a keyword.
227    pub fn is_keyword(&self) -> bool {
228        matches!(
229            self,
230            Self::Case
231                | Self::Class
232                | Self::Data
233                | Self::Default
234                | Self::Deriving
235                | Self::Do
236                | Self::Else
237                | Self::Foreign
238                | Self::If
239                | Self::Import
240                | Self::In
241                | Self::Infix
242                | Self::Infixl
243                | Self::Infixr
244                | Self::Instance
245                | Self::Let
246                | Self::Module
247                | Self::Newtype
248                | Self::Of
249                | Self::Then
250                | Self::Type
251                | Self::Where
252                | Self::As
253                | Self::Qualified
254                | Self::Hiding
255        )
256    }
257}
258
259impl oak_core::TokenType for HaskellTokenType {
260    const END_OF_STREAM: Self = Self::Eof;
261    type Role = oak_core::UniversalTokenRole;
262
263    fn role(&self) -> Self::Role {
264        match self {
265            Self::Whitespace | Self::Newline => oak_core::UniversalTokenRole::Whitespace,
266            Self::Comment => oak_core::UniversalTokenRole::Comment,
267            Self::Identifier | Self::Constructor => oak_core::UniversalTokenRole::Name,
268            Self::Number | Self::Integer | Self::Float | Self::String | Self::StringLiteral | Self::Char | Self::CharLiteral => oak_core::UniversalTokenRole::Literal,
269            _ if self.is_keyword() => oak_core::UniversalTokenRole::Keyword,
270            Self::Plus
271            | Self::Minus
272            | Self::Star
273            | Self::Slash
274            | Self::Percent
275            | Self::Assign
276            | Self::Equal
277            | Self::NotEqual
278            | Self::Less
279            | Self::Greater
280            | Self::LessEqual
281            | Self::GreaterEqual
282            | Self::And
283            | Self::Or
284            | Self::Arrow
285            | Self::LeftArrow
286            | Self::DoubleArrow
287            | Self::Pipe
288            | Self::Ampersand
289            | Self::Bang
290            | Self::Exclamation
291            | Self::Question
292            | Self::Colon
293            | Self::DoubleColon
294            | Self::Dollar
295            | Self::At
296            | Self::Tilde
297            | Self::Backslash
298            | Self::Append => oak_core::UniversalTokenRole::Operator,
299            Self::Semicolon
300            | Self::Comma
301            | Self::Dot
302            | Self::DoubleDot
303            | Self::DotDot
304            | Self::LeftParen
305            | Self::RightParen
306            | Self::LeftBracket
307            | Self::RightBracket
308            | Self::LeftBrace
309            | Self::RightBrace
310            | Self::Underscore
311            | Self::Quote
312            | Self::Backquote
313            | Self::Backtick => oak_core::UniversalTokenRole::Punctuation,
314            Self::Eof => oak_core::UniversalTokenRole::Eof,
315            _ => oak_core::UniversalTokenRole::None,
316        }
317    }
318
319    fn is_ignored(&self) -> bool {
320        matches!(self, Self::Whitespace | Self::Newline | Self::Comment)
321    }
322
323    fn is_comment(&self) -> bool {
324        matches!(self, Self::Comment)
325    }
326
327    fn is_whitespace(&self) -> bool {
328        matches!(self, Self::Whitespace | Self::Newline)
329    }
330}