gosyn/
token.rs

1//! Define all golang syntax token
2
3use std::fmt::{Debug, Formatter};
4use strum::EnumString;
5use strum::IntoStaticStr;
6
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10#[derive(Copy, Clone, Eq, PartialEq, Debug, EnumString, IntoStaticStr)]
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12pub enum Operator {
13    #[strum(serialize = "+")]
14    Add,
15    #[strum(serialize = "-")]
16    Sub,
17    #[strum(serialize = "*")]
18    Star,
19    #[strum(serialize = "/")]
20    Quo,
21    #[strum(serialize = "%")]
22    Rem,
23
24    #[strum(serialize = "&")]
25    And,
26    #[strum(serialize = "|")]
27    Or,
28    #[strum(serialize = "^")]
29    Xor,
30    #[strum(serialize = "<<")]
31    Shl,
32    #[strum(serialize = ">>")]
33    Shr,
34    #[strum(serialize = "&^")]
35    AndNot,
36
37    #[strum(serialize = "+=")]
38    AddAssign,
39    #[strum(serialize = "-=")]
40    SubAssign,
41    #[strum(serialize = "*=")]
42    MulAssign,
43    #[strum(serialize = "/=")]
44    QuoAssign,
45    #[strum(serialize = "%=")]
46    RemAssign,
47
48    #[strum(serialize = "&=")]
49    AndAssign,
50    #[strum(serialize = "|=")]
51    OrAssign,
52    #[strum(serialize = "^=")]
53    XorAssign,
54    #[strum(serialize = "<<=")]
55    ShlAssign,
56    #[strum(serialize = ">>=")]
57    ShrAssign,
58    #[strum(serialize = "&^=")]
59    AndNotAssign,
60
61    #[strum(serialize = "&&")]
62    AndAnd,
63    #[strum(serialize = "||")]
64    OrOr,
65    #[strum(serialize = "<-")]
66    Arrow,
67    #[strum(serialize = "++")]
68    Inc,
69    #[strum(serialize = "--")]
70    Dec,
71
72    #[strum(serialize = "==")]
73    Equal,
74    #[strum(serialize = "<")]
75    Less,
76    #[strum(serialize = ">")]
77    Greater,
78    #[strum(serialize = "=")]
79    Assign,
80    #[strum(serialize = "!")]
81    Not,
82    #[strum(serialize = "~")]
83    Tiled,
84
85    #[strum(serialize = "!=")]
86    NotEqual,
87    #[strum(serialize = "<=")]
88    LessEqual,
89    #[strum(serialize = ">=")]
90    GreaterEqual,
91    #[strum(serialize = ":=")]
92    Define,
93    #[strum(serialize = "...")]
94    DotDotDot,
95
96    #[strum(serialize = "(")]
97    ParenLeft,
98    #[strum(serialize = ")")]
99    ParenRight,
100    #[strum(serialize = "[")]
101    BarackLeft,
102    #[strum(serialize = "]")]
103    BarackRight,
104    #[strum(serialize = "{")]
105    BraceLeft,
106    #[strum(serialize = "}")]
107    BraceRight,
108
109    #[strum(serialize = ",")]
110    Comma,
111    #[strum(serialize = ":")]
112    Colon,
113    #[strum(serialize = ".")]
114    Dot,
115    #[strum(serialize = ";")]
116    SemiColon,
117}
118
119#[derive(Copy, Clone, Eq, PartialEq, Debug, EnumString, IntoStaticStr)]
120#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
121pub enum Keyword {
122    #[strum(serialize = "break")]
123    Break,
124    #[strum(serialize = "case")]
125    Case,
126    #[strum(serialize = "chan")]
127    Chan,
128    #[strum(serialize = "const")]
129    Const,
130    #[strum(serialize = "continue")]
131    Continue,
132
133    #[strum(serialize = "default")]
134    Default,
135    #[strum(serialize = "defer")]
136    Defer,
137    #[strum(serialize = "else")]
138    Else,
139    #[strum(serialize = "fallthrough")]
140    FallThrough,
141    #[strum(serialize = "for")]
142    For,
143
144    #[strum(serialize = "func")]
145    Func,
146    #[strum(serialize = "go")]
147    Go,
148    #[strum(serialize = "goto")]
149    Goto,
150    #[strum(serialize = "if")]
151    If,
152    #[strum(serialize = "import")]
153    Import,
154
155    #[strum(serialize = "interface")]
156    Interface,
157    #[strum(serialize = "map")]
158    Map,
159    #[strum(serialize = "package")]
160    Package,
161    #[strum(serialize = "range")]
162    Range,
163    #[strum(serialize = "return")]
164    Return,
165
166    #[strum(serialize = "select")]
167    Select,
168    #[strum(serialize = "struct")]
169    Struct,
170    #[strum(serialize = "switch")]
171    Switch,
172    #[strum(serialize = "type")]
173    Type,
174    #[strum(serialize = "var")]
175    Var,
176}
177
178#[derive(Copy, Clone, Eq, PartialEq, Debug)]
179#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
180pub enum LitKind {
181    Ident,
182    String,
183    Integer,
184    Float,
185    Imag,
186    Char,
187}
188
189#[derive(Eq, PartialEq, Clone)]
190pub enum Token {
191    Comment(String),
192    Keyword(Keyword),
193    Operator(Operator),
194    Literal(LitKind, String),
195}
196
197impl From<Keyword> for Token {
198    fn from(word: Keyword) -> Self {
199        Token::Keyword(word)
200    }
201}
202
203impl From<Operator> for Token {
204    fn from(op: Operator) -> Self {
205        Token::Operator(op)
206    }
207}
208
209#[rustfmt::skip]
210impl Operator {
211    pub fn precedence(&self) -> usize {
212        match self {
213            | Operator::OrOr => 1,
214            | Operator::AndAnd => 2,
215            | Operator::Equal
216            | Operator::NotEqual
217            | Operator::Less
218            | Operator::Greater
219            | Operator::LessEqual
220            | Operator::GreaterEqual => 3,
221            | Operator::Add
222            | Operator::Sub
223            | Operator::Or
224            | Operator::Xor => 4,
225            | Operator::Star
226            | Operator::Quo
227            | Operator::Rem
228            | Operator::Shl
229            | Operator::Shr
230            | Operator::And
231            | Operator::AndNot => 5,
232            _ => 0,
233        }
234    }
235
236    pub(crate) fn to_str(self) -> &'static str {
237        self.into()
238    }
239}
240
241impl Keyword {
242    fn to_str(self) -> &'static str {
243        self.into()
244    }
245}
246
247impl Debug for Token {
248    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
249        match self {
250            Token::Comment(_) => write!(f, "/* comment */"),
251            Token::Literal(_, lit) => write!(f, "'{lit}'"),
252            Token::Operator(op) => write!(f, "'{}'", op.to_str()),
253            Token::Keyword(word) => write!(f, "'{}'", word.to_str()),
254        }
255    }
256}
257
258impl Token {
259    pub fn str_len(&self) -> usize {
260        match self {
261            Token::Operator(op) => op.to_str().len(),
262            Token::Keyword(word) => word.to_str().len(),
263            Token::Comment(text) => text.len(),
264            Token::Literal(_, value) => value.len(),
265        }
266    }
267
268    pub fn kind(&self) -> TokenKind {
269        match self {
270            Token::Comment(_) => TokenKind::Comment,
271            Token::Operator(op) => TokenKind::Operator(*op),
272            Token::Keyword(word) => TokenKind::Keyword(*word),
273            Token::Literal(kind, _) => TokenKind::Literal(*kind),
274        }
275    }
276
277    pub fn is<K: Into<TokenKind>>(&self, exp: K) -> bool {
278        self.kind() == exp.into()
279    }
280
281    pub fn precedence(&self) -> Option<(Operator, usize)> {
282        match self {
283            Token::Operator(op) => Some((*op, op.precedence())),
284            _ => None,
285        }
286    }
287}
288
289#[derive(Eq, PartialEq, Copy, Clone)]
290pub enum TokenKind {
291    Comment,
292    Keyword(Keyword),
293    Literal(LitKind),
294    Operator(Operator),
295}
296
297impl From<Keyword> for TokenKind {
298    fn from(word: Keyword) -> Self {
299        TokenKind::Keyword(word)
300    }
301}
302
303impl From<LitKind> for TokenKind {
304    fn from(lit: LitKind) -> Self {
305        TokenKind::Literal(lit)
306    }
307}
308
309impl From<Operator> for TokenKind {
310    fn from(op: Operator) -> Self {
311        TokenKind::Operator(op)
312    }
313}
314
315impl Debug for TokenKind {
316    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
317        match self {
318            Self::Comment => unreachable!(),
319            Self::Keyword(word) => write!(f, "'{}'", word.to_str()),
320            Self::Operator(op) => write!(f, "'{}'", op.to_str()),
321            Self::Literal(kind) => match kind {
322                LitKind::Ident => write!(f, "Identifier"),
323                LitKind::String => write!(f, "String Literals"),
324                LitKind::Integer => write!(f, "Integer Literals"),
325                LitKind::Imag => write!(f, "Imaginary Literals"),
326                LitKind::Char => write!(f, "Character Literals"),
327                LitKind::Float => write!(f, "Float Literals"),
328            },
329        }
330    }
331}