sigil_parser/
interpreter.rs

1//! Tree-walking interpreter for Sigil.
2//!
3//! Executes Sigil AST directly for rapid prototyping and REPL.
4
5use crate::ast::*;
6use crate::span::Span;
7use std::collections::HashMap;
8use std::fmt;
9use std::rc::Rc;
10use std::cell::RefCell;
11use std::sync::{Arc, Mutex, mpsc};
12use std::thread::JoinHandle;
13
14/// Runtime value in Sigil.
15#[derive(Clone)]
16pub enum Value {
17    /// Null/void
18    Null,
19    /// Boolean
20    Bool(bool),
21    /// Integer (64-bit)
22    Int(i64),
23    /// Float (64-bit)
24    Float(f64),
25    /// String
26    String(Rc<String>),
27    /// Character
28    Char(char),
29    /// Array/list
30    Array(Rc<RefCell<Vec<Value>>>),
31    /// Tuple
32    Tuple(Rc<Vec<Value>>),
33    /// Struct instance
34    Struct {
35        name: String,
36        fields: Rc<RefCell<HashMap<String, Value>>>,
37    },
38    /// Enum variant
39    Variant {
40        enum_name: String,
41        variant_name: String,
42        fields: Option<Rc<Vec<Value>>>,
43    },
44    /// Function/closure
45    Function(Rc<Function>),
46    /// Built-in function
47    BuiltIn(Rc<BuiltInFn>),
48    /// Reference to another value
49    Ref(Rc<RefCell<Value>>),
50    /// Special mathematical values
51    Infinity,
52    Empty,
53    /// Evidence-wrapped value
54    Evidential {
55        value: Box<Value>,
56        evidence: Evidence,
57    },
58    /// Affect-wrapped value (sentiment, emotion, sarcasm, etc.)
59    Affective {
60        value: Box<Value>,
61        affect: RuntimeAffect,
62    },
63    /// HashMap
64    Map(Rc<RefCell<HashMap<String, Value>>>),
65    /// HashSet (stores keys only, values are unit)
66    Set(Rc<RefCell<std::collections::HashSet<String>>>),
67    /// Channel for message passing (sender, receiver)
68    Channel(Arc<ChannelInner>),
69    /// Thread handle
70    ThreadHandle(Arc<Mutex<Option<JoinHandle<Value>>>>),
71    /// Actor (mailbox + state)
72    Actor(Arc<ActorInner>),
73    /// Future - represents an async computation
74    Future(Rc<RefCell<FutureInner>>),
75}
76
77/// Future state for async computations
78#[derive(Clone)]
79pub enum FutureState {
80    /// Not yet started
81    Pending,
82    /// Currently executing
83    Running,
84    /// Completed with value
85    Ready(Box<Value>),
86    /// Failed with error
87    Failed(String),
88}
89
90/// Inner future representation
91pub struct FutureInner {
92    /// Current state
93    pub state: FutureState,
94    /// The computation to run (if pending)
95    pub computation: Option<FutureComputation>,
96    /// Completion time for timer futures
97    pub complete_at: Option<std::time::Instant>,
98}
99
100impl Clone for FutureInner {
101    fn clone(&self) -> Self {
102        FutureInner {
103            state: self.state.clone(),
104            computation: self.computation.clone(),
105            complete_at: self.complete_at,
106        }
107    }
108}
109
110/// Types of future computations
111#[derive(Clone)]
112pub enum FutureComputation {
113    /// Immediate value (already resolved)
114    Immediate(Box<Value>),
115    /// Timer - completes after duration
116    Timer(std::time::Duration),
117    /// Lazy computation - function + captured args
118    Lazy {
119        func: Rc<Function>,
120        args: Vec<Value>,
121    },
122    /// Join multiple futures
123    Join(Vec<Rc<RefCell<FutureInner>>>),
124    /// Race multiple futures (first to complete wins)
125    Race(Vec<Rc<RefCell<FutureInner>>>),
126}
127
128/// Inner channel state - wraps mpsc channel
129pub struct ChannelInner {
130    pub sender: Mutex<mpsc::Sender<Value>>,
131    pub receiver: Mutex<mpsc::Receiver<Value>>,
132}
133
134impl Clone for ChannelInner {
135    fn clone(&self) -> Self {
136        // Channels can't really be cloned - create a dummy
137        // This is for the Clone requirement on Value
138        panic!("Channels cannot be cloned directly - use channel_clone()")
139    }
140}
141
142/// Inner actor state - single-threaded for interpreter (Value contains Rc)
143/// For true async actors, use the JIT backend
144pub struct ActorInner {
145    pub name: String,
146    pub message_queue: Mutex<Vec<(String, String)>>,  // (msg_type, serialized_data)
147    pub message_count: std::sync::atomic::AtomicUsize,
148}
149
150/// Evidence level at runtime
151#[derive(Debug, Clone, Copy, PartialEq, Eq)]
152pub enum Evidence {
153    Known,      // !
154    Uncertain,  // ?
155    Reported,   // ~
156    Paradox,    // ‽
157}
158
159/// Runtime affect markers for sentiment and emotion tracking
160#[derive(Debug, Clone, PartialEq)]
161pub struct RuntimeAffect {
162    pub sentiment: Option<RuntimeSentiment>,
163    pub sarcasm: bool,           // ⸮
164    pub intensity: Option<RuntimeIntensity>,
165    pub formality: Option<RuntimeFormality>,
166    pub emotion: Option<RuntimeEmotion>,
167    pub confidence: Option<RuntimeConfidence>,
168}
169
170#[derive(Debug, Clone, Copy, PartialEq, Eq)]
171pub enum RuntimeSentiment {
172    Positive,  // ⊕
173    Negative,  // ⊖
174    Neutral,   // ⊜
175}
176
177#[derive(Debug, Clone, Copy, PartialEq, Eq)]
178pub enum RuntimeIntensity {
179    Up,   // ↑
180    Down, // ↓
181    Max,  // ⇈
182}
183
184#[derive(Debug, Clone, Copy, PartialEq, Eq)]
185pub enum RuntimeFormality {
186    Formal,   // ♔
187    Informal, // ♟
188}
189
190#[derive(Debug, Clone, Copy, PartialEq, Eq)]
191pub enum RuntimeEmotion {
192    Joy,      // ☺
193    Sadness,  // ☹
194    Anger,    // ⚡
195    Fear,     // ❄
196    Surprise, // ✦
197    Love,     // ♡
198}
199
200#[derive(Debug, Clone, Copy, PartialEq, Eq)]
201pub enum RuntimeConfidence {
202    High,   // ◉
203    Medium, // ◎
204    Low,    // ○
205}
206
207/// A Sigil function
208pub struct Function {
209    pub name: Option<String>,
210    pub params: Vec<String>,
211    pub body: Expr,
212    pub closure: Rc<RefCell<Environment>>,
213}
214
215/// Built-in function type
216pub struct BuiltInFn {
217    pub name: String,
218    pub arity: Option<usize>, // None = variadic
219    pub func: fn(&mut Interpreter, Vec<Value>) -> Result<Value, RuntimeError>,
220}
221
222impl fmt::Debug for Value {
223    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
224        match self {
225            Value::Null => write!(f, "null"),
226            Value::Bool(b) => write!(f, "{}", b),
227            Value::Int(n) => write!(f, "{}", n),
228            Value::Float(n) => write!(f, "{}", n),
229            Value::String(s) => write!(f, "\"{}\"", s),
230            Value::Char(c) => write!(f, "'{}'", c),
231            Value::Array(arr) => {
232                let arr = arr.borrow();
233                write!(f, "[")?;
234                for (i, v) in arr.iter().enumerate() {
235                    if i > 0 { write!(f, ", ")?; }
236                    write!(f, "{:?}", v)?;
237                }
238                write!(f, "]")
239            }
240            Value::Tuple(vals) => {
241                write!(f, "(")?;
242                for (i, v) in vals.iter().enumerate() {
243                    if i > 0 { write!(f, ", ")?; }
244                    write!(f, "{:?}", v)?;
245                }
246                write!(f, ")")
247            }
248            Value::Struct { name, fields } => {
249                write!(f, "{} {{ ", name)?;
250                let fields = fields.borrow();
251                for (i, (k, v)) in fields.iter().enumerate() {
252                    if i > 0 { write!(f, ", ")?; }
253                    write!(f, "{}: {:?}", k, v)?;
254                }
255                write!(f, " }}")
256            }
257            Value::Variant { enum_name, variant_name, fields } => {
258                write!(f, "{}::{}", enum_name, variant_name)?;
259                if let Some(fields) = fields {
260                    write!(f, "(")?;
261                    for (i, v) in fields.iter().enumerate() {
262                        if i > 0 { write!(f, ", ")?; }
263                        write!(f, "{:?}", v)?;
264                    }
265                    write!(f, ")")?;
266                }
267                Ok(())
268            }
269            Value::Function(func) => {
270                write!(f, "<fn {}>", func.name.as_deref().unwrap_or("anonymous"))
271            }
272            Value::BuiltIn(b) => write!(f, "<builtin {}>", b.name),
273            Value::Ref(r) => write!(f, "&{:?}", r.borrow()),
274            Value::Infinity => write!(f, "∞"),
275            Value::Empty => write!(f, "∅"),
276            Value::Evidential { value, evidence } => {
277                write!(f, "{:?}", value)?;
278                match evidence {
279                    Evidence::Known => write!(f, "!"),
280                    Evidence::Uncertain => write!(f, "?"),
281                    Evidence::Reported => write!(f, "~"),
282                    Evidence::Paradox => write!(f, "‽"),
283                }
284            }
285            Value::Map(map) => {
286                let map = map.borrow();
287                write!(f, "{{")?;
288                for (i, (k, v)) in map.iter().enumerate() {
289                    if i > 0 { write!(f, ", ")?; }
290                    write!(f, "{:?}: {:?}", k, v)?;
291                }
292                write!(f, "}}")
293            }
294            Value::Set(set) => {
295                let set = set.borrow();
296                write!(f, "Set{{")?;
297                for (i, k) in set.iter().enumerate() {
298                    if i > 0 { write!(f, ", ")?; }
299                    write!(f, "{:?}", k)?;
300                }
301                write!(f, "}}")
302            }
303            Value::Channel(_) => write!(f, "<channel>"),
304            Value::ThreadHandle(_) => write!(f, "<thread>"),
305            Value::Actor(actor) => write!(f, "<actor {}>", actor.name),
306            Value::Future(fut) => {
307                let fut = fut.borrow();
308                match &fut.state {
309                    FutureState::Pending => write!(f, "<future pending>"),
310                    FutureState::Running => write!(f, "<future running>"),
311                    FutureState::Ready(v) => write!(f, "<future ready: {:?}>", v),
312                    FutureState::Failed(e) => write!(f, "<future failed: {}>", e),
313                }
314            }
315            Value::Affective { value, affect } => {
316                write!(f, "{:?}", value)?;
317                if let Some(s) = &affect.sentiment {
318                    match s {
319                        RuntimeSentiment::Positive => write!(f, "⊕")?,
320                        RuntimeSentiment::Negative => write!(f, "⊖")?,
321                        RuntimeSentiment::Neutral => write!(f, "⊜")?,
322                    }
323                }
324                if affect.sarcasm { write!(f, "⸮")?; }
325                if let Some(i) = &affect.intensity {
326                    match i {
327                        RuntimeIntensity::Up => write!(f, "↑")?,
328                        RuntimeIntensity::Down => write!(f, "↓")?,
329                        RuntimeIntensity::Max => write!(f, "⇈")?,
330                    }
331                }
332                if let Some(fo) = &affect.formality {
333                    match fo {
334                        RuntimeFormality::Formal => write!(f, "♔")?,
335                        RuntimeFormality::Informal => write!(f, "♟")?,
336                    }
337                }
338                if let Some(e) = &affect.emotion {
339                    match e {
340                        RuntimeEmotion::Joy => write!(f, "☺")?,
341                        RuntimeEmotion::Sadness => write!(f, "☹")?,
342                        RuntimeEmotion::Anger => write!(f, "⚡")?,
343                        RuntimeEmotion::Fear => write!(f, "❄")?,
344                        RuntimeEmotion::Surprise => write!(f, "✦")?,
345                        RuntimeEmotion::Love => write!(f, "♡")?,
346                    }
347                }
348                if let Some(c) = &affect.confidence {
349                    match c {
350                        RuntimeConfidence::High => write!(f, "◉")?,
351                        RuntimeConfidence::Medium => write!(f, "◎")?,
352                        RuntimeConfidence::Low => write!(f, "○")?,
353                    }
354                }
355                Ok(())
356            }
357        }
358    }
359}
360
361impl fmt::Display for Value {
362    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
363        match self {
364            Value::Null => write!(f, "null"),
365            Value::Bool(b) => write!(f, "{}", b),
366            Value::Int(n) => write!(f, "{}", n),
367            Value::Float(n) => write!(f, "{}", n),
368            Value::String(s) => write!(f, "{}", s),
369            Value::Char(c) => write!(f, "{}", c),
370            Value::Array(arr) => {
371                let arr = arr.borrow();
372                write!(f, "[")?;
373                for (i, v) in arr.iter().enumerate() {
374                    if i > 0 { write!(f, ", ")?; }
375                    write!(f, "{}", v)?;
376                }
377                write!(f, "]")
378            }
379            Value::Evidential { value, .. } => write!(f, "{}", value),
380            Value::Affective { value, affect } => {
381                // Display affect markers as suffix symbols
382                let mut suffix = String::new();
383                if let Some(sent) = &affect.sentiment {
384                    suffix.push(match sent {
385                        RuntimeSentiment::Positive => '⊕',
386                        RuntimeSentiment::Negative => '⊖',
387                        RuntimeSentiment::Neutral => '⊜',
388                    });
389                }
390                if affect.sarcasm { suffix.push('⸮'); }
391                if let Some(int) = &affect.intensity {
392                    suffix.push(match int {
393                        RuntimeIntensity::Up => '↑',
394                        RuntimeIntensity::Down => '↓',
395                        RuntimeIntensity::Max => '⇈',
396                    });
397                }
398                if let Some(form) = &affect.formality {
399                    suffix.push(match form {
400                        RuntimeFormality::Formal => '♔',
401                        RuntimeFormality::Informal => '♟',
402                    });
403                }
404                if let Some(emo) = &affect.emotion {
405                    suffix.push(match emo {
406                        RuntimeEmotion::Joy => '☺',
407                        RuntimeEmotion::Sadness => '☹',
408                        RuntimeEmotion::Anger => '⚡',
409                        RuntimeEmotion::Fear => '❄',
410                        RuntimeEmotion::Surprise => '✦',
411                        RuntimeEmotion::Love => '♡',
412                    });
413                }
414                if let Some(conf) = &affect.confidence {
415                    suffix.push(match conf {
416                        RuntimeConfidence::High => '◉',
417                        RuntimeConfidence::Medium => '◎',
418                        RuntimeConfidence::Low => '○',
419                    });
420                }
421                write!(f, "{}{}", value, suffix)
422            }
423            _ => write!(f, "{:?}", self),
424        }
425    }
426}
427
428/// Runtime error
429#[derive(Debug)]
430pub struct RuntimeError {
431    pub message: String,
432    pub span: Option<Span>,
433}
434
435impl RuntimeError {
436    pub fn new(message: impl Into<String>) -> Self {
437        Self {
438            message: message.into(),
439            span: None,
440        }
441    }
442
443    pub fn with_span(message: impl Into<String>, span: Span) -> Self {
444        Self {
445            message: message.into(),
446            span: Some(span),
447        }
448    }
449}
450
451impl fmt::Display for RuntimeError {
452    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
453        write!(f, "Runtime error: {}", self.message)?;
454        if let Some(span) = self.span {
455            write!(f, " at {}", span)?;
456        }
457        Ok(())
458    }
459}
460
461/// Control flow signals for return/break/continue
462#[derive(Debug, Clone)]
463pub enum ControlFlow {
464    Return(Value),
465    Break(Option<Value>),
466    Continue,
467}
468
469impl From<ControlFlow> for RuntimeError {
470    fn from(cf: ControlFlow) -> Self {
471        match cf {
472            ControlFlow::Return(_) => RuntimeError::new("return outside function"),
473            ControlFlow::Break(_) => RuntimeError::new("break outside loop"),
474            ControlFlow::Continue => RuntimeError::new("continue outside loop"),
475        }
476    }
477}
478
479/// Result type that can contain control flow
480pub type EvalResult = Result<Value, EvalError>;
481
482/// Error type that includes control flow
483#[derive(Debug)]
484pub enum EvalError {
485    Runtime(RuntimeError),
486    Control(ControlFlow),
487}
488
489impl From<RuntimeError> for EvalError {
490    fn from(e: RuntimeError) -> Self {
491        EvalError::Runtime(e)
492    }
493}
494
495impl From<ControlFlow> for EvalError {
496    fn from(cf: ControlFlow) -> Self {
497        EvalError::Control(cf)
498    }
499}
500
501impl fmt::Display for EvalError {
502    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
503        match self {
504            EvalError::Runtime(e) => write!(f, "{}", e),
505            EvalError::Control(cf) => write!(f, "Unexpected control flow: {:?}", cf),
506        }
507    }
508}
509
510/// Environment for variable bindings
511#[derive(Clone)]
512pub struct Environment {
513    values: HashMap<String, Value>,
514    parent: Option<Rc<RefCell<Environment>>>,
515}
516
517impl Environment {
518    pub fn new() -> Self {
519        Self {
520            values: HashMap::new(),
521            parent: None,
522        }
523    }
524
525    pub fn with_parent(parent: Rc<RefCell<Environment>>) -> Self {
526        Self {
527            values: HashMap::new(),
528            parent: Some(parent),
529        }
530    }
531
532    pub fn define(&mut self, name: String, value: Value) {
533        self.values.insert(name, value);
534    }
535
536    pub fn get(&self, name: &str) -> Option<Value> {
537        if let Some(value) = self.values.get(name) {
538            Some(value.clone())
539        } else if let Some(ref parent) = self.parent {
540            parent.borrow().get(name)
541        } else {
542            None
543        }
544    }
545
546    pub fn set(&mut self, name: &str, value: Value) -> Result<(), RuntimeError> {
547        if self.values.contains_key(name) {
548            self.values.insert(name.to_string(), value);
549            Ok(())
550        } else if let Some(ref parent) = self.parent {
551            parent.borrow_mut().set(name, value)
552        } else {
553            Err(RuntimeError::new(format!("Undefined variable: {}", name)))
554        }
555    }
556}
557
558impl Default for Environment {
559    fn default() -> Self {
560        Self::new()
561    }
562}
563
564/// The Sigil interpreter
565pub struct Interpreter {
566    /// Global environment
567    pub globals: Rc<RefCell<Environment>>,
568    /// Current environment
569    pub environment: Rc<RefCell<Environment>>,
570    /// Type definitions
571    pub types: HashMap<String, TypeDef>,
572    /// Output buffer (for testing)
573    pub output: Vec<String>,
574    /// Return value from the last return statement (control flow)
575    return_value: Option<Value>,
576}
577
578/// Type definition for structs/enums
579pub enum TypeDef {
580    Struct(StructDef),
581    Enum(EnumDef),
582}
583
584impl Interpreter {
585    pub fn new() -> Self {
586        let globals = Rc::new(RefCell::new(Environment::new()));
587        let environment = globals.clone();
588
589        let mut interp = Self {
590            globals: globals.clone(),
591            environment,
592            types: HashMap::new(),
593            return_value: None,
594            output: Vec::new(),
595        };
596
597        // Register built-in functions
598        interp.register_builtins();
599
600        interp
601    }
602
603    fn register_builtins(&mut self) {
604        // Print function
605        self.define_builtin("print", None, |interp, args| {
606            let output: Vec<String> = args.iter().map(|v| format!("{}", v)).collect();
607            let line = output.join(" ");
608            println!("{}", line);
609            interp.output.push(line);
610            Ok(Value::Null)
611        });
612
613        // Type checking
614        self.define_builtin("type_of", Some(1), |_, args| {
615            let type_name = match &args[0] {
616                Value::Null => "null",
617                Value::Bool(_) => "bool",
618                Value::Int(_) => "i64",
619                Value::Float(_) => "f64",
620                Value::String(_) => "str",
621                Value::Char(_) => "char",
622                Value::Array(_) => "array",
623                Value::Tuple(_) => "tuple",
624                Value::Struct { name, .. } => name,
625                Value::Variant { enum_name, .. } => enum_name,
626                Value::Function(_) => "fn",
627                Value::BuiltIn(_) => "builtin",
628                Value::Ref(_) => "ref",
629                Value::Infinity => "infinity",
630                Value::Empty => "empty",
631                Value::Evidential { .. } => "evidential",
632                Value::Affective { .. } => "affective",
633                Value::Map(_) => "map",
634                Value::Set(_) => "set",
635                Value::Channel(_) => "channel",
636                Value::ThreadHandle(_) => "thread",
637                Value::Actor(_) => "actor",
638                Value::Future(_) => "future",
639            };
640            Ok(Value::String(Rc::new(type_name.to_string())))
641        });
642
643        // Array operations
644        self.define_builtin("len", Some(1), |_, args| {
645            match &args[0] {
646                Value::Array(arr) => Ok(Value::Int(arr.borrow().len() as i64)),
647                Value::String(s) => Ok(Value::Int(s.len() as i64)),
648                Value::Tuple(t) => Ok(Value::Int(t.len() as i64)),
649                _ => Err(RuntimeError::new("len() requires array, string, or tuple")),
650            }
651        });
652
653        self.define_builtin("push", Some(2), |_, args| {
654            match &args[0] {
655                Value::Array(arr) => {
656                    arr.borrow_mut().push(args[1].clone());
657                    Ok(Value::Null)
658                }
659                _ => Err(RuntimeError::new("push() requires array")),
660            }
661        });
662
663        self.define_builtin("pop", Some(1), |_, args| {
664            match &args[0] {
665                Value::Array(arr) => {
666                    arr.borrow_mut().pop()
667                        .ok_or_else(|| RuntimeError::new("pop() on empty array"))
668                }
669                _ => Err(RuntimeError::new("pop() requires array")),
670            }
671        });
672
673        // Math functions
674        self.define_builtin("abs", Some(1), |_, args| {
675            match &args[0] {
676                Value::Int(n) => Ok(Value::Int(n.abs())),
677                Value::Float(n) => Ok(Value::Float(n.abs())),
678                _ => Err(RuntimeError::new("abs() requires number")),
679            }
680        });
681
682        self.define_builtin("sqrt", Some(1), |_, args| {
683            match &args[0] {
684                Value::Int(n) => Ok(Value::Float((*n as f64).sqrt())),
685                Value::Float(n) => Ok(Value::Float(n.sqrt())),
686                _ => Err(RuntimeError::new("sqrt() requires number")),
687            }
688        });
689
690        self.define_builtin("sin", Some(1), |_, args| {
691            match &args[0] {
692                Value::Int(n) => Ok(Value::Float((*n as f64).sin())),
693                Value::Float(n) => Ok(Value::Float(n.sin())),
694                _ => Err(RuntimeError::new("sin() requires number")),
695            }
696        });
697
698        self.define_builtin("cos", Some(1), |_, args| {
699            match &args[0] {
700                Value::Int(n) => Ok(Value::Float((*n as f64).cos())),
701                Value::Float(n) => Ok(Value::Float(n.cos())),
702                _ => Err(RuntimeError::new("cos() requires number")),
703            }
704        });
705
706        // Evidence operations
707        self.define_builtin("known", Some(1), |_, args| {
708            Ok(Value::Evidential {
709                value: Box::new(args[0].clone()),
710                evidence: Evidence::Known,
711            })
712        });
713
714        self.define_builtin("uncertain", Some(1), |_, args| {
715            Ok(Value::Evidential {
716                value: Box::new(args[0].clone()),
717                evidence: Evidence::Uncertain,
718            })
719        });
720
721        self.define_builtin("reported", Some(1), |_, args| {
722            Ok(Value::Evidential {
723                value: Box::new(args[0].clone()),
724                evidence: Evidence::Reported,
725            })
726        });
727
728        // Range function
729        self.define_builtin("range", Some(2), |_, args| {
730            let start = match &args[0] {
731                Value::Int(n) => *n,
732                _ => return Err(RuntimeError::new("range() requires integers")),
733            };
734            let end = match &args[1] {
735                Value::Int(n) => *n,
736                _ => return Err(RuntimeError::new("range() requires integers")),
737            };
738            let values: Vec<Value> = (start..end).map(Value::Int).collect();
739            Ok(Value::Array(Rc::new(RefCell::new(values))))
740        });
741    }
742
743    fn define_builtin(
744        &mut self,
745        name: &str,
746        arity: Option<usize>,
747        func: fn(&mut Interpreter, Vec<Value>) -> Result<Value, RuntimeError>,
748    ) {
749        let builtin = Value::BuiltIn(Rc::new(BuiltInFn {
750            name: name.to_string(),
751            arity,
752            func,
753        }));
754        self.globals.borrow_mut().define(name.to_string(), builtin);
755    }
756
757    /// Execute a source file
758    pub fn execute(&mut self, file: &SourceFile) -> Result<Value, RuntimeError> {
759        let mut result = Value::Null;
760
761        for item in &file.items {
762            result = self.execute_item(&item.node)?;
763        }
764
765        // Look for main function and execute it
766        let main_fn = self.globals.borrow().get("main").and_then(|v| {
767            if let Value::Function(f) = v {
768                Some(f.clone())
769            } else {
770                None
771            }
772        });
773        if let Some(f) = main_fn {
774            result = self.call_function(&f, vec![])?;
775        }
776
777        Ok(result)
778    }
779
780    fn execute_item(&mut self, item: &Item) -> Result<Value, RuntimeError> {
781        match item {
782            Item::Function(func) => {
783                let fn_value = self.create_function(func)?;
784                self.globals.borrow_mut().define(func.name.name.clone(), fn_value);
785                Ok(Value::Null)
786            }
787            Item::Struct(s) => {
788                self.types.insert(s.name.name.clone(), TypeDef::Struct(s.clone()));
789                Ok(Value::Null)
790            }
791            Item::Enum(e) => {
792                self.types.insert(e.name.name.clone(), TypeDef::Enum(e.clone()));
793                Ok(Value::Null)
794            }
795            Item::Const(c) => {
796                let value = self.evaluate(&c.value)?;
797                self.globals.borrow_mut().define(c.name.name.clone(), value);
798                Ok(Value::Null)
799            }
800            Item::Static(s) => {
801                let value = self.evaluate(&s.value)?;
802                self.globals.borrow_mut().define(s.name.name.clone(), value);
803                Ok(Value::Null)
804            }
805            _ => Ok(Value::Null), // Skip other items for now
806        }
807    }
808
809    fn create_function(&self, func: &crate::ast::Function) -> Result<Value, RuntimeError> {
810        let params: Vec<String> = func.params.iter().map(|p| {
811            match &p.pattern {
812                Pattern::Ident { name, .. } => name.name.clone(),
813                _ => "_".to_string(),
814            }
815        }).collect();
816
817        let body = func.body.as_ref()
818            .map(|b| Expr::Block(b.clone()))
819            .unwrap_or(Expr::Literal(Literal::Bool(false)));
820
821        Ok(Value::Function(Rc::new(Function {
822            name: Some(func.name.name.clone()),
823            params,
824            body,
825            closure: self.environment.clone(),
826        })))
827    }
828
829    /// Evaluate an expression
830    pub fn evaluate(&mut self, expr: &Expr) -> Result<Value, RuntimeError> {
831        match expr {
832            Expr::Literal(lit) => self.eval_literal(lit),
833            Expr::Path(path) => self.eval_path(path),
834            Expr::Binary { left, op, right } => self.eval_binary(left, op, right),
835            Expr::Unary { op, expr } => self.eval_unary(op, expr),
836            Expr::Call { func, args } => self.eval_call(func, args),
837            Expr::Array(elements) => self.eval_array(elements),
838            Expr::Tuple(elements) => self.eval_tuple(elements),
839            Expr::Block(block) => self.eval_block(block),
840            Expr::If { condition, then_branch, else_branch } => {
841                self.eval_if(condition, then_branch, else_branch)
842            }
843            Expr::Match { expr, arms } => self.eval_match(expr, arms),
844            Expr::For { pattern, iter, body } => self.eval_for(pattern, iter, body),
845            Expr::While { condition, body } => self.eval_while(condition, body),
846            Expr::Loop(body) => self.eval_loop(body),
847            Expr::Return(value) => self.eval_return(value),
848            Expr::Break(value) => self.eval_break(value),
849            Expr::Continue => Err(RuntimeError::new("continue outside loop")),
850            Expr::Index { expr, index } => self.eval_index(expr, index),
851            Expr::Field { expr, field } => self.eval_field(expr, field),
852            Expr::MethodCall { receiver, method, args } => {
853                self.eval_method_call(receiver, method, args)
854            }
855            Expr::Pipe { expr, operations } => self.eval_pipe(expr, operations),
856            Expr::Closure { params, body } => self.eval_closure(params, body),
857            Expr::Struct { path, fields, rest } => self.eval_struct_literal(path, fields, rest),
858            Expr::Evidential { expr, evidentiality } => self.eval_evidential(expr, evidentiality),
859            Expr::Range { start, end, inclusive } => self.eval_range(start, end, *inclusive),
860            Expr::Assign { target, value } => self.eval_assign(target, value),
861            Expr::Await(inner) => {
862                let value = self.evaluate(inner)?;
863                self.await_value(value)
864            }
865            _ => Err(RuntimeError::new(format!("Unsupported expression: {:?}", expr))),
866        }
867    }
868
869    fn eval_assign(&mut self, target: &Expr, value: &Expr) -> Result<Value, RuntimeError> {
870        let val = self.evaluate(value)?;
871
872        match target {
873            Expr::Path(path) if path.segments.len() == 1 => {
874                let name = &path.segments[0].ident.name;
875                self.environment.borrow_mut().set(name, val.clone())?;
876                Ok(val)
877            }
878            Expr::Index { expr, index } => {
879                // Array/map index assignment
880                let idx = self.evaluate(index)?;
881                let idx = match idx {
882                    Value::Int(i) => i as usize,
883                    _ => return Err(RuntimeError::new("Index must be an integer")),
884                };
885
886                // Get the array and modify it
887                if let Expr::Path(path) = expr.as_ref() {
888                    if path.segments.len() == 1 {
889                        let name = &path.segments[0].ident.name;
890                        let current = self.environment.borrow().get(name)
891                            .ok_or_else(|| RuntimeError::new(format!("Undefined variable: {}", name)))?;
892
893                        if let Value::Array(arr) = current {
894                            let borrowed = arr.borrow();
895                            let mut new_arr = borrowed.clone();
896                            drop(borrowed);
897                            if idx < new_arr.len() {
898                                new_arr[idx] = val.clone();
899                                self.environment.borrow_mut().set(name, Value::Array(Rc::new(RefCell::new(new_arr))))?;
900                                return Ok(val);
901                            }
902                        }
903                    }
904                }
905                Err(RuntimeError::new("Invalid index assignment target"))
906            }
907            _ => Err(RuntimeError::new("Invalid assignment target")),
908        }
909    }
910
911    fn eval_literal(&mut self, lit: &Literal) -> Result<Value, RuntimeError> {
912        match lit {
913            Literal::Int { value, base, .. } => {
914                let n = self.parse_int(value, base)?;
915                Ok(Value::Int(n))
916            }
917            Literal::Float { value, .. } => {
918                let n: f64 = value.parse().map_err(|_| {
919                    RuntimeError::new(format!("Invalid float: {}", value))
920                })?;
921                Ok(Value::Float(n))
922            }
923            Literal::String(s) => Ok(Value::String(Rc::new(s.clone()))),
924            Literal::MultiLineString(s) => Ok(Value::String(Rc::new(s.clone()))),
925            Literal::RawString(s) => Ok(Value::String(Rc::new(s.clone()))),
926            Literal::ByteString(bytes) => {
927                // Convert byte array to an array of integers
928                let arr: Vec<Value> = bytes.iter().map(|&b| Value::Int(b as i64)).collect();
929                Ok(Value::Array(Rc::new(RefCell::new(arr))))
930            }
931            Literal::InterpolatedString { parts } => {
932                // Evaluate each part and concatenate
933                let mut result = String::new();
934                for part in parts {
935                    match part {
936                        InterpolationPart::Text(s) => result.push_str(s),
937                        InterpolationPart::Expr(expr) => {
938                            let value = self.evaluate(expr)?;
939                            result.push_str(&format!("{}", value));
940                        }
941                    }
942                }
943                Ok(Value::String(Rc::new(result)))
944            }
945            Literal::SigilStringSql(s) => {
946                // SQL sigil string - for now just return as string
947                // Future: could add SQL validation or templating
948                Ok(Value::String(Rc::new(s.clone())))
949            }
950            Literal::SigilStringRoute(s) => {
951                // Route sigil string - for now just return as string
952                // Future: could add route validation or templating
953                Ok(Value::String(Rc::new(s.clone())))
954            }
955            Literal::Char(c) => Ok(Value::Char(*c)),
956            Literal::Bool(b) => Ok(Value::Bool(*b)),
957            Literal::Null => Ok(Value::Null),
958            Literal::Empty => Ok(Value::Empty),
959            Literal::Infinity => Ok(Value::Infinity),
960            Literal::Circle => Ok(Value::Int(0)), // ◯ = zero
961        }
962    }
963
964    fn parse_int(&self, value: &str, base: &NumBase) -> Result<i64, RuntimeError> {
965        let (radix, prefix_len) = match base {
966            NumBase::Binary => (2, 2),      // 0b
967            NumBase::Octal => (8, 2),       // 0o
968            NumBase::Decimal => (10, 0),
969            NumBase::Hex => (16, 2),        // 0x
970            NumBase::Vigesimal => (20, 2),  // 0v
971            NumBase::Sexagesimal => (60, 2), // 0s
972            NumBase::Duodecimal => (12, 2), // 0z
973            NumBase::Explicit(b) => (*b as u32, 0),
974        };
975
976        let clean = value[prefix_len..].replace('_', "");
977        i64::from_str_radix(&clean, radix).map_err(|_| {
978            RuntimeError::new(format!("Invalid integer: {}", value))
979        })
980    }
981
982    fn eval_path(&self, path: &TypePath) -> Result<Value, RuntimeError> {
983        if path.segments.len() == 1 {
984            let name = &path.segments[0].ident.name;
985            self.environment.borrow().get(name)
986                .ok_or_else(|| RuntimeError::new(format!("Undefined variable: {}", name)))
987        } else {
988            // Multi-segment path (module::item or Type·method)
989            // Try full qualified name first (joined with ·)
990            let full_name = path.segments.iter()
991                .map(|s| s.ident.name.as_str())
992                .collect::<Vec<_>>()
993                .join("·");
994
995            if let Some(val) = self.environment.borrow().get(&full_name) {
996                return Ok(val);
997            }
998
999            // Try looking up the last segment (for Math·sqrt -> sqrt)
1000            let last_name = &path.segments.last().unwrap().ident.name;
1001            if let Some(val) = self.environment.borrow().get(last_name) {
1002                return Ok(val);
1003            }
1004
1005            // Check for enum variant syntax (EnumName::Variant)
1006            if path.segments.len() == 2 {
1007                let type_name = &path.segments[0].ident.name;
1008                let variant_name = &path.segments[1].ident.name;
1009
1010                // Check if this is an enum variant
1011                if let Some(TypeDef::Enum(enum_def)) = self.types.get(type_name) {
1012                    for variant in &enum_def.variants {
1013                        if &variant.name.name == variant_name {
1014                            // Return a variant constructor or unit variant
1015                            if matches!(variant.fields, crate::ast::StructFields::Unit) {
1016                                return Ok(Value::Variant {
1017                                    enum_name: type_name.clone(),
1018                                    variant_name: variant_name.clone(),
1019                                    fields: None,
1020                                });
1021                            }
1022                        }
1023                    }
1024                }
1025            }
1026
1027            Err(RuntimeError::new(format!(
1028                "Undefined: {} (tried {} and {})",
1029                full_name, full_name, last_name
1030            )))
1031        }
1032    }
1033
1034    fn eval_binary(&mut self, left: &Expr, op: &BinOp, right: &Expr) -> Result<Value, RuntimeError> {
1035        let lhs = self.evaluate(left)?;
1036
1037        // Short-circuit for && and ||
1038        match op {
1039            BinOp::And => {
1040                if !self.is_truthy(&lhs) {
1041                    return Ok(Value::Bool(false));
1042                }
1043                let rhs = self.evaluate(right)?;
1044                return Ok(Value::Bool(self.is_truthy(&rhs)));
1045            }
1046            BinOp::Or => {
1047                if self.is_truthy(&lhs) {
1048                    return Ok(Value::Bool(true));
1049                }
1050                let rhs = self.evaluate(right)?;
1051                return Ok(Value::Bool(self.is_truthy(&rhs)));
1052            }
1053            _ => {}
1054        }
1055
1056        let rhs = self.evaluate(right)?;
1057
1058        match (lhs, rhs) {
1059            (Value::Int(a), Value::Int(b)) => self.int_binary_op(a, b, op),
1060            (Value::Float(a), Value::Float(b)) => self.float_binary_op(a, b, op),
1061            (Value::Int(a), Value::Float(b)) => self.float_binary_op(a as f64, b, op),
1062            (Value::Float(a), Value::Int(b)) => self.float_binary_op(a, b as f64, op),
1063            (Value::String(a), Value::String(b)) => {
1064                match op {
1065                    BinOp::Add | BinOp::Concat => Ok(Value::String(Rc::new(format!("{}{}", a, b)))),
1066                    BinOp::Eq => Ok(Value::Bool(*a == *b)),
1067                    BinOp::Ne => Ok(Value::Bool(*a != *b)),
1068                    _ => Err(RuntimeError::new("Invalid string operation")),
1069                }
1070            }
1071            (Value::Bool(a), Value::Bool(b)) => {
1072                match op {
1073                    BinOp::Eq => Ok(Value::Bool(a == b)),
1074                    BinOp::Ne => Ok(Value::Bool(a != b)),
1075                    _ => Err(RuntimeError::new("Invalid boolean operation")),
1076                }
1077            }
1078            (Value::Array(a), Value::Array(b)) => {
1079                match op {
1080                    BinOp::Concat => {
1081                        let mut result = a.borrow().clone();
1082                        result.extend(b.borrow().iter().cloned());
1083                        Ok(Value::Array(Rc::new(RefCell::new(result))))
1084                    }
1085                    _ => Err(RuntimeError::new("Invalid array operation")),
1086                }
1087            }
1088            _ => Err(RuntimeError::new("Type mismatch in binary operation")),
1089        }
1090    }
1091
1092    fn int_binary_op(&self, a: i64, b: i64, op: &BinOp) -> Result<Value, RuntimeError> {
1093        Ok(match op {
1094            BinOp::Add => Value::Int(a + b),
1095            BinOp::Sub => Value::Int(a - b),
1096            BinOp::Mul => Value::Int(a * b),
1097            BinOp::Div => {
1098                if b == 0 {
1099                    return Err(RuntimeError::new("Division by zero"));
1100                }
1101                Value::Int(a / b)
1102            }
1103            BinOp::Rem => {
1104                if b == 0 {
1105                    return Err(RuntimeError::new("Division by zero"));
1106                }
1107                Value::Int(a % b)
1108            }
1109            BinOp::Pow => Value::Int(a.pow(b as u32)),
1110            BinOp::Eq => Value::Bool(a == b),
1111            BinOp::Ne => Value::Bool(a != b),
1112            BinOp::Lt => Value::Bool(a < b),
1113            BinOp::Le => Value::Bool(a <= b),
1114            BinOp::Gt => Value::Bool(a > b),
1115            BinOp::Ge => Value::Bool(a >= b),
1116            BinOp::BitAnd => Value::Int(a & b),
1117            BinOp::BitOr => Value::Int(a | b),
1118            BinOp::BitXor => Value::Int(a ^ b),
1119            BinOp::Shl => Value::Int(a << b),
1120            BinOp::Shr => Value::Int(a >> b),
1121            _ => return Err(RuntimeError::new("Invalid integer operation")),
1122        })
1123    }
1124
1125    fn float_binary_op(&self, a: f64, b: f64, op: &BinOp) -> Result<Value, RuntimeError> {
1126        Ok(match op {
1127            BinOp::Add => Value::Float(a + b),
1128            BinOp::Sub => Value::Float(a - b),
1129            BinOp::Mul => Value::Float(a * b),
1130            BinOp::Div => Value::Float(a / b),
1131            BinOp::Rem => Value::Float(a % b),
1132            BinOp::Pow => Value::Float(a.powf(b)),
1133            BinOp::Eq => Value::Bool((a - b).abs() < f64::EPSILON),
1134            BinOp::Ne => Value::Bool((a - b).abs() >= f64::EPSILON),
1135            BinOp::Lt => Value::Bool(a < b),
1136            BinOp::Le => Value::Bool(a <= b),
1137            BinOp::Gt => Value::Bool(a > b),
1138            BinOp::Ge => Value::Bool(a >= b),
1139            _ => return Err(RuntimeError::new("Invalid float operation")),
1140        })
1141    }
1142
1143    fn eval_unary(&mut self, op: &UnaryOp, expr: &Expr) -> Result<Value, RuntimeError> {
1144        let val = self.evaluate(expr)?;
1145        match (op, val) {
1146            (UnaryOp::Neg, Value::Int(n)) => Ok(Value::Int(-n)),
1147            (UnaryOp::Neg, Value::Float(n)) => Ok(Value::Float(-n)),
1148            (UnaryOp::Not, Value::Bool(b)) => Ok(Value::Bool(!b)),
1149            (UnaryOp::Not, Value::Int(n)) => Ok(Value::Int(!n)),
1150            (UnaryOp::Ref, val) => Ok(Value::Ref(Rc::new(RefCell::new(val)))),
1151            (UnaryOp::Deref, Value::Ref(r)) => Ok(r.borrow().clone()),
1152            _ => Err(RuntimeError::new("Invalid unary operation")),
1153        }
1154    }
1155
1156    fn eval_call(&mut self, func_expr: &Expr, args: &[Expr]) -> Result<Value, RuntimeError> {
1157        let func = self.evaluate(func_expr)?;
1158        let arg_values: Vec<Value> = args.iter()
1159            .map(|a| self.evaluate(a))
1160            .collect::<Result<_, _>>()?;
1161
1162        match func {
1163            Value::Function(f) => self.call_function(&f, arg_values),
1164            Value::BuiltIn(b) => self.call_builtin(&b, arg_values),
1165            _ => Err(RuntimeError::new("Cannot call non-function")),
1166        }
1167    }
1168
1169    pub fn call_function(&mut self, func: &Function, args: Vec<Value>) -> Result<Value, RuntimeError> {
1170        if args.len() != func.params.len() {
1171            return Err(RuntimeError::new(format!(
1172                "Expected {} arguments, got {}",
1173                func.params.len(),
1174                args.len()
1175            )));
1176        }
1177
1178        // Create new environment for function
1179        let env = Rc::new(RefCell::new(Environment::with_parent(func.closure.clone())));
1180
1181        // Bind parameters
1182        for (param, value) in func.params.iter().zip(args) {
1183            env.borrow_mut().define(param.clone(), value);
1184        }
1185
1186        // Execute function body
1187        let prev_env = self.environment.clone();
1188        self.environment = env;
1189
1190        let result = match self.evaluate(&func.body) {
1191            Ok(val) => Ok(val),
1192            Err(e) if e.message == "return" => {
1193                // Extract return value from stored location
1194                Ok(self.return_value.take().unwrap_or(Value::Null))
1195            }
1196            Err(e) => Err(e),
1197        };
1198
1199        self.environment = prev_env;
1200        result
1201    }
1202
1203    fn call_builtin(&mut self, builtin: &BuiltInFn, args: Vec<Value>) -> Result<Value, RuntimeError> {
1204        if let Some(arity) = builtin.arity {
1205            if args.len() != arity {
1206                return Err(RuntimeError::new(format!(
1207                    "{}() expects {} arguments, got {}",
1208                    builtin.name, arity, args.len()
1209                )));
1210            }
1211        }
1212        (builtin.func)(self, args)
1213    }
1214
1215    /// Await a value - if it's a future, resolve it; otherwise return as-is
1216    pub fn await_value(&mut self, value: Value) -> Result<Value, RuntimeError> {
1217        match value {
1218            Value::Future(fut) => {
1219                let mut fut_inner = fut.borrow_mut();
1220                self.poll_future(&mut fut_inner)
1221            }
1222            // Non-futures return immediately
1223            other => Ok(other),
1224        }
1225    }
1226
1227    /// Poll a future to completion
1228    fn poll_future(&mut self, fut: &mut FutureInner) -> Result<Value, RuntimeError> {
1229        // Check if already resolved
1230        match &fut.state {
1231            FutureState::Ready(v) => return Ok((**v).clone()),
1232            FutureState::Failed(e) => return Err(RuntimeError::new(e.clone())),
1233            _ => {}
1234        }
1235
1236        // Check if it's a timer future
1237        if let Some(complete_at) = fut.complete_at {
1238            if std::time::Instant::now() >= complete_at {
1239                fut.state = FutureState::Ready(Box::new(Value::Null));
1240                return Ok(Value::Null);
1241            } else {
1242                // Timer not complete - in interpreter, we just sleep
1243                let remaining = complete_at - std::time::Instant::now();
1244                std::thread::sleep(remaining);
1245                fut.state = FutureState::Ready(Box::new(Value::Null));
1246                return Ok(Value::Null);
1247            }
1248        }
1249
1250        // Execute computation if pending
1251        if let Some(computation) = fut.computation.take() {
1252            fut.state = FutureState::Running;
1253
1254            match computation {
1255                FutureComputation::Immediate(v) => {
1256                    fut.state = FutureState::Ready(v.clone());
1257                    Ok((*v).clone())
1258                }
1259                FutureComputation::Timer(duration) => {
1260                    // Sleep for the duration
1261                    std::thread::sleep(duration);
1262                    fut.state = FutureState::Ready(Box::new(Value::Null));
1263                    Ok(Value::Null)
1264                }
1265                FutureComputation::Lazy { func, args } => {
1266                    // Execute the function
1267                    match self.call_function(&func, args) {
1268                        Ok(result) => {
1269                            fut.state = FutureState::Ready(Box::new(result.clone()));
1270                            Ok(result)
1271                        }
1272                        Err(e) => {
1273                            fut.state = FutureState::Failed(e.message.clone());
1274                            Err(e)
1275                        }
1276                    }
1277                }
1278                FutureComputation::Join(futures) => {
1279                    // Await all futures and collect results
1280                    let mut results = Vec::new();
1281                    for f in futures {
1282                        let mut f_inner = f.borrow_mut();
1283                        results.push(self.poll_future(&mut f_inner)?);
1284                    }
1285                    let result = Value::Array(Rc::new(RefCell::new(results)));
1286                    fut.state = FutureState::Ready(Box::new(result.clone()));
1287                    Ok(result)
1288                }
1289                FutureComputation::Race(futures) => {
1290                    // Return first completed future
1291                    // In interpreter, just poll in order
1292                    for f in futures {
1293                        let f_inner = f.borrow_mut();
1294                        if matches!(f_inner.state, FutureState::Ready(_)) {
1295                            if let FutureState::Ready(v) = &f_inner.state {
1296                                fut.state = FutureState::Ready(v.clone());
1297                                return Ok((**v).clone());
1298                            }
1299                        }
1300                    }
1301                    // None ready, poll first one
1302                    Err(RuntimeError::new("No futures ready in race"))
1303                }
1304            }
1305        } else {
1306            // No computation - return current state
1307            match &fut.state {
1308                FutureState::Ready(v) => Ok((**v).clone()),
1309                FutureState::Failed(e) => Err(RuntimeError::new(e.clone())),
1310                _ => Err(RuntimeError::new("Future has no computation")),
1311            }
1312        }
1313    }
1314
1315    /// Create a new future from a value
1316    pub fn make_future_immediate(&self, value: Value) -> Value {
1317        Value::Future(Rc::new(RefCell::new(FutureInner {
1318            state: FutureState::Ready(Box::new(value)),
1319            computation: None,
1320            complete_at: None,
1321        })))
1322    }
1323
1324    /// Create a pending future with lazy computation
1325    pub fn make_future_lazy(&self, func: Rc<Function>, args: Vec<Value>) -> Value {
1326        Value::Future(Rc::new(RefCell::new(FutureInner {
1327            state: FutureState::Pending,
1328            computation: Some(FutureComputation::Lazy { func, args }),
1329            complete_at: None,
1330        })))
1331    }
1332
1333    /// Create a timer future
1334    pub fn make_future_timer(&self, duration: std::time::Duration) -> Value {
1335        Value::Future(Rc::new(RefCell::new(FutureInner {
1336            state: FutureState::Pending,
1337            computation: Some(FutureComputation::Timer(duration)),
1338            complete_at: Some(std::time::Instant::now() + duration),
1339        })))
1340    }
1341
1342    fn eval_array(&mut self, elements: &[Expr]) -> Result<Value, RuntimeError> {
1343        let values: Vec<Value> = elements.iter()
1344            .map(|e| self.evaluate(e))
1345            .collect::<Result<_, _>>()?;
1346        Ok(Value::Array(Rc::new(RefCell::new(values))))
1347    }
1348
1349    fn eval_tuple(&mut self, elements: &[Expr]) -> Result<Value, RuntimeError> {
1350        let values: Vec<Value> = elements.iter()
1351            .map(|e| self.evaluate(e))
1352            .collect::<Result<_, _>>()?;
1353        Ok(Value::Tuple(Rc::new(values)))
1354    }
1355
1356    fn eval_block(&mut self, block: &Block) -> Result<Value, RuntimeError> {
1357        let env = Rc::new(RefCell::new(Environment::with_parent(self.environment.clone())));
1358        let prev_env = self.environment.clone();
1359        self.environment = env;
1360
1361        let mut result = Value::Null;
1362
1363        for stmt in &block.stmts {
1364            match stmt {
1365                Stmt::Let { pattern, init, .. } => {
1366                    let value = match init {
1367                        Some(expr) => self.evaluate(expr)?,
1368                        None => Value::Null,
1369                    };
1370                    self.bind_pattern(pattern, value)?;
1371                }
1372                Stmt::Expr(expr) => {
1373                    result = self.evaluate(expr)?;
1374                }
1375                Stmt::Semi(expr) => {
1376                    self.evaluate(expr)?;
1377                    result = Value::Null;
1378                }
1379                Stmt::Item(item) => {
1380                    self.execute_item(item)?;
1381                }
1382            }
1383        }
1384
1385        if let Some(expr) = &block.expr {
1386            result = self.evaluate(expr)?;
1387        }
1388
1389        self.environment = prev_env;
1390        Ok(result)
1391    }
1392
1393    fn bind_pattern(&mut self, pattern: &Pattern, value: Value) -> Result<(), RuntimeError> {
1394        match pattern {
1395            Pattern::Ident { name, .. } => {
1396                self.environment.borrow_mut().define(name.name.clone(), value);
1397                Ok(())
1398            }
1399            Pattern::Tuple(patterns) => {
1400                if let Value::Tuple(values) = value {
1401                    if patterns.len() != values.len() {
1402                        return Err(RuntimeError::new("Tuple pattern size mismatch"));
1403                    }
1404                    for (p, v) in patterns.iter().zip(values.iter()) {
1405                        self.bind_pattern(p, v.clone())?;
1406                    }
1407                    Ok(())
1408                } else {
1409                    Err(RuntimeError::new("Expected tuple"))
1410                }
1411            }
1412            Pattern::Wildcard => Ok(()),
1413            _ => Err(RuntimeError::new("Unsupported pattern")),
1414        }
1415    }
1416
1417    fn eval_if(
1418        &mut self,
1419        condition: &Expr,
1420        then_branch: &Block,
1421        else_branch: &Option<Box<Expr>>,
1422    ) -> Result<Value, RuntimeError> {
1423        let cond = self.evaluate(condition)?;
1424        if self.is_truthy(&cond) {
1425            self.eval_block(then_branch)
1426        } else if let Some(else_expr) = else_branch {
1427            self.evaluate(else_expr)
1428        } else {
1429            Ok(Value::Null)
1430        }
1431    }
1432
1433    fn eval_match(&mut self, expr: &Expr, arms: &[MatchArm]) -> Result<Value, RuntimeError> {
1434        let value = self.evaluate(expr)?;
1435
1436        for arm in arms {
1437            if self.pattern_matches(&arm.pattern, &value)? {
1438                // Check guard if present
1439                if let Some(guard) = &arm.guard {
1440                    let guard_val = self.evaluate(guard)?;
1441                    if !self.is_truthy(&guard_val) {
1442                        continue;
1443                    }
1444                }
1445
1446                // Bind pattern variables and evaluate body
1447                let env = Rc::new(RefCell::new(Environment::with_parent(self.environment.clone())));
1448                let prev_env = self.environment.clone();
1449                self.environment = env;
1450
1451                self.bind_pattern(&arm.pattern, value)?;
1452                let result = self.evaluate(&arm.body);
1453
1454                self.environment = prev_env;
1455                return result;
1456            }
1457        }
1458
1459        Err(RuntimeError::new("No matching pattern"))
1460    }
1461
1462    fn pattern_matches(&mut self, pattern: &Pattern, value: &Value) -> Result<bool, RuntimeError> {
1463        match (pattern, value) {
1464            (Pattern::Wildcard, _) => Ok(true),
1465            (Pattern::Ident { .. }, _) => Ok(true),
1466            (Pattern::Literal(lit), val) => {
1467                let lit_val = self.eval_literal(lit)?;
1468                Ok(self.values_equal(&lit_val, val))
1469            }
1470            (Pattern::Tuple(patterns), Value::Tuple(values)) => {
1471                if patterns.len() != values.len() {
1472                    return Ok(false);
1473                }
1474                for (p, v) in patterns.iter().zip(values.iter()) {
1475                    if !self.pattern_matches(p, v)? {
1476                        return Ok(false);
1477                    }
1478                }
1479                Ok(true)
1480            }
1481            _ => Ok(false),
1482        }
1483    }
1484
1485    fn values_equal(&self, a: &Value, b: &Value) -> bool {
1486        match (a, b) {
1487            (Value::Null, Value::Null) => true,
1488            (Value::Bool(a), Value::Bool(b)) => a == b,
1489            (Value::Int(a), Value::Int(b)) => a == b,
1490            (Value::Float(a), Value::Float(b)) => (a - b).abs() < f64::EPSILON,
1491            (Value::String(a), Value::String(b)) => a == b,
1492            (Value::Char(a), Value::Char(b)) => a == b,
1493            _ => false,
1494        }
1495    }
1496
1497    fn eval_for(&mut self, pattern: &Pattern, iter: &Expr, body: &Block) -> Result<Value, RuntimeError> {
1498        let iterable = self.evaluate(iter)?;
1499        let items = match iterable {
1500            Value::Array(arr) => arr.borrow().clone(),
1501            Value::Tuple(t) => (*t).clone(),
1502            _ => return Err(RuntimeError::new("Cannot iterate over non-iterable")),
1503        };
1504
1505        let mut result = Value::Null;
1506        for item in items {
1507            let env = Rc::new(RefCell::new(Environment::with_parent(self.environment.clone())));
1508            let prev_env = self.environment.clone();
1509            self.environment = env;
1510
1511            self.bind_pattern(pattern, item)?;
1512
1513            match self.eval_block(body) {
1514                Ok(val) => result = val,
1515                Err(e) if e.message == "break" => {
1516                    self.environment = prev_env;
1517                    break;
1518                }
1519                Err(e) if e.message == "continue" => {
1520                    self.environment = prev_env;
1521                    continue;
1522                }
1523                Err(e) => {
1524                    self.environment = prev_env;
1525                    return Err(e);
1526                }
1527            }
1528
1529            self.environment = prev_env;
1530        }
1531
1532        Ok(result)
1533    }
1534
1535    fn eval_while(&mut self, condition: &Expr, body: &Block) -> Result<Value, RuntimeError> {
1536        let mut result = Value::Null;
1537        loop {
1538            let cond = self.evaluate(condition)?;
1539            if !self.is_truthy(&cond) {
1540                break;
1541            }
1542
1543            match self.eval_block(body) {
1544                Ok(val) => result = val,
1545                Err(e) if e.message == "break" => break,
1546                Err(e) if e.message == "continue" => continue,
1547                Err(e) => return Err(e),
1548            }
1549        }
1550        Ok(result)
1551    }
1552
1553    fn eval_loop(&mut self, body: &Block) -> Result<Value, RuntimeError> {
1554        loop {
1555            match self.eval_block(body) {
1556                Ok(_) => {}
1557                Err(e) if e.message == "break" => break,
1558                Err(e) if e.message == "continue" => continue,
1559                Err(e) => return Err(e),
1560            }
1561        }
1562        Ok(Value::Null)
1563    }
1564
1565    fn eval_return(&mut self, value: &Option<Box<Expr>>) -> Result<Value, RuntimeError> {
1566        let val = match value {
1567            Some(expr) => self.evaluate(expr)?,
1568            None => Value::Null,
1569        };
1570        // Store return value for call_function to retrieve
1571        self.return_value = Some(val);
1572        Err(RuntimeError::new("return"))
1573    }
1574
1575    fn eval_break(&mut self, _value: &Option<Box<Expr>>) -> Result<Value, RuntimeError> {
1576        // TODO: break with value for loop expressions
1577        Err(RuntimeError::new("break"))
1578    }
1579
1580    fn eval_index(&mut self, expr: &Expr, index: &Expr) -> Result<Value, RuntimeError> {
1581        let collection = self.evaluate(expr)?;
1582        let idx = self.evaluate(index)?;
1583
1584        match (collection, idx) {
1585            (Value::Array(arr), Value::Int(i)) => {
1586                let arr = arr.borrow();
1587                let i = if i < 0 { arr.len() as i64 + i } else { i } as usize;
1588                arr.get(i).cloned()
1589                    .ok_or_else(|| RuntimeError::new("Index out of bounds"))
1590            }
1591            (Value::Tuple(t), Value::Int(i)) => {
1592                let i = if i < 0 { t.len() as i64 + i } else { i } as usize;
1593                t.get(i).cloned()
1594                    .ok_or_else(|| RuntimeError::new("Index out of bounds"))
1595            }
1596            (Value::String(s), Value::Int(i)) => {
1597                let i = if i < 0 { s.len() as i64 + i } else { i } as usize;
1598                s.chars().nth(i)
1599                    .map(Value::Char)
1600                    .ok_or_else(|| RuntimeError::new("Index out of bounds"))
1601            }
1602            _ => Err(RuntimeError::new("Cannot index")),
1603        }
1604    }
1605
1606    fn eval_field(&mut self, expr: &Expr, field: &Ident) -> Result<Value, RuntimeError> {
1607        let value = self.evaluate(expr)?;
1608        match value {
1609            Value::Struct { fields, .. } => {
1610                fields.borrow().get(&field.name).cloned()
1611                    .ok_or_else(|| RuntimeError::new(format!("Unknown field: {}", field.name)))
1612            }
1613            Value::Tuple(t) => {
1614                // Tuple field access like .0, .1
1615                let idx: usize = field.name.parse()
1616                    .map_err(|_| RuntimeError::new("Invalid tuple index"))?;
1617                t.get(idx).cloned()
1618                    .ok_or_else(|| RuntimeError::new("Tuple index out of bounds"))
1619            }
1620            _ => Err(RuntimeError::new("Cannot access field on non-struct")),
1621        }
1622    }
1623
1624    fn eval_method_call(
1625        &mut self,
1626        receiver: &Expr,
1627        method: &Ident,
1628        args: &[Expr],
1629    ) -> Result<Value, RuntimeError> {
1630        let recv = self.evaluate(receiver)?;
1631        let arg_values: Vec<Value> = args.iter()
1632            .map(|a| self.evaluate(a))
1633            .collect::<Result<_, _>>()?;
1634
1635        // Built-in methods
1636        match (&recv, method.name.as_str()) {
1637            (Value::Array(arr), "len") => Ok(Value::Int(arr.borrow().len() as i64)),
1638            (Value::Array(arr), "push") => {
1639                if arg_values.len() != 1 {
1640                    return Err(RuntimeError::new("push expects 1 argument"));
1641                }
1642                arr.borrow_mut().push(arg_values[0].clone());
1643                Ok(Value::Null)
1644            }
1645            (Value::Array(arr), "pop") => {
1646                arr.borrow_mut().pop()
1647                    .ok_or_else(|| RuntimeError::new("pop on empty array"))
1648            }
1649            (Value::Array(arr), "reverse") => {
1650                let mut v = arr.borrow().clone();
1651                v.reverse();
1652                Ok(Value::Array(Rc::new(RefCell::new(v))))
1653            }
1654            (Value::String(s), "len") => Ok(Value::Int(s.len() as i64)),
1655            (Value::String(s), "chars") => {
1656                let chars: Vec<Value> = s.chars().map(Value::Char).collect();
1657                Ok(Value::Array(Rc::new(RefCell::new(chars))))
1658            }
1659            (Value::String(s), "contains") => {
1660                if arg_values.len() != 1 {
1661                    return Err(RuntimeError::new("contains expects 1 argument"));
1662                }
1663                match &arg_values[0] {
1664                    Value::String(sub) => Ok(Value::Bool(s.contains(sub.as_str()))),
1665                    _ => Err(RuntimeError::new("contains expects string")),
1666                }
1667            }
1668            _ => Err(RuntimeError::new(format!("Unknown method: {}", method.name))),
1669        }
1670    }
1671
1672    fn eval_pipe(&mut self, expr: &Expr, operations: &[PipeOp]) -> Result<Value, RuntimeError> {
1673        let mut value = self.evaluate(expr)?;
1674
1675        for op in operations {
1676            value = self.apply_pipe_op(value, op)?;
1677        }
1678
1679        Ok(value)
1680    }
1681
1682    fn apply_pipe_op(&mut self, value: Value, op: &PipeOp) -> Result<Value, RuntimeError> {
1683        match op {
1684            PipeOp::Transform(body) => {
1685                // τ{f} - map over collection or apply to single value
1686                match value {
1687                    Value::Array(arr) => {
1688                        let results: Vec<Value> = arr.borrow().iter()
1689                            .map(|item| {
1690                                self.environment.borrow_mut().define("_".to_string(), item.clone());
1691                                self.evaluate(body)
1692                            })
1693                            .collect::<Result<_, _>>()?;
1694                        Ok(Value::Array(Rc::new(RefCell::new(results))))
1695                    }
1696                    single => {
1697                        self.environment.borrow_mut().define("_".to_string(), single);
1698                        self.evaluate(body)
1699                    }
1700                }
1701            }
1702            PipeOp::Filter(predicate) => {
1703                // φ{p} - filter collection
1704                match value {
1705                    Value::Array(arr) => {
1706                        let results: Vec<Value> = arr.borrow().iter()
1707                            .filter_map(|item| {
1708                                self.environment.borrow_mut().define("_".to_string(), item.clone());
1709                                match self.evaluate(predicate) {
1710                                    Ok(v) if self.is_truthy(&v) => Some(Ok(item.clone())),
1711                                    Ok(_) => None,
1712                                    Err(e) => Some(Err(e)),
1713                                }
1714                            })
1715                            .collect::<Result<_, _>>()?;
1716                        Ok(Value::Array(Rc::new(RefCell::new(results))))
1717                    }
1718                    _ => Err(RuntimeError::new("Filter requires array")),
1719                }
1720            }
1721            PipeOp::Sort(field) => {
1722                // σ - sort collection
1723                match value {
1724                    Value::Array(arr) => {
1725                        let mut v = arr.borrow().clone();
1726                        v.sort_by(|a, b| self.compare_values(a, b, field));
1727                        Ok(Value::Array(Rc::new(RefCell::new(v))))
1728                    }
1729                    _ => Err(RuntimeError::new("Sort requires array")),
1730                }
1731            }
1732            PipeOp::Reduce(body) => {
1733                // ρ{f} - reduce collection
1734                match value {
1735                    Value::Array(arr) => {
1736                        let arr = arr.borrow();
1737                        if arr.is_empty() {
1738                            return Err(RuntimeError::new("Cannot reduce empty array"));
1739                        }
1740                        let mut acc = arr[0].clone();
1741                        for item in arr.iter().skip(1) {
1742                            self.environment.borrow_mut().define("acc".to_string(), acc);
1743                            self.environment.borrow_mut().define("_".to_string(), item.clone());
1744                            acc = self.evaluate(body)?;
1745                        }
1746                        Ok(acc)
1747                    }
1748                    _ => Err(RuntimeError::new("Reduce requires array")),
1749                }
1750            }
1751            PipeOp::Method { name, args } => {
1752                let arg_values: Vec<Value> = args.iter()
1753                    .map(|a| self.evaluate(a))
1754                    .collect::<Result<_, _>>()?;
1755
1756                // Check for built-in pipe methods
1757                match name.name.as_str() {
1758                    "collect" => Ok(value), // Already collected
1759                    "sum" | "Σ" => self.sum_values(value),
1760                    "product" | "Π" => self.product_values(value),
1761                    "len" => {
1762                        match &value {
1763                            Value::Array(arr) => Ok(Value::Int(arr.borrow().len() as i64)),
1764                            Value::String(s) => Ok(Value::Int(s.len() as i64)),
1765                            _ => Err(RuntimeError::new("len requires array or string")),
1766                        }
1767                    }
1768                    "reverse" => {
1769                        match value {
1770                            Value::Array(arr) => {
1771                                let mut v = arr.borrow().clone();
1772                                v.reverse();
1773                                Ok(Value::Array(Rc::new(RefCell::new(v))))
1774                            }
1775                            _ => Err(RuntimeError::new("reverse requires array")),
1776                        }
1777                    }
1778                    "first" => {
1779                        match &value {
1780                            Value::Array(arr) => arr.borrow().first().cloned()
1781                                .ok_or_else(|| RuntimeError::new("first on empty array")),
1782                            _ => Err(RuntimeError::new("first requires array")),
1783                        }
1784                    }
1785                    "last" => {
1786                        match &value {
1787                            Value::Array(arr) => arr.borrow().last().cloned()
1788                                .ok_or_else(|| RuntimeError::new("last on empty array")),
1789                            _ => Err(RuntimeError::new("last requires array")),
1790                        }
1791                    }
1792                    "take" => {
1793                        if arg_values.len() != 1 {
1794                            return Err(RuntimeError::new("take requires 1 argument"));
1795                        }
1796                        let n = match &arg_values[0] {
1797                            Value::Int(n) => *n as usize,
1798                            _ => return Err(RuntimeError::new("take requires integer")),
1799                        };
1800                        match value {
1801                            Value::Array(arr) => {
1802                                let v: Vec<Value> = arr.borrow().iter().take(n).cloned().collect();
1803                                Ok(Value::Array(Rc::new(RefCell::new(v))))
1804                            }
1805                            _ => Err(RuntimeError::new("take requires array")),
1806                        }
1807                    }
1808                    "skip" => {
1809                        if arg_values.len() != 1 {
1810                            return Err(RuntimeError::new("skip requires 1 argument"));
1811                        }
1812                        let n = match &arg_values[0] {
1813                            Value::Int(n) => *n as usize,
1814                            _ => return Err(RuntimeError::new("skip requires integer")),
1815                        };
1816                        match value {
1817                            Value::Array(arr) => {
1818                                let v: Vec<Value> = arr.borrow().iter().skip(n).cloned().collect();
1819                                Ok(Value::Array(Rc::new(RefCell::new(v))))
1820                            }
1821                            _ => Err(RuntimeError::new("skip requires array")),
1822                        }
1823                    }
1824                    _ => Err(RuntimeError::new(format!("Unknown pipe method: {}", name.name))),
1825                }
1826            }
1827            PipeOp::Await => {
1828                // Await a future - resolve it to a value
1829                self.await_value(value)
1830            }
1831            // New access morphemes
1832            PipeOp::First => {
1833                // α - first element
1834                match &value {
1835                    Value::Array(arr) => arr.borrow().first().cloned()
1836                        .ok_or_else(|| RuntimeError::new("first (α) on empty array")),
1837                    Value::Tuple(t) => t.first().cloned()
1838                        .ok_or_else(|| RuntimeError::new("first (α) on empty tuple")),
1839                    _ => Err(RuntimeError::new("first (α) requires array or tuple")),
1840                }
1841            }
1842            PipeOp::Last => {
1843                // ω - last element
1844                match &value {
1845                    Value::Array(arr) => arr.borrow().last().cloned()
1846                        .ok_or_else(|| RuntimeError::new("last (ω) on empty array")),
1847                    Value::Tuple(t) => t.last().cloned()
1848                        .ok_or_else(|| RuntimeError::new("last (ω) on empty tuple")),
1849                    _ => Err(RuntimeError::new("last (ω) requires array or tuple")),
1850                }
1851            }
1852            PipeOp::Middle => {
1853                // μ - middle/median element
1854                match &value {
1855                    Value::Array(arr) => {
1856                        let arr = arr.borrow();
1857                        if arr.is_empty() {
1858                            return Err(RuntimeError::new("middle (μ) on empty array"));
1859                        }
1860                        let mid = arr.len() / 2;
1861                        Ok(arr[mid].clone())
1862                    }
1863                    Value::Tuple(t) => {
1864                        if t.is_empty() {
1865                            return Err(RuntimeError::new("middle (μ) on empty tuple"));
1866                        }
1867                        let mid = t.len() / 2;
1868                        Ok(t[mid].clone())
1869                    }
1870                    _ => Err(RuntimeError::new("middle (μ) requires array or tuple")),
1871                }
1872            }
1873            PipeOp::Choice => {
1874                // χ - random element
1875                use std::time::{SystemTime, UNIX_EPOCH};
1876                match &value {
1877                    Value::Array(arr) => {
1878                        let arr = arr.borrow();
1879                        if arr.is_empty() {
1880                            return Err(RuntimeError::new("choice (χ) on empty array"));
1881                        }
1882                        let seed = SystemTime::now()
1883                            .duration_since(UNIX_EPOCH)
1884                            .unwrap_or(std::time::Duration::ZERO)
1885                            .as_nanos() as u64;
1886                        let idx = ((seed.wrapping_mul(1103515245).wrapping_add(12345)) >> 16) as usize % arr.len();
1887                        Ok(arr[idx].clone())
1888                    }
1889                    Value::Tuple(t) => {
1890                        if t.is_empty() {
1891                            return Err(RuntimeError::new("choice (χ) on empty tuple"));
1892                        }
1893                        let seed = SystemTime::now()
1894                            .duration_since(UNIX_EPOCH)
1895                            .unwrap_or(std::time::Duration::ZERO)
1896                            .as_nanos() as u64;
1897                        let idx = ((seed.wrapping_mul(1103515245).wrapping_add(12345)) >> 16) as usize % t.len();
1898                        Ok(t[idx].clone())
1899                    }
1900                    _ => Err(RuntimeError::new("choice (χ) requires array or tuple")),
1901                }
1902            }
1903            PipeOp::Nth(index_expr) => {
1904                // ν{n} - nth element
1905                let index = match self.evaluate(index_expr)? {
1906                    Value::Int(n) => n,
1907                    _ => return Err(RuntimeError::new("nth (ν) index must be integer")),
1908                };
1909                match &value {
1910                    Value::Array(arr) => {
1911                        let arr = arr.borrow();
1912                        if index < 0 || index as usize >= arr.len() {
1913                            return Err(RuntimeError::new("nth (ν) index out of bounds"));
1914                        }
1915                        Ok(arr[index as usize].clone())
1916                    }
1917                    Value::Tuple(t) => {
1918                        if index < 0 || index as usize >= t.len() {
1919                            return Err(RuntimeError::new("nth (ν) index out of bounds"));
1920                        }
1921                        Ok(t[index as usize].clone())
1922                    }
1923                    _ => Err(RuntimeError::new("nth (ν) requires array or tuple")),
1924                }
1925            }
1926            PipeOp::Next => {
1927                // ξ - next element (for iterators, currently just returns first)
1928                // In a full implementation, this would advance an iterator
1929                match &value {
1930                    Value::Array(arr) => arr.borrow().first().cloned()
1931                        .ok_or_else(|| RuntimeError::new("next (ξ) on empty array")),
1932                    Value::Tuple(t) => t.first().cloned()
1933                        .ok_or_else(|| RuntimeError::new("next (ξ) on empty tuple")),
1934                    _ => Err(RuntimeError::new("next (ξ) requires array or tuple")),
1935                }
1936            }
1937            PipeOp::Named { prefix, body } => {
1938                // Named morpheme like ·map{f}
1939                let method_name = prefix.iter().map(|i| i.name.as_str()).collect::<Vec<_>>().join("·");
1940                match method_name.as_str() {
1941                    "map" => {
1942                        if let Some(body) = body {
1943                            match value {
1944                                Value::Array(arr) => {
1945                                    let results: Vec<Value> = arr.borrow().iter()
1946                                        .map(|item| {
1947                                            self.environment.borrow_mut().define("_".to_string(), item.clone());
1948                                            self.evaluate(body)
1949                                        })
1950                                        .collect::<Result<_, _>>()?;
1951                                    Ok(Value::Array(Rc::new(RefCell::new(results))))
1952                                }
1953                                _ => Err(RuntimeError::new("map requires array")),
1954                            }
1955                        } else {
1956                            Ok(value)
1957                        }
1958                    }
1959                    "filter" => {
1960                        if let Some(body) = body {
1961                            match value {
1962                                Value::Array(arr) => {
1963                                    let results: Vec<Value> = arr.borrow().iter()
1964                                        .filter_map(|item| {
1965                                            self.environment.borrow_mut().define("_".to_string(), item.clone());
1966                                            match self.evaluate(body) {
1967                                                Ok(v) if self.is_truthy(&v) => Some(Ok(item.clone())),
1968                                                Ok(_) => None,
1969                                                Err(e) => Some(Err(e)),
1970                                            }
1971                                        })
1972                                        .collect::<Result<_, _>>()?;
1973                                    Ok(Value::Array(Rc::new(RefCell::new(results))))
1974                                }
1975                                _ => Err(RuntimeError::new("filter requires array")),
1976                            }
1977                        } else {
1978                            Ok(value)
1979                        }
1980                    }
1981                    _ => Err(RuntimeError::new(format!("Unknown named morpheme: {}", method_name))),
1982                }
1983            }
1984            PipeOp::Parallel(inner_op) => {
1985                // ∥ - parallel execution of the inner operation
1986                // For arrays, execute the operation in parallel using threads
1987                match value {
1988                    Value::Array(arr) => {
1989                        use std::sync::{Arc, Mutex};
1990
1991                        let arr_ref = arr.borrow();
1992                        let len = arr_ref.len();
1993                        if len == 0 {
1994                            return Ok(Value::Array(Rc::new(RefCell::new(vec![]))));
1995                        }
1996
1997                        // For Transform operations, parallelize across elements
1998                        match inner_op.as_ref() {
1999                            PipeOp::Transform(body) => {
2000                                // Determine number of threads (use available parallelism)
2001                                let num_threads = std::thread::available_parallelism()
2002                                    .map(|p| p.get())
2003                                    .unwrap_or(4)
2004                                    .min(len);
2005
2006                                // For future parallel implementation
2007                                let _chunk_size = (len + num_threads - 1) / num_threads;
2008                                let _results = Arc::new(Mutex::new(vec![Value::Null; len]));
2009                                let items: Vec<Value> = arr_ref.clone();
2010                                drop(arr_ref);
2011
2012                                // Clone the body expression for each thread (for future use)
2013                                let _body_str = format!("{:?}", body);
2014
2015                                // For now, fall back to sequential since full parallelization
2016                                // requires thread-safe evaluation context
2017                                // In production, this would use Rayon or a work-stealing scheduler
2018                                let mut result_vec = Vec::with_capacity(len);
2019                                for item in items.iter() {
2020                                    self.environment.borrow_mut().define("_".to_string(), item.clone());
2021                                    result_vec.push(self.evaluate(body)?);
2022                                }
2023                                Ok(Value::Array(Rc::new(RefCell::new(result_vec))))
2024                            }
2025                            PipeOp::Filter(predicate) => {
2026                                // Parallel filter - evaluate predicate in parallel
2027                                let items: Vec<Value> = arr_ref.clone();
2028                                drop(arr_ref);
2029
2030                                let mut result_vec = Vec::new();
2031                                for item in items.iter() {
2032                                    self.environment.borrow_mut().define("_".to_string(), item.clone());
2033                                    let pred_result = self.evaluate(predicate)?;
2034                                    if self.is_truthy(&pred_result) {
2035                                        result_vec.push(item.clone());
2036                                    }
2037                                }
2038                                Ok(Value::Array(Rc::new(RefCell::new(result_vec))))
2039                            }
2040                            _ => {
2041                                // For other operations, just apply them normally
2042                                drop(arr_ref);
2043                                self.apply_pipe_op(Value::Array(arr), inner_op)
2044                            }
2045                        }
2046                    }
2047                    _ => {
2048                        // For non-arrays, just apply the inner operation
2049                        self.apply_pipe_op(value, inner_op)
2050                    }
2051                }
2052            }
2053            PipeOp::Gpu(inner_op) => {
2054                // ⊛ - GPU compute shader execution
2055                // This is a placeholder that falls back to CPU execution
2056                // In production, this would:
2057                // 1. Generate SPIR-V/WGSL compute shader
2058                // 2. Submit to GPU via wgpu/vulkan
2059                // 3. Read back results
2060                match value {
2061                    Value::Array(arr) => {
2062                        // For now, emit a hint that GPU execution would occur
2063                        // and fall back to CPU
2064                        #[cfg(debug_assertions)]
2065                        eprintln!("[GPU] Would execute {:?} on GPU, falling back to CPU", inner_op);
2066
2067                        self.apply_pipe_op(Value::Array(arr), inner_op)
2068                    }
2069                    _ => self.apply_pipe_op(value, inner_op)
2070                }
2071            }
2072
2073            // ==========================================
2074            // Protocol Operations - Sigil-native networking
2075            // All protocol results are wrapped with Reported evidentiality
2076            // since network data comes from external sources ("hearsay")
2077            // ==========================================
2078
2079            PipeOp::Send(data_expr) => {
2080                // |send{data} or |⇒{data} - Send data over a connection
2081                // The value should be a connection object
2082                let data = self.evaluate(data_expr)?;
2083
2084                // Create a protocol response with Reported evidentiality
2085                // In production, this would actually send data over the network
2086                let response = self.protocol_send(&value, &data)?;
2087
2088                // Wrap in Reported evidentiality - network responses are hearsay
2089                Ok(self.wrap_reported(response))
2090            }
2091
2092            PipeOp::Recv => {
2093                // |recv or |⇐ - Receive data from a connection
2094                // The value should be a connection object
2095
2096                // In production, this would actually receive data from the network
2097                let response = self.protocol_recv(&value)?;
2098
2099                // Wrap in Reported evidentiality - network data is hearsay
2100                Ok(self.wrap_reported(response))
2101            }
2102
2103            PipeOp::Stream(handler_expr) => {
2104                // |stream{handler} or |≋{handler} - Stream data with a handler
2105                let handler = self.evaluate(handler_expr)?;
2106
2107                // Create a streaming iterator over network data
2108                // Each element will be wrapped in Reported evidentiality
2109                let stream = self.protocol_stream(&value, &handler)?;
2110                Ok(stream)
2111            }
2112
2113            PipeOp::Connect(config_expr) => {
2114                // |connect or |connect{config} or |⊸{config} - Establish connection
2115                let config = match config_expr {
2116                    Some(expr) => Some(self.evaluate(expr)?),
2117                    None => None,
2118                };
2119
2120                // Create a connection object
2121                let connection = self.protocol_connect(&value, config.as_ref())?;
2122                Ok(connection)
2123            }
2124
2125            PipeOp::Close => {
2126                // |close or |⊗ - Close connection gracefully
2127                self.protocol_close(&value)?;
2128                Ok(Value::Null)
2129            }
2130
2131            PipeOp::Header { name, value: value_expr } => {
2132                // |header{name, value} - Add/set header on request
2133                let header_name = self.evaluate(name)?;
2134                let header_value = self.evaluate(value_expr)?;
2135
2136                // Add header to the request builder
2137                self.protocol_add_header(value, &header_name, &header_value)
2138            }
2139
2140            PipeOp::Body(data_expr) => {
2141                // |body{data} - Set request body
2142                let body_data = self.evaluate(data_expr)?;
2143
2144                // Set body on the request builder
2145                self.protocol_set_body(value, &body_data)
2146            }
2147
2148            PipeOp::Timeout(ms_expr) => {
2149                // |timeout{ms} or |⏱{ms} - Set operation timeout
2150                let ms = self.evaluate(ms_expr)?;
2151
2152                // Set timeout on the request/connection
2153                self.protocol_set_timeout(value, &ms)
2154            }
2155
2156            PipeOp::Retry { count, strategy } => {
2157                // |retry{count} or |retry{count, strategy} - Set retry policy
2158                let retry_count = self.evaluate(count)?;
2159                let retry_strategy = match strategy {
2160                    Some(s) => Some(self.evaluate(s)?),
2161                    None => None,
2162                };
2163
2164                // Set retry policy on the request
2165                self.protocol_set_retry(value, &retry_count, retry_strategy.as_ref())
2166            }
2167        }
2168    }
2169
2170    // ==========================================
2171    // Protocol Helper Methods
2172    // ==========================================
2173
2174    /// Wrap a value in Reported evidentiality
2175    /// Network data is "hearsay" - it comes from external sources we can't verify
2176    fn wrap_reported(&self, value: Value) -> Value {
2177        Value::Evidential {
2178            value: Box::new(value),
2179            evidence: Evidence::Reported,
2180        }
2181    }
2182
2183    /// Send data over a protocol connection
2184    fn protocol_send(&mut self, connection: &Value, data: &Value) -> Result<Value, RuntimeError> {
2185        // Extract connection info and send data
2186        match connection {
2187            Value::Map(obj) => {
2188                let obj = obj.borrow();
2189                if let Some(Value::String(protocol)) = obj.get("__protocol__") {
2190                    match protocol.as_str() {
2191                        "http" | "https" => {
2192                            // For HTTP, "send" means execute the request
2193                            // The data becomes the body
2194                            #[cfg(debug_assertions)]
2195                            eprintln!("[HTTP] Would send request with body: {:?}", data);
2196                            Ok(Value::Map(Rc::new(RefCell::new({
2197                                let mut response = HashMap::new();
2198                                response.insert("status".to_string(), Value::Int(200));
2199                                response.insert("body".to_string(), data.clone());
2200                                response.insert("__protocol__".to_string(), Value::String(Rc::new("http_response".to_string())));
2201                                response
2202                            }))))
2203                        }
2204                        "ws" | "wss" => {
2205                            // For WebSocket, send a message
2206                            #[cfg(debug_assertions)]
2207                            eprintln!("[WebSocket] Would send message: {:?}", data);
2208                            Ok(Value::Bool(true)) // Message sent successfully
2209                        }
2210                        "grpc" => {
2211                            // For gRPC, send the request message
2212                            #[cfg(debug_assertions)]
2213                            eprintln!("[gRPC] Would send message: {:?}", data);
2214                            Ok(Value::Map(Rc::new(RefCell::new({
2215                                let mut response = HashMap::new();
2216                                response.insert("status".to_string(), Value::Int(0)); // OK
2217                                response.insert("message".to_string(), data.clone());
2218                                response.insert("__protocol__".to_string(), Value::String(Rc::new("grpc_response".to_string())));
2219                                response
2220                            }))))
2221                        }
2222                        "kafka" => {
2223                            // For Kafka, produce a message
2224                            #[cfg(debug_assertions)]
2225                            eprintln!("[Kafka] Would produce message: {:?}", data);
2226                            Ok(Value::Map(Rc::new(RefCell::new({
2227                                let mut result = HashMap::new();
2228                                result.insert("partition".to_string(), Value::Int(0));
2229                                result.insert("offset".to_string(), Value::Int(42));
2230                                result
2231                            }))))
2232                        }
2233                        _ => Err(RuntimeError::new(format!("Unknown protocol: {}", protocol))),
2234                    }
2235                } else {
2236                    Err(RuntimeError::new("Connection object missing __protocol__ field"))
2237                }
2238            }
2239            _ => Err(RuntimeError::new("send requires a connection object")),
2240        }
2241    }
2242
2243    /// Receive data from a protocol connection
2244    fn protocol_recv(&mut self, connection: &Value) -> Result<Value, RuntimeError> {
2245        match connection {
2246            Value::Map(obj) => {
2247                let obj = obj.borrow();
2248                if let Some(Value::String(protocol)) = obj.get("__protocol__") {
2249                    match protocol.as_str() {
2250                        "ws" | "wss" => {
2251                            // For WebSocket, receive a message
2252                            #[cfg(debug_assertions)]
2253                            eprintln!("[WebSocket] Would receive message");
2254                            Ok(Value::String(Rc::new("received message".to_string())))
2255                        }
2256                        "kafka" => {
2257                            // For Kafka, consume a message
2258                            #[cfg(debug_assertions)]
2259                            eprintln!("[Kafka] Would consume message");
2260                            Ok(Value::Map(Rc::new(RefCell::new({
2261                                let mut msg = HashMap::new();
2262                                msg.insert("key".to_string(), Value::Null);
2263                                msg.insert("value".to_string(), Value::String(Rc::new("consumed message".to_string())));
2264                                msg.insert("partition".to_string(), Value::Int(0));
2265                                msg.insert("offset".to_string(), Value::Int(100));
2266                                msg
2267                            }))))
2268                        }
2269                        "grpc" => {
2270                            // For gRPC streaming, receive next message
2271                            #[cfg(debug_assertions)]
2272                            eprintln!("[gRPC] Would receive stream message");
2273                            Ok(Value::Map(Rc::new(RefCell::new({
2274                                let mut msg = HashMap::new();
2275                                msg.insert("data".to_string(), Value::String(Rc::new("stream data".to_string())));
2276                                msg
2277                            }))))
2278                        }
2279                        _ => Err(RuntimeError::new(format!("recv not supported for protocol: {}", protocol))),
2280                    }
2281                } else {
2282                    Err(RuntimeError::new("Connection object missing __protocol__ field"))
2283                }
2284            }
2285            _ => Err(RuntimeError::new("recv requires a connection object")),
2286        }
2287    }
2288
2289    /// Create a streaming iterator over protocol data
2290    fn protocol_stream(&mut self, connection: &Value, _handler: &Value) -> Result<Value, RuntimeError> {
2291        // Create a lazy stream that yields values with Reported evidentiality
2292        match connection {
2293            Value::Map(obj) => {
2294                let obj = obj.borrow();
2295                if let Some(Value::String(protocol)) = obj.get("__protocol__") {
2296                    #[cfg(debug_assertions)]
2297                    eprintln!("[{}] Would create stream", protocol);
2298
2299                    // Return a stream object that can be iterated
2300                    Ok(Value::Map(Rc::new(RefCell::new({
2301                        let mut stream = HashMap::new();
2302                        stream.insert("__type__".to_string(), Value::String(Rc::new("Stream".to_string())));
2303                        stream.insert("__protocol__".to_string(), Value::String(protocol.clone()));
2304                        stream.insert("__evidentiality__".to_string(), Value::String(Rc::new("reported".to_string())));
2305                        stream
2306                    }))))
2307                } else {
2308                    Err(RuntimeError::new("Connection object missing __protocol__ field"))
2309                }
2310            }
2311            _ => Err(RuntimeError::new("stream requires a connection object")),
2312        }
2313    }
2314
2315    /// Establish a protocol connection
2316    fn protocol_connect(&mut self, target: &Value, _config: Option<&Value>) -> Result<Value, RuntimeError> {
2317        match target {
2318            Value::String(url) => {
2319                // Parse URL to determine protocol
2320                let protocol = if url.starts_with("wss://") || url.starts_with("ws://") {
2321                    if url.starts_with("wss://") { "wss" } else { "ws" }
2322                } else if url.starts_with("https://") || url.starts_with("http://") {
2323                    if url.starts_with("https://") { "https" } else { "http" }
2324                } else if url.starts_with("grpc://") || url.starts_with("grpcs://") {
2325                    "grpc"
2326                } else if url.starts_with("kafka://") {
2327                    "kafka"
2328                } else if url.starts_with("amqp://") || url.starts_with("amqps://") {
2329                    "amqp"
2330                } else {
2331                    "unknown"
2332                };
2333
2334                #[cfg(debug_assertions)]
2335                eprintln!("[{}] Would connect to: {}", protocol, url);
2336
2337                // Return a connection object
2338                Ok(Value::Map(Rc::new(RefCell::new({
2339                    let mut conn = HashMap::new();
2340                    conn.insert("__protocol__".to_string(), Value::String(Rc::new(protocol.to_string())));
2341                    conn.insert("url".to_string(), Value::String(url.clone()));
2342                    conn.insert("connected".to_string(), Value::Bool(true));
2343                    conn
2344                }))))
2345            }
2346            Value::Map(obj) => {
2347                // Already a connection config object
2348                let mut conn = obj.borrow().clone();
2349                conn.insert("connected".to_string(), Value::Bool(true));
2350                Ok(Value::Map(Rc::new(RefCell::new(conn))))
2351            }
2352            _ => Err(RuntimeError::new("connect requires URL string or config object")),
2353        }
2354    }
2355
2356    /// Close a protocol connection
2357    fn protocol_close(&mut self, connection: &Value) -> Result<(), RuntimeError> {
2358        match connection {
2359            Value::Map(obj) => {
2360                let mut obj = obj.borrow_mut();
2361                if let Some(Value::String(protocol)) = obj.get("__protocol__").cloned() {
2362                    #[cfg(debug_assertions)]
2363                    eprintln!("[{}] Would close connection", protocol);
2364                    obj.insert("connected".to_string(), Value::Bool(false));
2365                    Ok(())
2366                } else {
2367                    Err(RuntimeError::new("Connection object missing __protocol__ field"))
2368                }
2369            }
2370            _ => Err(RuntimeError::new("close requires a connection object")),
2371        }
2372    }
2373
2374    /// Add a header to a protocol request
2375    fn protocol_add_header(&mut self, mut request: Value, name: &Value, header_value: &Value) -> Result<Value, RuntimeError> {
2376        let name_str = match name {
2377            Value::String(s) => (**s).clone(),
2378            _ => return Err(RuntimeError::new("Header name must be a string")),
2379        };
2380        let value_str = match header_value {
2381            Value::String(s) => (**s).clone(),
2382            Value::Int(i) => i.to_string(),
2383            _ => return Err(RuntimeError::new("Header value must be string or int")),
2384        };
2385
2386        match &mut request {
2387            Value::Map(obj) => {
2388                let mut obj = obj.borrow_mut();
2389
2390                // Get or create headers map
2391                let headers = obj.entry("headers".to_string())
2392                    .or_insert_with(|| Value::Map(Rc::new(RefCell::new(HashMap::new()))));
2393
2394                if let Value::Map(headers_obj) = headers {
2395                    headers_obj.borrow_mut().insert(name_str, Value::String(Rc::new(value_str)));
2396                }
2397                drop(obj);
2398                Ok(request)
2399            }
2400            _ => Err(RuntimeError::new("header requires a request object")),
2401        }
2402    }
2403
2404    /// Set the body of a protocol request
2405    fn protocol_set_body(&mut self, mut request: Value, body: &Value) -> Result<Value, RuntimeError> {
2406        match &mut request {
2407            Value::Map(obj) => {
2408                obj.borrow_mut().insert("body".to_string(), body.clone());
2409                Ok(request)
2410            }
2411            _ => Err(RuntimeError::new("body requires a request object")),
2412        }
2413    }
2414
2415    /// Set the timeout for a protocol operation
2416    fn protocol_set_timeout(&mut self, mut request: Value, ms: &Value) -> Result<Value, RuntimeError> {
2417        let timeout_ms = match ms {
2418            Value::Int(n) => *n,
2419            Value::Float(f) => *f as i64,
2420            _ => return Err(RuntimeError::new("Timeout must be a number (milliseconds)")),
2421        };
2422
2423        match &mut request {
2424            Value::Map(obj) => {
2425                obj.borrow_mut().insert("timeout_ms".to_string(), Value::Int(timeout_ms));
2426                Ok(request)
2427            }
2428            _ => Err(RuntimeError::new("timeout requires a request object")),
2429        }
2430    }
2431
2432    /// Set the retry policy for a protocol operation
2433    fn protocol_set_retry(&mut self, mut request: Value, count: &Value, strategy: Option<&Value>) -> Result<Value, RuntimeError> {
2434        let retry_count = match count {
2435            Value::Int(n) => *n,
2436            _ => return Err(RuntimeError::new("Retry count must be an integer")),
2437        };
2438
2439        match &mut request {
2440            Value::Map(obj) => {
2441                let mut obj = obj.borrow_mut();
2442                obj.insert("retry_count".to_string(), Value::Int(retry_count));
2443                if let Some(strat) = strategy {
2444                    obj.insert("retry_strategy".to_string(), strat.clone());
2445                }
2446                drop(obj);
2447                Ok(request)
2448            }
2449            _ => Err(RuntimeError::new("retry requires a request object")),
2450        }
2451    }
2452
2453    fn sum_values(&self, value: Value) -> Result<Value, RuntimeError> {
2454        match value {
2455            Value::Array(arr) => {
2456                let arr = arr.borrow();
2457                if arr.is_empty() {
2458                    return Ok(Value::Int(0));
2459                }
2460                let mut sum = match &arr[0] {
2461                    Value::Int(_) => Value::Int(0),
2462                    Value::Float(_) => Value::Float(0.0),
2463                    _ => return Err(RuntimeError::new("Cannot sum non-numeric array")),
2464                };
2465                for item in arr.iter() {
2466                    sum = match (&sum, item) {
2467                        (Value::Int(a), Value::Int(b)) => Value::Int(a + b),
2468                        (Value::Float(a), Value::Float(b)) => Value::Float(a + b),
2469                        (Value::Int(a), Value::Float(b)) => Value::Float(*a as f64 + b),
2470                        (Value::Float(a), Value::Int(b)) => Value::Float(a + *b as f64),
2471                        _ => return Err(RuntimeError::new("Cannot sum non-numeric values")),
2472                    };
2473                }
2474                Ok(sum)
2475            }
2476            _ => Err(RuntimeError::new("sum requires array")),
2477        }
2478    }
2479
2480    fn product_values(&self, value: Value) -> Result<Value, RuntimeError> {
2481        match value {
2482            Value::Array(arr) => {
2483                let arr = arr.borrow();
2484                if arr.is_empty() {
2485                    return Ok(Value::Int(1));
2486                }
2487                let mut prod = match &arr[0] {
2488                    Value::Int(_) => Value::Int(1),
2489                    Value::Float(_) => Value::Float(1.0),
2490                    _ => return Err(RuntimeError::new("Cannot multiply non-numeric array")),
2491                };
2492                for item in arr.iter() {
2493                    prod = match (&prod, item) {
2494                        (Value::Int(a), Value::Int(b)) => Value::Int(a * b),
2495                        (Value::Float(a), Value::Float(b)) => Value::Float(a * b),
2496                        (Value::Int(a), Value::Float(b)) => Value::Float(*a as f64 * b),
2497                        (Value::Float(a), Value::Int(b)) => Value::Float(a * *b as f64),
2498                        _ => return Err(RuntimeError::new("Cannot multiply non-numeric values")),
2499                    };
2500                }
2501                Ok(prod)
2502            }
2503            _ => Err(RuntimeError::new("product requires array")),
2504        }
2505    }
2506
2507    fn compare_values(&self, a: &Value, b: &Value, _field: &Option<Ident>) -> std::cmp::Ordering {
2508        // Simple comparison for now
2509        match (a, b) {
2510            (Value::Int(a), Value::Int(b)) => a.cmp(b),
2511            (Value::Float(a), Value::Float(b)) => a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal),
2512            (Value::String(a), Value::String(b)) => a.cmp(b),
2513            _ => std::cmp::Ordering::Equal,
2514        }
2515    }
2516
2517    fn eval_closure(&mut self, params: &[ClosureParam], body: &Expr) -> Result<Value, RuntimeError> {
2518        let param_names: Vec<String> = params.iter().map(|p| {
2519            match &p.pattern {
2520                Pattern::Ident { name, .. } => name.name.clone(),
2521                _ => "_".to_string(),
2522            }
2523        }).collect();
2524
2525        Ok(Value::Function(Rc::new(Function {
2526            name: None,
2527            params: param_names,
2528            body: body.clone(),
2529            closure: self.environment.clone(),
2530        })))
2531    }
2532
2533    fn eval_struct_literal(
2534        &mut self,
2535        path: &TypePath,
2536        fields: &[FieldInit],
2537        _rest: &Option<Box<Expr>>,
2538    ) -> Result<Value, RuntimeError> {
2539        let name = path.segments.iter()
2540            .map(|s| s.ident.name.as_str())
2541            .collect::<Vec<_>>()
2542            .join("::");
2543
2544        let mut field_values = HashMap::new();
2545        for field in fields {
2546            let value = match &field.value {
2547                Some(expr) => self.evaluate(expr)?,
2548                None => self.environment.borrow().get(&field.name.name)
2549                    .ok_or_else(|| RuntimeError::new(format!("Unknown variable: {}", field.name.name)))?,
2550            };
2551            field_values.insert(field.name.name.clone(), value);
2552        }
2553
2554        Ok(Value::Struct {
2555            name,
2556            fields: Rc::new(RefCell::new(field_values)),
2557        })
2558    }
2559
2560    fn eval_evidential(&mut self, expr: &Expr, ev: &Evidentiality) -> Result<Value, RuntimeError> {
2561        let value = self.evaluate(expr)?;
2562        let evidence = match ev {
2563            Evidentiality::Known => Evidence::Known,
2564            Evidentiality::Uncertain => Evidence::Uncertain,
2565            Evidentiality::Reported => Evidence::Reported,
2566            Evidentiality::Paradox => Evidence::Paradox,
2567        };
2568        Ok(Value::Evidential {
2569            value: Box::new(value),
2570            evidence,
2571        })
2572    }
2573
2574    fn eval_range(
2575        &mut self,
2576        start: &Option<Box<Expr>>,
2577        end: &Option<Box<Expr>>,
2578        inclusive: bool,
2579    ) -> Result<Value, RuntimeError> {
2580        let start_val = match start {
2581            Some(e) => match self.evaluate(e)? {
2582                Value::Int(n) => n,
2583                _ => return Err(RuntimeError::new("Range requires integer bounds")),
2584            },
2585            None => 0,
2586        };
2587
2588        let end_val = match end {
2589            Some(e) => match self.evaluate(e)? {
2590                Value::Int(n) => n,
2591                _ => return Err(RuntimeError::new("Range requires integer bounds")),
2592            },
2593            None => return Err(RuntimeError::new("Range requires end bound")),
2594        };
2595
2596        let values: Vec<Value> = if inclusive {
2597            (start_val..=end_val).map(Value::Int).collect()
2598        } else {
2599            (start_val..end_val).map(Value::Int).collect()
2600        };
2601
2602        Ok(Value::Array(Rc::new(RefCell::new(values))))
2603    }
2604
2605    fn is_truthy(&self, value: &Value) -> bool {
2606        match value {
2607            Value::Null => false,
2608            Value::Bool(b) => *b,
2609            Value::Int(n) => *n != 0,
2610            Value::Float(n) => *n != 0.0,
2611            Value::String(s) => !s.is_empty(),
2612            Value::Array(arr) => !arr.borrow().is_empty(),
2613            Value::Empty => false,
2614            Value::Evidential { value, .. } => self.is_truthy(value),
2615            _ => true,
2616        }
2617    }
2618}
2619
2620impl Default for Interpreter {
2621    fn default() -> Self {
2622        Self::new()
2623    }
2624}
2625
2626#[cfg(test)]
2627mod tests {
2628    use super::*;
2629    use crate::Parser;
2630
2631    fn run(source: &str) -> Result<Value, RuntimeError> {
2632        let mut parser = Parser::new(source);
2633        let file = parser.parse_file().map_err(|e| RuntimeError::new(e.to_string()))?;
2634        let mut interp = Interpreter::new();
2635        interp.execute(&file)
2636    }
2637
2638    #[test]
2639    fn test_arithmetic() {
2640        assert!(matches!(run("fn main() { return 2 + 3; }"), Ok(Value::Int(5))));
2641        assert!(matches!(run("fn main() { return 10 - 4; }"), Ok(Value::Int(6))));
2642        assert!(matches!(run("fn main() { return 3 * 4; }"), Ok(Value::Int(12))));
2643        assert!(matches!(run("fn main() { return 15 / 3; }"), Ok(Value::Int(5))));
2644        assert!(matches!(run("fn main() { return 2 ** 10; }"), Ok(Value::Int(1024))));
2645    }
2646
2647    #[test]
2648    fn test_variables() {
2649        assert!(matches!(run("fn main() { let x = 42; return x; }"), Ok(Value::Int(42))));
2650    }
2651
2652    #[test]
2653    fn test_conditionals() {
2654        assert!(matches!(
2655            run("fn main() { if true { return 1; } else { return 2; } }"),
2656            Ok(Value::Int(1))
2657        ));
2658        assert!(matches!(
2659            run("fn main() { if false { return 1; } else { return 2; } }"),
2660            Ok(Value::Int(2))
2661        ));
2662    }
2663
2664    #[test]
2665    fn test_arrays() {
2666        assert!(matches!(run("fn main() { return [1, 2, 3][1]; }"), Ok(Value::Int(2))));
2667    }
2668
2669    #[test]
2670    fn test_functions() {
2671        let result = run("
2672            fn double(x: i64) -> i64 { return x * 2; }
2673            fn main() { return double(21); }
2674        ");
2675        assert!(matches!(result, Ok(Value::Int(42))));
2676    }
2677
2678    #[test]
2679    fn test_pipe_transform() {
2680        let result = run("fn main() { return [1, 2, 3]|τ{_ * 2}|sum; }");
2681        assert!(matches!(result, Ok(Value::Int(12))));
2682    }
2683
2684    #[test]
2685    fn test_pipe_filter() {
2686        let result = run("fn main() { return [1, 2, 3, 4, 5]|φ{_ > 2}|sum; }");
2687        assert!(matches!(result, Ok(Value::Int(12)))); // 3 + 4 + 5
2688    }
2689}