1use oak_core::{ElementType, Token, TokenType, UniversalElementRole, UniversalTokenRole};
2use serde::{Deserialize, Serialize};
3
4pub type FortranToken = Token<FortranSyntaxKind>;
5
6#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash, Serialize, Deserialize)]
8pub enum FortranSyntaxKind {
9 Whitespace,
11 Newline,
12 Comment,
13
14 Identifier,
16 IntegerLiteral,
17 Number,
18 NumberLiteral,
19 RealLiteral,
20 DoublePrecisionLiteral,
21 ComplexLiteral,
22 CharacterLiteral,
23 CharLiteral,
24 String,
25 StringLiteral,
26 LogicalLiteral,
27 True,
28 False,
29
30 Program,
32 EndProgram,
33 Subroutine,
34 EndSubroutine,
35 Function,
36 EndFunction,
37 Module,
38 EndModule,
39 Interface,
40 EndInterface,
41 Type,
42 EndType,
43 If,
44 Then,
45 ElseIf,
46 Else,
47 EndIf,
48 Do,
49 EndDo,
50 While,
51 Select,
52 Case,
53 EndSelect,
54 Where,
55 EndWhere,
56 Forall,
57 EndForall,
58 Associate,
59 EndAssociate,
60 Block,
61 EndBlock,
62 Critical,
63 EndCritical,
64 Procedure,
65 EndProcedure,
66 Abstract,
67 Allocatable,
68 Allocate,
69 Deallocate,
70 Assignment,
71 Bind,
72 Call,
73 Class,
74 Common,
75 Contains,
76 Continue,
77 Cycle,
78 Data,
79 Default,
80 Dimension,
81 Elemental,
82 Entry,
83 Equivalence,
84 Exit,
85 External,
86 Final,
87 Format,
88 Generic,
89 Go,
90 Goto,
91 Implicit,
92 Import,
93 Include,
94 Intent,
95 Intrinsic,
96 Kind,
97 Len,
98 None,
99 Nullify,
100 Only,
101 Optional,
102 Parameter,
103 Pause,
104 Pointer,
105 Print,
106 Private,
107 Protected,
108 Public,
109 Pure,
110 Read,
111 Recursive,
112 Result,
113 Return,
114 Rewind,
115 Save,
116 Stop,
117 Target,
118 Use,
119 Value,
120 Volatile,
121 Wait,
122 Write,
123 Inquire,
124 Backspace,
125 Close,
126 Open,
127 To,
128 End,
129 Double,
130 Precision,
131
132 Integer,
134 Real,
135 DoublePrecision,
136 Complex,
137 Character,
138 Logical,
139
140 Plus, Minus, Star, Slash, StarStar, Power, Concatenate, Equal, EqualEqual, NotEqual, SlashEqual, LessThan, Less, GreaterThan, Greater, LessEqual, GreaterEqual, Assign, Arrow, And, Or, Not, Eqv, Equivalent, Neqv, NotEquivalent, Eq, Ne, Lt, Le, Gt, Ge, LeftParen, RightParen, LeftBracket, RightBracket, Comma, Colon, DoubleColon, ColonColon, Semicolon, Percent, Ampersand, Dot, Root,
190
191 Error,
193 Eof,
194 EndFile,
195}
196
197impl FortranSyntaxKind {
198 pub fn is_trivia(&self) -> bool {
199 matches!(self, Self::Whitespace | Self::Newline | Self::Comment)
200 }
201
202 pub fn is_keyword(self) -> bool {
203 matches!(
204 self,
205 Self::Program
206 | Self::EndProgram
207 | Self::Subroutine
208 | Self::EndSubroutine
209 | Self::Function
210 | Self::EndFunction
211 | Self::Module
212 | Self::EndModule
213 | Self::Interface
214 | Self::EndInterface
215 | Self::Type
216 | Self::EndType
217 | Self::If
218 | Self::Then
219 | Self::ElseIf
220 | Self::Else
221 | Self::EndIf
222 | Self::Do
223 | Self::EndDo
224 | Self::While
225 | Self::Select
226 | Self::Case
227 | Self::EndSelect
228 | Self::Where
229 | Self::EndWhere
230 | Self::Forall
231 | Self::EndForall
232 | Self::Associate
233 | Self::EndAssociate
234 | Self::Block
235 | Self::EndBlock
236 | Self::Critical
237 | Self::EndCritical
238 | Self::Procedure
239 | Self::EndProcedure
240 | Self::Abstract
241 | Self::Allocatable
242 | Self::Allocate
243 | Self::Deallocate
244 | Self::Assignment
245 | Self::Bind
246 | Self::Call
247 | Self::Class
248 | Self::Common
249 | Self::Contains
250 | Self::Continue
251 | Self::Cycle
252 | Self::Data
253 | Self::Default
254 | Self::Dimension
255 | Self::Elemental
256 | Self::Entry
257 | Self::Equivalence
258 | Self::Exit
259 | Self::External
260 | Self::Final
261 | Self::Format
262 | Self::Generic
263 | Self::Go
264 | Self::Goto
265 | Self::Implicit
266 | Self::Import
267 | Self::Include
268 | Self::Intent
269 | Self::Intrinsic
270 | Self::Kind
271 | Self::Len
272 | Self::None
273 | Self::Nullify
274 | Self::Only
275 | Self::Optional
276 | Self::Parameter
277 | Self::Pause
278 | Self::Pointer
279 | Self::Print
280 | Self::Private
281 | Self::Protected
282 | Self::Public
283 | Self::Pure
284 | Self::Read
285 | Self::Recursive
286 | Self::Result
287 | Self::Return
288 | Self::Rewind
289 | Self::Save
290 | Self::Stop
291 | Self::Target
292 | Self::Use
293 | Self::Value
294 | Self::Volatile
295 | Self::Wait
296 | Self::Write
297 | Self::Inquire
298 | Self::Backspace
299 | Self::Close
300 | Self::Open
301 | Self::To
302 | Self::End
303 | Self::Double
304 | Self::Precision
305 | Self::Integer
306 | Self::Real
307 | Self::DoublePrecision
308 | Self::Complex
309 | Self::Character
310 | Self::Logical
311 )
312 }
313}
314
315impl TokenType for FortranSyntaxKind {
316 const END_OF_STREAM: Self = Self::Eof;
317 type Role = UniversalTokenRole;
318
319 fn role(&self) -> Self::Role {
320 match self {
321 Self::Whitespace | Self::Newline => UniversalTokenRole::Whitespace,
322 Self::Comment => UniversalTokenRole::Comment,
323 Self::Error => UniversalTokenRole::Error,
324 _ if self.is_keyword() => UniversalTokenRole::Keyword,
325 Self::Identifier => UniversalTokenRole::Name,
326 Self::IntegerLiteral
327 | Self::Number
328 | Self::NumberLiteral
329 | Self::RealLiteral
330 | Self::DoublePrecisionLiteral
331 | Self::ComplexLiteral
332 | Self::CharacterLiteral
333 | Self::CharLiteral
334 | Self::String
335 | Self::StringLiteral
336 | Self::LogicalLiteral
337 | Self::True
338 | Self::False => UniversalTokenRole::Literal,
339 Self::Plus
340 | Self::Minus
341 | Self::Star
342 | Self::Slash
343 | Self::StarStar
344 | Self::Concatenate
345 | Self::Equal
346 | Self::EqualEqual
347 | Self::SlashEqual
348 | Self::LessThan
349 | Self::LessEqual
350 | Self::GreaterThan
351 | Self::GreaterEqual
352 | Self::Not
353 | Self::And
354 | Self::Or
355 | Self::Eqv
356 | Self::Neqv => UniversalTokenRole::Operator,
357 Self::LeftParen | Self::RightParen | Self::LeftBracket | Self::RightBracket | Self::Comma | Self::Colon | Self::DoubleColon | Self::Semicolon | Self::Percent | Self::Arrow | Self::Ampersand => UniversalTokenRole::Punctuation,
358 Self::Eof => UniversalTokenRole::Eof,
359 _ => UniversalTokenRole::None,
360 }
361 }
362}
363
364impl ElementType for FortranSyntaxKind {
365 type Role = UniversalElementRole;
366
367 fn role(&self) -> Self::Role {
368 match self {
369 Self::Root => UniversalElementRole::Root,
370 Self::Program | Self::Subroutine | Self::Function | Self::Module | Self::Interface | Self::Type => UniversalElementRole::Definition,
371 Self::Error => UniversalElementRole::Error,
372 _ => UniversalElementRole::None,
373 }
374 }
375
376 fn is_root(&self) -> bool {
377 matches!(self, Self::Root)
378 }
379}