#[cfg(not(feature = "std"))]
use alloc::{string::String, vec::Vec};
use std::hash::{Hash, Hasher};
#[derive(Debug, Clone, PartialEq)]
pub(super) enum Token {
Number(f64),
Band(usize),
Ident(String),
Plus,
Minus,
Multiply,
Divide,
Power,
LeftParen,
RightParen,
Greater,
Less,
GreaterEqual,
LessEqual,
Equal,
NotEqual,
And,
Or,
If,
Then,
Else,
Comma,
}
#[derive(Debug, Clone)]
pub(super) enum Expr {
Number(f64),
Band(usize),
BinaryOp {
left: Box<Expr>,
op: BinaryOp,
right: Box<Expr>,
},
UnaryOp { op: UnaryOp, expr: Box<Expr> },
Function { name: String, args: Vec<Expr> },
Conditional {
condition: Box<Expr>,
then_expr: Box<Expr>,
else_expr: Box<Expr>,
},
CacheRef(u32),
}
impl PartialEq for Expr {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Expr::Number(a), Expr::Number(b)) => a.to_bits() == b.to_bits(),
(Expr::Band(a), Expr::Band(b)) => a == b,
(
Expr::BinaryOp {
left: ll,
op: lo,
right: lr,
},
Expr::BinaryOp {
left: rl,
op: ro,
right: rr,
},
) => lo == ro && ll == rl && lr == rr,
(Expr::UnaryOp { op: lo, expr: le }, Expr::UnaryOp { op: ro, expr: re }) => {
lo == ro && le == re
}
(Expr::Function { name: ln, args: la }, Expr::Function { name: rn, args: ra }) => {
ln == rn && la == ra
}
(
Expr::Conditional {
condition: lc,
then_expr: lt,
else_expr: le,
},
Expr::Conditional {
condition: rc,
then_expr: rt,
else_expr: re,
},
) => lc == rc && lt == rt && le == re,
(Expr::CacheRef(a), Expr::CacheRef(b)) => a == b,
_ => false,
}
}
}
impl Eq for Expr {}
impl Hash for Expr {
fn hash<H: Hasher>(&self, state: &mut H) {
match self {
Expr::Number(n) => {
0u8.hash(state);
n.to_bits().hash(state);
}
Expr::Band(b) => {
1u8.hash(state);
b.hash(state);
}
Expr::BinaryOp { left, op, right } => {
2u8.hash(state);
op.hash(state);
left.hash(state);
right.hash(state);
}
Expr::UnaryOp { op, expr } => {
3u8.hash(state);
op.hash(state);
expr.hash(state);
}
Expr::Function { name, args } => {
4u8.hash(state);
name.hash(state);
args.hash(state);
}
Expr::Conditional {
condition,
then_expr,
else_expr,
} => {
5u8.hash(state);
condition.hash(state);
then_expr.hash(state);
else_expr.hash(state);
}
Expr::CacheRef(i) => {
6u8.hash(state);
i.hash(state);
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(super) enum BinaryOp {
Add,
Subtract,
Multiply,
Divide,
Power,
Greater,
Less,
GreaterEqual,
LessEqual,
Equal,
NotEqual,
And,
Or,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(super) enum UnaryOp {
Negate,
}