corewars_core/
load_file.rs1use std::fmt;
2
3use lazy_static::lazy_static;
4
5mod metadata;
6mod program;
7mod types;
8
9pub use metadata::Metadata;
10pub use program::{Instructions, LabelMap, Program};
11pub use types::{AddressMode, Modifier, Offset, Opcode, PseudoOpcode, UOffset, Value};
12
13lazy_static! {
14 pub static ref DEFAULT_CONSTANTS: LabelMap = {
15 let mut constants = LabelMap::new();
16 constants.insert("CORESIZE".into(), 8000);
17 constants.insert("MAXPROCESSES".into(), 8000);
18 constants.insert("MAXCYCLES".into(), 80_000);
19 constants.insert("MAXLENGTH".into(), 100);
20 constants.insert("MINDISTANCE".into(), 100);
21 constants.insert("ROUNDS".into(), 1);
22
23 constants
26 };
27}
28
29#[derive(Debug)]
31pub struct Warrior {
32 pub program: Program,
33 pub metadata: Metadata,
34}
35
36impl fmt::Display for Warrior {
37 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
38 write!(formatter, "{}", self.metadata)?;
39 write!(formatter, "{}", self.program)
40 }
41}
42
43#[derive(Clone, Debug, Default, PartialEq)]
44pub struct Field {
45 pub address_mode: AddressMode,
46 pub value: Value,
47}
48
49impl fmt::Display for Field {
50 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51 f.pad(&format!("{}{}", self.address_mode, self.value))
52 }
53}
54
55impl Field {
56 pub fn direct(value: Offset) -> Self {
57 Self {
58 address_mode: AddressMode::Direct,
59 value: Value::Literal(value),
60 }
61 }
62
63 pub fn direct_label<S: ToString>(label: S) -> Self {
64 Self {
65 address_mode: AddressMode::Direct,
66 value: Value::Label(label.to_string()),
67 }
68 }
69
70 pub fn immediate(value: Offset) -> Self {
71 Self {
72 address_mode: AddressMode::Immediate,
73 value: Value::Literal(value),
74 }
75 }
76}
77
78#[derive(Clone, Debug, Default, PartialEq)]
79pub struct Instruction {
80 pub opcode: Opcode,
81 pub modifier: Modifier,
82 pub field_a: Field,
83 pub field_b: Field,
84}
85
86impl Instruction {
87 pub fn new(opcode: Opcode, field_a: Field, field_b: Field) -> Self {
88 let modifier =
89 Modifier::default_88_to_94(opcode, field_a.address_mode, field_b.address_mode);
90
91 Instruction {
92 opcode,
93 modifier,
94 field_a,
95 field_b,
96 }
97 }
98}
99
100impl fmt::Display for Instruction {
101 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102 f.pad(&format!(
103 "{op:<8}{a:<8}{b}",
107 op = format!("{}.{}", self.opcode, self.modifier),
108 a = format!("{},", self.field_a),
109 b = self.field_b,
110 ))
111 }
112}
113
114#[cfg(test)]
115mod test {
116 use super::*;
117
118 #[test]
119 fn default_instruction() {
120 let expected_instruction = Instruction {
121 opcode: Opcode::Dat,
122 modifier: Modifier::F,
123 field_a: Field {
124 address_mode: AddressMode::Direct,
125 value: Value::Literal(0),
126 },
127 field_b: Field {
128 address_mode: AddressMode::Direct,
129 value: Value::Literal(0),
130 },
131 };
132
133 assert_eq!(Instruction::default(), expected_instruction)
134 }
135}