1use 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#[derive(Clone)]
16pub enum Value {
17 Null,
19 Bool(bool),
21 Int(i64),
23 Float(f64),
25 String(Rc<String>),
27 Char(char),
29 Array(Rc<RefCell<Vec<Value>>>),
31 Tuple(Rc<Vec<Value>>),
33 Struct {
35 name: String,
36 fields: Rc<RefCell<HashMap<String, Value>>>,
37 },
38 Variant {
40 enum_name: String,
41 variant_name: String,
42 fields: Option<Rc<Vec<Value>>>,
43 },
44 Function(Rc<Function>),
46 BuiltIn(Rc<BuiltInFn>),
48 Ref(Rc<RefCell<Value>>),
50 Infinity,
52 Empty,
53 Evidential {
55 value: Box<Value>,
56 evidence: Evidence,
57 },
58 Affective {
60 value: Box<Value>,
61 affect: RuntimeAffect,
62 },
63 Map(Rc<RefCell<HashMap<String, Value>>>),
65 Set(Rc<RefCell<std::collections::HashSet<String>>>),
67 Channel(Arc<ChannelInner>),
69 ThreadHandle(Arc<Mutex<Option<JoinHandle<Value>>>>),
71 Actor(Arc<ActorInner>),
73 Future(Rc<RefCell<FutureInner>>),
75}
76
77#[derive(Clone)]
79pub enum FutureState {
80 Pending,
82 Running,
84 Ready(Box<Value>),
86 Failed(String),
88}
89
90pub struct FutureInner {
92 pub state: FutureState,
94 pub computation: Option<FutureComputation>,
96 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#[derive(Clone)]
112pub enum FutureComputation {
113 Immediate(Box<Value>),
115 Timer(std::time::Duration),
117 Lazy {
119 func: Rc<Function>,
120 args: Vec<Value>,
121 },
122 Join(Vec<Rc<RefCell<FutureInner>>>),
124 Race(Vec<Rc<RefCell<FutureInner>>>),
126}
127
128pub 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 panic!("Channels cannot be cloned directly - use channel_clone()")
139 }
140}
141
142pub struct ActorInner {
145 pub name: String,
146 pub message_queue: Mutex<Vec<(String, String)>>, pub message_count: std::sync::atomic::AtomicUsize,
148}
149
150#[derive(Debug, Clone, Copy, PartialEq, Eq)]
152pub enum Evidence {
153 Known, Uncertain, Reported, Paradox, }
158
159#[derive(Debug, Clone, PartialEq)]
161pub struct RuntimeAffect {
162 pub sentiment: Option<RuntimeSentiment>,
163 pub sarcasm: bool, 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, Negative, Neutral, }
176
177#[derive(Debug, Clone, Copy, PartialEq, Eq)]
178pub enum RuntimeIntensity {
179 Up, Down, Max, }
183
184#[derive(Debug, Clone, Copy, PartialEq, Eq)]
185pub enum RuntimeFormality {
186 Formal, Informal, }
189
190#[derive(Debug, Clone, Copy, PartialEq, Eq)]
191pub enum RuntimeEmotion {
192 Joy, Sadness, Anger, Fear, Surprise, Love, }
199
200#[derive(Debug, Clone, Copy, PartialEq, Eq)]
201pub enum RuntimeConfidence {
202 High, Medium, Low, }
206
207pub struct Function {
209 pub name: Option<String>,
210 pub params: Vec<String>,
211 pub body: Expr,
212 pub closure: Rc<RefCell<Environment>>,
213}
214
215pub struct BuiltInFn {
217 pub name: String,
218 pub arity: Option<usize>, 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 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#[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#[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
501pub type EvalResult = Result<Value, EvalError>;
503
504#[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#[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
586pub struct Interpreter {
588 pub globals: Rc<RefCell<Environment>>,
590 pub environment: Rc<RefCell<Environment>>,
592 pub types: HashMap<String, TypeDef>,
594 pub output: Vec<String>,
596 return_value: Option<Value>,
598}
599
600pub 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 interp.register_builtins();
621
622 interp
623 }
624
625 fn register_builtins(&mut self) {
626 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 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 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 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 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 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 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 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), }
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 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 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 match evidentiality {
903 Some(Evidentiality::Uncertain) => {
904 self.unwrap_result_or_option(awaited, true, false)
906 }
907 Some(Evidentiality::Known) => {
908 self.unwrap_result_or_option(awaited, true, true)
910 }
911 Some(Evidentiality::Reported) | Some(Evidentiality::Paradox) => {
912 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 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 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 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 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 combined_evidence = Self::combine_evidence(
1003 combined_evidence,
1004 Self::extract_evidence(&value),
1005 );
1006
1007 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 let display_value = Self::unwrap_value(&value);
1017 result.push_str(&format!("{}", display_value));
1018 }
1019 }
1020 }
1021
1022 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 Ok(Value::String(Rc::new(s.clone())))
1036 }
1037 Literal::SigilStringRoute(s) => {
1038 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)), }
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), NumBase::Octal => (8, 2), NumBase::Decimal => (10, 0),
1056 NumBase::Hex => (16, 2), NumBase::Vigesimal => (20, 2), NumBase::Sexagesimal => (60, 2), NumBase::Duodecimal => (12, 2), 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 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 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 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 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 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 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 let env = Rc::new(RefCell::new(Environment::with_parent(func.closure.clone())));
1274
1275 for (param, value) in func.params.iter().zip(args) {
1277 env.borrow_mut().define(param.clone(), value);
1278 }
1279
1280 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 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 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 other => Ok(other),
1324 }
1325 }
1326
1327 fn unwrap_result_or_option(
1331 &self,
1332 value: Value,
1333 propagate_errors: bool,
1334 panic_on_error: bool,
1335 ) -> Result<Value, RuntimeError> {
1336 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 fn poll_future(&mut self, fut: &mut FutureInner) -> Result<Value, RuntimeError> {
1378 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 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 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 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 std::thread::sleep(duration);
1411 fut.state = FutureState::Ready(Box::new(Value::Null));
1412 Ok(Value::Null)
1413 }
1414 FutureComputation::Lazy { func, args } => {
1415 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 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 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 Err(RuntimeError::new("No futures ready in race"))
1452 }
1453 }
1454 } else {
1455 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 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 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 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 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 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 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 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 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 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 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 let first = &segments[0];
1859 let mut value = if let Some(args) = &first.args {
1860 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 self.environment
1869 .borrow()
1870 .get(&first.name.name)
1871 .ok_or_else(|| RuntimeError::new(format!("undefined: {}", first.name.name)))?
1872 };
1873
1874 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 value = self.call_incorporation_method(&value, &segment.name.name, arg_values)?;
1889 }
1890
1891 Ok(value)
1892 }
1893
1894 fn call_incorporation_method(
1897 &mut self,
1898 receiver: &Value,
1899 method_name: &str,
1900 args: Vec<Value>,
1901 ) -> Result<Value, RuntimeError> {
1902 match (receiver, method_name) {
1904 (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 (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 (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 (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 _ => {
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 fn call_function_by_name(
2020 &mut self,
2021 name: &str,
2022 args: Vec<Value>,
2023 ) -> Result<Value, RuntimeError> {
2024 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 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 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 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 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 self.sum_values(value)
2129 }
2130 PipeOp::ReduceProd => {
2131 self.product_values(value)
2133 }
2134 PipeOp::ReduceMin => {
2135 self.min_values(value)
2137 }
2138 PipeOp::ReduceMax => {
2139 self.max_values(value)
2141 }
2142 PipeOp::ReduceConcat => {
2143 self.concat_values(value)
2145 }
2146 PipeOp::ReduceAll => {
2147 self.all_values(value)
2149 }
2150 PipeOp::ReduceAny => {
2151 self.any_values(value)
2153 }
2154 PipeOp::Match(arms) => {
2155 for arm in arms {
2157 if self.pattern_matches(&arm.pattern, &value)? {
2158 let prev_env = self.environment.clone();
2160 self.environment =
2161 Rc::new(RefCell::new(Environment::with_parent(prev_env.clone())));
2162
2163 self.bind_pattern(&arm.pattern, value.clone())?;
2165
2166 self.environment
2168 .borrow_mut()
2169 .define("_".to_string(), value.clone());
2170
2171 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 self.environment = prev_env;
2186 }
2187 }
2188 Err(RuntimeError::new("No pattern matched in pipe match"))
2189 }
2190 PipeOp::TryMap(mapper) => {
2191 match &value {
2193 Value::Struct { name, fields } if name == "Ok" || name.ends_with("::Ok") => {
2195 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 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 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 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 _ => 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 match name.name.as_str() {
2253 "collect" => Ok(value), "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 self.await_value(value)
2326 }
2327 PipeOp::First => {
2329 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 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 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 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 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 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 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 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 match inner_op.as_ref() {
2531 PipeOp::Transform(body) => {
2532 let num_threads = std::thread::available_parallelism()
2534 .map(|p| p.get())
2535 .unwrap_or(4)
2536 .min(len);
2537
2538 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 let _body_str = format!("{:?}", body);
2546
2547 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 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 drop(arr_ref);
2579 self.apply_pipe_op(Value::Array(arr), inner_op)
2580 }
2581 }
2582 }
2583 _ => {
2584 self.apply_pipe_op(value, inner_op)
2586 }
2587 }
2588 }
2589 PipeOp::Gpu(inner_op) => {
2590 match value {
2597 Value::Array(arr) => {
2598 #[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 PipeOp::Send(data_expr) => {
2618 let data = self.evaluate(data_expr)?;
2621
2622 let response = self.protocol_send(&value, &data)?;
2625
2626 Ok(self.wrap_reported(response))
2628 }
2629
2630 PipeOp::Recv => {
2631 let response = self.protocol_recv(&value)?;
2636
2637 Ok(self.wrap_reported(response))
2639 }
2640
2641 PipeOp::Stream(handler_expr) => {
2642 let handler = self.evaluate(handler_expr)?;
2644
2645 let stream = self.protocol_stream(&value, &handler)?;
2648 Ok(stream)
2649 }
2650
2651 PipeOp::Connect(config_expr) => {
2652 let config = match config_expr {
2654 Some(expr) => Some(self.evaluate(expr)?),
2655 None => None,
2656 };
2657
2658 let connection = self.protocol_connect(&value, config.as_ref())?;
2660 Ok(connection)
2661 }
2662
2663 PipeOp::Close => {
2664 self.protocol_close(&value)?;
2666 Ok(Value::Null)
2667 }
2668
2669 PipeOp::Header {
2670 name,
2671 value: value_expr,
2672 } => {
2673 let header_name = self.evaluate(name)?;
2675 let header_value = self.evaluate(value_expr)?;
2676
2677 self.protocol_add_header(value, &header_name, &header_value)
2679 }
2680
2681 PipeOp::Body(data_expr) => {
2682 let body_data = self.evaluate(data_expr)?;
2684
2685 self.protocol_set_body(value, &body_data)
2687 }
2688
2689 PipeOp::Timeout(ms_expr) => {
2690 let ms = self.evaluate(ms_expr)?;
2692
2693 self.protocol_set_timeout(value, &ms)
2695 }
2696
2697 PipeOp::Retry { count, strategy } => {
2698 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 self.protocol_set_retry(value, &retry_count, retry_strategy.as_ref())
2707 }
2708
2709 PipeOp::Validate {
2713 predicate,
2714 target_evidence,
2715 } => {
2716 let predicate_result = match predicate.as_ref() {
2719 Expr::Closure { params, body, .. } => {
2720 if let Some(param) = params.first() {
2721 let param_name = match ¶m.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 match predicate_result {
2736 Value::Bool(true) => {
2737 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 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 #[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 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 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 PipeOp::Also(func) => {
2845 match func.as_ref() {
2848 Expr::Closure { params, body, .. } => {
2849 if let Some(param) = params.first() {
2850 let param_name = match ¶m.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 let _ = self.evaluate(body);
2860 }
2861 _ => {
2862 let _ = self.evaluate(func);
2864 }
2865 }
2866 Ok(value)
2868 }
2869
2870 PipeOp::Apply(func) => {
2871 match func.as_ref() {
2874 Expr::Closure { params, body, .. } => {
2875 if let Some(param) = params.first() {
2876 let param_name = match ¶m.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 let _ = self.evaluate(body);
2886 }
2887 _ => {
2888 let _ = self.evaluate(func);
2889 }
2890 }
2891 Ok(value)
2893 }
2894
2895 PipeOp::TakeIf(predicate) => {
2896 let predicate_result = match predicate.as_ref() {
2898 Expr::Closure { params, body, .. } => {
2899 if let Some(param) = params.first() {
2900 let param_name = match ¶m.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 let predicate_result = match predicate.as_ref() {
2931 Expr::Closure { params, body, .. } => {
2932 if let Some(param) = params.first() {
2933 let param_name = match ¶m.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 match func.as_ref() {
2964 Expr::Closure { params, body, .. } => {
2965 if let Some(param) = params.first() {
2966 let param_name = match ¶m.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 PipeOp::All(pred) => {
2984 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 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 self.environment.borrow_mut().define("_".to_string(), value);
3024 self.evaluate(f)
3025 }
3026
3027 PipeOp::Zip(other_expr) => {
3028 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 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 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 let _ = var_expr;
3093 Ok(Value::Float(0.0)) }
3095
3096 PipeOp::SortAsc => {
3097 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 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 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 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 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 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 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 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 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 fn wrap_reported(&self, value: Value) -> Value {
3254 Value::Evidential {
3255 value: Box::new(value),
3256 evidence: Evidence::Reported,
3257 }
3258 }
3259
3260 fn protocol_send(&mut self, connection: &Value, data: &Value) -> Result<Value, RuntimeError> {
3262 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 #[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 #[cfg(debug_assertions)]
3287 eprintln!("[WebSocket] Would send message: {:?}", data);
3288 Ok(Value::Bool(true)) }
3290 "grpc" => {
3291 #[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)); 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 #[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 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 #[cfg(debug_assertions)]
3338 eprintln!("[WebSocket] Would receive message");
3339 Ok(Value::String(Rc::new("received message".to_string())))
3340 }
3341 "kafka" => {
3342 #[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 #[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 fn protocol_stream(
3387 &mut self,
3388 connection: &Value,
3389 _handler: &Value,
3390 ) -> Result<Value, RuntimeError> {
3391 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 fn extract_evidence(value: &Value) -> Option<Evidence> {
3923 match value {
3924 Value::Evidential { evidence, .. } => Some(*evidence),
3925 _ => None,
3926 }
3927 }
3928
3929 fn extract_affect(value: &Value) -> Option<&RuntimeAffect> {
3931 match value {
3932 Value::Affective { affect, .. } => Some(affect),
3933 _ => None,
3934 }
3935 }
3936
3937 fn affect_to_evidence(affect: &RuntimeAffect) -> Option<Evidence> {
3941 if affect.sarcasm {
3943 return Some(Evidence::Uncertain);
3944 }
3945
3946 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 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 fn unwrap_evidential(value: &Value) -> &Value {
3978 match value {
3979 Value::Evidential { value: inner, .. } => Self::unwrap_evidential(inner),
3980 _ => value,
3981 }
3982 }
3983
3984 fn unwrap_affective(value: &Value) -> &Value {
3986 match value {
3987 Value::Affective { value: inner, .. } => Self::unwrap_affective(inner),
3988 _ => value,
3989 }
3990 }
3991
3992 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)))); }
4153
4154 #[test]
4155 fn test_interpolation_evidentiality_propagation() {
4156 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 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 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 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}