This repository has been archived on 2020-09-15. You can view files and clone it, but cannot push or open issues or pull requests.
Files
not-python-old.2020-08-27/src/vm/mod.rs

152 lines
4.1 KiB
Rust
Raw Normal View History

pub mod frame;
pub mod op;
use crate::{
mem::gc::Gc,
obj::prelude::*,
vm::{frame::Frame, op::Op},
};
use std::rc::Rc;
/*
fn root_ns<I: Intern, G: Gc>(intern: &mut I, gc: &mut G) -> Ns {
let mut ns: Ns = Default::default();
ns.insert(
intern.intern_sym("Unit"),
Attrs::new(gc, Default::default()),
);
ns
}
*/
pub struct State<I: Intern, G: Gc> {
intern: I,
gc: G,
root_ns: Ns,
frames: Vec<Frame>,
}
impl<I: Intern, G: Gc> State<I, G> {
pub fn new(intern: I, gc: G, root_ns: Ns) -> Self {
//let root_ns = root_ns(&mut intern, &mut gc);
State {
intern,
gc,
root_ns,
frames: Default::default(),
}
}
pub fn frames(&self) -> &Vec<Frame> {
&self.frames
}
pub fn frames_mut(&mut self) -> &mut Vec<Frame> {
&mut self.frames
}
pub fn frame(&self) -> &Frame {
self.frames.last().unwrap()
}
pub fn frame_mut(&mut self) -> &mut Frame {
self.frames.last_mut().unwrap()
}
pub fn push_stack(&mut self, value: DynRef) {
self.frame_mut().push(value);
}
pub fn pop_stack(&mut self) -> Option<DynRef> {
self.frame_mut().pop()
}
pub fn ip(&self) -> usize {
self.frame().ip()
}
pub fn set_ip(&mut self, ip: usize) {
self.frame_mut().set_ip(ip);
}
pub fn get_local(&self, name: NameId) -> Option<DynRef> {
self.frame().get_local(name)
}
pub fn set_local(&mut self, name: NameId, obj_ref: DynRef) -> Option<DynRef> {
self.frame_mut().set_local(name, obj_ref)
}
pub fn ops(&self) -> &Rc<Vec<Op>> {
self.frame().ops()
}
pub fn resume(&mut self) {
while !self.frames().is_empty() {
self.resume_fun();
let _frame = self.frames_mut().pop().unwrap();
// Push return value?
}
}
pub fn resume_fun(&mut self) {
while self.ip() < self.ops().len() {
self.step();
}
}
pub fn step(&mut self) {
let mut next_ip = self.ip() + 1;
match self.ops()[self.ip()] {
Op::Push(name) => {
// TODO - local not found
let obj_ref = self.get_local(name).expect("TODO - local not found");
self.push_stack(obj_ref);
}
Op::Pop(name) => {
// stack should not underflow
let obj_ref = self.pop_stack().expect("misaligned stack for pop");
if let Some(name) = name {
self.set_local(name, obj_ref);
}
}
Op::GetAttr(sym) => {
let top = self.pop_stack().expect("misaligned stack for getattrs");
let obj_ref = {
let top_ref = top.borrow();
let attrs = top_ref.attrs();
let attrs_ref = attrs.borrow();
// TODO - local not found
attrs_ref.get(sym).expect("TODO - local not found")
};
self.push_stack(obj_ref);
}
Op::Call(argc) => {
let fun = self
.pop_stack()
.expect("misaligned stack for function call");
let mut argv = Vec::with_capacity(argc);
for _ in 0..argc {
let arg = self.pop_stack().expect("misaligned stack for argv");
argv.push(arg);
}
// reverse since arguments are pushed in order of being passed
argv.reverse();
// TODO
// move ops pointer to the stack frame
if let Some(_fun) = fun.borrow().as_any().downcast_ref::<Fun>() {
self.set_ip(next_ip);
next_ip = 0;
todo!("New stack frame");
} else if let Some(_fun) = fun.borrow().as_any().downcast_ref::<NativeFun>() {
todo!();
} else {
todo!("TODO - not a function");
}
}
}
self.set_ip(next_ip);
}
}