Skip to content

Commit a2961c2

Browse files
Clean up parsing code and fix several warnings
1 parent 789dae1 commit a2961c2

File tree

5 files changed

+42
-33
lines changed

5 files changed

+42
-33
lines changed

src/data/redcode.pest

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Instruction = _{ Operation ~ Field ~ ("," ~ Field)? }
1010

1111
Operation = ${ Opcode }
1212

13-
Field = ${ Mode? ~ Expr }
13+
Field = ${ AddressMode? ~ Expr }
1414

1515
Opcode = {
1616
^"DAT" | ^"MOV" | ^"ADD" | ^"SUB" | ^"MUL" | ^"DIV" | ^"MOD" |
@@ -20,7 +20,7 @@ Opcode = {
2020

2121
Modifier = { ^"A" | ^"B" | ^"AB" | ^"BA" | ^"F" | ^"X" | ^"I" }
2222

23-
Mode = { "#" | "$" | "*" | "@" | "{" | "<" | "}" | ">" }
23+
AddressMode = { "#" | "$" | "*" | "@" | "{" | "<" | "}" | ">" }
2424

2525
Expr = !{ Number }
2626

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#[macro_use]
22
extern crate pest_derive;
3-
#[macro_use]
43
extern crate pest;
54

65
#[macro_use]

src/load_file.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,8 @@ impl PartialEq for Core {
160160
}
161161
}
162162

163+
#[cfg(test)]
163164
mod tests {
164-
// seems to be a case of https://github.com/rust-lang/rust/issues/45268
165-
#[allow(unused_imports)]
166165
use super::*;
167166

168167
#[test]

src/parser.rs

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -53,26 +53,34 @@ pub fn parse(file_contents: &str) -> Result<Core, Error> {
5353
.next()
5454
.ok_or_else(Error::no_input)?;
5555

56-
for (i, instruction_inner) in parse_result
56+
for (i, line_pairs) in parse_result
5757
.into_inner()
58-
.filter_map(|instruction_inner| {
59-
let inner_pair = instruction_inner.into_inner();
60-
inner_pair.peek().map(|_| inner_pair)
61-
})
58+
.map(Pair::into_inner)
59+
.filter(|line_pair| line_pair.peek().is_some())
6260
.enumerate()
6361
{
64-
core.set(i, parse_instruction(instruction_inner));
62+
core.set(i, parse_instruction(line_pairs));
6563
}
6664

6765
Ok(core)
6866
}
6967

7068
fn parse_instruction(mut instruction_pairs: Pairs<Rule>) -> Instruction {
71-
let opcode = parse_opcode(&instruction_pairs.next().unwrap());
69+
let opcode = parse_opcode(
70+
&instruction_pairs
71+
.next()
72+
.expect("Opcode must be first pair in Instruction"),
73+
);
74+
75+
let field_a = parse_field(
76+
instruction_pairs
77+
.next()
78+
.expect("Field must appear after Opcode"),
79+
);
7280

73-
let field_a = parse_field(instruction_pairs.next().unwrap());
7481
let field_b = instruction_pairs
7582
.next()
83+
.filter(|pair| pair.as_rule() == Rule::Field)
7684
.map_or_else(Field::default, parse_field);
7785

7886
Instruction {
@@ -87,34 +95,38 @@ fn parse_opcode(opcode_pair: &Pair<Rule>) -> Opcode {
8795
}
8896

8997
fn parse_field(field_pair: Pair<Rule>) -> Field {
90-
let mut inner_pairs = field_pair.into_inner();
91-
let mut next_pair = inner_pairs
92-
.next()
93-
.expect("Attempt to parse Field with no inner pairs");
98+
dbg!(&field_pair);
9499

95-
let address_mode = if next_pair.as_rule() == Rule::Mode {
96-
let mode = AddressMode::from_str(next_pair.as_str()).unwrap();
97-
next_pair = inner_pairs
100+
let field_pairs = field_pair.into_inner();
101+
102+
let address_mode = field_pairs
103+
.peek()
104+
.filter(|pair| pair.as_rule() == Rule::AddressMode)
105+
.map_or(AddressMode::default(), |pair| {
106+
AddressMode::from_str(pair.as_str()).expect("Invalid AddressMode")
107+
});
108+
109+
let value = parse_value(
110+
field_pairs
111+
.skip_while(|pair| pair.as_rule() != Rule::Expr)
98112
.next()
99-
.expect("Attempt to parse Field with Mode pair but nothing else");
100-
mode
101-
} else {
102-
AddressMode::default()
103-
};
113+
.expect("No Expr in Field"),
114+
);
104115

105116
Field {
106117
address_mode,
107-
value: parse_value(&next_pair),
118+
value,
108119
}
109120
}
110121

111-
fn parse_value(value_pair: &Pair<Rule>) -> i32 {
122+
fn parse_value(value_pair: Pair<Rule>) -> i32 {
112123
i32::from_str_radix(value_pair.as_str(), 10).unwrap()
113124
}
114125

126+
#[cfg(test)]
115127
mod tests {
116-
// seems to be a case of https://github.com/rust-lang/rust/issues/45268
117-
#[allow(unused_imports)]
128+
use pest::{consumes_to, parses_to};
129+
118130
use super::*;
119131

120132
#[test]
@@ -149,7 +161,7 @@ mod tests {
149161
rule: Rule::Field,
150162
tokens: [
151163
Field(0, 4, [
152-
Mode(0, 1),
164+
AddressMode(0, 1),
153165
Expr(1, 4, [
154166
Number(1, 4)
155167
]),
@@ -170,7 +182,7 @@ mod tests {
170182
Opcode(0, 3)
171183
]),
172184
Field(4, 6, [
173-
Mode(4, 5),
185+
AddressMode(4, 5),
174186
Expr(5, 6, [
175187
Number(5, 6)
176188
])

src/util.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,8 @@ macro_rules! enum_string {
4444
};
4545
}
4646

47+
#[cfg(test)]
4748
mod tests {
48-
// seems to be a case of https://github.com/rust-lang/rust/issues/45268
49-
#[allow(unused_imports)]
5049
use std::{str::FromStr, string::ToString};
5150

5251
mod submod {

0 commit comments

Comments
 (0)