144 lines
3.4 KiB
Rust
144 lines
3.4 KiB
Rust
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<String>,
|
|
Rc<dyn Fn(Vec<Value>) -> Result<Value, EvalError>>,
|
|
),
|
|
}
|
|
|
|
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, "<function {}>", name),
|
|
Value::Function(None, _) => write!(f, "<function>"),
|
|
}
|
|
}
|
|
|
|
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<i8> for Value {
|
|
fn from(value: i8) -> Self {
|
|
Value::I8(value)
|
|
}
|
|
}
|
|
|
|
impl From<i16> for Value {
|
|
fn from(value: i16) -> Self {
|
|
Value::I16(value)
|
|
}
|
|
}
|
|
|
|
impl From<i32> for Value {
|
|
fn from(value: i32) -> Self {
|
|
Value::I32(value)
|
|
}
|
|
}
|
|
|
|
impl From<i64> for Value {
|
|
fn from(value: i64) -> Self {
|
|
Value::I64(value)
|
|
}
|
|
}
|
|
|
|
impl From<u8> for Value {
|
|
fn from(value: u8) -> Self {
|
|
Value::U8(value)
|
|
}
|
|
}
|
|
|
|
impl From<u16> for Value {
|
|
fn from(value: u16) -> Self {
|
|
Value::U16(value)
|
|
}
|
|
}
|
|
|
|
impl From<u32> for Value {
|
|
fn from(value: u32) -> Self {
|
|
Value::U32(value)
|
|
}
|
|
}
|
|
|
|
impl From<u64> for Value {
|
|
fn from(value: u64) -> Self {
|
|
Value::U64(value)
|
|
}
|
|
}
|