1
0
dust/dust-lang/src/value/abstract_value.rs

94 lines
2.5 KiB
Rust
Raw Normal View History

2024-11-15 21:42:27 -05:00
use std::fmt::{self, Display, Formatter};
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 {
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 {
AbstractValue::FunctionSelf => Ok(ConcreteValue::Function(vm.chunk().clone())),
AbstractValue::List { items, .. } => {
let mut resolved_items = Vec::with_capacity(items.len());
for pointer in items {
let resolved_item = vm.follow_pointer(*pointer)?.to_concrete_owned(vm)?;
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, "]")
}
}
}
}