1use crate::ast::{BinOp, Expr, Program, Stmt, UnaryOp};
5use crate::builtins::BuiltInRegistry;
6use crate::environment::Environment;
7use crate::value::{GeneratorState, Value};
8use std::cell::RefCell;
9use std::collections::VecDeque;
10use std::rc::Rc;
11
12#[derive(Debug, Clone, PartialEq)]
14pub enum RuntimeError {
15 UndefinedVariable(String),
17
18 TypeError(String),
20
21 TypeErrorDetailed { expected: String, got: String },
23
24 InvalidOperation(String),
26
27 DivisionByZero,
29
30 NotCallable(String),
32
33 WrongArity { expected: usize, got: usize },
35
36 Return(Value),
38
39 Yield(Value),
41
42 Break,
44
45 Continue,
47
48 Throw(Value),
50
51 CustomError(String),
53}
54
55impl std::fmt::Display for RuntimeError {
56 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
57 match self {
58 RuntimeError::UndefinedVariable(name) => write!(f, "Undefined variable: {}", name),
59 RuntimeError::TypeError(msg) => write!(f, "Type error: {}", msg),
60 RuntimeError::TypeErrorDetailed { expected, got } => {
61 write!(f, "Type error: expected {}, got {}", expected, got)
62 }
63 RuntimeError::InvalidOperation(msg) => write!(f, "Invalid operation: {}", msg),
64 RuntimeError::DivisionByZero => write!(f, "Division by zero"),
65 RuntimeError::NotCallable(name) => write!(f, "Not callable: {}", name),
66 RuntimeError::WrongArity { expected, got } => {
67 write!(
68 f,
69 "Wrong number of arguments: expected {}, got {}",
70 expected, got
71 )
72 }
73 RuntimeError::Return(val) => write!(f, "Return: {}", val),
74 RuntimeError::Yield(val) => write!(f, "Yield: {}", val),
75 RuntimeError::Break => write!(f, "Break outside of loop"),
76 RuntimeError::Continue => write!(f, "Continue outside of loop"),
77 RuntimeError::Throw(val) => write!(f, "Throw: {}", val),
78 RuntimeError::CustomError(msg) => write!(f, "{}", msg),
79 }
80 }
81}
82
83impl std::error::Error for RuntimeError {}
84
85pub type EvalResult = Result<Value, RuntimeError>;
86
87pub struct Evaluator {
89 env: Rc<RefCell<Environment>>,
91 registry: BuiltInRegistry,
93 trace: VecDeque<String>,
95 trace_seq: u64,
97}
98
99impl Evaluator {
100 const TRACE_MAX_ENTRIES: usize = 1024;
101
102 pub fn new() -> Self {
104 Self::with_permissions(crate::builtins::IOPermissions::default())
105 }
106
107 pub fn with_permissions(permissions: crate::builtins::IOPermissions) -> Self {
109 let env = Rc::new(RefCell::new(Environment::new()));
110
111 let registry = BuiltInRegistry::with_permissions(permissions);
113 for name in registry.names() {
114 env.borrow_mut()
115 .set(name.clone(), Value::BuiltIn { name, arity: 0 });
116 }
117
118 Evaluator {
119 env,
120 registry,
121 trace: VecDeque::new(),
122 trace_seq: 0,
123 }
124 }
125
126 pub fn with_env(env: Rc<RefCell<Environment>>) -> Self {
128 let registry = BuiltInRegistry::new();
129 Evaluator {
130 env,
131 registry,
132 trace: VecDeque::new(),
133 trace_seq: 0,
134 }
135 }
136
137 pub fn trace_push(&mut self, msg: String) {
139 self.trace_seq = self.trace_seq.saturating_add(1);
140 let entry = format!("#{} {}", self.trace_seq, msg);
141
142 if self.trace.len() >= Self::TRACE_MAX_ENTRIES {
143 self.trace.pop_front();
144 }
145 self.trace.push_back(entry);
146 }
147
148 pub fn take_trace(&mut self) -> Vec<String> {
150 std::mem::take(&mut self.trace).into_iter().collect()
151 }
152
153 pub fn clear_trace(&mut self) {
155 self.trace.clear();
156 self.trace_seq = 0;
157 }
158
159 pub fn reset_env(&mut self) {
164 self.env = Rc::new(RefCell::new(Environment::new()));
166
167 self.trace.clear();
169 self.trace_seq = 0;
170
171 for name in self.registry.names() {
173 self.env
174 .borrow_mut()
175 .set(name.clone(), Value::BuiltIn { name, arity: 0 });
176 }
177 }
178
179 pub fn eval_program(&mut self, program: &Program) -> EvalResult {
181 let mut result = Value::Null;
182
183 for stmt in program {
184 result = self.eval_statement(stmt)?;
185 }
186
187 Ok(result)
188 }
189
190 pub fn eval_statement(&mut self, stmt: &Stmt) -> EvalResult {
192 match stmt {
193 Stmt::Set { name, value } => {
194 let val = self.eval_expression(value)?;
195 self.env.borrow_mut().set(name.clone(), val.clone());
196 Ok(val)
197 }
198
199 Stmt::SetIndex {
200 object,
201 index,
202 value,
203 } => {
204 let val = self.eval_expression(value)?;
206
207 if let Expr::Identifier(name) = object.as_ref() {
209 let obj = self
211 .env
212 .borrow()
213 .get(name)
214 .ok_or_else(|| RuntimeError::UndefinedVariable(name.clone()))?;
215
216 let idx_val = self.eval_expression(index)?;
218
219 let new_obj = match (obj, idx_val) {
221 (Value::Array(mut arr), Value::Number(n)) => {
222 let idx = n as usize;
223 if idx >= arr.len() {
224 return Err(RuntimeError::InvalidOperation(format!(
225 "Index {} out of bounds (array length: {})",
226 idx,
227 arr.len()
228 )));
229 }
230 arr[idx] = val.clone();
231 Value::Array(arr)
232 }
233 (Value::Dict(mut dict), Value::String(key)) => {
234 dict.insert(key, val.clone());
235 Value::Dict(dict)
236 }
237 (obj, idx) => {
238 return Err(RuntimeError::TypeError(format!(
239 "Cannot index {} with {}",
240 obj.type_name(),
241 idx.type_name()
242 )));
243 }
244 };
245
246 self.env.borrow_mut().set(name.clone(), new_obj);
248 Ok(val)
249 } else {
250 Err(RuntimeError::InvalidOperation(
252 "Can only assign to simple variable indices (e.g., dict[key], not expr[key])"
253 .to_string(),
254 ))
255 }
256 }
257
258 Stmt::FuncDef { name, params, body } => {
259 let func = Value::Function {
260 params: params.clone(),
261 body: body.clone(),
262 env: Rc::clone(&self.env),
263 };
264 self.env.borrow_mut().set(name.clone(), func.clone());
265 Ok(func)
266 }
267
268 Stmt::GeneratorDef { name, params, body } => {
269 let r#gen = Value::Generator {
270 params: params.clone(),
271 body: body.clone(),
272 env: Rc::clone(&self.env),
273 state: GeneratorState::NotStarted,
274 };
275 self.env.borrow_mut().set(name.clone(), r#gen.clone());
276 Ok(r#gen)
277 }
278
279 Stmt::LazyDef { name, expr } => {
280 let lazy = Value::Lazy {
281 expr: expr.clone(),
282 env: Rc::clone(&self.env),
283 cached: None,
284 };
285 self.env.borrow_mut().set(name.clone(), lazy.clone());
286 Ok(lazy)
287 }
288
289 Stmt::Return(expr) => {
290 let val = self.eval_expression(expr)?;
291 Err(RuntimeError::Return(val))
292 }
293
294 Stmt::Yield(expr) => {
295 let val = self.eval_expression(expr)?;
296 Err(RuntimeError::Yield(val))
297 }
298
299 Stmt::Break => Err(RuntimeError::Break),
300
301 Stmt::Continue => Err(RuntimeError::Continue),
302
303 Stmt::While { condition, body } => {
304 let mut result = Value::Null;
305
306 loop {
307 let cond = self.eval_expression(condition)?;
308 if !cond.is_truthy() {
309 break;
310 }
311
312 let mut should_break = false;
313 for stmt in body {
314 match self.eval_statement(stmt) {
315 Ok(val) => result = val,
316 Err(RuntimeError::Break) => {
317 should_break = true;
318 break;
319 }
320 Err(RuntimeError::Continue) => break,
321 Err(e) => return Err(e),
322 }
323 }
324
325 if should_break {
326 break;
327 }
328 }
329
330 Ok(result)
331 }
332
333 Stmt::For {
334 var,
335 iterable,
336 body,
337 } => {
338 let iter_val = self.eval_expression(iterable)?;
339 let mut result = Value::Null;
340
341 match iter_val {
342 Value::Array(arr) => {
343 let mut should_break = false;
344 for item in arr {
345 self.env.borrow_mut().set(var.clone(), item);
346 for stmt in body {
347 match self.eval_statement(stmt) {
348 Ok(val) => result = val,
349 Err(RuntimeError::Break) => {
350 should_break = true;
351 break;
352 }
353 Err(RuntimeError::Continue) => break,
354 Err(e) => return Err(e),
355 }
356 }
357 if should_break {
358 break;
359 }
360 }
361 }
362 _ => {
363 return Err(RuntimeError::TypeError(format!(
364 "Cannot iterate over {}",
365 iter_val.type_name()
366 )));
367 }
368 }
369
370 Ok(result)
371 }
372
373 Stmt::ForIndexed {
374 index_var,
375 value_var,
376 iterable,
377 body,
378 } => {
379 let iter_val = self.eval_expression(iterable)?;
380 let mut result = Value::Null;
381
382 match iter_val {
383 Value::Array(arr) => {
384 let mut should_break = false;
385 for (idx, item) in arr.iter().enumerate() {
386 self.env
387 .borrow_mut()
388 .set(index_var.clone(), Value::Number(idx as f64));
389 self.env.borrow_mut().set(value_var.clone(), item.clone());
390 for stmt in body {
391 match self.eval_statement(stmt) {
392 Ok(val) => result = val,
393 Err(RuntimeError::Break) => {
394 should_break = true;
395 break;
396 }
397 Err(RuntimeError::Continue) => break,
398 Err(e) => return Err(e),
399 }
400 }
401 if should_break {
402 break;
403 }
404 }
405 }
406 _ => {
407 return Err(RuntimeError::TypeError(format!(
408 "Cannot iterate over {}",
409 iter_val.type_name()
410 )));
411 }
412 }
413
414 Ok(result)
415 }
416
417 Stmt::Switch {
418 expr,
419 cases,
420 default,
421 } => {
422 let val = self.eval_expression(expr)?;
423
424 for (case_expr, case_body) in cases {
425 let case_val = self.eval_expression(case_expr)?;
426 if val.equals(&case_val) {
427 let mut result = Value::Null;
428 for stmt in case_body {
429 result = self.eval_statement(stmt)?;
430 }
431 return Ok(result);
432 }
433 }
434
435 if let Some(default_body) = default {
436 let mut result = Value::Null;
437 for stmt in default_body {
438 result = self.eval_statement(stmt)?;
439 }
440 return Ok(result);
441 }
442
443 Ok(Value::Null)
444 }
445
446 Stmt::Import { .. } => {
447 Err(RuntimeError::InvalidOperation(
449 "Import not yet implemented".to_string(),
450 ))
451 }
452
453 Stmt::Export(_) => {
454 Err(RuntimeError::InvalidOperation(
456 "Export not yet implemented".to_string(),
457 ))
458 }
459
460 Stmt::Throw(expr) => {
461 let val = self.eval_expression(expr)?;
462 Err(RuntimeError::Throw(val))
463 }
464
465 Stmt::Expression(expr) => self.eval_expression(expr),
466 }
467 }
468
469 pub fn eval_expression(&mut self, expr: &Expr) -> EvalResult {
471 match expr {
472 Expr::Number(n) => Ok(Value::Number(*n)),
473
474 Expr::BigInteger(s) => {
475 use num_bigint::BigInt;
477 use num_rational::Ratio;
478
479 match s.parse::<BigInt>() {
480 Ok(big_int) => Ok(Value::Fraction(Ratio::new(big_int, BigInt::from(1)))),
481 Err(_) => Err(RuntimeError::InvalidOperation(format!(
482 "Invalid big integer: {}",
483 s
484 ))),
485 }
486 }
487
488 Expr::String(s) => Ok(Value::String(s.clone())),
489
490 Expr::Boolean(b) => Ok(Value::Boolean(*b)),
491
492 Expr::Null => Ok(Value::Null),
493
494 Expr::Identifier(name) => self
495 .env
496 .borrow()
497 .get(name)
498 .ok_or_else(|| RuntimeError::UndefinedVariable(name.clone())),
499
500 Expr::Binary { left, op, right } => {
501 match op {
503 BinOp::And => {
504 let left_val = self.eval_expression(left)?;
505 if !left_val.is_truthy() {
506 Ok(left_val)
508 } else {
509 self.eval_expression(right)
511 }
512 }
513 BinOp::Or => {
514 let left_val = self.eval_expression(left)?;
515 if left_val.is_truthy() {
516 Ok(left_val)
518 } else {
519 self.eval_expression(right)
521 }
522 }
523 _ => {
525 let left_val = self.eval_expression(left)?;
526 let right_val = self.eval_expression(right)?;
527 self.eval_binary_op(&left_val, op, &right_val)
528 }
529 }
530 }
531
532 Expr::Unary { op, expr } => {
533 let val = self.eval_expression(expr)?;
534 self.eval_unary_op(op, &val)
535 }
536
537 Expr::Call { func, args } => {
538 let func_val = self.eval_expression(func)?;
539 let arg_vals: Result<Vec<_>, _> =
540 args.iter().map(|arg| self.eval_expression(arg)).collect();
541 let arg_vals = arg_vals?;
542
543 self.call_function(&func_val, arg_vals)
544 }
545
546 Expr::Array(elements) => {
547 let vals: Result<Vec<_>, _> =
548 elements.iter().map(|e| self.eval_expression(e)).collect();
549 Ok(Value::Array(vals?))
550 }
551
552 Expr::Dict(pairs) => {
553 let mut map = std::collections::HashMap::new();
554 for (key, value_expr) in pairs {
555 let value = self.eval_expression(value_expr)?;
556 map.insert(key.clone(), value);
557 }
558 Ok(Value::Dict(map))
559 }
560
561 Expr::Index { object, index } => {
562 let obj_val = self.eval_expression(object)?;
563 let idx_val = self.eval_expression(index)?;
564
565 match (obj_val, idx_val) {
566 (Value::Array(arr), Value::Number(n)) => {
567 let idx = n as usize;
568 arr.get(idx).cloned().ok_or_else(|| {
569 RuntimeError::InvalidOperation(format!("Index {} out of bounds", idx))
570 })
571 }
572 (Value::String(s), Value::Number(n)) => {
573 let idx = n as usize;
574 let chars: Vec<char> = s.chars().collect();
575 chars
576 .get(idx)
577 .cloned()
578 .map(|ch| Value::String(ch.to_string()))
579 .ok_or_else(|| {
580 RuntimeError::InvalidOperation(format!(
581 "Index {} out of bounds (string length: {})",
582 idx,
583 chars.len()
584 ))
585 })
586 }
587 (Value::Dict(dict), Value::String(key)) => {
588 dict.get(&key).cloned().ok_or_else(|| {
589 RuntimeError::InvalidOperation(format!("Key '{}' not found", key))
590 })
591 }
592 (obj, idx) => Err(RuntimeError::TypeError(format!(
593 "Cannot index {} with {}",
594 obj.type_name(),
595 idx.type_name()
596 ))),
597 }
598 }
599
600 Expr::If {
601 condition,
602 then_branch,
603 elif_branches,
604 else_branch,
605 } => {
606 let cond = self.eval_expression(condition)?;
607
608 if cond.is_truthy() {
609 let mut result = Value::Null;
610 for stmt in then_branch {
611 result = self.eval_statement(stmt)?;
612 }
613 return Ok(result);
614 }
615
616 for (elif_cond, elif_body) in elif_branches {
617 let cond = self.eval_expression(elif_cond)?;
618 if cond.is_truthy() {
619 let mut result = Value::Null;
620 for stmt in elif_body {
621 result = self.eval_statement(stmt)?;
622 }
623 return Ok(result);
624 }
625 }
626
627 if let Some(else_body) = else_branch {
628 let mut result = Value::Null;
629 for stmt in else_body {
630 result = self.eval_statement(stmt)?;
631 }
632 return Ok(result);
633 }
634
635 Ok(Value::Null)
636 }
637
638 Expr::Lambda { params, body } => {
639 Ok(Value::Function {
641 params: params.clone(),
642 body: body.clone(),
643 env: Rc::clone(&self.env),
644 })
645 }
646 }
647 }
648
649 fn eval_binary_op(&self, left: &Value, op: &BinOp, right: &Value) -> EvalResult {
651 match op {
652 BinOp::Add => match (left, right) {
653 (Value::Number(a), Value::Number(b)) => Ok(Value::Number(a + b)),
654 (Value::String(a), Value::String(b)) => Ok(Value::String(format!("{}{}", a, b))),
655 (Value::Fraction(a), Value::Fraction(b)) => Ok(Value::Fraction(a + b)),
656 (Value::Number(a), Value::Fraction(b)) | (Value::Fraction(b), Value::Number(a)) => {
657 use num_bigint::BigInt;
658 use num_rational::Ratio;
659 if a.fract() == 0.0 {
660 let a_frac = Ratio::new(BigInt::from(*a as i64), BigInt::from(1));
661 Ok(Value::Fraction(a_frac + b))
662 } else {
663 use num_traits::ToPrimitive;
665 let b_float =
666 b.numer().to_f64().unwrap_or(0.0) / b.denom().to_f64().unwrap_or(1.0);
667 Ok(Value::Number(a + b_float))
668 }
669 }
670 _ => Err(RuntimeError::TypeError(format!(
671 "Cannot add {} and {}",
672 left.type_name(),
673 right.type_name()
674 ))),
675 },
676
677 BinOp::Subtract => match (left, right) {
678 (Value::Number(a), Value::Number(b)) => Ok(Value::Number(a - b)),
679 (Value::Fraction(a), Value::Fraction(b)) => Ok(Value::Fraction(a - b)),
680 (Value::Number(a), Value::Fraction(b)) => {
681 use num_bigint::BigInt;
682 use num_rational::Ratio;
683 if a.fract() == 0.0 {
684 let a_frac = Ratio::new(BigInt::from(*a as i64), BigInt::from(1));
685 Ok(Value::Fraction(a_frac - b))
686 } else {
687 use num_traits::ToPrimitive;
688 let b_float =
689 b.numer().to_f64().unwrap_or(0.0) / b.denom().to_f64().unwrap_or(1.0);
690 Ok(Value::Number(a - b_float))
691 }
692 }
693 (Value::Fraction(a), Value::Number(b)) => {
694 use num_bigint::BigInt;
695 use num_rational::Ratio;
696 if b.fract() == 0.0 {
697 let b_frac = Ratio::new(BigInt::from(*b as i64), BigInt::from(1));
698 Ok(Value::Fraction(a - b_frac))
699 } else {
700 use num_traits::ToPrimitive;
701 let a_float =
702 a.numer().to_f64().unwrap_or(0.0) / a.denom().to_f64().unwrap_or(1.0);
703 Ok(Value::Number(a_float - b))
704 }
705 }
706 _ => Err(RuntimeError::TypeError(format!(
707 "Cannot subtract {} from {}",
708 right.type_name(),
709 left.type_name()
710 ))),
711 },
712
713 BinOp::Multiply => match (left, right) {
714 (Value::Number(a), Value::Number(b)) => {
715 if a.fract() == 0.0 && b.fract() == 0.0 {
717 let max_safe = 9007199254740992.0; if a.abs() > max_safe || b.abs() > max_safe {
720 use num_bigint::BigInt;
722 use num_rational::Ratio;
723
724 let a_str = format!("{:.0}", a);
726 let b_str = format!("{:.0}", b);
727
728 if let (Ok(a_big), Ok(b_big)) =
729 (a_str.parse::<BigInt>(), b_str.parse::<BigInt>())
730 {
731 let result_big = a_big * b_big;
732 let frac = Ratio::new(result_big, BigInt::from(1));
733 return Ok(Value::Fraction(frac));
734 }
735 }
736 }
737 Ok(Value::Number(a * b))
738 }
739 (Value::Fraction(a), Value::Fraction(b)) => Ok(Value::Fraction(a * b)),
740 (Value::Number(a), Value::Fraction(b)) | (Value::Fraction(b), Value::Number(a)) => {
741 use num_bigint::BigInt;
742 use num_rational::Ratio;
743 if a.fract() == 0.0 {
744 let a_frac = Ratio::new(BigInt::from(*a as i64), BigInt::from(1));
745 Ok(Value::Fraction(a_frac * b))
746 } else {
747 Err(RuntimeError::TypeError(
748 "Cannot multiply non-integer Number with Fraction".to_string(),
749 ))
750 }
751 }
752 _ => Err(RuntimeError::TypeError(format!(
753 "Cannot multiply {} and {}",
754 left.type_name(),
755 right.type_name()
756 ))),
757 },
758
759 BinOp::Divide => match (left, right) {
760 (Value::Number(a), Value::Number(b)) => {
761 if *b == 0.0 {
762 Err(RuntimeError::DivisionByZero)
763 } else {
764 Ok(Value::Number(a / b))
765 }
766 }
767 (Value::Fraction(a), Value::Fraction(b)) => {
768 use num_traits::Zero;
769 if b.is_zero() {
770 Err(RuntimeError::DivisionByZero)
771 } else {
772 Ok(Value::Fraction(a / b))
773 }
774 }
775 (Value::Number(a), Value::Fraction(b)) => {
776 use num_bigint::BigInt;
777 use num_rational::Ratio;
778 use num_traits::Zero;
779 if b.is_zero() {
780 Err(RuntimeError::DivisionByZero)
781 } else if a.fract() == 0.0 {
782 let a_frac = Ratio::new(BigInt::from(*a as i64), BigInt::from(1));
783 Ok(Value::Fraction(a_frac / b))
784 } else {
785 use num_traits::ToPrimitive;
786 let b_float =
787 b.numer().to_f64().unwrap_or(0.0) / b.denom().to_f64().unwrap_or(1.0);
788 Ok(Value::Number(a / b_float))
789 }
790 }
791 (Value::Fraction(a), Value::Number(b)) => {
792 use num_bigint::BigInt;
793 use num_rational::Ratio;
794 if *b == 0.0 {
795 Err(RuntimeError::DivisionByZero)
796 } else if b.fract() == 0.0 {
797 let b_frac = Ratio::new(BigInt::from(*b as i64), BigInt::from(1));
798 Ok(Value::Fraction(a / b_frac))
799 } else {
800 use num_traits::ToPrimitive;
801 let a_float =
802 a.numer().to_f64().unwrap_or(0.0) / a.denom().to_f64().unwrap_or(1.0);
803 Ok(Value::Number(a_float / b))
804 }
805 }
806 _ => Err(RuntimeError::TypeError(format!(
807 "Cannot divide {} by {}",
808 left.type_name(),
809 right.type_name()
810 ))),
811 },
812
813 BinOp::Modulo => match (left, right) {
814 (Value::Number(a), Value::Number(b)) => {
815 if *b == 0.0 {
816 Err(RuntimeError::DivisionByZero)
817 } else {
818 Ok(Value::Number(a % b))
819 }
820 }
821 _ => Err(RuntimeError::TypeError(format!(
822 "Cannot modulo {} by {}",
823 left.type_name(),
824 right.type_name()
825 ))),
826 },
827
828 BinOp::Equal => Ok(Value::Boolean(left.equals(right))),
829
830 BinOp::NotEqual => Ok(Value::Boolean(!left.equals(right))),
831
832 BinOp::Less => match left.compare(right) {
833 Some(ord) => Ok(Value::Boolean(ord == std::cmp::Ordering::Less)),
834 None => Err(RuntimeError::TypeError(format!(
835 "Cannot compare {} and {}",
836 left.type_name(),
837 right.type_name()
838 ))),
839 },
840
841 BinOp::LessEqual => match left.compare(right) {
842 Some(ord) => Ok(Value::Boolean(ord != std::cmp::Ordering::Greater)),
843 None => Err(RuntimeError::TypeError(format!(
844 "Cannot compare {} and {}",
845 left.type_name(),
846 right.type_name()
847 ))),
848 },
849
850 BinOp::Greater => match left.compare(right) {
851 Some(ord) => Ok(Value::Boolean(ord == std::cmp::Ordering::Greater)),
852 None => Err(RuntimeError::TypeError(format!(
853 "Cannot compare {} and {}",
854 left.type_name(),
855 right.type_name()
856 ))),
857 },
858
859 BinOp::GreaterEqual => match left.compare(right) {
860 Some(ord) => Ok(Value::Boolean(ord != std::cmp::Ordering::Less)),
861 None => Err(RuntimeError::TypeError(format!(
862 "Cannot compare {} and {}",
863 left.type_name(),
864 right.type_name()
865 ))),
866 },
867
868 BinOp::And => {
869 if !left.is_truthy() {
870 Ok(left.clone())
871 } else {
872 Ok(right.clone())
873 }
874 }
875
876 BinOp::Or => {
877 if left.is_truthy() {
878 Ok(left.clone())
879 } else {
880 Ok(right.clone())
881 }
882 }
883 }
884 }
885
886 fn eval_unary_op(&self, op: &UnaryOp, val: &Value) -> EvalResult {
888 match op {
889 UnaryOp::Minus => match val {
890 Value::Number(n) => Ok(Value::Number(-n)),
891 _ => Err(RuntimeError::TypeError(format!(
892 "Cannot negate {}",
893 val.type_name()
894 ))),
895 },
896
897 UnaryOp::Not => Ok(Value::Boolean(!val.is_truthy())),
898 }
899 }
900
901 fn call_function(&mut self, func: &Value, args: Vec<Value>) -> EvalResult {
903 match func {
904 Value::Function { params, body, env } => {
905 if params.len() != args.len() {
906 return Err(RuntimeError::WrongArity {
907 expected: params.len(),
908 got: args.len(),
909 });
910 }
911
912 let func_env = Rc::new(RefCell::new(Environment::with_parent(Rc::clone(env))));
914
915 for (param, arg) in params.iter().zip(args.iter()) {
917 func_env.borrow_mut().set(param.clone(), arg.clone());
918 }
919
920 let prev_env = Rc::clone(&self.env);
922 self.env = func_env;
923
924 let mut result = Value::Null;
925 for stmt in body {
926 match self.eval_statement(stmt) {
927 Ok(val) => result = val,
928 Err(RuntimeError::Return(val)) => {
929 result = val;
930 break;
931 }
932 Err(e) => {
933 self.env = prev_env;
934 return Err(e);
935 }
936 }
937 }
938
939 self.env = prev_env;
940 Ok(result)
941 }
942
943 Value::BuiltIn { name, .. } => {
944 match name.as_str() {
946 "TRACE" => {
947 if args.is_empty() {
948 return Err(RuntimeError::WrongArity {
949 expected: 1,
950 got: 0,
951 });
952 }
953
954 let (label, payload_args) = if args.len() >= 2 {
957 match &args[0] {
958 Value::String(s) => (Some(s.as_str()), &args[1..]),
959 _ => (None, args.as_slice()),
960 }
961 } else {
962 (None, args.as_slice())
963 };
964
965 let payload = payload_args
966 .iter()
967 .map(|v| v.to_string())
968 .collect::<Vec<_>>()
969 .join(" ");
970
971 let msg = match label {
972 Some(l) => format!("[{}] {}", l, payload),
973 None => payload,
974 };
975
976 self.trace_push(msg);
977 Ok(Value::Null)
978 }
979 "MAP" => self.builtin_map(&args),
980 "FILTER" => self.builtin_filter(&args),
981 "REDUCE" => self.builtin_reduce(&args),
982 _ => {
983 if let Some((func, _arity)) = self.registry.get(name) {
985 func(&args)
987 } else {
988 Err(RuntimeError::NotCallable(format!(
989 "Built-in function '{}' not found",
990 name
991 )))
992 }
993 }
994 }
995 }
996
997 _ => Err(RuntimeError::NotCallable(func.type_name().to_string())),
998 }
999 }
1000
1001 fn builtin_map(&mut self, args: &[Value]) -> EvalResult {
1003 if args.len() != 2 {
1004 return Err(RuntimeError::WrongArity {
1005 expected: 2,
1006 got: args.len(),
1007 });
1008 }
1009
1010 let arr = match &args[0] {
1011 Value::Array(a) => a,
1012 other => {
1013 return Err(RuntimeError::TypeErrorDetailed {
1014 expected: "Array".to_string(),
1015 got: format!("{:?}", other),
1016 });
1017 }
1018 };
1019
1020 let func = &args[1];
1021
1022 let mut result = Vec::new();
1023 for item in arr {
1024 let mapped = self.call_function(func, vec![item.clone()])?;
1025 result.push(mapped);
1026 }
1027
1028 Ok(Value::Array(result))
1029 }
1030
1031 fn builtin_filter(&mut self, args: &[Value]) -> EvalResult {
1033 if args.len() != 2 {
1034 return Err(RuntimeError::WrongArity {
1035 expected: 2,
1036 got: args.len(),
1037 });
1038 }
1039
1040 let arr = match &args[0] {
1041 Value::Array(a) => a,
1042 other => {
1043 return Err(RuntimeError::TypeErrorDetailed {
1044 expected: "Array".to_string(),
1045 got: format!("{:?}", other),
1046 });
1047 }
1048 };
1049
1050 let predicate = &args[1];
1051
1052 let mut result = Vec::new();
1053 for item in arr {
1054 let test_result = self.call_function(predicate, vec![item.clone()])?;
1055 if test_result.is_truthy() {
1056 result.push(item.clone());
1057 }
1058 }
1059
1060 Ok(Value::Array(result))
1061 }
1062
1063 fn builtin_reduce(&mut self, args: &[Value]) -> EvalResult {
1065 if args.len() != 3 {
1066 return Err(RuntimeError::WrongArity {
1067 expected: 3,
1068 got: args.len(),
1069 });
1070 }
1071
1072 let arr = match &args[0] {
1073 Value::Array(a) => a,
1074 other => {
1075 return Err(RuntimeError::TypeErrorDetailed {
1076 expected: "Array".to_string(),
1077 got: format!("{:?}", other),
1078 });
1079 }
1080 };
1081
1082 let mut accumulator = args[1].clone();
1083 let func = &args[2];
1084
1085 for item in arr {
1086 accumulator = self.call_function(func, vec![accumulator, item.clone()])?;
1087 }
1088
1089 Ok(accumulator)
1090 }
1091}
1092
1093impl Default for Evaluator {
1094 fn default() -> Self {
1095 Self::new()
1096 }
1097}
1098
1099#[cfg(test)]
1100mod tests {
1101 use super::*;
1102 use crate::parser::Parser;
1103
1104 fn eval(code: &str) -> EvalResult {
1105 let mut parser = Parser::new(code);
1106 let program = parser.parse_program().unwrap();
1107 let mut evaluator = Evaluator::new();
1108 evaluator.eval_program(&program)
1109 }
1110
1111 #[test]
1112 fn test_eval_numbers() {
1113 assert_eq!(eval("42").unwrap(), Value::Number(42.0));
1114 #[allow(clippy::approx_constant)]
1115 {
1116 assert_eq!(eval("3.14").unwrap(), Value::Number(3.14));
1117 }
1118 }
1119
1120 #[test]
1121 fn test_eval_strings() {
1122 assert_eq!(
1123 eval(r#""hello""#).unwrap(),
1124 Value::String("hello".to_string())
1125 );
1126 }
1127
1128 #[test]
1129 fn test_eval_booleans() {
1130 assert_eq!(eval("True").unwrap(), Value::Boolean(true));
1131 assert_eq!(eval("False").unwrap(), Value::Boolean(false));
1132 }
1133
1134 #[test]
1135 fn test_eval_arithmetic() {
1136 assert_eq!(eval("(5 + 3)").unwrap(), Value::Number(8.0));
1137 assert_eq!(eval("(10 - 3)").unwrap(), Value::Number(7.0));
1138 assert_eq!(eval("(4 * 3)").unwrap(), Value::Number(12.0));
1139 assert_eq!(eval("(10 / 2)").unwrap(), Value::Number(5.0));
1140 assert_eq!(eval("(10 % 3)").unwrap(), Value::Number(1.0));
1141 }
1142
1143 #[test]
1144 fn test_eval_arithmetic_precedence() {
1145 assert_eq!(eval("(5 + 3 * 2)").unwrap(), Value::Number(11.0));
1146 assert_eq!(eval("((5 + 3) * 2)").unwrap(), Value::Number(16.0));
1147 }
1148
1149 #[test]
1150 fn test_eval_comparison() {
1151 assert_eq!(eval("(5 < 10)").unwrap(), Value::Boolean(true));
1152 assert_eq!(eval("(10 < 5)").unwrap(), Value::Boolean(false));
1153 assert_eq!(eval("(5 == 5)").unwrap(), Value::Boolean(true));
1154 assert_eq!(eval("(5 != 3)").unwrap(), Value::Boolean(true));
1155 }
1156
1157 #[test]
1158 fn test_eval_logical() {
1159 assert_eq!(eval("(True && False)").unwrap(), Value::Boolean(false));
1160 assert_eq!(eval("(True || False)").unwrap(), Value::Boolean(true));
1161 assert_eq!(eval("(!True)").unwrap(), Value::Boolean(false));
1162 }
1163
1164 #[test]
1165 fn test_eval_set() {
1166 let code = r#"
1167 Set X 42
1168 X
1169 "#;
1170 assert_eq!(eval(code).unwrap(), Value::Number(42.0));
1171 }
1172
1173 #[test]
1174 fn test_eval_function() {
1175 let code = r#"
1176 Func ADD (A, B) {
1177 Return (A + B)
1178 }
1179 ADD(5, 3)
1180 "#;
1181 assert_eq!(eval(code).unwrap(), Value::Number(8.0));
1182 }
1183
1184 #[test]
1185 fn test_eval_array() {
1186 let code = "[1, 2, 3]";
1187 let result = eval(code).unwrap();
1188 match result {
1189 Value::Array(arr) => {
1190 assert_eq!(arr.len(), 3);
1191 assert_eq!(arr[0], Value::Number(1.0));
1192 assert_eq!(arr[1], Value::Number(2.0));
1193 assert_eq!(arr[2], Value::Number(3.0));
1194 }
1195 _ => panic!("Expected array"),
1196 }
1197 }
1198
1199 #[test]
1200 fn test_eval_array_index() {
1201 let code = r#"
1202 Set ARR [10, 20, 30]
1203 ARR[1]
1204 "#;
1205 assert_eq!(eval(code).unwrap(), Value::Number(20.0));
1206 }
1207
1208 #[test]
1209 fn test_eval_if() {
1210 let code = r#"
1211 If (True) {
1212 Set X 42
1213 } Else {
1214 Set X 0
1215 }
1216 X
1217 "#;
1218 assert_eq!(eval(code).unwrap(), Value::Number(42.0));
1219 }
1220
1221 #[test]
1222 fn test_eval_for() {
1223 let code = r#"
1224 Set SUM 0
1225 For I In [1, 2, 3] {
1226 Set SUM (SUM + I)
1227 }
1228 SUM
1229 "#;
1230 assert_eq!(eval(code).unwrap(), Value::Number(6.0));
1231 }
1232}