corewars_core/load_file/
program.rs

1//! Definitions for types that hold information about a Redcode warrior (called
2//! a Program in memory)
3
4use std::{collections::HashMap, fmt};
5
6use super::{Instruction, PseudoOpcode, UOffset};
7
8pub type Instructions = Vec<Instruction>;
9pub type LabelMap = HashMap<String, usize>;
10
11/// A parsed Redcode program, which can be loaded into a core for execution
12#[derive(Default, PartialEq)]
13pub struct Program {
14    /// The list of instructions in the program. These are one-to-one copied into
15    /// the core when loaded for execution
16    pub instructions: Instructions,
17
18    /// The program's entry point as an instruction index
19    pub origin: Option<UOffset>,
20}
21
22impl Program {
23    pub fn get(&self, index: usize) -> Option<Instruction> {
24        self.instructions.get(index).cloned()
25    }
26
27    pub fn set(&mut self, index: usize, value: Instruction) {
28        if index >= self.instructions.len() {
29            self.instructions.resize_with(index + 1, Default::default);
30        }
31
32        self.instructions[index] = value;
33    }
34}
35
36impl fmt::Debug for Program {
37    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
38        writeln!(formatter, "{{")?;
39        writeln!(formatter, "origin: {:?},", self.origin)?;
40
41        let lines = self
42            .instructions
43            .iter()
44            .map(|s| s.to_string())
45            .collect::<Vec<_>>();
46
47        write!(formatter, "lines: {:#?},", lines)?;
48        writeln!(formatter, "}}")
49    }
50}
51
52impl fmt::Display for Program {
53    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
54        let mut lines = Vec::new();
55
56        if let Some(offset) = self.origin {
57            // Width to match other instruction types
58            lines.push(format!("{:<8}{}", PseudoOpcode::Org, offset));
59        }
60
61        for instruction in self.instructions.iter() {
62            lines.push(instruction.to_string());
63        }
64
65        write!(formatter, "{}", lines.join("\n"))
66    }
67}