1use serde::{Deserialize, Serialize};
2
3use crate::scanner::TokenType;
4
5#[derive(Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
6pub enum Precedence {
7 None,
8 Assignment,
9 Or,
10 And,
11 Equality,
12 Comparison,
13 Term,
14 Factor,
15 Increment,
16 Unary,
17 Call,
18 Primary,
19}
20
21#[derive(Serialize, Deserialize, Debug)]
22pub enum ParseFn {
23 None,
24 Unary,
25 Increment,
26 Grouping,
27 Number,
28 Binary,
29 Literal,
30 String,
31 Variable,
32 List,
33 HashMap,
34 And,
35 Or,
36 Call,
37 Dot,
38 This,
39 Super,
40}
41
42#[derive(Serialize, Deserialize, Debug)]
43pub struct ParseRule {
44 pub prefix: ParseFn,
45 pub infix: ParseFn,
46 pub precedence: Precedence,
47}
48
49impl ParseRule {
50 pub fn next_precedence(&self) -> Precedence {
51 match self.precedence {
52 Precedence::None => Precedence::Assignment,
53 Precedence::Assignment => Precedence::Or,
54 Precedence::Or => Precedence::And,
55 Precedence::And => Precedence::Equality,
56 Precedence::Equality => Precedence::Comparison,
57 Precedence::Comparison => Precedence::Term,
58 Precedence::Term => Precedence::Factor,
59 Precedence::Factor => Precedence::Unary,
60 Precedence::Unary => Precedence::Increment,
61 Precedence::Increment => Precedence::Call,
62 Precedence::Call => Precedence::Primary,
63 Precedence::Primary => Precedence::Primary,
64 }
65 }
66}
67
68const PARSE_RULE_NONE: ParseRule = ParseRule {
69 prefix: ParseFn::None,
70 infix: ParseFn::None,
71 precedence: Precedence::None,
72};
73
74const PARSE_RULE_LP: ParseRule = ParseRule {
75 prefix: ParseFn::Grouping,
76 infix: ParseFn::Call,
77 precedence: Precedence::Call,
78};
79
80const PARSE_RULE_MINUS: ParseRule = ParseRule {
81 prefix: ParseFn::Unary,
82 infix: ParseFn::Binary,
83 precedence: Precedence::Term,
84};
85
86const PARSE_RULE_MINUS_ASSIGN: ParseRule = ParseRule {
87 prefix: ParseFn::None,
88 infix: ParseFn::Variable,
89 precedence: Precedence::Assignment,
90};
91
92const PARSE_RULE_MINUS_MINUS: ParseRule = ParseRule {
93 prefix: ParseFn::Grouping,
94 infix: ParseFn::Increment,
95 precedence: Precedence::Increment,
96};
97
98const PARSE_RULE_PLUS: ParseRule = ParseRule {
99 prefix: ParseFn::None,
100 infix: ParseFn::Binary,
101 precedence: Precedence::Term,
102};
103
104const PARSE_RULE_PLUS_ASSIGN: ParseRule = ParseRule {
105 prefix: ParseFn::None,
106 infix: ParseFn::Binary,
107 precedence: Precedence::Assignment,
108};
109
110const PARSE_RULE_PLUS_PLUS: ParseRule = ParseRule {
111 prefix: ParseFn::Grouping,
112 infix: ParseFn::Increment,
113 precedence: Precedence::Increment,
114};
115
116const PARSE_RULE_SLASH: ParseRule = ParseRule {
117 prefix: ParseFn::None,
118 infix: ParseFn::Binary,
119 precedence: Precedence::Factor,
120};
121
122const PARSE_RULE_SLASH_ASSIGN: ParseRule = ParseRule {
123 prefix: ParseFn::None,
124 infix: ParseFn::Binary,
125 precedence: Precedence::Assignment,
126};
127
128const PARSE_RULE_STAR: ParseRule = ParseRule {
129 prefix: ParseFn::None,
130 infix: ParseFn::Binary,
131 precedence: Precedence::Factor,
132};
133
134const PARSE_RULE_STAR_ASSIGN: ParseRule = ParseRule {
135 prefix: ParseFn::None,
136 infix: ParseFn::Binary,
137 precedence: Precedence::Assignment,
138};
139
140const PARSE_RULE_NUM: ParseRule = ParseRule {
141 prefix: ParseFn::Number,
142 infix: ParseFn::None,
143 precedence: Precedence::None,
144};
145
146const PARSE_RULE_TRUE: ParseRule = ParseRule {
147 prefix: ParseFn::Literal,
148 infix: ParseFn::None,
149 precedence: Precedence::None,
150};
151
152const PARSE_RULE_FALSE: ParseRule = ParseRule {
153 prefix: ParseFn::Literal,
154 infix: ParseFn::None,
155 precedence: Precedence::None,
156};
157
158const PARSE_RULE_NIL: ParseRule = ParseRule {
159 prefix: ParseFn::Literal,
160 infix: ParseFn::None,
161 precedence: Precedence::None,
162};
163
164const PARSE_RULE_BANG: ParseRule = ParseRule {
165 prefix: ParseFn::Unary,
166 infix: ParseFn::None,
167 precedence: Precedence::None,
168};
169
170const PARSE_RULE_BE: ParseRule = ParseRule {
171 prefix: ParseFn::None,
172 infix: ParseFn::Binary,
173 precedence: Precedence::Equality,
174};
175
176const PARSE_RULE_EE: ParseRule = ParseRule {
177 prefix: ParseFn::None,
178 infix: ParseFn::Binary,
179 precedence: Precedence::Equality,
180};
181
182const PARSE_RULE_G: ParseRule = ParseRule {
183 prefix: ParseFn::None,
184 infix: ParseFn::Binary,
185 precedence: Precedence::Comparison,
186};
187
188const PARSE_RULE_GE: ParseRule = ParseRule {
189 prefix: ParseFn::None,
190 infix: ParseFn::Binary,
191 precedence: Precedence::Comparison,
192};
193const PARSE_RULE_L: ParseRule = ParseRule {
194 prefix: ParseFn::None,
195 infix: ParseFn::Binary,
196 precedence: Precedence::Comparison,
197};
198const PARSE_RULE_LE: ParseRule = ParseRule {
199 prefix: ParseFn::None,
200 infix: ParseFn::Binary,
201 precedence: Precedence::Comparison,
202};
203const PARSE_RULE_STR: ParseRule = ParseRule {
204 prefix: ParseFn::String,
205 infix: ParseFn::None,
206 precedence: Precedence::None,
207};
208const PARSE_RULE_ID: ParseRule = ParseRule {
209 prefix: ParseFn::Variable,
210 infix: ParseFn::None,
211 precedence: Precedence::None,
212};
213const PARSE_RULE_AND: ParseRule = ParseRule {
214 prefix: ParseFn::None,
215 infix: ParseFn::And,
216 precedence: Precedence::And,
217};
218const PARSE_RULE_OR: ParseRule = ParseRule {
219 prefix: ParseFn::None,
220 infix: ParseFn::Or,
221 precedence: Precedence::Or,
222};
223const PARSE_RULE_DOT: ParseRule = ParseRule {
224 prefix: ParseFn::None,
225 infix: ParseFn::Dot,
226 precedence: Precedence::Call,
227};
228const PARSE_RULE_THIS: ParseRule = ParseRule {
229 prefix: ParseFn::This,
230 infix: ParseFn::None,
231 precedence: Precedence::None,
232};
233const PARSE_RULE_SUPER: ParseRule = ParseRule {
234 prefix: ParseFn::Super,
235 infix: ParseFn::None,
236 precedence: Precedence::None,
237};
238const PARSE_RULE_LBRACKET: ParseRule = ParseRule {
239 prefix: ParseFn::List,
240 infix: ParseFn::None,
241 precedence: Precedence::None,
242};
243
244const PARSE_RULE_LBRACE: ParseRule = ParseRule {
245 prefix: ParseFn::HashMap,
246 infix: ParseFn::None,
247 precedence: Precedence::None,
248};
249
250pub fn get_rule(operator: TokenType) -> ParseRule {
251 match operator {
252 TokenType::LeftParen => PARSE_RULE_LP,
253 TokenType::LeftBracket => PARSE_RULE_LBRACKET,
254 TokenType::LeftBrace => PARSE_RULE_LBRACE,
255 TokenType::Minus => PARSE_RULE_MINUS,
256 TokenType::MinusMinus => PARSE_RULE_MINUS_MINUS,
257 TokenType::MinusAssign => PARSE_RULE_MINUS_ASSIGN,
258 TokenType::Plus => PARSE_RULE_PLUS,
259 TokenType::PlusPlus => PARSE_RULE_PLUS_PLUS,
260 TokenType::PlusAssign => PARSE_RULE_PLUS_ASSIGN,
261 TokenType::Slash => PARSE_RULE_SLASH,
262 TokenType::SlashAssign => PARSE_RULE_SLASH_ASSIGN,
263 TokenType::Star => PARSE_RULE_STAR,
264 TokenType::StarAssign => PARSE_RULE_STAR_ASSIGN,
265 TokenType::Number => PARSE_RULE_NUM,
266 TokenType::True => PARSE_RULE_TRUE,
267 TokenType::False => PARSE_RULE_FALSE,
268 TokenType::Nil => PARSE_RULE_NIL,
269 TokenType::Bang => PARSE_RULE_BANG,
270 TokenType::BangEqual => PARSE_RULE_BE,
271 TokenType::EqualEqual => PARSE_RULE_EE,
272 TokenType::Greater => PARSE_RULE_G,
273 TokenType::GreaterEqual => PARSE_RULE_GE,
274 TokenType::Less => PARSE_RULE_L,
275 TokenType::LessEqual => PARSE_RULE_LE,
276 TokenType::String => PARSE_RULE_STR,
277 TokenType::Identifier => PARSE_RULE_ID,
278 TokenType::And => PARSE_RULE_AND,
279 TokenType::Or => PARSE_RULE_OR,
280 TokenType::Dot => PARSE_RULE_DOT,
281 TokenType::This => PARSE_RULE_THIS,
282 TokenType::Super => PARSE_RULE_SUPER,
283 _ => PARSE_RULE_NONE,
284 }
285}