fix wrapping bug
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user