@@ -5,7 +5,7 @@ pub mod inst;
|
||||
pub mod signal;
|
||||
|
||||
use crate::{
|
||||
obj::{builtin::BUILTIN_OBJS, reserved::*, prelude::*},
|
||||
obj::{builtin::BUILTIN_OBJS, prelude::*, reserved::*},
|
||||
vm::{consts::ConstPool, error::*, frame::*, inst::*, signal::*},
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ pub struct Vm<'c> {
|
||||
}
|
||||
|
||||
impl<'c> Vm<'c> {
|
||||
pub fn new(const_pool: &'c ConstPool,) -> Self {
|
||||
pub fn new(const_pool: &'c ConstPool) -> Self {
|
||||
Self {
|
||||
stack: Default::default(),
|
||||
frames: vec![],
|
||||
@@ -122,9 +122,7 @@ impl<'c> Vm<'c> {
|
||||
let args = fun.args().clone();
|
||||
(*fun.fun_ptr())(callee, self, args)?
|
||||
}
|
||||
Frame::User(_) => {
|
||||
self.resume_user_fun()
|
||||
}
|
||||
Frame::User(_) => self.resume_user_fun(),
|
||||
};
|
||||
self.handle_signal(signal)?;
|
||||
}
|
||||
@@ -148,8 +146,11 @@ impl<'c> Vm<'c> {
|
||||
match signal {
|
||||
Signal::Call(callee, args) => {
|
||||
read_obj!(let callee_obj = callee);
|
||||
let frame = callee_obj.as_fun()
|
||||
.ok_or_else(|| Error::ValueError { error: "cannot call this object".to_string() })?
|
||||
let frame = callee_obj
|
||||
.as_fun()
|
||||
.ok_or_else(|| Error::ValueError {
|
||||
error: "cannot call this object".to_string(),
|
||||
})?
|
||||
.create_frame(callee.clone(), self, args)?;
|
||||
// Jump to the first address of the new function call if it's a user function
|
||||
if let Frame::User(_) = &frame {
|
||||
@@ -207,19 +208,20 @@ impl<'c> Vm<'c> {
|
||||
self.push(obj_ref);
|
||||
}
|
||||
Inst::LoadLocal(local) => {
|
||||
let value = self.get_local(local)
|
||||
let value = self
|
||||
.get_local(local)
|
||||
.expect("TODO: throw error for missing local");
|
||||
self.push(value);
|
||||
}
|
||||
Inst::LoadGlobal(global) => {
|
||||
let value = self.get_global(global)
|
||||
let value = self
|
||||
.get_global(global)
|
||||
.or_else(|| self.get_builtin(global))
|
||||
.expect("TODO: throw error for missing global");
|
||||
self.push(value);
|
||||
}
|
||||
Inst::PopLocal(name) => {
|
||||
let tos = self.pop()
|
||||
.expect("stack underflow");
|
||||
let tos = self.pop().expect("stack underflow");
|
||||
// pop into name
|
||||
if let Some(name) = name {
|
||||
self.set_local(name, tos);
|
||||
@@ -227,8 +229,7 @@ impl<'c> Vm<'c> {
|
||||
// else discard
|
||||
}
|
||||
Inst::PopGlobal(name) => {
|
||||
let tos = self.pop()
|
||||
.expect("stack underflow");
|
||||
let tos = self.pop().expect("stack underflow");
|
||||
// pop into name
|
||||
if let Some(name) = name {
|
||||
self.set_global(name, tos);
|
||||
@@ -244,10 +245,8 @@ impl<'c> Vm<'c> {
|
||||
self.push(attr);
|
||||
}
|
||||
Inst::SetAttr(sym) => {
|
||||
let target = self.pop()
|
||||
.expect("no target available for SetAttr");
|
||||
let source = self.pop()
|
||||
.expect("no source available for SetAttr");
|
||||
let target = self.pop().expect("no target available for SetAttr");
|
||||
let source = self.pop().expect("no source available for SetAttr");
|
||||
write_obj!(let target = target);
|
||||
if let Some(attrs) = target.attrs_mut() {
|
||||
attrs.insert(sym, source);
|
||||
@@ -266,15 +265,17 @@ impl<'c> Vm<'c> {
|
||||
Inst::Call(argc) => {
|
||||
let stack_top = self.stack.len() - argc;
|
||||
let args = self.stack.split_off(stack_top);
|
||||
let tos = self.pop()
|
||||
.expect("stack underflow");
|
||||
let tos = self.pop().expect("stack underflow");
|
||||
read_obj!(let tos = tos);
|
||||
let callee = tos.get_call()
|
||||
let callee = tos
|
||||
.get_call()
|
||||
.expect("TODO: throw an error for missing __call__ attr");
|
||||
signal = Some(Signal::Call(callee, args));
|
||||
}
|
||||
Inst::Index => todo!(),
|
||||
Inst::Return => { signal = Some(Signal::Return); }
|
||||
Inst::Return => {
|
||||
signal = Some(Signal::Return);
|
||||
}
|
||||
Inst::UnNeg => todo!(),
|
||||
Inst::UnPos => todo!(),
|
||||
Inst::BinPlus => {
|
||||
@@ -282,7 +283,8 @@ impl<'c> Vm<'c> {
|
||||
let lhs = self.pop().unwrap();
|
||||
let fun = {
|
||||
read_obj!(let lhs = lhs);
|
||||
lhs.get_plus().expect("TODO: throw an error for missing __add__ attr")
|
||||
lhs.get_plus()
|
||||
.expect("TODO: throw an error for missing __add__ attr")
|
||||
};
|
||||
signal = Some(Signal::Call(fun, vec![rhs]));
|
||||
}
|
||||
@@ -291,7 +293,8 @@ impl<'c> Vm<'c> {
|
||||
let lhs = self.pop().unwrap();
|
||||
let fun = {
|
||||
read_obj!(let lhs = lhs);
|
||||
lhs.get_minus().expect("TODO: throw an error for missing __sub__ attr")
|
||||
lhs.get_minus()
|
||||
.expect("TODO: throw an error for missing __sub__ attr")
|
||||
};
|
||||
signal = Some(Signal::Call(fun, vec![rhs]));
|
||||
}
|
||||
@@ -300,7 +303,8 @@ impl<'c> Vm<'c> {
|
||||
let lhs = self.pop().unwrap();
|
||||
let fun = {
|
||||
read_obj!(let lhs = lhs);
|
||||
lhs.get_mul().expect("TODO: throw an error for missing __mul__ attr")
|
||||
lhs.get_mul()
|
||||
.expect("TODO: throw an error for missing __mul__ attr")
|
||||
};
|
||||
signal = Some(Signal::Call(fun, vec![rhs]));
|
||||
}
|
||||
@@ -309,7 +313,8 @@ impl<'c> Vm<'c> {
|
||||
let lhs = self.pop().unwrap();
|
||||
let fun = {
|
||||
read_obj!(let lhs = lhs);
|
||||
lhs.get_div().expect("TODO: throw an error for missing __div__ attr")
|
||||
lhs.get_div()
|
||||
.expect("TODO: throw an error for missing __div__ attr")
|
||||
};
|
||||
signal = Some(Signal::Call(fun, vec![rhs]));
|
||||
}
|
||||
@@ -318,7 +323,8 @@ impl<'c> Vm<'c> {
|
||||
let lhs = self.pop().unwrap();
|
||||
let fun = {
|
||||
read_obj!(let lhs = lhs);
|
||||
lhs.get_eq().expect("TODO: throw an error for missing __eq__ attr")
|
||||
lhs.get_eq()
|
||||
.expect("TODO: throw an error for missing __eq__ attr")
|
||||
};
|
||||
signal = Some(Signal::Call(fun, vec![rhs]));
|
||||
}
|
||||
@@ -342,7 +348,7 @@ impl<'c> Vm<'c> {
|
||||
.get(&name.index())
|
||||
.cloned()
|
||||
}
|
||||
|
||||
|
||||
fn set_local(&mut self, name: Name, value: ObjRef) {
|
||||
let frame = self
|
||||
.frame_mut()
|
||||
@@ -363,7 +369,8 @@ impl<'c> Vm<'c> {
|
||||
}
|
||||
|
||||
fn set_global(&mut self, name: Name, value: ObjRef) {
|
||||
let frame = self.frames_mut()
|
||||
let frame = self
|
||||
.frames_mut()
|
||||
.first_mut()
|
||||
.expect("global stack frame")
|
||||
.user_frame_mut()
|
||||
|
||||
Reference in New Issue
Block a user