1use {
2 core::fmt,
3 serde::{Deserialize, Serialize},
4};
5
6#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7pub struct Register {
8 pub n: u8,
9}
10
11impl fmt::Display for Register {
12 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
13 write!(f, "r{}", self.n)
14 }
15}
16
17#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
18pub enum Number {
19 Int(i64),
20 Addr(i64),
21}
22
23impl Number {
24 pub fn to_i16(&self) -> i16 {
25 match self {
26 Number::Int(v) => *v as i16,
27 Number::Addr(a) => *a as i16,
28 }
29 }
30
31 pub fn to_i64(&self) -> i64 {
32 match self {
33 Number::Int(v) => *v,
34 Number::Addr(a) => *a,
35 }
36 }
37}
38
39impl fmt::Display for Number {
40 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
41 match self {
42 Number::Int(i) => write!(f, "{}", i),
43 Number::Addr(a) => write!(f, "{}", a),
44 }
45 }
46}
47
48impl std::ops::Add for Number {
49 type Output = Number;
50 fn add(self, other: Self) -> Number {
51 match (self, other) {
52 (Number::Int(a), Number::Int(b)) => Number::Int(a + b),
53 (Number::Addr(a), Number::Addr(b)) => Number::Addr(a + b),
54 (Number::Int(a), Number::Addr(b)) => Number::Addr(a + b),
55 (Number::Addr(a), Number::Int(b)) => Number::Addr(a + b),
56 }
57 }
58}
59
60impl std::ops::Sub for Number {
61 type Output = Number;
62 fn sub(self, other: Self) -> Number {
63 match (self, other) {
64 (Number::Int(a), Number::Int(b)) => Number::Int(a - b),
65 (Number::Addr(a), Number::Addr(b)) => Number::Addr(a - b),
66 (Number::Int(a), Number::Addr(b)) => Number::Addr(a - b),
67 (Number::Addr(a), Number::Int(b)) => Number::Addr(a - b),
68 }
69 }
70}
71
72impl std::ops::Mul for Number {
73 type Output = Number;
74 fn mul(self, other: Self) -> Number {
75 match (self, other) {
76 (Number::Int(a), Number::Int(b)) => Number::Int(a * b),
77 (Number::Addr(a), Number::Addr(b)) => Number::Addr(a * b),
78 (Number::Int(a), Number::Addr(b)) => Number::Addr(a * b),
79 (Number::Addr(a), Number::Int(b)) => Number::Addr(a * b),
80 }
81 }
82}
83
84impl std::ops::Div for Number {
85 type Output = Number;
86 fn div(self, other: Self) -> Number {
87 match (self, other) {
88 (Number::Int(a), Number::Int(b)) => Number::Int(a / b),
89 (Number::Addr(a), Number::Addr(b)) => Number::Addr(a / b),
90 (Number::Int(a), Number::Addr(b)) => Number::Addr(a / b),
91 (Number::Addr(a), Number::Int(b)) => Number::Addr(a / b),
92 }
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 #[test]
101 fn test_register_display() {
102 let reg = Register { n: 5 };
103 assert_eq!(reg.to_string(), "r5");
104
105 let reg0 = Register { n: 0 };
106 assert_eq!(reg0.to_string(), "r0");
107
108 let reg10 = Register { n: 10 };
109 assert_eq!(reg10.to_string(), "r10");
110 }
111
112 #[test]
113 fn test_number_to_i16() {
114 assert_eq!(Number::Int(42).to_i16(), 42i16);
115 assert_eq!(Number::Addr(100).to_i16(), 100i16);
116 assert_eq!(Number::Int(-5).to_i16(), -5i16);
117 }
118
119 #[test]
120 fn test_number_to_i64() {
121 assert_eq!(Number::Int(42).to_i64(), 42i64);
122 assert_eq!(Number::Addr(100).to_i64(), 100i64);
123 assert_eq!(Number::Int(-5).to_i64(), -5i64);
124 }
125
126 #[test]
127 fn test_number_display() {
128 assert_eq!(Number::Int(42).to_string(), "42");
129 assert_eq!(Number::Addr(100).to_string(), "100");
130 assert_eq!(Number::Int(-5).to_string(), "-5");
131 }
132
133 #[test]
134 fn test_number_add() {
135 let result = Number::Int(10) + Number::Int(20);
137 assert_eq!(result, Number::Int(30));
138
139 let result = Number::Addr(10) + Number::Addr(20);
141 assert_eq!(result, Number::Addr(30));
142
143 let result = Number::Int(10) + Number::Addr(20);
145 assert_eq!(result, Number::Addr(30));
146
147 let result = Number::Addr(10) + Number::Int(20);
149 assert_eq!(result, Number::Addr(30));
150 }
151
152 #[test]
153 fn test_number_sub() {
154 let result = Number::Int(30) - Number::Int(10);
156 assert_eq!(result, Number::Int(20));
157
158 let result = Number::Addr(30) - Number::Addr(10);
160 assert_eq!(result, Number::Addr(20));
161
162 let result = Number::Int(30) - Number::Addr(10);
164 assert_eq!(result, Number::Addr(20));
165
166 let result = Number::Addr(30) - Number::Int(10);
168 assert_eq!(result, Number::Addr(20));
169 }
170
171 #[test]
172 fn test_number_mul() {
173 let result = Number::Int(5) * Number::Int(4);
175 assert_eq!(result, Number::Int(20));
176
177 let result = Number::Addr(5) * Number::Addr(4);
179 assert_eq!(result, Number::Addr(20));
180
181 let result = Number::Int(5) * Number::Addr(4);
183 assert_eq!(result, Number::Addr(20));
184
185 let result = Number::Addr(5) * Number::Int(4);
187 assert_eq!(result, Number::Addr(20));
188 }
189
190 #[test]
191 fn test_number_div() {
192 let result = Number::Int(20) / Number::Int(4);
194 assert_eq!(result, Number::Int(5));
195
196 let result = Number::Addr(20) / Number::Addr(4);
198 assert_eq!(result, Number::Addr(5));
199
200 let result = Number::Int(20) / Number::Addr(4);
202 assert_eq!(result, Number::Addr(5));
203
204 let result = Number::Addr(20) / Number::Int(4);
206 assert_eq!(result, Number::Addr(5));
207 }
208}