From f0e3aef0611e2d158d85ababe77893fb94a21c64 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Thu, 4 Sep 2025 21:41:12 -0700 Subject: [PATCH] add get_state_part_kinds! macro --- crates/fayalite/src/sim/interpreter.rs | 2 + crates/fayalite/src/sim/interpreter/parts.rs | 170 +++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 crates/fayalite/src/sim/interpreter/parts.rs diff --git a/crates/fayalite/src/sim/interpreter.rs b/crates/fayalite/src/sim/interpreter.rs index 35a25d0..adf0f14 100644 --- a/crates/fayalite/src/sim/interpreter.rs +++ b/crates/fayalite/src/sim/interpreter.rs @@ -23,6 +23,8 @@ use std::{ }; use vec_map::VecMap; +pub(crate) mod parts; + pub(crate) type SmallUInt = u64; pub(crate) type SmallSInt = i64; pub(crate) const MIN_BITS_FOR_NEEDING_BIG: usize = SmallUInt::BITS as usize + 1; diff --git a/crates/fayalite/src/sim/interpreter/parts.rs b/crates/fayalite/src/sim/interpreter/parts.rs new file mode 100644 index 0000000..a19ed68 --- /dev/null +++ b/crates/fayalite/src/sim/interpreter/parts.rs @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// See Notices.txt for copyright information + +use crate::util::const_str_cmp; + +#[rustfmt::skip] +macro_rules! make_get_state_part_kinds { + ( + #![dollar = $d:tt] + $(state_part! { + singular_field = $state_singular_fields:ident; + plural_field = $state_plural_fields:ident; + kind = $state_kinds:ident; + singular_variant = $state_singular_variants:ident; + plural_variant = $state_plural_variants:ident; + })* + $(type_part! { + singular_field = $type_singular_fields:ident; + plural_field = $type_plural_fields:ident; + kind = $type_kinds:ident; + singular_variant = $type_singular_variants:ident; + plural_variant = $type_plural_variants:ident; + copy_insn = $copy_insn:ident; + })* + ) => { + make_get_state_part_kinds! { + #![dollar = $d] + parts! { + [$(state_singular_fields = (#[state] $state_singular_fields),)* $(state_singular_fields = (#[type] $type_singular_fields),)*]; + [$(type_singular_fields = ($type_singular_fields),)*]; + [$(state_plural_fields = (#[state] $state_plural_fields),)* $(state_plural_fields = (#[type] $type_plural_fields),)*]; + [$(type_plural_fields = ($type_plural_fields),)*]; + [$(state_kinds = (#[state] $state_kinds),)* $(state_kinds = (#[type] $type_kinds),)*]; + [$(type_kinds = ($type_kinds),)*]; + [$(state_singular_variants = (#[state] $state_singular_variants),)* $(state_singular_variants = (#[type] $type_singular_variants),)*]; + [$(type_singular_variants = ($type_singular_variants),)*]; + [$(state_plural_variants = (#[state] $state_plural_variants),)* $(state_plural_variants = (#[type] $type_plural_variants),)*]; + [$(type_plural_variants = ($type_plural_variants),)*]; + [$(copy_insns = ($copy_insn),)*]; + } + } + }; + ( + #![dollar = $d:tt] + parts! { + $([ + $first_name:ident = ($($first_value:tt)*), + $($name:ident = ($($value:tt)*),)* + ];)* + } + ) => { + const _: () = { + $($(assert!(const_str_cmp(stringify!($first_name), stringify!($name)).is_eq());)*)* + }; + macro_rules! get_state_part_kinds { + ($d macro_ident:ident! {$d ($d args:tt)*}) => { + get_state_part_kinds! { + @expand + $d macro_ident! {} + ($d ($d args)*) + () + } + }; + ($d macro_ident:ident!($d ($d args:tt)*)) => { + get_state_part_kinds! { + @expand + $d macro_ident!() + ($d ($d args)*) + () + } + }; + ( + @expand + $d macro_ident:ident! {} + () + ($d ($d args:tt)*) + ) => { + $d macro_ident! { + $d ($d args)* + } + }; + ( + @expand + $d macro_ident:ident!() + () + ($d ($d args:tt)*) + ) => { + $d macro_ident!( + $d ($d args)* + ) + }; + ( + @expand + $d macro_ident:ident! $d group:tt + (, $d ($d rest:tt)*) + ($d ($d prev_args:tt)*) + ) => { + get_state_part_kinds! { + @expand + $d macro_ident! $d group + ($d ($d rest)*) + ($d ($d prev_args)*,) + } + }; + ( + @expand + $d macro_ident:ident! $d group:tt + (custom = $d custom:tt $d ($d rest:tt)*) + ($d ($d prev_args:tt)*) + ) => { + get_state_part_kinds! { + @expand + $d macro_ident! $d group + ($d ($d rest)*) + ($d ($d prev_args)* custom = $d custom) + } + }; + $(( + @expand + $d macro_ident:ident! $d group:tt + ($first_name $d ($d rest:tt)*) + ($d ($d prev_args:tt)*) + ) => { + get_state_part_kinds! { + @expand + $d macro_ident! $d group + ($d ($d rest)*) + ($d ($d prev_args)* $first_name = [$($first_value)*, $($($value)*,)*]) + } + };)* + ( + @expand + $d macro_ident:ident! $d group:tt + ($d unexpected:tt $d ($d rest:tt)*) + ($d ($d prev_args:tt)*) + ) => { + compile_error! {concat!("Unexpected token: ", stringify!($d unexpected))} + }; + } + + pub(crate) use get_state_part_kinds; + }; +} + +make_get_state_part_kinds! { + #![dollar = $] + state_part! { + singular_field = memory; + plural_field = memories; + kind = StatePartKindMemories; + singular_variant = Memory; + plural_variant = Memories; + } + type_part! { + singular_field = small_slot; + plural_field = small_slots; + kind = StatePartKindSmallSlots; + singular_variant = SmallSlot; + plural_variant = SmallSlots; + copy_insn = CopySmall; + } + type_part! { + singular_field = big_slot; + plural_field = big_slots; + kind = StatePartKindBigSlots; + singular_variant = BigSlot; + plural_variant = BigSlots; + copy_insn = Copy; + } +}