Skip to main content

oak_fortran/kind/
mod.rs

1use oak_core::{ElementType, Token, TokenType, UniversalElementRole, UniversalTokenRole};
2use serde::{Deserialize, Serialize};
3
4pub type FortranToken = Token<FortranSyntaxKind>;
5
6/// Fortran 令牌种类
7#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash, Serialize, Deserialize)]
8pub enum FortranSyntaxKind {
9    // 基本 kind
10    Whitespace,
11    Newline,
12    Comment,
13
14    // 标识符和字面量
15    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    // Fortran 关键字
31    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    // 数据类型
133    Integer,
134    Real,
135    DoublePrecision,
136    Complex,
137    Character,
138    Logical,
139
140    // 操作符
141    Plus,          // +
142    Minus,         // -
143    Star,          // *
144    Slash,         // /
145    StarStar,      // **
146    Power,         // ** (alias for StarStar)
147    Concatenate,   // //
148    Equal,         // ==
149    EqualEqual,    // == (alias for Equal)
150    NotEqual,      // /=
151    SlashEqual,    // /= (alias for NotEqual)
152    LessThan,      // <
153    Less,          // < (alias for LessThan)
154    GreaterThan,   // >
155    Greater,       // > (alias for GreaterThan)
156    LessEqual,     // <=
157    GreaterEqual,  // >=
158    Assign,        // =
159    Arrow,         // =>
160    And,           // .and.
161    Or,            // .or.
162    Not,           // .not.
163    Eqv,           // .eqv.
164    Equivalent,    // .eqv. (alias for Eqv)
165    Neqv,          // .neqv.
166    NotEquivalent, // .neqv. (alias for Neqv)
167    Eq,            // .eq.
168    Ne,            // .ne.
169    Lt,            // .lt.
170    Le,            // .le.
171    Gt,            // .gt.
172    Ge,            // .ge.
173
174    // 分隔符
175    LeftParen,    // (
176    RightParen,   // )
177    LeftBracket,  // [
178    RightBracket, // ]
179    Comma,        // ,
180    Colon,        // :
181    DoubleColon,  // ::
182    ColonColon,   // :: (alias for DoubleColon)
183    Semicolon,    // ;
184    Percent,      // %
185    Ampersand,    // &
186    Dot,          // .
187
188    // 语法节点类型
189    Root,
190
191    // 特殊
192    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}