use std::ops::{Add, Sub, Mul, Div}; use super::super::types::Type; use super::super::types::Number; fn apply_arithmetic( func_i: fn(isize, isize) -> isize, func_f: fn(f32, f32) -> f32, operand_a: &Type, operand_b: &Type) -> Result { match (operand_a, operand_b) { (Type::Bool(_), _) | (_, Type::Bool(_)) | (Type::Str(_), _) | (_, Type::Str(_)) | (Type::Operator(_), _) | (_, Type::Operator(_)) => { Err("Incompatible types".to_string()) }, (Type::Number(Number::Int(i)), Type::Number(Number::Float(f))) | (Type::Number(Number::Float(f)), Type::Number(Number::Int(i))) => { Ok(Type::Number(Number::Float(func_f(*f, *i as f32)))) }, (Type::Number(Number::Int(a)), Type::Number(Number::Int(b))) => { Ok(Type::Number(Number::Int(func_i(*a, *b)))) }, (Type::Number(Number::Float(a)), Type::Number(Number::Float(b))) => { Ok(Type::Number(Number::Float(func_f(*a, *b)))) }, (Type::Symbol(_), Type::Number(_)) | (Type::Number(_), Type::Symbol(_)) | (Type::Symbol(_), Type::Symbol(_)) => Err("Not yet implemented".to_string()) } } impl Add for Type { type Output = Result; fn add(self, other: Type) -> Result { apply_arithmetic(|a, b| a + b, |a, b| a + b, &self, &other) } } impl Sub for Type { type Output = Result; fn sub(self, other: Type) -> Result { apply_arithmetic(|a, b| a - b, |a, b| a - b, &self, &other) } } impl Mul for Type { type Output = Result; fn mul(self, other: Type) -> Result { apply_arithmetic(|a, b| a * b, |a, b| a * b, &self, &other) } } impl Div for Type { type Output = Result; fn div(self, other: Type) -> Result { apply_arithmetic(|a, b| a / b, |a, b| a / b, &self, &other) } }