1
0

251 lines
7.8 KiB
Rust
Raw Normal View History

2024-11-15 19:18:00 -05:00
//! Runtime values used by the VM.
2024-12-17 03:22:44 -05:00
mod abstract_list;
2024-11-15 21:42:27 -05:00
mod concrete_value;
2024-12-17 03:22:44 -05:00
mod function;
2024-11-15 21:42:27 -05:00
mod range_value;
2024-11-15 19:18:00 -05:00
2024-12-17 03:22:44 -05:00
pub use abstract_list::AbstractList;
pub use concrete_value::{ConcreteValue, DustString};
2024-12-17 03:22:44 -05:00
pub use function::Function;
2024-11-15 21:42:27 -05:00
pub use range_value::RangeValue;
2024-12-14 08:49:02 -05:00
use serde::{Deserialize, Serialize};
2024-11-15 19:18:00 -05:00
use std::fmt::{self, Debug, Display, Formatter};
use crate::{vm::ThreadData, Type};
2024-11-15 19:18:00 -05:00
2024-12-14 08:49:02 -05:00
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
2024-11-17 20:32:53 -05:00
pub enum Value {
2024-11-16 01:29:21 -05:00
Concrete(ConcreteValue),
2024-12-17 03:22:44 -05:00
#[serde(skip)]
AbstractList(AbstractList),
#[serde(skip)]
Function(Function),
2024-11-15 19:18:00 -05:00
}
2024-11-17 20:32:53 -05:00
impl Value {
pub fn boolean(boolean: bool) -> Self {
Value::Concrete(ConcreteValue::Boolean(boolean))
}
pub fn byte(byte: u8) -> Self {
Value::Concrete(ConcreteValue::Byte(byte))
}
pub fn character(character: char) -> Self {
Value::Concrete(ConcreteValue::Character(character))
}
pub fn float(float: f64) -> Self {
Value::Concrete(ConcreteValue::Float(float))
}
pub fn integer(integer: i64) -> Self {
Value::Concrete(ConcreteValue::Integer(integer))
}
2024-12-25 10:04:35 -05:00
pub fn string(string: impl Into<DustString>) -> Self {
Value::Concrete(ConcreteValue::String(string.into()))
}
2024-12-04 05:10:53 -05:00
pub fn as_boolean(&self) -> Option<&bool> {
if let Value::Concrete(ConcreteValue::Boolean(value)) = self {
Some(value)
} else {
None
}
}
2024-12-17 03:22:44 -05:00
pub fn as_function(&self) -> Option<&Function> {
if let Value::Function(function) = self {
Some(function)
} else {
None
}
}
2024-12-17 07:10:47 -05:00
pub fn as_string(&self) -> Option<&DustString> {
if let Value::Concrete(ConcreteValue::String(value)) = self {
Some(value)
} else {
None
}
}
2024-12-14 08:49:02 -05:00
pub fn r#type(&self) -> Type {
match self {
2024-12-14 08:49:02 -05:00
Value::Concrete(concrete_value) => concrete_value.r#type(),
2024-12-17 03:22:44 -05:00
Value::AbstractList(AbstractList { item_type, .. }) => {
Type::List(Box::new(item_type.clone()))
}
Value::Function(Function { r#type, .. }) => Type::Function(Box::new(r#type.clone())),
}
}
2024-12-17 03:22:44 -05:00
pub fn add(&self, other: &Value) -> Value {
2025-01-08 04:21:01 -05:00
let sum = match (self, other) {
2024-12-17 03:22:44 -05:00
(Value::Concrete(left), Value::Concrete(right)) => left.add(right),
_ => panic!("{}", ValueError::CannotAdd(self.clone(), other.clone())),
};
2025-01-08 04:21:01 -05:00
Value::Concrete(sum)
}
2025-01-08 04:21:01 -05:00
pub fn subtract(&self, other: &Value) -> Value {
let difference = match (self, other) {
(Value::Concrete(left), Value::Concrete(right)) => left.subtract(right),
_ => panic!(
"{}",
ValueError::CannotSubtract(self.clone(), other.clone())
),
};
Value::Concrete(difference)
}
2024-12-14 08:49:02 -05:00
pub fn multiply(&self, other: &Value) -> Result<Value, ValueError> {
match (self, other) {
2024-12-14 08:49:02 -05:00
(Value::Concrete(left), Value::Concrete(right)) => {
2024-12-04 00:04:56 -05:00
left.multiply(right).map(Value::Concrete)
}
_ => Err(ValueError::CannotMultiply(
self.to_owned(),
other.to_owned(),
)),
}
}
2024-12-14 08:49:02 -05:00
pub fn divide(&self, other: &Value) -> Result<Value, ValueError> {
match (self, other) {
2024-12-14 08:49:02 -05:00
(Value::Concrete(left), Value::Concrete(right)) => {
2024-12-04 00:04:56 -05:00
left.divide(right).map(Value::Concrete)
}
_ => Err(ValueError::CannotDivide(self.to_owned(), other.to_owned())),
}
}
2024-12-14 08:49:02 -05:00
pub fn modulo(&self, other: &Value) -> Result<Value, ValueError> {
match (self, other) {
2024-12-14 08:49:02 -05:00
(Value::Concrete(left), Value::Concrete(right)) => {
2024-12-04 00:04:56 -05:00
left.modulo(right).map(Value::Concrete)
}
_ => Err(ValueError::CannotModulo(self.to_owned(), other.to_owned())),
}
}
2024-12-17 03:22:44 -05:00
pub fn negate(&self) -> Value {
let concrete = match self {
Value::Concrete(concrete_value) => concrete_value.negate(),
_ => panic!("{}", ValueError::CannotNegate(self.clone())),
};
Value::Concrete(concrete)
}
pub fn not(&self) -> Result<Value, ValueError> {
match self {
2024-12-14 08:49:02 -05:00
Value::Concrete(concrete_value) => concrete_value.not().map(Value::Concrete),
_ => Err(ValueError::CannotNot(self.to_owned())),
}
}
2025-01-08 04:21:01 -05:00
pub fn equals(&self, other: &Value) -> bool {
match (self, other) {
2025-01-08 04:21:01 -05:00
(Value::Concrete(left), Value::Concrete(right)) => left.equals(right),
_ => panic!(
"{}",
ValueError::CannotCompare(self.to_owned(), other.to_owned())
),
}
}
2024-12-14 08:49:02 -05:00
pub fn less(&self, other: &Value) -> Result<Value, ValueError> {
match (self, other) {
2024-12-14 08:49:02 -05:00
(Value::Concrete(left), Value::Concrete(right)) => {
2024-12-04 00:04:56 -05:00
left.less_than(right).map(Value::Concrete)
}
_ => Err(ValueError::CannotCompare(self.to_owned(), other.to_owned())),
}
}
2025-01-08 04:21:01 -05:00
pub fn less_than_or_equals(&self, other: &Value) -> Result<Value, ValueError> {
match (self, other) {
2024-12-14 08:49:02 -05:00
(Value::Concrete(left), Value::Concrete(right)) => {
2025-01-08 04:21:01 -05:00
left.less_than_or_equals(right).map(Value::Concrete)
2024-12-04 00:04:56 -05:00
}
_ => Err(ValueError::CannotCompare(self.to_owned(), other.to_owned())),
}
}
2024-12-14 08:49:02 -05:00
pub fn display(&self, data: &ThreadData) -> DustString {
2024-12-14 08:49:02 -05:00
match self {
Value::AbstractList(list) => list.display(data),
2024-12-14 16:17:02 -05:00
Value::Concrete(concrete_value) => concrete_value.display(),
2024-12-17 03:22:44 -05:00
Value::Function(function) => DustString::from(function.to_string()),
2024-12-14 08:49:02 -05:00
}
}
}
2024-12-14 08:49:02 -05:00
impl Display for Value {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
2024-12-17 03:22:44 -05:00
Value::Concrete(concrete_value) => write!(f, "{concrete_value}"),
Value::AbstractList(list) => write!(f, "{list}"),
Value::Function(function) => write!(f, "{function}"),
}
}
2024-11-15 19:18:00 -05:00
}
#[derive(Clone, Debug, PartialEq)]
pub enum ValueError {
CannotAdd(Value, Value),
CannotAnd(Value, Value),
CannotCompare(Value, Value),
CannotDivide(Value, Value),
CannotModulo(Value, Value),
CannotMultiply(Value, Value),
CannotNegate(Value),
CannotNot(Value),
CannotSubtract(Value, Value),
CannotOr(Value, Value),
2024-11-15 19:18:00 -05:00
}
impl Display for ValueError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
ValueError::CannotAdd(left, right) => {
write!(f, "Cannot add {left} and {right}")
}
ValueError::CannotAnd(left, right) => {
write!(f, "Cannot use logical AND operation on {left} and {right}")
}
ValueError::CannotCompare(left, right) => {
write!(f, "Cannot compare {left} and {right}")
}
ValueError::CannotDivide(left, right) => {
write!(f, "Cannot divide {left} by {right}")
}
ValueError::CannotModulo(left, right) => {
write!(f, "Cannot use modulo operation on {left} and {right}")
}
ValueError::CannotMultiply(left, right) => {
write!(f, "Cannot multiply {left} by {right}")
}
ValueError::CannotNegate(value) => {
write!(f, "Cannot negate {value}")
}
ValueError::CannotNot(value) => {
write!(f, "Cannot use logical NOT operation on {value}")
}
ValueError::CannotSubtract(left, right) => {
write!(f, "Cannot subtract {right} from {left}")
}
ValueError::CannotOr(left, right) => {
write!(f, "Cannot use logical OR operation on {left} and {right}")
}
}
}
}