Initial source commit
This commit is contained in:
commit
08b16dae6b
12 changed files with 833 additions and 0 deletions
45
src/instruction.rs
Normal file
45
src/instruction.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
#[derive(Debug, PartialEq)]
|
||||
pub enum Opcode {
|
||||
HLT,
|
||||
IGL
|
||||
}
|
||||
|
||||
|
||||
impl From<u8> for Opcode {
|
||||
fn from(vm: u8) -> Self {
|
||||
match vm {
|
||||
0 => Opcode::HLT,
|
||||
_ => Opcode::IGL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Instruction {
|
||||
opcode: Opcode
|
||||
}
|
||||
|
||||
impl Instruction {
|
||||
pub fn new(opcode: Opcode) -> Self {
|
||||
Instruction {
|
||||
opcode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod instruction_tests {
|
||||
use crate::instruction::*;
|
||||
|
||||
#[test]
|
||||
fn test_crate_hlt() {
|
||||
let opcode = Opcode::HLT;
|
||||
assert_eq!(opcode, Opcode::HLT);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_instruction() {
|
||||
let inst = Instruction::new(Opcode::HLT);
|
||||
assert_eq!(inst.opcode, Opcode::HLT);
|
||||
}
|
||||
}
|
2
src/lib.rs
Normal file
2
src/lib.rs
Normal file
|
@ -0,0 +1,2 @@
|
|||
mod vm;
|
||||
mod instruction;
|
5
src/main.rs
Normal file
5
src/main.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
70
src/vm.rs
Normal file
70
src/vm.rs
Normal file
|
@ -0,0 +1,70 @@
|
|||
use crate::instruction::Opcode;
|
||||
|
||||
pub struct VM {
|
||||
registers: [i32; 32],
|
||||
pc: usize,
|
||||
program: Vec<u8>
|
||||
}
|
||||
|
||||
impl VM {
|
||||
pub fn new() -> Self {
|
||||
VM {
|
||||
registers: [0; 32],
|
||||
pc: 0,
|
||||
program: vec![]
|
||||
}
|
||||
}
|
||||
|
||||
fn decode_opcode(&mut self) -> Opcode {
|
||||
let opcode = Opcode::from(self.program[self.pc]);
|
||||
self.pc += 1;
|
||||
opcode
|
||||
}
|
||||
|
||||
pub fn run(&mut self) {
|
||||
loop {
|
||||
if self.pc >= self.program.len() {
|
||||
break;
|
||||
}
|
||||
match self.decode_opcode() {
|
||||
Opcode::HLT => {
|
||||
println!("HLT encountered");
|
||||
return;
|
||||
}
|
||||
Opcode::IGL => {
|
||||
println!("Unrecognized opcode found! Terminating!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod vm_tests {
|
||||
use crate::vm::*;
|
||||
|
||||
#[test]
|
||||
fn test_crate_vm() {
|
||||
let test_vm = VM::new();
|
||||
assert_eq!(test_vm.registers[0], 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_opcode_hlt() {
|
||||
let mut test_vm = VM::new();
|
||||
let test_bytes = vec![0,0,0,0];
|
||||
test_vm.program = test_bytes;
|
||||
test_vm.run();
|
||||
assert_eq!(test_vm.pc, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_opcode_igl() {
|
||||
let mut test_vm = VM::new();
|
||||
let test_bytes = vec![200,0,0,0];
|
||||
test_vm.program = test_bytes;
|
||||
test_vm.run();
|
||||
assert_eq!(test_vm.pc, 1);
|
||||
}
|
||||
}
|
Reference in a new issue