1#![allow(clippy::unused_self)] #![allow(clippy::only_used_in_recursion)] #![allow(clippy::uninlined_format_args)] #![allow(clippy::cast_precision_loss)] #![allow(clippy::expect_used)] #![allow(clippy::cast_possible_truncation)] #![allow(unsafe_code)] use super::eval_expr;
18use super::eval_func;
19use super::eval_literal;
20use super::eval_method;
21use super::eval_operations;
22use crate::frontend::ast::{
23 BinaryOp as AstBinaryOp, Expr, ExprKind, Literal, MatchArm, Pattern, StringPart,
24};
25use crate::frontend::Param;
26use smallvec::{smallvec, SmallVec};
27use std::collections::HashMap;
28use std::sync::Arc;
29
30#[derive(Debug)]
32enum LoopControlOrError {
33 Break(Option<String>, Value),
34 Continue(Option<String>),
35 Return(Value), Error(InterpreterError),
37}
38
39#[derive(Debug, Clone)]
41pub struct DataFrameColumn {
42 pub name: String,
43 pub values: Vec<Value>,
44}
45
46#[derive(Clone, Debug)]
62pub enum Value {
63 Integer(i64),
65 Float(f64),
67 Bool(bool),
69 Byte(u8),
71 Nil,
73 String(Arc<str>),
75 Array(Arc<[Value]>),
77 Tuple(Arc<[Value]>),
79 Closure {
81 params: Vec<String>,
82 body: Arc<Expr>,
83 env: Arc<HashMap<String, Value>>, },
85 DataFrame { columns: Vec<DataFrameColumn> },
87 Object(Arc<HashMap<String, Value>>),
89 ObjectMut(Arc<std::sync::Mutex<HashMap<String, Value>>>),
91 Range {
93 start: Box<Value>,
94 end: Box<Value>,
95 inclusive: bool,
96 },
97 EnumVariant {
99 enum_name: String, variant_name: String, data: Option<Vec<Value>>,
102 },
103 BuiltinFunction(String),
105 Struct {
108 name: String,
109 fields: Arc<HashMap<String, Value>>,
110 },
111 Class {
115 class_name: String,
116 fields: Arc<std::sync::RwLock<HashMap<String, Value>>>,
117 methods: Arc<HashMap<String, Value>>, },
119 #[cfg(not(target_arch = "wasm32"))]
121 HtmlDocument(crate::stdlib::html::HtmlDocument),
122 #[cfg(not(target_arch = "wasm32"))]
124 HtmlElement(crate::stdlib::html::HtmlElement),
125}
126
127impl PartialEq for Value {
130 fn eq(&self, other: &Self) -> bool {
131 match (self, other) {
132 (Value::Integer(a), Value::Integer(b)) => a == b,
133 (Value::Float(a), Value::Float(b)) => a == b,
134 (Value::String(a), Value::String(b)) => a == b,
135 (Value::Bool(a), Value::Bool(b)) => a == b,
136 (Value::Array(a), Value::Array(b)) => a == b,
137 (Value::Tuple(a), Value::Tuple(b)) => a == b,
138 (Value::Object(a), Value::Object(b)) => Arc::ptr_eq(a, b) || **a == **b,
139 (Value::ObjectMut(a), Value::ObjectMut(b)) => Arc::ptr_eq(a, b), (Value::Struct { name: n1, fields: f1 }, Value::Struct { name: n2, fields: f2 }) => {
141 n1 == n2 && **f1 == **f2 }
143 (Value::Class { fields: f1, .. }, Value::Class { fields: f2, .. }) => {
144 Arc::ptr_eq(f1, f2) }
146 (Value::Nil, Value::Nil) => true,
147 (Value::Byte(a), Value::Byte(b)) => a == b,
148 #[cfg(not(target_arch = "wasm32"))]
149 (Value::HtmlDocument(_), Value::HtmlDocument(_)) => false, #[cfg(not(target_arch = "wasm32"))]
151 (Value::HtmlElement(_), Value::HtmlElement(_)) => false, _ => false, }
154 }
155}
156
157impl Value {
158 pub fn type_id(&self) -> std::any::TypeId {
163 use std::any::TypeId;
164 match self {
165 Value::Integer(_) => TypeId::of::<i64>(),
166 Value::Float(_) => TypeId::of::<f64>(),
167 Value::Bool(_) => TypeId::of::<bool>(),
168 Value::Byte(_) => TypeId::of::<u8>(),
169 Value::String(_) => TypeId::of::<String>(),
170 Value::Nil => TypeId::of::<()>(),
171 Value::Array(_) => TypeId::of::<Vec<Value>>(),
172 Value::Tuple(_) => TypeId::of::<(Value,)>(), Value::Closure { .. } => TypeId::of::<fn()>(), Value::DataFrame { .. } => TypeId::of::<crate::runtime::DataFrameColumn>(),
175 Value::Object(_) => TypeId::of::<HashMap<String, Value>>(),
176 Value::ObjectMut(_) => TypeId::of::<HashMap<String, Value>>(),
177 Value::Range { .. } => TypeId::of::<std::ops::Range<i64>>(),
178 Value::EnumVariant { .. } => TypeId::of::<(String, Option<Vec<Value>>)>(),
179 Value::BuiltinFunction(_) => TypeId::of::<fn()>(),
180 Value::Struct { .. } => TypeId::of::<HashMap<String, Value>>(),
181 Value::Class { .. } => TypeId::of::<HashMap<String, Value>>(),
182 #[cfg(not(target_arch = "wasm32"))]
183 Value::HtmlDocument(_) => TypeId::of::<crate::stdlib::html::HtmlDocument>(),
184 #[cfg(not(target_arch = "wasm32"))]
185 Value::HtmlElement(_) => TypeId::of::<crate::stdlib::html::HtmlElement>(),
186 }
187 }
188}
189
190#[derive(Debug)]
214pub struct Interpreter {
215 stack: Vec<Value>,
217
218 env_stack: Vec<HashMap<std::string::String, Value>>,
220
221 #[allow(dead_code)]
223 frames: Vec<CallFrame>,
224
225 #[allow(dead_code)]
227 execution_counts: HashMap<usize, u32>, field_caches: HashMap<String, InlineCache>,
231
232 type_feedback: TypeFeedback,
234
235 gc: ConservativeGC,
237
238 error_scopes: Vec<ErrorScope>,
240
241 stdout_buffer: Vec<String>,
244}
245
246#[derive(Debug, Clone)]
248struct ErrorScope {
249 env_depth: usize,
251}
252
253#[derive(Debug)]
255#[allow(dead_code)]
256pub struct CallFrame {
257 closure: Value,
259
260 ip: *const u8,
262
263 base: usize,
265
266 locals: usize,
268}
269
270unsafe impl Send for CallFrame {}
277
278pub enum InterpreterResult {
280 Continue,
281 Jump(usize),
282 Return(Value),
283 Error(InterpreterError),
284}
285
286#[derive(Debug, Clone)]
297pub enum InterpreterError {
298 TypeError(std::string::String),
299 RuntimeError(std::string::String),
300 StackOverflow,
301 StackUnderflow,
302 InvalidInstruction,
303 DivisionByZero,
304 IndexOutOfBounds,
305 Break(Option<String>, Value),
306 Continue(Option<String>),
307 Return(Value),
308 Throw(Value), AssertionFailed(std::string::String), RecursionLimitExceeded(usize, usize),
313}
314
315#[derive(Clone, Copy, Debug, PartialEq, Eq)]
319pub enum CacheState {
320 Uninitialized,
322 Monomorphic,
324 Polymorphic,
326 Megamorphic,
328}
329
330#[derive(Clone, Debug)]
332pub struct CacheEntry {
333 type_id: std::any::TypeId,
335 field_name: String,
337 cached_result: Value,
339 hit_count: u32,
341}
342
343#[derive(Clone, Debug)]
345pub struct InlineCache {
346 state: CacheState,
348 entries: SmallVec<[CacheEntry; 2]>,
350 total_hits: u32,
352 total_misses: u32,
354}
355
356impl InlineCache {
357 pub fn new() -> Self {
359 Self {
360 state: CacheState::Uninitialized,
361 entries: smallvec![],
362 total_hits: 0,
363 total_misses: 0,
364 }
365 }
366
367 pub fn lookup(&mut self, obj: &Value, field_name: &str) -> Option<Value> {
369 let type_id = obj.type_id();
370
371 for entry in &mut self.entries {
373 if entry.type_id == type_id && entry.field_name == field_name {
374 entry.hit_count += 1;
375 self.total_hits += 1;
376 return Some(entry.cached_result.clone());
377 }
378 }
379
380 self.total_misses += 1;
382 None
383 }
384
385 pub fn insert(&mut self, obj: &Value, field_name: String, result: Value) {
387 let type_id = obj.type_id();
388 let entry = CacheEntry {
389 type_id,
390 field_name,
391 cached_result: result,
392 hit_count: 1,
393 };
394
395 match self.entries.len() {
397 0 => {
398 self.state = CacheState::Monomorphic;
399 self.entries.push(entry);
400 }
401 1..=3 => {
402 self.state = CacheState::Polymorphic;
403 self.entries.push(entry);
404 }
405 _ => {
406 self.state = CacheState::Megamorphic;
408 if let Some(min_idx) = self
410 .entries
411 .iter()
412 .enumerate()
413 .min_by_key(|(_, e)| e.hit_count)
414 .map(|(i, _)| i)
415 {
416 self.entries[min_idx] = entry;
417 }
418 }
419 }
420 }
421
422 pub fn hit_rate(&self) -> f64 {
424 let total = self.total_hits + self.total_misses;
425 if total == 0 {
426 0.0
427 } else {
428 f64::from(self.total_hits) / f64::from(total)
429 }
430 }
431}
432
433impl Default for InlineCache {
434 fn default() -> Self {
435 Self::new()
436 }
437}
438
439#[derive(Clone, Debug)]
459pub struct TypeFeedback {
460 operation_sites: HashMap<usize, OperationFeedback>,
462 variable_types: HashMap<String, VariableTypeFeedback>,
464 call_sites: HashMap<usize, CallSiteFeedback>,
466 total_samples: u64,
468}
469
470#[derive(Clone, Debug)]
472pub struct OperationFeedback {
473 left_types: SmallVec<[std::any::TypeId; 4]>,
475 right_types: SmallVec<[std::any::TypeId; 4]>,
477 result_types: SmallVec<[std::any::TypeId; 4]>,
479 type_counts: HashMap<(std::any::TypeId, std::any::TypeId), u32>,
481 total_count: u32,
483}
484
485#[derive(Clone, Debug)]
487pub struct VariableTypeFeedback {
488 assigned_types: SmallVec<[std::any::TypeId; 4]>,
490 transitions: HashMap<std::any::TypeId, HashMap<std::any::TypeId, u32>>,
492 dominant_type: Option<std::any::TypeId>,
494 stability_score: f64,
496}
497
498#[derive(Clone, Debug)]
500pub struct CallSiteFeedback {
501 arg_type_patterns: SmallVec<[Vec<std::any::TypeId>; 4]>,
503 return_types: SmallVec<[std::any::TypeId; 4]>,
505 call_count: u32,
507 called_functions: HashMap<String, u32>,
509}
510
511impl TypeFeedback {
512 pub fn new() -> Self {
514 Self {
515 operation_sites: HashMap::new(),
516 variable_types: HashMap::new(),
517 call_sites: HashMap::new(),
518 total_samples: 0,
519 }
520 }
521
522 pub fn record_binary_op(
524 &mut self,
525 site_id: usize,
526 left: &Value,
527 right: &Value,
528 result: &Value,
529 ) {
530 let left_type = left.type_id();
531 let right_type = right.type_id();
532 let result_type = result.type_id();
533
534 let feedback = self
535 .operation_sites
536 .entry(site_id)
537 .or_insert_with(|| OperationFeedback {
538 left_types: smallvec![],
539 right_types: smallvec![],
540 result_types: smallvec![],
541 type_counts: HashMap::new(),
542 total_count: 0,
543 });
544
545 if !feedback.left_types.contains(&left_type) {
547 feedback.left_types.push(left_type);
548 }
549 if !feedback.right_types.contains(&right_type) {
550 feedback.right_types.push(right_type);
551 }
552 if !feedback.result_types.contains(&result_type) {
553 feedback.result_types.push(result_type);
554 }
555
556 let type_pair = (left_type, right_type);
558 *feedback.type_counts.entry(type_pair).or_insert(0) += 1;
559 feedback.total_count += 1;
560 self.total_samples += 1;
561 }
562
563 pub fn record_variable_assignment(&mut self, var_name: &str, new_type: std::any::TypeId) {
565 let feedback = self
566 .variable_types
567 .entry(var_name.to_string())
568 .or_insert_with(|| VariableTypeFeedback {
569 assigned_types: smallvec![],
570 transitions: HashMap::new(),
571 dominant_type: None,
572 stability_score: 1.0,
573 });
574
575 if let Some(prev_type) = feedback.dominant_type {
577 if prev_type != new_type {
578 feedback
579 .transitions
580 .entry(prev_type)
581 .or_default()
582 .entry(new_type)
583 .and_modify(|count| *count += 1)
584 .or_insert(1);
585 }
586 }
587
588 if !feedback.assigned_types.contains(&new_type) {
590 feedback.assigned_types.push(new_type);
591 }
592
593 feedback.dominant_type = Some(new_type);
595
596 feedback.stability_score = if feedback.assigned_types.len() == 1 {
598 1.0 } else {
600 1.0 / f64::from(u32::try_from(feedback.assigned_types.len()).unwrap_or(u32::MAX))
601 };
603 }
604
605 pub fn record_function_call(
607 &mut self,
608 site_id: usize,
609 func_name: &str,
610 args: &[Value],
611 result: &Value,
612 ) {
613 let arg_types: Vec<std::any::TypeId> = args.iter().map(Value::type_id).collect();
614 let return_type = result.type_id();
615
616 let feedback = self
617 .call_sites
618 .entry(site_id)
619 .or_insert_with(|| CallSiteFeedback {
620 arg_type_patterns: smallvec![],
621 return_types: smallvec![],
622 call_count: 0,
623 called_functions: HashMap::new(),
624 });
625
626 if !feedback
628 .arg_type_patterns
629 .iter()
630 .any(|pattern| pattern == &arg_types)
631 {
632 feedback.arg_type_patterns.push(arg_types);
633 }
634
635 if !feedback.return_types.contains(&return_type) {
637 feedback.return_types.push(return_type);
638 }
639
640 *feedback
642 .called_functions
643 .entry(func_name.to_string())
644 .or_insert(0) += 1;
645 feedback.call_count += 1;
646 }
647
648 pub fn get_specialization_candidates(&self) -> Vec<SpecializationCandidate> {
652 let mut candidates = Vec::new();
653
654 for (&site_id, feedback) in &self.operation_sites {
656 if feedback.left_types.len() == 1
657 && feedback.right_types.len() == 1
658 && feedback.total_count > 10
659 {
660 candidates.push(SpecializationCandidate {
661 kind: SpecializationKind::BinaryOperation {
662 site_id,
663 left_type: feedback.left_types[0],
664 right_type: feedback.right_types[0],
665 },
666 confidence: 1.0,
667 benefit_score: f64::from(feedback.total_count),
668 });
669 }
670 }
671
672 for (var_name, feedback) in &self.variable_types {
674 if feedback.stability_score > 0.8 && feedback.dominant_type.is_some() {
675 candidates.push(SpecializationCandidate {
676 kind: SpecializationKind::Variable {
677 name: var_name.clone(),
678 #[allow(clippy::expect_used)] specialized_type: feedback.dominant_type.expect("Dominant type should exist for stable variables"),
680 },
681 confidence: feedback.stability_score,
682 benefit_score: feedback.stability_score * 100.0,
683 });
684 }
685 }
686
687 for (&site_id, feedback) in &self.call_sites {
689 if feedback.arg_type_patterns.len() == 1
690 && feedback.return_types.len() == 1
691 && feedback.call_count > 5
692 {
693 candidates.push(SpecializationCandidate {
694 kind: SpecializationKind::FunctionCall {
695 site_id,
696 arg_types: feedback.arg_type_patterns[0].clone(),
697 return_type: feedback.return_types[0],
698 },
699 confidence: 1.0,
700 benefit_score: f64::from(feedback.call_count * 10),
701 });
702 }
703 }
704
705 candidates.sort_by(|a, b| {
707 b.benefit_score
708 .partial_cmp(&a.benefit_score)
709 .unwrap_or(std::cmp::Ordering::Equal)
710 });
711 candidates
712 }
713
714 pub fn get_statistics(&self) -> TypeFeedbackStats {
716 let monomorphic_sites = self
717 .operation_sites
718 .values()
719 .filter(|f| f.left_types.len() == 1 && f.right_types.len() == 1)
720 .count();
721
722 let stable_variables = self
723 .variable_types
724 .values()
725 .filter(|f| f.stability_score > 0.8)
726 .count();
727
728 let monomorphic_calls = self
729 .call_sites
730 .values()
731 .filter(|f| f.arg_type_patterns.len() == 1)
732 .count();
733
734 TypeFeedbackStats {
735 total_operation_sites: self.operation_sites.len(),
736 monomorphic_operation_sites: monomorphic_sites,
737 total_variables: self.variable_types.len(),
738 stable_variables,
739 total_call_sites: self.call_sites.len(),
740 monomorphic_call_sites: monomorphic_calls,
741 total_samples: self.total_samples,
742 }
743 }
744}
745
746impl Default for TypeFeedback {
747 fn default() -> Self {
748 Self::new()
749 }
750}
751
752#[derive(Clone, Debug)]
754#[allow(dead_code)] pub struct SpecializationCandidate {
756 kind: SpecializationKind,
758 confidence: f64,
760 benefit_score: f64,
762}
763
764#[derive(Clone, Debug)]
765pub enum SpecializationKind {
766 BinaryOperation {
767 site_id: usize,
768 left_type: std::any::TypeId,
769 right_type: std::any::TypeId,
770 },
771 Variable {
772 name: String,
773 specialized_type: std::any::TypeId,
774 },
775 FunctionCall {
776 site_id: usize,
777 arg_types: Vec<std::any::TypeId>,
778 return_type: std::any::TypeId,
779 },
780}
781
782#[derive(Clone, Debug)]
784pub struct TypeFeedbackStats {
785 pub total_operation_sites: usize,
787 pub monomorphic_operation_sites: usize,
789 pub total_variables: usize,
791 pub stable_variables: usize,
793 pub total_call_sites: usize,
795 pub monomorphic_call_sites: usize,
797 pub total_samples: u64,
799}
800
801pub use super::gc_impl::{ConservativeGC, GCInfo, GCObject, GCStats};
804
805pub use super::compilation::{
808 DirectThreadedInterpreter, InstructionResult, InterpreterState, ThreadedInstruction,
809};
810
811impl Interpreter {
812 pub fn new() -> Self {
829 let global_env = crate::runtime::builtin_init::init_global_environment();
831
832 Self {
833 stack: Vec::with_capacity(1024), env_stack: vec![global_env], frames: Vec::new(),
836 execution_counts: HashMap::new(),
837 field_caches: HashMap::new(),
838 type_feedback: TypeFeedback::new(),
839 gc: ConservativeGC::new(),
840 error_scopes: Vec::new(),
841 stdout_buffer: Vec::new(), }
843 }
844
845 pub fn eval_expr(&mut self, expr: &Expr) -> Result<Value, InterpreterError> {
882 self.eval_expr_kind(&expr.kind)
883 }
884
885 fn eval_expr_kind(&mut self, expr_kind: &ExprKind) -> Result<Value, InterpreterError> {
903 match expr_kind {
904 ExprKind::Literal(_) | ExprKind::Identifier(_) => self.eval_simple_expr(expr_kind),
906
907 ExprKind::Binary { .. }
909 | ExprKind::Unary { .. }
910 | ExprKind::Call { .. }
911 | ExprKind::MethodCall { .. }
912 | ExprKind::DataFrameOperation { .. }
913 | ExprKind::IndexAccess { .. }
914 | ExprKind::FieldAccess { .. }
915 | ExprKind::TypeCast { .. } => self.eval_operation_expr(expr_kind),
916
917 ExprKind::Function { .. } | ExprKind::Lambda { .. } => {
919 self.eval_function_expr(expr_kind)
920 }
921
922 kind if Self::is_control_flow_expr(kind) => self.eval_control_flow_expr(kind),
924
925 kind if Self::is_data_structure_expr(kind) => self.eval_data_structure_expr(kind),
927
928 kind if Self::is_assignment_expr(kind) => self.eval_assignment_expr(kind),
930
931 _ => self.eval_misc_expr(expr_kind),
933 }
934 }
935
936 fn eval_simple_expr(&mut self, expr_kind: &ExprKind) -> Result<Value, InterpreterError> {
941 match expr_kind {
942 ExprKind::Literal(lit) => Ok(eval_literal::eval_literal(lit)),
943 ExprKind::Identifier(name) => self.lookup_variable(name),
944 _ => unreachable!("eval_simple_expr called with non-simple expression"),
945 }
946 }
947
948 fn eval_operation_expr(&mut self, expr_kind: &ExprKind) -> Result<Value, InterpreterError> {
951 match expr_kind {
952 ExprKind::Binary { left, op, right } => self.eval_binary_expr(left, *op, right),
953 ExprKind::Unary { op, operand } => self.eval_unary_expr(*op, operand),
954 ExprKind::Call { func, args } => self.eval_function_call(func, args),
955 ExprKind::MethodCall {
956 receiver,
957 method,
958 args,
959 } => self.eval_method_call(receiver, method, args),
960 ExprKind::DataFrameOperation { source, operation } => {
961 self.eval_dataframe_operation(source, operation)
962 }
963 ExprKind::IndexAccess { object, index } => self.eval_index_access(object, index),
964 ExprKind::FieldAccess { object, field } => self.eval_field_access(object, field),
965 ExprKind::TypeCast { expr, target_type } => self.eval_type_cast(expr, target_type),
966 _ => unreachable!("eval_operation_expr called with non-operation expression"),
967 }
968 }
969
970 fn eval_function_expr(&mut self, expr_kind: &ExprKind) -> Result<Value, InterpreterError> {
973 match expr_kind {
974 ExprKind::Function {
975 name, params, body, ..
976 } => self.eval_function(name, params, body),
977 ExprKind::Lambda { params, body } => self.eval_lambda(params, body),
978 _ => unreachable!("eval_function_expr called with non-function expression"),
979 }
980 }
981
982 fn is_type_definition(expr_kind: &ExprKind) -> bool {
985 matches!(
986 expr_kind,
987 ExprKind::Actor { .. }
988 | ExprKind::Enum { .. }
989 | ExprKind::Struct { .. }
990 | ExprKind::TupleStruct { .. }
991 | ExprKind::Class { .. }
992 | ExprKind::Impl { .. }
993 )
994 }
995
996 fn is_actor_operation(expr_kind: &ExprKind) -> bool {
999 matches!(
1000 expr_kind,
1001 ExprKind::Spawn { .. } | ExprKind::ActorSend { .. } | ExprKind::ActorQuery { .. }
1002 )
1003 }
1004
1005 fn is_special_form(expr_kind: &ExprKind) -> bool {
1008 matches!(
1009 expr_kind,
1010 ExprKind::None
1011 | ExprKind::Some { .. }
1012 | ExprKind::Set(_)
1013 | ExprKind::LetPattern { .. }
1014 | ExprKind::StringInterpolation { .. }
1015 | ExprKind::QualifiedName { .. }
1016 | ExprKind::ObjectLiteral { .. }
1017 | ExprKind::StructLiteral { .. }
1018 )
1019 }
1020
1021 fn eval_type_definition(&mut self, expr_kind: &ExprKind) -> Result<Value, InterpreterError> {
1024 match expr_kind {
1025 ExprKind::Actor {
1026 name,
1027 state,
1028 handlers,
1029 } => self.eval_actor_definition(name, state, handlers),
1030 ExprKind::Enum {
1031 name,
1032 type_params,
1033 variants,
1034 is_pub,
1035 } => self.eval_enum_definition(name, type_params, variants, *is_pub),
1036 ExprKind::Struct {
1037 name,
1038 type_params,
1039 fields,
1040 derives: _,
1041 is_pub,
1042 } => self.eval_struct_definition(name, type_params, fields, *is_pub),
1043 ExprKind::TupleStruct { .. } => {
1044 Ok(Value::Nil)
1046 }
1047 ExprKind::Class {
1048 name,
1049 type_params,
1050 superclass,
1051 traits,
1052 fields,
1053 constructors,
1054 methods,
1055 constants,
1056 properties: _,
1057 derives,
1058 is_pub,
1059 is_sealed: _,
1060 is_abstract: _,
1061 decorators: _,
1062 } => self.eval_class_definition(
1063 name,
1064 type_params,
1065 superclass.as_ref(),
1066 traits,
1067 fields,
1068 constructors,
1069 methods,
1070 constants,
1071 derives,
1072 *is_pub,
1073 ),
1074 ExprKind::Impl {
1075 trait_name: _,
1076 for_type,
1077 methods,
1078 ..
1079 } => self.eval_impl_block(for_type, methods),
1080 _ => unreachable!("eval_type_definition called with non-type-definition"),
1081 }
1082 }
1083
1084 fn eval_actor_operation(&mut self, expr_kind: &ExprKind) -> Result<Value, InterpreterError> {
1087 match expr_kind {
1088 ExprKind::Spawn { actor } => self.eval_spawn_actor(actor),
1089 ExprKind::ActorSend { actor, message } => self.eval_actor_send(actor, message),
1090 ExprKind::ActorQuery { actor, message } => self.eval_actor_query(actor, message),
1091 _ => unreachable!("eval_actor_operation called with non-actor-operation"),
1092 }
1093 }
1094
1095 fn eval_special_form(&mut self, expr_kind: &ExprKind) -> Result<Value, InterpreterError> {
1098 match expr_kind {
1099 ExprKind::None => Ok(Value::EnumVariant {
1100 enum_name: "Option".to_string(),
1101 variant_name: "None".to_string(),
1102 data: None,
1103 }),
1104 ExprKind::Some { value } => Ok(Value::EnumVariant {
1105 enum_name: "Option".to_string(),
1106 variant_name: "Some".to_string(),
1107 data: Some(vec![self.eval_expr(value)?]),
1108 }),
1109 ExprKind::Set(statements) => {
1110 let mut result = Value::Nil;
1111 for stmt in statements {
1112 result = self.eval_expr(stmt)?;
1113 }
1114 Ok(result)
1115 }
1116 ExprKind::LetPattern {
1117 pattern,
1118 value,
1119 body,
1120 ..
1121 } => self.eval_let_pattern(pattern, value, body),
1122 ExprKind::StringInterpolation { parts } => self.eval_string_interpolation(parts),
1123 ExprKind::QualifiedName { module, name } => self.eval_qualified_name(module, name),
1124 ExprKind::ObjectLiteral { fields } => self.eval_object_literal(fields),
1125 ExprKind::StructLiteral {
1126 name,
1127 fields,
1128 base: _,
1129 } => self.eval_struct_literal(name, fields),
1130 _ => unreachable!("eval_special_form called with non-special-form"),
1131 }
1132 }
1133
1134 fn eval_misc_expr(&mut self, expr_kind: &ExprKind) -> Result<Value, InterpreterError> {
1137 if Self::is_type_definition(expr_kind) {
1138 return self.eval_type_definition(expr_kind);
1139 }
1140 if Self::is_actor_operation(expr_kind) {
1141 return self.eval_actor_operation(expr_kind);
1142 }
1143 if Self::is_special_form(expr_kind) {
1144 return self.eval_special_form(expr_kind);
1145 }
1146
1147 match expr_kind {
1150 ExprKind::ImportAll { module, alias } => {
1151 let parts: Vec<&str> = module.split("::").collect();
1154
1155 let mut current_value: Option<Value> = None;
1157 if let Some(first_part) = parts.first() {
1158 if let Some(global_env) = self.env_stack.first() {
1160 if let Some(root) = global_env.get(*first_part) {
1161 current_value = Some(root.clone());
1162
1163 for &part in parts.iter().skip(1) {
1165 if let Some(Value::Object(obj)) = current_value {
1166 if let Some(next_val) = obj.get(part) {
1167 current_value = Some(next_val.clone());
1168 } else {
1169 current_value = None;
1170 break;
1171 }
1172 } else {
1173 current_value = None;
1174 break;
1175 }
1176 }
1177 }
1178 }
1179 }
1180
1181 if let Some(value) = current_value {
1183 let import_name = if alias == "*" {
1185 return Ok(Value::Nil);
1187 } else if !alias.is_empty() && alias != "*" {
1188 alias.clone()
1189 } else {
1190 parts.last().unwrap_or(&"").to_string()
1191 };
1192
1193 if let Some(global_env) = self.env_stack.first_mut() {
1196 global_env.insert(import_name, value);
1197 }
1198 }
1199
1200 Ok(Value::Nil)
1201 }
1202 ExprKind::Import { .. } | ExprKind::ImportDefault { .. } => {
1203 Ok(Value::Nil)
1205 }
1206 ExprKind::Macro { name, args } => {
1208 if name == "vec" {
1209 let mut elements = Vec::new();
1211 for arg in args {
1212 let value = self.eval_expr(arg)?;
1213 elements.push(value);
1214 }
1215 Ok(Value::Array(elements.into()))
1216 } else if name == "println" {
1217 if args.is_empty() {
1220 println!();
1221 } else if args.len() == 1 {
1222 let value = self.eval_expr(&args[0])?;
1224 println!("{}", value);
1225 } else {
1226 let format_val = self.eval_expr(&args[0])?;
1228 let format_str = format_val.to_string();
1229
1230 let mut values = Vec::new();
1231 for arg in &args[1..] {
1232 values.push(self.eval_expr(arg)?);
1233 }
1234
1235 let mut result = String::new();
1237 let mut chars = format_str.chars().peekable();
1238 let mut value_index = 0;
1239
1240 while let Some(ch) = chars.next() {
1241 if ch == '{' {
1242 if chars.peek() == Some(&':') {
1243 chars.next();
1244 if chars.peek() == Some(&'?') {
1245 chars.next();
1246 if chars.peek() == Some(&'}') {
1247 chars.next();
1248 if value_index < values.len() {
1249 result.push_str(&format!("{:?}", values[value_index]));
1250 value_index += 1;
1251 } else {
1252 result.push_str("{:?}");
1253 }
1254 } else {
1255 result.push_str("{:?");
1256 }
1257 } else {
1258 result.push_str("{:");
1259 }
1260 } else if chars.peek() == Some(&'}') {
1261 chars.next();
1262 if value_index < values.len() {
1263 result.push_str(&values[value_index].to_string());
1264 value_index += 1;
1265 } else {
1266 result.push_str("{}");
1267 }
1268 } else {
1269 result.push(ch);
1270 }
1271 } else {
1272 result.push(ch);
1273 }
1274 }
1275
1276 println!("{}", result);
1277 }
1278 Ok(Value::Nil)
1279 } else if name == "format" {
1280 if args.is_empty() {
1282 return Err(InterpreterError::RuntimeError(
1283 "format!() requires at least one argument".to_string()
1284 ));
1285 }
1286
1287 let format_val = self.eval_expr(&args[0])?;
1289 let format_str = format_val.to_string();
1290
1291 let mut values = Vec::new();
1293 for arg in &args[1..] {
1294 values.push(self.eval_expr(arg)?);
1295 }
1296
1297 let mut result = String::new();
1299 let mut chars = format_str.chars().peekable();
1300 let mut value_index = 0;
1301
1302 while let Some(ch) = chars.next() {
1303 if ch == '{' {
1304 if chars.peek() == Some(&':') {
1306 chars.next(); if chars.peek() == Some(&'?') {
1308 chars.next(); if chars.peek() == Some(&'}') {
1310 chars.next(); if value_index < values.len() {
1312 result.push_str(&format!("{:?}", values[value_index]));
1313 value_index += 1;
1314 } else {
1315 result.push_str("{:?}"); }
1317 } else {
1318 result.push_str("{:?"); }
1320 } else {
1321 result.push_str("{:"); }
1323 } else if chars.peek() == Some(&'}') {
1324 chars.next(); if value_index < values.len() {
1326 result.push_str(&values[value_index].to_string());
1327 value_index += 1;
1328 } else {
1329 result.push_str("{}"); }
1331 } else {
1332 result.push(ch);
1333 }
1334 } else {
1335 result.push(ch);
1336 }
1337 }
1338
1339 Ok(Value::from_string(result))
1340 } else {
1341 Err(InterpreterError::RuntimeError(format!(
1343 "Macro '{}!' not yet implemented", name
1344 )))
1345 }
1346 }
1347 ExprKind::MacroInvocation { name, args } => {
1351 if name == "vec" {
1352 let mut elements = Vec::new();
1353 for arg in args {
1354 let value = self.eval_expr(arg)?;
1355 elements.push(value);
1356 }
1357 Ok(Value::Array(elements.into()))
1358 } else if name == "println" {
1359 if args.is_empty() {
1362 println!();
1363 } else if args.len() == 1 {
1364 let value = self.eval_expr(&args[0])?;
1366 println!("{}", value);
1367 } else {
1368 let format_val = self.eval_expr(&args[0])?;
1370 let format_str = format_val.to_string();
1371
1372 let mut values = Vec::new();
1373 for arg in &args[1..] {
1374 values.push(self.eval_expr(arg)?);
1375 }
1376
1377 let mut result = String::new();
1379 let mut chars = format_str.chars().peekable();
1380 let mut value_index = 0;
1381
1382 while let Some(ch) = chars.next() {
1383 if ch == '{' {
1384 if chars.peek() == Some(&':') {
1385 chars.next();
1386 if chars.peek() == Some(&'?') {
1387 chars.next();
1388 if chars.peek() == Some(&'}') {
1389 chars.next();
1390 if value_index < values.len() {
1391 result.push_str(&format!("{:?}", values[value_index]));
1392 value_index += 1;
1393 } else {
1394 result.push_str("{:?}");
1395 }
1396 } else {
1397 result.push_str("{:?");
1398 }
1399 } else {
1400 result.push_str("{:");
1401 }
1402 } else if chars.peek() == Some(&'}') {
1403 chars.next();
1404 if value_index < values.len() {
1405 result.push_str(&values[value_index].to_string());
1406 value_index += 1;
1407 } else {
1408 result.push_str("{}");
1409 }
1410 } else {
1411 result.push(ch);
1412 }
1413 } else {
1414 result.push(ch);
1415 }
1416 }
1417
1418 println!("{}", result);
1419 }
1420 Ok(Value::Nil)
1421 } else if name == "format" {
1422 if args.is_empty() {
1424 return Err(InterpreterError::RuntimeError(
1425 "format!() requires at least one argument".to_string()
1426 ));
1427 }
1428
1429 let format_val = self.eval_expr(&args[0])?;
1431 let format_str = format_val.to_string();
1432
1433 let mut values = Vec::new();
1435 for arg in &args[1..] {
1436 values.push(self.eval_expr(arg)?);
1437 }
1438
1439 let mut result = String::new();
1441 let mut chars = format_str.chars().peekable();
1442 let mut value_index = 0;
1443
1444 while let Some(ch) = chars.next() {
1445 if ch == '{' {
1446 if chars.peek() == Some(&':') {
1448 chars.next(); if chars.peek() == Some(&'?') {
1450 chars.next(); if chars.peek() == Some(&'}') {
1452 chars.next(); if value_index < values.len() {
1454 result.push_str(&format!("{:?}", values[value_index]));
1455 value_index += 1;
1456 } else {
1457 result.push_str("{:?}"); }
1459 } else {
1460 result.push_str("{:?"); }
1462 } else {
1463 result.push_str("{:"); }
1465 } else if chars.peek() == Some(&'}') {
1466 chars.next(); if value_index < values.len() {
1468 result.push_str(&values[value_index].to_string());
1469 value_index += 1;
1470 } else {
1471 result.push_str("{}"); }
1473 } else {
1474 result.push(ch);
1475 }
1476 } else {
1477 result.push(ch);
1478 }
1479 }
1480
1481 Ok(Value::from_string(result))
1482 } else {
1483 Err(InterpreterError::RuntimeError(format!(
1484 "Macro '{}!' not yet implemented", name
1485 )))
1486 }
1487 }
1488 _ => {
1489 Err(InterpreterError::RuntimeError(format!(
1491 "Expression type not yet implemented: {expr_kind:?}"
1492 )))
1493 }
1494 }
1495 }
1496
1497 fn eval_spawn_actor(&mut self, actor: &Expr) -> Result<Value, InterpreterError> {
1500 if let ExprKind::Identifier(name) = &actor.kind {
1502 if let Ok(def_value) = self.lookup_variable(name) {
1503 if let Value::Object(ref obj) = def_value {
1504 if let Some(Value::String(type_str)) = obj.get("__type") {
1505 if type_str.as_ref() == "Actor" {
1506 let constructor_marker =
1507 Value::from_string(format!("__actor_constructor__:{}", name));
1508 return self.call_function(constructor_marker, &[]);
1509 }
1510 }
1511 }
1512 }
1513 }
1514
1515 if let ExprKind::Call { func, args } = &actor.kind {
1517 if let ExprKind::Identifier(name) = &func.kind {
1518 if let Ok(def_value) = self.lookup_variable(name) {
1519 if let Value::Object(ref obj) = def_value {
1520 if let Some(Value::String(type_str)) = obj.get("__type") {
1521 if type_str.as_ref() == "Actor" {
1522 let constructor_marker =
1523 Value::from_string(format!("__actor_constructor__:{}", name));
1524 let arg_vals: Result<Vec<Value>, _> =
1525 args.iter().map(|arg| self.eval_expr(arg)).collect();
1526 let arg_vals = arg_vals?;
1527 return self.call_function(constructor_marker, &arg_vals);
1528 }
1529 }
1530 }
1531 }
1532 }
1533 }
1534
1535 let actor_value = self.eval_expr(actor)?;
1537 Ok(actor_value)
1538 }
1539
1540 fn eval_actor_send(&mut self, actor: &Expr, message: &Expr) -> Result<Value, InterpreterError> {
1543 let actor_value = self.eval_expr(actor)?;
1544 let message_value = self.eval_message_expr(message)?;
1545
1546 if let Value::ObjectMut(cell_rc) = actor_value {
1547 self.process_actor_message_sync_mut(&cell_rc, &message_value)?;
1548 Ok(Value::Nil)
1549 } else {
1550 Err(InterpreterError::RuntimeError(format!(
1551 "ActorSend requires an actor instance, got {}",
1552 actor_value.type_name()
1553 )))
1554 }
1555 }
1556
1557 fn eval_actor_query(
1560 &mut self,
1561 actor: &Expr,
1562 message: &Expr,
1563 ) -> Result<Value, InterpreterError> {
1564 let actor_value = self.eval_expr(actor)?;
1565 let message_value = self.eval_message_expr(message)?;
1566
1567 if let Value::ObjectMut(cell_rc) = actor_value {
1568 self.process_actor_message_sync_mut(&cell_rc, &message_value)
1569 } else {
1570 Err(InterpreterError::RuntimeError(format!(
1571 "ActorQuery requires an actor instance, got {}",
1572 actor_value.type_name()
1573 )))
1574 }
1575 }
1576
1577 fn is_control_flow_expr(expr_kind: &ExprKind) -> bool {
1578 eval_expr::is_control_flow_expr(expr_kind)
1579 }
1580
1581 fn is_data_structure_expr(expr_kind: &ExprKind) -> bool {
1582 eval_expr::is_data_structure_expr(expr_kind)
1583 }
1584
1585 fn is_assignment_expr(expr_kind: &ExprKind) -> bool {
1586 eval_expr::is_assignment_expr(expr_kind)
1587 }
1588
1589 fn eval_control_flow_expr(&mut self, expr_kind: &ExprKind) -> Result<Value, InterpreterError> {
1590 match expr_kind {
1591 ExprKind::If {
1592 condition,
1593 then_branch,
1594 else_branch,
1595 } => self.eval_if_expr(condition, then_branch, else_branch.as_deref()),
1596 ExprKind::Ternary {
1597 condition,
1598 true_expr,
1599 false_expr,
1600 } => {
1601 let cond_value = self.eval_expr(condition)?;
1603 if cond_value.is_truthy() {
1605 self.eval_expr(true_expr)
1606 } else {
1607 self.eval_expr(false_expr)
1608 }
1609 }
1610 ExprKind::Let {
1611 name, value, body, ..
1612 } => self.eval_let_expr(name, value, body),
1613 ExprKind::For {
1614 label,
1615 var,
1616 pattern,
1617 iter,
1618 body,
1619 } => self.eval_for_loop(label.as_ref(), var, pattern.as_ref(), iter, body),
1620 ExprKind::While {
1621 label,
1622 condition,
1623 body,
1624 } => self.eval_while_loop(label.as_ref(), condition, body),
1625 ExprKind::Loop { label, body } => self.eval_loop(label.as_ref(), body),
1626 ExprKind::Match { expr, arms } => self.eval_match(expr, arms),
1627 ExprKind::Break { label, value } => {
1628 let break_val = if let Some(expr) = value {
1630 self.eval_expr(expr)?
1631 } else {
1632 Value::Nil
1633 };
1634 Err(InterpreterError::Break(label.clone(), break_val))
1635 }
1636 ExprKind::Continue { label } => Err(InterpreterError::Continue(label.clone())),
1637 ExprKind::Return { value } => self.eval_return_expr(value.as_deref()),
1638 ExprKind::TryCatch {
1639 try_block,
1640 catch_clauses,
1641 finally_block,
1642 } => crate::runtime::eval_try_catch::eval_try_catch(
1643 self,
1644 try_block,
1645 catch_clauses,
1646 finally_block.as_deref(),
1647 ),
1648 ExprKind::Throw { expr } => crate::runtime::eval_try_catch::eval_throw(self, expr),
1649 _ => unreachable!("Non-control-flow expression passed to eval_control_flow_expr"),
1650 }
1651 }
1652
1653 fn eval_data_structure_expr(
1654 &mut self,
1655 expr_kind: &ExprKind,
1656 ) -> Result<Value, InterpreterError> {
1657 match expr_kind {
1658 ExprKind::List(elements) => self.eval_list_expr(elements),
1659 ExprKind::Block(statements) => self.eval_block_expr(statements),
1660 ExprKind::Tuple(elements) => self.eval_tuple_expr(elements),
1661 ExprKind::Range {
1662 start,
1663 end,
1664 inclusive,
1665 } => self.eval_range_expr(start, end, *inclusive),
1666 ExprKind::ArrayInit { value, size } => self.eval_array_init_expr(value, size),
1667 ExprKind::DataFrame { columns } => self.eval_dataframe_literal(columns),
1668 _ => unreachable!("Non-data-structure expression passed to eval_data_structure_expr"),
1669 }
1670 }
1671
1672 fn eval_assignment_expr(&mut self, expr_kind: &ExprKind) -> Result<Value, InterpreterError> {
1673 match expr_kind {
1674 ExprKind::Assign { target, value } => self.eval_assign(target, value),
1675 ExprKind::CompoundAssign { target, op, value } => {
1676 self.eval_compound_assign(target, *op, value)
1677 }
1678 _ => unreachable!("Non-assignment expression passed to eval_assignment_expr"),
1679 }
1680 }
1681
1682 fn eval_index_access(
1683 &mut self,
1684 object: &Expr,
1685 index: &Expr,
1686 ) -> Result<Value, InterpreterError> {
1687 let object_value = self.eval_expr(object)?;
1688 let index_value = self.eval_expr(index)?;
1689
1690 match (&object_value, &index_value) {
1691 (Value::Array(ref array), Value::Integer(idx)) => Self::index_array(array, *idx),
1692 (Value::String(ref s), Value::Integer(idx)) => Self::index_string(s, *idx),
1693 (Value::Tuple(ref tuple), Value::Integer(idx)) => Self::index_tuple(tuple, *idx),
1694 (Value::Object(ref fields), Value::String(ref key)) => Self::index_object(fields, key),
1695 (Value::ObjectMut(ref cell), Value::String(ref key)) => {
1696 Self::index_object_mut(cell, key)
1697 }
1698 (Value::DataFrame { columns }, Value::Integer(idx)) => {
1699 Self::index_dataframe_row(columns, *idx)
1700 }
1701 (Value::DataFrame { columns }, Value::String(ref col_name)) => {
1702 Self::index_dataframe_column(columns, col_name)
1703 }
1704 _ => Err(InterpreterError::RuntimeError(format!(
1705 "Cannot index {} with {}",
1706 object_value.type_name(),
1707 index_value.type_name()
1708 ))),
1709 }
1710 }
1711
1712 fn index_array(array: &[Value], idx: i64) -> Result<Value, InterpreterError> {
1715 let len = array.len() as i64;
1716 let actual_index = if idx < 0 {
1717 len + idx
1720 } else {
1721 idx
1722 };
1723
1724 if actual_index < 0 || actual_index >= len {
1726 return Err(InterpreterError::RuntimeError(format!(
1727 "Index {idx} out of bounds for array of length {len}"
1728 )));
1729 }
1730
1731 #[allow(clippy::cast_sign_loss)] Ok(array[actual_index as usize].clone())
1733 }
1734
1735 fn index_string(s: &str, idx: i64) -> Result<Value, InterpreterError> {
1738 let chars: Vec<char> = s.chars().collect();
1739 let len = chars.len() as i64;
1740 let actual_index = if idx < 0 {
1741 len + idx
1743 } else {
1744 idx
1745 };
1746
1747 if actual_index < 0 || actual_index >= len {
1749 return Err(InterpreterError::RuntimeError(format!(
1750 "Index {idx} out of bounds for string of length {len}"
1751 )));
1752 }
1753
1754 #[allow(clippy::cast_sign_loss)] Ok(Value::from_string(chars[actual_index as usize].to_string()))
1756 }
1757
1758 fn index_tuple(tuple: &[Value], idx: i64) -> Result<Value, InterpreterError> {
1761 let len = tuple.len() as i64;
1762 let actual_index = if idx < 0 {
1763 len + idx
1765 } else {
1766 idx
1767 };
1768
1769 if actual_index < 0 || actual_index >= len {
1771 return Err(InterpreterError::RuntimeError(format!(
1772 "Index {idx} out of bounds for tuple of length {len}"
1773 )));
1774 }
1775
1776 #[allow(clippy::cast_sign_loss)] Ok(tuple[actual_index as usize].clone())
1778 }
1779
1780 fn index_object(fields: &HashMap<String, Value>, key: &str) -> Result<Value, InterpreterError> {
1782 fields.get(key).cloned().ok_or_else(|| {
1783 InterpreterError::RuntimeError(format!("Key '{key}' not found in object"))
1784 })
1785 }
1786
1787 fn index_object_mut(
1789 cell: &Arc<std::sync::Mutex<HashMap<String, Value>>>,
1790 key: &str,
1791 ) -> Result<Value, InterpreterError> {
1792 cell.lock().unwrap().get(key).cloned().ok_or_else(|| {
1793 InterpreterError::RuntimeError(format!("Key '{key}' not found in object"))
1794 })
1795 }
1796
1797 fn index_dataframe_row(
1800 columns: &[DataFrameColumn],
1801 row_idx: i64,
1802 ) -> Result<Value, InterpreterError> {
1803 if columns.is_empty() {
1804 return Err(InterpreterError::RuntimeError(
1805 "Cannot index empty DataFrame".to_string(),
1806 ));
1807 }
1808
1809 let index = row_idx as usize;
1810 let num_rows = columns[0].values.len();
1811
1812 if index >= num_rows {
1813 return Err(InterpreterError::RuntimeError(format!(
1814 "Row index {index} out of bounds for DataFrame with {num_rows} rows"
1815 )));
1816 }
1817
1818 let mut row = HashMap::new();
1820 for col in columns {
1821 row.insert(col.name.clone(), col.values[index].clone());
1822 }
1823
1824 Ok(Value::Object(Arc::new(row)))
1825 }
1826
1827 fn index_dataframe_column(
1830 columns: &[DataFrameColumn],
1831 col_name: &str,
1832 ) -> Result<Value, InterpreterError> {
1833 columns
1834 .iter()
1835 .find(|col| col.name == col_name)
1836 .map(|col| Value::Array(Arc::from(col.values.clone())))
1837 .ok_or_else(|| {
1838 InterpreterError::RuntimeError(format!("Column '{col_name}' not found in DataFrame"))
1839 })
1840 }
1841
1842 fn check_field_visibility(
1845 &self,
1846 struct_name: &str,
1847 field: &str,
1848 ) -> Result<(), InterpreterError> {
1849 let struct_type = self.lookup_variable(struct_name).ok();
1851 if let Some(Value::Object(struct_obj)) = struct_type {
1852 if let Some(Value::Object(fields)) = struct_obj.get("__fields") {
1853 if let Some(Value::Object(field_info)) = fields.get(field) {
1854 if let Some(Value::String(visibility)) = field_info.get("visibility") {
1855 if visibility.as_ref() == "private" {
1856 return Err(InterpreterError::RuntimeError(format!(
1857 "Field '{}' is private and cannot be accessed outside the struct",
1858 field
1859 )));
1860 }
1861 }
1862 }
1863 }
1864 }
1865 Ok(())
1866 }
1867
1868 fn eval_field_access(&mut self, object: &Expr, field: &str) -> Result<Value, InterpreterError> {
1869 let object_value = self.eval_expr(object)?;
1870
1871 match object_value {
1872 Value::Object(ref object_map) => {
1873 if let Some(Value::String(type_str)) = object_map.get("__type") {
1875 if type_str.as_ref() == "Enum" {
1876 let enum_name = if let ExprKind::Identifier(name) = &object.kind {
1878 name.clone()
1879 } else {
1880 "UnknownEnum".to_string()
1881 };
1882 return Ok(Value::EnumVariant {
1884 enum_name,
1885 variant_name: field.to_string(),
1886 data: None, });
1888 }
1889 }
1890 self.access_object_field(object_map, field)
1891 }
1892 Value::ObjectMut(ref cell) => self.access_object_mut_field(cell, field),
1893 Value::Struct { ref name, ref fields } => {
1894 fields.get(field).cloned().ok_or_else(|| {
1896 InterpreterError::RuntimeError(format!(
1897 "Field '{field}' not found in struct {name}"
1898 ))
1899 })
1900 }
1901 Value::Class {
1902 ref class_name,
1903 ref fields,
1904 ..
1905 } => {
1906 let fields_read = fields.read().unwrap();
1908 fields_read.get(field).cloned().ok_or_else(|| {
1909 InterpreterError::RuntimeError(format!(
1910 "Field '{field}' not found in class {class_name}"
1911 ))
1912 })
1913 }
1914 Value::Tuple(ref elements) => {
1915 crate::runtime::eval_data_structures::eval_tuple_field_access(elements, field)
1917 }
1918 Value::DataFrame { ref columns } => {
1919 Self::index_dataframe_column(columns, field)
1921 }
1922 _ => Err(InterpreterError::RuntimeError(format!(
1923 "Cannot access field '{}' on type {}",
1924 field,
1925 object_value.type_name()
1926 ))),
1927 }
1928 }
1929
1930 fn access_object_field(
1932 &self,
1933 object_map: &HashMap<String, Value>,
1934 field: &str,
1935 ) -> Result<Value, InterpreterError> {
1936 if let Some(constructor) = Self::check_constructor_access(object_map, field) {
1938 return Ok(constructor);
1939 }
1940
1941 if let Some(actor_field) = Self::check_actor_field_access(object_map, field)? {
1943 return Ok(actor_field);
1944 }
1945
1946 self.check_struct_visibility(object_map, field)?;
1948
1949 Self::get_object_field(object_map, field)
1951 }
1952
1953 fn access_object_mut_field(
1955 &self,
1956 cell: &Arc<std::sync::Mutex<HashMap<String, Value>>>,
1957 field: &str,
1958 ) -> Result<Value, InterpreterError> {
1959 let object_map = cell.lock().unwrap();
1960
1961 if let Some(actor_field) = Self::check_actor_field_access(&object_map, field)? {
1963 return Ok(actor_field);
1964 }
1965
1966 self.check_struct_visibility(&object_map, field)?;
1968
1969 Self::get_object_field(&object_map, field)
1971 }
1972
1973 fn check_constructor_access(object_map: &HashMap<String, Value>, field: &str) -> Option<Value> {
1975 if field != "new" {
1976 return None;
1977 }
1978
1979 if let Some(Value::String(ref type_str)) = object_map.get("__type") {
1980 if let Some(Value::String(ref name)) = object_map.get("__name") {
1981 return match type_str.as_ref() {
1982 "Actor" => Some(Value::from_string(format!("__actor_constructor__:{name}"))),
1983 "Struct" => Some(Value::from_string(format!("__struct_constructor__:{name}"))),
1984 "Class" => Some(Value::from_string(format!(
1985 "__class_constructor__:{name}:new"
1986 ))),
1987 _ => None,
1988 };
1989 }
1990 }
1991 None
1992 }
1993
1994 fn check_actor_field_access(
1996 object_map: &HashMap<String, Value>,
1997 field: &str,
1998 ) -> Result<Option<Value>, InterpreterError> {
1999 if let Some(Value::String(actor_id)) = object_map.get("__actor_id") {
2000 use crate::runtime::actor_runtime::ACTOR_RUNTIME;
2001 let field_value = ACTOR_RUNTIME.get_actor_field(actor_id.as_ref(), field)?;
2002 Ok(Some(field_value.to_value()))
2003 } else {
2004 Ok(None)
2005 }
2006 }
2007
2008 fn check_struct_visibility(
2010 &self,
2011 object_map: &HashMap<String, Value>,
2012 field: &str,
2013 ) -> Result<(), InterpreterError> {
2014 if let Some(Value::String(struct_name)) = object_map.get("__struct_type") {
2015 self.check_field_visibility(struct_name.as_ref(), field)?;
2016 }
2017 Ok(())
2018 }
2019
2020 fn get_object_field(
2022 object_map: &HashMap<String, Value>,
2023 field: &str,
2024 ) -> Result<Value, InterpreterError> {
2025 object_map.get(field).cloned().ok_or_else(|| {
2026 InterpreterError::RuntimeError(format!("Object has no field named '{field}'"))
2027 })
2028 }
2029
2030 fn eval_object_literal(
2031 &mut self,
2032 fields: &[crate::frontend::ast::ObjectField],
2033 ) -> Result<Value, InterpreterError> {
2034 let mut object = HashMap::new();
2035
2036 for field in fields {
2037 match field {
2038 crate::frontend::ast::ObjectField::KeyValue { key, value } => {
2039 let eval_value = self.eval_expr(value)?;
2040 object.insert(key.clone(), eval_value);
2041 }
2042 crate::frontend::ast::ObjectField::Spread { expr: _ } => {
2043 return Err(InterpreterError::RuntimeError(
2044 "Spread operator in object literals not yet implemented".to_string(),
2045 ));
2046 }
2047 }
2048 }
2049
2050 Ok(Value::Object(Arc::new(object)))
2051 }
2052
2053 fn eval_qualified_name(&self, module: &str, name: &str) -> Result<Value, InterpreterError> {
2054 if module == "HashMap" && name == "new" {
2055 Ok(Value::from_string("__builtin_hashmap__".to_string()))
2056 } else if module == "String" && (name == "new" || name == "from") {
2057 Ok(Value::from_string(format!("__builtin_String_{}__", name)))
2059 } else if name == "new" {
2060 if let Ok(class_value) = self.lookup_variable(module) {
2062 if let Value::Object(ref class_info) = class_value {
2063 if let Some(Value::String(ref type_str)) = class_info.get("__type") {
2065 if type_str.as_ref() == "Class" {
2066 return Ok(Value::from_string(format!(
2068 "__class_constructor__:{}",
2069 module
2070 )));
2071 }
2072 }
2073 }
2074 }
2075 if let Ok(struct_value) = self.lookup_variable(module) {
2077 if let Value::Object(ref struct_info) = struct_value {
2078 if let Some(Value::String(ref type_str)) = struct_info.get("__type") {
2080 if type_str.as_ref() == "Struct" {
2081 return Ok(Value::from_string(format!(
2083 "__struct_constructor__:{}",
2084 module
2085 )));
2086 }
2087 }
2088 }
2089 }
2090 if let Ok(actor_value) = self.lookup_variable(module) {
2092 if let Value::Object(ref actor_info) = actor_value {
2093 if let Some(Value::String(ref type_str)) = actor_info.get("__type") {
2095 if type_str.as_ref() == "Actor" {
2096 return Ok(Value::from_string(format!(
2098 "__actor_constructor__:{}",
2099 module
2100 )));
2101 }
2102 }
2103 }
2104 }
2105 Err(InterpreterError::RuntimeError(format!(
2106 "Unknown qualified name: {}::{}",
2107 module, name
2108 )))
2109 } else {
2110 let qualified_method_name = format!("{}::{}", module, name);
2113 if let Ok(method_value) = self.lookup_variable(&qualified_method_name) {
2114 Ok(method_value)
2115 } else {
2116 Err(InterpreterError::RuntimeError(format!(
2117 "Unknown qualified name: {}::{}",
2118 module, name
2119 )))
2120 }
2121 }
2122 }
2123
2124 fn eval_literal(&self, lit: &Literal) -> Value {
2126 match lit {
2127 Literal::Integer(i, _) => Value::from_i64(*i),
2128 Literal::Float(f) => Value::from_f64(*f),
2129 Literal::String(s) => Value::from_string(s.clone()),
2130 Literal::Bool(b) => Value::from_bool(*b),
2131 Literal::Char(c) => Value::from_string(c.to_string()),
2132 Literal::Byte(b) => Value::Byte(*b),
2133 Literal::Unit => Value::nil(),
2134 Literal::Null => Value::nil(),
2135 }
2136 }
2137
2138 fn lookup_variable(&self, name: &str) -> Result<Value, InterpreterError> {
2140 if name == "Option::None" {
2142 return Ok(Value::EnumVariant {
2143 enum_name: "Option".to_string(),
2144 variant_name: "None".to_string(),
2145 data: None,
2146 });
2147 }
2148
2149 if name.contains("::") {
2151 let parts: Vec<&str> = name.split("::").collect();
2152 if parts.len() == 2 {
2153 let type_name = parts[0];
2154 let method_name = parts[1];
2155
2156 for env in self.env_stack.iter().rev() {
2158 if let Some(value) = env.get(type_name) {
2159 if let Value::Object(ref info) = value {
2160 if let Some(Value::String(ref type_str)) = info.get("__type") {
2162 if type_str.as_ref() == "Class" {
2163 if let Some(Value::Object(ref methods)) = info.get("__methods")
2165 {
2166 if let Some(Value::Object(ref method_meta)) =
2167 methods.get(method_name)
2168 {
2169 if let Some(Value::Bool(true)) =
2170 method_meta.get("is_static")
2171 {
2172 return Ok(Value::from_string(format!(
2174 "__class_static_method__:{}:{}",
2175 type_name, method_name
2176 )));
2177 }
2178 }
2179 }
2180
2181 if let Some(Value::Object(ref constructors)) =
2183 info.get("__constructors")
2184 {
2185 if constructors.contains_key(method_name) {
2186 return Ok(Value::from_string(format!(
2188 "__class_constructor__:{}:{}",
2189 type_name, method_name
2190 )));
2191 }
2192 }
2193 } else if type_str.as_ref() == "Struct" && method_name == "new" {
2194 return Ok(Value::from_string(format!(
2195 "__struct_constructor__:{}",
2196 type_name
2197 )));
2198 } else if type_str.as_ref() == "Actor" && method_name == "new" {
2199 return Ok(Value::from_string(format!(
2200 "__actor_constructor__:{}",
2201 type_name
2202 )));
2203 }
2204 }
2205 }
2206 }
2207 }
2208 }
2209 }
2210
2211 for env in self.env_stack.iter().rev() {
2213 if let Some(value) = env.get(name) {
2214 return Ok(value.clone());
2215 }
2216 }
2217 Err(InterpreterError::RuntimeError(format!(
2218 "Undefined variable: {name}"
2219 )))
2220 }
2221
2222 #[allow(clippy::expect_used)] pub fn current_env(&self) -> &HashMap<String, Value> {
2225 self.env_stack
2226 .last()
2227 .expect("Environment stack should never be empty")
2228 }
2229
2230 #[allow(clippy::expect_used)] fn env_set(&mut self, name: String, value: Value) {
2241 self.record_variable_assignment_feedback(&name, &value);
2243
2244 let env = self
2247 .env_stack
2248 .last_mut()
2249 .expect("Environment stack should never be empty");
2250 env.insert(name, value);
2251 }
2252
2253 fn env_set_mut(&mut self, name: String, value: Value) {
2260 self.record_variable_assignment_feedback(&name, &value);
2262
2263 for env in self.env_stack.iter_mut().rev() {
2265 if let std::collections::hash_map::Entry::Occupied(mut e) = env.entry(name.clone()) {
2266 e.insert(value);
2268 return;
2269 }
2270 }
2271
2272 let env = self
2274 .env_stack
2275 .last_mut()
2276 .expect("Environment stack should never be empty");
2277 env.insert(name, value);
2278 }
2279
2280 fn env_push(&mut self, env: HashMap<String, Value>) {
2282 self.env_stack.push(env);
2283 }
2284
2285 fn env_pop(&mut self) -> Option<HashMap<String, Value>> {
2287 if self.env_stack.len() > 1 {
2288 self.env_stack.pop()
2290 } else {
2291 None
2292 }
2293 }
2294
2295 fn eval_function_call_value(
2297 &mut self,
2298 func: &Value,
2299 args: &[Value],
2300 ) -> Result<Value, InterpreterError> {
2301 self.call_function(func.clone(), args)
2302 }
2303
2304 fn call_function(&mut self, func: Value, args: &[Value]) -> Result<Value, InterpreterError> {
2306 match func {
2307 Value::String(ref s) if s.starts_with("__class_constructor__:") => {
2308 let parts: Vec<&str> = s
2310 .strip_prefix("__class_constructor__:")
2311 .unwrap()
2312 .split(':')
2313 .collect();
2314
2315 if parts.len() == 2 {
2316 let class_name = parts[0];
2317 let constructor_name = parts[1];
2318 self.instantiate_class_with_constructor(class_name, constructor_name, args)
2319 } else {
2320 self.instantiate_class_with_constructor(parts[0], "new", args)
2322 }
2323 }
2324 Value::String(ref s) if s.starts_with("__class_static_method__:") => {
2325 let parts: Vec<&str> = s
2327 .strip_prefix("__class_static_method__:")
2328 .unwrap()
2329 .split(':')
2330 .collect();
2331
2332 if parts.len() == 2 {
2333 let class_name = parts[0];
2334 let method_name = parts[1];
2335 self.call_static_method(class_name, method_name, args)
2336 } else {
2337 Err(InterpreterError::RuntimeError(
2338 "Invalid static method marker".to_string(),
2339 ))
2340 }
2341 }
2342 Value::String(ref s) if s.starts_with("__struct_constructor__:") => {
2343 let struct_name = s.strip_prefix("__struct_constructor__:").unwrap();
2345 self.instantiate_struct_with_args(struct_name, args)
2346 }
2347 Value::String(ref s) if s.starts_with("__actor_constructor__:") => {
2348 let actor_name = s.strip_prefix("__actor_constructor__:").unwrap();
2350 self.instantiate_actor_with_args(actor_name, args)
2351 }
2352 Value::String(s) if s.starts_with("__builtin_") => {
2353 match crate::runtime::eval_builtin::eval_builtin_function(&s, args)? {
2355 Some(result) => Ok(result),
2356 None => Err(InterpreterError::RuntimeError(format!(
2357 "Unknown builtin function: {}",
2358 s
2359 ))),
2360 }
2361 }
2362 Value::Closure { params, body, env } => {
2363 crate::runtime::eval_function::check_recursion_depth()?;
2365
2366 if args.len() != params.len() {
2368 crate::runtime::eval_function::decrement_depth();
2369 return Err(InterpreterError::RuntimeError(format!(
2370 "Function expects {} arguments, got {}",
2371 params.len(),
2372 args.len()
2373 )));
2374 }
2375
2376 let mut new_env = env.as_ref().clone();
2378
2379 for (param, arg) in params.iter().zip(args) {
2381 new_env.insert(param.clone(), arg.clone());
2382 }
2383
2384 self.env_push(new_env);
2386
2387 let result = match self.eval_expr(&body) {
2390 Err(InterpreterError::Return(val)) => Ok(val),
2391 other => other,
2392 };
2393
2394 self.env_pop();
2396
2397 crate::runtime::eval_function::decrement_depth();
2399
2400 result
2401 }
2402 Value::Object(ref obj) => {
2403 if let Some(Value::String(type_str)) = obj.get("__type") {
2405 match type_str.as_ref() {
2406 "Struct" => {
2407 if let Some(Value::String(name)) = obj.get("__name") {
2409 self.instantiate_struct_with_args(name.as_ref(), args)
2410 } else {
2411 Err(InterpreterError::RuntimeError(
2412 "Struct missing __name field".to_string(),
2413 ))
2414 }
2415 }
2416 "Actor" => {
2417 if let Some(Value::String(name)) = obj.get("__name") {
2419 self.instantiate_actor_with_args(name.as_ref(), args)
2420 } else {
2421 Err(InterpreterError::RuntimeError(
2422 "Actor missing __name field".to_string(),
2423 ))
2424 }
2425 }
2426 "Class" => {
2427 if let Some(Value::String(name)) = obj.get("__name") {
2429 self.instantiate_class_with_args(name.as_ref(), args)
2430 } else {
2431 Err(InterpreterError::RuntimeError(
2432 "Class missing __name field".to_string(),
2433 ))
2434 }
2435 }
2436 _ => Err(InterpreterError::TypeError(format!(
2437 "Cannot call object of type: {}",
2438 type_str
2439 ))),
2440 }
2441 } else {
2442 Err(InterpreterError::TypeError(format!(
2443 "Cannot call non-function value: {}",
2444 func.type_name()
2445 )))
2446 }
2447 }
2448 _ => Err(InterpreterError::TypeError(format!(
2449 "Cannot call non-function value: {}",
2450 func.type_name()
2451 ))),
2452 }
2453 }
2454
2455 fn eval_binary_op(
2469 &self,
2470 op: AstBinaryOp,
2471 left: &Value,
2472 right: &Value,
2473 ) -> Result<Value, InterpreterError> {
2474 crate::runtime::eval_operations::eval_binary_op(op, left, right)
2475 }
2476
2477 fn eval_unary_op(
2478 &self,
2479 op: crate::frontend::ast::UnaryOp,
2480 operand: &Value,
2481 ) -> Result<Value, InterpreterError> {
2482 crate::runtime::eval_operations::eval_unary_op(op, operand)
2483 }
2484
2485 fn eval_binary_expr(
2487 &mut self,
2488 left: &Expr,
2489 op: crate::frontend::ast::BinaryOp,
2490 right: &Expr,
2491 ) -> Result<Value, InterpreterError> {
2492 match op {
2494 crate::frontend::ast::BinaryOp::Send => {
2495 let left_val = self.eval_expr(left)?;
2497 let message_val = self.eval_message_expr(right)?;
2498
2499 if let Value::ObjectMut(cell_rc) = left_val {
2501 self.process_actor_message_sync_mut(&cell_rc, &message_val)?;
2503 Ok(Value::Nil)
2505 } else {
2506 Err(InterpreterError::RuntimeError(format!(
2507 "Send operator requires an actor instance, got {}",
2508 left_val.type_name()
2509 )))
2510 }
2511 }
2512 crate::frontend::ast::BinaryOp::NullCoalesce => {
2513 let left_val = self.eval_expr(left)?;
2514 if matches!(left_val, Value::Nil) {
2515 self.eval_expr(right)
2516 } else {
2517 Ok(left_val)
2518 }
2519 }
2520 crate::frontend::ast::BinaryOp::And => {
2521 let left_val = self.eval_expr(left)?;
2522 if left_val.is_truthy() {
2523 self.eval_expr(right)
2524 } else {
2525 Ok(left_val)
2526 }
2527 }
2528 crate::frontend::ast::BinaryOp::Or => {
2529 let left_val = self.eval_expr(left)?;
2530 if left_val.is_truthy() {
2531 Ok(left_val)
2532 } else {
2533 self.eval_expr(right)
2534 }
2535 }
2536 _ => {
2537 let left_val = self.eval_expr(left)?;
2538 let right_val = self.eval_expr(right)?;
2539 let result = self.eval_binary_op(op, &left_val, &right_val)?;
2540
2541 let site_id = left.span.start; self.record_binary_op_feedback(site_id, &left_val, &right_val, &result);
2544
2545 Ok(result)
2546 }
2547 }
2548 }
2549
2550 fn eval_unary_expr(
2552 &mut self,
2553 op: crate::frontend::ast::UnaryOp,
2554 operand: &Expr,
2555 ) -> Result<Value, InterpreterError> {
2556 let operand_val = self.eval_expr(operand)?;
2557 self.eval_unary_op(op, &operand_val)
2558 }
2559
2560 fn eval_type_cast(
2565 &mut self,
2566 expr: &Expr,
2567 target_type: &str,
2568 ) -> Result<Value, InterpreterError> {
2569 if matches!(target_type, "i32" | "i64" | "isize") {
2572 if let ExprKind::FieldAccess { object, field } = &expr.kind {
2573 if let ExprKind::Identifier(enum_name) = &object.kind {
2574 let variant_name = field;
2576
2577 if let Some(Value::Object(enum_def)) = self.get_variable(enum_name) {
2579 if let Some(Value::Object(variants)) = enum_def.get("__variants") {
2580 if let Some(Value::Object(variant_info)) = variants.get(variant_name) {
2581 if let Some(Value::Integer(disc)) =
2582 variant_info.get("discriminant")
2583 {
2584 return Ok(Value::Integer(*disc));
2585 }
2586 }
2587 }
2588 }
2589 }
2590 }
2591 }
2592
2593 let value = self.eval_expr(expr)?;
2595
2596 match (value, target_type) {
2597 (Value::Integer(i), "f64" | "f32") => Ok(Value::Float(i as f64)),
2599
2600 (Value::Float(f), "i32" | "i64" | "isize") => Ok(Value::Integer(f as i64)),
2602
2603 (Value::Integer(i), "i32" | "i64" | "isize") => Ok(Value::Integer(i)),
2605
2606 (Value::Float(f), "f64" | "f32") => Ok(Value::Float(f)),
2608
2609 (Value::EnumVariant { enum_name, variant_name, .. }, "i32" | "i64" | "isize") => {
2612 if let Some(Value::Object(enum_def)) = self.get_variable(&enum_name) {
2614 if let Some(Value::Object(variants)) = enum_def.get("__variants") {
2615 if let Some(Value::Object(variant_info)) = variants.get(&variant_name) {
2616 if let Some(Value::Integer(disc)) = variant_info.get("discriminant") {
2617 return Ok(Value::Integer(*disc));
2618 }
2619 }
2620 }
2621 }
2622 Err(InterpreterError::TypeError(format!(
2623 "Cannot cast enum variant {}::{} to integer: enum definition not found",
2624 enum_name, variant_name
2625 )))
2626 }
2627
2628 (val, target) => Err(InterpreterError::TypeError(format!(
2630 "Cannot cast {} to {}",
2631 val.type_name(),
2632 target
2633 ))),
2634 }
2635 }
2636
2637 fn eval_if_expr(
2639 &mut self,
2640 condition: &Expr,
2641 then_branch: &Expr,
2642 else_branch: Option<&Expr>,
2643 ) -> Result<Value, InterpreterError> {
2644 crate::runtime::eval_control_flow_new::eval_if_expr(
2645 condition,
2646 then_branch,
2647 else_branch,
2648 |e| self.eval_expr(e),
2649 )
2650 }
2651
2652 fn eval_let_expr(
2654 &mut self,
2655 name: &str,
2656 value: &Expr,
2657 body: &Expr,
2658 ) -> Result<Value, InterpreterError> {
2659 let val = self.eval_expr(value)?;
2660 self.env_set(name.to_string(), val.clone());
2661
2662 match &body.kind {
2665 ExprKind::Literal(Literal::Unit) => Ok(val),
2666 _ => self.eval_expr(body),
2667 }
2668 }
2669
2670 fn eval_return_expr(&mut self, value: Option<&Expr>) -> Result<Value, InterpreterError> {
2672 crate::runtime::eval_control_flow_new::eval_return_expr(value, |e| self.eval_expr(e))
2673 }
2674
2675 fn eval_list_expr(&mut self, elements: &[Expr]) -> Result<Value, InterpreterError> {
2677 crate::runtime::eval_control_flow_new::eval_list_expr(elements, |e| self.eval_expr(e))
2678 }
2679
2680 fn eval_array_init_expr(
2682 &mut self,
2683 value_expr: &Expr,
2684 size_expr: &Expr,
2685 ) -> Result<Value, InterpreterError> {
2686 crate::runtime::eval_control_flow_new::eval_array_init_expr(value_expr, size_expr, |e| {
2687 self.eval_expr(e)
2688 })
2689 }
2690
2691 fn eval_block_expr(&mut self, statements: &[Expr]) -> Result<Value, InterpreterError> {
2693 crate::runtime::eval_control_flow_new::eval_block_expr(statements, |e| self.eval_expr(e))
2694 }
2695
2696 fn eval_tuple_expr(&mut self, elements: &[Expr]) -> Result<Value, InterpreterError> {
2698 crate::runtime::eval_control_flow_new::eval_tuple_expr(elements, |e| self.eval_expr(e))
2699 }
2700
2701 fn eval_dataframe_literal(
2704 &mut self,
2705 columns: &[crate::frontend::ast::DataFrameColumn],
2706 ) -> Result<Value, InterpreterError> {
2707 let mut evaluated_columns = Vec::new();
2708
2709 for col in columns {
2710 let mut evaluated_values = Vec::new();
2712 for value_expr in &col.values {
2713 evaluated_values.push(self.eval_expr(value_expr)?);
2714 }
2715
2716 evaluated_columns.push(DataFrameColumn {
2718 name: col.name.clone(),
2719 values: evaluated_values,
2720 });
2721 }
2722
2723 Ok(Value::DataFrame {
2724 columns: evaluated_columns,
2725 })
2726 }
2727
2728 fn eval_range_expr(
2730 &mut self,
2731 start: &Expr,
2732 end: &Expr,
2733 inclusive: bool,
2734 ) -> Result<Value, InterpreterError> {
2735 crate::runtime::eval_control_flow_new::eval_range_expr(start, end, inclusive, |e| {
2736 self.eval_expr(e)
2737 })
2738 }
2739
2740 #[cfg(test)]
2744 pub fn eval_string(&mut self, input: &str) -> Result<Value, Box<dyn std::error::Error>> {
2763 use crate::frontend::parser::Parser;
2764
2765 let mut parser = Parser::new(input);
2766 let expr = parser.parse_expr()?;
2767
2768 Ok(self.eval_expr(&expr)?)
2769 }
2770
2771 pub fn push(&mut self, value: Value) -> Result<(), InterpreterError> {
2775 if self.stack.len() >= 10_000 {
2776 return Err(InterpreterError::StackOverflow);
2778 }
2779 self.stack.push(value);
2780 Ok(())
2781 }
2782
2783 pub fn pop(&mut self) -> Result<Value, InterpreterError> {
2787 self.stack.pop().ok_or(InterpreterError::StackUnderflow)
2788 }
2789
2790 pub fn peek(&self, depth: usize) -> Result<Value, InterpreterError> {
2794 let index = self
2795 .stack
2796 .len()
2797 .checked_sub(depth + 1)
2798 .ok_or(InterpreterError::StackUnderflow)?;
2799 Ok(self.stack[index].clone())
2800 }
2801
2802 pub fn binary_op(&mut self, op: BinaryOp) -> Result<(), InterpreterError> {
2806 let right = self.pop()?;
2807 let left = self.pop()?;
2808
2809 let result = match op {
2810 BinaryOp::Add => eval_operations::eval_binary_op(AstBinaryOp::Add, &left, &right)?,
2811 BinaryOp::Sub => eval_operations::eval_binary_op(AstBinaryOp::Subtract, &left, &right)?,
2812 BinaryOp::Mul => eval_operations::eval_binary_op(AstBinaryOp::Multiply, &left, &right)?,
2813 BinaryOp::Div => eval_operations::eval_binary_op(AstBinaryOp::Divide, &left, &right)?,
2814 BinaryOp::Eq => eval_operations::eval_binary_op(AstBinaryOp::Equal, &left, &right)?,
2815 BinaryOp::Lt => eval_operations::eval_binary_op(AstBinaryOp::Less, &left, &right)?,
2816 BinaryOp::Gt => eval_operations::eval_binary_op(AstBinaryOp::Greater, &left, &right)?,
2817 };
2818
2819 self.push(result)?;
2820 Ok(())
2821 }
2822
2823 pub fn set_variable_string(&mut self, name: String, value: Value) {
2825 self.env_set(name, value);
2826 }
2827
2828 fn apply_binary_op(
2830 &self,
2831 left: &Value,
2832 op: AstBinaryOp,
2833 right: &Value,
2834 ) -> Result<Value, InterpreterError> {
2835 self.eval_binary_op(op, left, right)
2837 }
2838
2839 fn try_pattern_match(
2844 &self,
2845 pattern: &Pattern,
2846 value: &Value,
2847 ) -> Result<Option<Vec<(String, Value)>>, InterpreterError> {
2848 crate::runtime::eval_pattern_match::try_pattern_match(pattern, value, &|lit| {
2849 self.eval_literal(lit)
2850 })
2851 }
2852
2853 fn pattern_matches_internal(
2855 &self,
2856 pattern: &Pattern,
2857 value: &Value,
2858 ) -> Result<bool, InterpreterError> {
2859 crate::runtime::eval_pattern_match::pattern_matches(pattern, value, &|lit| {
2860 self.eval_literal(lit)
2861 })
2862 }
2863
2864 pub fn push_scope(&mut self) {
2866 let new_env = HashMap::new();
2867 self.env_push(new_env);
2868 }
2869
2870 pub fn pop_scope(&mut self) {
2871 self.env_pop();
2872 }
2873
2874 fn match_tuple_pattern(
2879 &self,
2880 patterns: &[Pattern],
2881 value: &Value,
2882 ) -> Result<bool, InterpreterError> {
2883 crate::runtime::eval_pattern_match::match_tuple_pattern(patterns, value, |lit| {
2884 self.eval_literal(lit)
2885 })
2886 }
2887
2888 fn match_list_pattern(
2889 &self,
2890 patterns: &[Pattern],
2891 value: &Value,
2892 ) -> Result<bool, InterpreterError> {
2893 crate::runtime::eval_pattern_match::match_list_pattern(patterns, value, |lit| {
2894 self.eval_literal(lit)
2895 })
2896 }
2897
2898 fn match_or_pattern(
2899 &self,
2900 patterns: &[Pattern],
2901 value: &Value,
2902 ) -> Result<bool, InterpreterError> {
2903 crate::runtime::eval_pattern_match::match_or_pattern(patterns, value, |lit| {
2904 self.eval_literal(lit)
2905 })
2906 }
2907
2908 pub fn get_field_cached(
2912 &mut self,
2913 obj: &Value,
2914 field_name: &str,
2915 ) -> Result<Value, InterpreterError> {
2916 let cache_key = format!("{:?}::{}", obj.type_id(), field_name);
2918
2919 if let Some(cache) = self.field_caches.get_mut(&cache_key) {
2921 if let Some(cached_result) = cache.lookup(obj, field_name) {
2922 return Ok(cached_result);
2923 }
2924 }
2925
2926 let result = self.compute_field_access(obj, field_name)?;
2928
2929 let cache = self.field_caches.entry(cache_key).or_default();
2931 cache.insert(obj, field_name.to_string(), result.clone());
2932
2933 Ok(result)
2934 }
2935
2936 fn compute_field_access(
2938 &self,
2939 obj: &Value,
2940 field_name: &str,
2941 ) -> Result<Value, InterpreterError> {
2942 match (obj, field_name) {
2943 (Value::String(s), "len") => Ok(Value::Integer(s.len().try_into().unwrap_or(i64::MAX))),
2945 (Value::String(s), "to_upper") => Ok(Value::from_string(s.to_uppercase())),
2946 (Value::String(s), "to_lower") => Ok(Value::from_string(s.to_lowercase())),
2947 (Value::String(s), "trim") => Ok(Value::from_string(s.trim().to_string())),
2948
2949 (Value::Array(arr), "len") => {
2951 Ok(Value::Integer(arr.len().try_into().unwrap_or(i64::MAX)))
2952 }
2953 (Value::Array(arr), "first") => arr
2954 .first()
2955 .cloned()
2956 .ok_or_else(|| InterpreterError::RuntimeError("Array is empty".to_string())),
2957 (Value::Array(arr), "last") => arr
2958 .last()
2959 .cloned()
2960 .ok_or_else(|| InterpreterError::RuntimeError("Array is empty".to_string())),
2961 (Value::Array(arr), "is_empty") => Ok(Value::from_bool(arr.is_empty())),
2962
2963 (obj, "type") => Ok(Value::from_string(obj.type_name().to_string())),
2965
2966 _ => Err(InterpreterError::RuntimeError(format!(
2967 "Field '{}' not found on type '{}'",
2968 field_name,
2969 obj.type_name()
2970 ))),
2971 }
2972 }
2973
2974 pub fn get_cache_stats(&self) -> HashMap<String, f64> {
2976 let mut stats = HashMap::new();
2977 for (key, cache) in &self.field_caches {
2978 stats.insert(key.clone(), cache.hit_rate());
2979 }
2980 stats
2981 }
2982
2983 pub fn clear_caches(&mut self) {
2985 self.field_caches.clear();
2986 }
2987
2988 #[allow(dead_code)] fn record_binary_op_feedback(
2991 &mut self,
2992 site_id: usize,
2993 left: &Value,
2994 right: &Value,
2995 result: &Value,
2996 ) {
2997 self.type_feedback
2998 .record_binary_op(site_id, left, right, result);
2999 }
3000
3001 #[allow(dead_code)] fn record_variable_assignment_feedback(&mut self, var_name: &str, value: &Value) {
3004 let type_id = value.type_id();
3005 self.type_feedback
3006 .record_variable_assignment(var_name, type_id);
3007 }
3008
3009 fn record_function_call_feedback(
3011 &mut self,
3012 site_id: usize,
3013 func_name: &str,
3014 args: &[Value],
3015 result: &Value,
3016 ) {
3017 self.type_feedback
3018 .record_function_call(site_id, func_name, args, result);
3019 }
3020
3021 pub fn get_type_feedback_stats(&self) -> TypeFeedbackStats {
3023 self.type_feedback.get_statistics()
3024 }
3025
3026 pub fn get_specialization_candidates(&self) -> Vec<SpecializationCandidate> {
3028 self.type_feedback.get_specialization_candidates()
3029 }
3030
3031 pub fn clear_type_feedback(&mut self) {
3033 self.type_feedback = TypeFeedback::new();
3034 }
3035
3036 pub fn gc_track(&mut self, value: Value) -> usize {
3038 self.gc.track_object(value)
3039 }
3040
3041 pub fn gc_collect(&mut self) -> GCStats {
3043 self.gc.force_collect()
3044 }
3045
3046 pub fn gc_stats(&self) -> GCStats {
3048 self.gc.get_stats()
3049 }
3050
3051 pub fn gc_info(&self) -> GCInfo {
3053 self.gc.get_info()
3054 }
3055
3056 pub fn gc_set_threshold(&mut self, threshold: usize) {
3058 self.gc.set_collection_threshold(threshold);
3059 }
3060
3061 pub fn gc_set_auto_collect(&mut self, enabled: bool) {
3063 self.gc.set_auto_collect(enabled);
3064 }
3065
3066 pub fn gc_clear(&mut self) {
3068 self.gc.clear();
3069 }
3070
3071 pub fn gc_alloc_array(&mut self, elements: Vec<Value>) -> Value {
3073 let array_value = Value::from_array(elements);
3074 self.gc.track_object(array_value.clone());
3075 array_value
3076 }
3077
3078 pub fn gc_alloc_string(&mut self, content: String) -> Value {
3080 let string_value = Value::from_string(content);
3081 self.gc.track_object(string_value.clone());
3082 string_value
3083 }
3084
3085 pub fn gc_alloc_closure(
3087 &mut self,
3088 params: Vec<String>,
3089 body: Arc<Expr>,
3090 env: Arc<HashMap<String, Value>>,
3091 ) -> Value {
3092 let closure_value = Value::Closure { params, body, env };
3093 self.gc.track_object(closure_value.clone());
3094 closure_value
3095 }
3096
3097 pub fn get_global_bindings(&self) -> HashMap<String, Value> {
3103 if let Some(global_env) = self.env_stack.first() {
3104 global_env.clone()
3105 } else {
3106 HashMap::new()
3107 }
3108 }
3109
3110 pub fn set_global_binding(&mut self, name: String, value: Value) {
3112 if let Some(global_env) = self.env_stack.first_mut() {
3113 global_env.insert(name, value);
3114 }
3115 }
3116
3117 pub fn clear_user_variables(&mut self) {
3119 if let Some(global_env) = self.env_stack.first_mut() {
3120 global_env.retain(|name, _| name.starts_with("__builtin_") || name == "nil");
3122 }
3123 }
3124
3125 pub fn get_current_bindings(&self) -> HashMap<String, Value> {
3127 if let Some(current_env) = self.env_stack.last() {
3128 current_env.clone()
3129 } else {
3130 HashMap::new()
3131 }
3132 }
3133
3134 fn eval_for_loop(
3136 &mut self,
3137 label: Option<&String>,
3138 var: &str,
3139 _pattern: Option<&Pattern>,
3140 iter: &Expr,
3141 body: &Expr,
3142 ) -> Result<Value, InterpreterError> {
3143 let iter_value = self.eval_expr(iter)?;
3144
3145 match iter_value {
3146 Value::Array(ref arr) => self.eval_for_array_iteration(label, var, arr, body),
3147 Value::Range {
3148 ref start,
3149 ref end,
3150 inclusive,
3151 } => self.eval_for_range_iteration(label, var, start, end, inclusive, body),
3152 _ => Err(InterpreterError::TypeError(
3153 "For loop requires an iterable".to_string(),
3154 )),
3155 }
3156 }
3157
3158 fn eval_for_array_iteration(
3161 &mut self,
3162 label: Option<&String>,
3163 loop_var: &str,
3164 arr: &[Value],
3165 body: &Expr,
3166 ) -> Result<Value, InterpreterError> {
3167 let mut last_value = Value::nil();
3168
3169 for item in arr {
3170 self.set_variable(loop_var, item.clone());
3171 match self.eval_loop_body_with_control_flow(body) {
3172 Ok(value) => last_value = value,
3173 Err(LoopControlOrError::Break(break_label, break_val)) => {
3174 if break_label.is_none() || break_label.as_deref() == label.map(String::as_str)
3176 {
3177 return Ok(break_val);
3178 }
3179 return Err(InterpreterError::Break(break_label, break_val));
3181 }
3182 Err(LoopControlOrError::Continue(continue_label)) => {
3183 if continue_label.is_none()
3185 || continue_label.as_deref() == label.map(String::as_str)
3186 {
3187 continue;
3188 }
3189 return Err(InterpreterError::Continue(continue_label));
3191 }
3192 Err(LoopControlOrError::Return(return_val)) => {
3193 return Err(InterpreterError::Return(return_val))
3194 }
3195 Err(LoopControlOrError::Error(e)) => return Err(e),
3196 }
3197 }
3198
3199 Ok(last_value)
3200 }
3201
3202 fn eval_for_range_iteration(
3205 &mut self,
3206 label: Option<&String>,
3207 loop_var: &str,
3208 start: &Value,
3209 end: &Value,
3210 inclusive: bool,
3211 body: &Expr,
3212 ) -> Result<Value, InterpreterError> {
3213 let (start_val, end_val) = self.extract_range_bounds(start, end)?;
3214 let mut last_value = Value::nil();
3215
3216 for i in self.create_range_iterator(start_val, end_val, inclusive) {
3217 self.set_variable(loop_var, Value::Integer(i));
3218 match self.eval_loop_body_with_control_flow(body) {
3219 Ok(value) => last_value = value,
3220 Err(LoopControlOrError::Break(break_label, break_val)) => {
3221 if break_label.is_none() || break_label.as_deref() == label.map(String::as_str)
3222 {
3223 return Ok(break_val);
3224 }
3225 return Err(InterpreterError::Break(break_label, break_val));
3226 }
3227 Err(LoopControlOrError::Continue(continue_label)) => {
3228 if continue_label.is_none()
3229 || continue_label.as_deref() == label.map(String::as_str)
3230 {
3231 continue;
3232 }
3233 return Err(InterpreterError::Continue(continue_label));
3234 }
3235 Err(LoopControlOrError::Return(return_val)) => {
3236 return Err(InterpreterError::Return(return_val))
3237 }
3238 Err(LoopControlOrError::Error(e)) => return Err(e),
3239 }
3240 }
3241
3242 Ok(last_value)
3243 }
3244
3245 fn extract_range_bounds(
3248 &self,
3249 start: &Value,
3250 end: &Value,
3251 ) -> Result<(i64, i64), InterpreterError> {
3252 match (start, end) {
3253 (Value::Integer(s), Value::Integer(e)) => Ok((*s, *e)),
3254 _ => Err(InterpreterError::TypeError(
3255 "Range bounds must be integers".to_string(),
3256 )),
3257 }
3258 }
3259
3260 fn create_range_iterator(
3263 &self,
3264 start: i64,
3265 end: i64,
3266 inclusive: bool,
3267 ) -> Box<dyn Iterator<Item = i64>> {
3268 if inclusive {
3269 Box::new(start..=end)
3270 } else {
3271 Box::new(start..end)
3272 }
3273 }
3274
3275 fn eval_loop_body_with_control_flow(
3278 &mut self,
3279 body: &Expr,
3280 ) -> Result<Value, LoopControlOrError> {
3281 match self.eval_expr(body) {
3282 Ok(value) => Ok(value),
3283 Err(InterpreterError::Break(label, val)) => Err(LoopControlOrError::Break(label, val)),
3284 Err(InterpreterError::Continue(label)) => Err(LoopControlOrError::Continue(label)),
3285 Err(InterpreterError::Return(val)) => Err(LoopControlOrError::Return(val)),
3286 Err(e) => Err(LoopControlOrError::Error(e)),
3287 }
3288 }
3289
3290 fn eval_while_loop(
3292 &mut self,
3293 label: Option<&String>,
3294 condition: &Expr,
3295 body: &Expr,
3296 ) -> Result<Value, InterpreterError> {
3297 let mut last_value = Value::Nil;
3298 loop {
3299 let cond_value = self.eval_expr(condition)?;
3300 if !matches!(cond_value, Value::Bool(true)) && cond_value != Value::Integer(1) {
3301 break;
3302 }
3303
3304 match self.eval_loop_body_with_control_flow(body) {
3305 Ok(value) => last_value = value,
3306 Err(LoopControlOrError::Break(break_label, break_val)) => {
3307 if break_label.is_none() || break_label.as_deref() == label.map(String::as_str)
3308 {
3309 return Ok(break_val);
3310 }
3311 return Err(InterpreterError::Break(break_label, break_val));
3312 }
3313 Err(LoopControlOrError::Continue(continue_label)) => {
3314 if continue_label.is_none()
3315 || continue_label.as_deref() == label.map(String::as_str)
3316 {
3317 continue;
3318 }
3319 return Err(InterpreterError::Continue(continue_label));
3320 }
3321 Err(LoopControlOrError::Return(return_val)) => {
3322 return Err(InterpreterError::Return(return_val))
3323 }
3324 Err(LoopControlOrError::Error(e)) => return Err(e),
3325 }
3326 }
3327 Ok(last_value)
3328 }
3329
3330 fn eval_loop(
3332 &mut self,
3333 label: Option<&String>,
3334 body: &Expr,
3335 ) -> Result<Value, InterpreterError> {
3336 loop {
3337 match self.eval_loop_body_with_control_flow(body) {
3338 Ok(_) => {}
3339 Err(LoopControlOrError::Break(break_label, break_val)) => {
3340 if break_label.is_none() || break_label.as_deref() == label.map(String::as_str)
3341 {
3342 return Ok(break_val);
3343 }
3344 return Err(InterpreterError::Break(break_label, break_val));
3345 }
3346 Err(LoopControlOrError::Continue(continue_label)) => {
3347 if continue_label.is_none()
3348 || continue_label.as_deref() == label.map(String::as_str)
3349 {
3350 continue;
3351 }
3352 return Err(InterpreterError::Continue(continue_label));
3353 }
3354 Err(LoopControlOrError::Return(return_val)) => {
3355 return Err(InterpreterError::Return(return_val))
3356 }
3357 Err(LoopControlOrError::Error(e)) => return Err(e),
3358 }
3359 }
3360 }
3361
3362 pub fn eval_match(&mut self, expr: &Expr, arms: &[MatchArm]) -> Result<Value, InterpreterError> {
3364 let value = self.eval_expr(expr)?;
3365
3366 for arm in arms {
3367 if let Some(bindings) = self.try_pattern_match(&arm.pattern, &value)? {
3369 self.push_scope();
3371
3372 for (name, val) in bindings {
3374 self.env_set(name, val);
3375 }
3376
3377 let guard_passed = if let Some(guard) = &arm.guard {
3379 match self.eval_expr(guard)? {
3380 Value::Bool(true) => true,
3381 Value::Bool(false) => false,
3382 _ => {
3383 self.pop_scope();
3384 return Err(InterpreterError::RuntimeError(
3385 "Guard condition must evaluate to a boolean".to_string(),
3386 ));
3387 }
3388 }
3389 } else {
3390 true };
3392
3393 if guard_passed {
3394 let result = self.eval_expr(&arm.body);
3396 self.pop_scope();
3397 return result;
3398 }
3399 self.pop_scope();
3401 }
3402 }
3403
3404 Err(InterpreterError::RuntimeError(
3405 "No match arm matched the value".to_string(),
3406 ))
3407 }
3408
3409 fn extract_mut_names(pattern: &Pattern) -> std::collections::HashSet<String> {
3413 let mut mut_names = std::collections::HashSet::new();
3414
3415 fn walk_pattern(
3416 p: &Pattern,
3417 mut_names: &mut std::collections::HashSet<String>,
3418 is_mut: bool,
3419 ) {
3420 match p {
3421 Pattern::Mut(inner) => walk_pattern(inner, mut_names, true),
3422 Pattern::Identifier(name) if is_mut => {
3423 mut_names.insert(name.clone());
3424 }
3425 Pattern::Tuple(patterns) | Pattern::List(patterns) => {
3426 for pat in patterns {
3427 walk_pattern(pat, mut_names, is_mut);
3428 }
3429 }
3430 Pattern::Struct { fields, .. } => {
3431 for field in fields {
3432 if let Some(ref pat) = field.pattern {
3433 walk_pattern(pat, mut_names, is_mut);
3434 }
3435 }
3436 }
3437 Pattern::AtBinding { pattern, .. } => walk_pattern(pattern, mut_names, is_mut),
3438 _ => {}
3439 }
3440 }
3441
3442 walk_pattern(pattern, &mut mut_names, false);
3443 mut_names
3444 }
3445
3446 fn eval_let_pattern(
3449 &mut self,
3450 pattern: &Pattern,
3451 value: &Expr,
3452 body: &Expr,
3453 ) -> Result<Value, InterpreterError> {
3454 let rhs_value = self.eval_expr(value)?;
3456
3457 let mut_names = Self::extract_mut_names(pattern);
3459
3460 if let Some(bindings) = self.try_pattern_match(pattern, &rhs_value)? {
3462 for (name, val) in bindings {
3464 if mut_names.contains(&name) {
3465 self.env_set_mut(name.clone(), val);
3466 } else {
3467 self.env_set(name, val);
3468 }
3469 }
3470
3471 match &body.kind {
3474 ExprKind::Literal(Literal::Unit) => Ok(rhs_value),
3475 _ => self.eval_expr(body),
3476 }
3477 } else {
3478 Err(InterpreterError::RuntimeError(
3479 "Pattern did not match the value".to_string(),
3480 ))
3481 }
3482 }
3483
3484 fn eval_assign(&mut self, target: &Expr, value: &Expr) -> Result<Value, InterpreterError> {
3522 let val = self.eval_expr(value)?;
3523
3524 match &target.kind {
3526 ExprKind::Identifier(name) => {
3527 self.set_variable(name, val.clone());
3528 Ok(val)
3529 }
3530 ExprKind::FieldAccess { object, field } => {
3531 match &object.kind {
3534 ExprKind::Identifier(obj_name) => {
3535 let obj = self.lookup_variable(obj_name)?;
3537
3538 match obj {
3540 Value::Object(ref map) => {
3541 let mut new_map = (**map).clone();
3543 new_map.insert(field.clone(), val.clone());
3544 let new_obj = Value::Object(Arc::new(new_map));
3545
3546 self.set_variable(obj_name, new_obj);
3548 Ok(val)
3549 }
3550 Value::ObjectMut(ref cell) => {
3551 cell.lock().unwrap().insert(field.clone(), val.clone());
3553 Ok(val)
3554 }
3555 Value::Class { ref fields, .. } => {
3556 let mut fields_write = fields.write().unwrap();
3558 fields_write.insert(field.clone(), val.clone());
3559 Ok(val)
3560 }
3561 Value::Struct { ref name, ref fields } => {
3562 let mut new_fields = (**fields).clone();
3564 new_fields.insert(field.clone(), val.clone());
3565 let new_struct = Value::Struct {
3566 name: name.clone(),
3567 fields: Arc::new(new_fields),
3568 };
3569
3570 self.set_variable(obj_name, new_struct);
3572 Ok(val)
3573 }
3574 _ => Err(InterpreterError::RuntimeError(format!(
3575 "Cannot access field '{}' on non-object",
3576 field
3577 ))),
3578 }
3579 }
3580 _ => Err(InterpreterError::RuntimeError(
3581 "Complex assignment targets not yet supported".to_string(),
3582 )),
3583 }
3584 }
3585 _ => Err(InterpreterError::RuntimeError(
3586 "Invalid assignment target".to_string(),
3587 )),
3588 }
3589 }
3590
3591 fn eval_compound_assign(
3593 &mut self,
3594 target: &Expr,
3595 op: AstBinaryOp,
3596 value: &Expr,
3597 ) -> Result<Value, InterpreterError> {
3598 let current = match &target.kind {
3600 ExprKind::Identifier(name) => self.lookup_variable(name)?,
3601 _ => {
3602 return Err(InterpreterError::RuntimeError(
3603 "Invalid compound assignment target".to_string(),
3604 ))
3605 }
3606 };
3607
3608 let rhs = self.eval_expr(value)?;
3610 let new_val = self.apply_binary_op(¤t, op, &rhs)?;
3611
3612 if let ExprKind::Identifier(name) = &target.kind {
3614 self.set_variable(name, new_val.clone());
3615 }
3616
3617 Ok(new_val)
3618 }
3619
3620 fn eval_string_method(
3622 &mut self,
3623 s: &Arc<str>,
3624 method: &str,
3625 args: &[Value],
3626 ) -> Result<Value, InterpreterError> {
3627 super::eval_string_methods::eval_string_method(s, method, args)
3628 }
3629
3630 #[allow(clippy::rc_buffer)]
3632 fn eval_array_method(
3633 &mut self,
3634 arr: &Arc<[Value]>,
3635 method: &str,
3636 args: &[Value],
3637 ) -> Result<Value, InterpreterError> {
3638 crate::runtime::eval_array::eval_array_method(arr, method, args, |func, args| {
3640 self.eval_function_call_value(func, args)
3641 })
3642 }
3643
3644 pub fn eval_method_call(
3646 &mut self,
3647 receiver: &Expr,
3648 method: &str,
3649 args: &[Expr],
3650 ) -> Result<Value, InterpreterError> {
3651 if let ExprKind::Identifier(namespace) = &receiver.kind {
3653 let namespace_method = format!("{namespace}_{method}");
3655
3656 let arg_values: Result<Vec<_>, _> = args.iter().map(|arg| self.eval_expr(arg)).collect();
3658 let arg_values = arg_values?;
3659
3660 if let Ok(Some(result)) = crate::runtime::eval_builtin::eval_builtin_function(&namespace_method, &arg_values) {
3661 return Ok(result);
3662 }
3663 }
3664
3665 if let ExprKind::Identifier(var_name) = &receiver.kind {
3668 if method == "push" && args.len() == 1 {
3669 if let Ok(Value::Array(arr)) = self.lookup_variable(var_name) {
3671 let arg_value = self.eval_expr(&args[0])?;
3673
3674 let mut new_arr = arr.to_vec();
3676 new_arr.push(arg_value);
3677
3678 self.env_set(var_name.clone(), Value::Array(Arc::from(new_arr)));
3680
3681 return Ok(Value::Nil); }
3683 } else if method == "pop" && args.is_empty() {
3684 if let Ok(Value::Array(arr)) = self.lookup_variable(var_name) {
3686 let mut new_arr = arr.to_vec();
3688 let popped_value = new_arr.pop().unwrap_or(Value::Nil);
3689
3690 self.env_set(var_name.clone(), Value::Array(Arc::from(new_arr)));
3692
3693 return Ok(popped_value); }
3695 }
3696 }
3697
3698 if let ExprKind::FieldAccess { object, field } = &receiver.kind {
3701 if let Ok(object_value) = self.eval_expr(object) {
3702 if let Value::ObjectMut(cell_rc) = object_value {
3703 if method == "push" && args.len() == 1 {
3705 let arg_value = self.eval_expr(&args[0])?;
3707
3708 let mut obj = cell_rc.lock().unwrap();
3710
3711 if let Some(field_value) = obj.get(field) {
3713 if let Value::Array(arr) = field_value {
3715 let mut new_arr = arr.to_vec();
3716 new_arr.push(arg_value);
3717 obj.insert(field.clone(), Value::Array(Arc::from(new_arr)));
3718 return Ok(Value::Nil); }
3720 }
3721 }
3722 }
3723 }
3724 }
3725
3726 let receiver_value = self.eval_expr(receiver)?;
3727
3728 if matches!(receiver_value, Value::DataFrame { .. }) {
3730 match method {
3731 "filter" => return self.eval_dataframe_filter_method(&receiver_value, args),
3732 "with_column" => {
3733 return self.eval_dataframe_with_column_method(&receiver_value, args)
3734 }
3735 "transform" => return self.eval_dataframe_transform_method(&receiver_value, args),
3736 _ => {}
3737 }
3738 }
3739
3740 if (method == "send" || method == "ask") && args.len() == 1 {
3742 let is_actor = match &receiver_value {
3744 Value::Object(ref obj) => obj.contains_key("__actor"),
3745 Value::ObjectMut(ref cell) => cell.lock().unwrap().contains_key("__actor"),
3746 _ => false,
3747 };
3748
3749 if is_actor {
3750 let arg_value = match &args[0].kind {
3752 ExprKind::Identifier(name) => {
3753 if let Ok(val) = self.lookup_variable(name) {
3755 val
3756 } else {
3757 let mut message = HashMap::new();
3759 message.insert(
3760 "__type".to_string(),
3761 Value::from_string("Message".to_string()),
3762 );
3763 message.insert("type".to_string(), Value::from_string(name.clone()));
3764 message.insert("data".to_string(), Value::Array(Arc::from(vec![])));
3765 Value::Object(Arc::new(message))
3766 }
3767 }
3768 _ => self.eval_expr(&args[0])?,
3769 };
3770 return self.dispatch_method_call(&receiver_value, method, &[arg_value], false);
3771 }
3772 }
3773
3774 let arg_values: Result<Vec<_>, _> = args.iter().map(|arg| self.eval_expr(arg)).collect();
3775 let arg_values = arg_values?;
3776
3777 self.dispatch_method_call(&receiver_value, method, &arg_values, args.is_empty())
3778 }
3779
3780 fn eval_message_expr(&mut self, message: &Expr) -> Result<Value, InterpreterError> {
3785 match &message.kind {
3786 ExprKind::Identifier(name) => {
3787 if let Ok(val) = self.lookup_variable(name) {
3789 Ok(val)
3790 } else {
3791 let mut msg_obj = HashMap::new();
3793 msg_obj.insert(
3794 "__type".to_string(),
3795 Value::from_string("Message".to_string()),
3796 );
3797 msg_obj.insert("type".to_string(), Value::from_string(name.clone()));
3798 msg_obj.insert("data".to_string(), Value::Array(Arc::from(vec![])));
3799 Ok(Value::Object(Arc::new(msg_obj)))
3800 }
3801 }
3802 _ => self.eval_expr(message),
3803 }
3804 }
3805
3806 fn dispatch_method_call(
3807 &mut self,
3808 receiver: &Value,
3809 method: &str,
3810 arg_values: &[Value],
3811 args_empty: bool,
3812 ) -> Result<Value, InterpreterError> {
3813 let base_method = if let Some(pos) = method.find("::") {
3817 &method[..pos]
3818 } else {
3819 method
3820 };
3821
3822 match receiver {
3823 Value::String(s) => self.eval_string_method(s, base_method, arg_values),
3824 Value::Array(arr) => self.eval_array_method(arr, base_method, arg_values),
3825 Value::Float(f) => self.eval_float_method(*f, base_method, args_empty),
3826 Value::Integer(n) => self.eval_integer_method(*n, base_method, arg_values),
3827 Value::DataFrame { columns } => self.eval_dataframe_method(columns, base_method, arg_values),
3828 Value::Object(obj) => {
3829 if base_method == "new" {
3831 if let Some(Value::String(ref type_str)) = obj.get("__type") {
3832 if let Some(Value::String(ref name)) = obj.get("__name") {
3833 match type_str.as_ref() {
3834 "Actor" => {
3835 return self.instantiate_actor_with_args(name, arg_values);
3836 }
3837 "Struct" => {
3838 return self.instantiate_struct_with_args(name, arg_values);
3839 }
3840 "Class" => {
3841 return self.instantiate_class_with_constructor(
3842 name, "new", arg_values,
3843 );
3844 }
3845 _ => {}
3846 }
3847 }
3848 }
3849 }
3850
3851 if let Some(Value::String(actor_name)) = obj.get("__actor") {
3853 self.eval_actor_instance_method(obj, actor_name.as_ref(), base_method, arg_values)
3854 }
3855 else if let Some(Value::String(class_name)) = obj.get("__class") {
3857 self.eval_class_instance_method(obj, class_name.as_ref(), base_method, arg_values)
3858 }
3859 else if let Some(Value::String(struct_name)) =
3861 obj.get("__struct_type").or_else(|| obj.get("__struct"))
3862 {
3863 self.eval_struct_instance_method(obj, struct_name.as_ref(), base_method, arg_values)
3864 }
3865 else if let Some(Value::String(type_str)) = obj.get("__type") {
3867 if type_str.as_ref() == "DataFrameBuilder" {
3868 self.eval_dataframe_builder_method(obj, base_method, arg_values)
3869 } else {
3870 self.eval_object_method(obj, base_method, arg_values, args_empty)
3871 }
3872 } else {
3873 self.eval_object_method(obj, base_method, arg_values, args_empty)
3874 }
3875 }
3876 Value::ObjectMut(cell_rc) => {
3877 let obj = cell_rc.lock().unwrap();
3880
3881 if let Some(Value::String(actor_name)) = obj.get("__actor") {
3883 let actor_name = actor_name.clone();
3884 drop(obj); self.eval_actor_instance_method_mut(
3886 cell_rc,
3887 actor_name.as_ref(),
3888 base_method,
3889 arg_values,
3890 )
3891 }
3892 else if let Some(Value::String(class_name)) = obj.get("__class") {
3894 let class_name = class_name.clone();
3895 drop(obj); self.eval_class_instance_method_mut(
3897 cell_rc,
3898 class_name.as_ref(),
3899 base_method,
3900 arg_values,
3901 )
3902 }
3903 else if let Some(Value::String(struct_name)) =
3905 obj.get("__struct_type").or_else(|| obj.get("__struct"))
3906 {
3907 let struct_name = struct_name.clone();
3908 drop(obj); self.eval_struct_instance_method_mut(
3910 cell_rc,
3911 struct_name.as_ref(),
3912 base_method,
3913 arg_values,
3914 )
3915 } else {
3916 drop(obj); self.eval_object_method_mut(cell_rc, base_method, arg_values, args_empty)
3918 }
3919 }
3920 Value::Struct { name, fields } => {
3921 self.eval_struct_instance_method(fields, name, base_method, arg_values)
3923 }
3924 Value::Class {
3925 class_name,
3926 fields,
3927 methods,
3928 } => {
3929 self.eval_class_instance_method_on_class(class_name, fields, methods, base_method, arg_values)
3931 }
3932 #[cfg(not(target_arch = "wasm32"))]
3933 Value::HtmlDocument(doc) => self.eval_html_document_method(doc, base_method, arg_values),
3934 #[cfg(not(target_arch = "wasm32"))]
3935 Value::HtmlElement(elem) => self.eval_html_element_method(elem, base_method, arg_values),
3936 _ => self.eval_generic_method(receiver, base_method, args_empty),
3937 }
3938 }
3939
3940 fn eval_float_method(
3941 &self,
3942 f: f64,
3943 method: &str,
3944 args_empty: bool,
3945 ) -> Result<Value, InterpreterError> {
3946 eval_method::eval_float_method(f, method, args_empty)
3947 }
3948
3949 fn eval_integer_method(
3950 &self,
3951 n: i64,
3952 method: &str,
3953 arg_values: &[Value],
3954 ) -> Result<Value, InterpreterError> {
3955 eval_method::eval_integer_method(n, method, arg_values)
3956 }
3957
3958 fn eval_generic_method(
3959 &self,
3960 receiver: &Value,
3961 method: &str,
3962 args_empty: bool,
3963 ) -> Result<Value, InterpreterError> {
3964 eval_method::eval_generic_method(receiver, method, args_empty)
3965 }
3966
3967 #[cfg(not(target_arch = "wasm32"))]
3970 fn eval_html_document_method(
3971 &self,
3972 doc: &crate::stdlib::html::HtmlDocument,
3973 method: &str,
3974 arg_values: &[Value],
3975 ) -> Result<Value, InterpreterError> {
3976 match method {
3977 "select" => {
3978 if arg_values.len() != 1 {
3979 return Err(InterpreterError::RuntimeError(
3980 "select() expects 1 argument (selector)".to_string(),
3981 ));
3982 }
3983 match &arg_values[0] {
3984 Value::String(selector) => {
3985 let elements = doc
3986 .select(selector.as_ref())
3987 .map_err(|e| InterpreterError::RuntimeError(format!("select() failed: {e}")))?;
3988 let values: Vec<Value> = elements
3989 .into_iter()
3990 .map(Value::HtmlElement)
3991 .collect();
3992 Ok(Value::Array(values.into()))
3993 }
3994 _ => Err(InterpreterError::RuntimeError(
3995 "select() expects a string selector".to_string(),
3996 )),
3997 }
3998 }
3999 "query_selector" => {
4000 if arg_values.len() != 1 {
4001 return Err(InterpreterError::RuntimeError(
4002 "query_selector() expects 1 argument (selector)".to_string(),
4003 ));
4004 }
4005 match &arg_values[0] {
4006 Value::String(selector) => {
4007 let element = doc
4008 .query_selector(selector.as_ref())
4009 .map_err(|e| InterpreterError::RuntimeError(format!("query_selector() failed: {e}")))?;
4010 Ok(element.map_or(Value::Nil, Value::HtmlElement))
4011 }
4012 _ => Err(InterpreterError::RuntimeError(
4013 "query_selector() expects a string selector".to_string(),
4014 )),
4015 }
4016 }
4017 "query_selector_all" => {
4018 if arg_values.len() != 1 {
4019 return Err(InterpreterError::RuntimeError(
4020 "query_selector_all() expects 1 argument (selector)".to_string(),
4021 ));
4022 }
4023 match &arg_values[0] {
4024 Value::String(selector) => {
4025 let elements = doc
4026 .query_selector_all(selector.as_ref())
4027 .map_err(|e| InterpreterError::RuntimeError(format!("query_selector_all() failed: {e}")))?;
4028 let values: Vec<Value> = elements
4029 .into_iter()
4030 .map(Value::HtmlElement)
4031 .collect();
4032 Ok(Value::Array(values.into()))
4033 }
4034 _ => Err(InterpreterError::RuntimeError(
4035 "query_selector_all() expects a string selector".to_string(),
4036 )),
4037 }
4038 }
4039 _ => Err(InterpreterError::RuntimeError(format!(
4040 "Unknown method '{}' on HtmlDocument",
4041 method
4042 ))),
4043 }
4044 }
4045
4046 #[cfg(not(target_arch = "wasm32"))]
4049 fn eval_html_element_method(
4050 &self,
4051 elem: &crate::stdlib::html::HtmlElement,
4052 method: &str,
4053 arg_values: &[Value],
4054 ) -> Result<Value, InterpreterError> {
4055 match method {
4056 "text" => {
4057 if !arg_values.is_empty() {
4058 return Err(InterpreterError::RuntimeError(
4059 "text() expects no arguments".to_string(),
4060 ));
4061 }
4062 Ok(Value::from_string(elem.text()))
4063 }
4064 "attr" => {
4065 if arg_values.len() != 1 {
4066 return Err(InterpreterError::RuntimeError(
4067 "attr() expects 1 argument (attribute name)".to_string(),
4068 ));
4069 }
4070 match &arg_values[0] {
4071 Value::String(attr_name) => {
4072 let value = elem.attr(attr_name.as_ref());
4073 Ok(value.map_or(Value::Nil, Value::from_string))
4074 }
4075 _ => Err(InterpreterError::RuntimeError(
4076 "attr() expects a string attribute name".to_string(),
4077 )),
4078 }
4079 }
4080 "html" => {
4081 if !arg_values.is_empty() {
4082 return Err(InterpreterError::RuntimeError(
4083 "html() expects no arguments".to_string(),
4084 ));
4085 }
4086 Ok(Value::from_string(elem.html()))
4087 }
4088 _ => Err(InterpreterError::RuntimeError(format!(
4089 "Unknown method '{}' on HtmlElement",
4090 method
4091 ))),
4092 }
4093 }
4094
4095 fn eval_actor_instance_method_mut(
4099 &mut self,
4100 cell_rc: &Arc<std::sync::Mutex<std::collections::HashMap<String, Value>>>,
4101 actor_name: &str,
4102 method: &str,
4103 arg_values: &[Value],
4104 ) -> Result<Value, InterpreterError> {
4105 if method == "send" {
4107 if arg_values.is_empty() {
4108 return Err(InterpreterError::RuntimeError(
4109 "send() requires a message argument".to_string(),
4110 ));
4111 }
4112 return self.process_actor_message_sync_mut(cell_rc, &arg_values[0]);
4113 }
4114
4115 let instance = cell_rc.lock().unwrap();
4117 self.eval_actor_instance_method(&instance, actor_name, method, arg_values)
4118 }
4119
4120 fn eval_class_instance_method_mut(
4121 &mut self,
4122 cell_rc: &Arc<std::sync::Mutex<std::collections::HashMap<String, Value>>>,
4123 class_name: &str,
4124 method: &str,
4125 arg_values: &[Value],
4126 ) -> Result<Value, InterpreterError> {
4127 let class_def = self.lookup_variable(class_name)?;
4132
4133 if let Value::Object(ref class_info) = class_def {
4134 if let Some(Value::Object(ref methods)) = class_info.get("__methods") {
4136 if let Some(Value::Object(ref method_meta)) = methods.get(method) {
4137 if let Some(Value::Closure { params, body, .. }) = method_meta.get("closure") {
4139 let is_static = method_meta
4141 .get("is_static")
4142 .and_then(|v| {
4143 if let Value::Bool(b) = v {
4144 Some(*b)
4145 } else {
4146 None
4147 }
4148 })
4149 .unwrap_or(false);
4150
4151 if is_static {
4152 return Err(InterpreterError::RuntimeError(format!(
4153 "Cannot call static method {} on instance",
4154 method
4155 )));
4156 }
4157
4158 let mut method_env = HashMap::new();
4160
4161 method_env
4164 .insert("self".to_string(), Value::ObjectMut(Arc::clone(cell_rc)));
4165
4166 if arg_values.len() != params.len() {
4168 return Err(InterpreterError::RuntimeError(format!(
4169 "Method {} expects {} arguments, got {}",
4170 method,
4171 params.len(),
4172 arg_values.len()
4173 )));
4174 }
4175
4176 for (param, arg) in params.iter().zip(arg_values) {
4177 method_env.insert(param.clone(), arg.clone());
4178 }
4179
4180 self.env_push(method_env);
4182
4183 let result = self.eval_expr(body)?;
4185
4186 self.env_pop();
4188
4189 return Ok(result);
4190 }
4191 }
4192 }
4193
4194 Err(InterpreterError::RuntimeError(format!(
4196 "Class {} has no method named {}",
4197 class_name, method
4198 )))
4199 } else {
4200 Err(InterpreterError::RuntimeError(format!(
4201 "{} is not a class",
4202 class_name
4203 )))
4204 }
4205 }
4206
4207 fn eval_class_instance_method_on_class(
4210 &mut self,
4211 class_name: &str,
4212 fields: &Arc<std::sync::RwLock<HashMap<String, Value>>>,
4213 methods: &Arc<HashMap<String, Value>>,
4214 method: &str,
4215 arg_values: &[Value],
4216 ) -> Result<Value, InterpreterError> {
4217 if let Some(method_closure) = methods.get(method) {
4219 if let Value::Closure { params, body, .. } = method_closure {
4220 if arg_values.len() != params.len() {
4222 return Err(InterpreterError::RuntimeError(format!(
4223 "Method {} expects {} arguments, got {}",
4224 method,
4225 params.len(),
4226 arg_values.len()
4227 )));
4228 }
4229
4230 let mut method_env = HashMap::new();
4232
4233 method_env.insert(
4235 "self".to_string(),
4236 Value::Class {
4237 class_name: class_name.to_string(),
4238 fields: Arc::clone(fields),
4239 methods: Arc::clone(methods),
4240 },
4241 );
4242
4243 for (param, arg) in params.iter().zip(arg_values) {
4245 method_env.insert(param.clone(), arg.clone());
4246 }
4247
4248 self.env_push(method_env);
4250
4251 let result = self.eval_expr(body)?;
4253
4254 self.env_pop();
4256
4257 Ok(result)
4258 } else {
4259 Err(InterpreterError::RuntimeError(format!(
4260 "Method {} is not a closure",
4261 method
4262 )))
4263 }
4264 } else {
4265 Err(InterpreterError::RuntimeError(format!(
4266 "Method '{}' not found for type class",
4267 method
4268 )))
4269 }
4270 }
4271
4272 fn eval_struct_instance_method_mut(
4273 &mut self,
4274 cell_rc: &Arc<std::sync::Mutex<std::collections::HashMap<String, Value>>>,
4275 struct_name: &str,
4276 method: &str,
4277 arg_values: &[Value],
4278 ) -> Result<Value, InterpreterError> {
4279 let instance = cell_rc.lock().unwrap();
4280 self.eval_struct_instance_method(&instance, struct_name, method, arg_values)
4281 }
4282
4283 fn eval_object_method_mut(
4284 &mut self,
4285 cell_rc: &Arc<std::sync::Mutex<std::collections::HashMap<String, Value>>>,
4286 method: &str,
4287 arg_values: &[Value],
4288 args_empty: bool,
4289 ) -> Result<Value, InterpreterError> {
4290 let instance = cell_rc.lock().unwrap();
4291 self.eval_object_method(&instance, method, arg_values, args_empty)
4292 }
4293
4294 fn eval_actor_instance_method(
4329 &mut self,
4330 instance: &std::collections::HashMap<String, Value>,
4331 _actor_name: &str,
4332 method: &str,
4333 arg_values: &[Value],
4334 ) -> Result<Value, InterpreterError> {
4335 match method {
4336 "send" => {
4337 if arg_values.is_empty() {
4339 return Err(InterpreterError::RuntimeError(
4340 "send() requires a message argument".to_string(),
4341 ));
4342 }
4343
4344 if let Some(Value::String(actor_id)) = instance.get("__actor_id") {
4346 use crate::runtime::actor_runtime::{ActorMessage, ACTOR_RUNTIME};
4347
4348 let message = &arg_values[0];
4350 let (msg_type, msg_data) = if let Value::Object(msg_obj) = message {
4351 if let Some(Value::String(type_str)) = msg_obj.get("__type") {
4352 if type_str.as_ref() == "Message" {
4353 let msg_type = msg_obj
4354 .get("type")
4355 .and_then(|v| {
4356 if let Value::String(s) = v {
4357 Some(s.to_string())
4358 } else {
4359 None
4360 }
4361 })
4362 .unwrap_or_else(|| "Unknown".to_string());
4363 let msg_data = msg_obj
4364 .get("data")
4365 .and_then(|v| {
4366 if let Value::Array(arr) = v {
4367 Some(arr.to_vec())
4368 } else {
4369 None
4370 }
4371 })
4372 .unwrap_or_else(Vec::new);
4373 (msg_type, msg_data)
4374 } else {
4375 ("Unknown".to_string(), vec![])
4376 }
4377 } else {
4378 ("Unknown".to_string(), vec![])
4379 }
4380 } else {
4381 ("Message".to_string(), vec![message.clone()])
4383 };
4384
4385 let str_data: Vec<String> =
4387 msg_data.iter().map(|v| format!("{:?}", v)).collect();
4388
4389 let actor_msg = ActorMessage {
4391 message_type: msg_type,
4392 data: str_data,
4393 };
4394
4395 ACTOR_RUNTIME.send_message(actor_id.as_ref(), actor_msg)?;
4396 return Ok(Value::Nil);
4397 }
4398
4399 self.process_actor_message_sync(instance, &arg_values[0])
4401 }
4402 "stop" => {
4403 Ok(Value::Bool(true))
4406 }
4407 "ask" => {
4408 if arg_values.is_empty() {
4411 return Err(InterpreterError::RuntimeError(
4412 "ask() requires a message argument".to_string(),
4413 ));
4414 }
4415
4416 let message = &arg_values[0];
4418
4419 if let Value::Object(msg_obj) = message {
4421 if let Some(Value::String(type_str)) = msg_obj.get("__type") {
4423 if type_str.as_ref() == "Message" {
4424 if let Some(Value::String(msg_type)) = msg_obj.get("type") {
4426 if let Some(Value::Array(data)) = msg_obj.get("data") {
4427 if let Some(handlers) = instance.get("__handlers") {
4429 if let Value::Array(handler_list) = handlers {
4430 for handler in handler_list.iter() {
4432 if let Value::Object(h) = handler {
4433 if let Some(Value::String(h_type)) =
4434 h.get("message_type")
4435 {
4436 if h_type.as_ref() == msg_type.as_ref() {
4437 if let Some(Value::Closure {
4439 params,
4440 body,
4441 env,
4442 }) = h.get("handler")
4443 {
4444 let mut handler_env =
4446 (**env).clone();
4447
4448 for (i, param_name) in
4450 params.iter().enumerate()
4451 {
4452 if let Some(value) = data.get(i)
4453 {
4454 handler_env.insert(
4455 param_name.clone(),
4456 value.clone(),
4457 );
4458 }
4459 }
4460
4461 handler_env.insert(
4463 "self".to_string(),
4464 Value::Object(Arc::new(
4465 instance.clone(),
4466 )),
4467 );
4468
4469 self.env_push(handler_env);
4471 let result =
4472 self.eval_expr(body)?;
4473 self.env_pop();
4474
4475 return Ok(result);
4476 }
4477 }
4478 }
4479 }
4480 }
4481 }
4482 }
4483
4484 return Ok(Value::from_string(format!(
4486 "Received: {}",
4487 msg_type.as_ref()
4488 )));
4489 }
4490 }
4491 }
4492 }
4493 }
4494
4495 Ok(message.clone())
4497 }
4498 _ => Err(InterpreterError::RuntimeError(format!(
4499 "Unknown actor method: {}",
4500 method
4501 ))),
4502 }
4503 }
4504
4505 fn process_actor_message_sync(
4543 &mut self,
4544 instance: &std::collections::HashMap<String, Value>,
4545 message: &Value,
4546 ) -> Result<Value, InterpreterError> {
4547 let (msg_type, msg_args) = if let Value::Object(msg_obj) = message {
4550 if let Some(Value::String(type_str)) = msg_obj.get("__type") {
4552 if type_str.as_ref() == "Message" {
4553 let msg_type = msg_obj
4554 .get("type")
4555 .and_then(|v| {
4556 if let Value::String(s) = v {
4557 Some(s.to_string())
4558 } else {
4559 None
4560 }
4561 })
4562 .unwrap_or_else(|| "Unknown".to_string());
4563 let msg_args = msg_obj
4564 .get("data")
4565 .and_then(|v| {
4566 if let Value::Array(arr) = v {
4567 Some(arr.to_vec())
4568 } else {
4569 None
4570 }
4571 })
4572 .unwrap_or_else(Vec::new);
4573 (msg_type, msg_args)
4574 } else {
4575 return Err(InterpreterError::RuntimeError(
4576 "Invalid message format".to_string(),
4577 ));
4578 }
4579 } else {
4580 return Err(InterpreterError::RuntimeError(
4581 "Invalid message format".to_string(),
4582 ));
4583 }
4584 } else {
4585 return Err(InterpreterError::RuntimeError(
4586 "Message must be an object".to_string(),
4587 ));
4588 };
4589
4590 if let Some(Value::Array(handlers)) = instance.get("__handlers") {
4592 for handler in handlers.iter() {
4593 if let Value::Object(handler_obj) = handler {
4594 if let Some(Value::String(handler_type)) = handler_obj.get("message_type") {
4595 if handler_type.as_ref() == msg_type {
4596 if let Some(Value::Closure { params, body, env }) =
4598 handler_obj.get("body")
4599 {
4600 let mut handler_env = (**env).clone();
4602
4603 for (i, param_name) in params.iter().enumerate() {
4605 if let Some(value) = msg_args.get(i) {
4606 handler_env.insert(param_name.clone(), value.clone());
4607 }
4608 }
4609
4610 let mut self_obj = HashMap::new();
4613 for (key, value) in instance {
4614 if !key.starts_with("__") {
4615 self_obj.insert(key.clone(), value.clone());
4616 }
4617 }
4618 handler_env
4619 .insert("self".to_string(), Value::Object(Arc::new(self_obj)));
4620
4621 self.env_stack.push(handler_env);
4623 let result = self.eval_expr(body);
4624 self.env_stack.pop();
4625
4626 return result;
4627 }
4628 }
4629 }
4630 }
4631 }
4632 }
4633
4634 Err(InterpreterError::RuntimeError(format!(
4635 "No handler found for message type: {}",
4636 msg_type
4637 )))
4638 }
4639
4640 fn process_actor_message_sync_mut(
4645 &mut self,
4646 cell_rc: &Arc<std::sync::Mutex<std::collections::HashMap<String, Value>>>,
4647 message: &Value,
4648 ) -> Result<Value, InterpreterError> {
4649 let instance = cell_rc.lock().unwrap();
4650
4651 let (msg_type, msg_args) = if let Value::Object(msg_obj) = message {
4653 if let Some(Value::String(type_str)) = msg_obj.get("__type") {
4654 if type_str.as_ref() == "Message" {
4655 let msg_type = msg_obj
4656 .get("type")
4657 .and_then(|v| {
4658 if let Value::String(s) = v {
4659 Some(s.to_string())
4660 } else {
4661 None
4662 }
4663 })
4664 .unwrap_or_else(|| "Unknown".to_string());
4665 let msg_args = msg_obj
4666 .get("data")
4667 .and_then(|v| {
4668 if let Value::Array(arr) = v {
4669 Some(arr.to_vec())
4670 } else {
4671 None
4672 }
4673 })
4674 .unwrap_or_else(Vec::new);
4675 (msg_type, msg_args)
4676 } else {
4677 return Err(InterpreterError::RuntimeError(
4678 "Invalid message format".to_string(),
4679 ));
4680 }
4681 } else {
4682 return Err(InterpreterError::RuntimeError(
4683 "Invalid message format".to_string(),
4684 ));
4685 }
4686 } else {
4687 return Err(InterpreterError::RuntimeError(
4688 "Message must be an object".to_string(),
4689 ));
4690 };
4691
4692 if let Some(Value::Array(handlers)) = instance.get("__handlers") {
4694 for handler in handlers.iter() {
4695 if let Value::Object(handler_obj) = handler {
4696 if let Some(Value::String(handler_type)) = handler_obj.get("message_type") {
4697 if handler_type.as_ref() == msg_type {
4698 if let Some(Value::Closure { params, body, env }) =
4700 handler_obj.get("body")
4701 {
4702 let params_clone = params.clone();
4704 let body_clone = body.clone();
4705 let env_clone = env.clone();
4706
4707 let param_types = handler_obj.get("param_types").and_then(|v| {
4709 if let Value::Array(types) = v {
4710 Some(types.clone())
4711 } else {
4712 None
4713 }
4714 });
4715
4716 drop(instance); if let Some(types) = param_types {
4720 for (i, expected_type_val) in types.iter().enumerate() {
4721 if let Value::String(expected_type) = expected_type_val {
4722 if let Some(actual_value) = msg_args.get(i) {
4723 let actual_type = actual_value.type_name();
4724 let expected_runtime_type =
4726 match expected_type.as_ref() {
4727 "i32" | "i64" | "int" => "integer",
4728 "f32" | "f64" | "float" => "float",
4729 "String" | "string" | "str" => "string",
4730 "bool" => "boolean",
4731 _ => expected_type.as_ref(),
4732 };
4733
4734 if actual_type != expected_runtime_type
4735 && expected_runtime_type != "Any"
4736 {
4737 return Err(InterpreterError::RuntimeError(format!(
4738 "Type error in message {}: parameter {} expects type '{}', got '{}'",
4739 msg_type, i, expected_runtime_type, actual_type
4740 )));
4741 }
4742 }
4743 }
4744 }
4745 }
4746
4747 let mut handler_env = (*env_clone).clone();
4749
4750 for (i, param_name) in params_clone.iter().enumerate() {
4752 if let Some(value) = msg_args.get(i) {
4753 handler_env.insert(param_name.clone(), value.clone());
4754 }
4755 }
4756
4757 handler_env.insert(
4760 "self".to_string(),
4761 Value::ObjectMut(Arc::clone(cell_rc)),
4762 );
4763
4764 self.env_stack.push(handler_env);
4766 let result = self.eval_expr(&body_clone);
4767 self.env_stack.pop();
4768
4769 return result;
4770 }
4771 }
4772 }
4773 }
4774 }
4775 }
4776
4777 Err(InterpreterError::RuntimeError(format!(
4778 "No handler found for message type: {}",
4779 msg_type
4780 )))
4781 }
4782
4783 fn eval_struct_instance_method(
4784 &mut self,
4785 instance: &std::collections::HashMap<String, Value>,
4786 struct_name: &str,
4787 method: &str,
4788 arg_values: &[Value],
4789 ) -> Result<Value, InterpreterError> {
4790 let qualified_method_name = format!("{}::{}", struct_name, method);
4792
4793 if let Ok(method_closure) = self.lookup_variable(&qualified_method_name) {
4794 if let Value::Closure { params, body, env } = method_closure {
4795 let expected_args = params.len();
4797 let provided_args = arg_values.len() + 1; if provided_args != expected_args {
4800 return Err(InterpreterError::RuntimeError(format!(
4801 "Method {} expects {} arguments, got {}",
4802 method,
4803 expected_args - 1, arg_values.len()
4805 )));
4806 }
4807
4808 let mut new_env = (*env).clone();
4810
4811 if let Some(self_param) = params.first() {
4814 new_env.insert(
4815 self_param.clone(),
4816 Value::Struct {
4817 name: struct_name.to_string(),
4818 fields: std::sync::Arc::new(instance.clone()),
4819 },
4820 );
4821 }
4822
4823 for (i, arg_value) in arg_values.iter().enumerate() {
4825 if let Some(param_name) = params.get(i + 1) {
4826 new_env.insert(param_name.clone(), arg_value.clone());
4828 }
4829 }
4830
4831 self.env_stack.push(new_env);
4833 let result = self.eval_expr(&body);
4834 self.env_stack.pop();
4835
4836 result
4837 } else {
4838 Err(InterpreterError::RuntimeError(format!(
4839 "Found {} but it's not a method closure",
4840 qualified_method_name
4841 )))
4842 }
4843 } else {
4844 self.eval_generic_method(
4846 &Value::Object(std::sync::Arc::new(instance.clone())),
4847 method,
4848 arg_values.is_empty(),
4849 )
4850 }
4851 }
4852
4853 fn eval_object_method(
4854 &self,
4855 obj: &std::collections::HashMap<String, Value>,
4856 method: &str,
4857 arg_values: &[Value],
4858 args_empty: bool,
4859 ) -> Result<Value, InterpreterError> {
4860 use crate::runtime::eval_method_dispatch;
4861 eval_method_dispatch::eval_method_call(
4862 &Value::Object(std::sync::Arc::new(obj.clone())),
4863 method,
4864 arg_values,
4865 args_empty,
4866 |_receiver, _args| {
4867 Err(InterpreterError::RuntimeError(
4868 "Function call not implemented in actor context".to_string(),
4869 ))
4870 },
4871 |_receiver, _args| {
4872 Err(InterpreterError::RuntimeError(
4873 "DataFrame filter not implemented in actor context".to_string(),
4874 ))
4875 },
4876 |_expr, _columns, _index| {
4877 Err(InterpreterError::RuntimeError(
4878 "Column context not implemented in actor context".to_string(),
4879 ))
4880 },
4881 )
4882 }
4883
4884 fn eval_actor_definition(
4889 &mut self,
4890 name: &str,
4891 state: &[crate::frontend::ast::StructField],
4892 handlers: &[crate::frontend::ast::ActorHandler],
4893 ) -> Result<Value, InterpreterError> {
4894 use std::collections::HashMap;
4895
4896 let mut actor_type = HashMap::new();
4898
4899 actor_type.insert(
4901 "__type".to_string(),
4902 Value::from_string("Actor".to_string()),
4903 );
4904 actor_type.insert("__name".to_string(), Value::from_string(name.to_string()));
4905
4906 let mut fields = HashMap::new();
4908 for field in state {
4909 let type_name = match &field.ty.kind {
4910 crate::frontend::ast::TypeKind::Named(n) => n.clone(),
4911 _ => "Any".to_string(),
4912 };
4913
4914 let mut field_meta = HashMap::new();
4916 field_meta.insert("type".to_string(), Value::from_string(type_name));
4917 field_meta.insert("is_mut".to_string(), Value::Bool(field.is_mut));
4918
4919 if let Some(ref default_expr) = field.default_value {
4921 match self.eval_expr(default_expr) {
4922 Ok(default_val) => {
4923 field_meta.insert("default".to_string(), default_val);
4924 }
4925 Err(_) => {
4926 field_meta.insert("default".to_string(), Value::Nil);
4928 }
4929 }
4930 } else {
4931 field_meta.insert("default".to_string(), Value::Nil);
4933 }
4934
4935 fields.insert(field.name.clone(), Value::Object(Arc::new(field_meta)));
4936 }
4937 actor_type.insert(
4938 "__fields".to_string(),
4939 Value::Object(std::sync::Arc::new(fields)),
4940 );
4941
4942 let mut handlers_array = Vec::new();
4944 for handler in handlers {
4945 let mut handler_obj = HashMap::new();
4947 handler_obj.insert(
4948 "message_type".to_string(),
4949 Value::from_string(handler.message_type.clone()),
4950 );
4951
4952 let param_names: Vec<String> = handler
4954 .params
4955 .iter()
4956 .map(crate::frontend::ast::Param::name)
4957 .collect();
4958 handler_obj.insert(
4959 "params".to_string(),
4960 Value::Array(Arc::from(
4961 param_names
4962 .iter()
4963 .map(|n| Value::from_string(n.clone()))
4964 .collect::<Vec<_>>(),
4965 )),
4966 );
4967
4968 let param_types: Vec<String> = handler
4970 .params
4971 .iter()
4972 .map(|p| match &p.ty.kind {
4973 crate::frontend::ast::TypeKind::Named(name) => name.clone(),
4974 _ => "Any".to_string(),
4975 })
4976 .collect();
4977 handler_obj.insert(
4978 "param_types".to_string(),
4979 Value::Array(Arc::from(
4980 param_types
4981 .iter()
4982 .map(|t| Value::from_string(t.clone()))
4983 .collect::<Vec<_>>(),
4984 )),
4985 );
4986
4987 handler_obj.insert(
4990 "body".to_string(),
4991 Value::Closure {
4992 params: param_names,
4993 body: Arc::new(*handler.body.clone()),
4994 env: Arc::new(self.current_env().clone()),
4995 },
4996 );
4997
4998 handlers_array.push(Value::Object(Arc::new(handler_obj)));
4999 }
5000 actor_type.insert(
5001 "__handlers".to_string(),
5002 Value::Array(Arc::from(handlers_array)),
5003 );
5004
5005 let actor_obj = Value::Object(std::sync::Arc::new(actor_type));
5007 self.set_variable(name, actor_obj.clone());
5008
5009 Ok(actor_obj)
5010 }
5011
5012 fn eval_struct_definition(
5016 &mut self,
5017 name: &str,
5018 _type_params: &[String], fields: &[crate::frontend::ast::StructField],
5020 _is_pub: bool,
5021 ) -> Result<Value, InterpreterError> {
5022 use std::collections::HashMap;
5023
5024 let mut struct_type = HashMap::new();
5026
5027 struct_type.insert(
5029 "__type".to_string(),
5030 Value::from_string("Struct".to_string()),
5031 );
5032 struct_type.insert("__name".to_string(), Value::from_string(name.to_string()));
5033
5034 let mut field_defs = HashMap::new();
5036 for field in fields {
5037 let type_name = match &field.ty.kind {
5039 crate::frontend::ast::TypeKind::Named(n) => n.clone(),
5040 crate::frontend::ast::TypeKind::Array { .. } => "Array".to_string(),
5041 crate::frontend::ast::TypeKind::Optional(_) => "Option".to_string(),
5042 crate::frontend::ast::TypeKind::List(_) => "List".to_string(),
5043 crate::frontend::ast::TypeKind::Tuple(_) => "Tuple".to_string(),
5044 _ => "Any".to_string(),
5045 };
5046
5047 let mut field_info = HashMap::new();
5048 field_info.insert("type".to_string(), Value::from_string(type_name));
5049 field_info.insert(
5050 "is_pub".to_string(),
5051 Value::from_bool(field.visibility.is_public()),
5052 );
5053 field_info.insert("is_mut".to_string(), Value::from_bool(field.is_mut));
5054 let visibility_str = match field.visibility {
5056 crate::frontend::ast::Visibility::Public => "pub",
5057 crate::frontend::ast::Visibility::PubCrate => "pub(crate)",
5058 crate::frontend::ast::Visibility::PubSuper => "pub(super)",
5059 crate::frontend::ast::Visibility::Private => "private",
5060 crate::frontend::ast::Visibility::Protected => "protected",
5061 };
5062 field_info.insert(
5063 "visibility".to_string(),
5064 Value::from_string(visibility_str.to_string()),
5065 );
5066
5067 if let Some(default_expr) = &field.default_value {
5069 let default_val = self.eval_expr(default_expr)?;
5070 field_info.insert("default".to_string(), default_val);
5071 }
5072
5073 field_defs.insert(
5074 field.name.clone(),
5075 Value::Object(std::sync::Arc::new(field_info)),
5076 );
5077 }
5078
5079 struct_type.insert(
5080 "__fields".to_string(),
5081 Value::Object(std::sync::Arc::new(field_defs)),
5082 );
5083
5084 let struct_obj = Value::Object(std::sync::Arc::new(struct_type));
5086 self.set_variable(name, struct_obj.clone());
5087
5088 Ok(struct_obj)
5089 }
5090
5091 fn eval_enum_definition(
5095 &mut self,
5096 name: &str,
5097 _type_params: &[String], variants: &[crate::frontend::ast::EnumVariant],
5099 _is_pub: bool,
5100 ) -> Result<Value, InterpreterError> {
5101 use std::collections::HashMap;
5102
5103 let mut enum_type = HashMap::new();
5105
5106 enum_type.insert(
5108 "__type".to_string(),
5109 Value::from_string("Enum".to_string()),
5110 );
5111 enum_type.insert("__name".to_string(), Value::from_string(name.to_string()));
5112
5113 let mut variant_defs = HashMap::new();
5115 for variant in variants {
5116 let mut variant_info = HashMap::new();
5117
5118 let kind_str = match &variant.kind {
5120 crate::frontend::ast::EnumVariantKind::Unit => "Unit",
5121 crate::frontend::ast::EnumVariantKind::Tuple(_) => "Tuple",
5122 crate::frontend::ast::EnumVariantKind::Struct(_) => "Struct",
5123 };
5124 variant_info.insert("kind".to_string(), Value::from_string(kind_str.to_string()));
5125
5126 if let Some(disc) = variant.discriminant {
5128 variant_info.insert("discriminant".to_string(), Value::Integer(disc));
5129 }
5130
5131 variant_defs.insert(
5132 variant.name.clone(),
5133 Value::Object(std::sync::Arc::new(variant_info)),
5134 );
5135 }
5136
5137 enum_type.insert(
5138 "__variants".to_string(),
5139 Value::Object(std::sync::Arc::new(variant_defs)),
5140 );
5141
5142 let enum_obj = Value::Object(std::sync::Arc::new(enum_type));
5144 self.set_variable(name, enum_obj.clone());
5145
5146 Ok(enum_obj)
5147 }
5148
5149 fn eval_struct_literal(
5153 &mut self,
5154 name: &str,
5155 fields: &[(String, crate::frontend::ast::Expr)],
5156 ) -> Result<Value, InterpreterError> {
5157 use std::collections::HashMap;
5158
5159 let struct_type = self.lookup_variable(name).map_err(|_| {
5161 InterpreterError::RuntimeError(format!("Undefined struct type: {name}"))
5162 })?;
5163
5164 let struct_type_obj = if let Value::Object(obj) = &struct_type {
5166 obj
5167 } else {
5168 return Err(InterpreterError::RuntimeError(format!(
5169 "{name} is not a struct type"
5170 )));
5171 };
5172
5173 let type_name = struct_type_obj
5175 .get("__type")
5176 .and_then(|v| {
5177 if let Value::String(s) = v {
5178 Some(s.as_ref())
5179 } else {
5180 None
5181 }
5182 })
5183 .unwrap_or("");
5184
5185 if type_name == "Actor" {
5187 let mut field_values = Vec::new();
5189 for (field_name, field_expr) in fields {
5190 let value = self.eval_expr(field_expr)?;
5191 field_values.push((field_name.clone(), value));
5192 }
5193
5194 let mut args_obj = HashMap::new();
5196 for (name, value) in field_values {
5197 args_obj.insert(name, value);
5198 }
5199
5200 return self.instantiate_actor_with_args(name, &[Value::Object(Arc::new(args_obj))]);
5202 }
5203
5204 if type_name != "Struct" {
5205 return Err(InterpreterError::RuntimeError(format!(
5206 "{name} is not a struct type (it's a {type_name})"
5207 )));
5208 }
5209
5210 let field_defs = struct_type_obj
5212 .get("__fields")
5213 .and_then(|v| {
5214 if let Value::Object(obj) = v {
5215 Some(obj)
5216 } else {
5217 None
5218 }
5219 })
5220 .ok_or_else(|| {
5221 InterpreterError::RuntimeError(format!("Invalid struct type definition for {name}"))
5222 })?;
5223
5224 let mut instance_fields = HashMap::new();
5226
5227 for (field_name, field_expr) in fields {
5229 if !field_defs.contains_key(field_name) {
5231 return Err(InterpreterError::RuntimeError(format!(
5232 "Struct {name} does not have field '{field_name}'"
5233 )));
5234 }
5235
5236 let field_value = self.eval_expr(field_expr)?;
5238 instance_fields.insert(field_name.clone(), field_value);
5239 }
5240
5241 for (field_name, field_def_value) in field_defs.iter() {
5243 if !instance_fields.contains_key(field_name) {
5244 if let Value::Object(field_info) = field_def_value {
5246 if let Some(default_val) = field_info.get("default") {
5247 instance_fields.insert(field_name.clone(), default_val.clone());
5249 } else {
5250 return Err(InterpreterError::RuntimeError(format!(
5252 "Missing required field '{field_name}' for struct {name}"
5253 )));
5254 }
5255 } else {
5256 return Err(InterpreterError::RuntimeError(format!(
5257 "Invalid field definition for '{field_name}' in struct {name}"
5258 )));
5259 }
5260 }
5261 }
5262
5263 Ok(Value::Struct {
5265 name: name.to_string(),
5266 fields: Arc::new(instance_fields),
5267 })
5268 }
5269
5270 fn eval_class_definition(
5286 &mut self,
5287 name: &str,
5288 _type_params: &[String],
5289 superclass: Option<&String>,
5290 _traits: &[String],
5291 fields: &[crate::frontend::ast::StructField],
5292 constructors: &[crate::frontend::ast::Constructor],
5293 methods: &[crate::frontend::ast::ClassMethod],
5294 constants: &[crate::frontend::ast::ClassConstant],
5295 _derives: &[String],
5296 _is_pub: bool,
5297 ) -> Result<Value, InterpreterError> {
5298 use std::collections::HashMap;
5299 use std::sync::Arc;
5300
5301 let mut class_info = HashMap::new();
5303
5304 class_info.insert(
5306 "__type".to_string(),
5307 Value::from_string("Class".to_string()),
5308 );
5309 class_info.insert("__name".to_string(), Value::from_string(name.to_string()));
5310
5311 if let Some(parent) = superclass {
5313 class_info.insert(
5314 "__superclass".to_string(),
5315 Value::from_string(parent.clone()),
5316 );
5317 }
5318
5319 let mut field_defs = HashMap::new();
5321 for field in fields {
5322 let mut field_info = HashMap::new();
5323
5324 let type_str = format!("{:?}", field.ty);
5326 field_info.insert("type".to_string(), Value::from_string(type_str));
5327
5328 field_info.insert(
5330 "is_pub".to_string(),
5331 Value::Bool(field.visibility.is_public()),
5332 );
5333 field_info.insert("is_mut".to_string(), Value::Bool(field.is_mut));
5334
5335 if let Some(ref default) = field.default_value {
5337 let default_val = self.eval_expr(default)?;
5339 field_info.insert("default".to_string(), default_val);
5340 }
5341
5342 field_defs.insert(
5343 field.name.clone(),
5344 Value::Object(std::sync::Arc::new(field_info)),
5345 );
5346 }
5347 class_info.insert("__fields".to_string(), Value::Object(Arc::new(field_defs)));
5348
5349 let mut constructor_info = HashMap::new();
5351 for constructor in constructors {
5352 let ctor_name = constructor
5354 .name
5355 .as_ref()
5356 .unwrap_or(&"new".to_string())
5357 .clone();
5358
5359 let param_names: Vec<String> = constructor
5361 .params
5362 .iter()
5363 .map(|p| match &p.pattern {
5364 crate::frontend::ast::Pattern::Identifier(name) => name.clone(),
5365 _ => "_".to_string(),
5366 })
5367 .collect();
5368
5369 let ctor_closure = Value::Closure {
5371 params: param_names,
5372 body: Arc::new((*constructor.body).clone()),
5373 env: Arc::new(HashMap::new()), };
5375
5376 constructor_info.insert(ctor_name, ctor_closure);
5377 }
5378
5379 if constructor_info.is_empty() {
5381 let default_body = Expr::new(
5383 ExprKind::Block(Vec::new()), crate::frontend::ast::Span::new(0, 0),
5385 );
5386
5387 let default_constructor = Value::Closure {
5388 params: Vec::new(), body: Arc::new(default_body),
5390 env: Arc::new(HashMap::new()),
5391 };
5392
5393 constructor_info.insert("new".to_string(), default_constructor);
5394 }
5395
5396 class_info.insert(
5397 "__constructors".to_string(),
5398 Value::Object(Arc::new(constructor_info)),
5399 );
5400
5401 let mut method_info = HashMap::new();
5403 for method in methods {
5404 let param_names: Vec<String> = method
5406 .params
5407 .iter()
5408 .filter_map(|p| match &p.pattern {
5409 crate::frontend::ast::Pattern::Identifier(name) if name != "self" => {
5410 Some(name.clone())
5411 }
5412 crate::frontend::ast::Pattern::Identifier(_) => None, _ => Some("_".to_string()),
5414 })
5415 .collect();
5416
5417 let method_closure = Value::Closure {
5419 params: param_names,
5420 body: Arc::new((*method.body).clone()),
5421 env: Arc::new(HashMap::new()),
5422 };
5423
5424 let mut method_meta = HashMap::new();
5426 method_meta.insert("closure".to_string(), method_closure);
5427 method_meta.insert("is_static".to_string(), Value::Bool(method.is_static));
5428 method_meta.insert("is_override".to_string(), Value::Bool(method.is_override));
5429
5430 method_info.insert(method.name.clone(), Value::Object(Arc::new(method_meta)));
5431 }
5432 class_info.insert(
5433 "__methods".to_string(),
5434 Value::Object(Arc::new(method_info)),
5435 );
5436
5437 let mut constants_info = HashMap::new();
5439 for constant in constants {
5440 let const_value = self.eval_expr(&constant.value)?;
5442
5443 let mut const_meta = HashMap::new();
5445 const_meta.insert("value".to_string(), const_value.clone());
5446 const_meta.insert(
5447 "type".to_string(),
5448 Value::from_string(format!("{:?}", constant.ty)),
5449 );
5450 const_meta.insert("is_pub".to_string(), Value::Bool(constant.is_pub));
5451
5452 constants_info.insert(constant.name.clone(), Value::Object(Arc::new(const_meta)));
5453
5454 let qualified_name = format!("{}::{}", name, constant.name);
5457 self.set_variable(&qualified_name, const_value);
5458 }
5459 class_info.insert(
5460 "__constants".to_string(),
5461 Value::Object(Arc::new(constants_info)),
5462 );
5463
5464 let class_value = Value::Object(Arc::new(class_info));
5466 self.set_variable(name, class_value.clone());
5467
5468 Ok(class_value)
5469 }
5470
5471 fn eval_impl_block(
5472 &mut self,
5473 for_type: &str,
5474 methods: &[crate::frontend::ast::ImplMethod],
5475 ) -> Result<Value, InterpreterError> {
5476 use std::collections::HashMap;
5477 use std::sync::Arc;
5478
5479 let mut impl_methods = HashMap::new();
5482
5483 for method in methods {
5484 let param_names: Vec<String> = method
5486 .params
5487 .iter()
5488 .map(|p| match &p.pattern {
5489 crate::frontend::ast::Pattern::Identifier(name) => name.clone(),
5490 _ => "_".to_string(), })
5492 .collect();
5493
5494 let closure = Value::Closure {
5496 params: param_names,
5497 body: Arc::new(*method.body.clone()),
5498 env: Arc::new(HashMap::new()),
5499 };
5500 impl_methods.insert(method.name.clone(), closure);
5501 }
5502
5503 for (method_name, method_closure) in impl_methods {
5506 let qualified_name = format!("{}::{}", for_type, method_name);
5507 self.set_variable(&qualified_name, method_closure);
5508 }
5509
5510 Ok(Value::Nil) }
5512
5513 fn instantiate_class_with_constructor(
5554 &mut self,
5555 class_name: &str,
5556 constructor_name: &str,
5557 args: &[Value],
5558 ) -> Result<Value, InterpreterError> {
5559 let class_def = self.lookup_variable(class_name)?;
5561
5562 if let Value::Object(ref class_info) = class_def {
5563 if let Some(Value::String(ref type_str)) = class_info.get("__type") {
5565 if type_str.as_ref() != "Class" {
5566 return Err(InterpreterError::RuntimeError(format!(
5567 "{} is not a class",
5568 class_name
5569 )));
5570 }
5571 }
5572
5573 let mut instance = HashMap::new();
5575 instance.insert(
5576 "__class".to_string(),
5577 Value::from_string(class_name.to_string()),
5578 );
5579
5580 fn collect_all_fields(
5582 class_info: &HashMap<String, Value>,
5583 interpreter: &Interpreter,
5584 ) -> HashMap<String, Value> {
5585 let mut all_fields = HashMap::new();
5586
5587 if let Some(Value::String(ref parent_name)) = class_info.get("__superclass") {
5589 if let Ok(Value::Object(ref parent_info)) =
5590 interpreter.lookup_variable(parent_name)
5591 {
5592 let parent_fields = collect_all_fields(parent_info, interpreter);
5593 all_fields.extend(parent_fields);
5594 }
5595 }
5596
5597 if let Some(Value::Object(ref fields)) = class_info.get("__fields") {
5599 for (field_name, field_info) in fields.iter() {
5600 if let Value::Object(ref field_meta) = field_info {
5601 if let Some(default) = field_meta.get("default") {
5603 all_fields.insert(field_name.clone(), default.clone());
5604 } else {
5605 all_fields.insert(field_name.clone(), Value::Nil);
5607 }
5608 }
5609 }
5610 }
5611
5612 all_fields
5613 }
5614
5615 let all_fields = collect_all_fields(class_info, self);
5617 for (field_name, field_value) in all_fields {
5618 instance.insert(field_name, field_value);
5619 }
5620
5621 if let Some(Value::Object(ref constructors)) = class_info.get("__constructors") {
5623 if let Some(constructor) = constructors.get(constructor_name) {
5625 if let Value::Closure {
5626 params,
5627 body,
5628 env: _,
5629 } = constructor
5630 {
5631 if args.len() != params.len() {
5633 return Err(InterpreterError::RuntimeError(format!(
5634 "constructor expects {} arguments, got {}",
5635 params.len(),
5636 args.len()
5637 )));
5638 }
5639
5640 let mut ctor_env = HashMap::new();
5642
5643 ctor_env.insert(
5645 "self".to_string(),
5646 Value::Object(Arc::new(instance.clone())),
5647 );
5648
5649 for (param, arg) in params.iter().zip(args) {
5651 ctor_env.insert(param.clone(), arg.clone());
5652 }
5653
5654 self.env_stack.push(ctor_env);
5656
5657 let _result = self.eval_expr(body)?;
5659
5660 let updated_self = self.lookup_variable("self")?;
5663 if let Value::Object(ref updated_instance) = updated_self {
5664 for (key, value) in updated_instance.iter() {
5666 if !key.starts_with("__") {
5667 instance.insert(key.clone(), value.clone());
5668 }
5669 }
5670 }
5671
5672 self.env_stack.pop();
5674 }
5675 }
5676 }
5677
5678 Ok(crate::runtime::object_helpers::new_mutable_object(instance))
5680 } else {
5681 Err(InterpreterError::RuntimeError(format!(
5682 "{} is not a class definition",
5683 class_name
5684 )))
5685 }
5686 }
5687
5688 fn instantiate_class_with_args(
5691 &mut self,
5692 class_name: &str,
5693 args: &[Value],
5694 ) -> Result<Value, InterpreterError> {
5695 use std::sync::RwLock;
5696
5697 let class_def = self.lookup_variable(class_name)?;
5699
5700 if let Value::Object(ref class_info) = class_def {
5701 if let Some(Value::String(ref type_str)) = class_info.get("__type") {
5703 if type_str.as_ref() != "Class" {
5704 return Err(InterpreterError::RuntimeError(format!(
5705 "{} is not a class",
5706 class_name
5707 )));
5708 }
5709 }
5710
5711 let mut methods_map = HashMap::new();
5713 if let Some(Value::Object(ref methods_obj)) = class_info.get("__methods") {
5714 for (method_name, method_value) in methods_obj.iter() {
5715 if let Value::Object(ref method_meta) = method_value {
5717 if let Some(closure) = method_meta.get("closure") {
5718 methods_map.insert(method_name.clone(), closure.clone());
5719 }
5720 }
5721 }
5722 }
5723
5724 let mut instance_fields = HashMap::new();
5726 if let Some(Value::Object(ref fields)) = class_info.get("__fields") {
5727 for (field_name, field_info) in fields.iter() {
5728 if let Value::Object(ref field_meta) = field_info {
5729 if let Some(default) = field_meta.get("default") {
5731 instance_fields.insert(field_name.clone(), default.clone());
5732 } else {
5733 instance_fields.insert(field_name.clone(), Value::Nil);
5735 }
5736 }
5737 }
5738 }
5739
5740 let class_instance = Value::Class {
5742 class_name: class_name.to_string(),
5743 fields: Arc::new(RwLock::new(instance_fields.clone())),
5744 methods: Arc::new(methods_map),
5745 };
5746
5747 if let Some(Value::Object(ref constructors)) = class_info.get("__constructors") {
5749 let constructor = constructors
5751 .get("init")
5752 .or_else(|| constructors.get("new"));
5753
5754 if let Some(constructor) = constructor {
5755 if let Value::Closure {
5756 params,
5757 body,
5758 env: _,
5759 } = constructor
5760 {
5761 if args.len() != params.len() {
5763 return Err(InterpreterError::RuntimeError(format!(
5764 "constructor expects {} arguments, got {}",
5765 params.len(),
5766 args.len()
5767 )));
5768 }
5769
5770 let mut ctor_env = HashMap::new();
5772
5773 ctor_env.insert("self".to_string(), class_instance.clone());
5775
5776 for (param, arg) in params.iter().zip(args) {
5778 ctor_env.insert(param.clone(), arg.clone());
5779 }
5780
5781 self.env_stack.push(ctor_env);
5783
5784 let _result = self.eval_expr(body)?;
5786
5787 self.env_stack.pop();
5789 }
5790 }
5791 }
5792
5793 Ok(class_instance)
5794 } else {
5795 Err(InterpreterError::RuntimeError(format!(
5796 "{} is not a class definition",
5797 class_name
5798 )))
5799 }
5800 }
5801
5802 fn instantiate_struct_with_args(
5803 &mut self,
5804 struct_name: &str,
5805 args: &[Value],
5806 ) -> Result<Value, InterpreterError> {
5807 let struct_def = self.lookup_variable(struct_name)?;
5809
5810 if let Value::Object(ref struct_info) = struct_def {
5811 if let Some(Value::String(ref type_str)) = struct_info.get("__type") {
5813 if type_str.as_ref() != "Struct" {
5814 return Err(InterpreterError::RuntimeError(format!(
5815 "{} is not a struct",
5816 struct_name
5817 )));
5818 }
5819 }
5820
5821 let mut instance = HashMap::new();
5825 instance.insert(
5826 "__struct".to_string(),
5827 Value::from_string(struct_name.to_string()),
5828 );
5829
5830 if let Some(Value::Object(ref fields)) = struct_info.get("__fields") {
5832 for (i, (field_name, field_info)) in fields.iter().enumerate() {
5834 if i < args.len() {
5835 instance.insert(field_name.clone(), args[i].clone());
5836 } else if let Value::Object(ref field_meta) = field_info {
5837 if let Some(default) = field_meta.get("default") {
5839 instance.insert(field_name.clone(), default.clone());
5840 } else {
5841 instance.insert(field_name.clone(), Value::Nil);
5843 }
5844 }
5845 }
5846 }
5847
5848 Ok(Value::Object(Arc::new(instance)))
5849 } else {
5850 Err(InterpreterError::RuntimeError(format!(
5851 "{} is not a struct definition",
5852 struct_name
5853 )))
5854 }
5855 }
5856
5857 fn instantiate_actor_with_args(
5892 &mut self,
5893 actor_name: &str,
5894 args: &[Value],
5895 ) -> Result<Value, InterpreterError> {
5896 let actor_def = self.lookup_variable(actor_name)?;
5898
5899 if let Value::Object(ref actor_info) = actor_def {
5900 if let Some(Value::String(ref type_str)) = actor_info.get("__type") {
5902 if type_str.as_ref() != "Actor" {
5903 return Err(InterpreterError::RuntimeError(format!(
5904 "{} is not an actor",
5905 actor_name
5906 )));
5907 }
5908 }
5909
5910 let mut instance = HashMap::new();
5912 instance.insert(
5913 "__actor".to_string(),
5914 Value::from_string(actor_name.to_string()),
5915 );
5916
5917 let named_args = if args.len() == 1 {
5919 if let Value::Object(ref obj) = args[0] {
5920 Some(obj)
5921 } else {
5922 None
5923 }
5924 } else {
5925 None
5926 };
5927
5928 if let Some(Value::Object(ref fields)) = actor_info.get("__fields") {
5931 if let Some(named) = named_args {
5932 for (field_name, _field_info) in fields.iter() {
5934 if let Some(value) = named.get(field_name) {
5935 instance.insert(field_name.clone(), value.clone());
5936 } else {
5937 instance.insert(field_name.clone(), Value::Nil);
5939 }
5940 }
5941 } else {
5942 for (i, (field_name, field_info)) in fields.iter().enumerate() {
5944 if i < args.len() {
5945 instance.insert(field_name.clone(), args[i].clone());
5946 } else if let Value::Object(ref field_meta) = field_info {
5947 if let Some(default) = field_meta.get("default") {
5949 instance.insert(field_name.clone(), default.clone());
5950 } else {
5951 instance.insert(field_name.clone(), Value::Nil);
5953 }
5954 } else {
5955 instance.insert(field_name.clone(), Value::Nil);
5957 }
5958 }
5959 }
5960 }
5961
5962 if let Some(handlers) = actor_info.get("__handlers") {
5964 instance.insert("__handlers".to_string(), handlers.clone());
5965 }
5966
5967 Ok(crate::runtime::object_helpers::new_mutable_object(instance))
5971 } else {
5972 Err(InterpreterError::RuntimeError(format!(
5973 "{} is not an actor definition",
5974 actor_name
5975 )))
5976 }
5977 }
5978
5979 fn eval_class_instance_method(
5980 &mut self,
5981 instance: &HashMap<String, Value>,
5982 class_name: &str,
5983 method: &str,
5984 arg_values: &[Value],
5985 ) -> Result<Value, InterpreterError> {
5986 let class_def = self.lookup_variable(class_name)?;
5988
5989 if let Value::Object(ref class_info) = class_def {
5990 if let Some(Value::Object(ref methods)) = class_info.get("__methods") {
5992 if let Some(Value::Object(ref method_meta)) = methods.get(method) {
5993 if let Some(Value::Closure { params, body, .. }) = method_meta.get("closure") {
5995 let is_static = method_meta
5997 .get("is_static")
5998 .and_then(|v| {
5999 if let Value::Bool(b) = v {
6000 Some(*b)
6001 } else {
6002 None
6003 }
6004 })
6005 .unwrap_or(false);
6006
6007 if is_static {
6008 return Err(InterpreterError::RuntimeError(format!(
6009 "Cannot call static method {} on instance",
6010 method
6011 )));
6012 }
6013
6014 let mut method_env = HashMap::new();
6016
6017 method_env.insert(
6019 "self".to_string(),
6020 Value::Object(Arc::new(instance.clone())),
6021 );
6022
6023 if arg_values.len() != params.len() {
6026 return Err(InterpreterError::RuntimeError(format!(
6027 "Method {} expects {} arguments, got {}",
6028 method,
6029 params.len(),
6030 arg_values.len()
6031 )));
6032 }
6033
6034 for (param, arg) in params.iter().zip(arg_values) {
6035 method_env.insert(param.clone(), arg.clone());
6036 }
6037
6038 self.env_push(method_env);
6040
6041 let result = self.eval_expr(body)?;
6043
6044 self.env_pop();
6046
6047 return Ok(result);
6048 }
6049 }
6050 }
6051
6052 Err(InterpreterError::RuntimeError(format!(
6054 "Class {} has no method named {}",
6055 class_name, method
6056 )))
6057 } else {
6058 Err(InterpreterError::RuntimeError(format!(
6059 "{} is not a class",
6060 class_name
6061 )))
6062 }
6063 }
6064
6065 fn call_static_method(
6066 &mut self,
6067 class_name: &str,
6068 method_name: &str,
6069 args: &[Value],
6070 ) -> Result<Value, InterpreterError> {
6071 let class_def = self.lookup_variable(class_name)?;
6073
6074 if let Value::Object(ref class_info) = class_def {
6075 if let Some(Value::Object(ref methods)) = class_info.get("__methods") {
6077 if let Some(Value::Object(ref method_meta)) = methods.get(method_name) {
6078 let is_static = method_meta
6080 .get("is_static")
6081 .and_then(|v| {
6082 if let Value::Bool(b) = v {
6083 Some(*b)
6084 } else {
6085 None
6086 }
6087 })
6088 .unwrap_or(false);
6089
6090 if !is_static {
6091 return Err(InterpreterError::RuntimeError(format!(
6092 "{} is not a static method",
6093 method_name
6094 )));
6095 }
6096
6097 if let Some(Value::Closure { params, body, .. }) = method_meta.get("closure") {
6099 if args.len() != params.len() {
6101 return Err(InterpreterError::RuntimeError(format!(
6102 "Static method {} expects {} arguments, got {}",
6103 method_name,
6104 params.len(),
6105 args.len()
6106 )));
6107 }
6108
6109 let mut method_env = HashMap::new();
6111
6112 for (i, param) in params.iter().enumerate() {
6114 method_env.insert(param.clone(), args[i].clone());
6115 }
6116
6117 self.env_stack.push(method_env);
6119
6120 let result = self.eval_expr(body);
6122
6123 self.env_stack.pop();
6125
6126 return result;
6127 }
6128 }
6129 }
6130
6131 Err(InterpreterError::RuntimeError(format!(
6132 "Static method {} not found in class {}",
6133 method_name, class_name
6134 )))
6135 } else {
6136 Err(InterpreterError::RuntimeError(format!(
6137 "{} is not a class",
6138 class_name
6139 )))
6140 }
6141 }
6142
6143 fn eval_dataframe_builder_method(
6146 &self,
6147 builder: &std::collections::HashMap<String, Value>,
6148 method: &str,
6149 arg_values: &[Value],
6150 ) -> Result<Value, InterpreterError> {
6151 match method {
6152 "column" => {
6153 if arg_values.len() != 2 {
6155 return Err(InterpreterError::RuntimeError(
6156 "DataFrame builder .column() requires 2 arguments (name, values)"
6157 .to_string(),
6158 ));
6159 }
6160
6161 let name = match &arg_values[0] {
6163 Value::String(s) => s.to_string(),
6164 _ => {
6165 return Err(InterpreterError::RuntimeError(
6166 "Column name must be a string".to_string(),
6167 ))
6168 }
6169 };
6170
6171 let values = match &arg_values[1] {
6173 Value::Array(arr) => arr.to_vec(),
6174 _ => {
6175 return Err(InterpreterError::RuntimeError(
6176 "Column values must be an array".to_string(),
6177 ))
6178 }
6179 };
6180
6181 let current_columns = match builder.get("__columns") {
6183 Some(Value::Array(cols)) => cols.to_vec(),
6184 _ => vec![],
6185 };
6186
6187 let mut col_obj = std::collections::HashMap::new();
6189 col_obj.insert("name".to_string(), Value::from_string(name));
6190 col_obj.insert("values".to_string(), Value::from_array(values));
6191
6192 let mut new_columns = current_columns;
6194 new_columns.push(Value::Object(std::sync::Arc::new(col_obj)));
6195
6196 let mut new_builder = builder.clone();
6198 new_builder.insert("__columns".to_string(), Value::from_array(new_columns));
6199
6200 Ok(Value::Object(std::sync::Arc::new(new_builder)))
6201 }
6202 "build" => {
6203 if !arg_values.is_empty() {
6205 return Err(InterpreterError::RuntimeError(
6206 "DataFrame builder .build() takes no arguments".to_string(),
6207 ));
6208 }
6209
6210 let columns_array = match builder.get("__columns") {
6212 Some(Value::Array(cols)) => cols,
6213 _ => return Ok(Value::DataFrame { columns: vec![] }),
6214 };
6215
6216 let mut df_columns = Vec::new();
6218 for col_val in columns_array.as_ref() {
6219 if let Value::Object(col_obj) = col_val {
6220 let name = match col_obj.get("name") {
6221 Some(Value::String(s)) => s.to_string(),
6222 _ => continue,
6223 };
6224 let values = match col_obj.get("values") {
6225 Some(Value::Array(vals)) => vals.to_vec(),
6226 _ => vec![],
6227 };
6228 df_columns.push(DataFrameColumn { name, values });
6229 }
6230 }
6231
6232 Ok(Value::DataFrame {
6233 columns: df_columns,
6234 })
6235 }
6236 _ => Err(InterpreterError::RuntimeError(format!(
6237 "Unknown builder method: {method}"
6238 ))),
6239 }
6240 }
6241
6242 fn eval_dataframe_method(
6243 &self,
6244 columns: &[DataFrameColumn],
6245 method: &str,
6246 arg_values: &[Value],
6247 ) -> Result<Value, InterpreterError> {
6248 crate::runtime::eval_dataframe_ops::eval_dataframe_method(columns, method, arg_values)
6249 }
6250
6251 fn eval_dataframe_filter_method(
6254 &mut self,
6255 receiver: &Value,
6256 args: &[Expr],
6257 ) -> Result<Value, InterpreterError> {
6258 if args.len() != 1 {
6259 return Err(InterpreterError::RuntimeError(
6260 "DataFrame.filter() requires exactly 1 argument (closure)".to_string(),
6261 ));
6262 }
6263
6264 if let Value::DataFrame { columns } = receiver {
6265 let closure = &args[0];
6266
6267 if !matches!(closure.kind, ExprKind::Lambda { .. }) {
6269 return Err(InterpreterError::RuntimeError(
6270 "DataFrame.filter() expects a lambda expression".to_string(),
6271 ));
6272 }
6273
6274 let num_rows = columns.first().map_or(0, |c| c.values.len());
6276 let mut keep_mask = Vec::with_capacity(num_rows);
6277
6278 for row_idx in 0..num_rows {
6279 let mut row = HashMap::new();
6281 for col in columns {
6282 if let Some(value) = col.values.get(row_idx) {
6283 row.insert(col.name.clone(), value.clone());
6284 }
6285 }
6286 let row_value = Value::Object(std::sync::Arc::new(row));
6287
6288 let result = self.eval_closure_with_value(closure, &row_value)?;
6290
6291 let keep = match result {
6293 Value::Bool(b) => b,
6294 _ => {
6295 return Err(InterpreterError::RuntimeError(
6296 "DataFrame.filter() closure must return boolean".to_string(),
6297 ))
6298 }
6299 };
6300
6301 keep_mask.push(keep);
6302 }
6303
6304 let mut new_columns = Vec::new();
6306 for col in columns {
6307 let mut filtered_values = Vec::new();
6308 for (idx, &keep) in keep_mask.iter().enumerate() {
6309 if keep {
6310 if let Some(val) = col.values.get(idx) {
6311 filtered_values.push(val.clone());
6312 }
6313 }
6314 }
6315 new_columns.push(DataFrameColumn {
6316 name: col.name.clone(),
6317 values: filtered_values,
6318 });
6319 }
6320
6321 Ok(Value::DataFrame {
6322 columns: new_columns,
6323 })
6324 } else {
6325 Err(InterpreterError::RuntimeError(
6326 "filter method can only be called on DataFrame".to_string(),
6327 ))
6328 }
6329 }
6330
6331 fn eval_dataframe_with_column_method(
6334 &mut self,
6335 receiver: &Value,
6336 args: &[Expr],
6337 ) -> Result<Value, InterpreterError> {
6338 if args.len() != 2 {
6339 return Err(InterpreterError::RuntimeError(
6340 "DataFrame.with_column() requires exactly 2 arguments (name, closure)".to_string(),
6341 ));
6342 }
6343
6344 let col_name = match self.eval_expr(&args[0])? {
6346 Value::String(s) => s.to_string(),
6347 _ => {
6348 return Err(InterpreterError::RuntimeError(
6349 "DataFrame.with_column() expects string column name".to_string(),
6350 ))
6351 }
6352 };
6353
6354 if let Value::DataFrame { columns } = receiver {
6355 let closure = &args[1];
6356
6357 let param_name = if let ExprKind::Lambda { params, .. } = &closure.kind {
6359 if params.len() != 1 {
6360 return Err(InterpreterError::RuntimeError(
6361 "with_column closure must have exactly 1 parameter".to_string(),
6362 ));
6363 }
6364 match ¶ms[0].pattern {
6365 crate::frontend::ast::Pattern::Identifier(name) => name.clone(),
6366 _ => {
6367 return Err(InterpreterError::RuntimeError(
6368 "with_column closure must have simple identifier parameter".to_string(),
6369 ))
6370 }
6371 }
6372 } else {
6373 return Err(InterpreterError::RuntimeError(
6374 "Expected lambda expression".to_string(),
6375 ));
6376 };
6377
6378 let matching_col = columns.iter().find(|c| c.name == param_name);
6380
6381 let mut new_values = Vec::new();
6382 let num_rows = columns.first().map_or(0, |c| c.values.len());
6383
6384 for row_idx in 0..num_rows {
6385 let value_to_bind = if let Some(col) = matching_col {
6386 col.values.get(row_idx).cloned().unwrap_or(Value::Nil)
6388 } else {
6389 let mut row = HashMap::new();
6391 for col in columns {
6392 if let Some(value) = col.values.get(row_idx) {
6393 row.insert(col.name.clone(), value.clone());
6394 }
6395 }
6396 Value::Object(std::sync::Arc::new(row))
6397 };
6398
6399 let result = self.eval_closure_with_value(closure, &value_to_bind)?;
6401 new_values.push(result);
6402 }
6403
6404 let mut new_columns = columns.clone();
6406 new_columns.push(crate::runtime::DataFrameColumn {
6407 name: col_name,
6408 values: new_values,
6409 });
6410
6411 Ok(Value::DataFrame {
6412 columns: new_columns,
6413 })
6414 } else {
6415 Err(InterpreterError::RuntimeError(
6416 "with_column method can only be called on DataFrame".to_string(),
6417 ))
6418 }
6419 }
6420
6421 fn eval_dataframe_transform_method(
6424 &mut self,
6425 receiver: &Value,
6426 args: &[Expr],
6427 ) -> Result<Value, InterpreterError> {
6428 if args.len() != 2 {
6429 return Err(InterpreterError::RuntimeError(
6430 "DataFrame.transform() requires exactly 2 arguments (column, closure)".to_string(),
6431 ));
6432 }
6433
6434 let col_name = match self.eval_expr(&args[0])? {
6436 Value::String(s) => s.to_string(),
6437 _ => {
6438 return Err(InterpreterError::RuntimeError(
6439 "DataFrame.transform() expects string column name".to_string(),
6440 ))
6441 }
6442 };
6443
6444 if let Value::DataFrame { columns } = receiver {
6445 let col_idx = columns
6447 .iter()
6448 .position(|c| c.name == col_name)
6449 .ok_or_else(|| {
6450 InterpreterError::RuntimeError(format!(
6451 "Column '{col_name}' not found in DataFrame"
6452 ))
6453 })?;
6454
6455 let closure = &args[1];
6456 let mut new_columns = columns.clone();
6457
6458 let mut transformed_values = Vec::new();
6460 for value in &columns[col_idx].values {
6461 let result = self.eval_closure_with_value(closure, value)?;
6463 transformed_values.push(result);
6464 }
6465
6466 new_columns[col_idx].values = transformed_values;
6467
6468 Ok(Value::DataFrame {
6469 columns: new_columns,
6470 })
6471 } else {
6472 Err(InterpreterError::RuntimeError(
6473 "transform method can only be called on DataFrame".to_string(),
6474 ))
6475 }
6476 }
6477
6478 fn eval_closure_with_value(
6481 &mut self,
6482 closure_expr: &Expr,
6483 value: &Value,
6484 ) -> Result<Value, InterpreterError> {
6485 match &closure_expr.kind {
6486 ExprKind::Lambda { params, body, .. } => {
6487 if params.len() != 1 {
6488 return Err(InterpreterError::RuntimeError(
6489 "Transform closure must have exactly 1 parameter".to_string(),
6490 ));
6491 }
6492
6493 let param_name = match ¶ms[0].pattern {
6495 crate::frontend::ast::Pattern::Identifier(name) => name.clone(),
6496 _ => {
6497 return Err(InterpreterError::RuntimeError(
6498 "Transform closure must have simple identifier parameter".to_string(),
6499 ))
6500 }
6501 };
6502
6503 let mut new_env = HashMap::new();
6505 new_env.insert(param_name, value.clone());
6506
6507 self.env_push(new_env);
6509
6510 let result = self.eval_expr(body)?;
6512
6513 self.env_pop();
6515
6516 Ok(result)
6517 }
6518 _ => Err(InterpreterError::RuntimeError(
6519 "Expected lambda expression".to_string(),
6520 )),
6521 }
6522 }
6523
6524 fn compare_values<F>(
6526 &self,
6527 left: &Value,
6528 right: &Value,
6529 cmp: F,
6530 ) -> Result<Value, InterpreterError>
6531 where
6532 F: Fn(i64, i64) -> bool,
6533 {
6534 match (left, right) {
6535 (Value::Integer(a), Value::Integer(b)) => Ok(Value::Bool(cmp(*a, *b))),
6536 (Value::Float(a), Value::Float(b)) => {
6537 let a_int = *a as i64;
6539 let b_int = *b as i64;
6540 Ok(Value::Bool(cmp(a_int, b_int)))
6541 }
6542 (Value::Integer(a), Value::Float(b)) => {
6543 let b_int = *b as i64;
6544 Ok(Value::Bool(cmp(*a, b_int)))
6545 }
6546 (Value::Float(a), Value::Integer(b)) => {
6547 let a_int = *a as i64;
6548 Ok(Value::Bool(cmp(a_int, *b)))
6549 }
6550 _ => Err(InterpreterError::RuntimeError(format!(
6551 "Cannot compare {} and {}",
6552 left.type_name(),
6553 right.type_name()
6554 ))),
6555 }
6556 }
6557
6558 fn values_equal(&self, left: &Value, right: &Value) -> bool {
6560 match (left, right) {
6561 (Value::Integer(a), Value::Integer(b)) => a == b,
6562 (Value::Float(a), Value::Float(b)) => (a - b).abs() < f64::EPSILON,
6563 (Value::Bool(a), Value::Bool(b)) => a == b,
6564 (Value::String(a), Value::String(b)) => a == b,
6565 (Value::Nil, Value::Nil) => true,
6566 _ => false,
6567 }
6568 }
6569
6570 fn eval_expr_with_column_context(
6572 &mut self,
6573 expr: &Expr,
6574 columns: &[DataFrameColumn],
6575 row_idx: usize,
6576 ) -> Result<Value, InterpreterError> {
6577 match &expr.kind {
6578 ExprKind::Call { func, args } => {
6580 if let ExprKind::Identifier(name) = &func.kind {
6581 if name == "col" && args.len() == 1 {
6582 let col_name_expr = &args[0];
6584 if let ExprKind::Literal(crate::frontend::ast::Literal::String(col_name)) =
6585 &col_name_expr.kind
6586 {
6587 for col in columns {
6589 if col.name == *col_name {
6590 if let Some(value) = col.values.get(row_idx) {
6591 return Ok(value.clone());
6592 }
6593 return Err(InterpreterError::RuntimeError(format!(
6594 "Row index {} out of bounds for column '{}'",
6595 row_idx, col_name
6596 )));
6597 }
6598 }
6599 return Err(InterpreterError::RuntimeError(format!(
6600 "Column '{}' not found",
6601 col_name
6602 )));
6603 }
6604 }
6605 }
6606 self.eval_expr(expr)
6608 }
6609 ExprKind::Binary { left, right, .. } => {
6611 let left_val = self.eval_expr_with_column_context(left, columns, row_idx)?;
6612 let right_val = self.eval_expr_with_column_context(right, columns, row_idx)?;
6613
6614 if let ExprKind::Binary { op, .. } = &expr.kind {
6617 match op {
6618 crate::frontend::ast::BinaryOp::Greater => {
6619 self.compare_values(&left_val, &right_val, |a, b| a > b)
6620 }
6621 crate::frontend::ast::BinaryOp::Less => {
6622 self.compare_values(&left_val, &right_val, |a, b| a < b)
6623 }
6624 crate::frontend::ast::BinaryOp::Equal => {
6625 Ok(Value::Bool(self.values_equal(&left_val, &right_val)))
6626 }
6627 crate::frontend::ast::BinaryOp::NotEqual => {
6628 Ok(Value::Bool(!self.values_equal(&left_val, &right_val)))
6629 }
6630 _ => self.eval_expr(expr), }
6632 } else {
6633 unreachable!()
6634 }
6635 }
6636 _ => self.eval_expr(expr),
6638 }
6639 }
6640
6641 fn eval_dataframe_operation(
6642 &mut self,
6643 source: &Expr,
6644 operation: &crate::frontend::ast::DataFrameOp,
6645 ) -> Result<Value, InterpreterError> {
6646 let source_value = self.eval_expr(source)?;
6647
6648 if let Value::DataFrame { columns } = source_value {
6649 crate::runtime::eval_dataframe_ops::eval_dataframe_operation(
6650 columns,
6651 operation,
6652 |expr, cols, idx| self.eval_expr_with_column_context(expr, cols, idx),
6653 )
6654 } else {
6655 Err(InterpreterError::RuntimeError(
6656 "DataFrameOperation can only be applied to DataFrame values".to_string(),
6657 ))
6658 }
6659 }
6660
6661 fn eval_string_interpolation(
6663 &mut self,
6664 parts: &[StringPart],
6665 ) -> Result<Value, InterpreterError> {
6666 use crate::runtime::eval_string_interpolation::format_value_for_interpolation;
6667
6668 let mut result = String::new();
6669 for part in parts {
6670 match part {
6671 StringPart::Text(text) => result.push_str(text),
6672 StringPart::Expr(expr) => {
6673 let value = self.eval_expr(expr)?;
6674 result.push_str(&format_value_for_interpolation(&value));
6676 }
6677 StringPart::ExprWithFormat { expr, format_spec } => {
6678 let value = self.eval_expr(expr)?;
6679 let formatted = Self::format_value_with_spec(&value, format_spec);
6681 result.push_str(&formatted);
6682 }
6683 }
6684 }
6685 Ok(Value::from_string(result))
6686 }
6687
6688 fn format_value_with_spec(value: &Value, spec: &str) -> String {
6690 if let Some(stripped) = spec.strip_prefix(":.") {
6692 if let Ok(precision) = stripped.parse::<usize>() {
6693 match value {
6694 Value::Float(f) => return format!("{:.precision$}", f, precision = precision),
6695 Value::Integer(i) => {
6696 return format!("{:.precision$}", *i as f64, precision = precision)
6697 }
6698 _ => {}
6699 }
6700 }
6701 }
6702 value.to_string()
6704 }
6705
6706 fn eval_function(
6708 &mut self,
6709 name: &str,
6710 params: &[Param],
6711 body: &Expr,
6712 ) -> Result<Value, InterpreterError> {
6713 let param_names: Vec<String> = params
6714 .iter()
6715 .map(crate::frontend::ast::Param::name)
6716 .collect();
6717
6718 let closure = Value::Closure {
6719 params: param_names,
6720 body: Arc::new(body.clone()),
6721 env: Arc::new(self.current_env().clone()),
6722 };
6723
6724 self.env_set(name.to_string(), closure.clone());
6726 Ok(closure)
6727 }
6728
6729 fn eval_lambda(&mut self, params: &[Param], body: &Expr) -> Result<Value, InterpreterError> {
6731 eval_func::eval_lambda(params, body, self.current_env())
6732 }
6733
6734 fn eval_function_call(
6736 &mut self,
6737 func: &Expr,
6738 args: &[Expr],
6739 ) -> Result<Value, InterpreterError> {
6740 if let ExprKind::FieldAccess { object, field } = &func.kind {
6743 if let ExprKind::Identifier(type_name) = &object.kind {
6744 if type_name == "Box" && field == "new" {
6746 if args.len() != 1 {
6747 return Err(InterpreterError::RuntimeError(format!(
6748 "Box::new() requires exactly 1 argument, got {}",
6749 args.len()
6750 )));
6751 }
6752 return self.eval_expr(&args[0]);
6754 }
6755 if type_name == "Vec" && field == "new" {
6757 if !args.is_empty() {
6758 return Err(InterpreterError::RuntimeError(format!(
6759 "Vec::new() takes no arguments, got {}",
6760 args.len()
6761 )));
6762 }
6763 return Ok(Value::Array(Arc::from([])));
6765 }
6766
6767 let qualified_method = format!("{}::{}", type_name, field);
6770 if let Ok(method_value) = self.lookup_variable(&qualified_method) {
6771 let arg_vals: Result<Vec<Value>, InterpreterError> =
6773 args.iter().map(|arg| self.eval_expr(arg)).collect();
6774 let arg_vals = arg_vals?;
6775 return self.call_function(method_value, &arg_vals);
6776 }
6777 }
6778 }
6779
6780 let func_val_result = self.eval_expr(func);
6782
6783 let func_val = match func_val_result {
6785 Ok(val) => val,
6786 Err(InterpreterError::RuntimeError(msg)) if msg.starts_with("Undefined variable:") => {
6787 if let ExprKind::Identifier(name) = &func.kind {
6789 let arg_vals: Result<Vec<Value>, InterpreterError> =
6791 args.iter().map(|arg| self.eval_expr(arg)).collect();
6792 let arg_vals = arg_vals?;
6793
6794 let mut message = HashMap::new();
6795 message.insert(
6796 "__type".to_string(),
6797 Value::from_string("Message".to_string()),
6798 );
6799 message.insert("type".to_string(), Value::from_string(name.clone()));
6800 message.insert("data".to_string(), Value::Array(Arc::from(arg_vals)));
6801
6802 return Ok(Value::Object(Arc::new(message)));
6803 }
6804 return Err(InterpreterError::RuntimeError(msg));
6805 }
6806 Err(e) => return Err(e),
6807 };
6808
6809 let arg_vals: Result<Vec<Value>, InterpreterError> =
6810 args.iter().map(|arg| self.eval_expr(arg)).collect();
6811 let arg_vals = arg_vals?;
6812
6813 if let Value::EnumVariant { enum_name, variant_name, data: _ } = func_val {
6815 return Ok(Value::EnumVariant {
6817 enum_name,
6818 variant_name,
6819 data: Some(arg_vals),
6820 });
6821 }
6822
6823 let result = self.call_function(func_val, &arg_vals)?;
6824
6825 let site_id = func.span.start; let func_name = match &func.kind {
6828 ExprKind::Identifier(name) => name.clone(),
6829 _ => "anonymous".to_string(),
6830 };
6831 self.record_function_call_feedback(site_id, &func_name, &arg_vals, &result);
6832 Ok(result)
6833 }
6834
6835 pub fn push_error_scope(&mut self) {
6840 self.error_scopes.push(ErrorScope {
6841 env_depth: self.env_stack.len(),
6842 });
6843 }
6844
6845 pub fn pop_error_scope(&mut self) {
6850 self.error_scopes.pop();
6851 }
6852
6853 pub fn set_variable(&mut self, name: &str, value: Value) {
6858 self.env_set_mut(name.to_string(), value);
6860 }
6861
6862 pub fn get_variable(&self, name: &str) -> Option<Value> {
6867 for env in self.env_stack.iter().rev() {
6869 if let Some(value) = env.get(name) {
6870 return Some(value.clone());
6871 }
6872 }
6873 None
6874 }
6875
6876 pub fn pattern_matches(
6881 &mut self,
6882 pattern: &Pattern,
6883 value: &Value,
6884 ) -> Result<bool, InterpreterError> {
6885 match pattern {
6887 Pattern::Identifier(_) => Ok(true), Pattern::Wildcard => Ok(true),
6889 Pattern::Literal(literal) => Ok(self.literal_matches(literal, value)),
6890 _ => Ok(false), }
6892 }
6893
6894 fn literal_matches(&self, literal: &Literal, value: &Value) -> bool {
6895 match (literal, value) {
6896 (Literal::Integer(a, _), Value::Integer(b)) => a == b,
6897 (Literal::Float(a), Value::Float(b)) => (a - b).abs() < f64::EPSILON,
6898 (Literal::String(a), Value::String(b)) => a == b.as_ref(),
6899 (Literal::Bool(a), Value::Bool(b)) => a == b,
6900 _ => false,
6901 }
6902 }
6903
6904 pub fn capture_stdout(&mut self, output: String) {
6922 self.stdout_buffer.push(output);
6923 }
6924
6925 pub fn get_stdout(&self) -> String {
6939 self.stdout_buffer.join("\n")
6940 }
6941
6942 pub fn clear_stdout(&mut self) {
6956 self.stdout_buffer.clear();
6957 }
6958
6959 pub fn has_stdout(&self) -> bool {
6962 !self.stdout_buffer.is_empty()
6963 }
6964}
6965
6966impl Default for Interpreter {
6967 fn default() -> Self {
6968 Self::new()
6969 }
6970}
6971
6972#[derive(Debug, Clone, Copy)]
6974pub enum BinaryOp {
6975 Add,
6976 Sub,
6977 Mul,
6978 Div,
6979 Eq,
6980 Lt,
6981 Gt,
6982}
6983
6984#[cfg(test)]
6985#[allow(clippy::expect_used)] #[allow(clippy::bool_assert_comparison)] #[allow(clippy::approx_constant)] #[allow(clippy::panic)] mod tests {
6990 use super::*;
6991
6992 #[test]
6993 fn test_value_creation() {
6994 let int_val = Value::from_i64(42);
6995 assert_eq!(int_val.as_i64().expect("Should be integer"), 42);
6996 assert_eq!(int_val.type_name(), "integer");
6997
6998 let bool_val = Value::from_bool(true);
6999 assert_eq!(bool_val.as_bool().expect("Should be boolean"), true);
7000 assert_eq!(bool_val.type_name(), "boolean");
7001
7002 let nil_val = Value::nil();
7003 assert!(nil_val.is_nil());
7004 assert_eq!(nil_val.type_name(), "nil");
7005
7006 let float_val = Value::from_f64(3.14);
7007 let f_value = float_val.as_f64().expect("Should be float");
7008 assert!((f_value - 3.14).abs() < f64::EPSILON);
7009 assert_eq!(float_val.type_name(), "float");
7010
7011 let string_val = Value::from_string("hello".to_string());
7012 assert_eq!(string_val.type_name(), "string");
7013 }
7014
7015 #[test]
7016 fn test_arithmetic() {
7017 let mut interp = Interpreter::new();
7018
7019 assert!(interp.push(Value::from_i64(2)).is_ok());
7021 assert!(interp.push(Value::from_i64(3)).is_ok());
7022 assert!(interp.binary_op(BinaryOp::Add).is_ok());
7023
7024 let result = interp.pop().expect("Stack should not be empty");
7025 assert_eq!(result, Value::Integer(5));
7026 }
7027
7028 #[test]
7029 fn test_mixed_arithmetic() {
7030 let mut interp = Interpreter::new();
7031
7032 assert!(interp.push(Value::from_i64(2)).is_ok());
7034 assert!(interp.push(Value::from_f64(3.5)).is_ok());
7035 assert!(interp.binary_op(BinaryOp::Add).is_ok());
7036
7037 let result = interp.pop().expect("Stack should not be empty");
7038 match result {
7039 Value::Float(f) => assert!((f - 5.5).abs() < f64::EPSILON),
7040 _ => unreachable!("Expected float, got {result:?}"),
7041 }
7042 }
7043}
7044
7045#[cfg(test)]
7046mod lambda_tests {
7047 use super::*;
7048
7049 #[test]
7050 fn test_lambda_variable_assignment_and_call() {
7051 let code = r"
7052 let double = x => x * 2
7053 double(5)
7054 ";
7055 let mut parser = crate::frontend::parser::Parser::new(code);
7056 let ast = parser.parse().expect("Parse failed");
7057 let mut interpreter = Interpreter::new();
7058 let result = interpreter.eval_expr(&ast).expect("Eval failed");
7059 assert_eq!(result, Value::Integer(10));
7060 }
7061
7062 #[test]
7063 fn test_lambda_pipe_syntax_variable_call() {
7064 let code = r"
7065 let triple = |x| x * 3
7066 triple(4)
7067 ";
7068 let mut parser = crate::frontend::parser::Parser::new(code);
7069 let ast = parser.parse().expect("Parse failed");
7070 let mut interpreter = Interpreter::new();
7071 let result = interpreter.eval_expr(&ast).expect("Eval failed");
7072 assert_eq!(result, Value::Integer(12));
7073 }
7074}
7075
7076#[cfg(test)]
7077mod negative_indexing_tests {
7078 use super::*;
7079
7080 #[test]
7083 fn test_negative_array_indexing_last_element() {
7084 let code = r#"
7085 let fruits = ["apple", "banana", "cherry"]
7086 fruits[-1]
7087 "#;
7088 let mut parser = crate::frontend::parser::Parser::new(code);
7089 let ast = parser.parse().expect("Parse failed");
7090 let mut interpreter = Interpreter::new();
7091 let result = interpreter.eval_expr(&ast).expect("Eval failed");
7092 assert_eq!(result, Value::from_string("cherry".to_string()));
7093 }
7094
7095 #[test]
7096 fn test_negative_array_indexing_second_to_last() {
7097 let code = r#"
7098 let fruits = ["apple", "banana", "cherry"]
7099 fruits[-2]
7100 "#;
7101 let mut parser = crate::frontend::parser::Parser::new(code);
7102 let ast = parser.parse().expect("Parse failed");
7103 let mut interpreter = Interpreter::new();
7104 let result = interpreter.eval_expr(&ast).expect("Eval failed");
7105 assert_eq!(result, Value::from_string("banana".to_string()));
7106 }
7107
7108 #[test]
7109 fn test_negative_array_indexing_first_element() {
7110 let code = r#"
7111 let fruits = ["apple", "banana", "cherry"]
7112 fruits[-3]
7113 "#;
7114 let mut parser = crate::frontend::parser::Parser::new(code);
7115 let ast = parser.parse().expect("Parse failed");
7116 let mut interpreter = Interpreter::new();
7117 let result = interpreter.eval_expr(&ast).expect("Eval failed");
7118 assert_eq!(result, Value::from_string("apple".to_string()));
7119 }
7120
7121 #[test]
7122 fn test_negative_array_indexing_out_of_bounds() {
7123 let code = r#"
7124 let fruits = ["apple", "banana"]
7125 fruits[-5]
7126 "#;
7127 let mut parser = crate::frontend::parser::Parser::new(code);
7128 let ast = parser.parse().expect("Parse failed");
7129 let mut interpreter = Interpreter::new();
7130 let result = interpreter.eval_expr(&ast);
7131 assert!(result.is_err(), "Should fail for out-of-bounds negative index");
7132 }
7133
7134 #[test]
7135 fn test_negative_string_indexing() {
7136 let code = r#"
7137 let word = "hello"
7138 word[-1]
7139 "#;
7140 let mut parser = crate::frontend::parser::Parser::new(code);
7141 let ast = parser.parse().expect("Parse failed");
7142 let mut interpreter = Interpreter::new();
7143 let result = interpreter.eval_expr(&ast).expect("Eval failed");
7144 assert_eq!(result, Value::from_string("o".to_string()));
7145 }
7146
7147 #[test]
7148 fn test_negative_tuple_indexing() {
7149 let code = r#"
7150 let point = (10, 20, 30)
7151 point[-1]
7152 "#;
7153 let mut parser = crate::frontend::parser::Parser::new(code);
7154 let ast = parser.parse().expect("Parse failed");
7155 let mut interpreter = Interpreter::new();
7156 let result = interpreter.eval_expr(&ast).expect("Eval failed");
7157 assert_eq!(result, Value::Integer(30));
7158 }
7159
7160 #[test]
7161 fn test_negative_indexing_with_integers() {
7162 let code = r#"
7163 let numbers = [100, 200, 300, 400]
7164 numbers[-2]
7165 "#;
7166 let mut parser = crate::frontend::parser::Parser::new(code);
7167 let ast = parser.parse().expect("Parse failed");
7168 let mut interpreter = Interpreter::new();
7169 let result = interpreter.eval_expr(&ast).expect("Eval failed");
7170 assert_eq!(result, Value::Integer(300));
7171 }
7172}
7173
7174