#[macro_use] mod macros; pub mod attrs; pub mod fun; pub mod int; pub mod intern; pub mod names; pub mod str; pub mod sym; #[cfg(test)] mod test; pub mod ty; pub mod prelude { pub use crate::obj::{attrs::*, fun::*, int::*, intern::*, str::*, sym::*, ty::*, Obj, ObjRef}; } use shredder::{Gc, Scan}; use std::{ marker::Unsize, ops::{CoerceUnsized, Deref, DerefMut}, sync::RwLock, }; use attrs::*; use sym::Sym; // // trait Obj // pub trait Obj: Scan + std::fmt::Debug { fn vtable(&self) -> &Vtable; fn attrs(&self) -> &Attrs; fn attrs_mut(&mut self) -> Option<&mut Attrs>; fn get_attr(&self, sym: &Sym) -> Option { self.attrs() .get(&sym) .cloned() .or_else(|| { let vtable = self.vtable().get(); vtable.get(&sym).cloned() }) } fn set_attr(&mut self, sym: Sym, value: ObjRef) -> Option { self.attrs_mut()?.insert(sym, value) } } // // struct ObjRef // #[derive(Debug, Scan)] pub struct ObjRef where T: Obj + ?Sized + Send + Sync, { gc: Gc>, } impl Clone for ObjRef where T: Obj + ?Sized + Send + Sync, { fn clone(&self) -> Self { ObjRef { gc: self.gc.clone(), } } } // // impl ObjRef // impl ObjRef where T: Obj + ?Sized + Send + Sync, { /// Check object reference equality. pub fn ref_eq(&self, other: &Self) -> bool { let lhs: &RwLock = &*self.gc.get(); let rhs: &RwLock = &*other.get(); std::ptr::eq::>(lhs, rhs) } } impl ObjRef where T: Obj + Send + Sync + 'static, { pub fn new(obj: T) -> Self { ObjRef { gc: Gc::new(RwLock::new(obj)), } } } impl CoerceUnsized> for ObjRef where T: Obj + Send + Sync + ?Sized + Unsize, U: Obj + Send + Sync + ?Sized, { } // // impl Deref for ObjRef // impl Deref for ObjRef { type Target = Gc>; fn deref(&self) -> &Self::Target { &self.gc } } // // impl DerefMut for ObjRef // impl DerefMut for ObjRef { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.gc } }