2024-11-15 19:18:00 -05:00
|
|
|
//! Runtime values used by the VM.
|
2024-11-15 21:42:27 -05:00
|
|
|
mod abstract_value;
|
|
|
|
mod concrete_value;
|
|
|
|
mod range_value;
|
2024-11-15 19:18:00 -05:00
|
|
|
|
2024-11-15 21:42:27 -05:00
|
|
|
pub use abstract_value::AbstractValue;
|
|
|
|
pub use concrete_value::ConcreteValue;
|
|
|
|
pub use range_value::RangeValue;
|
2024-11-15 19:18:00 -05:00
|
|
|
|
|
|
|
use std::fmt::{self, Debug, Display, Formatter};
|
|
|
|
|
2024-11-15 21:42:27 -05:00
|
|
|
use crate::{Vm, VmError};
|
2024-11-15 19:18:00 -05:00
|
|
|
|
2024-11-16 01:29:21 -05:00
|
|
|
#[derive(Clone, Debug, PartialEq, PartialOrd)]
|
2024-11-17 20:32:53 -05:00
|
|
|
pub enum Value {
|
2024-11-16 01:29:21 -05:00
|
|
|
Abstract(AbstractValue),
|
|
|
|
Concrete(ConcreteValue),
|
2024-11-15 19:18:00 -05:00
|
|
|
}
|
|
|
|
|
2024-11-17 20:32:53 -05:00
|
|
|
impl Value {
|
2024-11-28 05:02:51 -05:00
|
|
|
pub fn to_ref(&self) -> ValueRef {
|
|
|
|
match self {
|
|
|
|
Value::Abstract(abstract_value) => ValueRef::Abstract(abstract_value),
|
|
|
|
Value::Concrete(concrete_value) => ValueRef::Concrete(concrete_value),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-15 21:42:27 -05:00
|
|
|
pub fn to_concrete_owned(&self, vm: &Vm) -> Result<ConcreteValue, VmError> {
|
|
|
|
match self {
|
2024-11-17 20:32:53 -05:00
|
|
|
Value::Abstract(abstract_value) => abstract_value.to_concrete_owned(vm),
|
|
|
|
Value::Concrete(concrete_value) => Ok(concrete_value.clone()),
|
2024-11-15 19:18:00 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-15 21:42:27 -05:00
|
|
|
pub fn display(&self, vm: &Vm) -> Result<String, VmError> {
|
2024-11-15 19:18:00 -05:00
|
|
|
match self {
|
2024-11-17 20:32:53 -05:00
|
|
|
Value::Abstract(abstract_value) => abstract_value.display(vm),
|
|
|
|
Value::Concrete(concrete_value) => Ok(concrete_value.to_string()),
|
2024-11-15 19:18:00 -05:00
|
|
|
}
|
|
|
|
}
|
2024-12-04 02:52:09 -05:00
|
|
|
|
|
|
|
pub fn add_assign(&mut self, other: ValueRef) -> Result<(), ValueError> {
|
|
|
|
match (self, other) {
|
|
|
|
(Value::Concrete(left), ValueRef::Concrete(right)) => left.add_assign(right),
|
|
|
|
(left, right) => Err(ValueError::CannotAdd(left.clone(), right.to_owned())),
|
|
|
|
}
|
|
|
|
}
|
2024-11-15 19:18:00 -05:00
|
|
|
}
|
|
|
|
|
2024-11-28 05:02:51 -05:00
|
|
|
impl Display for Value {
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
|
|
|
match self {
|
|
|
|
Value::Abstract(abstract_value) => write!(f, "{}", abstract_value),
|
|
|
|
Value::Concrete(concrete_value) => write!(f, "{}", concrete_value),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
|
2024-11-16 01:29:21 -05:00
|
|
|
pub enum ValueRef<'a> {
|
|
|
|
Abstract(&'a AbstractValue),
|
|
|
|
Concrete(&'a ConcreteValue),
|
2024-11-15 21:42:27 -05:00
|
|
|
}
|
2024-11-15 19:18:00 -05:00
|
|
|
|
2024-11-16 01:29:21 -05:00
|
|
|
impl ValueRef<'_> {
|
2024-11-28 05:02:51 -05:00
|
|
|
pub fn to_owned(&self) -> Value {
|
|
|
|
match self {
|
|
|
|
ValueRef::Abstract(abstract_value) => Value::Abstract((*abstract_value).clone()),
|
|
|
|
ValueRef::Concrete(concrete_value) => Value::Concrete((*concrete_value).clone()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-15 21:42:27 -05:00
|
|
|
pub fn to_concrete_owned(&self, vm: &Vm) -> Result<ConcreteValue, VmError> {
|
2024-11-15 19:18:00 -05:00
|
|
|
match self {
|
2024-11-16 01:29:21 -05:00
|
|
|
ValueRef::Abstract(abstract_value) => abstract_value.to_concrete_owned(vm),
|
|
|
|
ValueRef::Concrete(concrete_value) => Ok((*concrete_value).clone()),
|
2024-11-15 19:18:00 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-15 21:42:27 -05:00
|
|
|
pub fn display(&self, vm: &Vm) -> Result<String, VmError> {
|
2024-11-15 19:18:00 -05:00
|
|
|
match self {
|
2024-11-16 01:29:21 -05:00
|
|
|
ValueRef::Abstract(abstract_value) => abstract_value.display(vm),
|
|
|
|
ValueRef::Concrete(concrete_value) => Ok(concrete_value.to_string()),
|
2024-11-15 19:18:00 -05:00
|
|
|
}
|
|
|
|
}
|
2024-11-28 05:02:51 -05:00
|
|
|
|
|
|
|
pub fn add(&self, other: ValueRef) -> Result<Value, ValueError> {
|
|
|
|
match (self, other) {
|
|
|
|
(ValueRef::Concrete(left), ValueRef::Concrete(right)) => {
|
2024-12-04 00:04:56 -05:00
|
|
|
left.add(right).map(Value::Concrete)
|
2024-11-28 05:02:51 -05:00
|
|
|
}
|
|
|
|
_ => Err(ValueError::CannotAdd(self.to_owned(), other.to_owned())),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn subtract(&self, other: ValueRef) -> Result<Value, ValueError> {
|
|
|
|
match (self, other) {
|
|
|
|
(ValueRef::Concrete(left), ValueRef::Concrete(right)) => {
|
2024-12-04 00:04:56 -05:00
|
|
|
left.subtract(right).map(Value::Concrete)
|
2024-11-28 05:02:51 -05:00
|
|
|
}
|
|
|
|
_ => Err(ValueError::CannotSubtract(
|
|
|
|
self.to_owned(),
|
|
|
|
other.to_owned(),
|
|
|
|
)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn multiply(&self, other: ValueRef) -> Result<Value, ValueError> {
|
|
|
|
match (self, other) {
|
|
|
|
(ValueRef::Concrete(left), ValueRef::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(),
|
|
|
|
)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn divide(&self, other: ValueRef) -> Result<Value, ValueError> {
|
|
|
|
match (self, other) {
|
|
|
|
(ValueRef::Concrete(left), ValueRef::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())),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn modulo(&self, other: ValueRef) -> Result<Value, ValueError> {
|
|
|
|
match (self, other) {
|
|
|
|
(ValueRef::Concrete(left), ValueRef::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())),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn negate(&self) -> Result<Value, ValueError> {
|
|
|
|
match self {
|
2024-12-04 00:04:56 -05:00
|
|
|
ValueRef::Concrete(concrete_value) => concrete_value.negate().map(Value::Concrete),
|
2024-11-28 05:02:51 -05:00
|
|
|
_ => Err(ValueError::CannotNegate(self.to_owned())),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn not(&self) -> Result<Value, ValueError> {
|
|
|
|
match self {
|
2024-12-04 00:04:56 -05:00
|
|
|
ValueRef::Concrete(concrete_value) => concrete_value.not().map(Value::Concrete),
|
2024-11-28 05:02:51 -05:00
|
|
|
_ => Err(ValueError::CannotNot(self.to_owned())),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn equal(&self, other: ValueRef) -> Result<Value, ValueError> {
|
|
|
|
match (self, other) {
|
|
|
|
(ValueRef::Concrete(left), ValueRef::Concrete(right)) => {
|
2024-12-04 00:04:56 -05:00
|
|
|
left.equal(right).map(Value::Concrete)
|
2024-11-28 05:02:51 -05:00
|
|
|
}
|
|
|
|
_ => Err(ValueError::CannotCompare(self.to_owned(), other.to_owned())),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn less_than(&self, other: ValueRef) -> Result<Value, ValueError> {
|
|
|
|
match (self, other) {
|
|
|
|
(ValueRef::Concrete(left), ValueRef::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())),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn less_than_or_equal(&self, other: ValueRef) -> Result<Value, ValueError> {
|
|
|
|
match (self, other) {
|
2024-12-04 00:04:56 -05:00
|
|
|
(ValueRef::Concrete(left), ValueRef::Concrete(right)) => {
|
|
|
|
left.less_than_or_equal(right).map(Value::Concrete)
|
|
|
|
}
|
2024-11-28 05:02:51 -05:00
|
|
|
_ => Err(ValueError::CannotCompare(self.to_owned(), other.to_owned())),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for ValueRef<'_> {
|
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
|
|
|
match self {
|
|
|
|
ValueRef::Abstract(abstract_value) => write!(f, "{}", abstract_value),
|
|
|
|
ValueRef::Concrete(concrete_value) => write!(f, "{}", concrete_value),
|
|
|
|
}
|
|
|
|
}
|
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}")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|