Я пытаюсь создать макрос для определения некоторых вариантов enum, представляющих инструкции на ассемблере.
Прямо сейчас у меня есть следующее, которое отлично работает. Это довольно бесполезно, но в конце концов я собираюсь добавить некоторые автоматически производные методы, чтобы потом иметь цель:
macro_rules! define_instructions {
($($inames:tt),+ $(,)*) => {
#[derive(Debug)]
pub enum Instruction {
$($inames),*
}
};
}
define_instructions! {
PsqLux,
PsqLx,
Twi,
}
fn main() {}
Проблема в том, что большинство (но не все) вариантов, которые я добавлю, должны будут иметь связанные значения:
define_instructions! {
PsqLux(u32, u32, u32, u32, u32),
PsqLx(u32, u32, u32, u32, u32),
Twi(u32, u32, u32),
SomethingWithoutAVariant,
}
Я попытался использовать это, чтобы разрешить вариантам иметь связанные значения (на самом деле он еще не поддерживает связанные значения, это только начало):
macro_rules! define_instructions {
(@define) => {};
(@define $iname:ident) => {
$iname,
};
(@define $iname:ident $($inames:tt)*) => {
$iname,
define_instructions! { @define $($inames)* }
};
($($inames:tt),+ $(,)*) => {
#[derive(Debug)]
pub enum Instruction {
define_instructions! { @define $($inames)* }
}
};
}
define_instructions! {
PsqLux,
PsqLx,
Twi,
}
Этот код дал мне эту ошибку:
error: expected one of `(`, `,`, `=`, `{`, or `}`, found `!`
--> src/main.rs:17:32
|
17 | define_instructions! { @define $($inames)* }
| ^ expected one of `(`, `,`, `=`, `{`, or `}` here
...
22 | / define_instructions! {
23 | | PsqLux,
24 | | PsqLx,
25 | | Twi,
26 | | }
| |_- in this macro invocation
Кажется, я не могу использовать макросы внутри определения enum
. Предполагая, что это правда, как я могу обойти это и быть в состоянии генерировать варианты перечисления, которые могут содержать или не содержать связанные значения?
Примечание : Я уверен, что что-то не так с добавленными мною правилами, но я бы по крайней мере хотел бы иметь возможность добраться до точки, где я могу их вызвать, чтобы я мог их получить рабочий.
Редактировать
Маккартон объяснил еще один способ сделать то, что я пытаюсь сделать, и это полезно на данный момент.
Однако я все еще хотел бы знать, как использовать макрос внутри определения enum, потому что в будущем я смогу написать макрос следующим образом:
define_instructions! {
/// Name: Trap Word Immediate
/// Simplified Mnemonics:
/// twgti rA, value = twi 8, _rA, _value
/// twllei rA, value = twi 6, _rA, _value
twi TO, rA, SIMM;
// and so on...
}
// That macro would become
pub enum Instruction {
/// Name: Trap Word Immediate
/// Usage: twi TO, rA, SIMM
/// Simplified Mnemonics:
/// twi 8, rA, value = twgti rA, value
/// twllei rA, value = twi 6, rA, value
Twi(u32, u32, u32, u32, u32),
}
Итак, у меня есть обходной путь, но мне все еще интересно, можно ли использовать макросы внутри определения enum
. Возможно ли это, а если нет, то почему?