use std::fmt;
use crate::class::Class;
use crate::value::Value;
use crate::SOMRef;
#[derive(Clone)]
pub struct Instance {
pub class: SOMRef<Class>,
pub locals: Vec<Value>,
}
impl Instance {
pub fn from_class(class: SOMRef<Class>) -> Self {
let mut locals = Vec::new();
fn collect_locals(class: &SOMRef<Class>, locals: &mut Vec<Value>) {
if let Some(class) = class.borrow().super_class() {
collect_locals(&class, locals);
}
locals.extend(class.borrow().locals.iter().map(|_| Value::Nil));
}
collect_locals(&class, &mut locals);
Self { class, locals }
}
pub fn class(&self) -> SOMRef<Class> {
self.class.clone()
}
pub fn super_class(&self) -> Option<SOMRef<Class>> {
self.class.borrow().super_class()
}
pub fn lookup_local(&self, idx: usize) -> Option<Value> {
self.locals.get(idx).cloned()
}
pub fn assign_local(&mut self, idx: usize, value: Value) -> Option<()> {
*self.locals.get_mut(idx)? = value;
Some(())
}
}
impl fmt::Debug for Instance {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Instance")
.field("name", &self.class.borrow().name())
.finish()
}
}