uni_core/primitives/
max.rs

1use crate::interpreter::Interpreter;
2use crate::value::{RuntimeError, Value};
3
4pub fn max_builtin(interp: &mut Interpreter) -> Result<(), RuntimeError> {
5    let b = interp.pop_number()?;
6    let a = interp.pop_number()?;
7
8    interp.push(Value::Number(a.max(b)));
9    Ok(())
10}
11
12#[cfg(test)]
13mod tests {
14    use super::*;
15    use crate::value::Value;
16
17    fn setup_interpreter() -> Interpreter {
18        Interpreter::new()
19    }
20
21    #[test]
22    fn test_max_first_larger() {
23        let mut interp = setup_interpreter();
24        interp.push(Value::Number(7.0));
25        interp.push(Value::Number(3.0));
26
27        max_builtin(&mut interp).unwrap();
28
29        let result = interp.pop().unwrap();
30        assert!(matches!(result, Value::Number(n) if n == 7.0));
31    }
32
33    #[test]
34    fn test_max_second_larger() {
35        let mut interp = setup_interpreter();
36        interp.push(Value::Number(2.0));
37        interp.push(Value::Number(8.0));
38
39        max_builtin(&mut interp).unwrap();
40
41        let result = interp.pop().unwrap();
42        assert!(matches!(result, Value::Number(n) if n == 8.0));
43    }
44
45    #[test]
46    fn test_max_equal() {
47        let mut interp = setup_interpreter();
48        interp.push(Value::Number(5.0));
49        interp.push(Value::Number(5.0));
50
51        max_builtin(&mut interp).unwrap();
52
53        let result = interp.pop().unwrap();
54        assert!(matches!(result, Value::Number(n) if n == 5.0));
55    }
56
57    #[test]
58    fn test_max_negative_numbers() {
59        let mut interp = setup_interpreter();
60        interp.push(Value::Number(-10.0));
61        interp.push(Value::Number(-5.0));
62
63        max_builtin(&mut interp).unwrap();
64
65        let result = interp.pop().unwrap();
66        assert!(matches!(result, Value::Number(n) if n == -5.0));
67    }
68
69    #[test]
70    fn test_max_mixed_signs() {
71        let mut interp = setup_interpreter();
72        interp.push(Value::Number(-3.0));
73        interp.push(Value::Number(5.0));
74
75        max_builtin(&mut interp).unwrap();
76
77        let result = interp.pop().unwrap();
78        assert!(matches!(result, Value::Number(n) if n == 5.0));
79    }
80
81    #[test]
82    fn test_max_decimals() {
83        let mut interp = setup_interpreter();
84        interp.push(Value::Number(3.14));
85        interp.push(Value::Number(2.71));
86
87        max_builtin(&mut interp).unwrap();
88
89        let result = interp.pop().unwrap();
90        assert!(matches!(result, Value::Number(n) if (n - 3.14).abs() < f64::EPSILON));
91    }
92
93    #[test]
94    fn test_max_stack_underflow() {
95        let mut interp = setup_interpreter();
96
97        let result = max_builtin(&mut interp);
98        assert!(matches!(result, Err(RuntimeError::StackUnderflow)));
99
100        interp.push(Value::Number(1.0));
101        let result = max_builtin(&mut interp);
102        assert!(matches!(result, Err(RuntimeError::StackUnderflow)));
103    }
104
105    #[test]
106    fn test_max_type_error() {
107        let mut interp = setup_interpreter();
108        interp.push(Value::Number(5.0));
109        interp.push(Value::String("hello".into()));
110
111        let result = max_builtin(&mut interp);
112        assert!(matches!(result, Err(RuntimeError::TypeError(_))));
113    }
114}