Implemented equality checks

- Ported over most of the unit tests for the checks from Iridium 1
This commit is contained in:
Anthony Foxclaw 2020-02-06 22:05:48 -05:00
parent 2564b650ff
commit 4822f5e00b
2 changed files with 145 additions and 8 deletions

View file

@ -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
View file

@ -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();