corewars_core/load_file/
program.rsuse std::collections::HashMap;
use std::convert::TryInto;
use std::fmt;
use super::{Instruction, PseudoOpcode};
pub type Instructions = Vec<Instruction>;
pub type LabelMap = HashMap<String, u32>;
#[derive(Default, PartialEq, Eq)]
pub struct Program {
pub instructions: Instructions,
pub origin: Option<u32>,
}
impl Program {
#[must_use]
pub fn len(&self) -> u32 {
self.instructions
.len()
.try_into()
.expect("Program should not have > u32::MAX instructions")
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.instructions.is_empty()
}
#[must_use]
pub fn get(&self, index: u32) -> Option<Instruction> {
self.instructions.get(index as usize).cloned()
}
pub fn set(&mut self, index: u32, value: Instruction) {
let index = index as usize;
if index >= self.instructions.len() {
self.instructions.resize_with(index + 1, Default::default);
}
self.instructions[index] = value;
}
}
impl fmt::Debug for Program {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
writeln!(formatter, "{{")?;
writeln!(formatter, "origin: {:?},", self.origin)?;
let lines = self
.instructions
.iter()
.map(std::string::ToString::to_string)
.collect::<Vec<_>>();
write!(formatter, "lines: {lines:#?},")?;
writeln!(formatter, "}}")
}
}
impl fmt::Display for Program {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let mut lines = Vec::new();
lines.push(format!(
"{:<8}{}",
PseudoOpcode::Org,
self.origin.unwrap_or_default()
));
for instruction in &self.instructions {
lines.push(instruction.to_string());
}
write!(formatter, "{}", lines.join("\n"))
}
}