diff --git a/src/machine.rs b/src/machine.rs index 9ed52f2..04ad5e4 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -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, + buf: [u8; 1], memory: [u32; 50000], + code: Vec, input: &'a mut BufReader>, output: &'a mut BufWriter>, - 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(); } }