uni_core/primitives/
print.rs1use crate::compat::format;
4use crate::interpreter::Interpreter;
5use crate::value::{RuntimeError, Value};
6
7pub fn print_builtin(interp: &mut Interpreter) -> Result<(), RuntimeError> {
11 let value = interp.pop()?;
12
13 let output = match &value {
15 Value::String(s) => {
16 format!("{}", s)
18 }
19 _ => {
20 format!("{}", value)
22 }
23 };
24
25 let _ = interp.write_str(&output);
28
29 Ok(())
30}
31
32#[cfg(test)]
33mod tests {
34 use super::*;
35 use crate::value::Value;
36
37 fn setup_interpreter() -> Interpreter {
38 Interpreter::new()
39 }
40
41 #[test]
42 fn test_print_builtin_number() {
43 let mut interp = setup_interpreter();
44
45 interp.push(Value::Number(42.0));
47
48 let result = print_builtin(&mut interp);
51 assert!(result.is_ok());
52
53 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
55 }
56
57 #[test]
58 fn test_print_builtin_string() {
59 let mut interp = setup_interpreter();
60
61 interp.push(Value::String("hello world".into()));
62 let result = print_builtin(&mut interp);
63 assert!(result.is_ok());
64
65 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
67 }
68
69 #[test]
70 fn test_print_builtin_boolean() {
71 let mut interp = setup_interpreter();
72
73 interp.push(Value::Boolean(true));
74 let result = print_builtin(&mut interp);
75 assert!(result.is_ok());
76
77 interp.push(Value::Boolean(false));
78 let result = print_builtin(&mut interp);
79 assert!(result.is_ok());
80
81 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
83 }
84
85 #[test]
86 fn test_print_builtin_null() {
87 let mut interp = setup_interpreter();
88
89 interp.push(Value::Null);
90 let result = print_builtin(&mut interp);
91 assert!(result.is_ok());
92
93 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
95 }
96
97 #[test]
98 fn test_print_builtin_atom() {
99 let mut interp = setup_interpreter();
100
101 let atom = interp.intern_atom("test");
102 interp.push(Value::Atom(atom));
103 let result = print_builtin(&mut interp);
104 assert!(result.is_ok());
105
106 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
108 }
109
110 #[test]
111 fn test_print_builtin_quoted_atom() {
112 let mut interp = setup_interpreter();
113
114 let quoted_atom = interp.intern_atom("quoted");
115 interp.push(Value::QuotedAtom(quoted_atom));
116 let result = print_builtin(&mut interp);
117 assert!(result.is_ok());
118
119 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
121 }
122
123 #[test]
124 fn test_print_builtin_empty_list() {
125 let mut interp = setup_interpreter();
126
127 interp.push(Value::Nil);
128 let result = print_builtin(&mut interp);
129 assert!(result.is_ok());
130
131 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
133 }
134
135 #[test]
136 fn test_print_builtin_list() {
137 let mut interp = setup_interpreter();
138
139 let list = interp.make_list(vec![
141 Value::Number(1.0),
142 Value::Number(2.0),
143 Value::Number(3.0),
144 ]);
145 interp.push(list);
146 let result = print_builtin(&mut interp);
147 assert!(result.is_ok());
148
149 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
151 }
152
153 #[test]
154 fn test_print_builtin_mixed_list() {
155 let mut interp = setup_interpreter();
156
157 let mixed_list = interp.make_list(vec![
159 Value::String("hello".into()),
160 Value::Number(42.0),
161 Value::Boolean(true),
162 ]);
163 interp.push(mixed_list);
164 let result = print_builtin(&mut interp);
165 assert!(result.is_ok());
166
167 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
169 }
170
171 #[test]
172 fn test_print_builtin_stack_underflow() {
173 let mut interp = setup_interpreter();
174
175 let result = print_builtin(&mut interp);
177 assert!(matches!(result, Err(RuntimeError::StackUnderflow)));
178 }
179
180 #[test]
181 fn test_print_builtin_multiple_values() {
182 let mut interp = setup_interpreter();
183
184 interp.push(Value::Number(1.0));
186 interp.push(Value::Number(2.0));
187 interp.push(Value::Number(3.0));
188
189 let result1 = print_builtin(&mut interp);
191 assert!(result1.is_ok());
192
193 let result2 = print_builtin(&mut interp);
194 assert!(result2.is_ok());
195
196 let result3 = print_builtin(&mut interp);
197 assert!(result3.is_ok());
198
199 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
201 }
202}