У меня есть enum, который представляет все возможные инструкции для процессора 8080.Инструкция может иметь длину 1, 2 или 3 байта, в зависимости от того, имеет ли она информацию, связанную с ней, и ее объем.Например:
#[allow(non_camel_case_types)]
enum Instruction {
None,
NOP,
LXI_B_D16(u8, u8),
STAX_B,
INX_B,
MVI_B_D8(u8),
MVI_C_D8(u8),
RRC,
LXI_D_D16(u8, u8),
MVI_D_D8(u8),
RAL,
DCR_E,
MVI_E_D8(u8),
LXI_H_D16(u8, u8),
SHLD(u16),
LHLD(u16),
// ...
}
Когда дело доходит до назначения адресов памяти инструкциям, я перебираю инструкцию за инструкцией по двоичному файлу, используя длину каждой инструкции, чтобы убедиться, что мой цикл не переместился на полпутичерез инструкцию и дай мне мусор.Я делаю это с помощью огромного выражения соответствия, которое возвращает кортеж, содержащий правильную инструкцию и ее длину:
match value {
0x00 => (Instruction::NOP, 1),
0x01 => (Instruction::LXI_B_D16(d1, d2), 3),
0x02 => (Instruction::STAX_B, 1),
0x05 => (Instruction::DCR_B, 1),
0x06 => (Instruction::MVI_B_D8(d1), 2),
0x07 => (Instruction::RLC, 1),
0x0e => (Instruction::MVI_C_D8(d1), 2),
0x0f => (Instruction::RRC, 1),
0x11 => (Instruction::LXI_D_D16(d1, d2), 3),
0x19 => (Instruction::DAD_D, 1),
// ...
}
Это уродливо, но я не хочу связывать это число длины с типом, потому что этодействительно важно только когда я разбираю файл.
Похоже, я должен иметь возможность просто определить длину инструкции по форме варианта.Все без аргументов имеет длину 1, все с одним аргументом u8 имеет длину 2, а все, что имеет один аргумент u16 или два аргумента u8, имеет длину 3.
Я не смог понять, как получить эту формупрограммно.Я не могу назвать len()
на нем, например, массивом или вектором.
Я не думаю, что это дубликат Как получить количество элементов в перечислении какконстантное значение? , так как я не ищу способ получить количество вариантов в перечислении, а количество аргументов любого отдельного варианта .