summaryrefslogtreecommitdiff
path: root/src/lib/eval/arith.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/eval/arith.rs')
-rw-r--r--src/lib/eval/arith.rs83
1 files changed, 58 insertions, 25 deletions
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<Type, String> {
+
+ 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<Type, String>;
fn add(self, other: Type) -> Result<Type, String> {
- 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<Type, String>;
+
+ fn sub(self, other: Type) -> Result<Type, String> {
+ apply_arithmetic(|a, b| a - b, |a, b| a - b, &self, &other)
+ }
+}
+
+impl Mul for Type {
+ type Output = Result<Type, String>;
+
+ fn mul(self, other: Type) -> Result<Type, String> {
+ apply_arithmetic(|a, b| a * b, |a, b| a * b, &self, &other)
+ }
+}
+
+impl Div for Type {
+ type Output = Result<Type, String>;
+
+ fn div(self, other: Type) -> Result<Type, String> {
+ apply_arithmetic(|a, b| a / b, |a, b| a / b, &self, &other)
}
}