diff options
| author | Mel <einebeere@gmail.com> | 2021-10-21 23:46:01 +0200 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2021-10-21 23:46:01 +0200 |
| commit | cff714c07e5e2c0f11c121504500a554d60c08cc (patch) | |
| tree | 6c9e98696530b2661343942948b9f1a50a8665e7 /src/interpret/value.rs | |
| parent | a4980b8dbf1394c2b302f1de7c72d2264426b86e (diff) | |
| download | rabbithole-cff714c07e5e2c0f11c121504500a554d60c08cc.tar.zst rabbithole-cff714c07e5e2c0f11c121504500a554d60c08cc.zip | |
Implement program walking.
Diffstat (limited to 'src/interpret/value.rs')
| -rw-r--r-- | src/interpret/value.rs | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/src/interpret/value.rs b/src/interpret/value.rs new file mode 100644 index 0000000..0c7843c --- /dev/null +++ b/src/interpret/value.rs @@ -0,0 +1,181 @@ +use crate::parse::ast::nodes::FnNode; +use anyhow::{anyhow, Result}; +use std::{cell::RefCell, rc::Rc}; + +type Ref<T> = RefCell<Rc<T>>; + +#[derive(Clone, Debug)] +pub enum Value { + Str(String), + Float(f64), + Int(i64), + Fn(Ref<FnNode>), + Void, +} + +impl Value { + pub fn add(self, rhs: Value) -> Result<Value> { + match self { + Value::Str(l) => match rhs { + Value::Str(r) => Ok(Value::Str(l + &r)), + Value::Float(r) => Ok(Value::Str(l + &r.to_string())), + Value::Int(r) => Ok(Value::Str(l + &r.to_string())), + _ => Err(anyhow!("Right operand can't be added.")), + }, + Value::Float(l) => match rhs { + Value::Str(r) => Ok(Value::Str(l.to_string() + &r)), + Value::Float(r) => Ok(Value::Float(l + r)), + Value::Int(r) => Ok(Value::Float(l + r as f64)), + _ => Err(anyhow!("Right operand can't be added.")), + }, + Value::Int(l) => match rhs { + Value::Str(r) => Ok(Value::Str(l.to_string() + &r)), + Value::Float(r) => Ok(Value::Float(l as f64 + r)), + Value::Int(r) => Ok(Value::Int(l + r)), + _ => Err(anyhow!("Right operand can't be added.")), + }, + _ => Err(anyhow!("Left operand can't be added.")), + } + } + + pub fn sub(self, rhs: Value) -> Result<Value> { + match self { + Value::Float(l) => match rhs { + Value::Float(r) => Ok(Value::Float(l - r)), + Value::Int(r) => Ok(Value::Float(l - r as f64)), + _ => Err(anyhow!("Right operand can't be substracted.")), + }, + Value::Int(l) => match rhs { + Value::Float(r) => Ok(Value::Float(l as f64 - r)), + Value::Int(r) => Ok(Value::Int(l - r)), + _ => Err(anyhow!("Right operand can't be substracted.")), + }, + _ => Err(anyhow!("Left operand can't be substracted from.")), + } + } + + pub fn mul(self, rhs: Value) -> Result<Value> { + match self { + Value::Float(l) => match rhs { + Value::Float(r) => Ok(Value::Float(l * r)), + Value::Int(r) => Ok(Value::Float(l * r as f64)), + _ => Err(anyhow!("Right operand can't be multiplied.")), + }, + Value::Int(l) => match rhs { + Value::Float(r) => Ok(Value::Float(l as f64 * r)), + Value::Int(r) => Ok(Value::Int(l * r)), + _ => Err(anyhow!("Right operand can't be multiplied.")), + }, + _ => Err(anyhow!("Left operand can't be multiplied.")), + } + } + + pub fn div(self, rhs: Value) -> Result<Value> { + match self { + Value::Float(l) => match rhs { + Value::Float(r) => Ok(Value::Float(l / r)), + Value::Int(r) => Ok(Value::Float(l / r as f64)), + _ => Err(anyhow!("Right operand can't be multiplied.")), + }, + Value::Int(l) => match rhs { + Value::Float(r) => Ok(Value::Float(l as f64 / r)), + Value::Int(r) => Ok(Value::Float(l as f64 / r as f64)), + _ => Err(anyhow!("Right operand can't be multiplied.")), + }, + _ => Err(anyhow!("Left operand can't be multiplied.")), + } + } +} + +// pub enum Value { +// Float(f64), +// Int(i64), +// } + +// impl Add for WalkValue { +// type Output = Self; + +// fn add(self, rhs: Self) -> Self::Output { +// match self { +// Self::Float(float) => match rhs { +// Self::Float(other_float) => Self::Float(float + other_float), +// Self::Int(other_int) => Self::Float(float + other_int as f64), +// }, +// Self::Int(int) => match rhs { +// Self::Float(other_float) => Self::Float(int as f64 + other_float), +// Self::Int(other_int) => Self::Int(int + other_int), +// }, +// } +// } +// } + +// impl Sub for WalkValue { +// type Output = Self; + +// fn sub(self, rhs: Self) -> Self::Output { +// match self { +// Self::Float(float) => match rhs { +// Self::Float(other_float) => Self::Float(float - other_float), +// Self::Int(other_int) => Self::Float(float - other_int as f64), +// }, +// Self::Int(int) => match rhs { +// Self::Float(other_float) => Self::Float(int as f64 - other_float), +// Self::Int(other_int) => Self::Int(int - other_int), +// }, +// } +// } +// } + +// impl Mul for WalkValue { +// type Output = Self; + +// fn mul(self, rhs: Self) -> Self::Output { +// match self { +// Self::Float(float) => match rhs { +// Self::Float(other_float) => Self::Float(float * other_float), +// Self::Int(other_int) => Self::Float(float * other_int as f64), +// }, +// Self::Int(int) => match rhs { +// Self::Float(other_float) => Self::Float(int as f64 * other_float), +// Self::Int(other_int) => Self::Int(int * other_int), +// }, +// } +// } +// } + +// impl Div for WalkValue { +// type Output = Self; + +// fn div(self, rhs: Self) -> Self::Output { +// match self { +// Self::Float(float) => match rhs { +// Self::Float(other_float) => Self::Float(float / other_float), +// Self::Int(other_int) => Self::Float(float / other_int as f64), +// }, +// Self::Int(int) => match rhs { +// Self::Float(other_float) => Self::Float(int as f64 / other_float), +// Self::Int(other_int) => Self::Float(int as f64 / other_int as f64), +// }, +// } +// } +// } + +// impl Neg for WalkValue { +// type Output = Self; + +// fn neg(self) -> Self::Output { +// match self { +// Self::Float(float) => Self::Float(-float), +// Self::Int(int) => Self::Int(-int), +// } +// } +// } + +// impl Display for WalkValue { +// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +// match self { +// Self::Float(float) => write!(f, "{}", float), +// Self::Int(int) => write!(f, "{}", int), +// } +// } +// } |
