1use crate::interpreter::Interpreter;
16use crate::value::{RuntimeError, Value};
17use crate::compat::{Rc, Vec, ToString};
18
19#[derive(Debug, Clone)]
23enum Continuation {
24 Value(Value),
26
27 List {
30 items: Vec<Value>,
31 index: usize,
32 },
33
34 If {
36 condition_result: bool,
37 true_branch: Value,
38 false_branch: Value,
39 },
40
41 Exec(Value),
43
44 Definition(Value),
46}
47
48pub fn execute_with_continuations(
51 initial_value: &Value,
52 interp: &mut Interpreter,
53) -> Result<(), RuntimeError> {
54 let mut continuation_stack: Vec<Continuation> = Vec::new();
55 continuation_stack.push(Continuation::Value(initial_value.clone()));
56
57 while let Some(continuation) = continuation_stack.pop() {
58 match continuation {
59 Continuation::Value(value) => {
60 execute_value_direct(&value, interp, &mut continuation_stack)?;
61 }
62
63 Continuation::List { items, index } => {
64 if index >= items.len() {
65 continue; }
67
68 let item = &items[index];
69 let is_tail_call = index == items.len() - 1;
70
71 if is_tail_call {
72 continuation_stack.push(Continuation::Value(item.clone()));
75 } else {
76 continuation_stack.push(Continuation::List {
78 items: items.clone(),
79 index: index + 1,
80 });
81 continuation_stack.push(Continuation::Value(item.clone()));
82 }
83 }
84
85 Continuation::If {
86 condition_result,
87 true_branch,
88 false_branch,
89 } => {
90 let branch = if condition_result {
91 true_branch
92 } else {
93 false_branch
94 };
95 match &branch {
97 Value::Pair(_, _) | Value::Nil => {
98 let items = list_to_vec(&branch)?;
99 continuation_stack.push(Continuation::List { items, index: 0 });
100 }
101 _ => {
102 continuation_stack.push(Continuation::Value(branch));
103 }
104 }
105 }
106
107 Continuation::Exec(value) => {
108 match &value {
110 Value::Pair(_, _) => {
111 let items = list_to_vec(&value)?;
112 continuation_stack.push(Continuation::List { items, index: 0 });
113 }
114 Value::Nil => {
115 }
117 _ => {
118 continuation_stack.push(Continuation::Value(value));
120 }
121 }
122 }
123
124 Continuation::Definition(definition) => {
125 match &definition {
126 Value::Pair(_, _) | Value::Nil => {
127 let items = list_to_vec(&definition)?;
129 continuation_stack.push(Continuation::List { items, index: 0 });
130 }
131 _ => {
132 continuation_stack.push(Continuation::Value(definition));
134 }
135 }
136 }
137 }
138 }
139
140 Ok(())
141}
142
143fn execute_value_direct(
146 value: &Value,
147 interp: &mut Interpreter,
148 continuation_stack: &mut Vec<Continuation>,
149) -> Result<(), RuntimeError> {
150 match value {
151 Value::Number(n) => {
153 interp.push(Value::Number(*n));
154 Ok(())
155 }
156 Value::Int32(i) => {
158 interp.push(Value::Int32(*i));
159 Ok(())
160 }
161 Value::Integer(i) => {
162 interp.push(Value::Integer(i.clone()));
163 Ok(())
164 }
165 Value::Rational(r) => {
166 interp.push(Value::Rational(r.clone()));
167 Ok(())
168 }
169 #[cfg(feature = "complex_numbers")]
170 Value::Complex(c) => {
171 interp.push(Value::Complex(*c));
172 Ok(())
173 }
174 #[cfg(feature = "complex_numbers")]
175 Value::GaussianInt(re, im) => {
176 interp.push(Value::GaussianInt(re.clone(), im.clone()));
177 Ok(())
178 }
179 Value::String(s) => {
180 interp.push(Value::String(s.clone()));
181 Ok(())
182 }
183 Value::Boolean(b) => {
184 interp.push(Value::Boolean(*b));
185 Ok(())
186 }
187 Value::Null => {
188 interp.push(Value::Null);
189 Ok(())
190 }
191 Value::Array(array) => {
192 interp.push(Value::Array(array.clone()));
193 Ok(())
194 }
195 Value::Variable(var) => {
196 interp.push(Value::Variable(var.clone()));
197 Ok(())
198 }
199 Value::Pair(_, _) | Value::Nil => {
200 interp.push(value.clone());
201 Ok(())
202 }
203 Value::QuotedAtom(atom_name) => {
204 interp.push(Value::Atom(atom_name.clone()));
205 Ok(())
206 }
207 Value::Builtin(func) => func(interp),
208 Value::Atom(atom_name) => {
209 execute_atom_with_continuations(atom_name, interp, continuation_stack)
210 }
211 Value::Record { .. } | Value::RecordType { .. } => {
213 interp.push(value.clone());
214 Ok(())
215 }
216 #[cfg(feature = "datetime")]
218 Value::DateTime(_) | Value::Duration(_) => {
219 interp.push(value.clone());
220 Ok(())
221 }
222 Value::I16Buffer(_) => {
224 interp.push(value.clone());
225 Ok(())
226 }
227 }
228}
229
230fn list_to_vec(list: &Value) -> Result<Vec<Value>, RuntimeError> {
232 let mut current = list.clone();
233 let mut items = Vec::new();
234
235 loop {
236 match current {
237 Value::Pair(car, cdr) => {
238 items.push((*car).clone());
239 current = (*cdr).clone();
240 }
241 Value::Nil => break,
242 _ => {
243 items.push(current);
245 break;
246 }
247 }
248 }
249
250 Ok(items)
251}
252
253fn execute_atom_with_continuations(
255 atom_name: &Rc<str>,
256 interp: &mut Interpreter,
257 continuation_stack: &mut Vec<Continuation>,
258) -> Result<(), RuntimeError> {
259 if &**atom_name == "exec" {
261 let value = interp.pop()?;
262 continuation_stack.push(Continuation::Exec(value));
263 return Ok(());
264 }
265
266 if &**atom_name == "if" {
267 let false_branch = interp.pop()?;
268 let true_branch = interp.pop()?;
269 let condition = interp.pop()?;
270
271 let condition_result = interp.is_truthy(&condition);
272 continuation_stack.push(Continuation::If {
273 condition_result,
274 true_branch,
275 false_branch,
276 });
277 return Ok(());
278 }
279
280 if &**atom_name == "quit" {
281 return Err(RuntimeError::QuitRequested);
283 }
284
285 match interp.dictionary.get(atom_name) {
287 Some(entry) => {
288 let entry_copy = entry.clone();
289
290 if entry_copy.is_executable {
291 continuation_stack.push(Continuation::Definition(entry_copy.value));
293 } else {
294 interp.push(entry_copy.value);
296 }
297 Ok(())
298 }
299 None => Err(RuntimeError::UndefinedWord((**atom_name).to_string())),
300 }
301}
302
303pub fn execute(value: &Value, interp: &mut Interpreter) -> Result<(), RuntimeError> {
307 execute_with_continuations(value, interp)
308}
309
310pub fn execute_string(code: &str, interp: &mut Interpreter) -> Result<(), RuntimeError> {
315 use crate::parser::parse;
318
319 let values = parse(code, interp)?;
323
324 for value in values {
328 execute(&value, interp)?;
329 }
330
331 Ok(())
332}
333
334#[cfg(test)]
336mod tests {
337 use super::*;
338 fn setup_interpreter() -> Interpreter {
343 Interpreter::new()
346 }
347
348 #[test]
349 fn test_execute_numbers() {
350 let mut interp = setup_interpreter();
351
352 let number = Value::Number(42.0);
354 execute(&number, &mut interp).unwrap();
355
356 let result = interp.pop().unwrap();
358 assert!(matches!(result, Value::Number(n) if n == 42.0));
359 }
360
361 #[test]
362 fn test_execute_strings() {
363 let mut interp = setup_interpreter();
364
365 let string_val: Rc<str> = "hello world".into();
366 let string = Value::String(string_val);
367 execute(&string, &mut interp).unwrap();
368
369 let result = interp.pop().unwrap();
370 assert!(matches!(result, Value::String(s) if s.as_ref() == "hello world"));
371 }
372
373 #[test]
374 fn test_execute_lists_as_data() {
375 let mut interp = setup_interpreter();
376
377 let plus_atom = interp.intern_atom("+");
379 let list = interp.make_list(vec![
380 Value::Number(1.0),
381 Value::Number(2.0),
382 Value::Atom(plus_atom),
383 ]);
384
385 execute(&list, &mut interp).unwrap();
386
387 let result = interp.pop().unwrap();
389 assert!(matches!(result, Value::Pair(_, _)));
390
391 assert!(interp.pop().is_err());
393 }
394
395 #[test]
396 fn test_execute_builtin_functions() {
397 let mut interp = setup_interpreter();
398
399 interp.push(Value::Number(3.0));
402 interp.push(Value::Number(5.0));
403
404 let plus_atom = interp.intern_atom("+");
406 execute(&Value::Atom(plus_atom), &mut interp).unwrap();
407
408 let result = interp.pop().unwrap();
410 assert!(matches!(result, Value::Number(n) if n == 8.0));
411 }
412
413 #[test]
414 fn test_execute_undefined_atom() {
415 let mut interp = setup_interpreter();
416
417 let undefined_atom = interp.intern_atom("nonexistent");
419 let result = execute(&Value::Atom(undefined_atom), &mut interp);
420
421 assert!(result.is_err());
422 assert!(
423 matches!(result.unwrap_err(), RuntimeError::UndefinedWord(s) if s == "nonexistent")
424 );
425 }
426
427 #[test]
428 fn test_execute_string_simple() {
429 let mut interp = setup_interpreter();
430
431 execute_string("42 3.14", &mut interp).unwrap();
433
434 let result1 = interp.pop().unwrap();
436 let result2 = interp.pop().unwrap();
437
438 assert!(matches!(result1, Value::Number(n) if n == 3.14));
439 assert!(matches!(result2, Value::Int32(42))); }
441
442 #[test]
443 fn test_execute_string_with_builtin() {
444 let mut interp = setup_interpreter();
445
446 execute_string("5 3 +", &mut interp).unwrap();
448
449 let result = interp.pop().unwrap();
451 assert!(matches!(result, Value::Int32(8))); assert!(interp.pop().is_err());
455 }
456
457 #[test]
462 fn test_tail_recursive_factorial() {
463 let mut interp = setup_interpreter();
464
465 execute_string(
467 "'count-down [dup 1 <= [drop 999] [1 - count-down] if] def",
468 &mut interp,
469 )
470 .unwrap();
471
472 execute_string("5 count-down", &mut interp).unwrap();
474 let result = interp.pop().unwrap();
475 assert!(matches!(result, Value::Int32(999))); }
477
478 #[test]
479 fn test_deep_tail_recursion() {
480 let mut interp = setup_interpreter();
481
482 execute_string(
484 "'countdown [dup 0 <= [drop 42] [1 - countdown] if] def",
485 &mut interp,
486 )
487 .unwrap();
488
489 execute_string("1000 countdown", &mut interp).unwrap();
491 let result = interp.pop().unwrap();
492 assert!(matches!(result, Value::Int32(42))); }
494
495 #[test]
496 fn test_mutually_tail_recursive_functions() {
497 let mut interp = setup_interpreter();
498
499 execute_string("'even [dup 0 = [drop true] [1 - odd] if] def", &mut interp).unwrap();
501 execute_string("'odd [dup 0 = [drop false] [1 - even] if] def", &mut interp).unwrap();
502
503 execute_string("10 even", &mut interp).unwrap();
505 let result = interp.pop().unwrap();
506 assert!(matches!(result, Value::Boolean(true)));
507
508 execute_string("11 odd", &mut interp).unwrap();
509 let result = interp.pop().unwrap();
510 assert!(matches!(result, Value::Boolean(true)));
511 }
512
513 #[test]
514 fn test_tail_call_in_if_branches() {
515 let mut interp = setup_interpreter();
516
517 execute_string(
519 "'branch-test [dup 10 > [drop 99] [1 + branch-test] if] def",
520 &mut interp,
521 )
522 .unwrap();
523
524 execute_string("5 branch-test", &mut interp).unwrap();
525 let result = interp.pop().unwrap();
526 assert!(matches!(result, Value::Int32(99))); }
528
529 #[test]
530 fn test_execute_string_with_list() {
531 let mut interp = setup_interpreter();
532
533 execute_string("[1 2 +] 42", &mut interp).unwrap();
535
536 let number = interp.pop().unwrap();
538 let list = interp.pop().unwrap();
539
540 assert!(matches!(number, Value::Int32(42))); assert!(matches!(list, Value::Pair(_, _)));
542 }
543
544 #[test]
545 fn test_execute_quoted_atoms() {
546 let mut interp = setup_interpreter();
547
548 let hello_atom = interp.intern_atom("hello");
555 let quote_atom = interp.intern_atom("quote");
556
557 let quoted_hello = Value::Pair(
558 Rc::new(Value::Atom(quote_atom)),
559 Rc::new(Value::Pair(
560 Rc::new(Value::Atom(hello_atom)),
561 Rc::new(Value::Nil),
562 )),
563 );
564
565 execute("ed_hello, &mut interp).unwrap();
567
568 let result = interp.pop().unwrap();
569 assert!(matches!(result, Value::Pair(_, _)));
570 }
571
572 #[test]
573 fn test_execute_string_parse_errors() {
574 let mut interp = setup_interpreter();
575
576 let result = execute_string("[1 2", &mut interp); assert!(result.is_err());
579
580 let result = execute_string("'[1 2]", &mut interp); assert!(result.is_err());
582 }
583}