use crate::cellref::CellRef;
use crate::range::Range;
#[derive(Debug, Clone, PartialEq)]
pub enum Expr {
Number(f64),
String(String),
Boolean(bool),
CellRef(CellRef),
Range(Range),
BinaryOp {
op: BinOp,
left: Box<Expr>,
right: Box<Expr>,
},
UnaryOp {
op: UnaryOp,
operand: Box<Expr>,
},
FunctionCall {
name: String,
args: Vec<Expr>,
},
Percent(Box<Expr>),
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum BinOp {
Add,
Sub,
Mul,
Div,
Pow,
Concat,
Eq,
Neq,
Lt,
Gt,
Lte,
Gte,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum UnaryOp {
Negate,
}
impl std::fmt::Display for Expr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Expr::Number(n) => write!(f, "{}", n),
Expr::String(s) => write!(f, "\"{}\"", s),
Expr::Boolean(b) => write!(f, "{}", if *b { "TRUE" } else { "FALSE" }),
Expr::CellRef(c) => write!(f, "{}", c),
Expr::Range(r) => write!(f, "{}", r),
Expr::BinaryOp { op, left, right } => {
write!(f, "({} {} {})", left, op, right)
}
Expr::UnaryOp { op, operand } => match op {
UnaryOp::Negate => write!(f, "(-{})", operand),
},
Expr::FunctionCall { name, args } => {
write!(f, "{}(", name)?;
for (i, arg) in args.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{}", arg)?;
}
write!(f, ")")
}
Expr::Percent(e) => write!(f, "({}%)", e),
}
}
}
impl std::fmt::Display for BinOp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
BinOp::Add => write!(f, "+"),
BinOp::Sub => write!(f, "-"),
BinOp::Mul => write!(f, "*"),
BinOp::Div => write!(f, "/"),
BinOp::Pow => write!(f, "^"),
BinOp::Concat => write!(f, "&"),
BinOp::Eq => write!(f, "="),
BinOp::Neq => write!(f, "!="),
BinOp::Lt => write!(f, "<"),
BinOp::Gt => write!(f, ">"),
BinOp::Lte => write!(f, "<="),
BinOp::Gte => write!(f, ">="),
}
}
}