diff --git a/Cargo.lock b/Cargo.lock index 3bc6add..68eb93a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -566,6 +566,8 @@ dependencies = [ "convert_case", "getrandom", "itertools", + "macro_rules_attribute", + "paste", "phf 0.11.2", "phf_codegen", "rand", @@ -728,6 +730,22 @@ dependencies = [ "url", ] +[[package]] +name = "macro_rules_attribute" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a82271f7bc033d84bbca59a3ce3e4159938cb08a9c3aebbe54d215131518a13" +dependencies = [ + "macro_rules_attribute-proc_macro", + "paste", +] + +[[package]] +name = "macro_rules_attribute-proc_macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dd856d451cc0da70e2ef2ce95a18e39a93b7558bedf10201ad28503f918568" + [[package]] name = "memchr" version = "2.7.2" @@ -826,6 +844,12 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "percent-encoding" version = "2.3.1" diff --git a/ic10emu/Cargo.toml b/ic10emu/Cargo.toml index 60d5dbc..1d20748 100644 --- a/ic10emu/Cargo.toml +++ b/ic10emu/Cargo.toml @@ -12,6 +12,8 @@ crate-type = ["lib", "cdylib"] [dependencies] const-crc32 = "1.3.0" itertools = "0.12.1" +macro_rules_attribute = "0.2.0" +paste = "1.0.14" phf = "0.11.2" rand = "0.8.5" regex = "1.10.3" diff --git a/ic10emu/src/vm.rs b/ic10emu/src/vm/mod.rs similarity index 99% rename from ic10emu/src/vm.rs rename to ic10emu/src/vm/mod.rs index f95c5b9..599fa36 100644 --- a/ic10emu/src/vm.rs +++ b/ic10emu/src/vm/mod.rs @@ -1,3 +1,7 @@ + + +mod object; + use crate::{ device::{Device, DeviceTemplate, SlotOccupant, SlotOccupantTemplate}, grammar::{BatchMode, LogicType, SlotLogicType}, diff --git a/ic10emu/src/vm/object/macros.rs b/ic10emu/src/vm/object/macros.rs new file mode 100644 index 0000000..fa003f3 --- /dev/null +++ b/ic10emu/src/vm/object/macros.rs @@ -0,0 +1,94 @@ + +macro_rules! __define_object_interface_for { + ($trt:ident) => { + paste::paste! { + #[allow(missing_docs)] + pub type [<$trt Ref>]<'a, T> = &'a dyn $trt::ID>; + #[allow(missing_docs)] + pub type [<$trt RefMut>]<'a, T> = &'a mut dyn $trt::ID>; + } + }; +} + +macro_rules! object_trait_for { + ( $($trt:ident),*) => { + $( + __define_object_interface_for!{$trt} + )* + pub trait Object { + type ID; + fn id(&self) -> &Self::ID; + + fn as_object(&self) -> &dyn Object; + + fn as_object_mut(&mut self) -> &mut dyn Object; + + paste::paste!{$( + #[inline(always)] + fn [](&self) -> Option<[<$trt Ref>]> { + None + } + + #[inline(always)] + fn [](&mut self) -> Option<[<$trt RefMut>]> { + None + } + )*} + } + }; +} + +macro_rules! __emit_dollar__ { + ($($rules:tt)*) => { + macro_rules! __emit__ { $($rules)* } + __emit__! { $ } + }; +} + +pub(in crate) use __emit_dollar__; + +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; + )} + )* + + }; +} +pub(in crate) use alias; + + + +macro_rules! impl_trait_interfaces { + ( $($trt:ident),*) => { + #[inline(always)] + fn as_object(&self) -> &dyn Object { + self + } + + #[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) + } + )*} + }; +} diff --git a/ic10emu/src/vm/object/mod.rs b/ic10emu/src/vm/object/mod.rs new file mode 100644 index 0000000..2f0a526 --- /dev/null +++ b/ic10emu/src/vm/object/mod.rs @@ -0,0 +1,5 @@ +mod macros; + +use macros::alias; + +