use essential_types::Word;
use crate::{error::TemporaryError, OpResult};
#[cfg(test)]
mod tests;
#[derive(Default, Debug, PartialEq)]
pub struct Memory(Vec<Word>);
impl Memory {
pub const SIZE_LIMIT: usize = 1024 * 10;
pub fn new() -> Self {
Self::default()
}
pub fn alloc(&mut self, size: Word) -> OpResult<()> {
let size = usize::try_from(size).map_err(|_| TemporaryError::Overflow)?;
let new_size = self
.0
.len()
.checked_add(size)
.ok_or(TemporaryError::Overflow)?;
if new_size > Self::SIZE_LIMIT {
return Err(TemporaryError::Overflow.into());
}
self.0.resize(new_size, 0);
Ok(())
}
pub fn store(&mut self, address: Word, value: Word) -> OpResult<()> {
let index = usize::try_from(address).map_err(|_| TemporaryError::IndexOutOfBounds)?;
*self
.0
.get_mut(index)
.ok_or(TemporaryError::IndexOutOfBounds)? = value;
Ok(())
}
pub fn load(&mut self, address: Word) -> OpResult<Word> {
let index = usize::try_from(address).map_err(|_| TemporaryError::IndexOutOfBounds)?;
Ok(*self.0.get(index).ok_or(TemporaryError::IndexOutOfBounds)?)
}
pub fn len(&self) -> OpResult<Word> {
Ok(self
.0
.len()
.try_into()
.map_err(|_| TemporaryError::Overflow)?)
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}