use crate::core::Expression;
use std::ops::{Add, Mul, Neg, Sub};
impl Add for Expression {
type Output = Expression;
fn add(self, rhs: Expression) -> Expression {
Expression::add(vec![self, rhs])
}
}
impl Add for &Expression {
type Output = Expression;
fn add(self, rhs: &Expression) -> Expression {
Expression::add(vec![self.clone(), rhs.clone()])
}
}
impl Add<&Expression> for Expression {
type Output = Expression;
fn add(self, rhs: &Expression) -> Expression {
Expression::add(vec![self, rhs.clone()])
}
}
impl Add<Expression> for &Expression {
type Output = Expression;
fn add(self, rhs: Expression) -> Expression {
Expression::add(vec![self.clone(), rhs])
}
}
impl Add<i32> for Expression {
type Output = Expression;
fn add(self, rhs: i32) -> Expression {
Expression::add(vec![self, Expression::integer(rhs as i64)])
}
}
impl Add<Expression> for i32 {
type Output = Expression;
fn add(self, rhs: Expression) -> Expression {
Expression::add(vec![Expression::integer(self as i64), rhs])
}
}
impl Add<i32> for &Expression {
type Output = Expression;
fn add(self, rhs: i32) -> Expression {
Expression::add(vec![self.clone(), Expression::integer(rhs as i64)])
}
}
impl Add<&Expression> for i32 {
type Output = Expression;
fn add(self, rhs: &Expression) -> Expression {
Expression::add(vec![Expression::integer(self as i64), rhs.clone()])
}
}
impl Sub for Expression {
type Output = Expression;
fn sub(self, rhs: Expression) -> Expression {
Expression::add(vec![self, -rhs])
}
}
impl Sub for &Expression {
type Output = Expression;
fn sub(self, rhs: &Expression) -> Expression {
Expression::add(vec![self.clone(), -rhs.clone()])
}
}
impl Sub<&Expression> for Expression {
type Output = Expression;
fn sub(self, rhs: &Expression) -> Expression {
Expression::add(vec![self, -rhs.clone()])
}
}
impl Sub<Expression> for &Expression {
type Output = Expression;
fn sub(self, rhs: Expression) -> Expression {
Expression::add(vec![self.clone(), -rhs])
}
}
impl Sub<i32> for Expression {
type Output = Expression;
fn sub(self, rhs: i32) -> Expression {
Expression::add(vec![self, Expression::integer(-rhs as i64)])
}
}
impl Sub<Expression> for i32 {
type Output = Expression;
fn sub(self, rhs: Expression) -> Expression {
Expression::add(vec![Expression::integer(self as i64), -rhs])
}
}
impl Mul for Expression {
type Output = Expression;
fn mul(self, rhs: Expression) -> Expression {
Expression::mul(vec![self, rhs])
}
}
impl Mul for &Expression {
type Output = Expression;
fn mul(self, rhs: &Expression) -> Expression {
Expression::mul(vec![self.clone(), rhs.clone()])
}
}
impl Mul<&Expression> for Expression {
type Output = Expression;
fn mul(self, rhs: &Expression) -> Expression {
Expression::mul(vec![self, rhs.clone()])
}
}
impl Mul<Expression> for &Expression {
type Output = Expression;
fn mul(self, rhs: Expression) -> Expression {
Expression::mul(vec![self.clone(), rhs])
}
}
impl Mul<i32> for Expression {
type Output = Expression;
fn mul(self, rhs: i32) -> Expression {
Expression::mul(vec![self, Expression::integer(rhs as i64)])
}
}
impl Mul<Expression> for i32 {
type Output = Expression;
fn mul(self, rhs: Expression) -> Expression {
Expression::mul(vec![Expression::integer(self as i64), rhs])
}
}
impl Mul<i32> for &Expression {
type Output = Expression;
fn mul(self, rhs: i32) -> Expression {
Expression::mul(vec![self.clone(), Expression::integer(rhs as i64)])
}
}
impl Mul<&Expression> for i32 {
type Output = Expression;
fn mul(self, rhs: &Expression) -> Expression {
Expression::mul(vec![Expression::integer(self as i64), rhs.clone()])
}
}
impl Neg for Expression {
type Output = Expression;
fn neg(self) -> Expression {
Expression::mul(vec![Expression::integer(-1), self])
}
}
impl Neg for &Expression {
type Output = Expression;
fn neg(self) -> Expression {
Expression::mul(vec![Expression::integer(-1), self.clone()])
}
}
#[cfg(test)]
mod tests {
use crate::{expr, Expression};
#[test]
fn test_addition() {
let x = expr!(x);
let y = expr!(y);
let sum = &x + &y;
assert!(matches!(sum, Expression::Add(_)));
}
#[test]
fn test_multiplication() {
let x = expr!(x);
let two = Expression::integer(2);
let product = &x * &two;
assert!(matches!(product, Expression::Mul(_)));
}
#[test]
fn test_integer_ops() {
let x = expr!(x);
let sum = &x + 5;
let product = 3 * &x;
assert!(matches!(sum, Expression::Add(_)));
assert!(matches!(product, Expression::Mul(_)));
}
#[test]
fn test_negation() {
let x = expr!(x);
let neg_x = -&x;
assert!(matches!(neg_x, Expression::Mul(_)));
}
}