From 4822f5e00b1b7d64178233b6c9ba0180527445cb Mon Sep 17 00:00:00 2001 From: Anthony Foxclaw <35226681+tonytins@users.noreply.github.com> Date: Thu, 6 Feb 2020 22:05:48 -0500 Subject: [PATCH] Implemented equality checks - Ported over most of the unit tests for the checks from Iridium 1 --- src/instruction.rs | 2 + src/vm.rs | 151 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 145 insertions(+), 8 deletions(-) diff --git a/src/instruction.rs b/src/instruction.rs index 7b120c4..f2cc10b 100644 --- a/src/instruction.rs +++ b/src/instruction.rs @@ -29,6 +29,7 @@ pub enum Opcode { JMPF, /// Jump backward JMPB, + NOP, } impl From for Opcode { @@ -50,6 +51,7 @@ impl From for Opcode { 14 => Opcode::LTE, 15 => Opcode::LT, 16 => Opcode::JMPE, + 17 => Opcode::NOP, _ => Opcode::IGL, } } diff --git a/src/vm.rs b/src/vm.rs index 653c2d9..04f582f 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -16,7 +16,7 @@ impl VM { pc: 0, program: vec![], remainder: 0, - equal_flag: false + equal_flag: false, } } @@ -100,13 +100,90 @@ impl VM { let target = self.registers[self.next_8_bits() as usize]; self.pc -= target as usize; } - Opcode::EQ => {} - Opcode::NEQ => {} - Opcode::GT => {} - Opcode::LT => {} - Opcode::GTE => {} - Opcode::LTE => {} - Opcode::JMPE => {} + Opcode::EQ => { + let reg1 = self.registers[self.next_8_bits() as usize]; + let reg2 = self.registers[self.next_8_bits() as usize]; + + if reg1 == reg2 { + self.equal_flag = true + } else { + self.equal_flag = false; + } + + self.next_8_bits(); + } + Opcode::NEQ => { + let reg1 = self.registers[self.next_8_bits() as usize]; + let reg2 = self.registers[self.next_8_bits() as usize]; + + if reg1 != reg2 { + self.equal_flag = true + } else { + self.equal_flag = false; + } + + self.next_8_bits(); + } + Opcode::GT => { + let reg1 = self.registers[self.next_8_bits() as usize]; + let reg2 = self.registers[self.next_8_bits() as usize]; + + if reg1 > reg2 { + self.equal_flag = true + } else { + self.equal_flag = false; + } + + self.next_8_bits(); + } + Opcode::LT => { + let reg1 = self.registers[self.next_8_bits() as usize]; + let reg2 = self.registers[self.next_8_bits() as usize]; + + if reg1 < reg2 { + self.equal_flag = true + } else { + self.equal_flag = false; + } + + self.next_8_bits(); + } + Opcode::GTE => { + let reg1 = self.registers[self.next_8_bits() as usize]; + let reg2 = self.registers[self.next_8_bits() as usize]; + + if reg1 >= reg2 { + self.equal_flag = true + } else { + self.equal_flag = false; + } + + self.next_8_bits(); + } + Opcode::LTE => { + let reg1 = self.registers[self.next_8_bits() as usize]; + let reg2 = self.registers[self.next_8_bits() as usize]; + + if reg1 <= reg2 { + self.equal_flag = true + } else { + self.equal_flag = false; + } + + self.next_8_bits(); + } + Opcode::JMPE => { + let reg = self.next_8_bits() as usize; + let target = self.registers[reg]; + if self.equal_flag { + self.pc = target as usize; + } + } + Opcode::NOP => { + self.next_8_bits(); + self.next_8_bits(); + self.next_8_bits(); + } } true } @@ -163,6 +240,64 @@ mod vm_tests { assert_eq!(vm.registers[2], 2); } + #[test] + fn test_eq_opcode() { + let mut vm = get_test_vm(); + vm.registers[0] = 10; + vm.registers[1] = 10; + vm.program = vec![10, 0, 1, 0, 10, 0, 1, 0]; + vm.run_once(); + assert_eq!(vm.equal_flag, true); + vm.registers[1] = 20; + vm.run_once(); + assert_eq!(vm.equal_flag, false); + } + + #[test] + fn test_neq_opcode() { + let mut vm = get_test_vm(); + vm.registers[0] = 10; + vm.registers[1] = 20; + vm.program = vec![11, 0, 1, 0, 11, 0, 1, 0]; + vm.run_once(); + assert_eq!(vm.equal_flag, true); + vm.registers[1] = 10; + vm.run_once(); + assert_eq!(vm.equal_flag, false); + } + + #[test] + fn test_gte_opcode() { + let mut vm = get_test_vm(); + vm.registers[0] = 20; + vm.registers[1] = 10; + vm.program = vec![12, 0, 1, 0, 12, 0, 1, 0, 12, 0, 1, 0]; + vm.run_once(); + assert_eq!(vm.equal_flag, true); + vm.registers[0] = 10; + vm.run_once(); + assert_eq!(vm.equal_flag, true); + vm.registers[0] = 5; + vm.run_once(); + assert_eq!(vm.equal_flag, false); + } + + #[test] + fn test_gt_opcode() { + let mut vm = get_test_vm(); + vm.registers[0] = 20; + vm.registers[1] = 10; + vm.program = vec![13, 0, 1, 0, 13, 0, 1, 0, 13, 0, 1, 0]; + vm.run_once(); + assert_eq!(vm.equal_flag, true); + vm.registers[0] = 10; + vm.run_once(); + assert_eq!(vm.equal_flag, false); + vm.registers[0] = 5; + vm.run_once(); + assert_eq!(vm.equal_flag, false); + } + #[test] fn test_opcode_igl() { let mut vm = get_test_vm();