add machine logic, first draft

This commit is contained in:
2021-09-20 13:28:03 +02:00
parent 46b9cfbd8d
commit 48d90e6a2a

View File

@@ -2,10 +2,10 @@ use std::io::{BufReader, BufWriter, Read, Write};
#[derive(Debug)]
pub enum InstructionType {
Plus,
Minus,
Left,
Right,
Increment,
Decrement,
Leftshift,
Rightshift,
PutChar,
GetChar,
JumpIfZero,
@@ -14,18 +14,18 @@ pub enum InstructionType {
#[derive(Debug)]
pub struct Instruction {
pub ins_type: InstructionType,
pub itype: InstructionType,
pub argument: usize,
}
pub struct Machine<'a> {
ip: usize,
mp: usize,
code: Vec<Instruction>,
buf: [u8; 1],
memory: [u32; 50000],
code: Vec<Instruction>,
input: &'a mut BufReader<Box<dyn Read>>,
output: &'a mut BufWriter<Box<dyn Write>>,
buf: [u8; 1],
}
impl<'a> Machine<'a> {
@@ -33,23 +33,84 @@ impl<'a> Machine<'a> {
Machine {
ip: 0,
mp: 0,
code,
buf: [0;1],
memory: [0; 50000],
code,
input,
output,
buf: [0;1],
}
}
pub fn execute(&mut self){
return;
// prevent ip from getting out of bounds
while self.ip < self.code.len() {
// get current instruction
let instruction = &self.code[self.ip];
// match type and execute
match instruction.itype {
InstructionType::Increment => {
self.memory[self.mp] += instruction.argument as u32
}
InstructionType::Decrement => {
self.memory[self.mp] -= instruction.argument as u32
}
InstructionType::Leftshift => {
self.mp += instruction.argument
}
InstructionType::Rightshift => {
self.mp -= instruction.argument
}
InstructionType::PutChar => {
for _ in 0..instruction.argument {
self.put_char()
}
}
InstructionType::GetChar => {
for _ in 0..instruction.argument {
self.get_char()
}
}
InstructionType::JumpIfZero => {
if self.memory[self.mp] == 0 {
self.ip = instruction.argument;
continue;
}
}
InstructionType::JumpIfNotZero => {
if self.memory[self.mp] != 0 {
self.ip = instruction.argument;
continue;
}
}
}
}
}
pub fn read_char(&mut self){
return;
pub fn get_char(&mut self){
let byte_input = match self.input.read(&mut self.buf) {
Ok(byte_input) => byte_input,
Err(e) => panic!(e),
};
if byte_input != 1 {
panic!("input read error")
}
self.memory[self.mp] = self.buf[0] as u32;
}
pub fn put_char(&mut self){
return;
self.buf[0] = self.memory[self.mp] as u8;
let byte_write = match self.output.write(&self.buf) {
Ok(byte_write) => byte_write,
Err(e) => panic!(e),
};
if byte_write != 1 {
panic!("output write error")
}
self.output.flush();
}
}