use std::{collections::VecDeque, convert::TryFrom};
pub(crate) struct Memory {
cells: VecDeque<u8>,
pointer: usize,
offset: usize,
}
impl Memory {
pub fn new() -> Self {
let mut cells = VecDeque::with_capacity(1);
cells.push_back(0);
Self {
cells,
pointer: 0,
offset: 0,
}
}
pub fn add(&mut self, amount: i8) {
let c = &mut self.cells[self.pointer];
*c = c.wrapping_add(amount as u8);
}
pub fn get_cell(&self) -> u8 {
self.cells[self.pointer]
}
pub fn set_cell(&mut self, c: u8) {
self.cells[self.pointer] = c;
}
pub fn move_pointer(&mut self, amount: isize) {
if amount >= 0 {
self.pointer += amount as usize;
if self.pointer >= self.cells.len() {
self.cells.resize(self.pointer + 1, 0);
}
} else {
let amount = (-amount) as usize;
if self.pointer >= amount {
self.pointer -= amount;
} else {
let offset = amount - self.pointer;
self.pointer = 0;
self.offset += offset;
self.cells.reserve(offset);
for _ in 0..offset {
self.cells.push_front(0);
}
}
}
}
pub fn append_debug(&self, output: &mut Vec<u8>) {
output.append(
&mut format!(
"[{},{}]",
i128::try_from(self.pointer).unwrap() - i128::try_from(self.offset).unwrap(),
self.get_cell(),
)
.into_bytes(),
);
}
}