Skip to content

Commit 5d23601

Browse files
Add more tests and iter_values for enum_string
1 parent 357e81f commit 5d23601

File tree

3 files changed

+61
-39
lines changed

3 files changed

+61
-39
lines changed

src/load_file.rs

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl Default for Modifier {
5151
}
5252

5353
impl Modifier {
54-
pub fn from_context(opcode: Opcode, a_mode: AddressMode, b_mode: AddressMode) -> Modifier {
54+
pub fn default_88_to_94(opcode: Opcode, a_mode: AddressMode, b_mode: AddressMode) -> Modifier {
5555
/// Implemented based on the ICWS '94 document,
5656
/// section A.2.1.2: ICWS'88 to ICWS'94 Conversion
5757
use Opcode::*;
@@ -68,7 +68,7 @@ impl Modifier {
6868
match opcode {
6969
Mov | Cmp | Seq | Sne => Modifier::I,
7070
Slt => Modifier::B,
71-
Add | Sub | Mul | Div | Mod => Modifier::F,
71+
Add | Sub | Mul | Div | Mod => Modifier::B,
7272
_ => unreachable!(),
7373
}
7474
}
@@ -132,7 +132,8 @@ pub struct Instruction {
132132

133133
impl Instruction {
134134
pub fn new(opcode: Opcode, field_a: Field, field_b: Field) -> Instruction {
135-
let modifier = Modifier::from_context(opcode, field_a.address_mode, field_b.address_mode);
135+
let modifier =
136+
Modifier::default_88_to_94(opcode, field_a.address_mode, field_b.address_mode);
136137
Instruction {
137138
opcode,
138139
modifier,
@@ -218,19 +219,9 @@ impl PartialEq for Core {
218219
#[cfg(test)]
219220
mod tests {
220221
use itertools::iproduct;
221-
use lazy_static::lazy_static;
222-
223-
use std::str::FromStr;
224222

225223
use super::*;
226224

227-
lazy_static! {
228-
static ref all_modes: vec::Vec<AddressMode> = ["#", "$", "@", "<", ">", "*", "{", "}"]
229-
.iter()
230-
.map(|mode_str| AddressMode::from_str(mode_str).unwrap())
231-
.collect();
232-
}
233-
234225
#[test]
235226
fn default_instruction() {
236227
let expected_instruction = Instruction {
@@ -250,57 +241,78 @@ mod tests {
250241
}
251242

252243
#[test]
253-
fn dat_from_context() {
254-
for (&a_mode, &b_mode) in iproduct!(all_modes.iter(), all_modes.iter()) {
244+
fn dat_default_88_to_94() {
245+
for (&a_mode, &b_mode) in iproduct!(AddressMode::iter_values(), AddressMode::iter_values())
246+
{
255247
assert_eq!(
256-
Modifier::from_context(Opcode::Dat, a_mode, b_mode),
248+
Modifier::default_88_to_94(Opcode::Dat, a_mode, b_mode),
257249
Modifier::F
258250
);
259251
}
260252
}
261253

262254
#[test]
263-
fn modifier_b_from_context() {
255+
fn modifier_b_default_88_to_94() {
264256
use Opcode::*;
265257

266-
let opcodes = [Jmp, Jmz, Jmn, Djn, Spl, Nop];
267-
268-
for (&a_mode, &b_mode) in iproduct!(all_modes.iter(), all_modes.iter()) {
269-
for &opcode in opcodes.iter() {
270-
assert_eq!(Modifier::from_context(opcode, a_mode, b_mode), Modifier::B);
258+
let opcodes = [Mov, Cmp, Seq, Sne];
259+
for (&opcode, &a_mode) in iproduct!(opcodes.iter(), AddressMode::iter_values()) {
260+
if a_mode != AddressMode::Immediate {
261+
assert_eq!(
262+
Modifier::default_88_to_94(opcode, a_mode, AddressMode::Immediate),
263+
Modifier::B
264+
);
271265
}
272266
}
273267

274-
let a_modes: vec::Vec<AddressMode> = ["$", "@", "<", ">", "*", "{", "}"]
275-
.iter()
276-
.map(|mode_str| AddressMode::from_str(mode_str).unwrap())
277-
.collect();
268+
let opcodes = [Add, Sub, Mul, Div, Mod];
269+
for (&opcode, &a_mode, &b_mode) in iproduct!(
270+
opcodes.iter(),
271+
AddressMode::iter_values(),
272+
AddressMode::iter_values()
273+
) {
274+
if a_mode != AddressMode::Immediate {
275+
assert_eq!(
276+
Modifier::default_88_to_94(opcode, a_mode, b_mode),
277+
Modifier::B
278+
);
279+
}
280+
}
278281

279-
for &a_mode in a_modes.iter() {
280-
for &b_mode in all_modes.iter() {
282+
for (&a_mode, &b_mode) in iproduct!(AddressMode::iter_values(), AddressMode::iter_values())
283+
{
284+
if a_mode != AddressMode::Immediate {
281285
assert_eq!(
282-
Modifier::from_context(Opcode::Slt, a_mode, b_mode),
286+
Modifier::default_88_to_94(Opcode::Slt, a_mode, b_mode),
283287
Modifier::B
284288
)
285289
}
286290
}
287291

288-
// TODO Mov, Cmp. Seq, Sne -> B
292+
let opcodes = [Jmp, Jmz, Jmn, Djn, Spl, Nop];
293+
for (&opcode, &a_mode, &b_mode) in iproduct!(
294+
opcodes.iter(),
295+
AddressMode::iter_values(),
296+
AddressMode::iter_values()
297+
) {
298+
assert_eq!(
299+
Modifier::default_88_to_94(opcode, a_mode, b_mode),
300+
Modifier::B
301+
);
302+
}
289303
}
290304

291305
#[test]
292-
fn modifier_ab_from_context() {
306+
fn modifier_ab_default_88_to_94() {
293307
use Opcode::*;
294308

295309
let opcodes = [Mov, Cmp, Seq, Sne, Add, Sub, Mul, Div, Mod, Slt];
296310

297-
for &b_mode in all_modes.iter() {
298-
for &opcode in opcodes.iter() {
299-
assert_eq!(
300-
Modifier::from_context(opcode, AddressMode::Immediate, b_mode),
301-
Modifier::AB
302-
);
303-
}
311+
for (&opcode, &b_mode) in iproduct!(opcodes.iter(), AddressMode::iter_values()) {
312+
assert_eq!(
313+
Modifier::default_88_to_94(opcode, AddressMode::Immediate, b_mode),
314+
Modifier::AB
315+
);
304316
}
305317
}
306318

src/parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ fn parse_instruction(mut instruction_pairs: Pairs<Rule>) -> Instruction {
8989
.map_or_else(Field::default, parse_field);
9090

9191
let modifier = maybe_modifier.unwrap_or_else(|| {
92-
Modifier::from_context(opcode, field_a.address_mode, field_b.address_mode)
92+
Modifier::default_88_to_94(opcode, field_a.address_mode, field_b.address_mode)
9393
});
9494

9595
Instruction {

src/util.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ macro_rules! enum_string {
4141
}
4242
}
4343
}
44+
45+
impl $name {
46+
#[allow(dead_code)]
47+
pub fn iter_values() -> ::std::slice::Iter<'static, Self> {
48+
use $name::*;
49+
#[allow(unused_variable)]
50+
const VALUES: &[$name] = &[$($variant,)*];
51+
VALUES.iter()
52+
}
53+
}
4454
};
4555
}
4656

0 commit comments

Comments
 (0)