@@ -34,6 +34,46 @@ enum_string!(pub PseudoOpcode, {
34
34
End => "END" ,
35
35
} ) ;
36
36
37
+ enum_string ! ( pub Modifier , {
38
+ A => "A" ,
39
+ B => "B" ,
40
+ AB => "AB" ,
41
+ BA => "BA" ,
42
+ F => "F" ,
43
+ X => "X" ,
44
+ I => "I" ,
45
+ } ) ;
46
+
47
+ impl Default for Modifier {
48
+ fn default ( ) -> Modifier {
49
+ Modifier :: F
50
+ }
51
+ }
52
+
53
+ impl Modifier {
54
+ pub fn from_context ( opcode : Opcode , a_mode : AddressMode , b_mode : AddressMode ) -> Modifier {
55
+ use Opcode :: * ;
56
+
57
+ match opcode {
58
+ Dat => Modifier :: F ,
59
+ Jmp | Jmz | Jmn | Djn | Spl | Nop => Modifier :: B ,
60
+ opcode => {
61
+ if a_mode == AddressMode :: Immediate {
62
+ Modifier :: AB
63
+ } else if b_mode == AddressMode :: Immediate {
64
+ Modifier :: B
65
+ } else {
66
+ match opcode {
67
+ Mov | Cmp | Seq | Sne => Modifier :: I ,
68
+ Slt => Modifier :: B ,
69
+ Add | Sub | Mul | Div | Mod => Modifier :: F ,
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+
37
77
enum_string ! ( pub AddressMode , {
38
78
Immediate => "#" ,
39
79
Direct => "$" ,
@@ -82,14 +122,17 @@ impl ToString for Field {
82
122
#[ derive( Copy , Clone , Default , Debug , PartialEq ) ]
83
123
pub struct Instruction {
84
124
pub opcode : Opcode ,
125
+ pub modifier : Modifier ,
85
126
pub field_a : Field ,
86
127
pub field_b : Field ,
87
128
}
88
129
89
130
impl Instruction {
90
131
pub fn new ( opcode : Opcode , field_a : Field , field_b : Field ) -> Instruction {
132
+ let modifier = Modifier :: from_context ( opcode, field_a. address_mode , field_b. address_mode ) ;
91
133
Instruction {
92
134
opcode,
135
+ modifier,
93
136
field_a,
94
137
field_b,
95
138
}
@@ -177,6 +220,7 @@ mod tests {
177
220
fn default_instruction ( ) {
178
221
let expected_instruction = Instruction {
179
222
opcode : Opcode :: Dat ,
223
+ modifier : Modifier :: F ,
180
224
field_a : Field {
181
225
address_mode : AddressMode :: Direct ,
182
226
value : 0 ,
0 commit comments