From ad9f7e6a689c7fe42444cbe22ecdf1de8d092d5b Mon Sep 17 00:00:00 2001 From: Dominick Allen Date: Fri, 26 Jun 2020 21:12:16 -0500 Subject: Evaluate basic arithmetic. --- src/lib/eval/arith.rs | 83 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 25 deletions(-) (limited to 'src/lib/eval/arith.rs') diff --git a/src/lib/eval/arith.rs b/src/lib/eval/arith.rs index fae69de..fe3a06b 100644 --- a/src/lib/eval/arith.rs +++ b/src/lib/eval/arith.rs @@ -1,34 +1,67 @@ -use std::ops::Add; +use std::ops::{Add, Sub, Mul, Div}; use super::super::types::Type; -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 { - match (self, other) { - (Bool(_), _) | (_, Bool(_)) | - (Str(_), _) | (_, Str(_)) | - (Operator(_), _) | (_, Operator(_)) => { - Err("Cannot add these types".to_string()) - }, - (Number(Number::Int(i)), Number(Number::Float(f))) | - (Number(Number::Float(f)), Number(Number::Int(i))) => { - Ok(Number(Number::Float(f + i as f32))) - }, - - (Number(Number::Int(a)), Number(Number::Int(b))) => { - Ok(Number(Number::Int(a + b))) - }, - - (Number(Number::Float(a)), Number(Number::Float(b))) => { - Ok(Number(Number::Float(a + b))) - }, - - (Symbol(_), Number(_)) | - (Number(_), Symbol(_)) | - (Symbol(_), Symbol(_)) => Err("Not yet implemented".to_string()) - } + 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) } } -- cgit v1.2.3