diff --git a/ic10emu/src/vm/object/macros.rs b/ic10emu/src/vm/object/macros.rs index fa003f3..7002311 100644 --- a/ic10emu/src/vm/object/macros.rs +++ b/ic10emu/src/vm/object/macros.rs @@ -1,27 +1,24 @@ - -macro_rules! __define_object_interface_for { - ($trt:ident) => { +macro_rules! object_trait { + (@intf $trait_name:ident $trt:path) => { paste::paste! { #[allow(missing_docs)] - pub type [<$trt Ref>]<'a, T> = &'a dyn $trt::ID>; + pub type [<$trt Ref>]<'a, T> = &'a dyn $trt::ID>; #[allow(missing_docs)] - pub type [<$trt RefMut>]<'a, T> = &'a mut dyn $trt::ID>; + pub type [<$trt RefMut>]<'a, T> = &'a mut dyn $trt::ID>; } }; -} - -macro_rules! object_trait_for { - ( $($trt:ident),*) => { + ( $trait_name:ident {$($trt:path),*}) => { $( - __define_object_interface_for!{$trt} + object_trait!{@intf $trait_name $trt} )* - pub trait Object { + + pub trait $trait_name { type ID; fn id(&self) -> &Self::ID; - fn as_object(&self) -> &dyn Object; + fn as_object(&self) -> &dyn $trait_name; - fn as_object_mut(&mut self) -> &mut dyn Object; + fn as_object_mut(&mut self) -> &mut dyn $trait_name; paste::paste!{$( #[inline(always)] @@ -38,57 +35,77 @@ macro_rules! object_trait_for { }; } -macro_rules! __emit_dollar__ { - ($($rules:tt)*) => { - macro_rules! __emit__ { $($rules)* } - __emit__! { $ } - }; -} +pub(in crate) use object_trait; -pub(in crate) use __emit_dollar__; +macro_rules! ObjectInterface { + { + #[custom(implements($trait_name:ident {$($trt:path),*}))] + $( #[$attr:meta] )* + $viz:vis struct $struct:ident { + $( + $(#[#field1:meta])* + $field1_viz:vis + $field1_name:ident : $field1_ty:ty, + ),* + #[custom(object_id)] + $(#[$id_attr:meta])* + $id_viz:vis $field_id:ident: $id_typ:ty, + $( + $(#[#field2:meta])* + $field2_viz:vis + $field2_name:ident : $field2_ty:ty, + ),* + } + } => { + impl $trait_name for $struct { + type ID = $id_typ; -macro_rules! alias { - ($($name:ident -> $(#[$($stuff:tt)*])+;)* ) => { - $( - $crate::vm::object::macros::__emit_dollar__! { ($_:tt) => ( - #[allow(nonstandard_style)] - macro_rules! $name {($_($item:tt)*) => ( - $( #[$($stuff)*] )+ - $_($item)* - )} - #[allow(unused_imports)] - pub(in crate) use $name; - )} - )* + fn id(&self) -> &Self::ID { + &self.$field_id + } + + #[inline(always)] + fn as_object(&self) -> &dyn $trait_name { + self + } + + #[inline(always)] + fn as_object_mut(&mut self) -> &mut dyn $trait_name { + self + } + + paste::paste!{$( + #[inline(always)] + fn [](&self) -> Option<[<$trt Ref>]> { + Some(self) + } + + #[inline(always)] + fn [](&mut self) -> Option<[<$trt RefMut>]> { + Some(self) + } + )*} + + } }; } -pub(in crate) use alias; +pub(in crate) use ObjectInterface; - - -macro_rules! impl_trait_interfaces { - ( $($trt:ident),*) => { - #[inline(always)] - fn as_object(&self) -> &dyn Object { - self +macro_rules! ObjectTrait { + { + #[custom(object_trait = $trait_name:ident)] + $(#[$attr:meta])* + $viz:vis trait $trt:ident $(: $($bound:path)* )? { + $($tbody:tt)* + } + } => { + $(#[$attr])* + $viz trait $trt: $($($bound)* +)? $trait_name { + $($tbody)* } - #[inline(always)] - fn as_object_mut(&mut self) -> &mut dyn Object { - self - } - - paste::paste!{$( - #[inline(always)] - fn [](&self) -> Option<[<$trt Ref>]> { - Some(self) - } - - #[inline(always)] - fn [](&mut self) -> Option<[<$trt RefMut>]> { - Some(self) - } - )*} }; } + +pub(in crate) use ObjectTrait; diff --git a/ic10emu/src/vm/object/mod.rs b/ic10emu/src/vm/object/mod.rs index 2f0a526..9c23d8b 100644 --- a/ic10emu/src/vm/object/mod.rs +++ b/ic10emu/src/vm/object/mod.rs @@ -1,5 +1,34 @@ +use macro_rules_attribute::derive; + mod macros; +mod traits; -use macros::alias; +use macros::{object_trait, ObjectInterface}; +use traits::Memory; +use crate::vm::object::traits::Test; +object_trait!(VmObject { Memory }); + +#[derive(ObjectInterface!)] +#[custom(implements(VmObject { Memory }))] +pub struct Generic { + mem1: Vec, + + #[custom(object_id)] + id: u32, + + mem2: Vec, +} + +impl Memory for Generic { + fn get_memory(&self) -> &Vec { + &self.mem1 + } + + fn set_memory(&mut self, index: usize, val: u32) { + self.mem2[index] = val; + } +} + +impl Test for Generic {} diff --git a/ic10emu/src/vm/object/traits.rs b/ic10emu/src/vm/object/traits.rs new file mode 100644 index 0000000..06369e9 --- /dev/null +++ b/ic10emu/src/vm/object/traits.rs @@ -0,0 +1,17 @@ +use macro_rules_attribute::apply; +use crate::vm::object::macros::ObjectTrait; +use crate::vm::object::VmObject; + +#[apply(ObjectTrait!)] +#[custom(object_trait = VmObject)] +pub trait Memory: Test { + fn get_memory(&self) -> &Vec; + fn set_memory(&mut self, index: usize, val: u32); +} + + +pub trait Test { + fn test(&self) { + println!("test!"); + } +}