macro_rules! impl_base_obj { ($base_name:ident, $type_name:ident) => { fn instantiate(&mut self) { let ty = $crate::obj::BUILTINS.with_borrow(|builtins| { builtins .get(stringify!($type_name)) .expect(concat!("no ", stringify!($type_name))) .clone() }); self.set_attr("__ty__", ty); self.$base_name.instantiate(); } fn is_instantiated(&self) -> bool { self.$base_name.is_instantiated() } fn attrs(&self) -> &$crate::obj::Attrs { self.$base_name.attrs() } fn attrs_mut(&mut self) -> &mut $crate::obj::Attrs { self.$base_name.attrs_mut() } fn as_any(&self) -> &dyn std::any::Any { self } fn as_any_mut(&mut self) -> &mut dyn std::any::Any { self } }; ($type_name:ident) => { impl_base_obj! { base, $type_name } }; } macro_rules! impl_create { ($($arg:ident : $ty:ty),* $(,)?) => { pub fn create($($arg : $ty ),*) -> $crate::obj::ObjP { let ptr = make_ptr(Self::new($($arg),*)); ptr.borrow_mut().instantiate(); ptr } } } pub(crate) use impl_base_obj; pub(crate) use impl_create;