BROKEN WIP: GARBAGE COLLECTION AND HEAP MANAGEMENT
Some checks failed
per-push tests / build (push) Failing after 4m38s
per-push tests / test-frontend (push) Has been skipped
per-push tests / timed-decomposer-parse (push) Has been skipped
per-push tests / test-utility (push) Has been skipped
per-push tests / test-backend (push) Has been skipped

Signed-off-by: Ava Affine <ava@sunnypup.io>
This commit is contained in:
Ava Apples Affine 2025-07-26 01:13:13 +00:00
parent 8d2d0ebf0c
commit 1359ebdded
6 changed files with 190 additions and 205 deletions

View file

@ -22,7 +22,7 @@ use crate::hmap::QuickMap;
use crate::stackstack::StackStack;
use crate::instr as i;
use crate::util::{Operand, Program, Address};
use crate::heap::Datum;
use crate::heap::{Gc, Datum};
use core::cell::RefCell;
@ -46,8 +46,8 @@ pub struct VM {
pub traps: Vec<Arc<dyn Fn(&mut VM)>>,
// data registers
pub expr: Datum,
pub oper: [Datum; NUM_OPERAND_REGISTERS],
pub expr: Gc<Datum>,
pub oper: [Gc<Datum>; NUM_OPERAND_REGISTERS],
// control flow registers
pub retn: usize,
@ -144,7 +144,7 @@ impl VM {
} $oper *match deref!(&instr.1[1]){
Datum::$in_type(l) => l,
_ => e!("illegal argument to instruction"),
})
}).into()
}
}
@ -210,24 +210,25 @@ impl VM {
},
i::JMPIF => {
if let Datum::Bool(true) = self.expr {
if let Datum::Bool(true) = *self.expr {
do_jmp!(0);
}
},
// boolean ops
i::EQ => self.expr = Datum::Bool(*deref!(&instr.1[0]) == *deref!(&instr.1[1])),
i::EQ => self.expr =
Datum::Bool(*deref!(&instr.1[0]) == *deref!(&instr.1[1])).into(),
i::LT => lr_oper!(Number, <, Bool),
i::GT => lr_oper!(Number, >, Bool),
i::LTE => lr_oper!(Number, <=, Bool),
i::GTE => lr_oper!(Number, >=, Bool),
i::BOOL_NOT => {
self.expr = Datum::Bool(!{
let Datum::Bool(a) = self.expr else {
let Datum::Bool(a) = *self.expr else {
e!("illegal argument to BOOL_NOT instruction");
};
a
});
}).into();
},
i::BOOL_AND => lr_oper!(Bool, &&, Bool),
@ -239,11 +240,11 @@ impl VM {
i::XOR => lr_oper!(Char, ^, Char),
i::BYTE_NOT => {
self.expr = Datum::Char(!{
let Datum::Char(a) = self.expr else {
let Datum::Char(a) = *self.expr else {
e!("illegal argument to BYTE_NOT instruction");
};
a
});
}).into();
},
// numeric ops
@ -268,7 +269,7 @@ impl VM {
e!("integer division on non integer value");
};
self.expr = Datum::Number(Number::Fra(Fraction(l / r, 1)));
self.expr = Datum::Number(Number::Fra(Fraction(l / r, 1))).into();
},
i::POW => {
@ -280,7 +281,7 @@ impl VM {
e!("illgal argument to POW instruction");
};
self.expr = Datum::Number((*l).pow(*r));
self.expr = Datum::Number((*l).pow(*r)).into();
},
i::INC => if let Datum::Number(src) = deref_mut!(&instr.1[0]) {
@ -319,8 +320,8 @@ impl VM {
}
},
i::MKVEC => self.expr = Datum::Vector(RefCell::from(vec![])),
i::MKBVEC => self.expr = Datum::ByteVector(RefCell::from(vec![])),
i::MKVEC => self.expr = Datum::Vector(RefCell::from(vec![])).into(),
i::MKBVEC => self.expr = Datum::ByteVector(RefCell::from(vec![])).into(),
i::INDEX => {
let Datum::Number(idx) = deref!(&instr.1[1]) else {
e!("illegal argument to INDEX instruction");
@ -334,13 +335,13 @@ impl VM {
match deref!(&instr.1[0]) {
Datum::Vector(v) => {
let a = (*v.borrow()[idx].clone()).clone();
self.expr = a;
self.expr = a.into();
},
Datum::ByteVector(bv) => {
let a = Datum::Char(bv.borrow()[idx]);
self.expr = a;
self.expr = a.into();
},
Datum::List(l) => self.expr = l[idx].clone(),
Datum::Cons(l) => self.expr = l[idx].clone(),
_ => e!("illegal argument to INDEX instruction")
};
},
@ -348,14 +349,14 @@ impl VM {
i::LENGTH => match deref!(&instr.1[0]) {
Datum::Vector(v) => {
let a = Datum::Number(Number::Fra(Fraction(v.borrow().len() as isize, 1)));
self.expr = a;
self.expr = a.into();
},
Datum::ByteVector(bv) => {
let a = Datum::Number(Number::Fra(Fraction(bv.borrow().len() as isize, 1)));
self.expr = a;
self.expr = a.into();
},
Datum::List(l) =>
self.expr = Datum::Number(Number::Fra(Fraction(l.len() as isize, 1))),
Datum::Cons(l) => self.expr =
Datum::Number(Number::Fra(Fraction(l.len() as isize, 1))).into(),
_ => e!("illegal argument to LENGTH instruction"),
},
@ -385,15 +386,16 @@ impl VM {
match deref!(&instr.1[0]) {
Datum::Vector(v) => {
let a = Datum::Vector(RefCell::from(v.borrow()[st..ed].to_vec()));
self.expr = a;
self.expr = a.into();
},
Datum::ByteVector(bv) => {
let a = Datum::ByteVector(RefCell::from(bv.borrow()[st..ed].to_vec()));
self.expr = a;
self.expr = a.into();
},
Datum::List(a) =>
self.expr = Datum::List(Rc::new(
(**a).subsl(st as isize, ed as isize))),
// TODO: do I deep copy the subslice?
Datum::Cons(a) => self.expr =
Datum::Cons(a.subsl(st as isize, ed as isize)).into(),
_ => e!("illegal argument to SUBSL instruction")
};
}
@ -425,15 +427,16 @@ impl VM {
},
i::CAR => {
let Datum::List(arg) = deref!(&instr.1[0]) else {
let Datum::Cons(arg) = deref!(&instr.1[0]) else {
e!("illegal argument to CAR instruction");
};
// TODO: need a none type dont we now
self.expr = (*arg.0).clone();
},
i::CDR => {
let Datum::List(arg) = deref!(&instr.1[0]) else {
let Datum::Cons(arg) = deref!(&instr.1[0]) else {
e!("illegal argument to CAR instruction");
};
@ -447,10 +450,6 @@ impl VM {
*/
},
// in order to maintain a language agnostic VM these must be traps
//i::PARSE => todo!("implement AST API"),
//i::EVAL => todo!("implement AST API"),
_ => {
e!("illegal instruction");
},