Initial start on equality checks

This commit is contained in:
Anthony Foxclaw 2020-02-06 21:40:09 -05:00
parent 75f814a99f
commit 2564b650ff
3 changed files with 105 additions and 9 deletions

View file

@ -6,15 +6,22 @@ Corten is based on Fletcher Haynes's [So you want to build a language VM](https:
## Instruction Set
| Register | Opcode |
| --- | --- |
| 0 | LOAD |
| Opcode | Function | Comment |
| --- | --- | --- |
| 0 | LOAD | Load program |
| 1 | ADD |
| 2 | SUB |
| 3 | MUL |
| 4 | DIV |
| 6 | HLT |
| 5 | JMP |
| 8 | JMPF |
| 9 | JMPB |
| _ | IGL |
| 6 | HLT | Halt |
| 5 | JMP | Jump |
| 8 | JMPF | Jump forward |
| 9 | JMPB | Jump backward |
| 10 | EQ | Equal |
| 11 | NEQ | Not equal |
| 12 | GTE | Greater then or equal to |
| 13 | GT | Greater then |
| 14 | LTE | Less then or equal |
| 15 | LT | Less then
| 16 | JMPE | Jump if equal |
| _ | IGL | Illegal action |

View file

@ -1,4 +1,4 @@
use crate::instruction::Opcode::LOAD;
#![allow(dead_code)]
#[derive(Debug, PartialEq)]
pub enum Opcode {
@ -9,7 +9,26 @@ pub enum Opcode {
SUB,
MUL,
DIV,
/// Equal
EQ,
/// Not equal
NEQ,
/// Greater then
GT,
/// Less then
LT,
/// Greater then or equal to
GTE,
/// less then or equal
LTE,
/// jump if equal
JMPE,
/// Jump
JMP,
/// Jump forward
JMPF,
/// Jump backward
JMPB,
}
impl From<u8> for Opcode {
@ -22,6 +41,15 @@ impl From<u8> for Opcode {
4 => Opcode::DIV,
6 => Opcode::HLT,
7 => Opcode::JMP,
8 => Opcode::JMPF,
9 => Opcode::JMPB,
10 => Opcode::EQ,
11 => Opcode::NEQ,
12 => Opcode::GTE,
13 => Opcode::GT,
14 => Opcode::LTE,
15 => Opcode::LT,
16 => Opcode::JMPE,
_ => Opcode::IGL,
}
}

View file

@ -6,6 +6,7 @@ pub struct VM {
pc: usize,
program: Vec<u8>,
remainder: u32,
equal_flag: bool,
}
impl VM {
@ -15,6 +16,7 @@ impl VM {
pc: 0,
program: vec![],
remainder: 0,
equal_flag: false
}
}
@ -63,6 +65,7 @@ impl VM {
}
Opcode::IGL => {
println!("Unrecognized opcode found! Terminating!");
return false;
}
Opcode::ADD => {
let reg1 = self.registers[self.next_8_bits() as usize];
@ -89,6 +92,21 @@ impl VM {
let reg2 = self.registers[self.next_8_bits() as usize];
self.registers[self.next_8_bits() as usize] = reg1 - reg2;
}
Opcode::JMPF => {
let target = self.registers[self.next_8_bits() as usize];
self.pc += target as usize;
}
Opcode::JMPB => {
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 => {}
}
true
}
@ -121,6 +139,30 @@ mod vm_tests {
assert_eq!(vm.pc, 1);
}
#[test]
fn test_add_opcode() {
let mut vm = get_test_vm();
vm.program = vec![1, 0, 1, 2];
vm.run();
assert_eq!(vm.registers[2], 15);
}
#[test]
fn test_sub_opcode() {
let mut vm = get_test_vm();
vm.program = vec![2, 1, 0, 2];
vm.run();
assert_eq!(vm.registers[2], 5);
}
#[test]
fn test_div_opcode() {
let mut vm = get_test_vm();
vm.program = vec![4, 1, 0, 2];
vm.run();
assert_eq!(vm.registers[2], 2);
}
#[test]
fn test_opcode_igl() {
let mut vm = get_test_vm();
@ -139,6 +181,25 @@ mod vm_tests {
assert_eq!(vm.pc, 1);
}
#[test]
fn test_jmpf_opcode() {
let mut vm = get_test_vm();
vm.registers[0] = 2;
vm.program = vec![8, 0, 0, 0, 6, 0, 0, 0];
vm.run_once();
assert_eq!(vm.pc, 4);
}
#[test]
fn test_jmpb_opcode() {
let mut vm = get_test_vm();
vm.registers[1] = 6;
vm.program = vec![0, 0, 0, 10, 9, 1, 0, 0];
vm.run_once();
vm.run_once();
assert_eq!(vm.pc, 0);
}
#[test]
fn test_load_opcode() {
let mut vm = get_test_vm();