1use oak_core::{Source, Token, TokenType, UniversalElementRole, UniversalTokenRole};
2#[cfg(feature = "serde")]
3use serde::{Deserialize, Serialize};
4
5pub type HaskellToken = Token<HaskellTokenType>;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9pub enum HaskellTokenType {
10 Whitespace,
11 Newline,
12 Comment,
13 Case,
14 Class,
15 Data,
16 Default,
17 Deriving,
18 Do,
19 Else,
20 Foreign,
21 If,
22 Import,
23 In,
24 Infix,
25 Infixl,
26 Infixr,
27 Instance,
28 Let,
29 Module,
30 Newtype,
31 Of,
32 Then,
33 Type,
34 Where,
35 Underscore,
36 As,
37 Qualified,
38 Hiding,
39 Identifier,
40 Constructor,
41 Number,
42 Integer,
43 Float,
44 String,
45 StringLiteral,
46 Char,
47 CharLiteral,
48 Plus,
49 Minus,
50 Star,
51 Slash,
52 Percent,
53 Assign,
54 Equal,
55 NotEqual,
56 Less,
57 Greater,
58 LessEqual,
59 GreaterEqual,
60 And,
61 Or,
62 Arrow,
63 LeftArrow,
64 DoubleArrow,
65 Pipe,
66 Ampersand,
67 Bang,
68 Exclamation,
69 Question,
70 Colon,
71 DoubleColon,
72 Semicolon,
73 Comma,
74 Dot,
75 DoubleDot,
76 DotDot,
77 Dollar,
78 At,
79 Tilde,
80 Backslash,
81 Append,
82 LeftParen,
83 RightParen,
84 LeftBracket,
85 RightBracket,
86 LeftBrace,
87 RightBrace,
88 Quote,
89 Backquote,
90 Backtick,
91 Function,
92 DataDeclaration,
93 ModuleDeclaration,
94 Root,
95 Error,
96 Eof,
97}
98
99impl HaskellTokenType {
100 pub fn is_keyword(&self) -> bool {
101 matches!(
102 self,
103 Self::Case
104 | Self::Class
105 | Self::Data
106 | Self::Default
107 | Self::Deriving
108 | Self::Do
109 | Self::Else
110 | Self::Foreign
111 | Self::If
112 | Self::Import
113 | Self::In
114 | Self::Infix
115 | Self::Infixl
116 | Self::Infixr
117 | Self::Instance
118 | Self::Let
119 | Self::Module
120 | Self::Newtype
121 | Self::Of
122 | Self::Then
123 | Self::Type
124 | Self::Where
125 | Self::As
126 | Self::Qualified
127 | Self::Hiding
128 )
129 }
130}
131
132impl oak_core::TokenType for HaskellTokenType {
133 const END_OF_STREAM: Self = Self::Eof;
134 type Role = oak_core::UniversalTokenRole;
135
136 fn role(&self) -> Self::Role {
137 match self {
138 Self::Whitespace | Self::Newline => oak_core::UniversalTokenRole::Whitespace,
139 Self::Comment => oak_core::UniversalTokenRole::Comment,
140 Self::Identifier | Self::Constructor => oak_core::UniversalTokenRole::Name,
141 Self::Number | Self::Integer | Self::Float | Self::String | Self::StringLiteral | Self::Char | Self::CharLiteral => oak_core::UniversalTokenRole::Literal,
142 _ if self.is_keyword() => oak_core::UniversalTokenRole::Keyword,
143 Self::Plus
144 | Self::Minus
145 | Self::Star
146 | Self::Slash
147 | Self::Percent
148 | Self::Assign
149 | Self::Equal
150 | Self::NotEqual
151 | Self::Less
152 | Self::Greater
153 | Self::LessEqual
154 | Self::GreaterEqual
155 | Self::And
156 | Self::Or
157 | Self::Arrow
158 | Self::LeftArrow
159 | Self::DoubleArrow
160 | Self::Pipe
161 | Self::Ampersand
162 | Self::Bang
163 | Self::Exclamation
164 | Self::Question
165 | Self::Colon
166 | Self::DoubleColon
167 | Self::Dollar
168 | Self::At
169 | Self::Tilde
170 | Self::Backslash
171 | Self::Append => oak_core::UniversalTokenRole::Operator,
172 Self::Semicolon
173 | Self::Comma
174 | Self::Dot
175 | Self::DoubleDot
176 | Self::DotDot
177 | Self::LeftParen
178 | Self::RightParen
179 | Self::LeftBracket
180 | Self::RightBracket
181 | Self::LeftBrace
182 | Self::RightBrace
183 | Self::Underscore
184 | Self::Quote
185 | Self::Backquote
186 | Self::Backtick => oak_core::UniversalTokenRole::Punctuation,
187 Self::Eof => oak_core::UniversalTokenRole::Eof,
188 _ => oak_core::UniversalTokenRole::None,
189 }
190 }
191
192 fn is_ignored(&self) -> bool {
193 matches!(self, Self::Whitespace | Self::Newline | Self::Comment)
194 }
195
196 fn is_comment(&self) -> bool {
197 matches!(self, Self::Comment)
198 }
199
200 fn is_whitespace(&self) -> bool {
201 matches!(self, Self::Whitespace | Self::Newline)
202 }
203}