phoenix_lang/
precedence.rs

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}