Skip to main content

oak_haskell/lexer/
token_type.rs

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