Skip to main content

oak_erlang/kind/
mod.rs

1use oak_core::{ElementType, Token, TokenType, UniversalElementRole, UniversalTokenRole};
2use serde::{Deserialize, Serialize};
3
4pub type ErlangToken = Token<ErlangSyntaxKind>;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
7pub enum ErlangSyntaxKind {
8    // 基本 kind
9    Whitespace,
10    Newline,
11    Comment,
12
13    // 标识符和字面量
14    Identifier,
15    Atom,
16    Variable,
17    Number,
18    String,
19    Character,
20
21    // Erlang 关键字
22    After,
23    And,
24    Andalso,
25    Band,
26    Begin,
27    Bnot,
28    Bor,
29    Bsl,
30    Bsr,
31    Bxor,
32    Case,
33    Catch,
34    Cond,
35    Div,
36    End,
37    Fun,
38    If,
39    Let,
40    Not,
41    Of,
42    Or,
43    Orelse,
44    Query,
45    Receive,
46    Rem,
47    Try,
48    When,
49    Xor,
50
51    // 操作符
52    Plus,            // +
53    Minus,           // -
54    Star,            // *
55    Slash,           // /
56    Equal,           // =
57    EqualEqual,      // ==
58    SlashEqual,      // /=
59    EqualColonEqual, // =:=
60    EqualSlashEqual, // =/=
61    Less,            // <
62    Greater,         // >
63    LessEqual,       // =<
64    GreaterEqual,    // >=
65    PlusPlus,        // ++
66    MinusMinus,      // --
67    Exclamation,     // !
68    Question,        // ?
69
70    // 分隔符
71    LeftParen,    // (
72    RightParen,   // )
73    LeftBrace,    // {
74    RightBrace,   // }
75    LeftBracket,  // [
76    RightBracket, // ]
77    Comma,        // ,
78    Semicolon,    // ;
79    Dot,          // .
80    Colon,        // :
81    Arrow,        // ->
82    Pipe,         // |
83    PipePipe,     // ||
84    Hash,         // #
85
86    // 语法节点类型
87    Root,
88    Item,
89    Module,
90    Export,
91    Attribute,
92    Function,
93    FunctionClause,
94    Pattern,
95    RecordPattern,
96    Statement,
97    Expr,
98    BinaryExpr,
99    CallExpr,
100    FunExpr,
101    CaseExpr,
102    CaseClause,
103    IfExpr,
104    IfClause,
105    TryExpr,
106    CatchClause,
107    ReceiveExpr,
108    ReceiveClause,
109    RecordExpr,
110
111    // 特殊
112    Error,
113    Eof,
114}
115
116impl ErlangSyntaxKind {
117    pub fn is_keyword(&self) -> bool {
118        matches!(
119            self,
120            Self::After
121                | Self::And
122                | Self::Andalso
123                | Self::Band
124                | Self::Begin
125                | Self::Bnot
126                | Self::Bor
127                | Self::Bsl
128                | Self::Bsr
129                | Self::Bxor
130                | Self::Case
131                | Self::Catch
132                | Self::Cond
133                | Self::Div
134                | Self::End
135                | Self::Fun
136                | Self::If
137                | Self::Let
138                | Self::Not
139                | Self::Of
140                | Self::Or
141                | Self::Orelse
142                | Self::Query
143                | Self::Receive
144                | Self::Rem
145                | Self::Try
146                | Self::When
147                | Self::Xor
148        )
149    }
150
151    pub fn is_operator(&self) -> bool {
152        matches!(
153            self,
154            Self::Plus
155                | Self::Minus
156                | Self::Star
157                | Self::Slash
158                | Self::Equal
159                | Self::EqualEqual
160                | Self::SlashEqual
161                | Self::EqualColonEqual
162                | Self::EqualSlashEqual
163                | Self::Less
164                | Self::Greater
165                | Self::LessEqual
166                | Self::GreaterEqual
167                | Self::PlusPlus
168                | Self::MinusMinus
169                | Self::Exclamation
170                | Self::Question
171        )
172    }
173
174    pub fn is_punctuation(&self) -> bool {
175        matches!(self, Self::LeftParen | Self::RightParen | Self::LeftBrace | Self::RightBrace | Self::LeftBracket | Self::RightBracket | Self::Comma | Self::Semicolon | Self::Dot | Self::Colon | Self::Arrow | Self::Pipe | Self::PipePipe | Self::Hash)
176    }
177}
178
179impl TokenType for ErlangSyntaxKind {
180    const END_OF_STREAM: Self = Self::Eof;
181    type Role = UniversalTokenRole;
182
183    fn role(&self) -> Self::Role {
184        match self {
185            Self::Whitespace | Self::Newline => UniversalTokenRole::Whitespace,
186            Self::Comment => UniversalTokenRole::Comment,
187            Self::Identifier | Self::Atom | Self::Variable => UniversalTokenRole::Name,
188            Self::Number | Self::String | Self::Character => UniversalTokenRole::Literal,
189            kind if kind.is_keyword() => UniversalTokenRole::Keyword,
190            kind if kind.is_operator() => UniversalTokenRole::Operator,
191            kind if kind.is_punctuation() => UniversalTokenRole::Punctuation,
192            Self::Error => UniversalTokenRole::Error,
193            _ => UniversalTokenRole::None,
194        }
195    }
196
197    fn is_comment(&self) -> bool {
198        matches!(self, Self::Comment)
199    }
200
201    fn is_whitespace(&self) -> bool {
202        matches!(self, Self::Whitespace | Self::Newline)
203    }
204}
205
206impl ElementType for ErlangSyntaxKind {
207    type Role = UniversalElementRole;
208
209    fn role(&self) -> Self::Role {
210        match self {
211            Self::Root => UniversalElementRole::Root,
212            Self::Module | Self::Function | Self::FunctionClause => UniversalElementRole::Definition,
213            Self::Statement => UniversalElementRole::Statement,
214            Self::Expr | Self::BinaryExpr | Self::CallExpr | Self::FunExpr | Self::CaseExpr | Self::IfExpr | Self::TryExpr | Self::ReceiveExpr | Self::RecordExpr => UniversalElementRole::Expression,
215            Self::Error => UniversalElementRole::Error,
216            _ => UniversalElementRole::None,
217        }
218    }
219
220    fn is_error(&self) -> bool {
221        matches!(self, Self::Error)
222    }
223
224    fn is_root(&self) -> bool {
225        matches!(self, Self::Root)
226    }
227}