diff --git a/.forgejo/workflows/test.yml b/.forgejo/workflows/test.yml index 0ce7564..da25a67 100644 --- a/.forgejo/workflows/test.yml +++ b/.forgejo/workflows/test.yml @@ -76,7 +76,5 @@ jobs: - name: setup rust toolchain uses: msrd0/rust-toolchain@nightly - name: test instruction decoding - run: cargo test util - - name: test garbage collection - run: cargo test heap + run: cargo test util # this is instruction decoding code diff --git a/hyphae/src/heap.rs b/hyphae/src/heap.rs index 6e54603..c616803 100644 --- a/hyphae/src/heap.rs +++ b/hyphae/src/heap.rs @@ -48,15 +48,15 @@ use organelle::Number; #[repr(transparent)] pub struct Gc(NonNull>); -impl From> for Gc { - fn from(src: Rc) -> Self { +impl From> for Gc { + fn from(src: Rc) -> Self { Gc(NonNull::new(Box::into_raw(Box::new(src.clone()))) .expect("GC obj from rc nonnull ptr check")) } } -impl From for Gc { - fn from(value: T) -> Self { +impl From for Gc { + fn from(value: Datum) -> Self { Gc(NonNull::new(Box::into_raw(Box::new(Rc::from(value)))) .expect("GC obj from datum nonnull ptr check")) } @@ -103,7 +103,7 @@ macro_rules! shallow_copy_rc { } } -impl Clone for Gc { +impl Clone for Gc { fn clone(&self) -> Self { Gc(shallow_copy_rc!(self.0.as_ptr())) } @@ -116,8 +116,7 @@ impl Clone for Gc { impl Drop for Gc { fn drop(&mut self) { unsafe { - let a = Box::>::from_raw(self.0.as_ptr()); - drop(a) + drop(Box::from_raw(self.0.as_ptr() as *mut Box>)) } } } @@ -133,7 +132,7 @@ impl Gc { } } -#[derive(PartialEq)] +#[derive(Clone, PartialEq)] pub enum Datum { Number(Number), Bool(bool), @@ -146,57 +145,14 @@ pub enum Datum { None } -// implemented by hand to force deep copy on Cons datum -impl Clone for Datum { - fn clone(&self) -> Datum { - match self { - Datum::Number(n) => Datum::Number(n.clone()), - Datum::Bool(n) => Datum::Bool(n.clone()), - Datum::Cons(n) => Datum::Cons(n.deep_copy()), - Datum::Symbol(n) => Datum::Symbol(n.clone()), - Datum::Char(n) => Datum::Char(n.clone()), - Datum::String(n) => Datum::String(n.clone()), - Datum::Vector(n) => - Datum::Vector(n.clone()), - Datum::ByteVector(n) => - Datum::ByteVector(n.clone()), - Datum::None => Datum::None, - } - } - - fn clone_from(&mut self, source: &Self) { - *self = source.clone(); - } -} - #[derive(Clone, PartialEq)] pub struct Cons(pub Option>, pub Option>); impl Cons { pub fn deep_copy(&self) -> Cons { - macro_rules! car_cpy { - () => { - if let Some(ref car) = self.0 { - if let Datum::Cons(ref car) = **car { - Some(Datum::Cons(car.deep_copy()).into()) - } else { - self.0.as_ref().map(|x| x.deep_copy()) - } - } else { - None - } - } - } - - if let Some(ref next) = self.1 { - if let Datum::Cons(ref next) = **next { - Cons(car_cpy!(), Some(Datum::Cons(next.deep_copy()).into())) - } else { - Cons(car_cpy!(), self.1.as_ref().map(|x| x.deep_copy())) - } - } else { - Cons(car_cpy!(), None) - } + // TODO: recursive deep copy through the whole list + Cons(self.0.as_ref().map(|x| x.deep_copy()), + self.1.as_ref().map(|x| x.deep_copy())) } pub fn subsl(&self, start: isize, end: isize) -> Cons { @@ -286,52 +242,3 @@ impl Index for Cons { } } } - - -#[cfg(test)] -mod tests { - use super::*; - - struct GcTester<'a>(&'a mut bool); - - // clone implementation leaks memory... but its for test - impl Clone for GcTester<'_> { - fn clone(&self) -> Self { - unsafe { - GcTester(Box::into_raw(Box::new(self.0.clone())) - .as_mut() - .expect("Gc Test obj mut ref fail")) - } - } - - fn clone_from(&mut self, _: &Self) { - unimplemented!("test impl") - } - } - - // in non test code Id have to get the box back - impl Drop for GcTester<'_> { - fn drop(&mut self) { - *self.0 = true; - } - } - - #[test] - fn test_gc_basic_behavior() { - let mut flag = false; - let a = Into::>::into(GcTester(&mut flag)); - drop(a); - assert!(flag) - } - - #[test] - fn test_gc_shallow_copy() { - let mut flag = false; - let a = - Into::>::into(GcTester(&mut flag)).clone(); - drop(a); - assert!(flag) - } - - // TODO: test deep copy -} diff --git a/hyphae/src/vm.rs b/hyphae/src/vm.rs index 4fe21d3..7bd245d 100644 --- a/hyphae/src/vm.rs +++ b/hyphae/src/vm.rs @@ -102,7 +102,7 @@ impl VM { Address::Oper3 => &self.oper[2], Address::Oper4 => &self.oper[3], Address::Stack => &self.stack[$oper.1], - Address::Numer => e!("cannot access constant numeric data"), + Address::Numer => e!("cannot access constant numeric"), Address::Instr => e!("bad access to instruction data"), } };