2024-11-15 21:42:27 -05:00
|
|
|
use std::fmt::{self, Display, Formatter};
|
|
|
|
|
2024-11-28 05:02:51 -05:00
|
|
|
use crate::{vm::Pointer, ConcreteValue, Value, ValueRef, Vm, VmError};
|
2024-11-15 21:42:27 -05:00
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, PartialOrd)]
|
|
|
|
pub enum AbstractValue {
|
|
|
|
FunctionSelf,
|
2024-11-16 01:29:21 -05:00
|
|
|
List { items: Vec<Pointer> },
|
2024-11-15 21:42:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl AbstractValue {
|
2024-11-28 05:02:51 -05:00
|
|
|
pub fn to_value(self) -> Value {
|
|
|
|
Value::Abstract(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn to_value_ref(&self) -> ValueRef {
|
|
|
|
ValueRef::Abstract(self)
|
|
|
|
}
|
|
|
|
|
2024-11-15 21:42:27 -05:00
|
|
|
pub fn to_concrete_owned(&self, vm: &Vm) -> Result<ConcreteValue, VmError> {
|
|
|
|
match self {
|
2024-12-04 00:04:56 -05:00
|
|
|
AbstractValue::FunctionSelf => Ok(ConcreteValue::function(vm.chunk().clone())),
|
2024-11-15 21:42:27 -05:00
|
|
|
AbstractValue::List { items, .. } => {
|
|
|
|
let mut resolved_items = Vec::with_capacity(items.len());
|
|
|
|
|
|
|
|
for pointer in items {
|
2024-12-09 08:27:45 -05:00
|
|
|
let resolved_item = vm.follow_pointer(*pointer)?.into_concrete_owned(vm)?;
|
2024-11-15 21:42:27 -05:00
|
|
|
|
|
|
|
resolved_items.push(resolved_item);
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(ConcreteValue::List(resolved_items))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn display(&self, vm: &Vm) -> Result<String, VmError> {
|
|
|
|
match self {
|
|
|
|
AbstractValue::FunctionSelf => Ok("self".to_string()),
|
|
|
|
AbstractValue::List { items, .. } => {
|
|
|
|
let mut display = "[".to_string();
|
|
|
|
|
|
|
|
for (i, item) in items.iter().enumerate() {
|
|
|
|
if i > 0 {
|
|
|
|
display.push_str(", ");
|
|
|
|
}
|
|
|
|
|
|
|
|
let item_display = vm.follow_pointer(*item)?.display(vm)?;
|
|
|
|
|
|
|
|
display.push_str(&item_display);
|
|
|
|
}
|
|
|
|
|
2024-11-16 01:29:21 -05:00
|
|
|
display.push(']');
|
2024-11-15 21:42:27 -05:00
|
|
|
|
|
|
|
Ok(display)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Clone for AbstractValue {
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
log::trace!("Cloning abstract value {:?}", self);
|
|
|
|
|
|
|
|
match self {
|
|
|
|
AbstractValue::FunctionSelf => AbstractValue::FunctionSelf,
|
2024-11-16 01:29:21 -05:00
|
|
|
AbstractValue::List { items } => AbstractValue::List {
|
2024-11-15 21:42:27 -05:00
|
|
|
items: items.clone(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for AbstractValue {
|
|
|
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
|
|
|
match self {
|
|
|
|
AbstractValue::FunctionSelf => write!(f, "self"),
|
|
|
|
AbstractValue::List { items, .. } => {
|
|
|
|
write!(f, "[")?;
|
|
|
|
|
|
|
|
for (i, item) in items.iter().enumerate() {
|
|
|
|
if i > 0 {
|
|
|
|
write!(f, ", ")?;
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, "{}", item)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, "]")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|