1use std::fmt::Display;
2
3use super::Span;
4
5#[derive(Debug, Clone, PartialEq, PartialOrd)]
6pub struct Token {
7 pub kind: TokenKind,
8 pub span: Span,
9}
10
11impl Token {
12 pub const EOF: Token = Token {
13 kind: TokenKind::Eof,
14 span: Span::ZERO,
15 };
16
17 pub const fn new(kind: TokenKind, span: Span) -> Token {
18 Token { kind, span }
19 }
20
21 pub fn is_eof(&self) -> bool {
22 self.kind == TokenKind::Eof
23 }
24}
25
26impl PartialEq<TokenKind> for Token {
27 fn eq(&self, other: &TokenKind) -> bool {
28 &self.kind == other
29 }
30}
31
32impl Display for Token {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 self.kind.fmt(f)
35 }
36}
37
38#[derive(Debug, Clone, PartialEq, PartialOrd)]
40pub enum TokenKind {
41 Keyword(Keyword),
42 Literal(Literal),
43 Identifier(String),
44 Operator(Operator),
45 Punctuation(Punctuation),
46 Eof,
47 Invalid,
48}
49
50impl Display for TokenKind {
51 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52 match self {
53 Self::Keyword(x) => write!(f, "{x}"),
54 Self::Literal(x) => write!(f, "{x}"),
55 Self::Identifier(x) => write!(f, "{x}"),
56 Self::Operator(x) => write!(f, "{x}"),
57 Self::Punctuation(x) => write!(f, "{x}"),
58 Self::Eof => write!(f, "EOF"),
59 Self::Invalid => write!(f, "InvalidToken"),
60 }
61 }
62}
63
64#[derive(Debug, Clone, PartialEq, PartialOrd)]
65pub enum Literal {
66 Integer(i32),
67 Float(f32),
68 String(String),
69 Boolean(bool),
70}
71
72impl Display for Literal {
73 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74 match self {
75 Self::Integer(x) => write!(f, "{x}"),
76 Self::Float(x) => write!(f, "{x}"),
77 Self::String(x) => write!(f, "\"{x}\""),
78 Self::Boolean(x) => write!(f, "{x}"),
79 }
80 }
81}
82
83#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
84pub enum Keyword {
85 Let,
86 Const,
87 If,
88 Else,
89 While,
90 Function,
91 Return,
92 Break,
93 Continue,
94}
95
96impl Display for Keyword {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 match self {
99 Self::Let => write!(f, "let"),
100 Self::Const => write!(f, "const"),
101 Self::If => write!(f, "if"),
102 Self::Else => write!(f, "else"),
103 Self::While => write!(f, "while"),
104 Self::Function => write!(f, "fn"),
105 Self::Return => write!(f, "return"),
106 Self::Break => write!(f, "break"),
107 Self::Continue => write!(f, "continue"),
108 }
109 }
110}
111
112pub const SEMICOLON_TOKEN: TokenKind = TokenKind::Punctuation(Punctuation::Semicolon);
113
114#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
115pub enum Operator {
116 Add,
117 Subtract,
118 Multiply,
119 Divide,
120 Modulo,
121 Power,
122 And,
123 Or,
124 Not,
125 Assignment,
126 Equal,
127 NotEqual,
128 Less,
129 Greater,
130 LessOrEqual,
131 GreaterOrEqual,
132 Arrow,
133}
134
135impl Display for Operator {
136 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
137 match self {
138 Self::Add => write!(f, "+"),
139 Self::Subtract => write!(f, "-"),
140 Self::Multiply => write!(f, "*"),
141 Self::Divide => write!(f, "/"),
142 Self::Modulo => write!(f, "%"),
143 Self::Power => write!(f, "^"),
144 Self::And => write!(f, "&&"),
145 Self::Or => write!(f, "||"),
146 Self::Not => write!(f, "!"),
147 Self::Assignment => write!(f, "="),
148 Self::Equal => write!(f, "=="),
149 Self::NotEqual => write!(f, "!="),
150 Self::Less => write!(f, "<"),
151 Self::Greater => write!(f, ">"),
152 Self::LessOrEqual => write!(f, "<="),
153 Self::GreaterOrEqual => write!(f, ">="),
154 Self::Arrow => write!(f, "->"),
155 }
156 }
157}
158
159impl Operator {
160 pub const fn is_binary(self) -> bool {
161 matches!(
162 self,
163 Operator::Add
164 | Operator::Subtract
165 | Operator::Multiply
166 | Operator::Divide
167 | Operator::Modulo
168 | Operator::Power
169 )
170 }
171
172 pub const fn is_unary(self) -> bool {
173 matches!(self, Operator::Subtract | Operator::Not)
174 }
175
176 pub const fn is_logical(self) -> bool {
177 matches!(
178 self,
179 Operator::Equal
180 | Operator::NotEqual
181 | Operator::Not
182 | Operator::Less
183 | Operator::LessOrEqual
184 | Operator::Greater
185 | Operator::GreaterOrEqual
186 )
187 }
188
189 pub const fn precedence(self) -> u8 {
190 match self {
191 Operator::Or => 1,
192 Operator::And => 2,
193 Operator::Equal | Operator::NotEqual => 3,
194 Operator::Less
195 | Operator::LessOrEqual
196 | Operator::Greater
197 | Operator::GreaterOrEqual => 4,
198 Operator::Add | Operator::Subtract => 5,
199 Operator::Multiply | Operator::Divide | Operator::Modulo => 6,
200 Operator::Power => 7,
201 Operator::Not => 8,
202 _ => 0,
203 }
204 }
205
206 pub const fn associativity(&self) -> Associativity {
207 if self.is_binary() {
208 Associativity::Left
209 } else {
210 Associativity::Right
211 }
212 }
213}
214
215#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
216pub enum Associativity {
217 Left,
218 Right,
219}
220
221#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
222pub enum Punctuation {
223 OpenParenthesis, CloseParenthesis, OpenBrace, CloseBrace, OpenBrackets, CloseBrackets, Semicolon, Comma, Colon, Dot, QuestionMark, }
235
236impl Display for Punctuation {
237 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
238 match self {
239 Self::OpenParenthesis => write!(f, "("),
240 Self::CloseParenthesis => write!(f, ")"),
241 Self::OpenBrace => write!(f, "{{"),
242 Self::CloseBrace => write!(f, "}}"),
243 Self::OpenBrackets => write!(f, "["),
244 Self::CloseBrackets => write!(f, "]"),
245 Self::Semicolon => write!(f, ";"),
246 Self::Comma => write!(f, ","),
247 Self::Colon => write!(f, ":"),
248 Self::Dot => write!(f, "."),
249 Self::QuestionMark => write!(f, "?"),
250 }
251 }
252}