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::cell::RefCell;
8use std::collections::HashMap;
9use std::fmt;
10use std::rc::Rc;
11use std::sync::{mpsc, Arc, Mutex};
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 {
236                        write!(f, ", ")?;
237                    }
238                    write!(f, "{:?}", v)?;
239                }
240                write!(f, "]")
241            }
242            Value::Tuple(vals) => {
243                write!(f, "(")?;
244                for (i, v) in vals.iter().enumerate() {
245                    if i > 0 {
246                        write!(f, ", ")?;
247                    }
248                    write!(f, "{:?}", v)?;
249                }
250                write!(f, ")")
251            }
252            Value::Struct { name, fields } => {
253                write!(f, "{} {{ ", name)?;
254                let fields = fields.borrow();
255                for (i, (k, v)) in fields.iter().enumerate() {
256                    if i > 0 {
257                        write!(f, ", ")?;
258                    }
259                    write!(f, "{}: {:?}", k, v)?;
260                }
261                write!(f, " }}")
262            }
263            Value::Variant {
264                enum_name,
265                variant_name,
266                fields,
267            } => {
268                write!(f, "{}::{}", enum_name, variant_name)?;
269                if let Some(fields) = fields {
270                    write!(f, "(")?;
271                    for (i, v) in fields.iter().enumerate() {
272                        if i > 0 {
273                            write!(f, ", ")?;
274                        }
275                        write!(f, "{:?}", v)?;
276                    }
277                    write!(f, ")")?;
278                }
279                Ok(())
280            }
281            Value::Function(func) => {
282                write!(f, "<fn {}>", func.name.as_deref().unwrap_or("anonymous"))
283            }
284            Value::BuiltIn(b) => write!(f, "<builtin {}>", b.name),
285            Value::Ref(r) => write!(f, "&{:?}", r.borrow()),
286            Value::Infinity => write!(f, "∞"),
287            Value::Empty => write!(f, "∅"),
288            Value::Evidential { value, evidence } => {
289                write!(f, "{:?}", value)?;
290                match evidence {
291                    Evidence::Known => write!(f, "!"),
292                    Evidence::Uncertain => write!(f, "?"),
293                    Evidence::Reported => write!(f, "~"),
294                    Evidence::Paradox => write!(f, "‽"),
295                }
296            }
297            Value::Map(map) => {
298                let map = map.borrow();
299                write!(f, "{{")?;
300                for (i, (k, v)) in map.iter().enumerate() {
301                    if i > 0 {
302                        write!(f, ", ")?;
303                    }
304                    write!(f, "{:?}: {:?}", k, v)?;
305                }
306                write!(f, "}}")
307            }
308            Value::Set(set) => {
309                let set = set.borrow();
310                write!(f, "Set{{")?;
311                for (i, k) in set.iter().enumerate() {
312                    if i > 0 {
313                        write!(f, ", ")?;
314                    }
315                    write!(f, "{:?}", k)?;
316                }
317                write!(f, "}}")
318            }
319            Value::Channel(_) => write!(f, "<channel>"),
320            Value::ThreadHandle(_) => write!(f, "<thread>"),
321            Value::Actor(actor) => write!(f, "<actor {}>", actor.name),
322            Value::Future(fut) => {
323                let fut = fut.borrow();
324                match &fut.state {
325                    FutureState::Pending => write!(f, "<future pending>"),
326                    FutureState::Running => write!(f, "<future running>"),
327                    FutureState::Ready(v) => write!(f, "<future ready: {:?}>", v),
328                    FutureState::Failed(e) => write!(f, "<future failed: {}>", e),
329                }
330            }
331            Value::Affective { value, affect } => {
332                write!(f, "{:?}", value)?;
333                if let Some(s) = &affect.sentiment {
334                    match s {
335                        RuntimeSentiment::Positive => write!(f, "⊕")?,
336                        RuntimeSentiment::Negative => write!(f, "⊖")?,
337                        RuntimeSentiment::Neutral => write!(f, "⊜")?,
338                    }
339                }
340                if affect.sarcasm {
341                    write!(f, "⸮")?;
342                }
343                if let Some(i) = &affect.intensity {
344                    match i {
345                        RuntimeIntensity::Up => write!(f, "↑")?,
346                        RuntimeIntensity::Down => write!(f, "↓")?,
347                        RuntimeIntensity::Max => write!(f, "⇈")?,
348                    }
349                }
350                if let Some(fo) = &affect.formality {
351                    match fo {
352                        RuntimeFormality::Formal => write!(f, "♔")?,
353                        RuntimeFormality::Informal => write!(f, "♟")?,
354                    }
355                }
356                if let Some(e) = &affect.emotion {
357                    match e {
358                        RuntimeEmotion::Joy => write!(f, "☺")?,
359                        RuntimeEmotion::Sadness => write!(f, "☹")?,
360                        RuntimeEmotion::Anger => write!(f, "⚡")?,
361                        RuntimeEmotion::Fear => write!(f, "❄")?,
362                        RuntimeEmotion::Surprise => write!(f, "✦")?,
363                        RuntimeEmotion::Love => write!(f, "♡")?,
364                    }
365                }
366                if let Some(c) = &affect.confidence {
367                    match c {
368                        RuntimeConfidence::High => write!(f, "◉")?,
369                        RuntimeConfidence::Medium => write!(f, "◎")?,
370                        RuntimeConfidence::Low => write!(f, "○")?,
371                    }
372                }
373                Ok(())
374            }
375        }
376    }
377}
378
379impl fmt::Display for Value {
380    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
381        match self {
382            Value::Null => write!(f, "null"),
383            Value::Bool(b) => write!(f, "{}", b),
384            Value::Int(n) => write!(f, "{}", n),
385            Value::Float(n) => write!(f, "{}", n),
386            Value::String(s) => write!(f, "{}", s),
387            Value::Char(c) => write!(f, "{}", c),
388            Value::Array(arr) => {
389                let arr = arr.borrow();
390                write!(f, "[")?;
391                for (i, v) in arr.iter().enumerate() {
392                    if i > 0 {
393                        write!(f, ", ")?;
394                    }
395                    write!(f, "{}", v)?;
396                }
397                write!(f, "]")
398            }
399            Value::Evidential { value, .. } => write!(f, "{}", value),
400            Value::Affective { value, affect } => {
401                // Display affect markers as suffix symbols
402                let mut suffix = String::new();
403                if let Some(sent) = &affect.sentiment {
404                    suffix.push(match sent {
405                        RuntimeSentiment::Positive => '⊕',
406                        RuntimeSentiment::Negative => '⊖',
407                        RuntimeSentiment::Neutral => '⊜',
408                    });
409                }
410                if affect.sarcasm {
411                    suffix.push('⸮');
412                }
413                if let Some(int) = &affect.intensity {
414                    suffix.push(match int {
415                        RuntimeIntensity::Up => '↑',
416                        RuntimeIntensity::Down => '↓',
417                        RuntimeIntensity::Max => '⇈',
418                    });
419                }
420                if let Some(form) = &affect.formality {
421                    suffix.push(match form {
422                        RuntimeFormality::Formal => '♔',
423                        RuntimeFormality::Informal => '♟',
424                    });
425                }
426                if let Some(emo) = &affect.emotion {
427                    suffix.push(match emo {
428                        RuntimeEmotion::Joy => '☺',
429                        RuntimeEmotion::Sadness => '☹',
430                        RuntimeEmotion::Anger => '⚡',
431                        RuntimeEmotion::Fear => '❄',
432                        RuntimeEmotion::Surprise => '✦',
433                        RuntimeEmotion::Love => '♡',
434                    });
435                }
436                if let Some(conf) = &affect.confidence {
437                    suffix.push(match conf {
438                        RuntimeConfidence::High => '◉',
439                        RuntimeConfidence::Medium => '◎',
440                        RuntimeConfidence::Low => '○',
441                    });
442                }
443                write!(f, "{}{}", value, suffix)
444            }
445            _ => write!(f, "{:?}", self),
446        }
447    }
448}
449
450/// Runtime error
451#[derive(Debug)]
452pub struct RuntimeError {
453    pub message: String,
454    pub span: Option<Span>,
455}
456
457impl RuntimeError {
458    pub fn new(message: impl Into<String>) -> Self {
459        Self {
460            message: message.into(),
461            span: None,
462        }
463    }
464
465    pub fn with_span(message: impl Into<String>, span: Span) -> Self {
466        Self {
467            message: message.into(),
468            span: Some(span),
469        }
470    }
471}
472
473impl fmt::Display for RuntimeError {
474    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
475        write!(f, "Runtime error: {}", self.message)?;
476        if let Some(span) = self.span {
477            write!(f, " at {}", span)?;
478        }
479        Ok(())
480    }
481}
482
483/// Control flow signals for return/break/continue
484#[derive(Debug, Clone)]
485pub enum ControlFlow {
486    Return(Value),
487    Break(Option<Value>),
488    Continue,
489}
490
491impl From<ControlFlow> for RuntimeError {
492    fn from(cf: ControlFlow) -> Self {
493        match cf {
494            ControlFlow::Return(_) => RuntimeError::new("return outside function"),
495            ControlFlow::Break(_) => RuntimeError::new("break outside loop"),
496            ControlFlow::Continue => RuntimeError::new("continue outside loop"),
497        }
498    }
499}
500
501/// Result type that can contain control flow
502pub type EvalResult = Result<Value, EvalError>;
503
504/// Error type that includes control flow
505#[derive(Debug)]
506pub enum EvalError {
507    Runtime(RuntimeError),
508    Control(ControlFlow),
509}
510
511impl From<RuntimeError> for EvalError {
512    fn from(e: RuntimeError) -> Self {
513        EvalError::Runtime(e)
514    }
515}
516
517impl From<ControlFlow> for EvalError {
518    fn from(cf: ControlFlow) -> Self {
519        EvalError::Control(cf)
520    }
521}
522
523impl fmt::Display for EvalError {
524    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
525        match self {
526            EvalError::Runtime(e) => write!(f, "{}", e),
527            EvalError::Control(cf) => write!(f, "Unexpected control flow: {:?}", cf),
528        }
529    }
530}
531
532/// Environment for variable bindings
533#[derive(Clone)]
534pub struct Environment {
535    values: HashMap<String, Value>,
536    parent: Option<Rc<RefCell<Environment>>>,
537}
538
539impl Environment {
540    pub fn new() -> Self {
541        Self {
542            values: HashMap::new(),
543            parent: None,
544        }
545    }
546
547    pub fn with_parent(parent: Rc<RefCell<Environment>>) -> Self {
548        Self {
549            values: HashMap::new(),
550            parent: Some(parent),
551        }
552    }
553
554    pub fn define(&mut self, name: String, value: Value) {
555        self.values.insert(name, value);
556    }
557
558    pub fn get(&self, name: &str) -> Option<Value> {
559        if let Some(value) = self.values.get(name) {
560            Some(value.clone())
561        } else if let Some(ref parent) = self.parent {
562            parent.borrow().get(name)
563        } else {
564            None
565        }
566    }
567
568    pub fn set(&mut self, name: &str, value: Value) -> Result<(), RuntimeError> {
569        if self.values.contains_key(name) {
570            self.values.insert(name.to_string(), value);
571            Ok(())
572        } else if let Some(ref parent) = self.parent {
573            parent.borrow_mut().set(name, value)
574        } else {
575            Err(RuntimeError::new(format!("Undefined variable: {}", name)))
576        }
577    }
578}
579
580impl Default for Environment {
581    fn default() -> Self {
582        Self::new()
583    }
584}
585
586/// The Sigil interpreter
587pub struct Interpreter {
588    /// Global environment
589    pub globals: Rc<RefCell<Environment>>,
590    /// Current environment
591    pub environment: Rc<RefCell<Environment>>,
592    /// Type definitions
593    pub types: HashMap<String, TypeDef>,
594    /// Output buffer (for testing)
595    pub output: Vec<String>,
596    /// Return value from the last return statement (control flow)
597    return_value: Option<Value>,
598}
599
600/// Type definition for structs/enums
601pub enum TypeDef {
602    Struct(StructDef),
603    Enum(EnumDef),
604}
605
606impl Interpreter {
607    pub fn new() -> Self {
608        let globals = Rc::new(RefCell::new(Environment::new()));
609        let environment = globals.clone();
610
611        let mut interp = Self {
612            globals: globals.clone(),
613            environment,
614            types: HashMap::new(),
615            return_value: None,
616            output: Vec::new(),
617        };
618
619        // Register built-in functions
620        interp.register_builtins();
621
622        interp
623    }
624
625    fn register_builtins(&mut self) {
626        // Print function
627        self.define_builtin("print", None, |interp, args| {
628            let output: Vec<String> = args.iter().map(|v| format!("{}", v)).collect();
629            let line = output.join(" ");
630            println!("{}", line);
631            interp.output.push(line);
632            Ok(Value::Null)
633        });
634
635        // Type checking
636        self.define_builtin("type_of", Some(1), |_, args| {
637            let type_name = match &args[0] {
638                Value::Null => "null",
639                Value::Bool(_) => "bool",
640                Value::Int(_) => "i64",
641                Value::Float(_) => "f64",
642                Value::String(_) => "str",
643                Value::Char(_) => "char",
644                Value::Array(_) => "array",
645                Value::Tuple(_) => "tuple",
646                Value::Struct { name, .. } => name,
647                Value::Variant { enum_name, .. } => enum_name,
648                Value::Function(_) => "fn",
649                Value::BuiltIn(_) => "builtin",
650                Value::Ref(_) => "ref",
651                Value::Infinity => "infinity",
652                Value::Empty => "empty",
653                Value::Evidential { .. } => "evidential",
654                Value::Affective { .. } => "affective",
655                Value::Map(_) => "map",
656                Value::Set(_) => "set",
657                Value::Channel(_) => "channel",
658                Value::ThreadHandle(_) => "thread",
659                Value::Actor(_) => "actor",
660                Value::Future(_) => "future",
661            };
662            Ok(Value::String(Rc::new(type_name.to_string())))
663        });
664
665        // Array operations
666        self.define_builtin("len", Some(1), |_, args| match &args[0] {
667            Value::Array(arr) => Ok(Value::Int(arr.borrow().len() as i64)),
668            Value::String(s) => Ok(Value::Int(s.len() as i64)),
669            Value::Tuple(t) => Ok(Value::Int(t.len() as i64)),
670            _ => Err(RuntimeError::new("len() requires array, string, or tuple")),
671        });
672
673        self.define_builtin("push", Some(2), |_, args| match &args[0] {
674            Value::Array(arr) => {
675                arr.borrow_mut().push(args[1].clone());
676                Ok(Value::Null)
677            }
678            _ => Err(RuntimeError::new("push() requires array")),
679        });
680
681        self.define_builtin("pop", Some(1), |_, args| match &args[0] {
682            Value::Array(arr) => arr
683                .borrow_mut()
684                .pop()
685                .ok_or_else(|| RuntimeError::new("pop() on empty array")),
686            _ => Err(RuntimeError::new("pop() requires array")),
687        });
688
689        // Math functions
690        self.define_builtin("abs", Some(1), |_, args| match &args[0] {
691            Value::Int(n) => Ok(Value::Int(n.abs())),
692            Value::Float(n) => Ok(Value::Float(n.abs())),
693            _ => Err(RuntimeError::new("abs() requires number")),
694        });
695
696        self.define_builtin("sqrt", Some(1), |_, args| match &args[0] {
697            Value::Int(n) => Ok(Value::Float((*n as f64).sqrt())),
698            Value::Float(n) => Ok(Value::Float(n.sqrt())),
699            _ => Err(RuntimeError::new("sqrt() requires number")),
700        });
701
702        self.define_builtin("sin", Some(1), |_, args| match &args[0] {
703            Value::Int(n) => Ok(Value::Float((*n as f64).sin())),
704            Value::Float(n) => Ok(Value::Float(n.sin())),
705            _ => Err(RuntimeError::new("sin() requires number")),
706        });
707
708        self.define_builtin("cos", Some(1), |_, args| match &args[0] {
709            Value::Int(n) => Ok(Value::Float((*n as f64).cos())),
710            Value::Float(n) => Ok(Value::Float(n.cos())),
711            _ => Err(RuntimeError::new("cos() requires number")),
712        });
713
714        // Evidence operations
715        self.define_builtin("known", Some(1), |_, args| {
716            Ok(Value::Evidential {
717                value: Box::new(args[0].clone()),
718                evidence: Evidence::Known,
719            })
720        });
721
722        self.define_builtin("uncertain", Some(1), |_, args| {
723            Ok(Value::Evidential {
724                value: Box::new(args[0].clone()),
725                evidence: Evidence::Uncertain,
726            })
727        });
728
729        self.define_builtin("reported", Some(1), |_, args| {
730            Ok(Value::Evidential {
731                value: Box::new(args[0].clone()),
732                evidence: Evidence::Reported,
733            })
734        });
735
736        // Range function
737        self.define_builtin("range", Some(2), |_, args| {
738            let start = match &args[0] {
739                Value::Int(n) => *n,
740                _ => return Err(RuntimeError::new("range() requires integers")),
741            };
742            let end = match &args[1] {
743                Value::Int(n) => *n,
744                _ => return Err(RuntimeError::new("range() requires integers")),
745            };
746            let values: Vec<Value> = (start..end).map(Value::Int).collect();
747            Ok(Value::Array(Rc::new(RefCell::new(values))))
748        });
749    }
750
751    fn define_builtin(
752        &mut self,
753        name: &str,
754        arity: Option<usize>,
755        func: fn(&mut Interpreter, Vec<Value>) -> Result<Value, RuntimeError>,
756    ) {
757        let builtin = Value::BuiltIn(Rc::new(BuiltInFn {
758            name: name.to_string(),
759            arity,
760            func,
761        }));
762        self.globals.borrow_mut().define(name.to_string(), builtin);
763    }
764
765    /// Execute a source file
766    pub fn execute(&mut self, file: &SourceFile) -> Result<Value, RuntimeError> {
767        let mut result = Value::Null;
768
769        for item in &file.items {
770            result = self.execute_item(&item.node)?;
771        }
772
773        // Look for main function and execute it
774        let main_fn = self.globals.borrow().get("main").and_then(|v| {
775            if let Value::Function(f) = v {
776                Some(f.clone())
777            } else {
778                None
779            }
780        });
781        if let Some(f) = main_fn {
782            result = self.call_function(&f, vec![])?;
783        }
784
785        Ok(result)
786    }
787
788    fn execute_item(&mut self, item: &Item) -> Result<Value, RuntimeError> {
789        match item {
790            Item::Function(func) => {
791                let fn_value = self.create_function(func)?;
792                self.globals
793                    .borrow_mut()
794                    .define(func.name.name.clone(), fn_value);
795                Ok(Value::Null)
796            }
797            Item::Struct(s) => {
798                self.types
799                    .insert(s.name.name.clone(), TypeDef::Struct(s.clone()));
800                Ok(Value::Null)
801            }
802            Item::Enum(e) => {
803                self.types
804                    .insert(e.name.name.clone(), TypeDef::Enum(e.clone()));
805                Ok(Value::Null)
806            }
807            Item::Const(c) => {
808                let value = self.evaluate(&c.value)?;
809                self.globals.borrow_mut().define(c.name.name.clone(), value);
810                Ok(Value::Null)
811            }
812            Item::Static(s) => {
813                let value = self.evaluate(&s.value)?;
814                self.globals.borrow_mut().define(s.name.name.clone(), value);
815                Ok(Value::Null)
816            }
817            _ => Ok(Value::Null), // Skip other items for now
818        }
819    }
820
821    fn create_function(&self, func: &crate::ast::Function) -> Result<Value, RuntimeError> {
822        let params: Vec<String> = func
823            .params
824            .iter()
825            .map(|p| match &p.pattern {
826                Pattern::Ident { name, .. } => name.name.clone(),
827                _ => "_".to_string(),
828            })
829            .collect();
830
831        let body = func
832            .body
833            .as_ref()
834            .map(|b| Expr::Block(b.clone()))
835            .unwrap_or(Expr::Literal(Literal::Bool(false)));
836
837        Ok(Value::Function(Rc::new(Function {
838            name: Some(func.name.name.clone()),
839            params,
840            body,
841            closure: self.environment.clone(),
842        })))
843    }
844
845    /// Evaluate an expression
846    pub fn evaluate(&mut self, expr: &Expr) -> Result<Value, RuntimeError> {
847        match expr {
848            Expr::Literal(lit) => self.eval_literal(lit),
849            Expr::Path(path) => self.eval_path(path),
850            Expr::Binary { left, op, right } => self.eval_binary(left, op, right),
851            Expr::Unary { op, expr } => self.eval_unary(op, expr),
852            Expr::Call { func, args } => self.eval_call(func, args),
853            Expr::Array(elements) => self.eval_array(elements),
854            Expr::Tuple(elements) => self.eval_tuple(elements),
855            Expr::Block(block) => self.eval_block(block),
856            Expr::If {
857                condition,
858                then_branch,
859                else_branch,
860            } => self.eval_if(condition, then_branch, else_branch),
861            Expr::Match { expr, arms } => self.eval_match(expr, arms),
862            Expr::For {
863                pattern,
864                iter,
865                body,
866            } => self.eval_for(pattern, iter, body),
867            Expr::While { condition, body } => self.eval_while(condition, body),
868            Expr::Loop(body) => self.eval_loop(body),
869            Expr::Return(value) => self.eval_return(value),
870            Expr::Break(value) => self.eval_break(value),
871            Expr::Continue => Err(RuntimeError::new("continue outside loop")),
872            Expr::Index { expr, index } => self.eval_index(expr, index),
873            Expr::Field { expr, field } => self.eval_field(expr, field),
874            Expr::MethodCall {
875                receiver,
876                method,
877                args,
878            } => self.eval_method_call(receiver, method, args),
879            // Polysynthetic incorporation: path·file·read·string
880            // Each segment is a method/function that transforms the value
881            Expr::Incorporation { segments } => self.eval_incorporation(segments),
882            Expr::Pipe { expr, operations } => self.eval_pipe(expr, operations),
883            Expr::Closure { params, body } => self.eval_closure(params, body),
884            Expr::Struct { path, fields, rest } => self.eval_struct_literal(path, fields, rest),
885            Expr::Evidential {
886                expr,
887                evidentiality,
888            } => self.eval_evidential(expr, evidentiality),
889            Expr::Range {
890                start,
891                end,
892                inclusive,
893            } => self.eval_range(start, end, *inclusive),
894            Expr::Assign { target, value } => self.eval_assign(target, value),
895            Expr::Await {
896                expr: inner,
897                evidentiality,
898            } => {
899                let value = self.evaluate(inner)?;
900                let awaited = self.await_value(value)?;
901                // Handle evidentiality marker semantics
902                match evidentiality {
903                    Some(Evidentiality::Uncertain) => {
904                        // ⌛? - propagate error like Try
905                        self.unwrap_result_or_option(awaited, true, false)
906                    }
907                    Some(Evidentiality::Known) => {
908                        // ⌛! - expect success, panic on error
909                        self.unwrap_result_or_option(awaited, true, true)
910                    }
911                    Some(Evidentiality::Reported) | Some(Evidentiality::Paradox) => {
912                        // ⌛~ or ⌛‽ - mark as external/reported, unwrap if Result/Option
913                        self.unwrap_result_or_option(awaited, false, false)
914                    }
915                    None => Ok(awaited),
916                }
917            }
918            _ => Err(RuntimeError::new(format!(
919                "Unsupported expression: {:?}",
920                expr
921            ))),
922        }
923    }
924
925    fn eval_assign(&mut self, target: &Expr, value: &Expr) -> Result<Value, RuntimeError> {
926        let val = self.evaluate(value)?;
927
928        match target {
929            Expr::Path(path) if path.segments.len() == 1 => {
930                let name = &path.segments[0].ident.name;
931                self.environment.borrow_mut().set(name, val.clone())?;
932                Ok(val)
933            }
934            Expr::Index { expr, index } => {
935                // Array/map index assignment
936                let idx = self.evaluate(index)?;
937                let idx = match idx {
938                    Value::Int(i) => i as usize,
939                    _ => return Err(RuntimeError::new("Index must be an integer")),
940                };
941
942                // Get the array and modify it
943                if let Expr::Path(path) = expr.as_ref() {
944                    if path.segments.len() == 1 {
945                        let name = &path.segments[0].ident.name;
946                        let current = self.environment.borrow().get(name).ok_or_else(|| {
947                            RuntimeError::new(format!("Undefined variable: {}", name))
948                        })?;
949
950                        if let Value::Array(arr) = current {
951                            let borrowed = arr.borrow();
952                            let mut new_arr = borrowed.clone();
953                            drop(borrowed);
954                            if idx < new_arr.len() {
955                                new_arr[idx] = val.clone();
956                                self.environment
957                                    .borrow_mut()
958                                    .set(name, Value::Array(Rc::new(RefCell::new(new_arr))))?;
959                                return Ok(val);
960                            }
961                        }
962                    }
963                }
964                Err(RuntimeError::new("Invalid index assignment target"))
965            }
966            _ => Err(RuntimeError::new("Invalid assignment target")),
967        }
968    }
969
970    fn eval_literal(&mut self, lit: &Literal) -> Result<Value, RuntimeError> {
971        match lit {
972            Literal::Int { value, base, .. } => {
973                let n = self.parse_int(value, base)?;
974                Ok(Value::Int(n))
975            }
976            Literal::Float { value, .. } => {
977                let n: f64 = value
978                    .parse()
979                    .map_err(|_| RuntimeError::new(format!("Invalid float: {}", value)))?;
980                Ok(Value::Float(n))
981            }
982            Literal::String(s) => Ok(Value::String(Rc::new(s.clone()))),
983            Literal::MultiLineString(s) => Ok(Value::String(Rc::new(s.clone()))),
984            Literal::RawString(s) => Ok(Value::String(Rc::new(s.clone()))),
985            Literal::ByteString(bytes) => {
986                // Convert byte array to an array of integers
987                let arr: Vec<Value> = bytes.iter().map(|&b| Value::Int(b as i64)).collect();
988                Ok(Value::Array(Rc::new(RefCell::new(arr))))
989            }
990            Literal::InterpolatedString { parts } => {
991                // Evaluate each part and concatenate, tracking evidentiality
992                let mut result = String::new();
993                let mut combined_evidence: Option<Evidence> = None;
994
995                for part in parts {
996                    match part {
997                        InterpolationPart::Text(s) => result.push_str(s),
998                        InterpolationPart::Expr(expr) => {
999                            let value = self.evaluate(expr)?;
1000
1001                            // Track explicit evidentiality
1002                            combined_evidence = Self::combine_evidence(
1003                                combined_evidence,
1004                                Self::extract_evidence(&value),
1005                            );
1006
1007                            // Track affect-derived evidentiality (sarcasm, confidence)
1008                            if let Some(affect) = Self::extract_affect(&value) {
1009                                combined_evidence = Self::combine_evidence(
1010                                    combined_evidence,
1011                                    Self::affect_to_evidence(affect),
1012                                );
1013                            }
1014
1015                            // Use the fully unwrapped value for display
1016                            let display_value = Self::unwrap_value(&value);
1017                            result.push_str(&format!("{}", display_value));
1018                        }
1019                    }
1020                }
1021
1022                // Wrap result with evidentiality if any interpolated values were evidential
1023                let string_value = Value::String(Rc::new(result));
1024                match combined_evidence {
1025                    Some(evidence) => Ok(Value::Evidential {
1026                        value: Box::new(string_value),
1027                        evidence,
1028                    }),
1029                    None => Ok(string_value),
1030                }
1031            }
1032            Literal::SigilStringSql(s) => {
1033                // SQL sigil string - for now just return as string
1034                // Future: could add SQL validation or templating
1035                Ok(Value::String(Rc::new(s.clone())))
1036            }
1037            Literal::SigilStringRoute(s) => {
1038                // Route sigil string - for now just return as string
1039                // Future: could add route validation or templating
1040                Ok(Value::String(Rc::new(s.clone())))
1041            }
1042            Literal::Char(c) => Ok(Value::Char(*c)),
1043            Literal::Bool(b) => Ok(Value::Bool(*b)),
1044            Literal::Null => Ok(Value::Null),
1045            Literal::Empty => Ok(Value::Empty),
1046            Literal::Infinity => Ok(Value::Infinity),
1047            Literal::Circle => Ok(Value::Int(0)), // ◯ = zero
1048        }
1049    }
1050
1051    fn parse_int(&self, value: &str, base: &NumBase) -> Result<i64, RuntimeError> {
1052        let (radix, prefix_len) = match base {
1053            NumBase::Binary => (2, 2), // 0b
1054            NumBase::Octal => (8, 2),  // 0o
1055            NumBase::Decimal => (10, 0),
1056            NumBase::Hex => (16, 2),         // 0x
1057            NumBase::Vigesimal => (20, 2),   // 0v
1058            NumBase::Sexagesimal => (60, 2), // 0s
1059            NumBase::Duodecimal => (12, 2),  // 0z
1060            NumBase::Explicit(b) => (*b as u32, 0),
1061        };
1062
1063        let clean = value[prefix_len..].replace('_', "");
1064        i64::from_str_radix(&clean, radix)
1065            .map_err(|_| RuntimeError::new(format!("Invalid integer: {}", value)))
1066    }
1067
1068    fn eval_path(&self, path: &TypePath) -> Result<Value, RuntimeError> {
1069        if path.segments.len() == 1 {
1070            let name = &path.segments[0].ident.name;
1071            self.environment
1072                .borrow()
1073                .get(name)
1074                .ok_or_else(|| RuntimeError::new(format!("Undefined variable: {}", name)))
1075        } else {
1076            // Multi-segment path (module::item or Type·method)
1077            // Try full qualified name first (joined with ·)
1078            let full_name = path
1079                .segments
1080                .iter()
1081                .map(|s| s.ident.name.as_str())
1082                .collect::<Vec<_>>()
1083                .join("·");
1084
1085            if let Some(val) = self.environment.borrow().get(&full_name) {
1086                return Ok(val);
1087            }
1088
1089            // Try looking up the last segment (for Math·sqrt -> sqrt)
1090            let last_name = &path.segments.last().unwrap().ident.name;
1091            if let Some(val) = self.environment.borrow().get(last_name) {
1092                return Ok(val);
1093            }
1094
1095            // Check for enum variant syntax (EnumName::Variant)
1096            if path.segments.len() == 2 {
1097                let type_name = &path.segments[0].ident.name;
1098                let variant_name = &path.segments[1].ident.name;
1099
1100                // Check if this is an enum variant
1101                if let Some(TypeDef::Enum(enum_def)) = self.types.get(type_name) {
1102                    for variant in &enum_def.variants {
1103                        if &variant.name.name == variant_name {
1104                            // Return a variant constructor or unit variant
1105                            if matches!(variant.fields, crate::ast::StructFields::Unit) {
1106                                return Ok(Value::Variant {
1107                                    enum_name: type_name.clone(),
1108                                    variant_name: variant_name.clone(),
1109                                    fields: None,
1110                                });
1111                            }
1112                        }
1113                    }
1114                }
1115            }
1116
1117            Err(RuntimeError::new(format!(
1118                "Undefined: {} (tried {} and {})",
1119                full_name, full_name, last_name
1120            )))
1121        }
1122    }
1123
1124    fn eval_binary(
1125        &mut self,
1126        left: &Expr,
1127        op: &BinOp,
1128        right: &Expr,
1129    ) -> Result<Value, RuntimeError> {
1130        let lhs = self.evaluate(left)?;
1131
1132        // Short-circuit for && and ||
1133        match op {
1134            BinOp::And => {
1135                if !self.is_truthy(&lhs) {
1136                    return Ok(Value::Bool(false));
1137                }
1138                let rhs = self.evaluate(right)?;
1139                return Ok(Value::Bool(self.is_truthy(&rhs)));
1140            }
1141            BinOp::Or => {
1142                if self.is_truthy(&lhs) {
1143                    return Ok(Value::Bool(true));
1144                }
1145                let rhs = self.evaluate(right)?;
1146                return Ok(Value::Bool(self.is_truthy(&rhs)));
1147            }
1148            _ => {}
1149        }
1150
1151        let rhs = self.evaluate(right)?;
1152
1153        match (lhs, rhs) {
1154            (Value::Int(a), Value::Int(b)) => self.int_binary_op(a, b, op),
1155            (Value::Float(a), Value::Float(b)) => self.float_binary_op(a, b, op),
1156            (Value::Int(a), Value::Float(b)) => self.float_binary_op(a as f64, b, op),
1157            (Value::Float(a), Value::Int(b)) => self.float_binary_op(a, b as f64, op),
1158            (Value::String(a), Value::String(b)) => match op {
1159                BinOp::Add | BinOp::Concat => Ok(Value::String(Rc::new(format!("{}{}", a, b)))),
1160                BinOp::Eq => Ok(Value::Bool(*a == *b)),
1161                BinOp::Ne => Ok(Value::Bool(*a != *b)),
1162                _ => Err(RuntimeError::new("Invalid string operation")),
1163            },
1164            (Value::Bool(a), Value::Bool(b)) => match op {
1165                BinOp::Eq => Ok(Value::Bool(a == b)),
1166                BinOp::Ne => Ok(Value::Bool(a != b)),
1167                _ => Err(RuntimeError::new("Invalid boolean operation")),
1168            },
1169            (Value::Array(a), Value::Array(b)) => match op {
1170                BinOp::Concat => {
1171                    let mut result = a.borrow().clone();
1172                    result.extend(b.borrow().iter().cloned());
1173                    Ok(Value::Array(Rc::new(RefCell::new(result))))
1174                }
1175                _ => Err(RuntimeError::new("Invalid array operation")),
1176            },
1177            _ => Err(RuntimeError::new("Type mismatch in binary operation")),
1178        }
1179    }
1180
1181    fn int_binary_op(&self, a: i64, b: i64, op: &BinOp) -> Result<Value, RuntimeError> {
1182        Ok(match op {
1183            BinOp::Add => Value::Int(a + b),
1184            BinOp::Sub => Value::Int(a - b),
1185            BinOp::Mul => Value::Int(a * b),
1186            BinOp::Div => {
1187                if b == 0 {
1188                    return Err(RuntimeError::new("Division by zero"));
1189                }
1190                Value::Int(a / b)
1191            }
1192            BinOp::Rem => {
1193                if b == 0 {
1194                    return Err(RuntimeError::new("Division by zero"));
1195                }
1196                Value::Int(a % b)
1197            }
1198            BinOp::Pow => Value::Int(a.pow(b as u32)),
1199            BinOp::Eq => Value::Bool(a == b),
1200            BinOp::Ne => Value::Bool(a != b),
1201            BinOp::Lt => Value::Bool(a < b),
1202            BinOp::Le => Value::Bool(a <= b),
1203            BinOp::Gt => Value::Bool(a > b),
1204            BinOp::Ge => Value::Bool(a >= b),
1205            BinOp::BitAnd => Value::Int(a & b),
1206            BinOp::BitOr => Value::Int(a | b),
1207            BinOp::BitXor => Value::Int(a ^ b),
1208            BinOp::Shl => Value::Int(a << b),
1209            BinOp::Shr => Value::Int(a >> b),
1210            _ => return Err(RuntimeError::new("Invalid integer operation")),
1211        })
1212    }
1213
1214    fn float_binary_op(&self, a: f64, b: f64, op: &BinOp) -> Result<Value, RuntimeError> {
1215        Ok(match op {
1216            BinOp::Add => Value::Float(a + b),
1217            BinOp::Sub => Value::Float(a - b),
1218            BinOp::Mul => Value::Float(a * b),
1219            BinOp::Div => Value::Float(a / b),
1220            BinOp::Rem => Value::Float(a % b),
1221            BinOp::Pow => Value::Float(a.powf(b)),
1222            BinOp::Eq => Value::Bool((a - b).abs() < f64::EPSILON),
1223            BinOp::Ne => Value::Bool((a - b).abs() >= f64::EPSILON),
1224            BinOp::Lt => Value::Bool(a < b),
1225            BinOp::Le => Value::Bool(a <= b),
1226            BinOp::Gt => Value::Bool(a > b),
1227            BinOp::Ge => Value::Bool(a >= b),
1228            _ => return Err(RuntimeError::new("Invalid float operation")),
1229        })
1230    }
1231
1232    fn eval_unary(&mut self, op: &UnaryOp, expr: &Expr) -> Result<Value, RuntimeError> {
1233        let val = self.evaluate(expr)?;
1234        match (op, val) {
1235            (UnaryOp::Neg, Value::Int(n)) => Ok(Value::Int(-n)),
1236            (UnaryOp::Neg, Value::Float(n)) => Ok(Value::Float(-n)),
1237            (UnaryOp::Not, Value::Bool(b)) => Ok(Value::Bool(!b)),
1238            (UnaryOp::Not, Value::Int(n)) => Ok(Value::Int(!n)),
1239            (UnaryOp::Ref, val) => Ok(Value::Ref(Rc::new(RefCell::new(val)))),
1240            (UnaryOp::Deref, Value::Ref(r)) => Ok(r.borrow().clone()),
1241            _ => Err(RuntimeError::new("Invalid unary operation")),
1242        }
1243    }
1244
1245    fn eval_call(&mut self, func_expr: &Expr, args: &[Expr]) -> Result<Value, RuntimeError> {
1246        let func = self.evaluate(func_expr)?;
1247        let arg_values: Vec<Value> = args
1248            .iter()
1249            .map(|a| self.evaluate(a))
1250            .collect::<Result<_, _>>()?;
1251
1252        match func {
1253            Value::Function(f) => self.call_function(&f, arg_values),
1254            Value::BuiltIn(b) => self.call_builtin(&b, arg_values),
1255            _ => Err(RuntimeError::new("Cannot call non-function")),
1256        }
1257    }
1258
1259    pub fn call_function(
1260        &mut self,
1261        func: &Function,
1262        args: Vec<Value>,
1263    ) -> Result<Value, RuntimeError> {
1264        if args.len() != func.params.len() {
1265            return Err(RuntimeError::new(format!(
1266                "Expected {} arguments, got {}",
1267                func.params.len(),
1268                args.len()
1269            )));
1270        }
1271
1272        // Create new environment for function
1273        let env = Rc::new(RefCell::new(Environment::with_parent(func.closure.clone())));
1274
1275        // Bind parameters
1276        for (param, value) in func.params.iter().zip(args) {
1277            env.borrow_mut().define(param.clone(), value);
1278        }
1279
1280        // Execute function body
1281        let prev_env = self.environment.clone();
1282        self.environment = env;
1283
1284        let result = match self.evaluate(&func.body) {
1285            Ok(val) => Ok(val),
1286            Err(e) if e.message == "return" => {
1287                // Extract return value from stored location
1288                Ok(self.return_value.take().unwrap_or(Value::Null))
1289            }
1290            Err(e) => Err(e),
1291        };
1292
1293        self.environment = prev_env;
1294        result
1295    }
1296
1297    fn call_builtin(
1298        &mut self,
1299        builtin: &BuiltInFn,
1300        args: Vec<Value>,
1301    ) -> Result<Value, RuntimeError> {
1302        if let Some(arity) = builtin.arity {
1303            if args.len() != arity {
1304                return Err(RuntimeError::new(format!(
1305                    "{}() expects {} arguments, got {}",
1306                    builtin.name,
1307                    arity,
1308                    args.len()
1309                )));
1310            }
1311        }
1312        (builtin.func)(self, args)
1313    }
1314
1315    /// Await a value - if it's a future, resolve it; otherwise return as-is
1316    pub fn await_value(&mut self, value: Value) -> Result<Value, RuntimeError> {
1317        match value {
1318            Value::Future(fut) => {
1319                let mut fut_inner = fut.borrow_mut();
1320                self.poll_future(&mut fut_inner)
1321            }
1322            // Non-futures return immediately
1323            other => Ok(other),
1324        }
1325    }
1326
1327    /// Unwrap a Result or Option value with configurable error handling
1328    /// - propagate_errors: if true, return error on Err/None; if false, just unwrap
1329    /// - panic_on_error: if true, panic instead of returning error
1330    fn unwrap_result_or_option(
1331        &self,
1332        value: Value,
1333        propagate_errors: bool,
1334        panic_on_error: bool,
1335    ) -> Result<Value, RuntimeError> {
1336        // First, determine what kind of value we have and extract any inner value
1337        let (is_ok_or_some, is_err, is_none, inner_val) = match &value {
1338            Value::Struct { name, fields } if name == "Ok" || name == "Some" => {
1339                let borrowed = fields.borrow();
1340                let inner = borrowed.get("0").or(borrowed.get("value")).cloned();
1341                (true, false, false, inner)
1342            }
1343            Value::Struct { name, fields } if name == "Err" => {
1344                let borrowed = fields.borrow();
1345                let inner = borrowed.get("0").or(borrowed.get("value")).cloned();
1346                (false, true, false, inner)
1347            }
1348            Value::Struct { name, .. } if name == "None" => (false, false, true, None),
1349            _ => return Ok(value),
1350        };
1351
1352        if is_ok_or_some {
1353            Ok(inner_val.unwrap_or(value))
1354        } else if is_err {
1355            let msg = format!("Error: {:?}", inner_val);
1356            if panic_on_error {
1357                panic!("{}", msg);
1358            } else if propagate_errors {
1359                Err(RuntimeError::new(msg))
1360            } else {
1361                Ok(inner_val.unwrap_or(value))
1362            }
1363        } else if is_none {
1364            if panic_on_error {
1365                panic!("Unwrapped None");
1366            } else if propagate_errors {
1367                Err(RuntimeError::new("Unwrapped None".to_string()))
1368            } else {
1369                Ok(value)
1370            }
1371        } else {
1372            Ok(value)
1373        }
1374    }
1375
1376    /// Poll a future to completion
1377    fn poll_future(&mut self, fut: &mut FutureInner) -> Result<Value, RuntimeError> {
1378        // Check if already resolved
1379        match &fut.state {
1380            FutureState::Ready(v) => return Ok((**v).clone()),
1381            FutureState::Failed(e) => return Err(RuntimeError::new(e.clone())),
1382            _ => {}
1383        }
1384
1385        // Check if it's a timer future
1386        if let Some(complete_at) = fut.complete_at {
1387            if std::time::Instant::now() >= complete_at {
1388                fut.state = FutureState::Ready(Box::new(Value::Null));
1389                return Ok(Value::Null);
1390            } else {
1391                // Timer not complete - in interpreter, we just sleep
1392                let remaining = complete_at - std::time::Instant::now();
1393                std::thread::sleep(remaining);
1394                fut.state = FutureState::Ready(Box::new(Value::Null));
1395                return Ok(Value::Null);
1396            }
1397        }
1398
1399        // Execute computation if pending
1400        if let Some(computation) = fut.computation.take() {
1401            fut.state = FutureState::Running;
1402
1403            match computation {
1404                FutureComputation::Immediate(v) => {
1405                    fut.state = FutureState::Ready(v.clone());
1406                    Ok((*v).clone())
1407                }
1408                FutureComputation::Timer(duration) => {
1409                    // Sleep for the duration
1410                    std::thread::sleep(duration);
1411                    fut.state = FutureState::Ready(Box::new(Value::Null));
1412                    Ok(Value::Null)
1413                }
1414                FutureComputation::Lazy { func, args } => {
1415                    // Execute the function
1416                    match self.call_function(&func, args) {
1417                        Ok(result) => {
1418                            fut.state = FutureState::Ready(Box::new(result.clone()));
1419                            Ok(result)
1420                        }
1421                        Err(e) => {
1422                            fut.state = FutureState::Failed(e.message.clone());
1423                            Err(e)
1424                        }
1425                    }
1426                }
1427                FutureComputation::Join(futures) => {
1428                    // Await all futures and collect results
1429                    let mut results = Vec::new();
1430                    for f in futures {
1431                        let mut f_inner = f.borrow_mut();
1432                        results.push(self.poll_future(&mut f_inner)?);
1433                    }
1434                    let result = Value::Array(Rc::new(RefCell::new(results)));
1435                    fut.state = FutureState::Ready(Box::new(result.clone()));
1436                    Ok(result)
1437                }
1438                FutureComputation::Race(futures) => {
1439                    // Return first completed future
1440                    // In interpreter, just poll in order
1441                    for f in futures {
1442                        let f_inner = f.borrow_mut();
1443                        if matches!(f_inner.state, FutureState::Ready(_)) {
1444                            if let FutureState::Ready(v) = &f_inner.state {
1445                                fut.state = FutureState::Ready(v.clone());
1446                                return Ok((**v).clone());
1447                            }
1448                        }
1449                    }
1450                    // None ready, poll first one
1451                    Err(RuntimeError::new("No futures ready in race"))
1452                }
1453            }
1454        } else {
1455            // No computation - return current state
1456            match &fut.state {
1457                FutureState::Ready(v) => Ok((**v).clone()),
1458                FutureState::Failed(e) => Err(RuntimeError::new(e.clone())),
1459                _ => Err(RuntimeError::new("Future has no computation")),
1460            }
1461        }
1462    }
1463
1464    /// Create a new future from a value
1465    pub fn make_future_immediate(&self, value: Value) -> Value {
1466        Value::Future(Rc::new(RefCell::new(FutureInner {
1467            state: FutureState::Ready(Box::new(value)),
1468            computation: None,
1469            complete_at: None,
1470        })))
1471    }
1472
1473    /// Create a pending future with lazy computation
1474    pub fn make_future_lazy(&self, func: Rc<Function>, args: Vec<Value>) -> Value {
1475        Value::Future(Rc::new(RefCell::new(FutureInner {
1476            state: FutureState::Pending,
1477            computation: Some(FutureComputation::Lazy { func, args }),
1478            complete_at: None,
1479        })))
1480    }
1481
1482    /// Create a timer future
1483    pub fn make_future_timer(&self, duration: std::time::Duration) -> Value {
1484        Value::Future(Rc::new(RefCell::new(FutureInner {
1485            state: FutureState::Pending,
1486            computation: Some(FutureComputation::Timer(duration)),
1487            complete_at: Some(std::time::Instant::now() + duration),
1488        })))
1489    }
1490
1491    fn eval_array(&mut self, elements: &[Expr]) -> Result<Value, RuntimeError> {
1492        let values: Vec<Value> = elements
1493            .iter()
1494            .map(|e| self.evaluate(e))
1495            .collect::<Result<_, _>>()?;
1496        Ok(Value::Array(Rc::new(RefCell::new(values))))
1497    }
1498
1499    fn eval_tuple(&mut self, elements: &[Expr]) -> Result<Value, RuntimeError> {
1500        let values: Vec<Value> = elements
1501            .iter()
1502            .map(|e| self.evaluate(e))
1503            .collect::<Result<_, _>>()?;
1504        Ok(Value::Tuple(Rc::new(values)))
1505    }
1506
1507    fn eval_block(&mut self, block: &Block) -> Result<Value, RuntimeError> {
1508        let env = Rc::new(RefCell::new(Environment::with_parent(
1509            self.environment.clone(),
1510        )));
1511        let prev_env = self.environment.clone();
1512        self.environment = env;
1513
1514        let mut result = Value::Null;
1515
1516        for stmt in &block.stmts {
1517            match stmt {
1518                Stmt::Let { pattern, init, .. } => {
1519                    let value = match init {
1520                        Some(expr) => self.evaluate(expr)?,
1521                        None => Value::Null,
1522                    };
1523                    self.bind_pattern(pattern, value)?;
1524                }
1525                Stmt::Expr(expr) => {
1526                    result = self.evaluate(expr)?;
1527                }
1528                Stmt::Semi(expr) => {
1529                    self.evaluate(expr)?;
1530                    result = Value::Null;
1531                }
1532                Stmt::Item(item) => {
1533                    self.execute_item(item)?;
1534                }
1535            }
1536        }
1537
1538        if let Some(expr) = &block.expr {
1539            result = self.evaluate(expr)?;
1540        }
1541
1542        self.environment = prev_env;
1543        Ok(result)
1544    }
1545
1546    fn bind_pattern(&mut self, pattern: &Pattern, value: Value) -> Result<(), RuntimeError> {
1547        match pattern {
1548            Pattern::Ident { name, .. } => {
1549                self.environment
1550                    .borrow_mut()
1551                    .define(name.name.clone(), value);
1552                Ok(())
1553            }
1554            Pattern::Tuple(patterns) => {
1555                if let Value::Tuple(values) = value {
1556                    if patterns.len() != values.len() {
1557                        return Err(RuntimeError::new("Tuple pattern size mismatch"));
1558                    }
1559                    for (p, v) in patterns.iter().zip(values.iter()) {
1560                        self.bind_pattern(p, v.clone())?;
1561                    }
1562                    Ok(())
1563                } else {
1564                    Err(RuntimeError::new("Expected tuple"))
1565                }
1566            }
1567            Pattern::Wildcard => Ok(()),
1568            _ => Err(RuntimeError::new("Unsupported pattern")),
1569        }
1570    }
1571
1572    fn eval_if(
1573        &mut self,
1574        condition: &Expr,
1575        then_branch: &Block,
1576        else_branch: &Option<Box<Expr>>,
1577    ) -> Result<Value, RuntimeError> {
1578        let cond = self.evaluate(condition)?;
1579        if self.is_truthy(&cond) {
1580            self.eval_block(then_branch)
1581        } else if let Some(else_expr) = else_branch {
1582            self.evaluate(else_expr)
1583        } else {
1584            Ok(Value::Null)
1585        }
1586    }
1587
1588    fn eval_match(&mut self, expr: &Expr, arms: &[MatchArm]) -> Result<Value, RuntimeError> {
1589        let value = self.evaluate(expr)?;
1590
1591        for arm in arms {
1592            if self.pattern_matches(&arm.pattern, &value)? {
1593                // Check guard if present
1594                if let Some(guard) = &arm.guard {
1595                    let guard_val = self.evaluate(guard)?;
1596                    if !self.is_truthy(&guard_val) {
1597                        continue;
1598                    }
1599                }
1600
1601                // Bind pattern variables and evaluate body
1602                let env = Rc::new(RefCell::new(Environment::with_parent(
1603                    self.environment.clone(),
1604                )));
1605                let prev_env = self.environment.clone();
1606                self.environment = env;
1607
1608                self.bind_pattern(&arm.pattern, value)?;
1609                let result = self.evaluate(&arm.body);
1610
1611                self.environment = prev_env;
1612                return result;
1613            }
1614        }
1615
1616        Err(RuntimeError::new("No matching pattern"))
1617    }
1618
1619    fn pattern_matches(&mut self, pattern: &Pattern, value: &Value) -> Result<bool, RuntimeError> {
1620        match (pattern, value) {
1621            (Pattern::Wildcard, _) => Ok(true),
1622            (Pattern::Ident { .. }, _) => Ok(true),
1623            (Pattern::Literal(lit), val) => {
1624                let lit_val = self.eval_literal(lit)?;
1625                Ok(self.values_equal(&lit_val, val))
1626            }
1627            (Pattern::Tuple(patterns), Value::Tuple(values)) => {
1628                if patterns.len() != values.len() {
1629                    return Ok(false);
1630                }
1631                for (p, v) in patterns.iter().zip(values.iter()) {
1632                    if !self.pattern_matches(p, v)? {
1633                        return Ok(false);
1634                    }
1635                }
1636                Ok(true)
1637            }
1638            _ => Ok(false),
1639        }
1640    }
1641
1642    fn values_equal(&self, a: &Value, b: &Value) -> bool {
1643        match (a, b) {
1644            (Value::Null, Value::Null) => true,
1645            (Value::Bool(a), Value::Bool(b)) => a == b,
1646            (Value::Int(a), Value::Int(b)) => a == b,
1647            (Value::Float(a), Value::Float(b)) => (a - b).abs() < f64::EPSILON,
1648            (Value::String(a), Value::String(b)) => a == b,
1649            (Value::Char(a), Value::Char(b)) => a == b,
1650            _ => false,
1651        }
1652    }
1653
1654    fn eval_for(
1655        &mut self,
1656        pattern: &Pattern,
1657        iter: &Expr,
1658        body: &Block,
1659    ) -> Result<Value, RuntimeError> {
1660        let iterable = self.evaluate(iter)?;
1661        let items = match iterable {
1662            Value::Array(arr) => arr.borrow().clone(),
1663            Value::Tuple(t) => (*t).clone(),
1664            _ => return Err(RuntimeError::new("Cannot iterate over non-iterable")),
1665        };
1666
1667        let mut result = Value::Null;
1668        for item in items {
1669            let env = Rc::new(RefCell::new(Environment::with_parent(
1670                self.environment.clone(),
1671            )));
1672            let prev_env = self.environment.clone();
1673            self.environment = env;
1674
1675            self.bind_pattern(pattern, item)?;
1676
1677            match self.eval_block(body) {
1678                Ok(val) => result = val,
1679                Err(e) if e.message == "break" => {
1680                    self.environment = prev_env;
1681                    break;
1682                }
1683                Err(e) if e.message == "continue" => {
1684                    self.environment = prev_env;
1685                    continue;
1686                }
1687                Err(e) => {
1688                    self.environment = prev_env;
1689                    return Err(e);
1690                }
1691            }
1692
1693            self.environment = prev_env;
1694        }
1695
1696        Ok(result)
1697    }
1698
1699    fn eval_while(&mut self, condition: &Expr, body: &Block) -> Result<Value, RuntimeError> {
1700        let mut result = Value::Null;
1701        loop {
1702            let cond = self.evaluate(condition)?;
1703            if !self.is_truthy(&cond) {
1704                break;
1705            }
1706
1707            match self.eval_block(body) {
1708                Ok(val) => result = val,
1709                Err(e) if e.message == "break" => break,
1710                Err(e) if e.message == "continue" => continue,
1711                Err(e) => return Err(e),
1712            }
1713        }
1714        Ok(result)
1715    }
1716
1717    fn eval_loop(&mut self, body: &Block) -> Result<Value, RuntimeError> {
1718        loop {
1719            match self.eval_block(body) {
1720                Ok(_) => {}
1721                Err(e) if e.message == "break" => break,
1722                Err(e) if e.message == "continue" => continue,
1723                Err(e) => return Err(e),
1724            }
1725        }
1726        Ok(Value::Null)
1727    }
1728
1729    fn eval_return(&mut self, value: &Option<Box<Expr>>) -> Result<Value, RuntimeError> {
1730        let val = match value {
1731            Some(expr) => self.evaluate(expr)?,
1732            None => Value::Null,
1733        };
1734        // Store return value for call_function to retrieve
1735        self.return_value = Some(val);
1736        Err(RuntimeError::new("return"))
1737    }
1738
1739    fn eval_break(&mut self, _value: &Option<Box<Expr>>) -> Result<Value, RuntimeError> {
1740        // TODO: break with value for loop expressions
1741        Err(RuntimeError::new("break"))
1742    }
1743
1744    fn eval_index(&mut self, expr: &Expr, index: &Expr) -> Result<Value, RuntimeError> {
1745        let collection = self.evaluate(expr)?;
1746        let idx = self.evaluate(index)?;
1747
1748        match (collection, idx) {
1749            (Value::Array(arr), Value::Int(i)) => {
1750                let arr = arr.borrow();
1751                let i = if i < 0 { arr.len() as i64 + i } else { i } as usize;
1752                arr.get(i)
1753                    .cloned()
1754                    .ok_or_else(|| RuntimeError::new("Index out of bounds"))
1755            }
1756            (Value::Tuple(t), Value::Int(i)) => {
1757                let i = if i < 0 { t.len() as i64 + i } else { i } as usize;
1758                t.get(i)
1759                    .cloned()
1760                    .ok_or_else(|| RuntimeError::new("Index out of bounds"))
1761            }
1762            (Value::String(s), Value::Int(i)) => {
1763                let i = if i < 0 { s.len() as i64 + i } else { i } as usize;
1764                s.chars()
1765                    .nth(i)
1766                    .map(Value::Char)
1767                    .ok_or_else(|| RuntimeError::new("Index out of bounds"))
1768            }
1769            _ => Err(RuntimeError::new("Cannot index")),
1770        }
1771    }
1772
1773    fn eval_field(&mut self, expr: &Expr, field: &Ident) -> Result<Value, RuntimeError> {
1774        let value = self.evaluate(expr)?;
1775        match value {
1776            Value::Struct { fields, .. } => fields
1777                .borrow()
1778                .get(&field.name)
1779                .cloned()
1780                .ok_or_else(|| RuntimeError::new(format!("Unknown field: {}", field.name))),
1781            Value::Tuple(t) => {
1782                // Tuple field access like .0, .1
1783                let idx: usize = field
1784                    .name
1785                    .parse()
1786                    .map_err(|_| RuntimeError::new("Invalid tuple index"))?;
1787                t.get(idx)
1788                    .cloned()
1789                    .ok_or_else(|| RuntimeError::new("Tuple index out of bounds"))
1790            }
1791            _ => Err(RuntimeError::new("Cannot access field on non-struct")),
1792        }
1793    }
1794
1795    fn eval_method_call(
1796        &mut self,
1797        receiver: &Expr,
1798        method: &Ident,
1799        args: &[Expr],
1800    ) -> Result<Value, RuntimeError> {
1801        let recv = self.evaluate(receiver)?;
1802        let arg_values: Vec<Value> = args
1803            .iter()
1804            .map(|a| self.evaluate(a))
1805            .collect::<Result<_, _>>()?;
1806
1807        // Built-in methods
1808        match (&recv, method.name.as_str()) {
1809            (Value::Array(arr), "len") => Ok(Value::Int(arr.borrow().len() as i64)),
1810            (Value::Array(arr), "push") => {
1811                if arg_values.len() != 1 {
1812                    return Err(RuntimeError::new("push expects 1 argument"));
1813                }
1814                arr.borrow_mut().push(arg_values[0].clone());
1815                Ok(Value::Null)
1816            }
1817            (Value::Array(arr), "pop") => arr
1818                .borrow_mut()
1819                .pop()
1820                .ok_or_else(|| RuntimeError::new("pop on empty array")),
1821            (Value::Array(arr), "reverse") => {
1822                let mut v = arr.borrow().clone();
1823                v.reverse();
1824                Ok(Value::Array(Rc::new(RefCell::new(v))))
1825            }
1826            (Value::String(s), "len") => Ok(Value::Int(s.len() as i64)),
1827            (Value::String(s), "chars") => {
1828                let chars: Vec<Value> = s.chars().map(Value::Char).collect();
1829                Ok(Value::Array(Rc::new(RefCell::new(chars))))
1830            }
1831            (Value::String(s), "contains") => {
1832                if arg_values.len() != 1 {
1833                    return Err(RuntimeError::new("contains expects 1 argument"));
1834                }
1835                match &arg_values[0] {
1836                    Value::String(sub) => Ok(Value::Bool(s.contains(sub.as_str()))),
1837                    _ => Err(RuntimeError::new("contains expects string")),
1838                }
1839            }
1840            _ => Err(RuntimeError::new(format!(
1841                "Unknown method: {}",
1842                method.name
1843            ))),
1844        }
1845    }
1846
1847    /// Evaluate polysynthetic incorporation: path·file·read·string
1848    /// The first segment provides the initial value, subsequent segments are method-like transformations
1849    fn eval_incorporation(
1850        &mut self,
1851        segments: &[IncorporationSegment],
1852    ) -> Result<Value, RuntimeError> {
1853        if segments.is_empty() {
1854            return Err(RuntimeError::new("empty incorporation chain"));
1855        }
1856
1857        // First segment: get initial value (variable lookup or function call)
1858        let first = &segments[0];
1859        let mut value = if let Some(args) = &first.args {
1860            // First segment is a function call: func(args)·next·...
1861            let arg_values: Vec<Value> = args
1862                .iter()
1863                .map(|a| self.evaluate(a))
1864                .collect::<Result<_, _>>()?;
1865            self.call_function_by_name(&first.name.name, arg_values)?
1866        } else {
1867            // First segment is a variable: var·next·...
1868            self.environment
1869                .borrow()
1870                .get(&first.name.name)
1871                .ok_or_else(|| RuntimeError::new(format!("undefined: {}", first.name.name)))?
1872        };
1873
1874        // Process remaining segments as method-like calls
1875        for segment in segments.iter().skip(1) {
1876            let arg_values: Vec<Value> = segment
1877                .args
1878                .as_ref()
1879                .map(|args| {
1880                    args.iter()
1881                        .map(|a| self.evaluate(a))
1882                        .collect::<Result<Vec<_>, _>>()
1883                })
1884                .transpose()?
1885                .unwrap_or_default();
1886
1887            // Try to call as a method on the value
1888            value = self.call_incorporation_method(&value, &segment.name.name, arg_values)?;
1889        }
1890
1891        Ok(value)
1892    }
1893
1894    /// Call a method in an incorporation chain
1895    /// This looks up the segment name as a method or stdlib function
1896    fn call_incorporation_method(
1897        &mut self,
1898        receiver: &Value,
1899        method_name: &str,
1900        args: Vec<Value>,
1901    ) -> Result<Value, RuntimeError> {
1902        // First try as a method on the receiver value
1903        match (receiver, method_name) {
1904            // String methods
1905            (Value::String(s), "len") => Ok(Value::Int(s.len() as i64)),
1906            (Value::String(s), "upper") | (Value::String(s), "uppercase") => {
1907                Ok(Value::String(Rc::new(s.to_uppercase())))
1908            }
1909            (Value::String(s), "lower") | (Value::String(s), "lowercase") => {
1910                Ok(Value::String(Rc::new(s.to_lowercase())))
1911            }
1912            (Value::String(s), "trim") => Ok(Value::String(Rc::new(s.trim().to_string()))),
1913            (Value::String(s), "chars") => {
1914                let chars: Vec<Value> = s
1915                    .chars()
1916                    .map(|c| Value::String(Rc::new(c.to_string())))
1917                    .collect();
1918                Ok(Value::Array(Rc::new(RefCell::new(chars))))
1919            }
1920            (Value::String(s), "lines") => {
1921                let lines: Vec<Value> = s
1922                    .lines()
1923                    .map(|l| Value::String(Rc::new(l.to_string())))
1924                    .collect();
1925                Ok(Value::Array(Rc::new(RefCell::new(lines))))
1926            }
1927            (Value::String(s), "bytes") => {
1928                let bytes: Vec<Value> = s.bytes().map(|b| Value::Int(b as i64)).collect();
1929                Ok(Value::Array(Rc::new(RefCell::new(bytes))))
1930            }
1931            (Value::String(s), "parse_int") | (Value::String(s), "to_int") => s
1932                .parse::<i64>()
1933                .map(Value::Int)
1934                .map_err(|_| RuntimeError::new(format!("cannot parse '{}' as int", s))),
1935            (Value::String(s), "parse_float") | (Value::String(s), "to_float") => s
1936                .parse::<f64>()
1937                .map(Value::Float)
1938                .map_err(|_| RuntimeError::new(format!("cannot parse '{}' as float", s))),
1939
1940            // Array methods
1941            (Value::Array(arr), "len") => Ok(Value::Int(arr.borrow().len() as i64)),
1942            (Value::Array(arr), "first") => arr
1943                .borrow()
1944                .first()
1945                .cloned()
1946                .ok_or_else(|| RuntimeError::new("empty array")),
1947            (Value::Array(arr), "last") => arr
1948                .borrow()
1949                .last()
1950                .cloned()
1951                .ok_or_else(|| RuntimeError::new("empty array")),
1952            (Value::Array(arr), "reverse") | (Value::Array(arr), "rev") => {
1953                let mut v = arr.borrow().clone();
1954                v.reverse();
1955                Ok(Value::Array(Rc::new(RefCell::new(v))))
1956            }
1957            (Value::Array(arr), "join") => {
1958                let sep = args
1959                    .first()
1960                    .map(|v| match v {
1961                        Value::String(s) => s.to_string(),
1962                        _ => "".to_string(),
1963                    })
1964                    .unwrap_or_default();
1965                let joined = arr
1966                    .borrow()
1967                    .iter()
1968                    .map(|v| format!("{}", v))
1969                    .collect::<Vec<_>>()
1970                    .join(&sep);
1971                Ok(Value::String(Rc::new(joined)))
1972            }
1973            (Value::Array(arr), "sum") => {
1974                let mut sum = 0i64;
1975                for v in arr.borrow().iter() {
1976                    match v {
1977                        Value::Int(i) => sum += i,
1978                        Value::Float(f) => return Ok(Value::Float(sum as f64 + f)),
1979                        _ => {}
1980                    }
1981                }
1982                Ok(Value::Int(sum))
1983            }
1984
1985            // Number methods
1986            (Value::Int(n), "abs") => Ok(Value::Int(n.abs())),
1987            (Value::Float(n), "abs") => Ok(Value::Float(n.abs())),
1988            (Value::Int(n), "to_string") | (Value::Int(n), "string") => {
1989                Ok(Value::String(Rc::new(n.to_string())))
1990            }
1991            (Value::Float(n), "to_string") | (Value::Float(n), "string") => {
1992                Ok(Value::String(Rc::new(n.to_string())))
1993            }
1994            (Value::Int(n), "to_float") | (Value::Int(n), "float") => Ok(Value::Float(*n as f64)),
1995            (Value::Float(n), "to_int") | (Value::Float(n), "int") => Ok(Value::Int(*n as i64)),
1996
1997            // Map/Struct field access
1998            (Value::Map(map), field) => map
1999                .borrow()
2000                .get(field)
2001                .cloned()
2002                .ok_or_else(|| RuntimeError::new(format!("no field '{}' in map", field))),
2003            (Value::Struct { fields, .. }, field) => fields
2004                .borrow()
2005                .get(field)
2006                .cloned()
2007                .ok_or_else(|| RuntimeError::new(format!("no field '{}' in struct", field))),
2008
2009            // Try stdlib function with receiver as first arg
2010            _ => {
2011                let mut all_args = vec![receiver.clone()];
2012                all_args.extend(args);
2013                self.call_function_by_name(method_name, all_args)
2014            }
2015        }
2016    }
2017
2018    /// Call a function by name from the environment
2019    fn call_function_by_name(
2020        &mut self,
2021        name: &str,
2022        args: Vec<Value>,
2023    ) -> Result<Value, RuntimeError> {
2024        // Get the function value from environment (clone to avoid borrow issues)
2025        let func_value = self.environment.borrow().get(name);
2026
2027        match func_value {
2028            Some(Value::Function(f)) => self.call_function(&f, args),
2029            Some(Value::BuiltIn(b)) => self.call_builtin(&b, args),
2030            Some(_) => Err(RuntimeError::new(format!("{} is not a function", name))),
2031            None => Err(RuntimeError::new(format!("undefined function: {}", name))),
2032        }
2033    }
2034
2035    fn eval_pipe(&mut self, expr: &Expr, operations: &[PipeOp]) -> Result<Value, RuntimeError> {
2036        let mut value = self.evaluate(expr)?;
2037
2038        for op in operations {
2039            value = self.apply_pipe_op(value, op)?;
2040        }
2041
2042        Ok(value)
2043    }
2044
2045    fn apply_pipe_op(&mut self, value: Value, op: &PipeOp) -> Result<Value, RuntimeError> {
2046        match op {
2047            PipeOp::Transform(body) => {
2048                // τ{f} - map over collection or apply to single value
2049                match value {
2050                    Value::Array(arr) => {
2051                        let results: Vec<Value> = arr
2052                            .borrow()
2053                            .iter()
2054                            .map(|item| {
2055                                self.environment
2056                                    .borrow_mut()
2057                                    .define("_".to_string(), item.clone());
2058                                self.evaluate(body)
2059                            })
2060                            .collect::<Result<_, _>>()?;
2061                        Ok(Value::Array(Rc::new(RefCell::new(results))))
2062                    }
2063                    single => {
2064                        self.environment
2065                            .borrow_mut()
2066                            .define("_".to_string(), single);
2067                        self.evaluate(body)
2068                    }
2069                }
2070            }
2071            PipeOp::Filter(predicate) => {
2072                // φ{p} - filter collection
2073                match value {
2074                    Value::Array(arr) => {
2075                        let results: Vec<Value> = arr
2076                            .borrow()
2077                            .iter()
2078                            .filter_map(|item| {
2079                                self.environment
2080                                    .borrow_mut()
2081                                    .define("_".to_string(), item.clone());
2082                                match self.evaluate(predicate) {
2083                                    Ok(v) if self.is_truthy(&v) => Some(Ok(item.clone())),
2084                                    Ok(_) => None,
2085                                    Err(e) => Some(Err(e)),
2086                                }
2087                            })
2088                            .collect::<Result<_, _>>()?;
2089                        Ok(Value::Array(Rc::new(RefCell::new(results))))
2090                    }
2091                    _ => Err(RuntimeError::new("Filter requires array")),
2092                }
2093            }
2094            PipeOp::Sort(field) => {
2095                // σ - sort collection
2096                match value {
2097                    Value::Array(arr) => {
2098                        let mut v = arr.borrow().clone();
2099                        v.sort_by(|a, b| self.compare_values(a, b, field));
2100                        Ok(Value::Array(Rc::new(RefCell::new(v))))
2101                    }
2102                    _ => Err(RuntimeError::new("Sort requires array")),
2103                }
2104            }
2105            PipeOp::Reduce(body) => {
2106                // ρ{f} - reduce collection
2107                match value {
2108                    Value::Array(arr) => {
2109                        let arr = arr.borrow();
2110                        if arr.is_empty() {
2111                            return Err(RuntimeError::new("Cannot reduce empty array"));
2112                        }
2113                        let mut acc = arr[0].clone();
2114                        for item in arr.iter().skip(1) {
2115                            self.environment.borrow_mut().define("acc".to_string(), acc);
2116                            self.environment
2117                                .borrow_mut()
2118                                .define("_".to_string(), item.clone());
2119                            acc = self.evaluate(body)?;
2120                        }
2121                        Ok(acc)
2122                    }
2123                    _ => Err(RuntimeError::new("Reduce requires array")),
2124                }
2125            }
2126            PipeOp::ReduceSum => {
2127                // ρ+ or ρ_sum - sum all elements
2128                self.sum_values(value)
2129            }
2130            PipeOp::ReduceProd => {
2131                // ρ* or ρ_prod - multiply all elements
2132                self.product_values(value)
2133            }
2134            PipeOp::ReduceMin => {
2135                // ρ_min - find minimum element
2136                self.min_values(value)
2137            }
2138            PipeOp::ReduceMax => {
2139                // ρ_max - find maximum element
2140                self.max_values(value)
2141            }
2142            PipeOp::ReduceConcat => {
2143                // ρ++ or ρ_cat - concatenate strings/arrays
2144                self.concat_values(value)
2145            }
2146            PipeOp::ReduceAll => {
2147                // ρ& or ρ_all - logical AND (all true)
2148                self.all_values(value)
2149            }
2150            PipeOp::ReduceAny => {
2151                // ρ| or ρ_any - logical OR (any true)
2152                self.any_values(value)
2153            }
2154            PipeOp::Match(arms) => {
2155                // |match{ Pattern => expr, ... } - pattern matching in pipe
2156                for arm in arms {
2157                    if self.pattern_matches(&arm.pattern, &value)? {
2158                        // Create new scope for pattern bindings
2159                        let prev_env = self.environment.clone();
2160                        self.environment =
2161                            Rc::new(RefCell::new(Environment::with_parent(prev_env.clone())));
2162
2163                        // Bind pattern variables
2164                        self.bind_pattern(&arm.pattern, value.clone())?;
2165
2166                        // Also bind _ to the piped value for convenient access
2167                        self.environment
2168                            .borrow_mut()
2169                            .define("_".to_string(), value.clone());
2170
2171                        // Check guard if present
2172                        let guard_passes = if let Some(guard) = &arm.guard {
2173                            matches!(self.evaluate(guard)?, Value::Bool(true))
2174                        } else {
2175                            true
2176                        };
2177
2178                        if guard_passes {
2179                            let result = self.evaluate(&arm.body)?;
2180                            self.environment = prev_env;
2181                            return Ok(result);
2182                        }
2183
2184                        // Guard failed, restore environment and try next arm
2185                        self.environment = prev_env;
2186                    }
2187                }
2188                Err(RuntimeError::new("No pattern matched in pipe match"))
2189            }
2190            PipeOp::TryMap(mapper) => {
2191                // |? or |?{mapper} - unwrap Result/Option or transform error
2192                match &value {
2193                    // Handle Result-like values (struct with ok/err fields)
2194                    Value::Struct { name, fields } if name == "Ok" || name.ends_with("::Ok") => {
2195                        // Extract the inner value from Ok
2196                        let fields = fields.borrow();
2197                        fields
2198                            .get("0")
2199                            .or_else(|| fields.get("value"))
2200                            .cloned()
2201                            .ok_or_else(|| RuntimeError::new("Ok variant has no value"))
2202                    }
2203                    Value::Struct { name, fields } if name == "Err" || name.ends_with("::Err") => {
2204                        // Transform error if mapper provided, otherwise propagate
2205                        let fields = fields.borrow();
2206                        let err_val = fields
2207                            .get("0")
2208                            .or_else(|| fields.get("error"))
2209                            .cloned()
2210                            .unwrap_or(Value::Null);
2211                        if let Some(mapper_expr) = mapper {
2212                            // Apply mapper to error
2213                            let prev_env = self.environment.clone();
2214                            self.environment =
2215                                Rc::new(RefCell::new(Environment::with_parent(prev_env.clone())));
2216                            self.environment
2217                                .borrow_mut()
2218                                .define("_".to_string(), err_val);
2219                            let mapped = self.evaluate(mapper_expr)?;
2220                            self.environment = prev_env;
2221                            Err(RuntimeError::new(format!("Error: {:?}", mapped)))
2222                        } else {
2223                            Err(RuntimeError::new(format!("Error: {:?}", err_val)))
2224                        }
2225                    }
2226                    // Handle Option-like values
2227                    Value::Struct { name, fields }
2228                        if name == "Some" || name.ends_with("::Some") =>
2229                    {
2230                        let fields = fields.borrow();
2231                        fields
2232                            .get("0")
2233                            .or_else(|| fields.get("value"))
2234                            .cloned()
2235                            .ok_or_else(|| RuntimeError::new("Some variant has no value"))
2236                    }
2237                    Value::Struct { name, .. } if name == "None" || name.ends_with("::None") => {
2238                        Err(RuntimeError::new("Unwrapped None value"))
2239                    }
2240                    Value::Null => Err(RuntimeError::new("Unwrapped null value")),
2241                    // Pass through non-Result/Option values unchanged
2242                    _ => Ok(value),
2243                }
2244            }
2245            PipeOp::Method { name, args } => {
2246                let arg_values: Vec<Value> = args
2247                    .iter()
2248                    .map(|a| self.evaluate(a))
2249                    .collect::<Result<_, _>>()?;
2250
2251                // Check for built-in pipe methods
2252                match name.name.as_str() {
2253                    "collect" => Ok(value), // Already collected
2254                    "sum" | "Σ" => self.sum_values(value),
2255                    "product" | "Π" => self.product_values(value),
2256                    "len" => match &value {
2257                        Value::Array(arr) => Ok(Value::Int(arr.borrow().len() as i64)),
2258                        Value::String(s) => Ok(Value::Int(s.len() as i64)),
2259                        _ => Err(RuntimeError::new("len requires array or string")),
2260                    },
2261                    "reverse" => match value {
2262                        Value::Array(arr) => {
2263                            let mut v = arr.borrow().clone();
2264                            v.reverse();
2265                            Ok(Value::Array(Rc::new(RefCell::new(v))))
2266                        }
2267                        _ => Err(RuntimeError::new("reverse requires array")),
2268                    },
2269                    "first" => match &value {
2270                        Value::Array(arr) => arr
2271                            .borrow()
2272                            .first()
2273                            .cloned()
2274                            .ok_or_else(|| RuntimeError::new("first on empty array")),
2275                        _ => Err(RuntimeError::new("first requires array")),
2276                    },
2277                    "last" => match &value {
2278                        Value::Array(arr) => arr
2279                            .borrow()
2280                            .last()
2281                            .cloned()
2282                            .ok_or_else(|| RuntimeError::new("last on empty array")),
2283                        _ => Err(RuntimeError::new("last requires array")),
2284                    },
2285                    "take" => {
2286                        if arg_values.len() != 1 {
2287                            return Err(RuntimeError::new("take requires 1 argument"));
2288                        }
2289                        let n = match &arg_values[0] {
2290                            Value::Int(n) => *n as usize,
2291                            _ => return Err(RuntimeError::new("take requires integer")),
2292                        };
2293                        match value {
2294                            Value::Array(arr) => {
2295                                let v: Vec<Value> = arr.borrow().iter().take(n).cloned().collect();
2296                                Ok(Value::Array(Rc::new(RefCell::new(v))))
2297                            }
2298                            _ => Err(RuntimeError::new("take requires array")),
2299                        }
2300                    }
2301                    "skip" => {
2302                        if arg_values.len() != 1 {
2303                            return Err(RuntimeError::new("skip requires 1 argument"));
2304                        }
2305                        let n = match &arg_values[0] {
2306                            Value::Int(n) => *n as usize,
2307                            _ => return Err(RuntimeError::new("skip requires integer")),
2308                        };
2309                        match value {
2310                            Value::Array(arr) => {
2311                                let v: Vec<Value> = arr.borrow().iter().skip(n).cloned().collect();
2312                                Ok(Value::Array(Rc::new(RefCell::new(v))))
2313                            }
2314                            _ => Err(RuntimeError::new("skip requires array")),
2315                        }
2316                    }
2317                    _ => Err(RuntimeError::new(format!(
2318                        "Unknown pipe method: {}",
2319                        name.name
2320                    ))),
2321                }
2322            }
2323            PipeOp::Await => {
2324                // Await a future - resolve it to a value
2325                self.await_value(value)
2326            }
2327            // New access morphemes
2328            PipeOp::First => {
2329                // α - first element
2330                match &value {
2331                    Value::Array(arr) => arr
2332                        .borrow()
2333                        .first()
2334                        .cloned()
2335                        .ok_or_else(|| RuntimeError::new("first (α) on empty array")),
2336                    Value::Tuple(t) => t
2337                        .first()
2338                        .cloned()
2339                        .ok_or_else(|| RuntimeError::new("first (α) on empty tuple")),
2340                    _ => Err(RuntimeError::new("first (α) requires array or tuple")),
2341                }
2342            }
2343            PipeOp::Last => {
2344                // ω - last element
2345                match &value {
2346                    Value::Array(arr) => arr
2347                        .borrow()
2348                        .last()
2349                        .cloned()
2350                        .ok_or_else(|| RuntimeError::new("last (ω) on empty array")),
2351                    Value::Tuple(t) => t
2352                        .last()
2353                        .cloned()
2354                        .ok_or_else(|| RuntimeError::new("last (ω) on empty tuple")),
2355                    _ => Err(RuntimeError::new("last (ω) requires array or tuple")),
2356                }
2357            }
2358            PipeOp::Middle => {
2359                // μ - middle/median element
2360                match &value {
2361                    Value::Array(arr) => {
2362                        let arr = arr.borrow();
2363                        if arr.is_empty() {
2364                            return Err(RuntimeError::new("middle (μ) on empty array"));
2365                        }
2366                        let mid = arr.len() / 2;
2367                        Ok(arr[mid].clone())
2368                    }
2369                    Value::Tuple(t) => {
2370                        if t.is_empty() {
2371                            return Err(RuntimeError::new("middle (μ) on empty tuple"));
2372                        }
2373                        let mid = t.len() / 2;
2374                        Ok(t[mid].clone())
2375                    }
2376                    _ => Err(RuntimeError::new("middle (μ) requires array or tuple")),
2377                }
2378            }
2379            PipeOp::Choice => {
2380                // χ - random element
2381                use std::time::{SystemTime, UNIX_EPOCH};
2382                match &value {
2383                    Value::Array(arr) => {
2384                        let arr = arr.borrow();
2385                        if arr.is_empty() {
2386                            return Err(RuntimeError::new("choice (χ) on empty array"));
2387                        }
2388                        let seed = SystemTime::now()
2389                            .duration_since(UNIX_EPOCH)
2390                            .unwrap_or(std::time::Duration::ZERO)
2391                            .as_nanos() as u64;
2392                        let idx = ((seed.wrapping_mul(1103515245).wrapping_add(12345)) >> 16)
2393                            as usize
2394                            % arr.len();
2395                        Ok(arr[idx].clone())
2396                    }
2397                    Value::Tuple(t) => {
2398                        if t.is_empty() {
2399                            return Err(RuntimeError::new("choice (χ) on empty tuple"));
2400                        }
2401                        let seed = SystemTime::now()
2402                            .duration_since(UNIX_EPOCH)
2403                            .unwrap_or(std::time::Duration::ZERO)
2404                            .as_nanos() as u64;
2405                        let idx = ((seed.wrapping_mul(1103515245).wrapping_add(12345)) >> 16)
2406                            as usize
2407                            % t.len();
2408                        Ok(t[idx].clone())
2409                    }
2410                    _ => Err(RuntimeError::new("choice (χ) requires array or tuple")),
2411                }
2412            }
2413            PipeOp::Nth(index_expr) => {
2414                // ν{n} - nth element
2415                let index = match self.evaluate(index_expr)? {
2416                    Value::Int(n) => n,
2417                    _ => return Err(RuntimeError::new("nth (ν) index must be integer")),
2418                };
2419                match &value {
2420                    Value::Array(arr) => {
2421                        let arr = arr.borrow();
2422                        if index < 0 || index as usize >= arr.len() {
2423                            return Err(RuntimeError::new("nth (ν) index out of bounds"));
2424                        }
2425                        Ok(arr[index as usize].clone())
2426                    }
2427                    Value::Tuple(t) => {
2428                        if index < 0 || index as usize >= t.len() {
2429                            return Err(RuntimeError::new("nth (ν) index out of bounds"));
2430                        }
2431                        Ok(t[index as usize].clone())
2432                    }
2433                    _ => Err(RuntimeError::new("nth (ν) requires array or tuple")),
2434                }
2435            }
2436            PipeOp::Next => {
2437                // ξ - next element (for iterators, currently just returns first)
2438                // In a full implementation, this would advance an iterator
2439                match &value {
2440                    Value::Array(arr) => arr
2441                        .borrow()
2442                        .first()
2443                        .cloned()
2444                        .ok_or_else(|| RuntimeError::new("next (ξ) on empty array")),
2445                    Value::Tuple(t) => t
2446                        .first()
2447                        .cloned()
2448                        .ok_or_else(|| RuntimeError::new("next (ξ) on empty tuple")),
2449                    _ => Err(RuntimeError::new("next (ξ) requires array or tuple")),
2450                }
2451            }
2452            PipeOp::Named { prefix, body } => {
2453                // Named morpheme like ·map{f}
2454                let method_name = prefix
2455                    .iter()
2456                    .map(|i| i.name.as_str())
2457                    .collect::<Vec<_>>()
2458                    .join("·");
2459                match method_name.as_str() {
2460                    "map" => {
2461                        if let Some(body) = body {
2462                            match value {
2463                                Value::Array(arr) => {
2464                                    let results: Vec<Value> = arr
2465                                        .borrow()
2466                                        .iter()
2467                                        .map(|item| {
2468                                            self.environment
2469                                                .borrow_mut()
2470                                                .define("_".to_string(), item.clone());
2471                                            self.evaluate(body)
2472                                        })
2473                                        .collect::<Result<_, _>>()?;
2474                                    Ok(Value::Array(Rc::new(RefCell::new(results))))
2475                                }
2476                                _ => Err(RuntimeError::new("map requires array")),
2477                            }
2478                        } else {
2479                            Ok(value)
2480                        }
2481                    }
2482                    "filter" => {
2483                        if let Some(body) = body {
2484                            match value {
2485                                Value::Array(arr) => {
2486                                    let results: Vec<Value> = arr
2487                                        .borrow()
2488                                        .iter()
2489                                        .filter_map(|item| {
2490                                            self.environment
2491                                                .borrow_mut()
2492                                                .define("_".to_string(), item.clone());
2493                                            match self.evaluate(body) {
2494                                                Ok(v) if self.is_truthy(&v) => {
2495                                                    Some(Ok(item.clone()))
2496                                                }
2497                                                Ok(_) => None,
2498                                                Err(e) => Some(Err(e)),
2499                                            }
2500                                        })
2501                                        .collect::<Result<_, _>>()?;
2502                                    Ok(Value::Array(Rc::new(RefCell::new(results))))
2503                                }
2504                                _ => Err(RuntimeError::new("filter requires array")),
2505                            }
2506                        } else {
2507                            Ok(value)
2508                        }
2509                    }
2510                    _ => Err(RuntimeError::new(format!(
2511                        "Unknown named morpheme: {}",
2512                        method_name
2513                    ))),
2514                }
2515            }
2516            PipeOp::Parallel(inner_op) => {
2517                // ∥ - parallel execution of the inner operation
2518                // For arrays, execute the operation in parallel using threads
2519                match value {
2520                    Value::Array(arr) => {
2521                        use std::sync::{Arc, Mutex};
2522
2523                        let arr_ref = arr.borrow();
2524                        let len = arr_ref.len();
2525                        if len == 0 {
2526                            return Ok(Value::Array(Rc::new(RefCell::new(vec![]))));
2527                        }
2528
2529                        // For Transform operations, parallelize across elements
2530                        match inner_op.as_ref() {
2531                            PipeOp::Transform(body) => {
2532                                // Determine number of threads (use available parallelism)
2533                                let num_threads = std::thread::available_parallelism()
2534                                    .map(|p| p.get())
2535                                    .unwrap_or(4)
2536                                    .min(len);
2537
2538                                // For future parallel implementation
2539                                let _chunk_size = (len + num_threads - 1) / num_threads;
2540                                let _results = Arc::new(Mutex::new(vec![Value::Null; len]));
2541                                let items: Vec<Value> = arr_ref.clone();
2542                                drop(arr_ref);
2543
2544                                // Clone the body expression for each thread (for future use)
2545                                let _body_str = format!("{:?}", body);
2546
2547                                // For now, fall back to sequential since full parallelization
2548                                // requires thread-safe evaluation context
2549                                // In production, this would use Rayon or a work-stealing scheduler
2550                                let mut result_vec = Vec::with_capacity(len);
2551                                for item in items.iter() {
2552                                    self.environment
2553                                        .borrow_mut()
2554                                        .define("_".to_string(), item.clone());
2555                                    result_vec.push(self.evaluate(body)?);
2556                                }
2557                                Ok(Value::Array(Rc::new(RefCell::new(result_vec))))
2558                            }
2559                            PipeOp::Filter(predicate) => {
2560                                // Parallel filter - evaluate predicate in parallel
2561                                let items: Vec<Value> = arr_ref.clone();
2562                                drop(arr_ref);
2563
2564                                let mut result_vec = Vec::new();
2565                                for item in items.iter() {
2566                                    self.environment
2567                                        .borrow_mut()
2568                                        .define("_".to_string(), item.clone());
2569                                    let pred_result = self.evaluate(predicate)?;
2570                                    if self.is_truthy(&pred_result) {
2571                                        result_vec.push(item.clone());
2572                                    }
2573                                }
2574                                Ok(Value::Array(Rc::new(RefCell::new(result_vec))))
2575                            }
2576                            _ => {
2577                                // For other operations, just apply them normally
2578                                drop(arr_ref);
2579                                self.apply_pipe_op(Value::Array(arr), inner_op)
2580                            }
2581                        }
2582                    }
2583                    _ => {
2584                        // For non-arrays, just apply the inner operation
2585                        self.apply_pipe_op(value, inner_op)
2586                    }
2587                }
2588            }
2589            PipeOp::Gpu(inner_op) => {
2590                // ⊛ - GPU compute shader execution
2591                // This is a placeholder that falls back to CPU execution
2592                // In production, this would:
2593                // 1. Generate SPIR-V/WGSL compute shader
2594                // 2. Submit to GPU via wgpu/vulkan
2595                // 3. Read back results
2596                match value {
2597                    Value::Array(arr) => {
2598                        // For now, emit a hint that GPU execution would occur
2599                        // and fall back to CPU
2600                        #[cfg(debug_assertions)]
2601                        eprintln!(
2602                            "[GPU] Would execute {:?} on GPU, falling back to CPU",
2603                            inner_op
2604                        );
2605
2606                        self.apply_pipe_op(Value::Array(arr), inner_op)
2607                    }
2608                    _ => self.apply_pipe_op(value, inner_op),
2609                }
2610            }
2611
2612            // ==========================================
2613            // Protocol Operations - Sigil-native networking
2614            // All protocol results are wrapped with Reported evidentiality
2615            // since network data comes from external sources ("hearsay")
2616            // ==========================================
2617            PipeOp::Send(data_expr) => {
2618                // |send{data} or |⇒{data} - Send data over a connection
2619                // The value should be a connection object
2620                let data = self.evaluate(data_expr)?;
2621
2622                // Create a protocol response with Reported evidentiality
2623                // In production, this would actually send data over the network
2624                let response = self.protocol_send(&value, &data)?;
2625
2626                // Wrap in Reported evidentiality - network responses are hearsay
2627                Ok(self.wrap_reported(response))
2628            }
2629
2630            PipeOp::Recv => {
2631                // |recv or |⇐ - Receive data from a connection
2632                // The value should be a connection object
2633
2634                // In production, this would actually receive data from the network
2635                let response = self.protocol_recv(&value)?;
2636
2637                // Wrap in Reported evidentiality - network data is hearsay
2638                Ok(self.wrap_reported(response))
2639            }
2640
2641            PipeOp::Stream(handler_expr) => {
2642                // |stream{handler} or |≋{handler} - Stream data with a handler
2643                let handler = self.evaluate(handler_expr)?;
2644
2645                // Create a streaming iterator over network data
2646                // Each element will be wrapped in Reported evidentiality
2647                let stream = self.protocol_stream(&value, &handler)?;
2648                Ok(stream)
2649            }
2650
2651            PipeOp::Connect(config_expr) => {
2652                // |connect or |connect{config} or |⊸{config} - Establish connection
2653                let config = match config_expr {
2654                    Some(expr) => Some(self.evaluate(expr)?),
2655                    None => None,
2656                };
2657
2658                // Create a connection object
2659                let connection = self.protocol_connect(&value, config.as_ref())?;
2660                Ok(connection)
2661            }
2662
2663            PipeOp::Close => {
2664                // |close or |⊗ - Close connection gracefully
2665                self.protocol_close(&value)?;
2666                Ok(Value::Null)
2667            }
2668
2669            PipeOp::Header {
2670                name,
2671                value: value_expr,
2672            } => {
2673                // |header{name, value} - Add/set header on request
2674                let header_name = self.evaluate(name)?;
2675                let header_value = self.evaluate(value_expr)?;
2676
2677                // Add header to the request builder
2678                self.protocol_add_header(value, &header_name, &header_value)
2679            }
2680
2681            PipeOp::Body(data_expr) => {
2682                // |body{data} - Set request body
2683                let body_data = self.evaluate(data_expr)?;
2684
2685                // Set body on the request builder
2686                self.protocol_set_body(value, &body_data)
2687            }
2688
2689            PipeOp::Timeout(ms_expr) => {
2690                // |timeout{ms} or |⏱{ms} - Set operation timeout
2691                let ms = self.evaluate(ms_expr)?;
2692
2693                // Set timeout on the request/connection
2694                self.protocol_set_timeout(value, &ms)
2695            }
2696
2697            PipeOp::Retry { count, strategy } => {
2698                // |retry{count} or |retry{count, strategy} - Set retry policy
2699                let retry_count = self.evaluate(count)?;
2700                let retry_strategy = match strategy {
2701                    Some(s) => Some(self.evaluate(s)?),
2702                    None => None,
2703                };
2704
2705                // Set retry policy on the request
2706                self.protocol_set_retry(value, &retry_count, retry_strategy.as_ref())
2707            }
2708
2709            // ==========================================
2710            // Evidence Promotion Operations
2711            // ==========================================
2712            PipeOp::Validate {
2713                predicate,
2714                target_evidence,
2715            } => {
2716                // |validate!{predicate} - validate and promote evidence
2717                // Execute the predicate with the current value
2718                let predicate_result = match predicate.as_ref() {
2719                    Expr::Closure { params, body, .. } => {
2720                        if let Some(param) = params.first() {
2721                            let param_name = match &param.pattern {
2722                                Pattern::Ident { name, .. } => name.name.clone(),
2723                                _ => "it".to_string(),
2724                            };
2725                            self.environment
2726                                .borrow_mut()
2727                                .define(param_name, value.clone());
2728                        }
2729                        self.evaluate(body)?
2730                    }
2731                    _ => self.evaluate(predicate)?,
2732                };
2733
2734                // Check if validation passed
2735                match predicate_result {
2736                    Value::Bool(true) => {
2737                        // Validation passed: promote evidence
2738                        let target_ev = match target_evidence {
2739                            Evidentiality::Known => Evidence::Known,
2740                            Evidentiality::Uncertain => Evidence::Uncertain,
2741                            Evidentiality::Reported => Evidence::Reported,
2742                            Evidentiality::Paradox => Evidence::Paradox,
2743                        };
2744                        let inner = match value {
2745                            Value::Evidential { value: v, .. } => *v,
2746                            v => v,
2747                        };
2748                        Ok(Value::Evidential {
2749                            value: Box::new(inner),
2750                            evidence: target_ev,
2751                        })
2752                    }
2753                    Value::Bool(false) => Err(RuntimeError::new(
2754                        "validation failed: predicate returned false",
2755                    )),
2756                    _ => Err(RuntimeError::new("validation predicate must return bool")),
2757                }
2758            }
2759
2760            PipeOp::Assume {
2761                reason,
2762                target_evidence,
2763            } => {
2764                // |assume!("reason") - explicitly assume evidence (with audit trail)
2765                let reason_str: Rc<String> = if let Some(r) = reason {
2766                    match self.evaluate(r)? {
2767                        Value::String(s) => s,
2768                        _ => Rc::new("<no reason>".to_string()),
2769                    }
2770                } else {
2771                    Rc::new("<no reason>".to_string())
2772                };
2773
2774                // Log the assumption for audit purposes
2775                #[cfg(debug_assertions)]
2776                eprintln!(
2777                    "[AUDIT] Evidence assumption: {} - reason: {}",
2778                    match target_evidence {
2779                        Evidentiality::Known => "!",
2780                        Evidentiality::Uncertain => "?",
2781                        Evidentiality::Reported => "~",
2782                        Evidentiality::Paradox => "‽",
2783                    },
2784                    reason_str
2785                );
2786
2787                let target_ev = match target_evidence {
2788                    Evidentiality::Known => Evidence::Known,
2789                    Evidentiality::Uncertain => Evidence::Uncertain,
2790                    Evidentiality::Reported => Evidence::Reported,
2791                    Evidentiality::Paradox => Evidence::Paradox,
2792                };
2793
2794                let inner = match value {
2795                    Value::Evidential { value: v, .. } => *v,
2796                    v => v,
2797                };
2798
2799                Ok(Value::Evidential {
2800                    value: Box::new(inner),
2801                    evidence: target_ev,
2802                })
2803            }
2804
2805            PipeOp::AssertEvidence(expected) => {
2806                // |assert_evidence!{!} - assert evidence level
2807                let actual_evidence = match &value {
2808                    Value::Evidential { evidence, .. } => evidence.clone(),
2809                    _ => Evidence::Known,
2810                };
2811
2812                let expected_ev = match expected {
2813                    Evidentiality::Known => Evidence::Known,
2814                    Evidentiality::Uncertain => Evidence::Uncertain,
2815                    Evidentiality::Reported => Evidence::Reported,
2816                    Evidentiality::Paradox => Evidence::Paradox,
2817                };
2818
2819                // Check if actual satisfies expected
2820                let satisfies = match (&actual_evidence, &expected_ev) {
2821                    (Evidence::Known, _) => true,
2822                    (
2823                        Evidence::Uncertain,
2824                        Evidence::Uncertain | Evidence::Reported | Evidence::Paradox,
2825                    ) => true,
2826                    (Evidence::Reported, Evidence::Reported | Evidence::Paradox) => true,
2827                    (Evidence::Paradox, Evidence::Paradox) => true,
2828                    _ => false,
2829                };
2830
2831                if satisfies {
2832                    Ok(value)
2833                } else {
2834                    Err(RuntimeError::new(format!(
2835                        "evidence assertion failed: expected {:?}, found {:?}",
2836                        expected_ev, actual_evidence
2837                    )))
2838                }
2839            }
2840
2841            // ==========================================
2842            // Scope Functions (Kotlin-inspired)
2843            // ==========================================
2844            PipeOp::Also(func) => {
2845                // |also{f} - execute side effect, return original value
2846                // Execute the function with the value for side effects
2847                match func.as_ref() {
2848                    Expr::Closure { params, body, .. } => {
2849                        if let Some(param) = params.first() {
2850                            let param_name = match &param.pattern {
2851                                Pattern::Ident { name, .. } => name.name.clone(),
2852                                _ => "it".to_string(),
2853                            };
2854                            self.environment
2855                                .borrow_mut()
2856                                .define(param_name, value.clone());
2857                        }
2858                        // Execute for side effects, ignore result
2859                        let _ = self.evaluate(body);
2860                    }
2861                    _ => {
2862                        // Call as function with value as argument
2863                        let _ = self.evaluate(func);
2864                    }
2865                }
2866                // Return original value unchanged
2867                Ok(value)
2868            }
2869
2870            PipeOp::Apply(func) => {
2871                // |apply{block} - mutate value in place, return modified value
2872                // The closure receives the value and can modify it
2873                match func.as_ref() {
2874                    Expr::Closure { params, body, .. } => {
2875                        if let Some(param) = params.first() {
2876                            let param_name = match &param.pattern {
2877                                Pattern::Ident { name, .. } => name.name.clone(),
2878                                _ => "it".to_string(),
2879                            };
2880                            self.environment
2881                                .borrow_mut()
2882                                .define(param_name, value.clone());
2883                        }
2884                        // Execute the body - mutations happen via the bound variable
2885                        let _ = self.evaluate(body);
2886                    }
2887                    _ => {
2888                        let _ = self.evaluate(func);
2889                    }
2890                }
2891                // Return the (potentially modified) value
2892                Ok(value)
2893            }
2894
2895            PipeOp::TakeIf(predicate) => {
2896                // |take_if{p} - return Some(value) if predicate true, None otherwise
2897                let predicate_result = match predicate.as_ref() {
2898                    Expr::Closure { params, body, .. } => {
2899                        if let Some(param) = params.first() {
2900                            let param_name = match &param.pattern {
2901                                Pattern::Ident { name, .. } => name.name.clone(),
2902                                _ => "it".to_string(),
2903                            };
2904                            self.environment
2905                                .borrow_mut()
2906                                .define(param_name, value.clone());
2907                        }
2908                        self.evaluate(body)?
2909                    }
2910                    _ => self.evaluate(predicate)?,
2911                };
2912
2913                match predicate_result {
2914                    Value::Bool(true) => Ok(Value::Variant {
2915                        enum_name: "Option".to_string(),
2916                        variant_name: "Some".to_string(),
2917                        fields: Some(Rc::new(vec![value])),
2918                    }),
2919                    Value::Bool(false) => Ok(Value::Variant {
2920                        enum_name: "Option".to_string(),
2921                        variant_name: "None".to_string(),
2922                        fields: None,
2923                    }),
2924                    _ => Err(RuntimeError::new("take_if predicate must return bool")),
2925                }
2926            }
2927
2928            PipeOp::TakeUnless(predicate) => {
2929                // |take_unless{p} - return Some(value) if predicate false, None otherwise
2930                let predicate_result = match predicate.as_ref() {
2931                    Expr::Closure { params, body, .. } => {
2932                        if let Some(param) = params.first() {
2933                            let param_name = match &param.pattern {
2934                                Pattern::Ident { name, .. } => name.name.clone(),
2935                                _ => "it".to_string(),
2936                            };
2937                            self.environment
2938                                .borrow_mut()
2939                                .define(param_name, value.clone());
2940                        }
2941                        self.evaluate(body)?
2942                    }
2943                    _ => self.evaluate(predicate)?,
2944                };
2945
2946                match predicate_result {
2947                    Value::Bool(false) => Ok(Value::Variant {
2948                        enum_name: "Option".to_string(),
2949                        variant_name: "Some".to_string(),
2950                        fields: Some(Rc::new(vec![value])),
2951                    }),
2952                    Value::Bool(true) => Ok(Value::Variant {
2953                        enum_name: "Option".to_string(),
2954                        variant_name: "None".to_string(),
2955                        fields: None,
2956                    }),
2957                    _ => Err(RuntimeError::new("take_unless predicate must return bool")),
2958                }
2959            }
2960
2961            PipeOp::Let(func) => {
2962                // |let{f} - transform value (alias for map/transform)
2963                match func.as_ref() {
2964                    Expr::Closure { params, body, .. } => {
2965                        if let Some(param) = params.first() {
2966                            let param_name = match &param.pattern {
2967                                Pattern::Ident { name, .. } => name.name.clone(),
2968                                _ => "it".to_string(),
2969                            };
2970                            self.environment
2971                                .borrow_mut()
2972                                .define(param_name, value.clone());
2973                        }
2974                        self.evaluate(body)
2975                    }
2976                    _ => self.evaluate(func),
2977                }
2978            }
2979
2980            // ==========================================
2981            // Mathematical & APL-Inspired Operations
2982            // ==========================================
2983            PipeOp::All(pred) => {
2984                // |∀{p} - check if ALL elements satisfy predicate
2985                match value {
2986                    Value::Array(arr) => {
2987                        for elem in arr.borrow().iter() {
2988                            self.environment
2989                                .borrow_mut()
2990                                .define("_".to_string(), elem.clone());
2991                            let result = self.evaluate(pred)?;
2992                            if !self.is_truthy(&result) {
2993                                return Ok(Value::Bool(false));
2994                            }
2995                        }
2996                        Ok(Value::Bool(true))
2997                    }
2998                    _ => Err(RuntimeError::new("All requires array")),
2999                }
3000            }
3001
3002            PipeOp::Any(pred) => {
3003                // |∃{p} - check if ANY element satisfies predicate
3004                match value {
3005                    Value::Array(arr) => {
3006                        for elem in arr.borrow().iter() {
3007                            self.environment
3008                                .borrow_mut()
3009                                .define("_".to_string(), elem.clone());
3010                            let result = self.evaluate(pred)?;
3011                            if self.is_truthy(&result) {
3012                                return Ok(Value::Bool(true));
3013                            }
3014                        }
3015                        Ok(Value::Bool(false))
3016                    }
3017                    _ => Err(RuntimeError::new("Any requires array")),
3018                }
3019            }
3020
3021            PipeOp::Compose(f) => {
3022                // |∘{f} - function composition / apply function
3023                self.environment.borrow_mut().define("_".to_string(), value);
3024                self.evaluate(f)
3025            }
3026
3027            PipeOp::Zip(other_expr) => {
3028                // |⋈{other} - zip with another collection
3029                let other = self.evaluate(other_expr)?;
3030                match (value, other) {
3031                    (Value::Array(arr1), Value::Array(arr2)) => {
3032                        let zipped: Vec<Value> = arr1
3033                            .borrow()
3034                            .iter()
3035                            .zip(arr2.borrow().iter())
3036                            .map(|(a, b)| Value::Tuple(Rc::new(vec![a.clone(), b.clone()])))
3037                            .collect();
3038                        Ok(Value::Array(Rc::new(RefCell::new(zipped))))
3039                    }
3040                    _ => Err(RuntimeError::new("Zip requires two arrays")),
3041                }
3042            }
3043
3044            PipeOp::Scan(f) => {
3045                // |∫{f} - cumulative fold (scan)
3046                match value {
3047                    Value::Array(arr) => {
3048                        let arr = arr.borrow();
3049                        if arr.is_empty() {
3050                            return Ok(Value::Array(Rc::new(RefCell::new(vec![]))));
3051                        }
3052                        let mut results = vec![arr[0].clone()];
3053                        let mut acc = arr[0].clone();
3054                        for elem in arr.iter().skip(1) {
3055                            self.environment
3056                                .borrow_mut()
3057                                .define("acc".to_string(), acc.clone());
3058                            self.environment
3059                                .borrow_mut()
3060                                .define("_".to_string(), elem.clone());
3061                            acc = self.evaluate(f)?;
3062                            results.push(acc.clone());
3063                        }
3064                        Ok(Value::Array(Rc::new(RefCell::new(results))))
3065                    }
3066                    _ => Err(RuntimeError::new("Scan requires array")),
3067                }
3068            }
3069
3070            PipeOp::Diff => {
3071                // |∂ - differences between adjacent elements
3072                match value {
3073                    Value::Array(arr) => {
3074                        let arr = arr.borrow();
3075                        if arr.len() < 2 {
3076                            return Ok(Value::Array(Rc::new(RefCell::new(vec![]))));
3077                        }
3078                        let mut diffs = Vec::new();
3079                        for i in 1..arr.len() {
3080                            let diff = self.subtract_values(&arr[i], &arr[i - 1])?;
3081                            diffs.push(diff);
3082                        }
3083                        Ok(Value::Array(Rc::new(RefCell::new(diffs))))
3084                    }
3085                    _ => Err(RuntimeError::new("Diff requires array")),
3086                }
3087            }
3088
3089            PipeOp::Gradient(var_expr) => {
3090                // |∇{var} - automatic differentiation
3091                // For now, just a placeholder - real autodiff requires tape recording
3092                let _ = var_expr;
3093                Ok(Value::Float(0.0)) // TODO: Implement real autodiff
3094            }
3095
3096            PipeOp::SortAsc => {
3097                // |⍋ - sort ascending
3098                match value {
3099                    Value::Array(arr) => {
3100                        let mut v = arr.borrow().clone();
3101                        v.sort_by(|a, b| self.compare_values(a, b, &None));
3102                        Ok(Value::Array(Rc::new(RefCell::new(v))))
3103                    }
3104                    _ => Err(RuntimeError::new("SortAsc requires array")),
3105                }
3106            }
3107
3108            PipeOp::SortDesc => {
3109                // |⍒ - sort descending
3110                match value {
3111                    Value::Array(arr) => {
3112                        let mut v = arr.borrow().clone();
3113                        v.sort_by(|a, b| self.compare_values(b, a, &None));
3114                        Ok(Value::Array(Rc::new(RefCell::new(v))))
3115                    }
3116                    _ => Err(RuntimeError::new("SortDesc requires array")),
3117                }
3118            }
3119
3120            PipeOp::Reverse => {
3121                // |⌽ - reverse collection
3122                match value {
3123                    Value::Array(arr) => {
3124                        let mut v = arr.borrow().clone();
3125                        v.reverse();
3126                        Ok(Value::Array(Rc::new(RefCell::new(v))))
3127                    }
3128                    _ => Err(RuntimeError::new("Reverse requires array")),
3129                }
3130            }
3131
3132            PipeOp::Cycle(n_expr) => {
3133                // |↻{n} - repeat collection n times
3134                match value {
3135                    Value::Array(arr) => {
3136                        let n_val = self.evaluate(n_expr)?;
3137                        let n = match n_val {
3138                            Value::Int(i) => i as usize,
3139                            _ => return Err(RuntimeError::new("Cycle count must be integer")),
3140                        };
3141                        let arr = arr.borrow();
3142                        let cycled: Vec<Value> =
3143                            arr.iter().cloned().cycle().take(arr.len() * n).collect();
3144                        Ok(Value::Array(Rc::new(RefCell::new(cycled))))
3145                    }
3146                    _ => Err(RuntimeError::new("Cycle requires array")),
3147                }
3148            }
3149
3150            PipeOp::Windows(n_expr) => {
3151                // |⌺{n} - sliding windows
3152                match value {
3153                    Value::Array(arr) => {
3154                        let n_val = self.evaluate(n_expr)?;
3155                        let n = match n_val {
3156                            Value::Int(i) => i as usize,
3157                            _ => return Err(RuntimeError::new("Window size must be integer")),
3158                        };
3159                        let arr = arr.borrow();
3160                        let windows: Vec<Value> = arr
3161                            .windows(n)
3162                            .map(|w| Value::Array(Rc::new(RefCell::new(w.to_vec()))))
3163                            .collect();
3164                        Ok(Value::Array(Rc::new(RefCell::new(windows))))
3165                    }
3166                    _ => Err(RuntimeError::new("Windows requires array")),
3167                }
3168            }
3169
3170            PipeOp::Chunks(n_expr) => {
3171                // |⊞{n} - split into chunks
3172                match value {
3173                    Value::Array(arr) => {
3174                        let n_val = self.evaluate(n_expr)?;
3175                        let n = match n_val {
3176                            Value::Int(i) => i as usize,
3177                            _ => return Err(RuntimeError::new("Chunk size must be integer")),
3178                        };
3179                        let arr = arr.borrow();
3180                        let chunks: Vec<Value> = arr
3181                            .chunks(n)
3182                            .map(|c| Value::Array(Rc::new(RefCell::new(c.to_vec()))))
3183                            .collect();
3184                        Ok(Value::Array(Rc::new(RefCell::new(chunks))))
3185                    }
3186                    _ => Err(RuntimeError::new("Chunks requires array")),
3187                }
3188            }
3189
3190            PipeOp::Flatten => {
3191                // |⋳ - flatten nested collection
3192                match value {
3193                    Value::Array(arr) => {
3194                        let mut flat = Vec::new();
3195                        for elem in arr.borrow().iter() {
3196                            match elem {
3197                                Value::Array(inner) => {
3198                                    flat.extend(inner.borrow().iter().cloned());
3199                                }
3200                                other => flat.push(other.clone()),
3201                            }
3202                        }
3203                        Ok(Value::Array(Rc::new(RefCell::new(flat))))
3204                    }
3205                    _ => Err(RuntimeError::new("Flatten requires array")),
3206                }
3207            }
3208
3209            PipeOp::Unique => {
3210                // |∪ - remove duplicates
3211                match value {
3212                    Value::Array(arr) => {
3213                        let mut seen = std::collections::HashSet::new();
3214                        let mut unique = Vec::new();
3215                        for elem in arr.borrow().iter() {
3216                            let key = format!("{:?}", elem);
3217                            if seen.insert(key) {
3218                                unique.push(elem.clone());
3219                            }
3220                        }
3221                        Ok(Value::Array(Rc::new(RefCell::new(unique))))
3222                    }
3223                    _ => Err(RuntimeError::new("Unique requires array")),
3224                }
3225            }
3226
3227            PipeOp::Enumerate => {
3228                // |⍳ - pair with indices
3229                match value {
3230                    Value::Array(arr) => {
3231                        let enumerated: Vec<Value> = arr
3232                            .borrow()
3233                            .iter()
3234                            .enumerate()
3235                            .map(|(i, v)| {
3236                                Value::Tuple(Rc::new(vec![Value::Int(i as i64), v.clone()]))
3237                            })
3238                            .collect();
3239                        Ok(Value::Array(Rc::new(RefCell::new(enumerated))))
3240                    }
3241                    _ => Err(RuntimeError::new("Enumerate requires array")),
3242                }
3243            }
3244        }
3245    }
3246
3247    // ==========================================
3248    // Protocol Helper Methods
3249    // ==========================================
3250
3251    /// Wrap a value in Reported evidentiality
3252    /// Network data is "hearsay" - it comes from external sources we can't verify
3253    fn wrap_reported(&self, value: Value) -> Value {
3254        Value::Evidential {
3255            value: Box::new(value),
3256            evidence: Evidence::Reported,
3257        }
3258    }
3259
3260    /// Send data over a protocol connection
3261    fn protocol_send(&mut self, connection: &Value, data: &Value) -> Result<Value, RuntimeError> {
3262        // Extract connection info and send data
3263        match connection {
3264            Value::Map(obj) => {
3265                let obj = obj.borrow();
3266                if let Some(Value::String(protocol)) = obj.get("__protocol__") {
3267                    match protocol.as_str() {
3268                        "http" | "https" => {
3269                            // For HTTP, "send" means execute the request
3270                            // The data becomes the body
3271                            #[cfg(debug_assertions)]
3272                            eprintln!("[HTTP] Would send request with body: {:?}", data);
3273                            Ok(Value::Map(Rc::new(RefCell::new({
3274                                let mut response = HashMap::new();
3275                                response.insert("status".to_string(), Value::Int(200));
3276                                response.insert("body".to_string(), data.clone());
3277                                response.insert(
3278                                    "__protocol__".to_string(),
3279                                    Value::String(Rc::new("http_response".to_string())),
3280                                );
3281                                response
3282                            }))))
3283                        }
3284                        "ws" | "wss" => {
3285                            // For WebSocket, send a message
3286                            #[cfg(debug_assertions)]
3287                            eprintln!("[WebSocket] Would send message: {:?}", data);
3288                            Ok(Value::Bool(true)) // Message sent successfully
3289                        }
3290                        "grpc" => {
3291                            // For gRPC, send the request message
3292                            #[cfg(debug_assertions)]
3293                            eprintln!("[gRPC] Would send message: {:?}", data);
3294                            Ok(Value::Map(Rc::new(RefCell::new({
3295                                let mut response = HashMap::new();
3296                                response.insert("status".to_string(), Value::Int(0)); // OK
3297                                response.insert("message".to_string(), data.clone());
3298                                response.insert(
3299                                    "__protocol__".to_string(),
3300                                    Value::String(Rc::new("grpc_response".to_string())),
3301                                );
3302                                response
3303                            }))))
3304                        }
3305                        "kafka" => {
3306                            // For Kafka, produce a message
3307                            #[cfg(debug_assertions)]
3308                            eprintln!("[Kafka] Would produce message: {:?}", data);
3309                            Ok(Value::Map(Rc::new(RefCell::new({
3310                                let mut result = HashMap::new();
3311                                result.insert("partition".to_string(), Value::Int(0));
3312                                result.insert("offset".to_string(), Value::Int(42));
3313                                result
3314                            }))))
3315                        }
3316                        _ => Err(RuntimeError::new(format!("Unknown protocol: {}", protocol))),
3317                    }
3318                } else {
3319                    Err(RuntimeError::new(
3320                        "Connection object missing __protocol__ field",
3321                    ))
3322                }
3323            }
3324            _ => Err(RuntimeError::new("send requires a connection object")),
3325        }
3326    }
3327
3328    /// Receive data from a protocol connection
3329    fn protocol_recv(&mut self, connection: &Value) -> Result<Value, RuntimeError> {
3330        match connection {
3331            Value::Map(obj) => {
3332                let obj = obj.borrow();
3333                if let Some(Value::String(protocol)) = obj.get("__protocol__") {
3334                    match protocol.as_str() {
3335                        "ws" | "wss" => {
3336                            // For WebSocket, receive a message
3337                            #[cfg(debug_assertions)]
3338                            eprintln!("[WebSocket] Would receive message");
3339                            Ok(Value::String(Rc::new("received message".to_string())))
3340                        }
3341                        "kafka" => {
3342                            // For Kafka, consume a message
3343                            #[cfg(debug_assertions)]
3344                            eprintln!("[Kafka] Would consume message");
3345                            Ok(Value::Map(Rc::new(RefCell::new({
3346                                let mut msg = HashMap::new();
3347                                msg.insert("key".to_string(), Value::Null);
3348                                msg.insert(
3349                                    "value".to_string(),
3350                                    Value::String(Rc::new("consumed message".to_string())),
3351                                );
3352                                msg.insert("partition".to_string(), Value::Int(0));
3353                                msg.insert("offset".to_string(), Value::Int(100));
3354                                msg
3355                            }))))
3356                        }
3357                        "grpc" => {
3358                            // For gRPC streaming, receive next message
3359                            #[cfg(debug_assertions)]
3360                            eprintln!("[gRPC] Would receive stream message");
3361                            Ok(Value::Map(Rc::new(RefCell::new({
3362                                let mut msg = HashMap::new();
3363                                msg.insert(
3364                                    "data".to_string(),
3365                                    Value::String(Rc::new("stream data".to_string())),
3366                                );
3367                                msg
3368                            }))))
3369                        }
3370                        _ => Err(RuntimeError::new(format!(
3371                            "recv not supported for protocol: {}",
3372                            protocol
3373                        ))),
3374                    }
3375                } else {
3376                    Err(RuntimeError::new(
3377                        "Connection object missing __protocol__ field",
3378                    ))
3379                }
3380            }
3381            _ => Err(RuntimeError::new("recv requires a connection object")),
3382        }
3383    }
3384
3385    /// Create a streaming iterator over protocol data
3386    fn protocol_stream(
3387        &mut self,
3388        connection: &Value,
3389        _handler: &Value,
3390    ) -> Result<Value, RuntimeError> {
3391        // Create a lazy stream that yields values with Reported evidentiality
3392        match connection {
3393            Value::Map(obj) => {
3394                let obj = obj.borrow();
3395                if let Some(Value::String(protocol)) = obj.get("__protocol__") {
3396                    #[cfg(debug_assertions)]
3397                    eprintln!("[{}] Would create stream", protocol);
3398
3399                    // Return a stream object that can be iterated
3400                    Ok(Value::Map(Rc::new(RefCell::new({
3401                        let mut stream = HashMap::new();
3402                        stream.insert(
3403                            "__type__".to_string(),
3404                            Value::String(Rc::new("Stream".to_string())),
3405                        );
3406                        stream.insert("__protocol__".to_string(), Value::String(protocol.clone()));
3407                        stream.insert(
3408                            "__evidentiality__".to_string(),
3409                            Value::String(Rc::new("reported".to_string())),
3410                        );
3411                        stream
3412                    }))))
3413                } else {
3414                    Err(RuntimeError::new(
3415                        "Connection object missing __protocol__ field",
3416                    ))
3417                }
3418            }
3419            _ => Err(RuntimeError::new("stream requires a connection object")),
3420        }
3421    }
3422
3423    /// Establish a protocol connection
3424    fn protocol_connect(
3425        &mut self,
3426        target: &Value,
3427        _config: Option<&Value>,
3428    ) -> Result<Value, RuntimeError> {
3429        match target {
3430            Value::String(url) => {
3431                // Parse URL to determine protocol
3432                let protocol = if url.starts_with("wss://") || url.starts_with("ws://") {
3433                    if url.starts_with("wss://") {
3434                        "wss"
3435                    } else {
3436                        "ws"
3437                    }
3438                } else if url.starts_with("https://") || url.starts_with("http://") {
3439                    if url.starts_with("https://") {
3440                        "https"
3441                    } else {
3442                        "http"
3443                    }
3444                } else if url.starts_with("grpc://") || url.starts_with("grpcs://") {
3445                    "grpc"
3446                } else if url.starts_with("kafka://") {
3447                    "kafka"
3448                } else if url.starts_with("amqp://") || url.starts_with("amqps://") {
3449                    "amqp"
3450                } else {
3451                    "unknown"
3452                };
3453
3454                #[cfg(debug_assertions)]
3455                eprintln!("[{}] Would connect to: {}", protocol, url);
3456
3457                // Return a connection object
3458                Ok(Value::Map(Rc::new(RefCell::new({
3459                    let mut conn = HashMap::new();
3460                    conn.insert(
3461                        "__protocol__".to_string(),
3462                        Value::String(Rc::new(protocol.to_string())),
3463                    );
3464                    conn.insert("url".to_string(), Value::String(url.clone()));
3465                    conn.insert("connected".to_string(), Value::Bool(true));
3466                    conn
3467                }))))
3468            }
3469            Value::Map(obj) => {
3470                // Already a connection config object
3471                let mut conn = obj.borrow().clone();
3472                conn.insert("connected".to_string(), Value::Bool(true));
3473                Ok(Value::Map(Rc::new(RefCell::new(conn))))
3474            }
3475            _ => Err(RuntimeError::new(
3476                "connect requires URL string or config object",
3477            )),
3478        }
3479    }
3480
3481    /// Close a protocol connection
3482    fn protocol_close(&mut self, connection: &Value) -> Result<(), RuntimeError> {
3483        match connection {
3484            Value::Map(obj) => {
3485                let mut obj = obj.borrow_mut();
3486                if let Some(Value::String(protocol)) = obj.get("__protocol__").cloned() {
3487                    #[cfg(debug_assertions)]
3488                    eprintln!("[{}] Would close connection", protocol);
3489                    obj.insert("connected".to_string(), Value::Bool(false));
3490                    Ok(())
3491                } else {
3492                    Err(RuntimeError::new(
3493                        "Connection object missing __protocol__ field",
3494                    ))
3495                }
3496            }
3497            _ => Err(RuntimeError::new("close requires a connection object")),
3498        }
3499    }
3500
3501    /// Add a header to a protocol request
3502    fn protocol_add_header(
3503        &mut self,
3504        mut request: Value,
3505        name: &Value,
3506        header_value: &Value,
3507    ) -> Result<Value, RuntimeError> {
3508        let name_str = match name {
3509            Value::String(s) => (**s).clone(),
3510            _ => return Err(RuntimeError::new("Header name must be a string")),
3511        };
3512        let value_str = match header_value {
3513            Value::String(s) => (**s).clone(),
3514            Value::Int(i) => i.to_string(),
3515            _ => return Err(RuntimeError::new("Header value must be string or int")),
3516        };
3517
3518        match &mut request {
3519            Value::Map(obj) => {
3520                let mut obj = obj.borrow_mut();
3521
3522                // Get or create headers map
3523                let headers = obj
3524                    .entry("headers".to_string())
3525                    .or_insert_with(|| Value::Map(Rc::new(RefCell::new(HashMap::new()))));
3526
3527                if let Value::Map(headers_obj) = headers {
3528                    headers_obj
3529                        .borrow_mut()
3530                        .insert(name_str, Value::String(Rc::new(value_str)));
3531                }
3532                drop(obj);
3533                Ok(request)
3534            }
3535            _ => Err(RuntimeError::new("header requires a request object")),
3536        }
3537    }
3538
3539    /// Set the body of a protocol request
3540    fn protocol_set_body(
3541        &mut self,
3542        mut request: Value,
3543        body: &Value,
3544    ) -> Result<Value, RuntimeError> {
3545        match &mut request {
3546            Value::Map(obj) => {
3547                obj.borrow_mut().insert("body".to_string(), body.clone());
3548                Ok(request)
3549            }
3550            _ => Err(RuntimeError::new("body requires a request object")),
3551        }
3552    }
3553
3554    /// Set the timeout for a protocol operation
3555    fn protocol_set_timeout(
3556        &mut self,
3557        mut request: Value,
3558        ms: &Value,
3559    ) -> Result<Value, RuntimeError> {
3560        let timeout_ms = match ms {
3561            Value::Int(n) => *n,
3562            Value::Float(f) => *f as i64,
3563            _ => return Err(RuntimeError::new("Timeout must be a number (milliseconds)")),
3564        };
3565
3566        match &mut request {
3567            Value::Map(obj) => {
3568                obj.borrow_mut()
3569                    .insert("timeout_ms".to_string(), Value::Int(timeout_ms));
3570                Ok(request)
3571            }
3572            _ => Err(RuntimeError::new("timeout requires a request object")),
3573        }
3574    }
3575
3576    /// Set the retry policy for a protocol operation
3577    fn protocol_set_retry(
3578        &mut self,
3579        mut request: Value,
3580        count: &Value,
3581        strategy: Option<&Value>,
3582    ) -> Result<Value, RuntimeError> {
3583        let retry_count = match count {
3584            Value::Int(n) => *n,
3585            _ => return Err(RuntimeError::new("Retry count must be an integer")),
3586        };
3587
3588        match &mut request {
3589            Value::Map(obj) => {
3590                let mut obj = obj.borrow_mut();
3591                obj.insert("retry_count".to_string(), Value::Int(retry_count));
3592                if let Some(strat) = strategy {
3593                    obj.insert("retry_strategy".to_string(), strat.clone());
3594                }
3595                drop(obj);
3596                Ok(request)
3597            }
3598            _ => Err(RuntimeError::new("retry requires a request object")),
3599        }
3600    }
3601
3602    fn sum_values(&self, value: Value) -> Result<Value, RuntimeError> {
3603        match value {
3604            Value::Array(arr) => {
3605                let arr = arr.borrow();
3606                if arr.is_empty() {
3607                    return Ok(Value::Int(0));
3608                }
3609                let mut sum = match &arr[0] {
3610                    Value::Int(_) => Value::Int(0),
3611                    Value::Float(_) => Value::Float(0.0),
3612                    _ => return Err(RuntimeError::new("Cannot sum non-numeric array")),
3613                };
3614                for item in arr.iter() {
3615                    sum = match (&sum, item) {
3616                        (Value::Int(a), Value::Int(b)) => Value::Int(a + b),
3617                        (Value::Float(a), Value::Float(b)) => Value::Float(a + b),
3618                        (Value::Int(a), Value::Float(b)) => Value::Float(*a as f64 + b),
3619                        (Value::Float(a), Value::Int(b)) => Value::Float(a + *b as f64),
3620                        _ => return Err(RuntimeError::new("Cannot sum non-numeric values")),
3621                    };
3622                }
3623                Ok(sum)
3624            }
3625            _ => Err(RuntimeError::new("sum requires array")),
3626        }
3627    }
3628
3629    fn product_values(&self, value: Value) -> Result<Value, RuntimeError> {
3630        match value {
3631            Value::Array(arr) => {
3632                let arr = arr.borrow();
3633                if arr.is_empty() {
3634                    return Ok(Value::Int(1));
3635                }
3636                let mut prod = match &arr[0] {
3637                    Value::Int(_) => Value::Int(1),
3638                    Value::Float(_) => Value::Float(1.0),
3639                    _ => return Err(RuntimeError::new("Cannot multiply non-numeric array")),
3640                };
3641                for item in arr.iter() {
3642                    prod = match (&prod, item) {
3643                        (Value::Int(a), Value::Int(b)) => Value::Int(a * b),
3644                        (Value::Float(a), Value::Float(b)) => Value::Float(a * b),
3645                        (Value::Int(a), Value::Float(b)) => Value::Float(*a as f64 * b),
3646                        (Value::Float(a), Value::Int(b)) => Value::Float(a * *b as f64),
3647                        _ => return Err(RuntimeError::new("Cannot multiply non-numeric values")),
3648                    };
3649                }
3650                Ok(prod)
3651            }
3652            _ => Err(RuntimeError::new("product requires array")),
3653        }
3654    }
3655
3656    fn min_values(&self, value: Value) -> Result<Value, RuntimeError> {
3657        match value {
3658            Value::Array(arr) => {
3659                let arr = arr.borrow();
3660                if arr.is_empty() {
3661                    return Err(RuntimeError::new("Cannot find min of empty array"));
3662                }
3663                let mut min = arr[0].clone();
3664                for item in arr.iter().skip(1) {
3665                    min = match (&min, item) {
3666                        (Value::Int(a), Value::Int(b)) => {
3667                            if *b < *a {
3668                                Value::Int(*b)
3669                            } else {
3670                                Value::Int(*a)
3671                            }
3672                        }
3673                        (Value::Float(a), Value::Float(b)) => {
3674                            if *b < *a {
3675                                Value::Float(*b)
3676                            } else {
3677                                Value::Float(*a)
3678                            }
3679                        }
3680                        (Value::Int(a), Value::Float(b)) => {
3681                            let af = *a as f64;
3682                            if *b < af {
3683                                Value::Float(*b)
3684                            } else {
3685                                Value::Float(af)
3686                            }
3687                        }
3688                        (Value::Float(a), Value::Int(b)) => {
3689                            let bf = *b as f64;
3690                            if bf < *a {
3691                                Value::Float(bf)
3692                            } else {
3693                                Value::Float(*a)
3694                            }
3695                        }
3696                        _ => {
3697                            return Err(RuntimeError::new("Cannot find min of non-numeric values"))
3698                        }
3699                    };
3700                }
3701                Ok(min)
3702            }
3703            _ => Err(RuntimeError::new("min requires array")),
3704        }
3705    }
3706
3707    fn max_values(&self, value: Value) -> Result<Value, RuntimeError> {
3708        match value {
3709            Value::Array(arr) => {
3710                let arr = arr.borrow();
3711                if arr.is_empty() {
3712                    return Err(RuntimeError::new("Cannot find max of empty array"));
3713                }
3714                let mut max = arr[0].clone();
3715                for item in arr.iter().skip(1) {
3716                    max = match (&max, item) {
3717                        (Value::Int(a), Value::Int(b)) => {
3718                            if *b > *a {
3719                                Value::Int(*b)
3720                            } else {
3721                                Value::Int(*a)
3722                            }
3723                        }
3724                        (Value::Float(a), Value::Float(b)) => {
3725                            if *b > *a {
3726                                Value::Float(*b)
3727                            } else {
3728                                Value::Float(*a)
3729                            }
3730                        }
3731                        (Value::Int(a), Value::Float(b)) => {
3732                            let af = *a as f64;
3733                            if *b > af {
3734                                Value::Float(*b)
3735                            } else {
3736                                Value::Float(af)
3737                            }
3738                        }
3739                        (Value::Float(a), Value::Int(b)) => {
3740                            let bf = *b as f64;
3741                            if bf > *a {
3742                                Value::Float(bf)
3743                            } else {
3744                                Value::Float(*a)
3745                            }
3746                        }
3747                        _ => {
3748                            return Err(RuntimeError::new("Cannot find max of non-numeric values"))
3749                        }
3750                    };
3751                }
3752                Ok(max)
3753            }
3754            _ => Err(RuntimeError::new("max requires array")),
3755        }
3756    }
3757
3758    fn concat_values(&self, value: Value) -> Result<Value, RuntimeError> {
3759        match value {
3760            Value::Array(arr) => {
3761                let arr = arr.borrow();
3762                if arr.is_empty() {
3763                    return Ok(Value::String(Rc::new(String::new())));
3764                }
3765                // Determine if we're concatenating strings or arrays
3766                match &arr[0] {
3767                    Value::String(_) => {
3768                        let mut result = String::new();
3769                        for item in arr.iter() {
3770                            if let Value::String(s) = item {
3771                                result.push_str(s);
3772                            } else {
3773                                return Err(RuntimeError::new(
3774                                    "concat requires all elements to be strings",
3775                                ));
3776                            }
3777                        }
3778                        Ok(Value::String(Rc::new(result)))
3779                    }
3780                    Value::Array(_) => {
3781                        let mut result = Vec::new();
3782                        for item in arr.iter() {
3783                            if let Value::Array(inner) = item {
3784                                result.extend(inner.borrow().iter().cloned());
3785                            } else {
3786                                return Err(RuntimeError::new(
3787                                    "concat requires all elements to be arrays",
3788                                ));
3789                            }
3790                        }
3791                        Ok(Value::Array(Rc::new(RefCell::new(result))))
3792                    }
3793                    _ => Err(RuntimeError::new("concat requires strings or arrays")),
3794                }
3795            }
3796            _ => Err(RuntimeError::new("concat requires array")),
3797        }
3798    }
3799
3800    fn all_values(&self, value: Value) -> Result<Value, RuntimeError> {
3801        match value {
3802            Value::Array(arr) => {
3803                let arr = arr.borrow();
3804                for item in arr.iter() {
3805                    match item {
3806                        Value::Bool(b) => {
3807                            if !*b {
3808                                return Ok(Value::Bool(false));
3809                            }
3810                        }
3811                        _ => return Err(RuntimeError::new("all requires array of booleans")),
3812                    }
3813                }
3814                Ok(Value::Bool(true))
3815            }
3816            _ => Err(RuntimeError::new("all requires array")),
3817        }
3818    }
3819
3820    fn any_values(&self, value: Value) -> Result<Value, RuntimeError> {
3821        match value {
3822            Value::Array(arr) => {
3823                let arr = arr.borrow();
3824                for item in arr.iter() {
3825                    match item {
3826                        Value::Bool(b) => {
3827                            if *b {
3828                                return Ok(Value::Bool(true));
3829                            }
3830                        }
3831                        _ => return Err(RuntimeError::new("any requires array of booleans")),
3832                    }
3833                }
3834                Ok(Value::Bool(false))
3835            }
3836            _ => Err(RuntimeError::new("any requires array")),
3837        }
3838    }
3839
3840    fn compare_values(&self, a: &Value, b: &Value, _field: &Option<Ident>) -> std::cmp::Ordering {
3841        // Simple comparison for now
3842        match (a, b) {
3843            (Value::Int(a), Value::Int(b)) => a.cmp(b),
3844            (Value::Float(a), Value::Float(b)) => {
3845                a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal)
3846            }
3847            (Value::String(a), Value::String(b)) => a.cmp(b),
3848            _ => std::cmp::Ordering::Equal,
3849        }
3850    }
3851
3852    /// Subtract two values (for diff operation)
3853    fn subtract_values(&self, a: &Value, b: &Value) -> Result<Value, RuntimeError> {
3854        match (a, b) {
3855            (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a - b)),
3856            (Value::Float(a), Value::Float(b)) => Ok(Value::Float(a - b)),
3857            (Value::Int(a), Value::Float(b)) => Ok(Value::Float(*a as f64 - b)),
3858            (Value::Float(a), Value::Int(b)) => Ok(Value::Float(a - *b as f64)),
3859            _ => Err(RuntimeError::new(format!(
3860                "Cannot subtract {:?} from {:?}",
3861                b, a
3862            ))),
3863        }
3864    }
3865
3866    fn eval_closure(
3867        &mut self,
3868        params: &[ClosureParam],
3869        body: &Expr,
3870    ) -> Result<Value, RuntimeError> {
3871        let param_names: Vec<String> = params
3872            .iter()
3873            .map(|p| match &p.pattern {
3874                Pattern::Ident { name, .. } => name.name.clone(),
3875                _ => "_".to_string(),
3876            })
3877            .collect();
3878
3879        Ok(Value::Function(Rc::new(Function {
3880            name: None,
3881            params: param_names,
3882            body: body.clone(),
3883            closure: self.environment.clone(),
3884        })))
3885    }
3886
3887    fn eval_struct_literal(
3888        &mut self,
3889        path: &TypePath,
3890        fields: &[FieldInit],
3891        _rest: &Option<Box<Expr>>,
3892    ) -> Result<Value, RuntimeError> {
3893        let name = path
3894            .segments
3895            .iter()
3896            .map(|s| s.ident.name.as_str())
3897            .collect::<Vec<_>>()
3898            .join("::");
3899
3900        let mut field_values = HashMap::new();
3901        for field in fields {
3902            let value = match &field.value {
3903                Some(expr) => self.evaluate(expr)?,
3904                None => self
3905                    .environment
3906                    .borrow()
3907                    .get(&field.name.name)
3908                    .ok_or_else(|| {
3909                        RuntimeError::new(format!("Unknown variable: {}", field.name.name))
3910                    })?,
3911            };
3912            field_values.insert(field.name.name.clone(), value);
3913        }
3914
3915        Ok(Value::Struct {
3916            name,
3917            fields: Rc::new(RefCell::new(field_values)),
3918        })
3919    }
3920
3921    /// Extract evidentiality from a value (recursively unwraps Evidential wrapper)
3922    fn extract_evidence(value: &Value) -> Option<Evidence> {
3923        match value {
3924            Value::Evidential { evidence, .. } => Some(*evidence),
3925            _ => None,
3926        }
3927    }
3928
3929    /// Extract affect from a value
3930    fn extract_affect(value: &Value) -> Option<&RuntimeAffect> {
3931        match value {
3932            Value::Affective { affect, .. } => Some(affect),
3933            _ => None,
3934        }
3935    }
3936
3937    /// Derive evidence from affect markers.
3938    /// Sarcasm implies uncertainty (meaning is inverted).
3939    /// Confidence directly maps to evidence levels.
3940    fn affect_to_evidence(affect: &RuntimeAffect) -> Option<Evidence> {
3941        // Sarcasm indicates the literal meaning shouldn't be trusted
3942        if affect.sarcasm {
3943            return Some(Evidence::Uncertain);
3944        }
3945
3946        // Confidence maps directly to evidence
3947        match affect.confidence {
3948            Some(RuntimeConfidence::High) => Some(Evidence::Known),
3949            Some(RuntimeConfidence::Low) => Some(Evidence::Uncertain),
3950            Some(RuntimeConfidence::Medium) | None => None,
3951        }
3952    }
3953
3954    /// Combine two evidence levels, returning the "worst" (most uncertain) one.
3955    /// Order: Known < Uncertain < Reported < Paradox
3956    fn combine_evidence(a: Option<Evidence>, b: Option<Evidence>) -> Option<Evidence> {
3957        match (a, b) {
3958            (None, None) => None,
3959            (Some(e), None) | (None, Some(e)) => Some(e),
3960            (Some(a), Some(b)) => {
3961                let rank = |e: Evidence| match e {
3962                    Evidence::Known => 0,
3963                    Evidence::Uncertain => 1,
3964                    Evidence::Reported => 2,
3965                    Evidence::Paradox => 3,
3966                };
3967                if rank(a) >= rank(b) {
3968                    Some(a)
3969                } else {
3970                    Some(b)
3971                }
3972            }
3973        }
3974    }
3975
3976    /// Unwrap an evidential value to get the inner value for display
3977    fn unwrap_evidential(value: &Value) -> &Value {
3978        match value {
3979            Value::Evidential { value: inner, .. } => Self::unwrap_evidential(inner),
3980            _ => value,
3981        }
3982    }
3983
3984    /// Unwrap an affective value to get the inner value
3985    fn unwrap_affective(value: &Value) -> &Value {
3986        match value {
3987            Value::Affective { value: inner, .. } => Self::unwrap_affective(inner),
3988            _ => value,
3989        }
3990    }
3991
3992    /// Unwrap both evidential and affective wrappers
3993    fn unwrap_value(value: &Value) -> &Value {
3994        match value {
3995            Value::Evidential { value: inner, .. } => Self::unwrap_value(inner),
3996            Value::Affective { value: inner, .. } => Self::unwrap_value(inner),
3997            _ => value,
3998        }
3999    }
4000
4001    fn eval_evidential(&mut self, expr: &Expr, ev: &Evidentiality) -> Result<Value, RuntimeError> {
4002        let value = self.evaluate(expr)?;
4003        let evidence = match ev {
4004            Evidentiality::Known => Evidence::Known,
4005            Evidentiality::Uncertain => Evidence::Uncertain,
4006            Evidentiality::Reported => Evidence::Reported,
4007            Evidentiality::Paradox => Evidence::Paradox,
4008        };
4009        Ok(Value::Evidential {
4010            value: Box::new(value),
4011            evidence,
4012        })
4013    }
4014
4015    fn eval_range(
4016        &mut self,
4017        start: &Option<Box<Expr>>,
4018        end: &Option<Box<Expr>>,
4019        inclusive: bool,
4020    ) -> Result<Value, RuntimeError> {
4021        let start_val = match start {
4022            Some(e) => match self.evaluate(e)? {
4023                Value::Int(n) => n,
4024                _ => return Err(RuntimeError::new("Range requires integer bounds")),
4025            },
4026            None => 0,
4027        };
4028
4029        let end_val = match end {
4030            Some(e) => match self.evaluate(e)? {
4031                Value::Int(n) => n,
4032                _ => return Err(RuntimeError::new("Range requires integer bounds")),
4033            },
4034            None => return Err(RuntimeError::new("Range requires end bound")),
4035        };
4036
4037        let values: Vec<Value> = if inclusive {
4038            (start_val..=end_val).map(Value::Int).collect()
4039        } else {
4040            (start_val..end_val).map(Value::Int).collect()
4041        };
4042
4043        Ok(Value::Array(Rc::new(RefCell::new(values))))
4044    }
4045
4046    fn is_truthy(&self, value: &Value) -> bool {
4047        match value {
4048            Value::Null => false,
4049            Value::Bool(b) => *b,
4050            Value::Int(n) => *n != 0,
4051            Value::Float(n) => *n != 0.0,
4052            Value::String(s) => !s.is_empty(),
4053            Value::Array(arr) => !arr.borrow().is_empty(),
4054            Value::Empty => false,
4055            Value::Evidential { value, .. } => self.is_truthy(value),
4056            _ => true,
4057        }
4058    }
4059}
4060
4061impl Default for Interpreter {
4062    fn default() -> Self {
4063        Self::new()
4064    }
4065}
4066
4067#[cfg(test)]
4068mod tests {
4069    use super::*;
4070    use crate::Parser;
4071
4072    fn run(source: &str) -> Result<Value, RuntimeError> {
4073        let mut parser = Parser::new(source);
4074        let file = parser
4075            .parse_file()
4076            .map_err(|e| RuntimeError::new(e.to_string()))?;
4077        let mut interp = Interpreter::new();
4078        interp.execute(&file)
4079    }
4080
4081    #[test]
4082    fn test_arithmetic() {
4083        assert!(matches!(
4084            run("fn main() { return 2 + 3; }"),
4085            Ok(Value::Int(5))
4086        ));
4087        assert!(matches!(
4088            run("fn main() { return 10 - 4; }"),
4089            Ok(Value::Int(6))
4090        ));
4091        assert!(matches!(
4092            run("fn main() { return 3 * 4; }"),
4093            Ok(Value::Int(12))
4094        ));
4095        assert!(matches!(
4096            run("fn main() { return 15 / 3; }"),
4097            Ok(Value::Int(5))
4098        ));
4099        assert!(matches!(
4100            run("fn main() { return 2 ** 10; }"),
4101            Ok(Value::Int(1024))
4102        ));
4103    }
4104
4105    #[test]
4106    fn test_variables() {
4107        assert!(matches!(
4108            run("fn main() { let x = 42; return x; }"),
4109            Ok(Value::Int(42))
4110        ));
4111    }
4112
4113    #[test]
4114    fn test_conditionals() {
4115        assert!(matches!(
4116            run("fn main() { if true { return 1; } else { return 2; } }"),
4117            Ok(Value::Int(1))
4118        ));
4119        assert!(matches!(
4120            run("fn main() { if false { return 1; } else { return 2; } }"),
4121            Ok(Value::Int(2))
4122        ));
4123    }
4124
4125    #[test]
4126    fn test_arrays() {
4127        assert!(matches!(
4128            run("fn main() { return [1, 2, 3][1]; }"),
4129            Ok(Value::Int(2))
4130        ));
4131    }
4132
4133    #[test]
4134    fn test_functions() {
4135        let result = run("
4136            fn double(x: i64) -> i64 { return x * 2; }
4137            fn main() { return double(21); }
4138        ");
4139        assert!(matches!(result, Ok(Value::Int(42))));
4140    }
4141
4142    #[test]
4143    fn test_pipe_transform() {
4144        let result = run("fn main() { return [1, 2, 3]|τ{_ * 2}|sum; }");
4145        assert!(matches!(result, Ok(Value::Int(12))));
4146    }
4147
4148    #[test]
4149    fn test_pipe_filter() {
4150        let result = run("fn main() { return [1, 2, 3, 4, 5]|φ{_ > 2}|sum; }");
4151        assert!(matches!(result, Ok(Value::Int(12)))); // 3 + 4 + 5
4152    }
4153
4154    #[test]
4155    fn test_interpolation_evidentiality_propagation() {
4156        // Test that evidentiality propagates through string interpolation
4157        // When an evidential value is interpolated, the result string should carry that evidentiality
4158        let result = run(r#"
4159            fn main() {
4160                let rep = reported(42);
4161
4162                // Interpolating a reported value should make the string reported
4163                let s = f"Value: {rep}";
4164                return s;
4165            }
4166        "#);
4167
4168        match result {
4169            Ok(Value::Evidential {
4170                evidence: Evidence::Reported,
4171                value,
4172            }) => {
4173                // The inner value should be a string
4174                assert!(matches!(*value, Value::String(_)));
4175            }
4176            Ok(other) => panic!("Expected Evidential Reported, got {:?}", other),
4177            Err(e) => panic!("Error: {:?}", e),
4178        }
4179    }
4180
4181    #[test]
4182    fn test_interpolation_worst_evidence_wins() {
4183        // When multiple evidential values are interpolated, the worst evidence level wins
4184        let result = run(r#"
4185            fn main() {
4186                let k = known(1);         // Known is best
4187                let u = uncertain(2);     // Uncertain is worse
4188
4189                // Combining known and uncertain should yield uncertain
4190                let s = f"{k} and {u}";
4191                return s;
4192            }
4193        "#);
4194
4195        match result {
4196            Ok(Value::Evidential {
4197                evidence: Evidence::Uncertain,
4198                ..
4199            }) => (),
4200            Ok(other) => panic!("Expected Evidential Uncertain, got {:?}", other),
4201            Err(e) => panic!("Error: {:?}", e),
4202        }
4203    }
4204
4205    #[test]
4206    fn test_interpolation_no_evidential_plain_string() {
4207        // When no evidential values are interpolated, the result is a plain string
4208        let result = run(r#"
4209            fn main() {
4210                let x = 42;
4211                let s = f"Value: {x}";
4212                return s;
4213            }
4214        "#);
4215
4216        match result {
4217            Ok(Value::String(s)) => {
4218                assert_eq!(*s, "Value: 42");
4219            }
4220            Ok(other) => panic!("Expected plain String, got {:?}", other),
4221            Err(e) => panic!("Error: {:?}", e),
4222        }
4223    }
4224}