sbpf_common/
inst_param.rs

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        // Int + Int
136        let result = Number::Int(10) + Number::Int(20);
137        assert_eq!(result, Number::Int(30));
138
139        // Addr + Addr
140        let result = Number::Addr(10) + Number::Addr(20);
141        assert_eq!(result, Number::Addr(30));
142
143        // Int + Addr
144        let result = Number::Int(10) + Number::Addr(20);
145        assert_eq!(result, Number::Addr(30));
146
147        // Addr + Int
148        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        // Int - Int
155        let result = Number::Int(30) - Number::Int(10);
156        assert_eq!(result, Number::Int(20));
157
158        // Addr - Addr
159        let result = Number::Addr(30) - Number::Addr(10);
160        assert_eq!(result, Number::Addr(20));
161
162        // Int - Addr
163        let result = Number::Int(30) - Number::Addr(10);
164        assert_eq!(result, Number::Addr(20));
165
166        // Addr - Int
167        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        // Int * Int
174        let result = Number::Int(5) * Number::Int(4);
175        assert_eq!(result, Number::Int(20));
176
177        // Addr * Addr
178        let result = Number::Addr(5) * Number::Addr(4);
179        assert_eq!(result, Number::Addr(20));
180
181        // Int * Addr
182        let result = Number::Int(5) * Number::Addr(4);
183        assert_eq!(result, Number::Addr(20));
184
185        // Addr * Int
186        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        // Int / Int
193        let result = Number::Int(20) / Number::Int(4);
194        assert_eq!(result, Number::Int(5));
195
196        // Addr / Addr
197        let result = Number::Addr(20) / Number::Addr(4);
198        assert_eq!(result, Number::Addr(5));
199
200        // Int / Addr
201        let result = Number::Int(20) / Number::Addr(4);
202        assert_eq!(result, Number::Addr(5));
203
204        // Addr / Int
205        let result = Number::Addr(20) / Number::Int(4);
206        assert_eq!(result, Number::Addr(5));
207    }
208}