uni_core/primitives/
bit_or.rs1use crate::interpreter::Interpreter;
2use crate::value::{RuntimeError, Value};
3
4pub fn bit_or_builtin(interp: &mut Interpreter) -> Result<(), RuntimeError> {
5 let b = interp.pop_number()?;
6 let a = interp.pop_number()?;
7
8 let a_int = a as i64;
10 let b_int = b as i64;
11
12 let result = a_int | b_int;
13 interp.push(Value::Number(result as f64));
14 Ok(())
15}
16
17#[cfg(test)]
18mod tests {
19 use super::*;
20 use crate::value::Value;
21
22 fn setup_interpreter() -> Interpreter {
23 Interpreter::new()
24 }
25
26 #[test]
27 fn test_bit_or_basic() {
28 let mut interp = setup_interpreter();
29 interp.push(Value::Number(5.0)); interp.push(Value::Number(3.0)); bit_or_builtin(&mut interp).unwrap();
33
34 let result = interp.pop().unwrap();
35 assert!(matches!(result, Value::Number(n) if n == 7.0)); }
37
38 #[test]
39 fn test_bit_or_no_overlap() {
40 let mut interp = setup_interpreter();
41 interp.push(Value::Number(8.0)); interp.push(Value::Number(4.0)); bit_or_builtin(&mut interp).unwrap();
45
46 let result = interp.pop().unwrap();
47 assert!(matches!(result, Value::Number(n) if n == 12.0)); }
49
50 #[test]
51 fn test_bit_or_with_zero() {
52 let mut interp = setup_interpreter();
53 interp.push(Value::Number(42.0));
54 interp.push(Value::Number(0.0));
55
56 bit_or_builtin(&mut interp).unwrap();
57
58 let result = interp.pop().unwrap();
59 assert!(matches!(result, Value::Number(n) if n == 42.0));
60 }
61
62 #[test]
63 fn test_bit_or_same_values() {
64 let mut interp = setup_interpreter();
65 interp.push(Value::Number(15.0));
66 interp.push(Value::Number(15.0));
67
68 bit_or_builtin(&mut interp).unwrap();
69
70 let result = interp.pop().unwrap();
71 assert!(matches!(result, Value::Number(n) if n == 15.0));
72 }
73
74 #[test]
75 fn test_bit_or_powers_of_two() {
76 let mut interp = setup_interpreter();
77
78 let test_cases = [
79 (1.0, 2.0, 3.0), (4.0, 8.0, 12.0), (1.0, 4.0, 5.0), (2.0, 8.0, 10.0), ];
84
85 for (a, b, expected) in test_cases {
86 interp.push(Value::Number(a));
87 interp.push(Value::Number(b));
88 bit_or_builtin(&mut interp).unwrap();
89 let result = interp.pop().unwrap();
90 assert!(
91 matches!(result, Value::Number(n) if n == expected),
92 "{} | {} should be {}, got {:?}",
93 a,
94 b,
95 expected,
96 result
97 );
98 }
99 }
100
101 #[test]
102 fn test_bit_or_alternating_patterns() {
103 let mut interp = setup_interpreter();
104 interp.push(Value::Number(170.0)); interp.push(Value::Number(85.0)); bit_or_builtin(&mut interp).unwrap();
108
109 let result = interp.pop().unwrap();
110 assert!(matches!(result, Value::Number(n) if n == 255.0)); }
112
113 #[test]
114 fn test_bit_or_large_numbers() {
115 let mut interp = setup_interpreter();
116 interp.push(Value::Number(512.0)); interp.push(Value::Number(255.0)); bit_or_builtin(&mut interp).unwrap();
120
121 let result = interp.pop().unwrap();
122 assert!(matches!(result, Value::Number(n) if n == 767.0)); }
124
125 #[test]
126 fn test_bit_or_negative_numbers() {
127 let mut interp = setup_interpreter();
128
129 interp.push(Value::Number(-1.0)); interp.push(Value::Number(42.0));
132
133 bit_or_builtin(&mut interp).unwrap();
134
135 let result = interp.pop().unwrap();
136 assert!(matches!(result, Value::Number(n) if n == -1.0)); }
138
139 #[test]
140 fn test_bit_or_fractional_truncation() {
141 let mut interp = setup_interpreter();
142
143 interp.push(Value::Number(5.7));
145 interp.push(Value::Number(2.9));
146
147 bit_or_builtin(&mut interp).unwrap();
148
149 let result = interp.pop().unwrap();
150 assert!(matches!(result, Value::Number(n) if n == 7.0)); }
152
153 #[test]
154 fn test_bit_or_commutative() {
155 let mut interp = setup_interpreter();
156
157 let a = 13.0;
158 let b = 7.0;
159
160 interp.push(Value::Number(a));
162 interp.push(Value::Number(b));
163 bit_or_builtin(&mut interp).unwrap();
164 let result1 = interp.pop().unwrap();
165
166 interp.push(Value::Number(b));
168 interp.push(Value::Number(a));
169 bit_or_builtin(&mut interp).unwrap();
170 let result2 = interp.pop().unwrap();
171
172 assert!(matches!((result1, result2), (Value::Number(n1), Value::Number(n2)) if n1 == n2));
173 }
174
175 #[test]
176 fn test_bit_or_with_all_bits_set() {
177 let mut interp = setup_interpreter();
178
179 interp.push(Value::Number(123.0)); interp.push(Value::Number(255.0)); bit_or_builtin(&mut interp).unwrap();
184
185 let result = interp.pop().unwrap();
186 assert!(matches!(result, Value::Number(n) if n == 255.0)); }
188
189 #[test]
190 fn test_bit_or_identity() {
191 let mut interp = setup_interpreter();
192
193 let values = [1.0, 7.0, 15.0, 31.0, 63.0];
195
196 for value in values {
197 interp.push(Value::Number(value));
198 interp.push(Value::Number(0.0));
199 bit_or_builtin(&mut interp).unwrap();
200 let result = interp.pop().unwrap();
201 assert!(
202 matches!(result, Value::Number(n) if n == value),
203 "{} | 0 should be {}, got {:?}",
204 value,
205 value,
206 result
207 );
208 }
209 }
210
211 #[test]
212 fn test_bit_or_stack_underflow() {
213 let mut interp = setup_interpreter();
214
215 let result = bit_or_builtin(&mut interp);
216 assert!(matches!(result, Err(RuntimeError::StackUnderflow)));
217
218 interp.push(Value::Number(5.0));
219 let result = bit_or_builtin(&mut interp);
220 assert!(matches!(result, Err(RuntimeError::StackUnderflow)));
221 }
222
223 #[test]
224 fn test_bit_or_type_error() {
225 let mut interp = setup_interpreter();
226 interp.push(Value::String("hello".into()));
227 interp.push(Value::Number(5.0));
228
229 let result = bit_or_builtin(&mut interp);
230 assert!(matches!(result, Err(RuntimeError::TypeError(_))));
231 }
232}