diff --git a/ic10emu/src/vm/mod.rs b/ic10emu/src/vm/mod.rs index 599fa36..0c9fabd 100644 --- a/ic10emu/src/vm/mod.rs +++ b/ic10emu/src/vm/mod.rs @@ -54,6 +54,7 @@ pub struct VM { /// list of device id's touched on the last operation operation_modified: RefCell>, + objects: Vec, } impl Default for VM { @@ -64,7 +65,7 @@ impl Default for VM { impl VM { pub fn new() -> Self { - let id_gen = IdSpace::default(); + let id_space = IdSpace::default(); let mut network_id_space = IdSpace::default(); let default_network_key = network_id_space.next(); let default_network = Rc::new(RefCell::new(Network::new(default_network_key))); @@ -76,10 +77,11 @@ impl VM { devices: BTreeMap::new(), networks, default_network: default_network_key, - id_space: id_gen, + id_space, network_id_space, random: Rc::new(RefCell::new(crate::rand_mscorlib::Random::new())), operation_modified: RefCell::new(Vec::new()), + objects: Vec::new(), }; let _ = vm.add_ic(None); vm diff --git a/ic10emu/src/vm/object/macros.rs b/ic10emu/src/vm/object/macros.rs index 7002311..accde95 100644 --- a/ic10emu/src/vm/object/macros.rs +++ b/ic10emu/src/vm/object/macros.rs @@ -1,5 +1,5 @@ macro_rules! object_trait { - (@intf $trait_name:ident $trt:path) => { + (intf {$trait_name:ident $trt:path}) => { paste::paste! { #[allow(missing_docs)] pub type [<$trt Ref>]<'a, T> = &'a dyn $trt::ID>; @@ -9,7 +9,7 @@ macro_rules! object_trait { }; ( $trait_name:ident {$($trt:path),*}) => { $( - object_trait!{@intf $trait_name $trt} + $crate::vm::object::macros::object_trait!{intf {$trait_name $trt}} )* pub trait $trait_name { @@ -22,12 +22,12 @@ macro_rules! object_trait { paste::paste!{$( #[inline(always)] - fn [](&self) -> Option<[<$trt Ref>]> { + fn [](&self) -> Option<[<$trt Ref>]> { None } #[inline(always)] - fn [](&mut self) -> Option<[<$trt RefMut>]> { + fn [](&mut self) -> Option<[<$trt RefMut>]> { None } )*} @@ -35,7 +35,7 @@ macro_rules! object_trait { }; } -pub(in crate) use object_trait; +pub(crate) use object_trait; macro_rules! ObjectInterface { { @@ -90,13 +90,14 @@ macro_rules! ObjectInterface { }; } -pub(in crate) use ObjectInterface; +pub(crate) use ObjectInterface; +#[allow(unused_macros)] macro_rules! ObjectTrait { { #[custom(object_trait = $trait_name:ident)] $(#[$attr:meta])* - $viz:vis trait $trt:ident $(: $($bound:path)* )? { + $viz:vis trait $trt:ident $(: $($bound:tt)* )? { $($tbody:tt)* } } => { @@ -107,5 +108,56 @@ macro_rules! ObjectTrait { }; } +#[allow(unused_imports)] +pub(crate) use ObjectTrait; -pub(in crate) use ObjectTrait; +macro_rules! tag_object_traits { + { + @tag + tag=$trt_name:ident; + acc={ $($tagged_trt:ident,)* } + $(#[$attr:meta])* + $viz:vis trait $trt:ident $(: $($bound:path)* )? { + $($tbody:tt)* + } + $($used:tt)* + } => { + #[doc = concat!("Autotagged with ", stringify!($trt_name))] + $(#[$attr])* + $viz trait $trt : $($($bound)* +)? $trt_name { + $($tbody)* + } + + $crate::vm::object::macros::tag_object_traits!{ @tag tag=$trt_name; acc={ $trt, $($tagged_trt,)* } $($used)* } + }; + { + @tag + tag=$trt_name:ident; + acc={ $($tagged_trt:ident,)* } + impl $name:ident for $trt:path { + $($body:tt)* + } + $($used:tt)* + } => { + /// Untouched by tag macro + impl $name for $trt { + $($body)* + } + $crate::vm::object::macros::tag_object_traits!{ @tag tag=$trt_name; acc={ $($tagged_trt,)* } $($used)* } + }; + { + @tag + tag=$trt_name:ident; + acc={ $($tagged_trt:ident,)* } + } => { + + // end tagged traits {$trt_name} + + $crate::vm::object::macros::object_trait!($trt_name { $($tagged_trt),* }); + }; + { #![object_trait($trt_name:ident)] $($tree:tt)* } => { + $crate::vm::object::macros::tag_object_traits!{ @tag tag=$trt_name; acc={} $($tree)* } + }; +} + +pub(crate) use tag_object_traits; diff --git a/ic10emu/src/vm/object/mod.rs b/ic10emu/src/vm/object/mod.rs index 9c23d8b..688a608 100644 --- a/ic10emu/src/vm/object/mod.rs +++ b/ic10emu/src/vm/object/mod.rs @@ -3,32 +3,35 @@ use macro_rules_attribute::derive; mod macros; mod traits; -use macros::{object_trait, ObjectInterface}; -use traits::Memory; +use macros::ObjectInterface; +use traits::*; -use crate::vm::object::traits::Test; +pub type ObjectID = u32; +pub type BoxedObject = Box>; -object_trait!(VmObject { Memory }); #[derive(ObjectInterface!)] -#[custom(implements(VmObject { Memory }))] +#[custom(implements(Object { Memory }))] pub struct Generic { - mem1: Vec, + mem1: Vec, #[custom(object_id)] - id: u32, + id: ObjectID, - mem2: Vec, + mem2: Vec, } impl Memory for Generic { - fn get_memory(&self) -> &Vec { + fn get_memory(&self) -> &Vec { &self.mem1 } - fn set_memory(&mut self, index: usize, val: u32) { + fn set_memory(&mut self, index: usize, val: f64) { self.mem2[index] = val; } + + fn size(&self) -> usize { + self.mem1.len() + } } -impl Test for Generic {} diff --git a/ic10emu/src/vm/object/traits.rs b/ic10emu/src/vm/object/traits.rs index 06369e9..a42130f 100644 --- a/ic10emu/src/vm/object/traits.rs +++ b/ic10emu/src/vm/object/traits.rs @@ -1,17 +1,55 @@ -use macro_rules_attribute::apply; -use crate::vm::object::macros::ObjectTrait; -use crate::vm::object::VmObject; +use crate::{grammar, vm::{object::{macros::tag_object_traits, ObjectID}, VM}}; -#[apply(ObjectTrait!)] -#[custom(object_trait = VmObject)] -pub trait Memory: Test { - fn get_memory(&self) -> &Vec; - fn set_memory(&mut self, index: usize, val: u32); -} +tag_object_traits! { + #![object_trait(Object)] - -pub trait Test { - fn test(&self) { - println!("test!"); + pub trait Memory { + fn size(&self) -> usize; } + + pub trait MemoryWritable: Memory { + fn set_memory(&mut self, index: usize, val: f64); + fn clear_memory(&mut self); + } + + pub trait MemoryReadable: Memory { + fn get_memory(&self) -> &Vec; + } + + pub trait Logicable { + fn is_logic_readable(&self) -> bool; + fn is_logic_writeable(&self) -> bool; + fn set_logic(&mut self, lt: grammar::LogicType, value: f64); + fn get_logic(&self, lt: grammar::LogicType) -> Option; + + fn slots_count(&self) -> usize; + // fn get_slot(&self, index: usize) -> Slot; + fn set_slot_logic(&mut self, slt: grammar::SlotLogicType, value: f64); + fn get_slot_logic(&self, slt: grammar::SlotLogicType) -> Option; + } + + pub trait CircuitHolder: Logicable { + fn clear_error(&mut self); + fn set_error(&mut self, state: i32); + fn get_logicable_from_index(&self, device: usize, vm: &VM) -> Option>; + fn get_logicable_from_id(&self, device: ObjectID, vm: &VM) -> Option>; + fn get_source_code(&self) -> String; + fn set_source_code(&self, code: String); + } + + pub trait SourceCode { + fn get_source_code(&self) -> String; + fn set_source_code(&self, code: String); + + } + + pub trait Instructable: Memory { + // fn get_instructions(&self) -> Vec + } + + pub trait LogicStack: Memory { + // fn logic_stack(&self) -> LogicStack; + } + } +