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, JMPF,
/// Jump backward /// Jump backward
JMPB, JMPB,
NOP,
} }
impl From<u8> for Opcode { impl From<u8> for Opcode {
@ -50,6 +51,7 @@ impl From<u8> for Opcode {
14 => Opcode::LTE, 14 => Opcode::LTE,
15 => Opcode::LT, 15 => Opcode::LT,
16 => Opcode::JMPE, 16 => Opcode::JMPE,
17 => Opcode::NOP,
_ => Opcode::IGL, _ => Opcode::IGL,
} }
} }

151
src/vm.rs
View file

@ -16,7 +16,7 @@ impl VM {
pc: 0, pc: 0,
program: vec![], program: vec![],
remainder: 0, remainder: 0,
equal_flag: false equal_flag: false,
} }
} }
@ -100,13 +100,90 @@ impl VM {
let target = self.registers[self.next_8_bits() as usize]; let target = self.registers[self.next_8_bits() as usize];
self.pc -= target as usize; self.pc -= target as usize;
} }
Opcode::EQ => {} Opcode::EQ => {
Opcode::NEQ => {} let reg1 = self.registers[self.next_8_bits() as usize];
Opcode::GT => {} let reg2 = self.registers[self.next_8_bits() as usize];
Opcode::LT => {}
Opcode::GTE => {} if reg1 == reg2 {
Opcode::LTE => {} self.equal_flag = true
Opcode::JMPE => {} } 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 true
} }
@ -163,6 +240,64 @@ mod vm_tests {
assert_eq!(vm.registers[2], 2); 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] #[test]
fn test_opcode_igl() { fn test_opcode_igl() {
let mut vm = get_test_vm(); let mut vm = get_test_vm();