use super::EvalError; use std::fmt; use std::rc::Rc; /// Values in the interpreter. /// /// Yes, this is yet another definition of a structure called `Value`, which /// are almost entirely identical. However, it's nice to have them separated /// by type so that we don't mix them up. #[derive(Clone)] pub enum Value { I8(i8), I16(i16), I32(i32), I64(i64), U8(u8), U16(u16), U32(u32), U64(u64), Function( Option, Rc) -> Result>, ), } fn format_value(value: &Value, f: &mut fmt::Formatter<'_>) -> fmt::Result { match value { Value::I8(x) => write!(f, "{}i8", x), Value::I16(x) => write!(f, "{}i16", x), Value::I32(x) => write!(f, "{}i32", x), Value::I64(x) => write!(f, "{}i64", x), Value::U8(x) => write!(f, "{}u8", x), Value::U16(x) => write!(f, "{}u16", x), Value::U32(x) => write!(f, "{}u32", x), Value::U64(x) => write!(f, "{}u64", x), Value::Function(Some(name), _) => write!(f, "", name), Value::Function(None, _) => write!(f, ""), } } impl fmt::Debug for Value { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { format_value(self, f) } } impl fmt::Display for Value { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { format_value(self, f) } } impl PartialEq for Value { fn eq(&self, other: &Self) -> bool { match self { Value::I8(x) => match other { Value::I8(y) => x == y, _ => false, }, Value::I16(x) => match other { Value::I16(y) => x == y, _ => false, }, Value::I32(x) => match other { Value::I32(y) => x == y, _ => false, }, Value::I64(x) => match other { Value::I64(y) => x == y, _ => false, }, Value::U8(x) => match other { Value::U8(y) => x == y, _ => false, }, Value::U16(x) => match other { Value::U16(y) => x == y, _ => false, }, Value::U32(x) => match other { Value::U32(y) => x == y, _ => false, }, Value::U64(x) => match other { Value::U64(y) => x == y, _ => false, }, Value::Function(Some(x), _) => match other { Value::Function(Some(y), _) => x == y, _ => false, }, Value::Function(None, _) => false, } } } impl From for Value { fn from(value: i8) -> Self { Value::I8(value) } } impl From for Value { fn from(value: i16) -> Self { Value::I16(value) } } impl From for Value { fn from(value: i32) -> Self { Value::I32(value) } } impl From for Value { fn from(value: i64) -> Self { Value::I64(value) } } impl From for Value { fn from(value: u8) -> Self { Value::U8(value) } } impl From for Value { fn from(value: u16) -> Self { Value::U16(value) } } impl From for Value { fn from(value: u32) -> Self { Value::U32(value) } } impl From for Value { fn from(value: u64) -> Self { Value::U64(value) } }