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::Pair(_, _) | Value::Nil => {
196 interp.push(value.clone());
197 Ok(())
198 }
199 Value::QuotedAtom(atom_name) => {
200 interp.push(Value::Atom(atom_name.clone()));
201 Ok(())
202 }
203 Value::Builtin(func) => func(interp),
204 Value::Atom(atom_name) => {
205 execute_atom_with_continuations(atom_name, interp, continuation_stack)
206 }
207 Value::Record { .. } | Value::RecordType { .. } => {
209 interp.push(value.clone());
210 Ok(())
211 }
212 #[cfg(feature = "datetime")]
214 Value::DateTime(_) | Value::Duration(_) => {
215 interp.push(value.clone());
216 Ok(())
217 }
218 Value::I16Buffer(_) => {
220 interp.push(value.clone());
221 Ok(())
222 }
223 }
224}
225
226fn list_to_vec(list: &Value) -> Result<Vec<Value>, RuntimeError> {
228 let mut current = list.clone();
229 let mut items = Vec::new();
230
231 loop {
232 match current {
233 Value::Pair(car, cdr) => {
234 items.push((*car).clone());
235 current = (*cdr).clone();
236 }
237 Value::Nil => break,
238 _ => {
239 items.push(current);
241 break;
242 }
243 }
244 }
245
246 Ok(items)
247}
248
249fn execute_atom_with_continuations(
251 atom_name: &Rc<str>,
252 interp: &mut Interpreter,
253 continuation_stack: &mut Vec<Continuation>,
254) -> Result<(), RuntimeError> {
255 if &**atom_name == "exec" {
257 let value = interp.pop()?;
258 continuation_stack.push(Continuation::Exec(value));
259 return Ok(());
260 }
261
262 if &**atom_name == "if" {
263 let false_branch = interp.pop()?;
264 let true_branch = interp.pop()?;
265 let condition = interp.pop()?;
266
267 let condition_result = interp.is_truthy(&condition);
268 continuation_stack.push(Continuation::If {
269 condition_result,
270 true_branch,
271 false_branch,
272 });
273 return Ok(());
274 }
275
276 if &**atom_name == "quit" {
277 return Err(RuntimeError::QuitRequested);
279 }
280
281 match interp.dictionary.get(atom_name) {
283 Some(entry) => {
284 let entry_copy = entry.clone();
285
286 if entry_copy.is_executable {
287 continuation_stack.push(Continuation::Definition(entry_copy.value));
289 } else {
290 interp.push(entry_copy.value);
292 }
293 Ok(())
294 }
295 None => Err(RuntimeError::UndefinedWord((**atom_name).to_string())),
296 }
297}
298
299pub fn execute(value: &Value, interp: &mut Interpreter) -> Result<(), RuntimeError> {
303 execute_with_continuations(value, interp)
304}
305
306pub fn execute_string(code: &str, interp: &mut Interpreter) -> Result<(), RuntimeError> {
311 use crate::parser::parse;
314
315 let values = parse(code, interp)?;
319
320 for value in values {
324 execute(&value, interp)?;
325 }
326
327 Ok(())
328}
329
330#[cfg(test)]
332mod tests {
333 use super::*;
334 fn setup_interpreter() -> Interpreter {
339 Interpreter::new()
342 }
343
344 #[test]
345 fn test_execute_numbers() {
346 let mut interp = setup_interpreter();
347
348 let number = Value::Number(42.0);
350 execute(&number, &mut interp).unwrap();
351
352 let result = interp.pop().unwrap();
354 assert!(matches!(result, Value::Number(n) if n == 42.0));
355 }
356
357 #[test]
358 fn test_execute_strings() {
359 let mut interp = setup_interpreter();
360
361 let string_val: Rc<str> = "hello world".into();
362 let string = Value::String(string_val);
363 execute(&string, &mut interp).unwrap();
364
365 let result = interp.pop().unwrap();
366 assert!(matches!(result, Value::String(s) if s.as_ref() == "hello world"));
367 }
368
369 #[test]
370 fn test_execute_lists_as_data() {
371 let mut interp = setup_interpreter();
372
373 let plus_atom = interp.intern_atom("+");
375 let list = interp.make_list(vec![
376 Value::Number(1.0),
377 Value::Number(2.0),
378 Value::Atom(plus_atom),
379 ]);
380
381 execute(&list, &mut interp).unwrap();
382
383 let result = interp.pop().unwrap();
385 assert!(matches!(result, Value::Pair(_, _)));
386
387 assert!(interp.pop().is_err());
389 }
390
391 #[test]
392 fn test_execute_builtin_functions() {
393 let mut interp = setup_interpreter();
394
395 interp.push(Value::Number(3.0));
398 interp.push(Value::Number(5.0));
399
400 let plus_atom = interp.intern_atom("+");
402 execute(&Value::Atom(plus_atom), &mut interp).unwrap();
403
404 let result = interp.pop().unwrap();
406 assert!(matches!(result, Value::Number(n) if n == 8.0));
407 }
408
409 #[test]
410 fn test_execute_undefined_atom() {
411 let mut interp = setup_interpreter();
412
413 let undefined_atom = interp.intern_atom("nonexistent");
415 let result = execute(&Value::Atom(undefined_atom), &mut interp);
416
417 assert!(result.is_err());
418 assert!(
419 matches!(result.unwrap_err(), RuntimeError::UndefinedWord(s) if s == "nonexistent")
420 );
421 }
422
423 #[test]
424 fn test_execute_string_simple() {
425 let mut interp = setup_interpreter();
426
427 execute_string("42 3.14", &mut interp).unwrap();
429
430 let result1 = interp.pop().unwrap();
432 let result2 = interp.pop().unwrap();
433
434 assert!(matches!(result1, Value::Number(n) if n == 3.14));
435 assert!(matches!(result2, Value::Int32(42))); }
437
438 #[test]
439 fn test_execute_string_with_builtin() {
440 let mut interp = setup_interpreter();
441
442 execute_string("5 3 +", &mut interp).unwrap();
444
445 let result = interp.pop().unwrap();
447 assert!(matches!(result, Value::Int32(8))); assert!(interp.pop().is_err());
451 }
452
453 #[test]
458 fn test_tail_recursive_factorial() {
459 let mut interp = setup_interpreter();
460
461 execute_string(
463 "'count-down [dup 1 <= [drop 999] [1 - count-down] if] def",
464 &mut interp,
465 )
466 .unwrap();
467
468 execute_string("5 count-down", &mut interp).unwrap();
470 let result = interp.pop().unwrap();
471 assert!(matches!(result, Value::Int32(999))); }
473
474 #[test]
475 fn test_deep_tail_recursion() {
476 let mut interp = setup_interpreter();
477
478 execute_string(
480 "'countdown [dup 0 <= [drop 42] [1 - countdown] if] def",
481 &mut interp,
482 )
483 .unwrap();
484
485 execute_string("1000 countdown", &mut interp).unwrap();
487 let result = interp.pop().unwrap();
488 assert!(matches!(result, Value::Int32(42))); }
490
491 #[test]
492 fn test_mutually_tail_recursive_functions() {
493 let mut interp = setup_interpreter();
494
495 execute_string("'even [dup 0 = [drop true] [1 - odd] if] def", &mut interp).unwrap();
497 execute_string("'odd [dup 0 = [drop false] [1 - even] if] def", &mut interp).unwrap();
498
499 execute_string("10 even", &mut interp).unwrap();
501 let result = interp.pop().unwrap();
502 assert!(matches!(result, Value::Boolean(true)));
503
504 execute_string("11 odd", &mut interp).unwrap();
505 let result = interp.pop().unwrap();
506 assert!(matches!(result, Value::Boolean(true)));
507 }
508
509 #[test]
510 fn test_tail_call_in_if_branches() {
511 let mut interp = setup_interpreter();
512
513 execute_string(
515 "'branch-test [dup 10 > [drop 99] [1 + branch-test] if] def",
516 &mut interp,
517 )
518 .unwrap();
519
520 execute_string("5 branch-test", &mut interp).unwrap();
521 let result = interp.pop().unwrap();
522 assert!(matches!(result, Value::Int32(99))); }
524
525 #[test]
526 fn test_execute_string_with_list() {
527 let mut interp = setup_interpreter();
528
529 execute_string("[1 2 +] 42", &mut interp).unwrap();
531
532 let number = interp.pop().unwrap();
534 let list = interp.pop().unwrap();
535
536 assert!(matches!(number, Value::Int32(42))); assert!(matches!(list, Value::Pair(_, _)));
538 }
539
540 #[test]
541 fn test_execute_quoted_atoms() {
542 let mut interp = setup_interpreter();
543
544 let hello_atom = interp.intern_atom("hello");
551 let quote_atom = interp.intern_atom("quote");
552
553 let quoted_hello = Value::Pair(
554 Rc::new(Value::Atom(quote_atom)),
555 Rc::new(Value::Pair(
556 Rc::new(Value::Atom(hello_atom)),
557 Rc::new(Value::Nil),
558 )),
559 );
560
561 execute("ed_hello, &mut interp).unwrap();
563
564 let result = interp.pop().unwrap();
565 assert!(matches!(result, Value::Pair(_, _)));
566 }
567
568 #[test]
569 fn test_execute_string_parse_errors() {
570 let mut interp = setup_interpreter();
571
572 let result = execute_string("[1 2", &mut interp); assert!(result.is_err());
575
576 let result = execute_string("'[1 2]", &mut interp); assert!(result.is_err());
578 }
579}