Skip to main content

oak_haskell/parser/
element_type.rs

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