uni_core/primitives/
drop.rs

1// RUST CONCEPT: Modular primitive organization
2// Each primitive gets its own file with implementation and tests
3use crate::interpreter::Interpreter;
4use crate::value::RuntimeError;
5
6// RUST CONCEPT: Stack manipulation - removing top element
7// Stack-based drop: ( value -- )
8pub fn drop_builtin(interp: &mut Interpreter) -> Result<(), RuntimeError> {
9    // RUST CONCEPT: We don't need to do anything with the popped value
10    // Just pop it and discard it
11    interp.pop()?;
12    Ok(())
13}
14
15#[cfg(test)]
16mod tests {
17    use super::*;
18    use crate::value::Value;
19
20    fn setup_interpreter() -> Interpreter {
21        Interpreter::new()
22    }
23
24    #[test]
25    fn test_drop_builtin() {
26        let mut interp = setup_interpreter();
27
28        // Test dropping a number
29        interp.push(Value::Number(42.0));
30        interp.push(Value::Number(17.0));
31        drop_builtin(&mut interp).unwrap();
32
33        // Should have only 42.0 left
34        let result = interp.pop().unwrap();
35        assert!(matches!(result, Value::Number(n) if n == 42.0));
36
37        // Stack should now be empty
38        let empty_result = interp.pop();
39        assert!(matches!(empty_result, Err(RuntimeError::StackUnderflow)));
40    }
41
42    #[test]
43    fn test_drop_builtin_various_types() {
44        let mut interp = setup_interpreter();
45
46        // Test dropping different value types
47        interp.push(Value::Number(1.0));
48        interp.push(Value::String("drop me".into()));
49        drop_builtin(&mut interp).unwrap();
50        let result = interp.pop().unwrap();
51        assert!(matches!(result, Value::Number(n) if n == 1.0));
52
53        interp.push(Value::Boolean(true));
54        interp.push(Value::Null);
55        drop_builtin(&mut interp).unwrap();
56        let result = interp.pop().unwrap();
57        assert!(matches!(result, Value::Boolean(true)));
58
59        let keep_atom = interp.intern_atom("keep");
60        interp.push(Value::Atom(keep_atom));
61        interp.push(Value::Nil);
62        drop_builtin(&mut interp).unwrap();
63        let result = interp.pop().unwrap();
64        if let Value::Atom(atom) = result {
65            assert_eq!(&*atom, "keep");
66        } else {
67            panic!("Expected atom");
68        }
69    }
70
71    #[test]
72    fn test_drop_builtin_stack_underflow() {
73        let mut interp = setup_interpreter();
74
75        // Test with empty stack
76        let result = drop_builtin(&mut interp);
77        assert!(matches!(result, Err(RuntimeError::StackUnderflow)));
78    }
79}