zen_expression/parser/
constants.rs1use nohash_hasher::BuildNoHashHasher;
2use once_cell::sync::Lazy;
3use std::collections::HashMap;
4
5use crate::lexer::{ArithmeticOperator, ComparisonOperator, LogicalOperator, Operator};
6use Associativity::{Left, Right};
7
8type NoHasher = BuildNoHashHasher<Operator>;
9
10#[derive(Debug, PartialEq, Eq, Clone, Copy)]
11pub enum Associativity {
12 Left,
13 Right,
14}
15
16#[derive(Debug, PartialEq)]
17pub struct ParserOperator {
18 pub precedence: u8,
19 pub associativity: Associativity,
20}
21
22impl ParserOperator {
23 pub fn binary(operator: &Operator) -> Option<&'static ParserOperator> {
24 BINARY_OPERATORS.get(operator)
25 }
26
27 pub fn unary(operator: &Operator) -> Option<&'static ParserOperator> {
28 UNARY_OPERATORS.get(operator)
29 }
30}
31
32macro_rules! hashmap {
33 (@single $($x:tt)*) => (());
34 (@count $($rest:expr),*) => (<[()]>::len(&[$(hashmap!(@single $rest)),*]));
35
36 ($($key:expr => $value:expr,)+) => { hashmap!($($key => $value),+) };
37 ($($key:expr => $value:expr),*) => {
38 {
39 let _cap = hashmap!(@count $($key),*);
40 let mut _map = ::std::collections::HashMap::default();
41 _map.reserve(_cap);
42 $(
43 let _ = _map.insert($key, $value);
44 )*
45 _map
46 }
47 };
48}
49
50pub(crate) static BINARY_OPERATORS: Lazy<HashMap<Operator, ParserOperator, NoHasher>> = Lazy::new(
51 || {
52 hashmap! {
53 Operator::Logical(LogicalOperator::Or) => ParserOperator { precedence: 10, associativity: Left },
54 Operator::Logical(LogicalOperator::And) => ParserOperator { precedence: 15, associativity: Left },
55 Operator::Comparison(ComparisonOperator::Equal) => ParserOperator { precedence: 20, associativity: Left },
56 Operator::Comparison(ComparisonOperator::NotEqual) => ParserOperator { precedence: 20, associativity: Left },
57 Operator::Comparison(ComparisonOperator::LessThan) => ParserOperator { precedence: 20, associativity: Left },
58 Operator::Comparison(ComparisonOperator::GreaterThan) => ParserOperator { precedence: 20, associativity: Left },
59 Operator::Comparison(ComparisonOperator::LessThanOrEqual) => ParserOperator { precedence: 20, associativity: Left },
60 Operator::Comparison(ComparisonOperator::GreaterThanOrEqual) => ParserOperator { precedence: 20, associativity: Left },
61 Operator::Comparison(ComparisonOperator::NotIn) => ParserOperator { precedence: 20, associativity: Left },
62 Operator::Comparison(ComparisonOperator::In) => ParserOperator { precedence: 20, associativity: Left },
63 Operator::Arithmetic(ArithmeticOperator::Add) => ParserOperator { precedence: 30, associativity: Left },
64 Operator::Arithmetic(ArithmeticOperator::Subtract) => ParserOperator { precedence: 30, associativity: Left },
65 Operator::Arithmetic(ArithmeticOperator::Multiply) => ParserOperator { precedence: 60, associativity: Left },
66 Operator::Arithmetic(ArithmeticOperator::Divide) => ParserOperator { precedence: 60, associativity: Left },
67 Operator::Arithmetic(ArithmeticOperator::Modulus) => ParserOperator { precedence: 60, associativity: Left },
68 Operator::Arithmetic(ArithmeticOperator::Power) => ParserOperator { precedence: 70, associativity: Right },
69 Operator::Logical(LogicalOperator::NullishCoalescing) => ParserOperator { precedence: 80, associativity: Left },
70 }
71 },
72);
73
74pub(crate) static UNARY_OPERATORS: Lazy<HashMap<Operator, ParserOperator, NoHasher>> = Lazy::new(
75 || {
76 hashmap! {
77 Operator::Logical(LogicalOperator::Not) => ParserOperator { precedence: 50, associativity: Left },
78 Operator::Arithmetic(ArithmeticOperator::Add) => ParserOperator { precedence: 200, associativity: Left },
79 Operator::Arithmetic(ArithmeticOperator::Subtract) => ParserOperator { precedence: 200, associativity: Left },
80 }
81 },
82);