@@ -53,26 +53,34 @@ pub fn parse(file_contents: &str) -> Result<Core, Error> {
53
53
. next ( )
54
54
. ok_or_else ( Error :: no_input) ?;
55
55
56
- for ( i, instruction_inner ) in parse_result
56
+ for ( i, line_pairs ) in parse_result
57
57
. 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 ( ) )
62
60
. enumerate ( )
63
61
{
64
- core. set ( i, parse_instruction ( instruction_inner ) ) ;
62
+ core. set ( i, parse_instruction ( line_pairs ) ) ;
65
63
}
66
64
67
65
Ok ( core)
68
66
}
69
67
70
68
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
+ ) ;
72
80
73
- let field_a = parse_field ( instruction_pairs. next ( ) . unwrap ( ) ) ;
74
81
let field_b = instruction_pairs
75
82
. next ( )
83
+ . filter ( |pair| pair. as_rule ( ) == Rule :: Field )
76
84
. map_or_else ( Field :: default, parse_field) ;
77
85
78
86
Instruction {
@@ -87,34 +95,38 @@ fn parse_opcode(opcode_pair: &Pair<Rule>) -> Opcode {
87
95
}
88
96
89
97
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) ;
94
99
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 )
98
112
. 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
+ ) ;
104
115
105
116
Field {
106
117
address_mode,
107
- value : parse_value ( & next_pair ) ,
118
+ value,
108
119
}
109
120
}
110
121
111
- fn parse_value ( value_pair : & Pair < Rule > ) -> i32 {
122
+ fn parse_value ( value_pair : Pair < Rule > ) -> i32 {
112
123
i32:: from_str_radix ( value_pair. as_str ( ) , 10 ) . unwrap ( )
113
124
}
114
125
126
+ #[ cfg( test) ]
115
127
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
+
118
130
use super :: * ;
119
131
120
132
#[ test]
@@ -149,7 +161,7 @@ mod tests {
149
161
rule: Rule :: Field ,
150
162
tokens: [
151
163
Field ( 0 , 4 , [
152
- Mode ( 0 , 1 ) ,
164
+ AddressMode ( 0 , 1 ) ,
153
165
Expr ( 1 , 4 , [
154
166
Number ( 1 , 4 )
155
167
] ) ,
@@ -170,7 +182,7 @@ mod tests {
170
182
Opcode ( 0 , 3 )
171
183
] ) ,
172
184
Field ( 4 , 6 , [
173
- Mode ( 4 , 5 ) ,
185
+ AddressMode ( 4 , 5 ) ,
174
186
Expr ( 5 , 6 , [
175
187
Number ( 5 , 6 )
176
188
] )
0 commit comments