Skip to content

Commit 159ba88

Browse files
Clean up load file format and add ORG support
Alignment makes things much more readable. Also set the origin point for a program if provided, 0 if not specified.
1 parent 9ca35f9 commit 159ba88

File tree

8 files changed

+104
-49
lines changed

8 files changed

+104
-49
lines changed

src/load_file.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl Default for Field {
4141

4242
impl fmt::Display for Field {
4343
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
44-
write!(f, "{}{}", self.address_mode, self.value)
44+
f.pad(&format!("{}{}", self.address_mode, self.value))
4545
}
4646
}
4747

@@ -53,6 +53,13 @@ impl Field {
5353
}
5454
}
5555

56+
pub fn direct_label<S: ToString>(label: S) -> Self {
57+
Self {
58+
address_mode: AddressMode::Direct,
59+
value: Value::Label(label.to_string()),
60+
}
61+
}
62+
5663
pub fn immediate(value: i32) -> Self {
5764
Self {
5865
address_mode: AddressMode::Immediate,
@@ -89,11 +96,10 @@ pub struct Instruction {
8996

9097
impl fmt::Display for Instruction {
9198
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92-
write!(
93-
f,
94-
"{}.{} {}, {}",
99+
f.pad(&format!(
100+
"{}.{:<2} {}, {}",
95101
self.opcode, self.modifier, self.field_a, self.field_b,
96-
)
102+
))
97103
}
98104
}
99105

src/load_file/program.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{collections::HashMap, fmt};
22

3-
use super::{Instruction, DEFAULT_CONSTANTS};
3+
use super::{Field, Instruction, Opcode, DEFAULT_CONSTANTS};
44

55
type Instructions = Vec<Instruction>;
66
pub type LabelMap = HashMap<String, usize>;
@@ -9,6 +9,7 @@ pub struct Program {
99
instructions: Instructions,
1010
resolved: Option<Instructions>,
1111
labels: LabelMap,
12+
origin: Option<Field>,
1213
}
1314

1415
impl PartialEq for Program {
@@ -36,6 +37,9 @@ impl fmt::Debug for Program {
3637

3738
impl fmt::Display for Program {
3839
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
40+
if let Some(origin) = self.get_origin() {
41+
writeln!(f, "{:<6} {}", Opcode::Org, origin.value)?;
42+
}
3943
write!(
4044
f,
4145
"{}",
@@ -57,6 +61,7 @@ impl Program {
5761
instructions: Instructions::new(),
5862
resolved: None,
5963
labels: DEFAULT_CONSTANTS.clone(),
64+
origin: None,
6065
}
6166
}
6267

@@ -65,6 +70,7 @@ impl Program {
6570
instructions: vec![Default::default(); size],
6671
resolved: None,
6772
labels: DEFAULT_CONSTANTS.clone(),
73+
origin: None,
6874
}
6975
}
7076

@@ -85,6 +91,16 @@ impl Program {
8591
self.instructions[index] = value;
8692
}
8793

94+
pub fn set_origin(&mut self, field: Field) {
95+
self.origin = Some(field);
96+
}
97+
98+
pub fn get_origin(&self) -> Option<Field> {
99+
self.origin
100+
.as_ref()
101+
.and_then(|field| field.resolve(0, &self.labels).ok())
102+
}
103+
88104
pub fn add_label(&mut self, index: usize, label: String) -> Result<(), String> {
89105
if index > self.instructions.len() {
90106
return Err(format!(
@@ -151,6 +167,34 @@ mod tests {
151167
assert!(program.label_address("never_mentioned").is_none());
152168
}
153169

170+
#[test]
171+
fn literal_origin() {
172+
let mut program = Program::with_capacity(200);
173+
174+
program.set_origin(Field::direct(12));
175+
176+
assert_eq!(program.get_origin().unwrap(), Field::direct(12))
177+
}
178+
179+
#[test]
180+
fn labeled_origin() {
181+
let mut program = Program::with_capacity(200);
182+
183+
program
184+
.add_label(123, "baz".into())
185+
.expect("Should add baz");
186+
program.add_label(0, "foo".into()).expect("Should add foo");
187+
188+
program.set_origin(Field::direct_label("baz"));
189+
assert_eq!(program.get_origin().unwrap(), Field::direct(123));
190+
191+
program.set_origin(Field::direct_label("foo"));
192+
assert_eq!(program.get_origin().unwrap(), Field::direct(0));
193+
194+
program.set_origin(Field::direct_label("nonexistent"));
195+
assert!(program.get_origin().is_none());
196+
}
197+
154198
#[test]
155199
fn resolve_failure() {
156200
let mut program = Program::with_capacity(10);

src/load_file/types.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,15 @@ enum_string!(pub Opcode {
1818
Slt => "SLT",
1919
Spl => "SPL",
2020
Nop => "NOP",
21+
Org => "ORG",
2122
});
2223

2324
impl Default for Opcode {
2425
fn default() -> Self {
25-
Opcode::Dat
26+
Self::Dat
2627
}
2728
}
2829

29-
enum_string!(pub PseudoOpcode {
30-
Org => "ORG",
31-
Equ => "EQU",
32-
End => "END",
33-
});
34-
3530
enum_string!(pub Modifier {
3631
A => "A",
3732
B => "B",
@@ -44,7 +39,7 @@ enum_string!(pub Modifier {
4439

4540
impl Default for Modifier {
4641
fn default() -> Self {
47-
Modifier::F
42+
Self::F
4843
}
4944
}
5045

@@ -106,10 +101,11 @@ impl Default for Value {
106101

107102
impl fmt::Display for Value {
108103
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
109-
match self {
110-
Self::Label(value) => write!(f, "{}", value),
111-
Self::Literal(value) => write!(f, "{}", value),
112-
}
104+
let value_string = match self {
105+
Self::Label(value) => value.to_string(),
106+
Self::Literal(value) => value.to_string(),
107+
};
108+
f.pad(&value_string)
113109
}
114110
}
115111

src/parser.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ impl IntoError for &str {}
3636
impl<T: IntoError> From<T> for Error {
3737
fn from(displayable_error: T) -> Self {
3838
Error {
39-
details: format!("{}", displayable_error),
39+
details: displayable_error.to_string(),
4040
}
4141
}
4242
}
@@ -78,8 +78,14 @@ pub fn parse(file_contents: &str) -> Result<ParsedProgram, Error> {
7878
}
7979
}
8080
grammar::Rule::Instruction => {
81-
program.set(i, parse_instruction(pair.into_inner()));
82-
i += 1;
81+
let instruction = parse_instruction(pair.into_inner());
82+
83+
if instruction.opcode == Opcode::Org {
84+
program.set_origin(instruction.field_a);
85+
} else {
86+
program.set(i, instruction);
87+
i += 1;
88+
}
8389
}
8490
_ => (),
8591
}

src/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ macro_rules! enum_string {
2121
impl ::std::fmt::Display for $name {
2222
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
2323
match *self {
24-
$(Self::$variant => write!(f, "{}", $value),)*
24+
$(Self::$variant => f.pad($value),)*
2525
}
2626
}
2727
}

tests/data/dwarf_loadfile.red

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
;date April 29, 1993
66
;strategy Bombs every fourth instruction.
77
;assert CORESIZE % 4 == 0
8-
ORG $1
9-
DAT.F #0, #0
8+
ORG 1
9+
DAT.F #0, #0
1010
ADD.AB #4, $-1
1111
MOV.AB #0, @-2
12-
JMP.A $-2, #0
12+
JMP.A $-2, #0
1313
END

tests/data/test.red

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ mov 1, 0
66
jmp loop
77
jmp begin
88

9+
org begin
10+
911
begin: add # 1, @ 2
1012
sub 3, 4
1113
mul 5, 6

tests/data/test_loadfile.red

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
1-
MOV.I $0, $1
2-
DAT.F $1, $2
3-
MOV.I $1, $0
4-
JMP.B $16, #0
5-
JMP.B $1, #0
1+
ORG 5
2+
MOV.I $0, $1
3+
DAT.F $1, $2
4+
MOV.I $1, $0
5+
JMP.B $16, #0
6+
JMP.B $1, #0
67
ADD.AB #1, @2
7-
SUB.F $3, $4
8-
MUL.F $5, $6
9-
DIV.F $7, $8
10-
MOD.F $9, $10
11-
JMZ.B $0, #0
12-
JMN.B $0, #0
13-
DJN.B $0, #0
14-
CMP.B $0, #0
15-
SEQ.B $0, #0
16-
SNE.B $0, #0
17-
SLT.B $0, #0
18-
SPL.B $0, #0
19-
NOP.B $0, #0
20-
MOV.A $1, $2
21-
MOV.B $1, $2
8+
SUB.F $3, $4
9+
MUL.F $5, $6
10+
DIV.F $7, $8
11+
MOD.F $9, $10
12+
JMZ.B $0, #0
13+
JMN.B $0, #0
14+
DJN.B $0, #0
15+
CMP.B $0, #0
16+
SEQ.B $0, #0
17+
SNE.B $0, #0
18+
SLT.B $0, #0
19+
SPL.B $0, #0
20+
NOP.B $0, #0
21+
MOV.A $1, $2
22+
MOV.B $1, $2
2223
MOV.AB $1, $2
2324
MOV.BA $1, $2
24-
MOV.F $1, $2
25-
MOV.X $1, $2
26-
MOV.I $1, $2
27-
JMP.B $-7, #0
25+
MOV.F $1, $2
26+
MOV.X $1, $2
27+
MOV.I $1, $2
28+
JMP.B $-7, #0

0 commit comments

Comments
 (0)