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;
|
2024-12-04 06:38:24 -05:00
|
|
|
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};
|
|
|
|
|
2025-02-03 17:49:38 -05:00
|
|
|
use crate::{Type, vm::Thread};
|
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 {
|
2024-12-18 14:57:29 -05:00
|
|
|
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-18 14:57:29 -05:00
|
|
|
}
|
|
|
|
|
2025-01-09 19:56:36 -05:00
|
|
|
pub fn as_boolean(&self) -> Option<bool> {
|
|
|
|
if let Value::Concrete(ConcreteValue::Boolean(boolean)) = self {
|
|
|
|
Some(*boolean)
|
2024-12-04 05:10:53 -05:00
|
|
|
} else {
|
|
|
|
None
|
2024-12-04 02:52:09 -05:00
|
|
|
}
|
|
|
|
}
|
2024-11-28 05:02:51 -05:00
|
|
|
|
2025-01-13 09:49:08 -05:00
|
|
|
pub fn as_byte(&self) -> Option<u8> {
|
|
|
|
if let Value::Concrete(ConcreteValue::Byte(byte)) = self {
|
|
|
|
Some(*byte)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn as_character(&self) -> Option<char> {
|
|
|
|
if let Value::Concrete(ConcreteValue::Character(character)) = self {
|
|
|
|
Some(*character)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn as_float(&self) -> Option<f64> {
|
|
|
|
if let Value::Concrete(ConcreteValue::Float(float)) = self {
|
|
|
|
Some(*float)
|
|
|
|
} 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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-09 19:56:36 -05:00
|
|
|
pub fn as_integer(&self) -> Option<i64> {
|
|
|
|
if let Value::Concrete(ConcreteValue::Integer(integer)) = self {
|
|
|
|
Some(*integer)
|
|
|
|
} 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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-09 19:56:36 -05:00
|
|
|
pub fn is_string(&self) -> bool {
|
|
|
|
matches!(self, Value::Concrete(ConcreteValue::String(_)))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_function(&self) -> bool {
|
|
|
|
matches!(self, Value::Function(_))
|
|
|
|
}
|
|
|
|
|
2024-12-14 08:49:02 -05:00
|
|
|
pub fn r#type(&self) -> Type {
|
2024-11-28 05:02:51 -05:00
|
|
|
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-11-28 05:02:51 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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)
|
2024-11-28 05:02:51 -05:00
|
|
|
}
|
|
|
|
|
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-11-28 05:02:51 -05:00
|
|
|
}
|
|
|
|
|
2024-12-14 08:49:02 -05:00
|
|
|
pub fn multiply(&self, other: &Value) -> Result<Value, ValueError> {
|
2024-11-28 05:02:51 -05:00
|
|
|
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)
|
2024-11-28 05:02:51 -05:00
|
|
|
}
|
|
|
|
_ => 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> {
|
2024-11-28 05:02:51 -05:00
|
|
|
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)
|
2024-11-28 05:02:51 -05:00
|
|
|
}
|
|
|
|
_ => 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> {
|
2024-11-28 05:02:51 -05:00
|
|
|
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)
|
2024-11-28 05:02:51 -05:00
|
|
|
}
|
|
|
|
_ => 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)
|
2024-11-28 05:02:51 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
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),
|
2024-11-28 05:02:51 -05:00
|
|
|
_ => Err(ValueError::CannotNot(self.to_owned())),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-08 04:21:01 -05:00
|
|
|
pub fn equals(&self, other: &Value) -> bool {
|
2024-11-28 05:02:51 -05:00
|
|
|
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-11-28 05:02:51 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-14 08:49:02 -05:00
|
|
|
pub fn less(&self, other: &Value) -> Result<Value, ValueError> {
|
2024-11-28 05:02:51 -05:00
|
|
|
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)
|
2024-11-28 05:02:51 -05:00
|
|
|
}
|
|
|
|
_ => 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> {
|
2024-11-28 05:02:51 -05:00
|
|
|
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
|
|
|
}
|
2024-11-28 05:02:51 -05:00
|
|
|
_ => Err(ValueError::CannotCompare(self.to_owned(), other.to_owned())),
|
|
|
|
}
|
|
|
|
}
|
2024-12-14 08:49:02 -05:00
|
|
|
|
2025-02-03 17:49:38 -05:00
|
|
|
pub fn display(&self, data: &Thread) -> DustString {
|
2024-12-14 08:49:02 -05:00
|
|
|
match self {
|
2025-01-09 05:31:45 -05:00
|
|
|
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-11-28 05:02:51 -05:00
|
|
|
}
|
|
|
|
|
2024-12-14 08:49:02 -05:00
|
|
|
impl Display for Value {
|
2024-11-28 05:02:51 -05:00
|
|
|
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-28 05:02:51 -05:00
|
|
|
}
|
|
|
|
}
|
2024-11-15 19:18:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub enum ValueError {
|
2024-11-28 05:02:51 -05:00
|
|
|
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}")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|