fix wrapping bug

This commit is contained in:
aaron
2021-09-23 01:52:06 +02:00
parent 9071a057a2
commit 32a9e03680

View File

@@ -1,24 +1,28 @@
use std::io::{BufReader, BufWriter, Read, Write}; use std::io::{BufReader, BufWriter, Read, Write};
use crate::instruction::{Instruction, InstructionType}; use crate::instruction::{Instruction, InstructionType};
const CELL_SIZE: u8 = 255;
const ADDRESS_SIZE: usize = 30000;
pub struct Machine<'a> { pub struct Machine<'a> {
ip: usize, ip: usize,
mp: usize, mp: usize,
buf: [u8; 1], buf: [u8; 1],
memory: [u32; 50000], memory: [u8; ADDRESS_SIZE],
code: Vec<Instruction>, code: Vec<Instruction>,
input: &'a mut BufReader<Box<dyn Read>>, input: &'a mut BufReader<Box<dyn Read>>,
output: &'a mut BufWriter<Box<dyn Write>>, output: &'a mut BufWriter<Box<dyn Write>>,
} }
impl<'a> Machine<'a> { impl<'a> Machine<'a> {
pub fn new(code: Vec<Instruction>, input: &'a mut BufReader<Box<dyn Read>>, output: &'a mut BufWriter<Box<dyn Write>>) -> Self { pub fn new(code: Vec<Instruction>,
input: &'a mut BufReader<Box<dyn Read>>,
output: &'a mut BufWriter<Box<dyn Write>>) -> Self {
Machine { Machine {
ip: 0, ip: 0,
mp: 0, mp: 0,
buf: [0; 1], buf: [0; 1],
memory: [0; 50000], memory: [0; ADDRESS_SIZE],
code, code,
input, input,
output, output,
@@ -30,7 +34,7 @@ impl<'a> Machine<'a> {
while self.ip < self.code.len() { while self.ip < self.code.len() {
// get current instruction // get current instruction
let instruction = &self.code[self.ip]; let instruction = &self.code[self.ip];
println!("{:?}", instruction); println!("{:?} ; {}", instruction, self.mp);
// match type and execute // match type and execute
match instruction.itype { match instruction.itype {
InstructionType::Increment => self.do_increment(instruction.argument), InstructionType::Increment => self.do_increment(instruction.argument),
@@ -55,21 +59,41 @@ impl<'a> Machine<'a> {
self.ip += 1; self.ip += 1;
} }
} }
// safely increment cell value
pub fn do_increment(&mut self, argument: usize){ pub fn do_increment(&mut self, argument: usize){
self.memory[self.mp] += argument as u32 if((self.memory[self.mp] + argument as u8) >= CELL_SIZE ) {
self.memory[self.mp] = CELL_SIZE - (self.memory[self.mp] + argument as u8);
} else {
self.memory[self.mp] += argument as u8;
}
} }
// safely decrement cell value
pub fn do_decrement(&mut self, argument: usize){ pub fn do_decrement(&mut self, argument: usize){
self.memory[self.mp] -= argument as u32 if( self.memory[self.mp] < argument as u8 ){
} self.memory[self.mp] = CELL_SIZE - argument as u8;
} else {
pub fn do_leftshift(&mut self, argument: usize){ self.memory[self.mp] -= argument as u8;
self.mp += argument }
} }
// safely increment memory pointer address
pub fn do_rightshift(&mut self, argument: usize){ pub fn do_rightshift(&mut self, argument: usize){
self.mp -= argument if((self.mp + argument) >= ADDRESS_SIZE ){
self.mp = ADDRESS_SIZE - (self.mp + argument);
} else {
self.mp += argument;
}
}
// safely decrement memory pointer address
pub fn do_leftshift(&mut self, argument: usize){
if( self.mp < argument ) {
self.mp = ADDRESS_SIZE - argument;
} else {
self.mp -= argument;
}
} }
pub fn do_get_char(&mut self, argument: usize){ pub fn do_get_char(&mut self, argument: usize){
@@ -83,7 +107,7 @@ impl<'a> Machine<'a> {
panic!("input read error") panic!("input read error")
} }
self.memory[self.mp] = self.buf[0] as u32; self.memory[self.mp] = self.buf[0] as u8;
} }
} }