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