uni_core/primitives/
stack.rs1use crate::compat::format;
4use crate::interpreter::Interpreter;
5use crate::value::RuntimeError;
6
7#[cfg(not(target_os = "none"))]
8use std::vec::Vec;
9#[cfg(target_os = "none")]
10use alloc::vec::Vec;
11
12pub fn stack_builtin(interp: &mut Interpreter) -> Result<(), RuntimeError> {
15 if interp.stack.is_empty() {
16 let _ = interp.writeln("Stack is empty");
17 } else {
18 let mut lines = Vec::new();
21
22 let msg = format!("Stack ({} items):", interp.stack.len());
23 lines.push(msg);
24
25 let limit = if cfg!(target_os = "none") { 5 } else { 10 };
28
29 for (i, value) in interp.stack.iter().rev().enumerate() {
30 if i >= limit {
31 let msg = format!(" ... and {} more", interp.stack.len() - limit);
32 lines.push(msg);
33 break;
34 }
35 let msg = format!(" {}: {}", i, value);
36 lines.push(msg);
37 }
38
39 for line in lines {
41 let _ = interp.writeln(&line);
42 }
43 }
44
45 Ok(())
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51 use crate::value::Value;
52
53 fn setup_interpreter() -> Interpreter {
54 Interpreter::new()
55 }
56
57 #[test]
58 fn test_stack_builtin_empty() {
59 let mut interp = setup_interpreter();
60
61 let result = stack_builtin(&mut interp);
63 assert!(result.is_ok());
64 }
65
66 #[test]
67 fn test_stack_builtin_with_values() {
68 let mut interp = setup_interpreter();
69
70 interp.push(Value::Number(1.0));
72 interp.push(Value::Number(2.0));
73 interp.push(Value::Number(3.0));
74
75 let result = stack_builtin(&mut interp);
77 assert!(result.is_ok());
78 }
79
80 #[test]
81 fn test_stack_builtin_no_stack_effect() {
82 let mut interp = setup_interpreter();
83
84 interp.push(Value::Number(1.0));
86 interp.push(Value::Number(2.0));
87 interp.push(Value::Number(3.0));
88
89 let stack_before = interp.stack.len();
90
91 let result = stack_builtin(&mut interp);
93 assert!(result.is_ok());
94
95 let stack_after = interp.stack.len();
96 assert_eq!(stack_before, stack_after);
97 }
98
99 #[test]
100 fn test_stack_builtin_many_items() {
101 let mut interp = setup_interpreter();
102
103 for i in 0..20 {
105 interp.push(Value::Number(i as f64));
106 }
107
108 let result = stack_builtin(&mut interp);
110 assert!(result.is_ok());
111
112 assert_eq!(interp.stack.len(), 20);
114 }
115}