[fine] Classes!

It's kinda amazing this works actually
This commit is contained in:
John Doty 2024-01-20 11:03:33 -08:00
parent 0ee89bf26b
commit 4505996710
5 changed files with 319 additions and 40 deletions

View file

@ -29,6 +29,10 @@ pub enum VMErrorCode {
FunctionOutOfRange(usize),
#[error("internal error: stack type mismatch ({0:?} is not function)")]
StackExpectedFunction(StackValue),
#[error("internal error: stack type mismatch ({0:?} is not object)")]
StackExpectedObject(StackValue),
#[error("internal error: slot {0} was out of range for object (type {1} with {2} slots)")]
SlotOutOfRange(usize, Rc<str>, usize),
}
#[derive(Debug)]
@ -45,6 +49,19 @@ pub struct Object {
values: Box<[StackValue]>,
}
impl Object {
pub fn get_slot(&self, index: usize) -> Result<StackValue> {
match self.values.get(index) {
Some(v) => Ok(v.clone()),
None => Err(VMErrorCode::SlotOutOfRange(
index,
self.name.clone(),
self.values.len(),
)),
}
}
}
#[derive(Clone, Debug)]
pub enum StackValue {
Nothing,
@ -109,6 +126,13 @@ impl Frame {
}
}
fn pop_object(&mut self) -> Result<Rc<Object>> {
match self.pop_value()? {
StackValue::Object(v) => Ok(v),
v => Err(VMErrorCode::StackExpectedObject(v)),
}
}
fn push_value(&mut self, v: StackValue) {
self.stack.push(v)
}
@ -410,6 +434,10 @@ fn eval_one(
f.push_object(object.into());
}
Instruction::LoadSlot(slot) => {
let obj = f.pop_object()?;
f.push_value(obj.get_slot(slot)?);
}
}
Ok(Flow::Continue)