#[derive(Debug, Clone, PartialEq)]
pub enum Expr {
Lit(f64),
Var(String),
Add(Box<Expr>, Box<Expr>),
Sub(Box<Expr>, Box<Expr>),
Mul(Box<Expr>, Box<Expr>),
Div(Box<Expr>, Box<Expr>),
Pow(Box<Expr>, u32),
Sin(Box<Expr>),
Cos(Box<Expr>),
Log(Box<Expr>),
Exp(Box<Expr>),
}
impl Expr {
pub fn lit(v: f64) -> Self {
Expr::Lit(v)
}
pub fn var(name: &str) -> Self {
Expr::Var(name.to_string())
}
#[allow(clippy::should_implement_trait)]
pub fn add(a: Expr, b: Expr) -> Self {
Expr::Add(Box::new(a), Box::new(b))
}
#[allow(clippy::should_implement_trait)]
pub fn sub(a: Expr, b: Expr) -> Self {
Expr::Sub(Box::new(a), Box::new(b))
}
#[allow(clippy::should_implement_trait)]
pub fn mul(a: Expr, b: Expr) -> Self {
Expr::Mul(Box::new(a), Box::new(b))
}
#[allow(clippy::should_implement_trait)]
pub fn div(a: Expr, b: Expr) -> Self {
Expr::Div(Box::new(a), Box::new(b))
}
pub fn pow(a: Expr, n: u32) -> Self {
Expr::Pow(Box::new(a), n)
}
pub fn sin(a: Expr) -> Self {
Expr::Sin(Box::new(a))
}
pub fn cos(a: Expr) -> Self {
Expr::Cos(Box::new(a))
}
pub fn log(a: Expr) -> Self {
Expr::Log(Box::new(a))
}
pub fn exp(a: Expr) -> Self {
Expr::Exp(Box::new(a))
}
}
impl std::fmt::Display for Expr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Expr::Lit(v) => write!(f, "{}", v),
Expr::Var(name) => write!(f, "{}", name),
Expr::Add(a, b) => write!(f, "({} + {})", a, b),
Expr::Sub(a, b) => write!(f, "({} - {})", a, b),
Expr::Mul(a, b) => write!(f, "({} * {})", a, b),
Expr::Div(a, b) => write!(f, "({} / {})", a, b),
Expr::Pow(a, n) => write!(f, "({} ^ {})", a, n),
Expr::Sin(a) => write!(f, "sin({})", a),
Expr::Cos(a) => write!(f, "cos({})", a),
Expr::Log(a) => write!(f, "log({})", a),
Expr::Exp(a) => write!(f, "exp({})", a),
}
}
}