use std::fmt;
use crate::{Effect, Value};
pub struct Memory {
pub values: Vec<Value>,
}
impl Memory {
pub fn read(&self, address: u32) -> Result<Value, InvalidAddress> {
let Ok(address): Result<usize, _> = address.try_into() else {
return Err(InvalidAddress);
};
let Some(value) = self.values.get(address).copied() else {
return Err(InvalidAddress);
};
Ok(value)
}
pub fn write(
&mut self,
address: u32,
value: Value,
) -> Result<(), InvalidAddress> {
let Ok(address): Result<usize, _> = address.try_into() else {
return Err(InvalidAddress);
};
if address >= self.values.len() {
return Err(InvalidAddress);
}
self.values[address] = value;
Ok(())
}
pub fn to_i32_slice(&self) -> &[i32] {
bytemuck::cast_slice(&self.values)
}
pub fn to_u32_slice(&self) -> &[u32] {
bytemuck::cast_slice(&self.values)
}
}
impl Default for Memory {
fn default() -> Self {
Self {
values: vec![Value::from(0); 1024],
}
}
}
impl fmt::Debug for Memory {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut values = self.values.iter().peekable();
write!(f, "[")?;
while let Some(value) = values.next() {
write!(f, "{value:?}")?;
if values.peek().is_some() {
write!(f, ", ")?;
}
}
write!(f, "]")?;
Ok(())
}
}
#[derive(Debug)]
pub struct InvalidAddress;
impl From<InvalidAddress> for Effect {
fn from(InvalidAddress: InvalidAddress) -> Self {
Effect::InvalidAddress
}
}