Implemented equality checks
- Ported over most of the unit tests for the checks from Iridium 1
This commit is contained in:
parent
2564b650ff
commit
4822f5e00b
2 changed files with 145 additions and 8 deletions
|
@ -29,6 +29,7 @@ pub enum Opcode {
|
|||
JMPF,
|
||||
/// Jump backward
|
||||
JMPB,
|
||||
NOP,
|
||||
}
|
||||
|
||||
impl From<u8> for Opcode {
|
||||
|
@ -50,6 +51,7 @@ impl From<u8> for Opcode {
|
|||
14 => Opcode::LTE,
|
||||
15 => Opcode::LT,
|
||||
16 => Opcode::JMPE,
|
||||
17 => Opcode::NOP,
|
||||
_ => Opcode::IGL,
|
||||
}
|
||||
}
|
||||
|
|
151
src/vm.rs
151
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();
|
||||
|
|
Reference in a new issue