Initial start on equality checks
This commit is contained in:
parent
75f814a99f
commit
2564b650ff
3 changed files with 105 additions and 9 deletions
23
docs/spec.md
23
docs/spec.md
|
@ -6,15 +6,22 @@ Corten is based on Fletcher Haynes's [So you want to build a language VM](https:
|
||||||
|
|
||||||
## Instruction Set
|
## Instruction Set
|
||||||
|
|
||||||
| Register | Opcode |
|
| Opcode | Function | Comment |
|
||||||
| --- | --- |
|
| --- | --- | --- |
|
||||||
| 0 | LOAD |
|
| 0 | LOAD | Load program |
|
||||||
| 1 | ADD |
|
| 1 | ADD |
|
||||||
| 2 | SUB |
|
| 2 | SUB |
|
||||||
| 3 | MUL |
|
| 3 | MUL |
|
||||||
| 4 | DIV |
|
| 4 | DIV |
|
||||||
| 6 | HLT |
|
| 6 | HLT | Halt |
|
||||||
| 5 | JMP |
|
| 5 | JMP | Jump |
|
||||||
| 8 | JMPF |
|
| 8 | JMPF | Jump forward |
|
||||||
| 9 | JMPB |
|
| 9 | JMPB | Jump backward |
|
||||||
| _ | IGL |
|
| 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 |
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::instruction::Opcode::LOAD;
|
#![allow(dead_code)]
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum Opcode {
|
pub enum Opcode {
|
||||||
|
@ -9,7 +9,26 @@ pub enum Opcode {
|
||||||
SUB,
|
SUB,
|
||||||
MUL,
|
MUL,
|
||||||
DIV,
|
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,
|
JMP,
|
||||||
|
/// Jump forward
|
||||||
|
JMPF,
|
||||||
|
/// Jump backward
|
||||||
|
JMPB,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u8> for Opcode {
|
impl From<u8> for Opcode {
|
||||||
|
@ -22,6 +41,15 @@ impl From<u8> for Opcode {
|
||||||
4 => Opcode::DIV,
|
4 => Opcode::DIV,
|
||||||
6 => Opcode::HLT,
|
6 => Opcode::HLT,
|
||||||
7 => Opcode::JMP,
|
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,
|
_ => Opcode::IGL,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
61
src/vm.rs
61
src/vm.rs
|
@ -6,6 +6,7 @@ pub struct VM {
|
||||||
pc: usize,
|
pc: usize,
|
||||||
program: Vec<u8>,
|
program: Vec<u8>,
|
||||||
remainder: u32,
|
remainder: u32,
|
||||||
|
equal_flag: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VM {
|
impl VM {
|
||||||
|
@ -15,6 +16,7 @@ impl VM {
|
||||||
pc: 0,
|
pc: 0,
|
||||||
program: vec![],
|
program: vec![],
|
||||||
remainder: 0,
|
remainder: 0,
|
||||||
|
equal_flag: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +65,7 @@ impl VM {
|
||||||
}
|
}
|
||||||
Opcode::IGL => {
|
Opcode::IGL => {
|
||||||
println!("Unrecognized opcode found! Terminating!");
|
println!("Unrecognized opcode found! Terminating!");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
Opcode::ADD => {
|
Opcode::ADD => {
|
||||||
let reg1 = self.registers[self.next_8_bits() as usize];
|
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];
|
let reg2 = self.registers[self.next_8_bits() as usize];
|
||||||
self.registers[self.next_8_bits() as usize] = reg1 - reg2;
|
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
|
true
|
||||||
}
|
}
|
||||||
|
@ -121,6 +139,30 @@ mod vm_tests {
|
||||||
assert_eq!(vm.pc, 1);
|
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]
|
#[test]
|
||||||
fn test_opcode_igl() {
|
fn test_opcode_igl() {
|
||||||
let mut vm = get_test_vm();
|
let mut vm = get_test_vm();
|
||||||
|
@ -139,6 +181,25 @@ mod vm_tests {
|
||||||
assert_eq!(vm.pc, 1);
|
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]
|
#[test]
|
||||||
fn test_load_opcode() {
|
fn test_load_opcode() {
|
||||||
let mut vm = get_test_vm();
|
let mut vm = get_test_vm();
|
||||||
|
|
Reference in a new issue