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.writeln(&output);
27
28 Ok(())
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34 use crate::value::Value;
35
36 fn setup_interpreter() -> Interpreter {
37 Interpreter::new()
38 }
39
40 #[test]
41 fn test_print_builtin_number() {
42 let mut interp = setup_interpreter();
43
44 interp.push(Value::Number(42.0));
46
47 let result = print_builtin(&mut interp);
50 assert!(result.is_ok());
51
52 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
54 }
55
56 #[test]
57 fn test_print_builtin_string() {
58 let mut interp = setup_interpreter();
59
60 interp.push(Value::String("hello world".into()));
61 let result = print_builtin(&mut interp);
62 assert!(result.is_ok());
63
64 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
66 }
67
68 #[test]
69 fn test_print_builtin_boolean() {
70 let mut interp = setup_interpreter();
71
72 interp.push(Value::Boolean(true));
73 let result = print_builtin(&mut interp);
74 assert!(result.is_ok());
75
76 interp.push(Value::Boolean(false));
77 let result = print_builtin(&mut interp);
78 assert!(result.is_ok());
79
80 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
82 }
83
84 #[test]
85 fn test_print_builtin_null() {
86 let mut interp = setup_interpreter();
87
88 interp.push(Value::Null);
89 let result = print_builtin(&mut interp);
90 assert!(result.is_ok());
91
92 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
94 }
95
96 #[test]
97 fn test_print_builtin_atom() {
98 let mut interp = setup_interpreter();
99
100 let atom = interp.intern_atom("test");
101 interp.push(Value::Atom(atom));
102 let result = print_builtin(&mut interp);
103 assert!(result.is_ok());
104
105 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
107 }
108
109 #[test]
110 fn test_print_builtin_quoted_atom() {
111 let mut interp = setup_interpreter();
112
113 let quoted_atom = interp.intern_atom("quoted");
114 interp.push(Value::QuotedAtom(quoted_atom));
115 let result = print_builtin(&mut interp);
116 assert!(result.is_ok());
117
118 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
120 }
121
122 #[test]
123 fn test_print_builtin_empty_list() {
124 let mut interp = setup_interpreter();
125
126 interp.push(Value::Nil);
127 let result = print_builtin(&mut interp);
128 assert!(result.is_ok());
129
130 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
132 }
133
134 #[test]
135 fn test_print_builtin_list() {
136 let mut interp = setup_interpreter();
137
138 let list = interp.make_list(vec![
140 Value::Number(1.0),
141 Value::Number(2.0),
142 Value::Number(3.0),
143 ]);
144 interp.push(list);
145 let result = print_builtin(&mut interp);
146 assert!(result.is_ok());
147
148 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
150 }
151
152 #[test]
153 fn test_print_builtin_mixed_list() {
154 let mut interp = setup_interpreter();
155
156 let mixed_list = interp.make_list(vec![
158 Value::String("hello".into()),
159 Value::Number(42.0),
160 Value::Boolean(true),
161 ]);
162 interp.push(mixed_list);
163 let result = print_builtin(&mut interp);
164 assert!(result.is_ok());
165
166 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
168 }
169
170 #[test]
171 fn test_print_builtin_stack_underflow() {
172 let mut interp = setup_interpreter();
173
174 let result = print_builtin(&mut interp);
176 assert!(matches!(result, Err(RuntimeError::StackUnderflow)));
177 }
178
179 #[test]
180 fn test_print_builtin_multiple_values() {
181 let mut interp = setup_interpreter();
182
183 interp.push(Value::Number(1.0));
185 interp.push(Value::Number(2.0));
186 interp.push(Value::Number(3.0));
187
188 let result1 = print_builtin(&mut interp);
190 assert!(result1.is_ok());
191
192 let result2 = print_builtin(&mut interp);
193 assert!(result2.is_ok());
194
195 let result3 = print_builtin(&mut interp);
196 assert!(result3.is_ok());
197
198 assert!(matches!(interp.pop(), Err(RuntimeError::StackUnderflow)));
200 }
201}