1use crate::ast::*;
6use crate::span::Span;
7use std::cell::RefCell;
8use std::collections::{HashMap, HashSet};
9use std::fmt;
10use std::path::PathBuf;
11use std::rc::Rc;
12use std::sync::{mpsc, Arc, Mutex};
13use std::thread::JoinHandle;
14
15#[cfg(feature = "websocket")]
17use crate::websocket;
18
19#[derive(Clone)]
21pub enum Value {
22 Null,
24 Bool(bool),
26 Int(i64),
28 Float(f64),
30 String(Rc<String>),
32 Char(char),
34 Array(Rc<RefCell<Vec<Value>>>),
36 Tuple(Rc<Vec<Value>>),
38 Struct {
40 name: String,
41 fields: Rc<RefCell<HashMap<String, Value>>>,
42 },
43 Variant {
45 enum_name: String,
46 variant_name: String,
47 fields: Option<Rc<Vec<Value>>>,
48 },
49 Function(Rc<Function>),
51 BuiltIn(Rc<BuiltInFn>),
53 Ref(Rc<RefCell<Value>>),
55 Infinity,
57 Empty,
58 Evidential {
60 value: Box<Value>,
61 evidence: Evidence,
62 },
63 Affective {
65 value: Box<Value>,
66 affect: RuntimeAffect,
67 },
68 Map(Rc<RefCell<HashMap<String, Value>>>),
70 Set(Rc<RefCell<std::collections::HashSet<String>>>),
72 Channel(Arc<ChannelInner>),
74 ThreadHandle(Arc<Mutex<Option<JoinHandle<Value>>>>),
76 Actor(Arc<ActorInner>),
78 Future(Rc<RefCell<FutureInner>>),
80 VariantConstructor {
82 enum_name: String,
83 variant_name: String,
84 },
85 DefaultConstructor {
87 type_name: String,
88 },
89 Range {
91 start: Option<i64>,
92 end: Option<i64>,
93 inclusive: bool,
94 },
95}
96
97#[derive(Clone)]
99pub enum FutureState {
100 Pending,
102 Running,
104 Ready(Box<Value>),
106 Failed(String),
108}
109
110pub struct FutureInner {
112 pub state: FutureState,
114 pub computation: Option<FutureComputation>,
116 pub complete_at: Option<std::time::Instant>,
118}
119
120impl Clone for FutureInner {
121 fn clone(&self) -> Self {
122 FutureInner {
123 state: self.state.clone(),
124 computation: self.computation.clone(),
125 complete_at: self.complete_at,
126 }
127 }
128}
129
130#[derive(Clone)]
132pub enum FutureComputation {
133 Immediate(Box<Value>),
135 Timer(std::time::Duration),
137 Lazy {
139 func: Rc<Function>,
140 args: Vec<Value>,
141 },
142 Join(Vec<Rc<RefCell<FutureInner>>>),
144 Race(Vec<Rc<RefCell<FutureInner>>>),
146}
147
148pub struct ChannelInner {
150 pub sender: Mutex<mpsc::Sender<Value>>,
151 pub receiver: Mutex<mpsc::Receiver<Value>>,
152}
153
154impl Clone for ChannelInner {
155 fn clone(&self) -> Self {
156 panic!("Channels cannot be cloned directly - use channel_clone()")
159 }
160}
161
162pub struct ActorInner {
165 pub name: String,
166 pub message_queue: Mutex<Vec<(String, String)>>, pub message_count: std::sync::atomic::AtomicUsize,
168}
169
170#[derive(Debug, Clone, Copy, PartialEq, Eq)]
172pub enum Evidence {
173 Known, Uncertain, Reported, Predicted, Paradox, }
179
180#[derive(Debug, Clone, PartialEq)]
182pub struct RuntimeAffect {
183 pub sentiment: Option<RuntimeSentiment>,
184 pub sarcasm: bool, pub intensity: Option<RuntimeIntensity>,
186 pub formality: Option<RuntimeFormality>,
187 pub emotion: Option<RuntimeEmotion>,
188 pub confidence: Option<RuntimeConfidence>,
189}
190
191#[derive(Debug, Clone, Copy, PartialEq, Eq)]
192pub enum RuntimeSentiment {
193 Positive, Negative, Neutral, }
197
198#[derive(Debug, Clone, Copy, PartialEq, Eq)]
199pub enum RuntimeIntensity {
200 Up, Down, Max, }
204
205#[derive(Debug, Clone, Copy, PartialEq, Eq)]
206pub enum RuntimeFormality {
207 Formal, Informal, }
210
211#[derive(Debug, Clone, Copy, PartialEq, Eq)]
212pub enum RuntimeEmotion {
213 Joy, Sadness, Anger, Fear, Surprise, Love, }
220
221#[derive(Debug, Clone, Copy, PartialEq, Eq)]
222pub enum RuntimeConfidence {
223 High, Medium, Low, }
227
228pub struct Function {
230 pub name: Option<String>,
231 pub params: Vec<String>,
232 pub body: Expr,
233 pub closure: Rc<RefCell<Environment>>,
234 pub generic_params: Vec<String>,
236}
237
238pub struct BuiltInFn {
240 pub name: String,
241 pub arity: Option<usize>, pub func: fn(&mut Interpreter, Vec<Value>) -> Result<Value, RuntimeError>,
243}
244
245impl fmt::Debug for Value {
246 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247 match self {
248 Value::Null => write!(f, "null"),
249 Value::Bool(b) => write!(f, "{}", b),
250 Value::Int(n) => write!(f, "{}", n),
251 Value::Float(n) => write!(f, "{}", n),
252 Value::String(s) => write!(f, "\"{}\"", s),
253 Value::Char(c) => write!(f, "'{}'", c),
254 Value::Array(arr) => {
255 let arr = arr.borrow();
256 write!(f, "[")?;
257 for (i, v) in arr.iter().enumerate() {
258 if i > 0 {
259 write!(f, ", ")?;
260 }
261 write!(f, "{:?}", v)?;
262 }
263 write!(f, "]")
264 }
265 Value::Tuple(vals) => {
266 write!(f, "(")?;
267 for (i, v) in vals.iter().enumerate() {
268 if i > 0 {
269 write!(f, ", ")?;
270 }
271 write!(f, "{:?}", v)?;
272 }
273 write!(f, ")")
274 }
275 Value::Struct { name, fields } => {
276 write!(f, "{} {{ ", name)?;
277 let fields = fields.borrow();
278 for (i, (k, v)) in fields.iter().enumerate() {
279 if i > 0 {
280 write!(f, ", ")?;
281 }
282 write!(f, "{}: {:?}", k, v)?;
283 }
284 write!(f, " }}")
285 }
286 Value::Variant {
287 enum_name,
288 variant_name,
289 fields,
290 } => {
291 write!(f, "{}::{}", enum_name, variant_name)?;
292 if let Some(fields) = fields {
293 write!(f, "(")?;
294 for (i, v) in fields.iter().enumerate() {
295 if i > 0 {
296 write!(f, ", ")?;
297 }
298 write!(f, "{:?}", v)?;
299 }
300 write!(f, ")")?;
301 }
302 Ok(())
303 }
304 Value::Function(func) => {
305 write!(f, "<fn {}>", func.name.as_deref().unwrap_or("anonymous"))
306 }
307 Value::BuiltIn(b) => write!(f, "<builtin {}>", b.name),
308 Value::Ref(r) => write!(f, "&{:?}", r.borrow()),
309 Value::Infinity => write!(f, "∞"),
310 Value::Empty => write!(f, "∅"),
311 Value::Evidential { value, evidence } => {
312 write!(f, "{:?}", value)?;
313 match evidence {
314 Evidence::Known => write!(f, "!"),
315 Evidence::Uncertain => write!(f, "?"),
316 Evidence::Reported => write!(f, "~"),
317 Evidence::Predicted => write!(f, "◊"),
318 Evidence::Paradox => write!(f, "‽"),
319 }
320 }
321 Value::Map(map) => {
322 let map = map.borrow();
323 write!(f, "{{")?;
324 for (i, (k, v)) in map.iter().enumerate() {
325 if i > 0 {
326 write!(f, ", ")?;
327 }
328 write!(f, "{:?}: {:?}", k, v)?;
329 }
330 write!(f, "}}")
331 }
332 Value::Set(set) => {
333 let set = set.borrow();
334 write!(f, "Set{{")?;
335 for (i, k) in set.iter().enumerate() {
336 if i > 0 {
337 write!(f, ", ")?;
338 }
339 write!(f, "{:?}", k)?;
340 }
341 write!(f, "}}")
342 }
343 Value::Channel(_) => write!(f, "<channel>"),
344 Value::ThreadHandle(_) => write!(f, "<thread>"),
345 Value::Actor(actor) => write!(f, "<actor {}>", actor.name),
346 Value::Future(fut) => {
347 let fut = fut.borrow();
348 match &fut.state {
349 FutureState::Pending => write!(f, "<future pending>"),
350 FutureState::Running => write!(f, "<future running>"),
351 FutureState::Ready(v) => write!(f, "<future ready: {:?}>", v),
352 FutureState::Failed(e) => write!(f, "<future failed: {}>", e),
353 }
354 }
355 Value::Affective { value, affect } => {
356 write!(f, "{:?}", value)?;
357 if let Some(s) = &affect.sentiment {
358 match s {
359 RuntimeSentiment::Positive => write!(f, "⊕")?,
360 RuntimeSentiment::Negative => write!(f, "⊖")?,
361 RuntimeSentiment::Neutral => write!(f, "⊜")?,
362 }
363 }
364 if affect.sarcasm {
365 write!(f, "⸮")?;
366 }
367 if let Some(i) = &affect.intensity {
368 match i {
369 RuntimeIntensity::Up => write!(f, "↑")?,
370 RuntimeIntensity::Down => write!(f, "↓")?,
371 RuntimeIntensity::Max => write!(f, "⇈")?,
372 }
373 }
374 if let Some(fo) = &affect.formality {
375 match fo {
376 RuntimeFormality::Formal => write!(f, "♔")?,
377 RuntimeFormality::Informal => write!(f, "♟")?,
378 }
379 }
380 if let Some(e) = &affect.emotion {
381 match e {
382 RuntimeEmotion::Joy => write!(f, "☺")?,
383 RuntimeEmotion::Sadness => write!(f, "☹")?,
384 RuntimeEmotion::Anger => write!(f, "⚡")?,
385 RuntimeEmotion::Fear => write!(f, "❄")?,
386 RuntimeEmotion::Surprise => write!(f, "✦")?,
387 RuntimeEmotion::Love => write!(f, "♡")?,
388 }
389 }
390 if let Some(c) = &affect.confidence {
391 match c {
392 RuntimeConfidence::High => write!(f, "◉")?,
393 RuntimeConfidence::Medium => write!(f, "◎")?,
394 RuntimeConfidence::Low => write!(f, "○")?,
395 }
396 }
397 Ok(())
398 }
399 Value::VariantConstructor {
400 enum_name,
401 variant_name,
402 } => {
403 write!(f, "<constructor {}::{}>", enum_name, variant_name)
404 }
405 Value::DefaultConstructor { type_name } => {
406 write!(f, "<default {}>", type_name)
407 }
408 Value::Range {
409 start,
410 end,
411 inclusive,
412 } => match (start, end) {
413 (Some(s), Some(e)) => {
414 if *inclusive {
415 write!(f, "{}..={}", s, e)
416 } else {
417 write!(f, "{}..{}", s, e)
418 }
419 }
420 (Some(s), None) => write!(f, "{}..", s),
421 (None, Some(e)) => {
422 if *inclusive {
423 write!(f, "..={}", e)
424 } else {
425 write!(f, "..{}", e)
426 }
427 }
428 (None, None) => write!(f, ".."),
429 },
430 }
431 }
432}
433
434impl fmt::Display for Value {
435 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
436 match self {
437 Value::Null => write!(f, "null"),
438 Value::Bool(b) => write!(f, "{}", b),
439 Value::Int(n) => write!(f, "{}", n),
440 Value::Float(n) => {
441 if n.fract() == 0.0 && n.is_finite() {
444 write!(f, "{}", *n as i64)
445 } else {
446 write!(f, "{}", n)
447 }
448 }
449 Value::String(s) => write!(f, "{}", s),
450 Value::Char(c) => write!(f, "{}", c),
451 Value::Array(arr) => {
452 let arr = arr.borrow();
453 write!(f, "[")?;
454 for (i, v) in arr.iter().enumerate() {
455 if i > 0 {
456 write!(f, ", ")?;
457 }
458 write!(f, "{}", v)?;
459 }
460 write!(f, "]")
461 }
462 Value::Evidential { value, .. } => write!(f, "{}", value),
463 Value::Affective { value, affect } => {
464 let mut suffix = String::new();
466 if let Some(sent) = &affect.sentiment {
467 suffix.push(match sent {
468 RuntimeSentiment::Positive => '⊕',
469 RuntimeSentiment::Negative => '⊖',
470 RuntimeSentiment::Neutral => '⊜',
471 });
472 }
473 if affect.sarcasm {
474 suffix.push('⸮');
475 }
476 if let Some(int) = &affect.intensity {
477 suffix.push(match int {
478 RuntimeIntensity::Up => '↑',
479 RuntimeIntensity::Down => '↓',
480 RuntimeIntensity::Max => '⇈',
481 });
482 }
483 if let Some(form) = &affect.formality {
484 suffix.push(match form {
485 RuntimeFormality::Formal => '♔',
486 RuntimeFormality::Informal => '♟',
487 });
488 }
489 if let Some(emo) = &affect.emotion {
490 suffix.push(match emo {
491 RuntimeEmotion::Joy => '☺',
492 RuntimeEmotion::Sadness => '☹',
493 RuntimeEmotion::Anger => '⚡',
494 RuntimeEmotion::Fear => '❄',
495 RuntimeEmotion::Surprise => '✦',
496 RuntimeEmotion::Love => '♡',
497 });
498 }
499 if let Some(conf) = &affect.confidence {
500 suffix.push(match conf {
501 RuntimeConfidence::High => '◉',
502 RuntimeConfidence::Medium => '◎',
503 RuntimeConfidence::Low => '○',
504 });
505 }
506 write!(f, "{}{}", value, suffix)
507 }
508 Value::Struct { name, fields } if name == "Cbit" => {
510 let fields = fields.borrow();
511 match fields.get("__value__") {
512 Some(Value::Bool(true)) => write!(f, "1"),
513 Some(Value::Bool(false)) => write!(f, "0"),
514 _ => write!(f, "Cbit(invalid)"),
515 }
516 }
517 Value::Struct { name, fields } if name == "Qubit" => {
518 let fields = fields.borrow();
520 if let Some(Value::Float(alpha)) = fields.get("__alpha_real__") {
521 if *alpha >= 0.999 {
522 write!(f, "|0⟩")
523 } else if let Some(Value::Float(beta)) = fields.get("__beta_real__") {
524 if *beta >= 0.999 {
525 write!(f, "|1⟩")
526 } else {
527 write!(f, "|ψ⟩")
528 }
529 } else {
530 write!(f, "|ψ⟩")
531 }
532 } else {
533 write!(f, "|ψ⟩")
534 }
535 }
536 Value::Struct { name, fields } if name == "Tensor" => {
537 let fields = fields.borrow();
539 if let Some(Value::Array(data)) = fields.get("data") {
540 let data = data.borrow();
541 if data.len() <= 10 {
542 write!(f, "Tensor([")?;
543 for (i, v) in data.iter().enumerate() {
544 if i > 0 { write!(f, ", ")?; }
545 write!(f, "{}", v)?;
546 }
547 write!(f, "])")
548 } else {
549 write!(f, "Tensor([{} elements])", data.len())
550 }
551 } else if let Some(Value::Float(val)) = fields.get("_value") {
552 write!(f, "Tensor({})", val)
553 } else {
554 write!(f, "Tensor(...)")
555 }
556 }
557 _ => write!(f, "{:?}", self),
558 }
559 }
560}
561
562impl Value {
563 pub fn as_tensor_scalar(&self) -> Option<f64> {
567 match self {
568 Value::Struct { name, fields } if name == "Tensor" => {
569 tensor_scalar_from_fields(&fields.borrow())
570 }
571 Value::Float(f) => Some(*f),
572 Value::Int(n) => Some(*n as f64),
573 _ => None,
574 }
575 }
576
577 pub fn as_tensor_data(&self) -> Option<Vec<f64>> {
580 match self {
581 Value::Struct { name, fields } if name == "Tensor" => {
582 tensor_data_from_fields(&fields.borrow())
583 }
584 _ => None,
585 }
586 }
587
588 pub fn as_tensor_shape(&self) -> Option<Vec<usize>> {
591 match self {
592 Value::Struct { name, fields } if name == "Tensor" => {
593 tensor_shape_from_fields(&fields.borrow())
594 }
595 _ => None,
596 }
597 }
598}
599
600fn tensor_scalar_from_fields(fields: &HashMap<String, Value>) -> Option<f64> {
610 if let Some(val) = fields.get("_value") {
612 match val {
613 Value::Float(f) => return Some(*f),
614 Value::Int(n) => return Some(*n as f64),
615 _ => {}
616 }
617 }
618 let data_field = fields.get("__data__").or_else(|| fields.get("data"));
620 if let Some(Value::Array(arr)) = data_field {
621 if let Some(first) = arr.borrow().first() {
622 match first {
623 Value::Float(f) => return Some(*f),
624 Value::Int(n) => return Some(*n as f64),
625 _ => {}
626 }
627 }
628 }
629 None
630}
631
632fn tensor_data_from_fields(fields: &HashMap<String, Value>) -> Option<Vec<f64>> {
635 let arr = fields.get("__data__").or_else(|| fields.get("data"));
636 if let Some(Value::Array(arr)) = arr {
637 Some(
638 arr.borrow()
639 .iter()
640 .map(|v| match v {
641 Value::Float(f) => *f,
642 Value::Int(n) => *n as f64,
643 _ => 0.0,
644 })
645 .collect(),
646 )
647 } else {
648 None
649 }
650}
651
652fn tensor_shape_from_fields(fields: &HashMap<String, Value>) -> Option<Vec<usize>> {
655 let arr = fields.get("__shape__").or_else(|| fields.get("shape"));
656 if let Some(Value::Array(arr)) = arr {
657 Some(
658 arr.borrow()
659 .iter()
660 .map(|v| match v {
661 Value::Int(n) => *n as usize,
662 _ => 0,
663 })
664 .collect(),
665 )
666 } else {
667 None
668 }
669}
670
671use crate::ast::{Item, SourceFile, StructFields, Visibility as AstVisibility};
676use crate::span::Spanned;
677
678fn ast_to_value_source_file(sf: &SourceFile) -> Value {
680 let mut fields = HashMap::new();
681
682 let items: Vec<Value> = sf
684 .items
685 .iter()
686 .map(|item| ast_to_value_item(item))
687 .collect();
688 fields.insert(
689 "items".to_string(),
690 Value::Array(Rc::new(RefCell::new(items))),
691 );
692 fields.insert("item_count".to_string(), Value::Int(sf.items.len() as i64));
693
694 Value::Variant {
696 enum_name: "Result".to_string(),
697 variant_name: "Ok".to_string(),
698 fields: Some(Rc::new(vec![Value::Struct {
699 name: "SourceFile".to_string(),
700 fields: Rc::new(RefCell::new(fields)),
701 }])),
702 }
703}
704
705fn ast_to_value_item(item: &Spanned<Item>) -> Value {
707 let mut fields = HashMap::new();
708
709 fields.insert("start".to_string(), Value::Int(item.span.start as i64));
711 fields.insert("end".to_string(), Value::Int(item.span.end as i64));
712
713 match &item.node {
715 Item::Function(f) => {
716 fields.insert(
717 "kind".to_string(),
718 Value::String(Rc::new("Function".to_string())),
719 );
720 fields.insert(
721 "name".to_string(),
722 Value::String(Rc::new(f.name.name.clone())),
723 );
724 fields.insert(
725 "visibility".to_string(),
726 Value::String(Rc::new(visibility_to_string(&f.visibility))),
727 );
728 fields.insert("is_async".to_string(), Value::Bool(f.is_async));
729 fields.insert("param_count".to_string(), Value::Int(f.params.len() as i64));
730 fields.insert(
731 "has_return_type".to_string(),
732 Value::Bool(f.return_type.is_some()),
733 );
734
735 let params: Vec<Value> = f
737 .params
738 .iter()
739 .map(|p| {
740 let mut pf = HashMap::new();
741 pf.insert(
742 "type".to_string(),
743 Value::String(Rc::new(format!("{:?}", p.ty))),
744 );
745 Value::Struct {
746 name: "Param".to_string(),
747 fields: Rc::new(RefCell::new(pf)),
748 }
749 })
750 .collect();
751 fields.insert(
752 "params".to_string(),
753 Value::Array(Rc::new(RefCell::new(params))),
754 );
755 }
756 Item::Struct(s) => {
757 fields.insert(
758 "kind".to_string(),
759 Value::String(Rc::new("Struct".to_string())),
760 );
761 fields.insert(
762 "name".to_string(),
763 Value::String(Rc::new(s.name.name.clone())),
764 );
765 fields.insert(
766 "visibility".to_string(),
767 Value::String(Rc::new(visibility_to_string(&s.visibility))),
768 );
769
770 let (field_count, field_names) = match &s.fields {
772 StructFields::Named(fields_vec) => {
773 let names: Vec<Value> = fields_vec
774 .iter()
775 .map(|f| Value::String(Rc::new(f.name.name.clone())))
776 .collect();
777 (fields_vec.len() as i64, names)
778 }
779 StructFields::Tuple(types) => (types.len() as i64, vec![]),
780 StructFields::Unit => (0, vec![]),
781 };
782 fields.insert("field_count".to_string(), Value::Int(field_count));
783 fields.insert(
784 "fields".to_string(),
785 Value::Array(Rc::new(RefCell::new(field_names))),
786 );
787 }
788 Item::Enum(e) => {
789 fields.insert(
790 "kind".to_string(),
791 Value::String(Rc::new("Enum".to_string())),
792 );
793 fields.insert(
794 "name".to_string(),
795 Value::String(Rc::new(e.name.name.clone())),
796 );
797 fields.insert(
798 "visibility".to_string(),
799 Value::String(Rc::new(visibility_to_string(&e.visibility))),
800 );
801 fields.insert(
802 "variant_count".to_string(),
803 Value::Int(e.variants.len() as i64),
804 );
805
806 let variants: Vec<Value> = e
808 .variants
809 .iter()
810 .map(|v| Value::String(Rc::new(v.name.name.clone())))
811 .collect();
812 fields.insert(
813 "variants".to_string(),
814 Value::Array(Rc::new(RefCell::new(variants))),
815 );
816 }
817 Item::Trait(t) => {
818 fields.insert(
819 "kind".to_string(),
820 Value::String(Rc::new("Trait".to_string())),
821 );
822 fields.insert(
823 "name".to_string(),
824 Value::String(Rc::new(t.name.name.clone())),
825 );
826 fields.insert(
827 "visibility".to_string(),
828 Value::String(Rc::new(visibility_to_string(&t.visibility))),
829 );
830 fields.insert("method_count".to_string(), Value::Int(t.items.len() as i64));
831 }
832 Item::Impl(i) => {
833 fields.insert(
834 "kind".to_string(),
835 Value::String(Rc::new("Impl".to_string())),
836 );
837 if let Some(trait_path) = &i.trait_ {
838 fields.insert(
839 "trait_name".to_string(),
840 Value::String(Rc::new(format!("{:?}", trait_path))),
841 );
842 }
843 fields.insert("method_count".to_string(), Value::Int(i.items.len() as i64));
844 }
845 Item::TypeAlias(t) => {
846 fields.insert(
847 "kind".to_string(),
848 Value::String(Rc::new("TypeAlias".to_string())),
849 );
850 fields.insert(
851 "name".to_string(),
852 Value::String(Rc::new(t.name.name.clone())),
853 );
854 }
855 Item::Module(m) => {
856 fields.insert(
857 "kind".to_string(),
858 Value::String(Rc::new("Module".to_string())),
859 );
860 fields.insert(
861 "name".to_string(),
862 Value::String(Rc::new(m.name.name.clone())),
863 );
864 }
865 Item::Use(u) => {
866 fields.insert(
867 "kind".to_string(),
868 Value::String(Rc::new("Use".to_string())),
869 );
870 fields.insert(
871 "path".to_string(),
872 Value::String(Rc::new(format!("{:?}", u.tree))),
873 );
874 }
875 Item::Const(c) => {
876 fields.insert(
877 "kind".to_string(),
878 Value::String(Rc::new("Const".to_string())),
879 );
880 fields.insert(
881 "name".to_string(),
882 Value::String(Rc::new(c.name.name.clone())),
883 );
884 }
885 Item::Static(s) => {
886 fields.insert(
887 "kind".to_string(),
888 Value::String(Rc::new("Static".to_string())),
889 );
890 fields.insert(
891 "name".to_string(),
892 Value::String(Rc::new(s.name.name.clone())),
893 );
894 }
895 Item::Actor(a) => {
896 fields.insert(
897 "kind".to_string(),
898 Value::String(Rc::new("Actor".to_string())),
899 );
900 fields.insert(
901 "name".to_string(),
902 Value::String(Rc::new(a.name.name.clone())),
903 );
904 }
905 Item::ExternBlock(_) => {
906 fields.insert(
907 "kind".to_string(),
908 Value::String(Rc::new("ExternBlock".to_string())),
909 );
910 }
911 Item::Macro(m) => {
912 fields.insert(
913 "kind".to_string(),
914 Value::String(Rc::new("Macro".to_string())),
915 );
916 fields.insert(
917 "name".to_string(),
918 Value::String(Rc::new(m.name.name.clone())),
919 );
920 }
921 Item::MacroInvocation(m) => {
922 fields.insert(
923 "kind".to_string(),
924 Value::String(Rc::new("MacroInvocation".to_string())),
925 );
926 fields.insert(
927 "path".to_string(),
928 Value::String(Rc::new(format!("{:?}", m.path))),
929 );
930 }
931 Item::Plurality(_) => {
932 fields.insert(
933 "kind".to_string(),
934 Value::String(Rc::new("Plurality".to_string())),
935 );
936 }
937 }
938
939 Value::Struct {
940 name: "Item".to_string(),
941 fields: Rc::new(RefCell::new(fields)),
942 }
943}
944
945fn visibility_to_string(vis: &AstVisibility) -> String {
947 match vis {
948 AstVisibility::Private => "private".to_string(),
949 AstVisibility::Public => "public".to_string(),
950 AstVisibility::Crate => "crate".to_string(),
951 AstVisibility::Super => "super".to_string(),
952 }
953}
954
955#[derive(Debug, Clone, Copy, PartialEq, Eq)]
957pub enum RuntimeErrorCode {
958 DivisionByZero,
960 IndexOutOfBounds,
962 UndefinedVariable,
964 TypeError,
966 InvalidOperation,
968 AssertionFailed,
970 Overflow,
972 StackOverflow,
974 ControlFlowError,
976 LinearTypeViolation,
978 Generic,
980}
981
982impl RuntimeErrorCode {
983 pub fn code(&self) -> &'static str {
984 match self {
985 RuntimeErrorCode::DivisionByZero => "R0001",
986 RuntimeErrorCode::IndexOutOfBounds => "R0002",
987 RuntimeErrorCode::UndefinedVariable => "R0003",
988 RuntimeErrorCode::TypeError => "R0004",
989 RuntimeErrorCode::InvalidOperation => "R0005",
990 RuntimeErrorCode::AssertionFailed => "R0006",
991 RuntimeErrorCode::Overflow => "R0007",
992 RuntimeErrorCode::StackOverflow => "R0008",
993 RuntimeErrorCode::ControlFlowError => "R0009",
994 RuntimeErrorCode::LinearTypeViolation => "R0010",
995 RuntimeErrorCode::Generic => "R0000",
996 }
997 }
998}
999
1000#[derive(Debug)]
1002pub struct RuntimeError {
1003 pub message: String,
1004 pub span: Option<Span>,
1005 pub code: RuntimeErrorCode,
1006}
1007
1008impl RuntimeError {
1009 pub fn new(message: impl Into<String>) -> Self {
1010 Self {
1011 message: message.into(),
1012 span: None,
1013 code: RuntimeErrorCode::Generic,
1014 }
1015 }
1016
1017 pub fn with_span(message: impl Into<String>, span: Span) -> Self {
1018 Self {
1019 message: message.into(),
1020 span: Some(span),
1021 code: RuntimeErrorCode::Generic,
1022 }
1023 }
1024
1025 pub fn with_code(mut self, code: RuntimeErrorCode) -> Self {
1026 self.code = code;
1027 self
1028 }
1029
1030 pub fn division_by_zero() -> Self {
1034 Self::new("division by zero").with_code(RuntimeErrorCode::DivisionByZero)
1035 }
1036
1037 pub fn linear_type_violation(var_name: &str) -> Self {
1039 Self::new(format!(
1040 "linear value '{}' used twice (no-cloning theorem violation)",
1041 var_name
1042 ))
1043 .with_code(RuntimeErrorCode::LinearTypeViolation)
1044 }
1045
1046 pub fn index_out_of_bounds(index: i64, len: usize) -> Self {
1048 Self::new(format!("index {} out of bounds for length {}", index, len))
1049 .with_code(RuntimeErrorCode::IndexOutOfBounds)
1050 }
1051
1052 pub fn undefined_variable(name: &str) -> Self {
1054 Self::new(format!("undefined variable: `{}`", name))
1055 .with_code(RuntimeErrorCode::UndefinedVariable)
1056 }
1057
1058 pub fn type_error(expected: &str, found: &str) -> Self {
1060 Self::new(format!("expected {}, found {}", expected, found))
1061 .with_code(RuntimeErrorCode::TypeError)
1062 }
1063
1064 pub fn invalid_operation(op: &str, context: &str) -> Self {
1066 Self::new(format!("{} is not valid for {}", op, context))
1067 .with_code(RuntimeErrorCode::InvalidOperation)
1068 }
1069
1070 pub fn assertion_failed(msg: Option<&str>) -> Self {
1072 let message = match msg {
1073 Some(m) => format!("assertion failed: {}", m),
1074 None => "assertion failed".to_string(),
1075 };
1076 Self::new(message).with_code(RuntimeErrorCode::AssertionFailed)
1077 }
1078}
1079
1080impl fmt::Display for RuntimeError {
1081 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1082 write!(f, "[{}] Runtime error: {}", self.code.code(), self.message)?;
1083 if let Some(span) = self.span {
1084 write!(f, " at {}", span)?;
1085 }
1086 Ok(())
1087 }
1088}
1089
1090#[derive(Debug, Clone)]
1092pub enum ControlFlow {
1093 Return(Value),
1094 Break(Option<Value>),
1095 Continue,
1096}
1097
1098impl From<ControlFlow> for RuntimeError {
1099 fn from(cf: ControlFlow) -> Self {
1100 match cf {
1101 ControlFlow::Return(_) => RuntimeError::new("return outside function")
1102 .with_code(RuntimeErrorCode::ControlFlowError),
1103 ControlFlow::Break(_) => RuntimeError::new("break outside loop")
1104 .with_code(RuntimeErrorCode::ControlFlowError),
1105 ControlFlow::Continue => RuntimeError::new("continue outside loop")
1106 .with_code(RuntimeErrorCode::ControlFlowError),
1107 }
1108 }
1109}
1110
1111pub type EvalResult = Result<Value, EvalError>;
1113
1114#[derive(Debug)]
1116pub enum EvalError {
1117 Runtime(RuntimeError),
1118 Control(ControlFlow),
1119}
1120
1121impl From<RuntimeError> for EvalError {
1122 fn from(e: RuntimeError) -> Self {
1123 EvalError::Runtime(e)
1124 }
1125}
1126
1127impl From<ControlFlow> for EvalError {
1128 fn from(cf: ControlFlow) -> Self {
1129 EvalError::Control(cf)
1130 }
1131}
1132
1133impl fmt::Display for EvalError {
1134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1135 match self {
1136 EvalError::Runtime(e) => write!(f, "{}", e),
1137 EvalError::Control(cf) => write!(f, "Unexpected control flow: {:?}", cf),
1138 }
1139 }
1140}
1141
1142#[derive(Clone)]
1144pub struct Environment {
1145 values: HashMap<String, Value>,
1146 parent: Option<Rc<RefCell<Environment>>>,
1147}
1148
1149impl Environment {
1150 pub fn new() -> Self {
1151 Self {
1152 values: HashMap::new(),
1153 parent: None,
1154 }
1155 }
1156
1157 pub fn with_parent(parent: Rc<RefCell<Environment>>) -> Self {
1158 Self {
1159 values: HashMap::new(),
1160 parent: Some(parent),
1161 }
1162 }
1163
1164 pub fn define(&mut self, name: String, value: Value) {
1165 self.values.insert(name, value);
1166 }
1167
1168 pub fn get(&self, name: &str) -> Option<Value> {
1169 if let Some(value) = self.values.get(name) {
1170 Some(value.clone())
1171 } else if let Some(ref parent) = self.parent {
1172 parent.borrow().get(name)
1173 } else {
1174 None
1175 }
1176 }
1177
1178 pub fn set(&mut self, name: &str, value: Value) -> Result<(), RuntimeError> {
1179 if self.values.contains_key(name) {
1180 self.values.insert(name.to_string(), value);
1181 Ok(())
1182 } else if let Some(ref parent) = self.parent {
1183 parent.borrow_mut().set(name, value)
1184 } else {
1185 Err(RuntimeError::undefined_variable(name))
1186 }
1187 }
1188
1189 pub fn iter_values(&self) -> impl Iterator<Item = (&String, &Value)> {
1192 self.values.iter()
1193 }
1194
1195 pub fn all_values(&self) -> Vec<(String, Value)> {
1197 let mut values: Vec<(String, Value)> = self.values
1198 .iter()
1199 .map(|(k, v)| (k.clone(), v.clone()))
1200 .collect();
1201 if let Some(ref parent) = self.parent {
1202 values.extend(parent.borrow().all_values());
1203 }
1204 values
1205 }
1206}
1207
1208impl Default for Environment {
1209 fn default() -> Self {
1210 Self::new()
1211 }
1212}
1213
1214#[derive(Default)]
1216pub struct LinearTypeState {
1217 pub consumed: RefCell<HashSet<String>>,
1219 pub vars: RefCell<HashSet<String>>,
1221}
1222
1223#[derive(Default)]
1225pub struct TypeConstructionContext {
1226 pub tensor_shape: RefCell<Option<Vec<i64>>>,
1228 pub struct_generics: RefCell<Option<(String, Vec<i64>)>>,
1230}
1231
1232pub struct Interpreter {
1234 pub globals: Rc<RefCell<Environment>>,
1236 pub environment: Rc<RefCell<Environment>>,
1238 pub types: HashMap<String, TypeDef>,
1240 pub variant_constructors: HashMap<String, (String, String, usize)>,
1242 pub default_structs: HashMap<String, StructDef>,
1244 pub output: Vec<String>,
1246 return_value: Option<Value>,
1248 pub program_args: Option<Vec<String>>,
1250 pub current_module: Option<String>,
1252 pub current_self_type: Option<String>,
1254 pub generic_type_bindings: HashMap<String, String>,
1256 pub current_source_dir: Option<String>,
1258 pub loaded_crates: HashSet<String>,
1260 pub loading_crates: HashSet<String>,
1262 pub project_root: Option<PathBuf>,
1264 pub workspace_members: HashMap<String, PathBuf>,
1266 pub drop_types: HashSet<String>,
1268 pub linear_state: LinearTypeState,
1270 pub mutable_vars: RefCell<HashSet<String>>,
1272 pub var_types: RefCell<HashMap<String, (String, Vec<String>)>>,
1274 pub type_context: TypeConstructionContext,
1276 pub ir_functions: RefCell<Vec<Value>>,
1279 pub ir_traits: RefCell<Vec<Value>>,
1281 pub ir_modules: RefCell<Vec<Value>>,
1283 pub ir_constants: RefCell<Vec<Value>>,
1285 pub ir_impls: RefCell<Vec<Value>>,
1287 pub source_code: RefCell<String>,
1289 pub user_macros: RefCell<HashMap<String, (Vec<String>, String, HashMap<String, String>)>>,
1294 pub source_text: Option<String>,
1297 pub function_spans: HashMap<String, crate::span::Span>,
1299 pub trait_defs: Vec<crate::ast::TraitDef>,
1301 pub impl_blocks: Vec<crate::ast::ImplBlock>,
1303 pub const_defs: Vec<(String, crate::span::Span)>,
1305 pub crate_modules: HashSet<String>,
1307 pub crate_name: Option<String>,
1309 pub crate_alias: Option<String>,
1311 pub const_generic_params: HashMap<String, Vec<String>>,
1314 pub const_generic_deferred_consts: HashMap<String, crate::ast::Expr>,
1317}
1318
1319#[derive(Clone)]
1321pub enum TypeDef {
1322 Struct(StructDef),
1323 Enum(EnumDef),
1324}
1325
1326impl Interpreter {
1327 pub fn new() -> Self {
1328 let globals = Rc::new(RefCell::new(Environment::new()));
1329 let environment = globals.clone();
1330
1331 let mut interp = Self {
1332 globals: globals.clone(),
1333 environment,
1334 types: HashMap::new(),
1335 variant_constructors: HashMap::new(),
1336 default_structs: HashMap::new(),
1337 return_value: None,
1338 output: Vec::new(),
1339 program_args: None,
1340 current_module: None,
1341 current_self_type: None,
1342 generic_type_bindings: HashMap::new(),
1343 current_source_dir: None,
1344 loaded_crates: HashSet::new(),
1345 loading_crates: HashSet::new(),
1346 project_root: None,
1347 workspace_members: HashMap::new(),
1348 drop_types: HashSet::new(),
1349 linear_state: LinearTypeState::default(),
1350 mutable_vars: RefCell::new(HashSet::new()),
1351 var_types: RefCell::new(HashMap::new()),
1352 type_context: TypeConstructionContext::default(),
1353 ir_functions: RefCell::new(Vec::new()),
1354 ir_traits: RefCell::new(Vec::new()),
1355 ir_modules: RefCell::new(Vec::new()),
1356 ir_constants: RefCell::new(Vec::new()),
1357 ir_impls: RefCell::new(Vec::new()),
1358 source_code: RefCell::new(String::new()),
1359 user_macros: RefCell::new(HashMap::new()),
1360 source_text: None,
1362 function_spans: HashMap::new(),
1363 trait_defs: Vec::new(),
1364 impl_blocks: Vec::new(),
1365 const_defs: Vec::new(),
1366 crate_modules: HashSet::new(),
1367 crate_name: None,
1368 crate_alias: None,
1369 const_generic_params: HashMap::new(),
1370 const_generic_deferred_consts: HashMap::new(),
1371 };
1372
1373 interp.register_builtins();
1375
1376 interp
1377 }
1378
1379 pub fn set_program_args(&mut self, args: Vec<String>) {
1381 self.program_args = Some(args);
1382 }
1383
1384 pub fn set_current_module(&mut self, module: Option<String>) {
1386 self.current_module = module;
1387 }
1388
1389 pub fn set_current_source_dir(&mut self, dir: Option<String>) {
1391 self.current_source_dir = dir;
1392 }
1393
1394 pub fn set_source_dir(&mut self, dir: String) {
1397 self.current_source_dir = Some(dir);
1398 }
1399
1400 pub fn set_crate_name(&mut self, name: String) {
1402 self.crate_name = Some(name);
1403 }
1404
1405 pub fn set_crate_alias(&mut self, alias: String) {
1407 self.crate_alias = Some(alias);
1408 }
1409
1410 pub fn register_module(&mut self, name: String) {
1412 self.crate_modules.insert(name);
1413 }
1414
1415 pub fn get_program_args(&self) -> Vec<String> {
1417 self.program_args
1418 .clone()
1419 .unwrap_or_else(|| std::env::args().collect())
1420 }
1421
1422 pub fn discover_project(&mut self, source_dir: &str) -> Result<(), RuntimeError> {
1425 let mut current = PathBuf::from(source_dir);
1426 if let Ok(canonical) = current.canonicalize() {
1428 current = canonical;
1429 }
1430
1431 loop {
1433 for name in &["Sigil.toml", "sigil.toml", "Grimoire.toml", "grimoire.toml"] {
1435 let manifest = current.join(name);
1436 if manifest.exists() {
1437 if let Ok(result) = self.try_parse_workspace_toml(&manifest) {
1438 if result {
1439 return Ok(());
1440 }
1441 }
1443 }
1444 }
1445
1446 if !current.pop() {
1447 crate::sigil_debug!(
1449 "DEBUG discover_project: no workspace config found from {}",
1450 source_dir
1451 );
1452 return Ok(());
1453 }
1454 }
1455 }
1456
1457 fn try_parse_workspace_toml(&mut self, path: &PathBuf) -> Result<bool, RuntimeError> {
1460 let content = std::fs::read_to_string(path)
1461 .map_err(|e| RuntimeError::new(format!("Failed to read Sigil.toml: {}", e)))?;
1462
1463 let toml_value: toml::Value = content
1464 .parse()
1465 .map_err(|e| RuntimeError::new(format!("Failed to parse Sigil.toml: {}", e)))?;
1466
1467 if let Some(workspace) = toml_value.get("workspace") {
1469 if workspace
1470 .get("members")
1471 .and_then(|m| m.as_array())
1472 .is_some()
1473 {
1474 return self.parse_sigil_toml(path).map(|_| true);
1476 }
1477 }
1478
1479 crate::sigil_debug!(
1481 "DEBUG try_parse_workspace_toml: {:?} is not a workspace config",
1482 path
1483 );
1484 Ok(false)
1485 }
1486
1487 fn parse_sigil_toml(&mut self, path: &PathBuf) -> Result<(), RuntimeError> {
1489 let content = std::fs::read_to_string(path)
1490 .map_err(|e| RuntimeError::new(format!("Failed to read Sigil.toml: {}", e)))?;
1491
1492 let toml_value: toml::Value = content
1493 .parse()
1494 .map_err(|e| RuntimeError::new(format!("Failed to parse Sigil.toml: {}", e)))?;
1495
1496 self.project_root = path.parent().map(|p| p.to_path_buf());
1497
1498 if let Some(workspace) = toml_value.get("workspace") {
1500 if let Some(members) = workspace.get("members").and_then(|m| m.as_array()) {
1501 for member in members {
1502 if let Some(member_path) = member.as_str() {
1503 let crate_name = std::path::Path::new(member_path)
1505 .file_name()
1506 .and_then(|n| n.to_str())
1507 .map(|n| n.replace("-", "_"))
1508 .unwrap_or_default();
1509
1510 if !crate_name.is_empty() {
1511 crate::sigil_debug!(
1512 "DEBUG parse_sigil_toml: registered workspace member: {} -> {}",
1513 &crate_name,
1514 member_path
1515 );
1516 self.workspace_members
1517 .insert(crate_name, PathBuf::from(member_path));
1518 }
1519 }
1520 }
1521 }
1522 }
1523
1524 crate::sigil_debug!(
1525 "DEBUG parse_sigil_toml: loaded {} workspace members from {:?}",
1526 self.workspace_members.len(),
1527 path
1528 );
1529
1530 Ok(())
1531 }
1532
1533 pub fn load_crate(&mut self, crate_name: &str) -> Result<bool, RuntimeError> {
1535 if self.loaded_crates.contains(crate_name) {
1537 return Ok(true);
1538 }
1539
1540 if self.loading_crates.contains(crate_name) {
1542 return Err(RuntimeError::new(format!(
1543 "Circular dependency detected: crate '{}' is already being loaded",
1544 crate_name
1545 )));
1546 }
1547
1548 let crate_path = match self.workspace_members.get(crate_name) {
1550 Some(p) => p.clone(),
1551 None => {
1552 crate::sigil_debug!(
1553 "DEBUG load_crate: crate '{}' not found in workspace members",
1554 crate_name
1555 );
1556 return Ok(false);
1557 }
1558 };
1559
1560 let project_root = match &self.project_root {
1561 Some(r) => r.clone(),
1562 None => {
1563 crate::sigil_debug!("DEBUG load_crate: no project root set");
1564 return Ok(false);
1565 }
1566 };
1567
1568 let lib_path = project_root.join(&crate_path).join("src").join("lib.sigil");
1570
1571 if !lib_path.exists() {
1572 crate::sigil_debug!("DEBUG load_crate: lib.sigil not found at {:?}", lib_path);
1573 return Ok(false);
1574 }
1575
1576 self.loading_crates.insert(crate_name.to_string());
1578
1579 crate::sigil_debug!(
1580 "DEBUG load_crate: loading crate '{}' from {:?}",
1581 crate_name,
1582 lib_path
1583 );
1584
1585 let source = std::fs::read_to_string(&lib_path)
1587 .map_err(|e| RuntimeError::new(format!("Failed to read {:?}: {}", lib_path, e)))?;
1588
1589 let prev_module = self.current_module.clone();
1591 let prev_source_dir = self.current_source_dir.clone();
1592
1593 self.current_module = Some(crate_name.to_string());
1595 self.current_source_dir = lib_path.parent().map(|p| p.to_string_lossy().to_string());
1596
1597 let mut parser = crate::Parser::new(&source);
1599
1600 match parser.parse_file() {
1601 Ok(parsed_file) => {
1602 for item in &parsed_file.items {
1604 if let Err(e) = self.execute_item(&item.node) {
1605 crate::sigil_warn!("Warning: error loading crate '{}': {}", crate_name, e);
1606 }
1607 }
1608 }
1609 Err(e) => {
1610 crate::sigil_warn!("Warning: failed to parse crate '{}': {:?}", crate_name, e);
1611 }
1612 }
1613
1614 self.current_module = prev_module;
1616 self.current_source_dir = prev_source_dir;
1617
1618 self.loading_crates.remove(crate_name);
1620 self.loaded_crates.insert(crate_name.to_string());
1621
1622 crate::sigil_debug!(
1623 "DEBUG load_crate: successfully loaded crate '{}'",
1624 crate_name
1625 );
1626
1627 Ok(true)
1628 }
1629
1630 fn register_builtins(&mut self) {
1631 self.globals
1633 .borrow_mut()
1634 .define("PhantomData".to_string(), Value::Null);
1635
1636 self.define_builtin("print", None, |interp, args| {
1638 let output: Vec<String> = args.iter().map(|v| format!("{}", v)).collect();
1639 let line = output.join(" ");
1640 println!("{}", line);
1641 interp.output.push(line);
1642 Ok(Value::Null)
1643 });
1644
1645 self.define_builtin("type_of", Some(1), |_, args| {
1647 let type_name = match &args[0] {
1648 Value::Null => "null",
1649 Value::Bool(_) => "bool",
1650 Value::Int(_) => "i64",
1651 Value::Float(_) => "f64",
1652 Value::String(_) => "str",
1653 Value::Char(_) => "char",
1654 Value::Array(_) => "array",
1655 Value::Tuple(_) => "tuple",
1656 Value::Struct { name, .. } => name,
1657 Value::Variant { enum_name, .. } => enum_name,
1658 Value::Function(_) => "fn",
1659 Value::BuiltIn(_) => "builtin",
1660 Value::Ref(_) => "ref",
1661 Value::Infinity => "infinity",
1662 Value::Empty => "empty",
1663 Value::Evidential { .. } => "evidential",
1664 Value::Affective { .. } => "affective",
1665 Value::Map(_) => "map",
1666 Value::Set(_) => "set",
1667 Value::Channel(_) => "channel",
1668 Value::ThreadHandle(_) => "thread",
1669 Value::Actor(_) => "actor",
1670 Value::Future(_) => "future",
1671 Value::VariantConstructor { .. } => "variant_constructor",
1672 Value::DefaultConstructor { .. } => "default_constructor",
1673 Value::Range { .. } => "range",
1674 };
1675 Ok(Value::String(Rc::new(type_name.to_string())))
1676 });
1677
1678 self.define_builtin("len", Some(1), |_, args| match &args[0] {
1680 Value::Array(arr) => Ok(Value::Int(arr.borrow().len() as i64)),
1681 Value::String(s) => Ok(Value::Int(s.len() as i64)),
1682 Value::Tuple(t) => Ok(Value::Int(t.len() as i64)),
1683 _ => Err(RuntimeError::new("len() requires array, string, or tuple")),
1684 });
1685
1686 self.define_builtin("push", Some(2), |_, args| match &args[0] {
1687 Value::Array(arr) => {
1688 arr.borrow_mut().push(args[1].clone());
1689 Ok(Value::Null)
1690 }
1691 _ => Err(RuntimeError::new("push() requires array")),
1692 });
1693
1694 self.define_builtin("pop", Some(1), |_, args| match &args[0] {
1695 Value::Array(arr) => arr
1696 .borrow_mut()
1697 .pop()
1698 .ok_or_else(|| RuntimeError::new("pop() on empty array")),
1699 _ => Err(RuntimeError::new("pop() requires array")),
1700 });
1701
1702 self.define_builtin("abs", Some(1), |_, args| match &args[0] {
1704 Value::Int(n) => Ok(Value::Int(n.abs())),
1705 Value::Float(n) => Ok(Value::Float(n.abs())),
1706 _ => Err(RuntimeError::new("abs() requires number")),
1707 });
1708
1709 self.define_builtin("sqrt", Some(1), |_, args| match &args[0] {
1710 Value::Int(n) => Ok(Value::Float((*n as f64).sqrt())),
1711 Value::Float(n) => Ok(Value::Float(n.sqrt())),
1712 _ => Err(RuntimeError::new("sqrt() requires number")),
1713 });
1714
1715 self.define_builtin("sin", Some(1), |_, args| match &args[0] {
1716 Value::Int(n) => Ok(Value::Float((*n as f64).sin())),
1717 Value::Float(n) => Ok(Value::Float(n.sin())),
1718 _ => Err(RuntimeError::new("sin() requires number")),
1719 });
1720
1721 self.define_builtin("cos", Some(1), |_, args| match &args[0] {
1722 Value::Int(n) => Ok(Value::Float((*n as f64).cos())),
1723 Value::Float(n) => Ok(Value::Float(n.cos())),
1724 _ => Err(RuntimeError::new("cos() requires number")),
1725 });
1726
1727 self.define_builtin("known", Some(1), |_, args| {
1729 Ok(Value::Evidential {
1730 value: Box::new(args[0].clone()),
1731 evidence: Evidence::Known,
1732 })
1733 });
1734
1735 self.define_builtin("uncertain", Some(1), |_, args| {
1736 Ok(Value::Evidential {
1737 value: Box::new(args[0].clone()),
1738 evidence: Evidence::Uncertain,
1739 })
1740 });
1741
1742 self.define_builtin("reported", Some(1), |_, args| {
1743 Ok(Value::Evidential {
1744 value: Box::new(args[0].clone()),
1745 evidence: Evidence::Reported,
1746 })
1747 });
1748
1749 self.globals.borrow_mut().define(
1751 "Box·new".to_string(),
1752 Value::BuiltIn(Rc::new(BuiltInFn {
1753 name: "Box·new".to_string(),
1754 arity: Some(1),
1755 func: |_, args| Ok(args[0].clone()),
1756 })),
1757 );
1758
1759 self.globals.borrow_mut().define(
1761 "Map·new".to_string(),
1762 Value::BuiltIn(Rc::new(BuiltInFn {
1763 name: "Map·new".to_string(),
1764 arity: Some(0),
1765 func: |_, _| Ok(Value::Map(Rc::new(RefCell::new(HashMap::new())))),
1766 })),
1767 );
1768
1769 self.define_builtin("range", Some(2), |_, args| {
1771 let start = match &args[0] {
1772 Value::Int(n) => *n,
1773 _ => return Err(RuntimeError::new("range() requires integers")),
1774 };
1775 let end = match &args[1] {
1776 Value::Int(n) => *n,
1777 _ => return Err(RuntimeError::new("range() requires integers")),
1778 };
1779 let values: Vec<Value> = (start..end).map(Value::Int).collect();
1780 Ok(Value::Array(Rc::new(RefCell::new(values))))
1781 });
1782
1783 self.globals.borrow_mut().define(
1785 "ExitCode·SUCCESS".to_string(),
1786 Value::Variant {
1787 enum_name: "ExitCode".to_string(),
1788 variant_name: "SUCCESS".to_string(),
1789 fields: Some(Rc::new(vec![Value::Int(0)])),
1790 },
1791 );
1792 self.globals.borrow_mut().define(
1793 "ExitCode·FAILURE".to_string(),
1794 Value::Variant {
1795 enum_name: "ExitCode".to_string(),
1796 variant_name: "FAILURE".to_string(),
1797 fields: Some(Rc::new(vec![Value::Int(1)])),
1798 },
1799 );
1800
1801 self.define_builtin("PathBuf·from", Some(1), |_, args| {
1803 let arg = match &args[0] {
1805 Value::Ref(r) => r.borrow().clone(),
1806 other => other.clone(),
1807 };
1808 let path = match &arg {
1809 Value::String(s2) => s2.as_str().to_string(),
1810 _ => return Err(RuntimeError::new("PathBuf::from expects a string")),
1811 };
1812 let mut fields = HashMap::new();
1814 fields.insert("path".to_string(), Value::String(Rc::new(path)));
1815 Ok(Value::Struct {
1816 name: "PathBuf".to_string(),
1817 fields: Rc::new(RefCell::new(fields)),
1818 })
1819 });
1820
1821 self.define_builtin("Path·new", Some(1), |_, args| {
1823 let arg = match &args[0] {
1825 Value::Ref(r) => r.borrow().clone(),
1826 other => other.clone(),
1827 };
1828 let path = match &arg {
1829 Value::String(s2) => s2.as_str().to_string(),
1830 _ => return Err(RuntimeError::new("Path::new expects a string")),
1831 };
1832 let mut fields = HashMap::new();
1833 fields.insert("path".to_string(), Value::String(Rc::new(path)));
1834 Ok(Value::Struct {
1835 name: "Path".to_string(),
1836 fields: Rc::new(RefCell::new(fields)),
1837 })
1838 });
1839
1840 self.define_builtin("std·fs·read_to_string", Some(1), |interp, args| {
1842 fn unwrap_refs(v: &Value) -> Value {
1844 match v {
1845 Value::Ref(r) => unwrap_refs(&r.borrow()),
1846 other => other.clone(),
1847 }
1848 }
1849 let arg = unwrap_refs(&args[0]);
1850 crate::sigil_debug!("DEBUG read_to_string: arg = {:?}", arg);
1851 crate::sigil_debug!(
1853 "DEBUG read_to_string: env has path = {:?}",
1854 interp.environment.borrow().get("path")
1855 );
1856 let path = match &arg {
1857 Value::String(s) => s.to_string(),
1858 Value::Struct { name, fields, .. } => {
1860 crate::sigil_debug!("DEBUG read_to_string: struct name = {}", name);
1861 fields
1862 .borrow()
1863 .get("path")
1864 .and_then(|v| {
1865 if let Value::String(s) = v {
1866 Some(s.to_string())
1867 } else {
1868 None
1869 }
1870 })
1871 .ok_or_else(|| RuntimeError::new("Expected path field in struct"))?
1872 }
1873 Value::Variant {
1875 enum_name,
1876 variant_name,
1877 fields,
1878 } if enum_name == "Option" && variant_name == "Some" => {
1879 if let Some(fields) = fields {
1880 if let Some(Value::String(s)) = fields.first() {
1881 s.to_string()
1882 } else {
1883 return Err(RuntimeError::new(
1884 "read_to_string: Option::Some does not contain a string",
1885 ));
1886 }
1887 } else {
1888 return Err(RuntimeError::new(
1889 "read_to_string: Option::Some has no fields",
1890 ));
1891 }
1892 }
1893 _ => {
1894 return Err(RuntimeError::new(&format!(
1895 "read_to_string expects a path string or PathBuf, got {:?}",
1896 arg
1897 )))
1898 }
1899 };
1900 match std::fs::read_to_string(&path) {
1901 Ok(content) => Ok(Value::Variant {
1902 enum_name: "Result".to_string(),
1903 variant_name: "Ok".to_string(),
1904 fields: Some(Rc::new(vec![Value::String(Rc::new(content))])),
1905 }),
1906 Err(e) => Ok(Value::Variant {
1907 enum_name: "Result".to_string(),
1908 variant_name: "Err".to_string(),
1909 fields: Some(Rc::new(vec![Value::String(Rc::new(e.to_string()))])),
1910 }),
1911 }
1912 });
1913
1914 self.define_builtin("fs·read_to_string", Some(1), |_, args| {
1916 let arg = match &args[0] {
1917 Value::Ref(r) => r.borrow().clone(),
1918 other => other.clone(),
1919 };
1920 let path = match &arg {
1921 Value::String(s) => s.to_string(),
1922 Value::Struct { fields, .. } => fields
1923 .borrow()
1924 .get("path")
1925 .and_then(|v| {
1926 if let Value::String(s) = v {
1927 Some(s.to_string())
1928 } else {
1929 None
1930 }
1931 })
1932 .ok_or_else(|| RuntimeError::new("Expected path field in struct"))?,
1933 _ => {
1934 return Err(RuntimeError::new(
1935 "read_to_string expects a path string or PathBuf",
1936 ))
1937 }
1938 };
1939 match std::fs::read_to_string(&path) {
1940 Ok(content) => Ok(Value::Variant {
1941 enum_name: "Result".to_string(),
1942 variant_name: "Ok".to_string(),
1943 fields: Some(Rc::new(vec![Value::String(Rc::new(content))])),
1944 }),
1945 Err(e) => Ok(Value::Variant {
1946 enum_name: "Result".to_string(),
1947 variant_name: "Err".to_string(),
1948 fields: Some(Rc::new(vec![Value::String(Rc::new(e.to_string()))])),
1949 }),
1950 }
1951 });
1952
1953 self.define_builtin("std·fs·read_dir", Some(1), |_, args| {
1955 fn unwrap_refs(v: &Value) -> Value {
1956 match v {
1957 Value::Ref(r) => unwrap_refs(&r.borrow()),
1958 other => other.clone(),
1959 }
1960 }
1961 let arg = unwrap_refs(&args[0]);
1962 let path = match &arg {
1963 Value::String(s) => s.to_string(),
1964 Value::Struct { name, fields, .. } if name == "Path" || name == "PathBuf" => fields
1965 .borrow()
1966 .get("path")
1967 .and_then(|v| {
1968 if let Value::String(s) = v {
1969 Some(s.to_string())
1970 } else {
1971 None
1972 }
1973 })
1974 .ok_or_else(|| RuntimeError::new("Expected path field in struct"))?,
1975 _ => {
1976 return Err(RuntimeError::new(&format!(
1977 "read_dir expects a path, got {:?}",
1978 arg
1979 )))
1980 }
1981 };
1982 match std::fs::read_dir(&path) {
1983 Ok(entries) => {
1984 let entry_values: Vec<Value> = entries
1986 .filter_map(|e| e.ok())
1987 .map(|e| {
1988 let entry_path = e.path().to_string_lossy().to_string();
1989 let mut fields = HashMap::new();
1990 fields.insert("path".to_string(), Value::String(Rc::new(entry_path)));
1991 Value::Variant {
1993 enum_name: "Result".to_string(),
1994 variant_name: "Ok".to_string(),
1995 fields: Some(Rc::new(vec![Value::Struct {
1996 name: "DirEntry".to_string(),
1997 fields: Rc::new(RefCell::new(fields)),
1998 }])),
1999 }
2000 })
2001 .collect();
2002 Ok(Value::Variant {
2004 enum_name: "Result".to_string(),
2005 variant_name: "Ok".to_string(),
2006 fields: Some(Rc::new(vec![Value::Array(Rc::new(RefCell::new(
2007 entry_values,
2008 )))])),
2009 })
2010 }
2011 Err(e) => Ok(Value::Variant {
2012 enum_name: "Result".to_string(),
2013 variant_name: "Err".to_string(),
2014 fields: Some(Rc::new(vec![Value::String(Rc::new(e.to_string()))])),
2015 }),
2016 }
2017 });
2018
2019 self.define_builtin("fs·read_dir", Some(1), |_, args| {
2021 fn unwrap_refs(v: &Value) -> Value {
2022 match v {
2023 Value::Ref(r) => unwrap_refs(&r.borrow()),
2024 other => other.clone(),
2025 }
2026 }
2027 let arg = unwrap_refs(&args[0]);
2028 let path = match &arg {
2029 Value::String(s) => s.to_string(),
2030 Value::Struct { name, fields, .. } if name == "Path" || name == "PathBuf" => fields
2031 .borrow()
2032 .get("path")
2033 .and_then(|v| {
2034 if let Value::String(s) = v {
2035 Some(s.to_string())
2036 } else {
2037 None
2038 }
2039 })
2040 .ok_or_else(|| RuntimeError::new("Expected path field in struct"))?,
2041 _ => {
2042 return Err(RuntimeError::new(&format!(
2043 "read_dir expects a path, got {:?}",
2044 arg
2045 )))
2046 }
2047 };
2048 match std::fs::read_dir(&path) {
2049 Ok(entries) => {
2050 let entry_values: Vec<Value> = entries
2051 .filter_map(|e| e.ok())
2052 .map(|e| {
2053 let entry_path = e.path().to_string_lossy().to_string();
2054 let mut fields = HashMap::new();
2055 fields.insert("path".to_string(), Value::String(Rc::new(entry_path)));
2056 Value::Variant {
2057 enum_name: "Result".to_string(),
2058 variant_name: "Ok".to_string(),
2059 fields: Some(Rc::new(vec![Value::Struct {
2060 name: "DirEntry".to_string(),
2061 fields: Rc::new(RefCell::new(fields)),
2062 }])),
2063 }
2064 })
2065 .collect();
2066 Ok(Value::Variant {
2067 enum_name: "Result".to_string(),
2068 variant_name: "Ok".to_string(),
2069 fields: Some(Rc::new(vec![Value::Array(Rc::new(RefCell::new(
2070 entry_values,
2071 )))])),
2072 })
2073 }
2074 Err(e) => Ok(Value::Variant {
2075 enum_name: "Result".to_string(),
2076 variant_name: "Err".to_string(),
2077 fields: Some(Rc::new(vec![Value::String(Rc::new(e.to_string()))])),
2078 }),
2079 }
2080 });
2081
2082 self.define_builtin("std·env·var", Some(1), |_, args| {
2084 fn unwrap_refs(v: &Value) -> Value {
2085 match v {
2086 Value::Ref(r) => unwrap_refs(&r.borrow()),
2087 other => other.clone(),
2088 }
2089 }
2090 let arg = unwrap_refs(&args[0]);
2091 let var_name = match &arg {
2092 Value::String(s) => s.to_string(),
2093 _ => return Err(RuntimeError::new("env::var expects a string")),
2094 };
2095 match std::env::var(&var_name) {
2096 Ok(value) => Ok(Value::Variant {
2097 enum_name: "Result".to_string(),
2098 variant_name: "Ok".to_string(),
2099 fields: Some(Rc::new(vec![Value::String(Rc::new(value))])),
2100 }),
2101 Err(_) => Ok(Value::Variant {
2102 enum_name: "Result".to_string(),
2103 variant_name: "Err".to_string(),
2104 fields: Some(Rc::new(vec![Value::String(Rc::new(
2105 "Environment variable not found".to_string(),
2106 ))])),
2107 }),
2108 }
2109 });
2110
2111 self.define_builtin("env·var", Some(1), |_, args| {
2113 fn unwrap_refs(v: &Value) -> Value {
2114 match v {
2115 Value::Ref(r) => unwrap_refs(&r.borrow()),
2116 other => other.clone(),
2117 }
2118 }
2119 let arg = unwrap_refs(&args[0]);
2120 let var_name = match &arg {
2121 Value::String(s) => s.to_string(),
2122 _ => return Err(RuntimeError::new("env::var expects a string")),
2123 };
2124 match std::env::var(&var_name) {
2125 Ok(value) => Ok(Value::Variant {
2126 enum_name: "Result".to_string(),
2127 variant_name: "Ok".to_string(),
2128 fields: Some(Rc::new(vec![Value::String(Rc::new(value))])),
2129 }),
2130 Err(_) => Ok(Value::Variant {
2131 enum_name: "Result".to_string(),
2132 variant_name: "Err".to_string(),
2133 fields: Some(Rc::new(vec![Value::String(Rc::new(
2134 "Environment variable not found".to_string(),
2135 ))])),
2136 }),
2137 }
2138 });
2139
2140 self.define_builtin("std·env·args", Some(0), |interp, _| {
2143 let args = interp.get_program_args();
2144 let arg_values: Vec<Value> = args
2145 .iter()
2146 .map(|s| Value::String(Rc::new(s.clone())))
2147 .collect();
2148 Ok(Value::Array(Rc::new(RefCell::new(arg_values))))
2149 });
2150
2151 self.define_builtin("env·args", Some(0), |interp, _| {
2153 let args = interp.get_program_args();
2154 let arg_values: Vec<Value> = args
2155 .iter()
2156 .map(|s| Value::String(Rc::new(s.clone())))
2157 .collect();
2158 Ok(Value::Array(Rc::new(RefCell::new(arg_values))))
2159 });
2160
2161 self.define_builtin("fs_read", Some(1), |_, args| {
2167 let path = match &args[0] {
2168 Value::String(s) => s.to_string(),
2169 _ => return Err(RuntimeError::new("fs_read requires a string path")),
2170 };
2171 match std::fs::read_to_string(&path) {
2172 Ok(content) => Ok(Value::String(Rc::new(content))),
2173 Err(e) => {
2174 crate::sigil_debug!("DEBUG fs_read error for '{}': {}", path, e);
2175 Ok(Value::Null)
2176 }
2177 }
2178 });
2179
2180 self.define_builtin("fs_list", Some(1), |_, args| {
2182 let path = match &args[0] {
2183 Value::String(s) => s.to_string(),
2184 _ => return Err(RuntimeError::new("fs_list requires a string path")),
2185 };
2186 match std::fs::read_dir(&path) {
2187 Ok(entries) => {
2188 let files: Vec<Value> = entries
2189 .filter_map(|e| e.ok())
2190 .map(|e| {
2191 Value::String(Rc::new(e.file_name().to_string_lossy().to_string()))
2192 })
2193 .collect();
2194 Ok(Value::Array(Rc::new(RefCell::new(files))))
2195 }
2196 Err(e) => {
2197 crate::sigil_debug!("DEBUG fs_list error for '{}': {}", path, e);
2198 Ok(Value::Array(Rc::new(RefCell::new(Vec::new()))))
2199 }
2200 }
2201 });
2202
2203 self.define_builtin("fs_is_dir", Some(1), |_, args| {
2205 let path = match &args[0] {
2206 Value::String(s) => s.to_string(),
2207 _ => return Err(RuntimeError::new("fs_is_dir requires a string path")),
2208 };
2209 Ok(Value::Bool(std::path::Path::new(&path).is_dir()))
2210 });
2211
2212 self.define_builtin("fs_is_file", Some(1), |_, args| {
2214 let path = match &args[0] {
2215 Value::String(s) => s.to_string(),
2216 _ => return Err(RuntimeError::new("fs_is_file requires a string path")),
2217 };
2218 Ok(Value::Bool(std::path::Path::new(&path).is_file()))
2219 });
2220
2221 self.define_builtin("fs_exists", Some(1), |_, args| {
2223 let path = match &args[0] {
2224 Value::String(s) => s.to_string(),
2225 _ => return Err(RuntimeError::new("fs_exists requires a string path")),
2226 };
2227 Ok(Value::Bool(std::path::Path::new(&path).exists()))
2228 });
2229
2230 self.define_builtin("path_extension", Some(1), |_, args| {
2232 let path = match &args[0] {
2233 Value::String(s) => s.to_string(),
2234 _ => return Err(RuntimeError::new("path_extension requires a string path")),
2235 };
2236 let ext = std::path::Path::new(&path)
2237 .extension()
2238 .and_then(|e| e.to_str())
2239 .map(|s| s.to_string());
2240 match ext {
2241 Some(e) => Ok(Value::String(Rc::new(e))),
2242 None => Ok(Value::Null),
2243 }
2244 });
2245
2246 self.define_builtin("path_join", Some(2), |_, args| {
2248 let base = match &args[0] {
2249 Value::String(s) => s.to_string(),
2250 _ => return Err(RuntimeError::new("path_join requires string paths")),
2251 };
2252 let part = match &args[1] {
2253 Value::String(s) => s.to_string(),
2254 _ => return Err(RuntimeError::new("path_join requires string paths")),
2255 };
2256 let joined = std::path::Path::new(&base).join(&part);
2257 Ok(Value::String(Rc::new(joined.to_string_lossy().to_string())))
2258 });
2259
2260 self.define_builtin("path_parent", Some(1), |_, args| {
2262 let path = match &args[0] {
2263 Value::String(s) => s.to_string(),
2264 _ => return Err(RuntimeError::new("path_parent requires a string path")),
2265 };
2266 match std::path::Path::new(&path).parent() {
2267 Some(p) => Ok(Value::String(Rc::new(p.to_string_lossy().to_string()))),
2268 None => Ok(Value::Null),
2269 }
2270 });
2271
2272 self.define_builtin("path_file_name", Some(1), |_, args| {
2274 let path = match &args[0] {
2275 Value::String(s) => s.to_string(),
2276 _ => return Err(RuntimeError::new("path_file_name requires a string path")),
2277 };
2278 match std::path::Path::new(&path).file_name() {
2279 Some(n) => Ok(Value::String(Rc::new(n.to_string_lossy().to_string()))),
2280 None => Ok(Value::Null),
2281 }
2282 });
2283
2284 #[cfg(feature = "native")]
2289 {
2290 self.define_builtin("TreeSitterParser·new", Some(1), |_, args| {
2292 use crate::tree_sitter_support::{TSLanguage, TSParser};
2293
2294 let lang_str = match &args[0] {
2296 Value::String(s) => s.to_string(),
2297 Value::Variant {
2298 enum_name,
2299 variant_name,
2300 ..
2301 } => {
2302 format!("{}::{}", enum_name, variant_name)
2304 }
2305 other => format!("{:?}", other),
2306 };
2307
2308 let language = match TSLanguage::from_str(&lang_str) {
2310 Some(lang) => lang,
2311 None => {
2312 return Ok(Value::Variant {
2313 enum_name: "Result".to_string(),
2314 variant_name: "Err".to_string(),
2315 fields: Some(Rc::new(vec![Value::Struct {
2316 name: "ParseError".to_string(),
2317 fields: Rc::new(RefCell::new({
2318 let mut f = HashMap::new();
2319 f.insert(
2320 "kind".to_string(),
2321 Value::String(Rc::new("ParserNotFound".to_string())),
2322 );
2323 f.insert(
2324 "message".to_string(),
2325 Value::String(Rc::new(format!(
2326 "Unsupported language: {}",
2327 lang_str
2328 ))),
2329 );
2330 f
2331 })),
2332 }])),
2333 });
2334 }
2335 };
2336
2337 match TSParser::new(language) {
2339 Ok(_) => {
2340 let mut fields = HashMap::new();
2342 fields.insert("language".to_string(), Value::String(Rc::new(lang_str)));
2343 fields.insert(
2344 "_ts_language".to_string(),
2345 Value::String(Rc::new(format!("{:?}", language))),
2346 );
2347
2348 Ok(Value::Variant {
2349 enum_name: "Result".to_string(),
2350 variant_name: "Ok".to_string(),
2351 fields: Some(Rc::new(vec![Value::Struct {
2352 name: "TreeSitterParser".to_string(),
2353 fields: Rc::new(RefCell::new(fields)),
2354 }])),
2355 })
2356 }
2357 Err(e) => Ok(Value::Variant {
2358 enum_name: "Result".to_string(),
2359 variant_name: "Err".to_string(),
2360 fields: Some(Rc::new(vec![Value::Struct {
2361 name: "ParseError".to_string(),
2362 fields: Rc::new(RefCell::new({
2363 let mut f = HashMap::new();
2364 f.insert(
2365 "kind".to_string(),
2366 Value::String(Rc::new("ParserNotFound".to_string())),
2367 );
2368 f.insert("message".to_string(), Value::String(Rc::new(e)));
2369 f
2370 })),
2371 }])),
2372 }),
2373 }
2374 });
2375
2376 self.define_builtin("tree_sitter_parse", Some(2), |_, args| {
2378 use crate::tree_sitter_support::{node_to_value, parse_source};
2379
2380 let lang_str = match &args[0] {
2382 Value::String(s) => s.to_string(),
2383 Value::Variant {
2384 enum_name,
2385 variant_name,
2386 ..
2387 } => {
2388 format!("{}::{}", enum_name, variant_name)
2389 }
2390 other => format!("{:?}", other),
2391 };
2392
2393 let source = match &args[1] {
2394 Value::String(s) => s.to_string(),
2395 _ => {
2396 return Err(RuntimeError::new(
2397 "tree_sitter_parse expects source code string as second argument",
2398 ))
2399 }
2400 };
2401
2402 match parse_source(&lang_str, &source) {
2404 Ok(tree) => {
2405 let root = tree.root_node();
2407 let root_fields = node_to_value(&root);
2408
2409 let mut tree_fields = HashMap::new();
2411 tree_fields.insert(
2412 "root".to_string(),
2413 Value::Struct {
2414 name: "SyntaxNode".to_string(),
2415 fields: Rc::new(RefCell::new(root_fields)),
2416 },
2417 );
2418 tree_fields.insert("source".to_string(), Value::String(Rc::new(source)));
2419
2420 Ok(Value::Variant {
2421 enum_name: "Result".to_string(),
2422 variant_name: "Ok".to_string(),
2423 fields: Some(Rc::new(vec![Value::Struct {
2424 name: "TSTree".to_string(),
2425 fields: Rc::new(RefCell::new(tree_fields)),
2426 }])),
2427 })
2428 }
2429 Err(e) => Ok(Value::Variant {
2430 enum_name: "Result".to_string(),
2431 variant_name: "Err".to_string(),
2432 fields: Some(Rc::new(vec![Value::Struct {
2433 name: "ParseError".to_string(),
2434 fields: Rc::new(RefCell::new({
2435 let mut f = HashMap::new();
2436 f.insert(
2437 "kind".to_string(),
2438 Value::String(Rc::new("SyntaxError".to_string())),
2439 );
2440 f.insert("message".to_string(), Value::String(Rc::new(e)));
2441 f
2442 })),
2443 }])),
2444 }),
2445 }
2446 });
2447
2448 self.define_builtin("tree_sitter_supported_languages", Some(0), |_, _| {
2450 use crate::tree_sitter_support::supported_languages;
2451
2452 let languages: Vec<Value> = supported_languages()
2453 .iter()
2454 .map(|s| Value::String(Rc::new(s.to_string())))
2455 .collect();
2456
2457 Ok(Value::Array(Rc::new(RefCell::new(languages))))
2458 });
2459 } self.define_builtin("tree_sitter_node_text", Some(2), |_, args| {
2463 let (start_byte, end_byte) = match &args[0] {
2465 Value::Struct { fields, .. } => {
2466 let fields = fields.borrow();
2467 let start = match fields.get("start_byte") {
2468 Some(Value::Int(n)) => *n as usize,
2469 _ => return Err(RuntimeError::new("Node missing start_byte field")),
2470 };
2471 let end = match fields.get("end_byte") {
2472 Some(Value::Int(n)) => *n as usize,
2473 _ => return Err(RuntimeError::new("Node missing end_byte field")),
2474 };
2475 (start, end)
2476 }
2477 _ => {
2478 return Err(RuntimeError::new(
2479 "tree_sitter_node_text expects a SyntaxNode struct",
2480 ))
2481 }
2482 };
2483
2484 let source = match &args[1] {
2485 Value::String(s) => s.to_string(),
2486 _ => {
2487 return Err(RuntimeError::new(
2488 "tree_sitter_node_text expects source string as second argument",
2489 ))
2490 }
2491 };
2492
2493 if end_byte <= source.len() && start_byte <= end_byte {
2494 Ok(Value::String(Rc::new(
2495 source[start_byte..end_byte].to_string(),
2496 )))
2497 } else {
2498 Err(RuntimeError::new("Byte range out of bounds"))
2499 }
2500 });
2501
2502 self.define_builtin("sigil_parse", Some(1), |_, args| {
2508 let source = match &args[0] {
2509 Value::String(s) => s.to_string(),
2510 Value::Ref(r) => {
2511 if let Value::String(s) = &*r.borrow() {
2512 s.to_string()
2513 } else {
2514 return Err(RuntimeError::new("sigil_parse expects string source"));
2515 }
2516 }
2517 _ => return Err(RuntimeError::new("sigil_parse expects string source")),
2518 };
2519
2520 let mut parser = crate::Parser::new(&source);
2522 match parser.parse_file() {
2523 Ok(source_file) => {
2524 Ok(ast_to_value_source_file(&source_file))
2526 }
2527 Err(e) => {
2528 let mut fields = HashMap::new();
2530 fields.insert(
2531 "message".to_string(),
2532 Value::String(Rc::new(format!("{}", e))),
2533 );
2534 Ok(Value::Variant {
2535 enum_name: "Result".to_string(),
2536 variant_name: "Err".to_string(),
2537 fields: Some(Rc::new(vec![Value::Struct {
2538 name: "ParseError".to_string(),
2539 fields: Rc::new(RefCell::new(fields)),
2540 }])),
2541 })
2542 }
2543 }
2544 });
2545
2546 self.define_builtin("sigil_parse_file", Some(1), |_, args| {
2548 let path = match &args[0] {
2549 Value::String(s) => s.to_string(),
2550 Value::Ref(r) => {
2551 if let Value::String(s) = &*r.borrow() {
2552 s.to_string()
2553 } else {
2554 return Err(RuntimeError::new("sigil_parse_file expects string path"));
2555 }
2556 }
2557 _ => return Err(RuntimeError::new("sigil_parse_file expects string path")),
2558 };
2559
2560 let source = match std::fs::read_to_string(&path) {
2562 Ok(s) => s,
2563 Err(e) => {
2564 let mut fields = HashMap::new();
2565 fields.insert(
2566 "message".to_string(),
2567 Value::String(Rc::new(format!("IO error: {}", e))),
2568 );
2569 return Ok(Value::Variant {
2570 enum_name: "Result".to_string(),
2571 variant_name: "Err".to_string(),
2572 fields: Some(Rc::new(vec![Value::Struct {
2573 name: "ParseError".to_string(),
2574 fields: Rc::new(RefCell::new(fields)),
2575 }])),
2576 });
2577 }
2578 };
2579
2580 let mut parser = crate::Parser::new(&source);
2582 match parser.parse_file() {
2583 Ok(source_file) => Ok(ast_to_value_source_file(&source_file)),
2584 Err(e) => {
2585 let mut fields = HashMap::new();
2586 fields.insert(
2587 "message".to_string(),
2588 Value::String(Rc::new(format!("{}", e))),
2589 );
2590 Ok(Value::Variant {
2591 enum_name: "Result".to_string(),
2592 variant_name: "Err".to_string(),
2593 fields: Some(Rc::new(vec![Value::Struct {
2594 name: "ParseError".to_string(),
2595 fields: Rc::new(RefCell::new(fields)),
2596 }])),
2597 })
2598 }
2599 }
2600 });
2601
2602 let rc_new = Value::BuiltIn(Rc::new(BuiltInFn {
2604 name: "Rc·new".to_string(),
2605 arity: Some(1),
2606 func: |_, args| {
2607 let mut fields = HashMap::new();
2608 fields.insert("_value".to_string(), args[0].clone());
2609 Ok(Value::Struct {
2610 name: "Rc".to_string(),
2611 fields: std::rc::Rc::new(RefCell::new(fields)),
2612 })
2613 },
2614 }));
2615 self.globals
2616 .borrow_mut()
2617 .define("Rc·new".to_string(), rc_new);
2618
2619 let cell_new = Value::BuiltIn(Rc::new(BuiltInFn {
2621 name: "Cell·new".to_string(),
2622 arity: Some(1),
2623 func: |_, args| {
2624 let mut fields = HashMap::new();
2625 fields.insert("_value".to_string(), args[0].clone());
2626 Ok(Value::Struct {
2627 name: "Cell".to_string(),
2628 fields: std::rc::Rc::new(RefCell::new(fields)),
2629 })
2630 },
2631 }));
2632 self.globals
2633 .borrow_mut()
2634 .define("Cell·new".to_string(), cell_new);
2635 }
2636
2637 fn define_builtin(
2638 &mut self,
2639 name: &str,
2640 arity: Option<usize>,
2641 func: fn(&mut Interpreter, Vec<Value>) -> Result<Value, RuntimeError>,
2642 ) {
2643 let builtin = Value::BuiltIn(Rc::new(BuiltInFn {
2644 name: name.to_string(),
2645 arity,
2646 func,
2647 }));
2648 self.globals.borrow_mut().define(name.to_string(), builtin);
2649 }
2650
2651 pub fn set_source_code(&mut self, source: String) {
2653 *self.source_code.borrow_mut() = source;
2654 }
2655
2656 fn offset_to_line(&self, offset: usize) -> i64 {
2658 let source = self.source_code.borrow();
2659 if source.is_empty() || offset >= source.len() {
2660 return 1; }
2662 let mut safe_offset = offset;
2664 while safe_offset > 0 && !source.is_char_boundary(safe_offset) {
2665 safe_offset -= 1;
2666 }
2667 let line_count = source[..safe_offset].matches('\n').count() + 1;
2669 line_count as i64
2670 }
2671
2672 pub fn execute(&mut self, file: &SourceFile) -> Result<Value, RuntimeError> {
2674 let mut result = Value::Null;
2675
2676 for item in &file.items {
2677 result = self.execute_item(&item.node)?;
2678 }
2679
2680 let main_fn = self.globals.borrow().get("main").and_then(|v| {
2682 if let Value::Function(f) = v {
2683 Some(f.clone())
2684 } else {
2685 None
2686 }
2687 });
2688 if let Some(f) = main_fn {
2689 if f.params.is_empty() {
2692 result = self.call_function(&f, vec![])?;
2693 }
2694 }
2695
2696 Ok(result)
2697 }
2698
2699 pub fn execute_definitions(&mut self, file: &SourceFile) -> Result<Value, RuntimeError> {
2702 let mut result = Value::Null;
2703
2704 for item in &file.items {
2705 result = self.execute_item(&item.node)?;
2706 }
2707
2708 Ok(result)
2709 }
2710
2711 fn execute_item(&mut self, item: &Item) -> Result<Value, RuntimeError> {
2712 match item {
2713 Item::Function(func) => {
2714 let fn_value = self.create_function(func)?;
2715 let fn_name = func.name.name.clone();
2716
2717 self.globals
2719 .borrow_mut()
2720 .define(fn_name.clone(), fn_value.clone());
2721
2722 if let Some(ref module) = self.current_module {
2724 let qualified_name = format!("{}·{}", module, fn_name);
2725 self.globals.borrow_mut().define(qualified_name, fn_value);
2726 }
2727
2728 self.function_spans.insert(fn_name.clone(), func.name.span.clone());
2730
2731 let span = &func.name.span;
2733 let start_line = self.offset_to_line(span.start);
2734 let end_line = self.offset_to_line(span.end);
2735
2736 let mut start_fields = HashMap::new();
2737 start_fields.insert("line".to_string(), Value::Int(start_line));
2738 start_fields.insert("column".to_string(), Value::Int(1));
2739 let start = Value::Struct {
2740 name: "SpanPos".to_string(),
2741 fields: Rc::new(RefCell::new(start_fields)),
2742 };
2743
2744 let mut end_fields = HashMap::new();
2745 end_fields.insert("line".to_string(), Value::Int(end_line));
2746 end_fields.insert("column".to_string(), Value::Int(1));
2747 let end = Value::Struct {
2748 name: "SpanPos".to_string(),
2749 fields: Rc::new(RefCell::new(end_fields)),
2750 };
2751
2752 let mut span_fields = HashMap::new();
2753 span_fields.insert("start".to_string(), start);
2754 span_fields.insert("end".to_string(), end);
2755 let span_value = Value::Struct {
2756 name: "Span".to_string(),
2757 fields: Rc::new(RefCell::new(span_fields)),
2758 };
2759
2760 let mut func_fields = HashMap::new();
2761 func_fields.insert("name".to_string(), Value::String(Rc::new(fn_name)));
2762 func_fields.insert("span".to_string(), span_value);
2763 self.ir_functions.borrow_mut().push(Value::Struct {
2764 name: "FunctionIR".to_string(),
2765 fields: Rc::new(RefCell::new(func_fields)),
2766 });
2767
2768 Ok(Value::Null)
2769 }
2770 Item::Struct(s) => {
2771 self.types
2773 .insert(s.name.name.clone(), TypeDef::Struct(s.clone()));
2774
2775 if let Some(ref module) = self.current_module {
2777 let qualified_name = format!("{}·{}", module, s.name.name);
2778 self.types
2779 .insert(qualified_name, TypeDef::Struct(s.clone()));
2780 }
2781
2782 if matches!(&s.fields, crate::ast::StructFields::Unit) {
2784 let unit_value = Value::Struct {
2785 name: s.name.name.clone(),
2786 fields: Rc::new(RefCell::new(HashMap::new())),
2787 };
2788 self.globals
2789 .borrow_mut()
2790 .define(s.name.name.clone(), unit_value.clone());
2791
2792 if let Some(ref module) = self.current_module {
2794 let qualified_name = format!("{}·{}", module, s.name.name);
2795 self.globals.borrow_mut().define(qualified_name, unit_value);
2796 }
2797 }
2798
2799 let has_default = s
2801 .attrs
2802 .derives
2803 .iter()
2804 .any(|d| matches!(d, DeriveTrait::Default));
2805 if has_default {
2806 self.default_structs.insert(s.name.name.clone(), s.clone());
2807 if let Some(ref module) = self.current_module {
2808 let qualified_name = format!("{}·{}", module, s.name.name);
2809 self.default_structs.insert(qualified_name, s.clone());
2810 }
2811 }
2812
2813 Ok(Value::Null)
2814 }
2815 Item::Enum(e) => {
2816 self.types
2818 .insert(e.name.name.clone(), TypeDef::Enum(e.clone()));
2819
2820 if let Some(ref module) = self.current_module {
2822 let qualified_name = format!("{}·{}", module, e.name.name);
2823 self.types.insert(qualified_name, TypeDef::Enum(e.clone()));
2824 }
2825
2826 let enum_name = e.name.name.clone();
2829 for variant in &e.variants {
2830 let variant_name = variant.name.name.clone();
2831 let qualified_name = format!("{}·{}", enum_name, variant_name);
2832
2833 let arity = match &variant.fields {
2834 crate::ast::StructFields::Unit => 0,
2835 crate::ast::StructFields::Tuple(types) => types.len(),
2836 crate::ast::StructFields::Named(fields) => fields.len(),
2837 };
2838
2839 self.variant_constructors.insert(
2841 qualified_name.clone(),
2842 (enum_name.clone(), variant_name.clone(), arity),
2843 );
2844 }
2845 Ok(Value::Null)
2846 }
2847 Item::Const(c) => {
2848 self.const_defs.push((c.name.name.clone(), c.name.span.clone()));
2850
2851 let value = self.evaluate(&c.value)?;
2852 self.globals.borrow_mut().define(c.name.name.clone(), value.clone());
2853
2854 let mut const_fields = HashMap::new();
2856 const_fields.insert("name".to_string(), Value::String(Rc::new(c.name.name.clone())));
2857 const_fields.insert("value".to_string(), value);
2858 self.ir_constants.borrow_mut().push(Value::Struct {
2859 name: "ConstDef".to_string(),
2860 fields: Rc::new(RefCell::new(const_fields)),
2861 });
2862
2863 Ok(Value::Null)
2864 }
2865 Item::Static(s) => {
2866 let value = self.evaluate(&s.value)?;
2867 self.globals.borrow_mut().define(s.name.name.clone(), value);
2868 if s.mutable {
2870 self.mutable_vars.borrow_mut().insert(s.name.name.clone());
2871 }
2872 Ok(Value::Null)
2873 }
2874 Item::ExternBlock(extern_block) => {
2875 for item in &extern_block.items {
2877 if let ExternItem::Function(func) = item {
2878 let name = func.name.name.clone();
2879 match name.as_str() {
2881 "sigil_read_file" => {
2882 self.define_builtin("sigil_read_file", Some(2), |_, args| {
2883 let path = match &args[0] {
2885 Value::String(s) => (**s).clone(),
2886 _ => {
2887 return Err(RuntimeError::new(
2888 "sigil_read_file expects string path",
2889 ))
2890 }
2891 };
2892 match std::fs::read_to_string(&path) {
2893 Ok(content) => {
2894 Ok(Value::String(Rc::new(content)))
2896 }
2897 Err(_) => Ok(Value::Null),
2898 }
2899 });
2900 }
2901 "sigil_file_len" => {
2902 self.define_builtin("sigil_file_len", Some(0), |_, _| {
2903 Ok(Value::Int(0))
2905 });
2906 }
2907 "sigil_write_file" => {
2908 self.define_builtin("sigil_write_file", Some(4), |_, args| {
2909 let path = match &args[0] {
2910 Value::String(s) => (**s).clone(),
2911 _ => {
2912 return Err(RuntimeError::new(
2913 "sigil_write_file expects string path",
2914 ))
2915 }
2916 };
2917 let content = match &args[2] {
2918 Value::String(s) => (**s).clone(),
2919 _ => {
2920 return Err(RuntimeError::new(
2921 "sigil_write_file expects string content",
2922 ))
2923 }
2924 };
2925 match std::fs::write(&path, &content) {
2926 Ok(_) => Ok(Value::Bool(true)),
2927 Err(_) => Ok(Value::Bool(false)),
2928 }
2929 });
2930 }
2931 "write" => {
2932 self.define_builtin("write", Some(3), |_, args| {
2933 let fd = match &args[0] {
2935 Value::Int(n) => *n,
2936 _ => 1,
2937 };
2938 let content = match &args[1] {
2939 Value::String(s) => (**s).clone(),
2940 _ => format!("{}", args[1]),
2941 };
2942 if fd == 1 {
2943 print!("{}", content);
2944 } else if fd == 2 {
2945 eprint!("{}", content);
2946 }
2947 Ok(Value::Int(content.len() as i64))
2948 });
2949 }
2950 _ => {
2951 }
2953 }
2954 }
2955 }
2956 Ok(Value::Null)
2957 }
2958 Item::Impl(impl_block) => {
2959 self.impl_blocks.push(impl_block.clone());
2961
2962 let type_name = match &impl_block.self_ty {
2964 TypeExpr::Path(path) => path
2965 .segments
2966 .iter()
2967 .map(|s| s.ident.name.as_str())
2968 .collect::<Vec<_>>()
2969 .join("·"),
2970 _ => return Ok(Value::Null), };
2972
2973 let const_params: Vec<String> = impl_block.generics.as_ref()
2975 .map(|g| g.params.iter().filter_map(|p| match p {
2976 crate::ast::GenericParam::Const { name, .. } => Some(name.name.clone()),
2977 _ => None,
2978 }).collect())
2979 .unwrap_or_default();
2980
2981 if !const_params.is_empty() {
2982 self.const_generic_params.insert(type_name.clone(), const_params.clone());
2983 }
2984
2985 if let Some(trait_path) = &impl_block.trait_ {
2987 let trait_name = trait_path
2988 .segments
2989 .iter()
2990 .map(|s| s.ident.name.as_str())
2991 .collect::<Vec<_>>()
2992 .join("·");
2993 if trait_name == "Drop" {
2994 self.drop_types.insert(type_name.clone());
2995 }
2996 }
2997
2998 for impl_item in &impl_block.items {
3000 match impl_item {
3001 ImplItem::Function(func) => {
3002 let fn_value = self.create_function(func)?;
3003 let qualified_name = format!("{}·{}", type_name, func.name.name);
3004 if type_name == "Lexer" && func.name.name.contains("keyword") {
3006 crate::sigil_debug!("DEBUG registering: {}", qualified_name);
3007 }
3008 self.globals
3009 .borrow_mut()
3010 .define(qualified_name.clone(), fn_value.clone());
3011
3012 if let Some(ref module) = self.current_module {
3014 let fully_qualified = format!("{}·{}", module, qualified_name);
3015 self.globals.borrow_mut().define(fully_qualified, fn_value);
3016 }
3017 }
3018 ImplItem::Const(c) => {
3019 if const_params.is_empty() {
3020 let value = self.evaluate(&c.value)?;
3022 let qualified_name = format!("{}·{}", type_name, c.name.name);
3023 self.globals.borrow_mut().define(qualified_name.clone(), value.clone());
3024
3025 if let Some(ref module) = self.current_module {
3026 let fully_qualified = format!("{}·{}", module, qualified_name);
3027 self.globals.borrow_mut().define(fully_qualified, value);
3028 }
3029 } else {
3030 match self.evaluate(&c.value) {
3032 Ok(value) => {
3033 let qualified_name = format!("{}·{}", type_name, c.name.name);
3034 self.globals.borrow_mut().define(qualified_name.clone(), value.clone());
3035
3036 if let Some(ref module) = self.current_module {
3037 let fully_qualified = format!("{}·{}", module, qualified_name);
3038 self.globals.borrow_mut().define(fully_qualified, value);
3039 }
3040 }
3041 Err(e) if const_params.iter().any(|p| e.message.contains(p)) => {
3042 let key = format!("{}·{}", type_name, c.name.name);
3044 self.const_generic_deferred_consts.insert(key, c.value.clone());
3045 }
3046 Err(e) => return Err(e),
3047 }
3048 }
3049 }
3050 _ => {}
3051 }
3052 }
3053
3054 if let Some(trait_path) = &impl_block.trait_ {
3057 let t_name = trait_path
3058 .segments
3059 .iter()
3060 .map(|s| s.ident.name.as_str())
3061 .collect::<Vec<_>>()
3062 .join("·");
3063
3064 let impl_method_names: std::collections::HashSet<String> = impl_block
3066 .items
3067 .iter()
3068 .filter_map(|item| match item {
3069 ImplItem::Function(f) => Some(f.name.name.clone()),
3070 _ => None,
3071 })
3072 .collect();
3073
3074 if let Some(trait_def) = self.trait_defs.iter().find(|td| td.name.name == t_name).cloned() {
3076 for trait_item in &trait_def.items {
3077 if let crate::ast::TraitItem::Function(f) = trait_item {
3078 if f.body.is_some() && !impl_method_names.contains(&f.name.name) {
3079 let fn_value = self.create_function(f)?;
3080 let qualified_name = format!("{}·{}", type_name, f.name.name);
3081 self.globals
3082 .borrow_mut()
3083 .define(qualified_name.clone(), fn_value.clone());
3084
3085 if let Some(ref module) = self.current_module {
3086 let fully_qualified = format!("{}·{}", module, qualified_name);
3087 self.globals.borrow_mut().define(fully_qualified, fn_value);
3088 }
3089 }
3090 }
3091 }
3092 }
3093 }
3094
3095 let trait_name = impl_block.trait_.as_ref().map(|t| {
3097 t.segments.iter().map(|s| s.ident.name.as_str()).collect::<Vec<_>>().join("·")
3098 });
3099 let mut impl_fields = HashMap::new();
3100 impl_fields.insert("type_name".to_string(), Value::String(Rc::new(type_name.clone())));
3101 impl_fields.insert("trait_name".to_string(), match trait_name {
3102 Some(t) => Value::String(Rc::new(t)),
3103 None => Value::Null,
3104 });
3105 impl_fields.insert("method_count".to_string(), Value::Int(impl_block.items.len() as i64));
3106 self.ir_impls.borrow_mut().push(Value::Struct {
3107 name: "ImplDef".to_string(),
3108 fields: Rc::new(RefCell::new(impl_fields)),
3109 });
3110
3111 Ok(Value::Null)
3112 }
3113 Item::Module(module) => {
3114 let module_name = &module.name.name;
3116
3117 self.crate_modules.insert(module_name.clone());
3119
3120 if let Some(items) = &module.items {
3121 for item in items {
3124 match &item.node {
3125 Item::Const(c) => {
3126 let value = self.evaluate(&c.value)?;
3127 let qualified_name = format!("{}·{}", module_name, c.name.name);
3128 self.globals.borrow_mut().define(qualified_name, value);
3129 }
3130 Item::Static(s) => {
3131 let value = self.evaluate(&s.value)?;
3132 let qualified_name = format!("{}·{}", module_name, s.name.name);
3133 self.globals.borrow_mut().define(qualified_name, value);
3134 }
3135 Item::Function(func) => {
3136 let fn_value = self.create_function(func)?;
3137 let qualified_name = format!("{}·{}", module_name, func.name.name);
3138 self.globals.borrow_mut().define(qualified_name, fn_value);
3139 }
3140 Item::Struct(s) => {
3141 let qualified_name = format!("{}·{}", module_name, s.name.name);
3142 self.types
3143 .insert(qualified_name, TypeDef::Struct(s.clone()));
3144 }
3145 Item::Enum(e) => {
3146 let qualified_name = format!("{}·{}", module_name, e.name.name);
3147 self.types.insert(qualified_name, TypeDef::Enum(e.clone()));
3148 }
3149 Item::Impl(impl_block) => {
3150 let type_name = match &impl_block.self_ty {
3153 TypeExpr::Path(path) => path
3154 .segments
3155 .iter()
3156 .map(|s| s.ident.name.as_str())
3157 .collect::<Vec<_>>()
3158 .join("·"),
3159 _ => continue, };
3161
3162 let qualified_type = if type_name.contains("·") {
3165 type_name.clone()
3166 } else {
3167 format!("{}·{}", module_name, type_name)
3168 };
3169
3170 if let Some(trait_path) = &impl_block.trait_ {
3172 let trait_name = trait_path
3173 .segments
3174 .iter()
3175 .map(|s| s.ident.name.as_str())
3176 .collect::<Vec<_>>()
3177 .join("·");
3178 if trait_name == "Drop" {
3179 self.drop_types.insert(qualified_type.clone());
3180 }
3181 }
3182
3183 for impl_item in &impl_block.items {
3185 if let ImplItem::Function(func) = impl_item {
3186 let fn_value = self.create_function(func)?;
3187 let qualified_name =
3189 format!("{}·{}", qualified_type, func.name.name);
3190 self.globals
3191 .borrow_mut()
3192 .define(qualified_name.clone(), fn_value.clone());
3193
3194 let local_name =
3197 format!("{}·{}", type_name, func.name.name);
3198 if local_name != qualified_name {
3199 self.globals
3200 .borrow_mut()
3201 .define(local_name, fn_value.clone());
3202 }
3203 }
3204 }
3205 }
3206 Item::Module(nested_mod) => {
3207 let nested_name =
3209 format!("{}·{}", module_name, nested_mod.name.name);
3210
3211 self.crate_modules.insert(nested_name.clone());
3213
3214 if let Some(nested_items) = &nested_mod.items {
3215 let prev_module = self.current_module.clone();
3218 self.current_module = Some(nested_name.clone());
3219 for nested_item in nested_items {
3220 if let Err(e) = self.execute_item(&nested_item.node) {
3221 crate::sigil_warn!(
3222 "Warning: error in nested module {}: {}",
3223 nested_name,
3224 e
3225 );
3226 }
3227 }
3228 self.current_module = prev_module;
3229 }
3230 }
3231 _ => {} }
3233 }
3234 } else {
3235 if let Some(ref source_dir) = self.current_source_dir {
3237 let module_path =
3238 std::path::Path::new(source_dir).join(format!("{}.sigil", module_name));
3239
3240 if module_path.exists() {
3241 crate::sigil_debug!(
3242 "DEBUG Loading external module: {}",
3243 module_path.display()
3244 );
3245
3246 match std::fs::read_to_string(&module_path) {
3247 Ok(source) => {
3248 let mut parser = crate::Parser::new(&source);
3250 match parser.parse_file() {
3251 Ok(parsed_file) => {
3252 let prev_module = self.current_module.clone();
3254
3255 self.current_module = Some(module_name.clone());
3257
3258 for item in &parsed_file.items {
3260 if let Err(e) = self.execute_item(&item.node) {
3261 crate::sigil_warn!(
3262 "Warning: error in module {}: {}",
3263 module_name,
3264 e
3265 );
3266 }
3267 }
3268
3269 self.current_module = prev_module;
3271 }
3272 Err(e) => {
3273 crate::sigil_warn!(
3274 "Warning: failed to parse module {}: {:?}",
3275 module_name,
3276 e
3277 );
3278 }
3279 }
3280 }
3281 Err(e) => {
3282 crate::sigil_warn!(
3283 "Warning: failed to read module file {}: {}",
3284 module_path.display(),
3285 e
3286 );
3287 }
3288 }
3289 } else {
3290 crate::sigil_debug!(
3291 "DEBUG Module file not found: {} (source_dir={})",
3292 module_path.display(),
3293 source_dir
3294 );
3295 }
3296 } else {
3297 crate::sigil_debug!(
3298 "DEBUG No source_dir set, cannot load external module: {}",
3299 module_name
3300 );
3301 }
3302 }
3303
3304 let mut module_fields = HashMap::new();
3306 module_fields.insert("name".to_string(), Value::String(Rc::new(module_name.clone())));
3307 module_fields.insert("is_inline".to_string(), Value::Bool(module.items.is_some()));
3308 self.ir_modules.borrow_mut().push(Value::Struct {
3309 name: "ModuleDef".to_string(),
3310 fields: Rc::new(RefCell::new(module_fields)),
3311 });
3312
3313 Ok(Value::Null)
3314 }
3315 Item::Use(use_decl) => {
3316 self.process_use_tree(&use_decl.tree, &[])?;
3318 Ok(Value::Null)
3319 }
3320 Item::Trait(trait_def) => {
3321 self.trait_defs.push(trait_def.clone());
3323
3324 let method_names: Vec<Value> = trait_def.items.iter().filter_map(|item| {
3326 match item {
3327 crate::ast::TraitItem::Function(f) => Some(Value::String(Rc::new(f.name.name.clone()))),
3328 _ => None,
3329 }
3330 }).collect();
3331
3332 let mut trait_fields = HashMap::new();
3333 trait_fields.insert("name".to_string(), Value::String(Rc::new(trait_def.name.name.clone())));
3334 trait_fields.insert("method_count".to_string(), Value::Int(trait_def.items.len() as i64));
3335 trait_fields.insert("methods".to_string(), Value::Array(Rc::new(RefCell::new(method_names))));
3336 self.ir_traits.borrow_mut().push(Value::Struct {
3337 name: "TraitDef".to_string(),
3338 fields: Rc::new(RefCell::new(trait_fields)),
3339 });
3340
3341 Ok(Value::Null)
3342 }
3343 Item::Macro(m) => {
3344 let rules = m.rules.trim();
3348
3349 let inner = if rules.starts_with('{') && rules.ends_with('}') {
3351 rules[1..rules.len() - 1].trim()
3352 } else {
3353 rules
3354 };
3355
3356 let (params, body, field_map) = if let Some(arrow_pos) = inner.find("=>") {
3359 let pattern_part = inner[..arrow_pos].trim();
3361 let body_part = inner[arrow_pos + 2..].trim();
3362
3363 let mut field_map: HashMap<String, String> = HashMap::new();
3366 let params = if pattern_part.starts_with('(') {
3367 let inner_pat = if pattern_part.ends_with(')') {
3368 &pattern_part[1..pattern_part.len()-1]
3369 } else {
3370 &pattern_part[1..]
3371 };
3372 let mut extracted = Vec::new();
3374 let mut i = 0;
3375 let chars: Vec<char> = inner_pat.chars().collect();
3376 while i < chars.len() {
3377 if chars[i] == '$' {
3378 let dollar_pos = i;
3379 i += 1;
3380 let mut name = String::new();
3382 while i < chars.len() && chars[i].is_alphanumeric() || (i < chars.len() && chars[i] == '_') {
3383 name.push(chars[i]);
3384 i += 1;
3385 }
3386 if i < chars.len() && chars[i] == ':' {
3388 while i < chars.len() && !matches!(chars[i], ',' | ')' | '}') {
3389 i += 1;
3390 }
3391 }
3392 if !name.is_empty() {
3393 let mut j = dollar_pos;
3396 while j > 0 && chars[j - 1] == ' ' {
3398 j -= 1;
3399 }
3400 if j > 0 && chars[j - 1] == ':' {
3402 j -= 1;
3403 while j > 0 && chars[j - 1] == ' ' {
3405 j -= 1;
3406 }
3407 let field_end = j;
3409 while j > 0 && (chars[j - 1].is_alphanumeric() || chars[j - 1] == '_') {
3410 j -= 1;
3411 }
3412 if field_end > j {
3413 let field_name: String = chars[j..field_end].iter().collect();
3414 field_map.insert(field_name, name.clone());
3415 }
3416 }
3417 extracted.push(name);
3418 }
3419 } else {
3420 i += 1;
3421 }
3422 }
3423 extracted
3424 } else {
3425 Vec::new()
3426 };
3427
3428 let body = if body_part.starts_with('{') && body_part.ends_with('}') {
3430 body_part[1..body_part.len()-1].trim().to_string()
3431 } else {
3432 body_part.to_string()
3433 };
3434
3435 (params, body, field_map)
3436 } else if inner.starts_with('(') {
3437 let mut depth = 0;
3439 let mut paren_end = 0;
3440 for (i, c) in inner.chars().enumerate() {
3441 match c {
3442 '(' => depth += 1,
3443 ')' => {
3444 depth -= 1;
3445 if depth == 0 {
3446 paren_end = i;
3447 break;
3448 }
3449 }
3450 _ => {}
3451 }
3452 }
3453
3454 let param_str = &inner[1..paren_end];
3455 let params: Vec<String> = param_str
3456 .split(',')
3457 .map(|p| p.trim().trim_start_matches('$').to_string())
3458 .filter(|p| !p.is_empty())
3459 .collect();
3460
3461 let rest = inner[paren_end + 1..].trim();
3462 let body = if rest.starts_with('{') && rest.ends_with('}') {
3463 rest[1..rest.len() - 1].trim().to_string()
3464 } else {
3465 rest.to_string()
3466 };
3467
3468 (params, body, HashMap::new())
3469 } else {
3470 (Vec::new(), inner.to_string(), HashMap::new())
3472 };
3473
3474 self.user_macros
3476 .borrow_mut()
3477 .insert(m.name.name.clone(), (params, body, field_map));
3478
3479 Ok(Value::Null)
3480 }
3481 _ => Ok(Value::Null), }
3483 }
3484
3485 fn process_use_tree(
3487 &mut self,
3488 tree: &crate::ast::UseTree,
3489 prefix: &[String],
3490 ) -> Result<(), RuntimeError> {
3491 use crate::ast::UseTree;
3492 match tree {
3493 UseTree::Path {
3494 prefix: path_prefix,
3495 suffix,
3496 } => {
3497 let mut new_prefix = prefix.to_vec();
3499 new_prefix.push(path_prefix.name.clone());
3500 self.process_use_tree(suffix, &new_prefix)
3501 }
3502 UseTree::Name(name) => {
3503 let mut path = prefix.to_vec();
3505 path.push(name.name.clone());
3506 let qualified = path.join("·");
3507 let simple_name = name.name.clone();
3508
3509 if !prefix.is_empty() {
3512 let crate_name = &prefix[0];
3513
3514 if crate_name == "crate" || crate_name == "tome" || crate_name == "above" {
3517 if !self.types.contains_key(&qualified)
3518 && self.globals.borrow().get(&qualified).is_none()
3519 {
3520 if let Some(source_dir) = &self.current_source_dir.clone() {
3522 let module_name = if prefix.len() >= 2 {
3526 prefix[1].clone()
3527 } else {
3528 simple_name.clone()
3530 };
3531 let module_file = format!("{}/{}.sigil", source_dir, module_name);
3532 crate::sigil_debug!(
3533 "DEBUG process_use_tree: loading tome module '{}' from {}",
3534 module_name,
3535 module_file
3536 );
3537 if self.loaded_crates.contains(&module_file) {
3539 } else if std::path::Path::new(&module_file).exists() {
3541 self.loaded_crates.insert(module_file.clone());
3543
3544 if let Ok(source) = std::fs::read_to_string(&module_file) {
3546 let prev_module = self.current_module.clone();
3548
3549 self.current_module = Some(module_name.clone());
3552
3553 let mut parser = crate::Parser::new(&source);
3554 if let Ok(parsed_file) = parser.parse_file() {
3555 for item in &parsed_file.items {
3556 let _ = self.execute_item(&item.node);
3557 }
3558 }
3559
3560 self.current_module = prev_module;
3562 }
3563 }
3564 }
3565 }
3566 } else if !self.types.contains_key(&qualified)
3567 && self.globals.borrow().get(&qualified).is_none()
3568 && !self.loaded_crates.contains(crate_name)
3569 {
3570 if let Err(e) = self.load_crate(crate_name) {
3572 crate::sigil_debug!(
3573 "DEBUG process_use_tree: failed to load crate '{}': {}",
3574 crate_name,
3575 e
3576 );
3577 }
3578 }
3579 }
3580
3581 let lookup_name = if !prefix.is_empty()
3585 && (prefix[0] == "crate" || prefix[0] == "tome" || prefix[0] == "above")
3586 {
3587 simple_name.clone()
3589 } else {
3590 qualified.clone()
3591 };
3592
3593 if let Some(type_def) = self.types.get(&lookup_name).cloned() {
3594 if lookup_name != simple_name {
3595 self.types.insert(simple_name.clone(), type_def.clone());
3596 }
3597 self.types.insert(qualified.clone(), type_def);
3599 }
3600 let func = self.globals.borrow().get(&lookup_name).map(|v| v.clone());
3602 if let Some(val) = func {
3603 self.globals
3604 .borrow_mut()
3605 .define(simple_name.clone(), val.clone());
3606 if lookup_name != qualified {
3607 self.globals.borrow_mut().define(qualified.clone(), val);
3608 }
3609 }
3610
3611 let method_prefix = format!("{}·", qualified);
3615 let matching_methods: Vec<(String, Value)> = {
3616 let globals = self.globals.borrow();
3617 globals
3618 .values
3619 .iter()
3620 .filter(|(k, _)| k.starts_with(&method_prefix))
3621 .map(|(k, v)| {
3622 let method_suffix = k.strip_prefix(&method_prefix).unwrap();
3624 let new_name = format!("{}·{}", simple_name, method_suffix);
3625 (new_name, v.clone())
3626 })
3627 .collect()
3628 };
3629 for (name, val) in matching_methods {
3630 self.globals.borrow_mut().define(name, val);
3631 }
3632 Ok(())
3633 }
3634 UseTree::Rename { name, alias } => {
3635 let mut path = prefix.to_vec();
3637 path.push(name.name.clone());
3638 let qualified = path.join("·");
3639 let alias_name = alias.name.clone();
3640
3641 if let Some(type_def) = self.types.get(&qualified).cloned() {
3642 self.types.insert(alias_name.clone(), type_def);
3643 }
3644 let func = self.globals.borrow().get(&qualified).map(|v| v.clone());
3645 if let Some(val) = func {
3646 self.globals.borrow_mut().define(alias_name, val);
3647 }
3648 Ok(())
3649 }
3650 UseTree::Glob => {
3651 let path_prefix = prefix.join("·");
3653 let matching_types: Vec<(String, TypeDef)> = self
3655 .types
3656 .iter()
3657 .filter(|(k, _)| k.starts_with(&path_prefix) && k.len() > path_prefix.len())
3658 .map(|(k, v)| {
3659 let suffix = k
3660 .strip_prefix(&path_prefix)
3661 .unwrap()
3662 .trim_start_matches('·');
3663 (suffix.to_string(), v.clone())
3664 })
3665 .filter(|(k, _)| !k.contains('·')) .collect();
3667 for (name, def) in matching_types {
3668 self.types.insert(name, def);
3669 }
3670 let matching_funcs: Vec<(String, Value)> = {
3672 let globals = self.globals.borrow();
3673 globals
3674 .values
3675 .iter()
3676 .filter(|(k, _)| k.starts_with(&path_prefix) && k.len() > path_prefix.len())
3677 .map(|(k, v)| {
3678 let suffix = k
3679 .strip_prefix(&path_prefix)
3680 .unwrap()
3681 .trim_start_matches('·');
3682 (suffix.to_string(), v.clone())
3683 })
3684 .filter(|(k, _)| !k.contains('·'))
3685 .collect()
3686 };
3687 for (name, val) in matching_funcs {
3688 self.globals.borrow_mut().define(name, val);
3689 }
3690 Ok(())
3691 }
3692 UseTree::Group(trees) => {
3693 for tree in trees {
3695 self.process_use_tree(tree, prefix)?;
3696 }
3697 Ok(())
3698 }
3699 }
3700 }
3701
3702 fn create_function(&self, func: &crate::ast::Function) -> Result<Value, RuntimeError> {
3703 let params: Vec<String> = func
3704 .params
3705 .iter()
3706 .map(|p| Self::extract_param_name(&p.pattern))
3707 .collect();
3708
3709 let body = func
3710 .body
3711 .as_ref()
3712 .map(|b| Expr::Block(b.clone()))
3713 .unwrap_or(Expr::Literal(Literal::Bool(false)));
3714
3715 let generic_params = func
3717 .generics
3718 .as_ref()
3719 .map(|g| {
3720 g.params
3721 .iter()
3722 .filter_map(|p| match p {
3723 crate::ast::GenericParam::Type { name, .. } => Some(name.name.clone()),
3724 _ => None,
3725 })
3726 .collect()
3727 })
3728 .unwrap_or_default();
3729
3730 Ok(Value::Function(Rc::new(Function {
3731 name: Some(func.name.name.clone()),
3732 params,
3733 body,
3734 closure: self.environment.clone(),
3735 generic_params,
3736 })))
3737 }
3738
3739 fn extract_param_name(pattern: &Pattern) -> String {
3741 match pattern {
3742 Pattern::Ident { name, .. } => name.name.clone(),
3743 Pattern::Ref { pattern: inner, .. } => Self::extract_param_name(inner),
3745 Pattern::RefBinding { name, .. } => name.name.clone(),
3747 _ => "_".to_string(),
3748 }
3749 }
3750
3751 pub fn evaluate(&mut self, expr: &Expr) -> Result<Value, RuntimeError> {
3753 match expr {
3754 Expr::Literal(lit) => self.eval_literal(lit),
3755 Expr::Path(path) => self.eval_path(path),
3756 Expr::Binary { left, op, right } => self.eval_binary(left, op, right),
3757 Expr::Unary { op, expr } => self.eval_unary(op, expr),
3758 Expr::Call { func, args } => self.eval_call(func, args),
3759 Expr::Array(elements) => self.eval_array(elements),
3760 Expr::Tuple(elements) => self.eval_tuple(elements),
3761 Expr::Block(block) => self.eval_block(block),
3762 Expr::If {
3763 condition,
3764 then_branch,
3765 else_branch,
3766 } => self.eval_if(condition, then_branch, else_branch),
3767 Expr::Match { expr, arms } => self.eval_match(expr, arms),
3768 Expr::For {
3769 pattern,
3770 iter,
3771 body,
3772 ..
3773 } => self.eval_for(pattern, iter, body),
3774 Expr::While {
3775 condition, body, ..
3776 } => self.eval_while(condition, body),
3777 Expr::Loop { body, .. } => self.eval_loop(body),
3778 Expr::Return(value) => self.eval_return(value),
3779 Expr::Break { value, .. } => self.eval_break(value),
3780 Expr::Continue { .. } => Err(RuntimeError::new("continue")),
3781 Expr::Index { expr, index } => self.eval_index(expr, index),
3782 Expr::Field { expr, field } => self.eval_field(expr, field),
3783 Expr::MethodCall {
3784 receiver,
3785 method,
3786 args,
3787 ..
3788 } => self.eval_method_call(receiver, method, args),
3789 Expr::Incorporation { segments } => self.eval_incorporation(segments),
3792 Expr::Pipe { expr, operations } => self.eval_pipe(expr, operations),
3793 Expr::Closure { params, body, .. } => self.eval_closure(params, body),
3794 Expr::Struct { path, fields, rest } => self.eval_struct_literal(path, fields, rest),
3795 Expr::Evidential {
3796 expr,
3797 evidentiality,
3798 } => self.eval_evidential(expr, evidentiality),
3799 Expr::Range {
3800 start,
3801 end,
3802 inclusive,
3803 } => {
3804 crate::sigil_debug!("DEBUG evaluate: Expr::Range being evaluated standalone");
3805 self.eval_range(start, end, *inclusive)
3806 }
3807 Expr::Assign { target, value } => self.eval_assign(target, value),
3808 Expr::Let { pattern, value } => {
3809 let val = self.evaluate(value)?;
3812 if self.pattern_matches(pattern, &val)? {
3814 self.bind_pattern(pattern, val)?;
3816 Ok(Value::Bool(true))
3817 } else {
3818 Ok(Value::Bool(false))
3820 }
3821 }
3822 Expr::Await {
3823 expr: inner,
3824 evidentiality,
3825 } => {
3826 let value = self.evaluate(inner)?;
3827 let awaited = self.await_value(value)?;
3828 match evidentiality {
3830 Some(Evidentiality::Uncertain) => {
3831 self.unwrap_result_or_option(awaited, true, false)
3833 }
3834 Some(Evidentiality::Known) => {
3835 self.unwrap_result_or_option(awaited, true, true)
3837 }
3838 Some(Evidentiality::Reported)
3839 | Some(Evidentiality::Paradox)
3840 | Some(Evidentiality::Predicted) => {
3841 self.unwrap_result_or_option(awaited, false, false)
3843 }
3844 None => Ok(awaited),
3845 }
3846 }
3847 Expr::Macro { path, tokens } => {
3849 let macro_name = path
3850 .segments
3851 .last()
3852 .map(|s| s.ident.name.as_str())
3853 .unwrap_or("");
3854 crate::sigil_debug!(
3855 "DEBUG Expr::Macro: name='{}', tokens='{}'",
3856 macro_name,
3857 tokens
3858 );
3859
3860 match macro_name {
3861 "format" => self.eval_format_macro(tokens),
3862 "println" => {
3863 let formatted = self.eval_format_macro(tokens)?;
3864 if let Value::String(s) = formatted {
3865 println!("{}", s);
3866 }
3867 Ok(Value::Null)
3868 }
3869 "eprintln" => {
3870 let formatted = self.eval_format_macro(tokens)?;
3871 if let Value::String(s) = formatted {
3872 eprintln!("{}", s);
3873 }
3874 Ok(Value::Null)
3875 }
3876 "print" => {
3877 let formatted = self.eval_format_macro(tokens)?;
3878 if let Value::String(s) = formatted {
3879 print!("{}", s);
3880 }
3881 Ok(Value::Null)
3882 }
3883 "eprint" => {
3884 let formatted = self.eval_format_macro(tokens)?;
3885 if let Value::String(s) = formatted {
3886 eprint!("{}", s);
3887 }
3888 Ok(Value::Null)
3889 }
3890 "vec" => {
3891 self.eval_vec_macro(tokens)
3893 }
3894 "panic" => {
3895 let formatted = self.eval_format_macro(tokens)?;
3896 let msg = if let Value::String(s) = formatted {
3897 s.to_string()
3898 } else {
3899 "panic!".to_string()
3900 };
3901 Err(RuntimeError::new(format!("panic: {}", msg)))
3902 }
3903 "assert" => {
3904 let trimmed = tokens.trim();
3906 let mut parser = crate::parser::Parser::new(trimmed);
3907 match parser.parse_expr() {
3908 Ok(expr) => {
3909 let condition = self.evaluate(&expr)?;
3910 if self.is_truthy(&condition) {
3911 Ok(Value::Null)
3912 } else {
3913 Err(RuntimeError::new(format!(
3914 "assertion failed: `{}`",
3915 trimmed
3916 )))
3917 }
3918 }
3919 Err(_) => Err(RuntimeError::new(format!(
3920 "assert!: failed to parse expression: {}",
3921 trimmed
3922 ))),
3923 }
3924 }
3925 "assert_eq" => {
3926 let trimmed = tokens.trim();
3928 let mut depth = 0;
3930 let mut split_pos = None;
3931 for (i, c) in trimmed.char_indices() {
3932 match c {
3933 '(' | '[' | '{' => depth += 1,
3934 ')' | ']' | '}' => depth -= 1,
3935 ',' if depth == 0 => {
3936 split_pos = Some(i);
3937 break;
3938 }
3939 _ => {}
3940 }
3941 }
3942 if let Some(pos) = split_pos {
3943 let left_str = trimmed[..pos].trim();
3944 let right_str = trimmed[pos + 1..].trim();
3945 let mut p1 = crate::parser::Parser::new(left_str);
3946 let mut p2 = crate::parser::Parser::new(right_str);
3947 match (p1.parse_expr(), p2.parse_expr()) {
3948 (Ok(left_expr), Ok(right_expr)) => {
3949 let left = self.evaluate(&left_expr)?;
3950 let right = self.evaluate(&right_expr)?;
3951 if self.values_equal(&left, &right) {
3952 Ok(Value::Null)
3953 } else {
3954 Err(RuntimeError::new(format!(
3955 "assertion failed: `assert_eq!({}, {})` - left: {:?}, right: {:?}",
3956 left_str, right_str, left, right
3957 )))
3958 }
3959 }
3960 _ => Err(RuntimeError::new(format!(
3961 "assert_eq!: failed to parse expressions: {}",
3962 trimmed
3963 ))),
3964 }
3965 } else {
3966 Err(RuntimeError::new(format!(
3967 "assert_eq! requires two arguments separated by comma: {}",
3968 trimmed
3969 )))
3970 }
3971 }
3972 _ => {
3973 let macro_def = self.user_macros.borrow().get(macro_name).cloned();
3976 if let Some((params, body, field_map)) = macro_def {
3977 self.expand_user_macro(¶ms, &body, tokens, None, &field_map)
3979 } else {
3980 Ok(Value::String(Rc::new(tokens.clone())))
3982 }
3983 }
3984 }
3985 }
3986 Expr::Unsafe(block) => self.eval_block(block),
3988 Expr::Async { block, .. } => self.eval_block(block),
3990 Expr::Try(inner) => {
3992 let value = self.evaluate(inner)?;
3993 match &value {
3996 Value::Variant {
3997 enum_name,
3998 variant_name,
3999 fields,
4000 } => {
4001 match (enum_name.as_str(), variant_name.as_str()) {
4002 ("Result", "Ok") => {
4003 if let Some(f) = fields {
4004 Ok(f.first().cloned().unwrap_or(Value::Null))
4005 } else {
4006 Ok(Value::Null)
4007 }
4008 }
4009 ("Result", "Err") => {
4010 crate::sigil_debug!(
4011 "DEBUG Try propagating Result::Err with fields: {:?}",
4012 fields
4013 );
4014 let err_msg = if let Some(f) = fields {
4015 let first = f.first().cloned().unwrap_or(Value::Null);
4016 crate::sigil_debug!("DEBUG Try error first value: {}", first);
4017 match &first {
4019 Value::Struct { name, fields: sf } => {
4020 let field_str = sf
4021 .borrow()
4022 .iter()
4023 .map(|(k, v)| format!("{}: {}", k, v))
4024 .collect::<Vec<_>>()
4025 .join(", ");
4026 format!("{} {{ {} }}", name, field_str)
4027 }
4028 Value::Variant {
4029 enum_name: en,
4030 variant_name: vn,
4031 fields: vf,
4032 } => {
4033 let vf_str = vf
4034 .as_ref()
4035 .map(|vs| {
4036 vs.iter()
4037 .map(|v| format!("{}", v))
4038 .collect::<Vec<_>>()
4039 .join(", ")
4040 })
4041 .unwrap_or_default();
4042 format!("{}::{} {{ {} }}", en, vn, vf_str)
4043 }
4044 _ => format!("{}", first),
4045 }
4046 } else {
4047 "error".to_string()
4048 };
4049 Err(RuntimeError::new(format!("try failed: {}", err_msg)))
4050 }
4051 ("Option", "Some") => {
4052 if let Some(f) = fields {
4053 Ok(f.first().cloned().unwrap_or(Value::Null))
4054 } else {
4055 Ok(Value::Null)
4056 }
4057 }
4058 ("Option", "None") => Err(RuntimeError::new("try failed: None")),
4059 _ => Ok(value), }
4061 }
4062 _ => Ok(value), }
4064 }
4065 Expr::Cast { expr, ty } => {
4067 let value = self.evaluate(expr)?;
4068 let type_name = match ty {
4070 TypeExpr::Path(path) => {
4071 if !path.segments.is_empty() {
4072 path.segments
4073 .last()
4074 .map(|s| s.ident.name.as_str())
4075 .unwrap_or("")
4076 } else {
4077 ""
4078 }
4079 }
4080 _ => "",
4081 };
4082 match (value, type_name) {
4083 (Value::Char(c), "u8") => Ok(Value::Int(c as i64)),
4085 (Value::Char(c), "u16") => Ok(Value::Int(c as i64)),
4086 (Value::Char(c), "u32") => Ok(Value::Int(c as i64)),
4087 (Value::Char(c), "u64") => Ok(Value::Int(c as i64)),
4088 (Value::Char(c), "i8") => Ok(Value::Int(c as i64)),
4089 (Value::Char(c), "i16") => Ok(Value::Int(c as i64)),
4090 (Value::Char(c), "i32") => Ok(Value::Int(c as i64)),
4091 (Value::Char(c), "i64") => Ok(Value::Int(c as i64)),
4092 (Value::Char(c), "usize") => Ok(Value::Int(c as i64)),
4093 (Value::Char(c), "isize") => Ok(Value::Int(c as i64)),
4094 (Value::Int(i), "u8") => Ok(Value::Int(i)),
4096 (Value::Int(i), "u16") => Ok(Value::Int(i)),
4097 (Value::Int(i), "u32") => Ok(Value::Int(i)),
4098 (Value::Int(i), "u64") => Ok(Value::Int(i)),
4099 (Value::Int(i), "i8") => Ok(Value::Int(i)),
4100 (Value::Int(i), "i16") => Ok(Value::Int(i)),
4101 (Value::Int(i), "i32") => Ok(Value::Int(i)),
4102 (Value::Int(i), "i64") => Ok(Value::Int(i)),
4103 (Value::Int(i), "usize") => Ok(Value::Int(i)),
4104 (Value::Int(i), "isize") => Ok(Value::Int(i)),
4105 (Value::Float(f), "i32") => Ok(Value::Int(f as i64)),
4107 (Value::Float(f), "i64") => Ok(Value::Int(f as i64)),
4108 (Value::Float(f), "u32") => Ok(Value::Int(f as i64)),
4109 (Value::Float(f), "u64") => Ok(Value::Int(f as i64)),
4110 (Value::Int(i), "f32") => Ok(Value::Float(i as f64)),
4112 (Value::Int(i), "f64") => Ok(Value::Float(i as f64)),
4113 (Value::Int(i), "char") => {
4115 if let Some(c) = char::from_u32(i as u32) {
4116 Ok(Value::Char(c))
4117 } else {
4118 Err(RuntimeError::new(format!("invalid char code: {}", i)))
4119 }
4120 }
4121 (v, _) => Ok(v),
4123 }
4124 }
4125 Expr::NamedArg { value, .. } => self.evaluate(value),
4127 _ => Err(RuntimeError::new(format!(
4128 "Unsupported expression: {:?}",
4129 expr
4130 ))),
4131 }
4132 }
4133
4134 fn eval_assign(&mut self, target: &Expr, value: &Expr) -> Result<Value, RuntimeError> {
4135 let val = self.evaluate(value)?;
4136
4137 match target {
4138 Expr::Path(path) if path.segments.len() == 1 => {
4139 let name = &path.segments[0].ident.name;
4140 let in_env = self.environment.borrow().get(name).is_some();
4142 let in_globals = self.globals.borrow().get(name).is_some();
4143
4144 if !self.mutable_vars.borrow().contains(name) {
4145 if in_env || in_globals {
4147 return Err(RuntimeError::new(format!(
4148 "cannot assign to immutable variable '{}'. \
4149 Hint: Use `≔ Δ {} = ...` or `vary {} = ...` to declare mutable variables",
4150 name, name, name
4151 )));
4152 }
4153 }
4154
4155 if in_globals && !in_env {
4157 self.globals.borrow_mut().set(name, val.clone())?;
4158 } else {
4159 self.environment.borrow_mut().set(name, val.clone())?;
4160 }
4161 Ok(val)
4162 }
4163 Expr::Index { expr, index } => {
4164 let idx = self.evaluate(index)?;
4166 let idx = match idx {
4167 Value::Int(i) => i as usize,
4168 _ => return Err(RuntimeError::new("Index must be an integer")),
4169 };
4170
4171 if let Expr::Path(path) = expr.as_ref() {
4173 if path.segments.len() == 1 {
4174 let name = &path.segments[0].ident.name;
4175 let current = self.environment.borrow().get(name).ok_or_else(|| {
4176 RuntimeError::new(format!("Undefined variable: {}", name))
4177 })?;
4178
4179 if let Value::Array(arr) = current {
4180 let borrowed = arr.borrow();
4181 let mut new_arr = borrowed.clone();
4182 drop(borrowed);
4183 if idx < new_arr.len() {
4184 new_arr[idx] = val.clone();
4185 self.environment
4186 .borrow_mut()
4187 .set(name, Value::Array(Rc::new(RefCell::new(new_arr))))?;
4188 return Ok(val);
4189 }
4190 }
4191 }
4192 }
4193
4194 let target = self.evaluate(expr)?;
4199 let target = match &target {
4201 Value::Ref(r) => r.borrow().clone(),
4202 other => other.clone(),
4203 };
4204 match target {
4205 Value::Array(arr) => {
4206 let mut borrowed = arr.borrow_mut();
4207 if idx < borrowed.len() {
4208 borrowed[idx] = val.clone();
4209 return Ok(val);
4210 }
4211 Err(RuntimeError::new(format!(
4212 "Index {} out of bounds for array of length {}",
4213 idx,
4214 borrowed.len()
4215 )))
4216 }
4217 _ => Err(RuntimeError::new("Invalid index assignment target")),
4218 }
4219 }
4220 Expr::Field { expr, field } => {
4221 match expr.as_ref() {
4224 Expr::Path(path) if path.segments.len() == 1 => {
4225 let var_name = &path.segments[0].ident.name;
4226 let current = self.environment.borrow().get(var_name).ok_or_else(|| {
4227 RuntimeError::new(format!("Undefined variable: {}", var_name))
4228 })?;
4229
4230 match current {
4231 Value::Struct { fields, .. } => {
4232 fields.borrow_mut().insert(field.name.clone(), val.clone());
4233 Ok(val)
4234 }
4235 Value::Ref(r) => {
4236 let mut borrowed = r.borrow_mut();
4237 if let Value::Struct { fields, .. } = &mut *borrowed {
4238 fields.borrow_mut().insert(field.name.clone(), val.clone());
4239 Ok(val)
4240 } else {
4241 Err(RuntimeError::new("Cannot assign field on non-struct ref"))
4242 }
4243 }
4244 _ => Err(RuntimeError::new("Cannot assign field on non-struct")),
4245 }
4246 }
4247 _ => {
4248 let struct_val = self.evaluate(expr)?;
4250 match struct_val {
4251 Value::Struct { fields, .. } => {
4252 fields.borrow_mut().insert(field.name.clone(), val.clone());
4253 Ok(val)
4254 }
4255 Value::Ref(r) => {
4256 let mut borrowed = r.borrow_mut();
4257 if let Value::Struct { fields, .. } = &mut *borrowed {
4258 fields.borrow_mut().insert(field.name.clone(), val.clone());
4259 Ok(val)
4260 } else {
4261 Err(RuntimeError::new("Cannot assign field on non-struct"))
4262 }
4263 }
4264 _ => Err(RuntimeError::new("Cannot assign field on non-struct")),
4265 }
4266 }
4267 }
4268 }
4269 Expr::Unary {
4270 op: UnaryOp::Deref,
4271 expr: inner,
4272 } => {
4273 let ptr_val = self.evaluate(inner)?;
4276 match ptr_val {
4277 Value::Ref(r) => {
4278 *r.borrow_mut() = val.clone();
4279 Ok(val)
4280 }
4281 _ => Err(RuntimeError::new(
4282 "Cannot dereference assign to non-reference",
4283 )),
4284 }
4285 }
4286 Expr::Deref(inner) => {
4287 let ptr_val = self.evaluate(inner)?;
4290 match ptr_val {
4291 Value::Ref(r) => {
4292 *r.borrow_mut() = val.clone();
4293 Ok(val)
4294 }
4295 _ => Err(RuntimeError::new(
4296 "Cannot dereference assign to non-reference",
4297 )),
4298 }
4299 }
4300 _ => Err(RuntimeError::new("Invalid assignment target")),
4301 }
4302 }
4303
4304 fn eval_literal(&mut self, lit: &Literal) -> Result<Value, RuntimeError> {
4305 match lit {
4306 Literal::Int { value, base, .. } => {
4307 let n = self.parse_int(value, base)?;
4308 Ok(Value::Int(n))
4309 }
4310 Literal::Float { value, .. } => {
4311 let n: f64 = value
4312 .parse()
4313 .map_err(|_| RuntimeError::new(format!("Invalid float: {}", value)))?;
4314 Ok(Value::Float(n))
4315 }
4316 Literal::String(s) => Ok(Value::String(Rc::new(s.clone()))),
4317 Literal::MultiLineString(s) => Ok(Value::String(Rc::new(s.clone()))),
4318 Literal::RawString(s) => Ok(Value::String(Rc::new(s.clone()))),
4319 Literal::ByteString(bytes) => {
4320 let arr: Vec<Value> = bytes.iter().map(|&b| Value::Int(b as i64)).collect();
4322 Ok(Value::Array(Rc::new(RefCell::new(arr))))
4323 }
4324 Literal::InterpolatedString { parts } => {
4325 let mut result = String::new();
4327 let mut combined_evidence: Option<Evidence> = None;
4328
4329 for part in parts {
4330 match part {
4331 InterpolationPart::Text(s) => result.push_str(s),
4332 InterpolationPart::Expr(expr) => {
4333 let value = self.evaluate(expr)?;
4334
4335 combined_evidence = Self::combine_evidence(
4337 combined_evidence,
4338 Self::extract_evidence(&value),
4339 );
4340
4341 if let Some(affect) = Self::extract_affect(&value) {
4343 combined_evidence = Self::combine_evidence(
4344 combined_evidence,
4345 Self::affect_to_evidence(affect),
4346 );
4347 }
4348
4349 let display_value = Self::unwrap_value(&value);
4351 result.push_str(&format!("{}", display_value));
4352 }
4353 }
4354 }
4355
4356 let string_value = Value::String(Rc::new(result));
4358 match combined_evidence {
4359 Some(evidence) => Ok(Value::Evidential {
4360 value: Box::new(string_value),
4361 evidence,
4362 }),
4363 None => Ok(string_value),
4364 }
4365 }
4366 Literal::SigilStringSql(s) => {
4367 Ok(Value::String(Rc::new(s.clone())))
4370 }
4371 Literal::SigilStringRoute(s) => {
4372 Ok(Value::String(Rc::new(s.clone())))
4375 }
4376 Literal::Char(c) => Ok(Value::Char(*c)),
4377 Literal::ByteChar(b) => Ok(Value::Int(*b as i64)),
4378 Literal::Bool(b) => Ok(Value::Bool(*b)),
4379 Literal::Null => Ok(Value::Null),
4380 Literal::Empty => Ok(Value::Empty),
4381 Literal::Infinity => Ok(Value::Infinity),
4382 Literal::Circle => Ok(Value::Int(0)), }
4384 }
4385
4386 fn parse_int(&self, value: &str, base: &NumBase) -> Result<i64, RuntimeError> {
4387 let (radix, prefix_len) = match base {
4388 NumBase::Binary => (2, 2), NumBase::Octal => (8, 2), NumBase::Decimal => (10, 0),
4391 NumBase::Hex => (16, 2), NumBase::Vigesimal => (20, 2), NumBase::Sexagesimal => (60, 2), NumBase::Duodecimal => (12, 2), NumBase::Explicit(b) => (*b as u32, 0),
4396 };
4397
4398 let clean = value[prefix_len..].replace('_', "");
4399 i64::from_str_radix(&clean, radix)
4400 .map_err(|_| RuntimeError::new(format!("Invalid integer: {}", value)))
4401 }
4402
4403 fn eval_path(&self, path: &TypePath) -> Result<Value, RuntimeError> {
4404 if path.segments.len() == 1 {
4405 let name = &path.segments[0].ident.name;
4406 if let Some(val) = self.environment.borrow().get(name) {
4410 if self.linear_state.vars.borrow().contains(name) {
4412 if self.linear_state.consumed.borrow().contains(name) {
4414 return Err(RuntimeError::linear_type_violation(name));
4415 }
4416 self.linear_state.consumed.borrow_mut().insert(name.clone());
4418 }
4419 return Ok(val);
4420 }
4421 if name == "_" {
4423 return Ok(Value::Null);
4424 }
4425 if name == "Self" {
4427 if let Some(ref self_type) = self.current_self_type {
4428 if let Some(TypeDef::Struct(struct_def)) = self.types.get(self_type) {
4430 if matches!(struct_def.fields, crate::ast::StructFields::Unit) {
4431 return Ok(Value::Struct {
4432 name: self_type.clone(),
4433 fields: Rc::new(RefCell::new(HashMap::new())),
4434 });
4435 }
4436 }
4437 return Ok(Value::Struct {
4439 name: self_type.clone(),
4440 fields: Rc::new(RefCell::new(HashMap::new())),
4441 });
4442 }
4443 }
4444 if name.len() <= 2 {
4445 crate::sigil_debug!("DEBUG Undefined variable '{}' (len={})", name, name.len());
4446 }
4447 Err(RuntimeError::undefined_variable(name))
4448 } else {
4449 let full_name = path
4452 .segments
4453 .iter()
4454 .map(|s| {
4455 if s.ident.name == "Self" {
4457 if let Some(ref self_type) = self.current_self_type {
4458 return self_type.clone();
4459 }
4460 }
4461 if let Some(concrete) = self.generic_type_bindings.get(&s.ident.name) {
4463 return concrete.clone();
4464 }
4465 s.ident.name.clone()
4466 })
4467 .collect::<Vec<_>>()
4468 .join("·");
4469
4470 if let Some(val) = self.environment.borrow().get(&full_name) {
4471 return Ok(val);
4472 }
4473
4474 if let Some(val) = self.globals.borrow().get(&full_name) {
4476 return Ok(val);
4477 }
4478
4479 if let Some(ref current_mod) = self.current_module {
4482 let crate_name = current_mod.split('·').next().unwrap_or(current_mod);
4484 let crate_qualified = format!("{}·{}", crate_name, full_name);
4485 if full_name.contains("execute") {
4486 crate::sigil_debug!(
4487 "DEBUG eval_path: Looking for '{}' with crate_qualified='{}'",
4488 full_name,
4489 crate_qualified
4490 );
4491 }
4492 if let Some(val) = self.globals.borrow().get(&crate_qualified) {
4493 crate::sigil_debug!(
4494 "DEBUG eval_path: FOUND '{}' via crate_qualified",
4495 crate_qualified
4496 );
4497 return Ok(val);
4498 }
4499 } else if full_name.contains("execute") {
4500 crate::sigil_debug!(
4501 "DEBUG eval_path: current_module is None, can't resolve '{}'",
4502 full_name
4503 );
4504 }
4505
4506 if full_name.ends_with("·new") {
4508 crate::sigil_debug!(
4509 "DEBUG eval_path: Looking for '{}' - NOT FOUND in globals",
4510 full_name
4511 );
4512 }
4513
4514 if path.segments.len() >= 2 {
4518 let variant_name = &path.segments.last().unwrap().ident.name;
4519
4520 let type_segments: Vec<&str> = path.segments[..path.segments.len() - 1]
4522 .iter()
4523 .map(|s| s.ident.name.as_str())
4524 .collect();
4525
4526 let type_name_direct = type_segments.join("::");
4531 let type_name_qualified = type_segments.join("·");
4532
4533 let enum_def_and_name = self
4535 .types
4536 .get(&type_name_direct)
4537 .map(|td| (td, type_name_direct.clone()))
4538 .or_else(|| {
4539 self.types
4540 .get(&type_name_qualified)
4541 .map(|td| (td, type_name_qualified.clone()))
4542 });
4543
4544 if let Some((TypeDef::Enum(enum_def), actual_enum_name)) = enum_def_and_name {
4545 for variant in &enum_def.variants {
4546 if &variant.name.name == variant_name {
4547 if matches!(variant.fields, crate::ast::StructFields::Unit) {
4549 return Ok(Value::Variant {
4550 enum_name: actual_enum_name,
4551 variant_name: variant_name.clone(),
4552 fields: None,
4553 });
4554 }
4555 }
4556 }
4557 }
4558
4559 for (actual_type_name, type_def) in &self.types {
4561 if let TypeDef::Enum(enum_def) = type_def {
4562 let matches = actual_type_name == &type_name_direct
4565 || actual_type_name == &type_name_qualified
4566 || actual_type_name.ends_with(&format!("·{}", type_name_direct));
4567
4568 if matches {
4569 for variant in &enum_def.variants {
4570 if &variant.name.name == variant_name {
4571 if matches!(variant.fields, crate::ast::StructFields::Unit) {
4572 return Ok(Value::Variant {
4573 enum_name: actual_type_name.clone(),
4574 variant_name: variant_name.clone(),
4575 fields: None,
4576 });
4577 }
4578 }
4579 }
4580 }
4581 }
4582 }
4583 }
4584
4585 let last_name = &path.segments.last().unwrap().ident.name;
4587 if let Some(val) = self.environment.borrow().get(last_name) {
4588 if last_name == "new" {
4590 crate::sigil_debug!(
4591 "DEBUG eval_path: FALLBACK from '{}' to '{}' - found in env",
4592 full_name,
4593 last_name
4594 );
4595 }
4596 return Ok(val);
4597 }
4598
4599 if path.segments.len() == 2 && path.segments[0].ident.name == "Self" {
4601 if let Some(ref self_type) = self.current_self_type {
4602 let qualified = format!("{}·{}", self_type, last_name);
4604 if let Some(val) = self.globals.borrow().get(&qualified) {
4605 return Ok(val);
4606 }
4607 }
4608 }
4609
4610 if let Some((enum_name, variant_name, arity)) =
4612 self.variant_constructors.get(&full_name).cloned()
4613 {
4614 if arity == 0 {
4617 return Ok(Value::Variant {
4618 enum_name,
4619 variant_name,
4620 fields: None,
4621 });
4622 }
4623 }
4627
4628 if path.segments.len() == 2 {
4631 if let Some(val) = self.globals.borrow().get(&full_name) {
4633 return Ok(val);
4634 }
4635 if let Some(ref current_mod) = self.current_module {
4637 let crate_name = current_mod.split('·').next().unwrap_or(current_mod);
4638 let module_qualified = format!("{}·{}", crate_name, full_name);
4639 if let Some(val) = self.globals.borrow().get(&module_qualified) {
4640 return Ok(val);
4641 }
4642 }
4643 }
4644
4645 if path.segments.len() == 2 {
4647 let type_name = &path.segments[0].ident.name;
4648 let method_name = &path.segments[1].ident.name;
4649
4650 let is_method = method_name
4652 .chars()
4653 .next()
4654 .map_or(false, |c| c.is_lowercase())
4655 || method_name == "new"
4656 || method_name == "default"
4657 || method_name == "from"
4658 || method_name == "try_from"
4659 || method_name == "into"
4660 || method_name == "with_capacity"
4661 || method_name == "from_str";
4662
4663 if is_method {
4664 return Ok(Value::Struct {
4667 name: format!("__constructor__{}", type_name),
4668 fields: Rc::new(RefCell::new(HashMap::new())),
4669 });
4670 } else {
4671 if let Some(TypeDef::Enum(enum_def)) = self.types.get(type_name) {
4673 let variant_exists = enum_def
4675 .variants
4676 .iter()
4677 .any(|v| v.name.name == *method_name);
4678 if !variant_exists {
4679 return Err(RuntimeError::new(format!(
4680 "no variant '{}' on enum '{}'",
4681 method_name, type_name
4682 )));
4683 }
4684 }
4685 return Ok(Value::Variant {
4687 enum_name: type_name.clone(),
4688 variant_name: method_name.clone(),
4689 fields: None,
4690 });
4691 }
4692 }
4693
4694 Err(RuntimeError::new(format!(
4695 "Undefined: {} (tried {} and {})",
4696 full_name, full_name, last_name
4697 )))
4698 }
4699 }
4700
4701 fn eval_binary(
4702 &mut self,
4703 left: &Expr,
4704 op: &BinOp,
4705 right: &Expr,
4706 ) -> Result<Value, RuntimeError> {
4707 let lhs = self.evaluate(left)?;
4708
4709 match op {
4711 BinOp::And => {
4712 if !self.is_truthy(&lhs) {
4713 return Ok(Value::Bool(false));
4714 }
4715 let rhs = self.evaluate(right)?;
4716 return Ok(Value::Bool(self.is_truthy(&rhs)));
4717 }
4718 BinOp::Or => {
4719 if self.is_truthy(&lhs) {
4720 return Ok(Value::Bool(true));
4721 }
4722 let rhs = self.evaluate(right)?;
4723 return Ok(Value::Bool(self.is_truthy(&rhs)));
4724 }
4725 _ => {}
4726 }
4727
4728 let rhs = self.evaluate(right)?;
4729
4730 let lhs = Self::unwrap_all(&lhs);
4732 let rhs = Self::unwrap_all(&rhs);
4733
4734 let lhs = self.resolve_constant(lhs);
4736 let rhs = self.resolve_constant(rhs);
4737
4738 if matches!(op, BinOp::Mul)
4740 && (matches!(lhs, Value::Null)
4741 || matches!(rhs, Value::Null)
4742 || matches!(lhs, Value::Struct { .. })
4743 || matches!(rhs, Value::Struct { .. }))
4744 {
4745 crate::sigil_debug!("DEBUG eval_binary Mul: left={:?}, right={:?}", left, right);
4746 crate::sigil_debug!(
4747 "DEBUG eval_binary Mul: lhs={}, rhs={}",
4748 self.format_value(&lhs),
4749 self.format_value(&rhs)
4750 );
4751 }
4752
4753 match (lhs, rhs) {
4754 (Value::Int(a), Value::Int(b)) => self.int_binary_op(a, b, op),
4755 (Value::Float(a), Value::Float(b)) => self.float_binary_op(a, b, op),
4756 (Value::Int(a), Value::Float(b)) => self.float_binary_op(a as f64, b, op),
4757 (Value::Float(a), Value::Int(b)) => self.float_binary_op(a, b as f64, op),
4758 (Value::String(a), Value::String(b)) => match op {
4759 BinOp::Add | BinOp::Concat => Ok(Value::String(Rc::new(format!("{}{}", a, b)))),
4760 BinOp::Eq => Ok(Value::Bool(*a == *b)),
4761 BinOp::Ne => Ok(Value::Bool(*a != *b)),
4762 _ => Err(RuntimeError::new("Invalid string operation")),
4763 },
4764 (Value::Bool(a), Value::Bool(b)) => match op {
4765 BinOp::Eq => Ok(Value::Bool(a == b)),
4766 BinOp::Ne => Ok(Value::Bool(a != b)),
4767 _ => Err(RuntimeError::new("Invalid boolean operation")),
4768 },
4769 (Value::Array(a), Value::Array(b)) => match op {
4770 BinOp::Concat => {
4771 let mut result = a.borrow().clone();
4772 result.extend(b.borrow().iter().cloned());
4773 Ok(Value::Array(Rc::new(RefCell::new(result))))
4774 }
4775 BinOp::Convolve => {
4776 let arr_a = a.borrow();
4782 let arr_b = b.borrow();
4783
4784 let is_shard_array = arr_a.first().map_or(
4786 false,
4787 |v| matches!(v, Value::Struct { name, .. } if name == "Shard"),
4788 );
4789
4790 if is_shard_array {
4791 let mut seen_indices: std::collections::HashSet<i64> =
4793 std::collections::HashSet::new();
4794 let mut result = Vec::new();
4795
4796 for shard in arr_a.iter() {
4798 if let Value::Struct { fields, .. } = shard {
4799 if let Some(Value::Int(idx)) = fields.borrow().get("index") {
4800 if seen_indices.insert(*idx) {
4801 result.push(shard.clone());
4802 }
4803 } else {
4804 result.push(shard.clone());
4806 }
4807 } else {
4808 result.push(shard.clone());
4809 }
4810 }
4811
4812 for shard in arr_b.iter() {
4814 if let Value::Struct { fields, .. } = shard {
4815 if let Some(Value::Int(idx)) = fields.borrow().get("index") {
4816 if seen_indices.insert(*idx) {
4817 result.push(shard.clone());
4818 }
4819 } else {
4821 result.push(shard.clone());
4823 }
4824 } else {
4825 result.push(shard.clone());
4826 }
4827 }
4828
4829 Ok(Value::Array(Rc::new(RefCell::new(result))))
4830 } else {
4831 let mut result = arr_a.clone();
4833 result.extend(arr_b.iter().cloned());
4834 Ok(Value::Array(Rc::new(RefCell::new(result))))
4835 }
4836 }
4837 BinOp::Eq => {
4838 let arr_a = a.borrow();
4839 let arr_b = b.borrow();
4840 let equal = arr_a.len() == arr_b.len()
4841 && arr_a.iter().zip(arr_b.iter()).all(|(x, y)| {
4842 self.values_equal(x, y)
4843 });
4844 Ok(Value::Bool(equal))
4845 }
4846 BinOp::Ne => {
4847 let arr_a = a.borrow();
4848 let arr_b = b.borrow();
4849 let equal = arr_a.len() == arr_b.len()
4850 && arr_a.iter().zip(arr_b.iter()).all(|(x, y)| {
4851 self.values_equal(x, y)
4852 });
4853 Ok(Value::Bool(!equal))
4854 }
4855 _ => Err(RuntimeError::new("Invalid array operation")),
4856 },
4857 (Value::Null, Value::Null) => match op {
4859 BinOp::Eq => Ok(Value::Bool(true)),
4860 BinOp::Ne => Ok(Value::Bool(false)),
4861 _ => {
4862 crate::sigil_debug!("DEBUG: null op {:?} on (Null, Null)", op);
4863 Err(RuntimeError::new(format!(
4864 "Invalid null operation: {:?} on (Null, Null)",
4865 op
4866 )))
4867 }
4868 },
4869 (Value::Null, other) | (other, Value::Null) => match op {
4870 BinOp::Eq => Ok(Value::Bool(false)),
4871 BinOp::Ne => Ok(Value::Bool(true)),
4872 _ => {
4873 crate::sigil_debug!(
4874 "DEBUG: null op {:?} with other={}",
4875 op,
4876 self.format_value(&other)
4877 );
4878 Err(RuntimeError::new(format!(
4879 "Invalid null operation: {:?}",
4880 op
4881 )))
4882 }
4883 },
4884 (Value::Char(a), Value::Char(b)) => match op {
4886 BinOp::Eq => Ok(Value::Bool(a == b)),
4887 BinOp::Ne => Ok(Value::Bool(a != b)),
4888 BinOp::Lt => Ok(Value::Bool(a < b)),
4889 BinOp::Le => Ok(Value::Bool(a <= b)),
4890 BinOp::Gt => Ok(Value::Bool(a > b)),
4891 BinOp::Ge => Ok(Value::Bool(a >= b)),
4892 _ => Err(RuntimeError::new("Invalid char operation")),
4893 },
4894 (Value::String(a), Value::Char(b)) => match op {
4896 BinOp::Add | BinOp::Concat => Ok(Value::String(Rc::new(format!("{}{}", a, b)))),
4897 _ => Err(RuntimeError::new("Invalid string/char operation")),
4898 },
4899 (Value::Char(a), Value::String(b)) => match op {
4900 BinOp::Add | BinOp::Concat => Ok(Value::String(Rc::new(format!("{}{}", a, b)))),
4901 _ => Err(RuntimeError::new("Invalid char/string operation")),
4902 },
4903 (
4905 Value::Variant {
4906 enum_name: e1,
4907 variant_name: v1,
4908 fields: f1,
4909 },
4910 Value::Variant {
4911 enum_name: e2,
4912 variant_name: v2,
4913 fields: f2,
4914 },
4915 ) => match op {
4916 BinOp::Eq => {
4917 let eq = e1 == e2
4918 && v1 == v2
4919 && match (f1, f2) {
4920 (None, None) => true,
4921 (Some(a), Some(b)) => Rc::ptr_eq(&a, &b),
4922 _ => false,
4923 };
4924 Ok(Value::Bool(eq))
4925 }
4926 BinOp::Ne => {
4927 let eq = e1 == e2
4928 && v1 == v2
4929 && match (f1, f2) {
4930 (None, None) => true,
4931 (Some(a), Some(b)) => Rc::ptr_eq(&a, &b),
4932 _ => false,
4933 };
4934 Ok(Value::Bool(!eq))
4935 }
4936 _ => Err(RuntimeError::new("Invalid variant operation")),
4937 },
4938 (
4940 Value::Struct {
4941 name: n1,
4942 fields: f1,
4943 },
4944 Value::Struct {
4945 name: n2,
4946 fields: f2,
4947 },
4948 ) => match op {
4949 BinOp::Eq => {
4950 if n1 == "Cbit" && n2 == "Cbit" {
4952 let v1 = f1.borrow().get("__value__").cloned();
4953 let v2 = f2.borrow().get("__value__").cloned();
4954 let eq = match (v1, v2) {
4955 (Some(Value::Bool(a)), Some(Value::Bool(b))) => a == b,
4956 (Some(Value::Int(a)), Some(Value::Int(b))) => a == b,
4957 _ => Rc::ptr_eq(&f1, &f2),
4958 };
4959 Ok(Value::Bool(eq))
4960 } else {
4961 Ok(Value::Bool(n1 == n2 && Rc::ptr_eq(&f1, &f2)))
4962 }
4963 }
4964 BinOp::Ne => {
4965 if n1 == "Cbit" && n2 == "Cbit" {
4967 let v1 = f1.borrow().get("__value__").cloned();
4968 let v2 = f2.borrow().get("__value__").cloned();
4969 let neq = match (v1, v2) {
4970 (Some(Value::Bool(a)), Some(Value::Bool(b))) => a != b,
4971 (Some(Value::Int(a)), Some(Value::Int(b))) => a != b,
4972 _ => !Rc::ptr_eq(&f1, &f2),
4973 };
4974 Ok(Value::Bool(neq))
4975 } else {
4976 Ok(Value::Bool(n1 != n2 || !Rc::ptr_eq(&f1, &f2)))
4977 }
4978 }
4979 BinOp::Mul if n1 == "Tensor" && n2 == "Tensor" => {
4981 let val1 = tensor_scalar_from_fields(&f1.borrow())
4983 .ok_or_else(|| RuntimeError::new("left tensor has no scalar data"))?;
4984 let val2 = tensor_scalar_from_fields(&f2.borrow())
4985 .ok_or_else(|| RuntimeError::new("right tensor has no scalar data"))?;
4986 let result = val1 * val2;
4988 let mut fields = std::collections::HashMap::new();
4989 fields.insert(
4990 "shape".to_string(),
4991 Value::Array(Rc::new(RefCell::new(vec![]))),
4992 );
4993 fields.insert(
4994 "data".to_string(),
4995 Value::Array(Rc::new(RefCell::new(vec![Value::Float(result)]))),
4996 );
4997 fields.insert("requires_grad".to_string(), Value::Bool(false));
4998 fields.insert("_value".to_string(), Value::Float(result));
4999 fields.insert("_op".to_string(), Value::String(Rc::new("mul".to_string())));
5001 fields.insert("_operand1".to_string(), Value::Float(val1));
5002 fields.insert("_operand2".to_string(), Value::Float(val2));
5003 Ok(Value::Struct {
5004 name: "Tensor".to_string(),
5005 fields: Rc::new(RefCell::new(fields)),
5006 })
5007 }
5008 BinOp::MatMul if n1 == "Tensor" && n2 == "Tensor" => {
5010 let f1_ref = f1.borrow();
5012 let f2_ref = f2.borrow();
5013 let shape1 = tensor_shape_from_fields(&f1_ref)
5014 .ok_or_else(|| RuntimeError::new("left tensor has no shape"))?;
5015 let shape2 = tensor_shape_from_fields(&f2_ref)
5016 .ok_or_else(|| RuntimeError::new("right tensor has no shape"))?;
5017 let data1 = tensor_data_from_fields(&f1_ref)
5018 .ok_or_else(|| RuntimeError::new("left tensor has no data"))?;
5019 let data2 = tensor_data_from_fields(&f2_ref)
5020 .ok_or_else(|| RuntimeError::new("right tensor has no data"))?;
5021 drop(f1_ref);
5022 drop(f2_ref);
5023
5024 let m = if shape1.len() >= 2 { shape1[0] } else { 1 };
5026 let n1_dim = if shape1.len() >= 2 {
5027 shape1[1]
5028 } else if !shape1.is_empty() {
5029 shape1[0]
5030 } else {
5031 1
5032 };
5033 let p = if shape2.len() >= 2 { shape2[1] } else { 1 };
5034
5035 let mut result_data = vec![0.0; m * p];
5037 for i in 0..m {
5038 for j in 0..p {
5039 let mut sum = 0.0;
5040 for k in 0..n1_dim {
5041 let a_idx = i * n1_dim + k;
5042 let b_idx = k * p + j;
5043 if a_idx < data1.len() && b_idx < data2.len() {
5044 sum += data1[a_idx] * data2[b_idx];
5045 }
5046 }
5047 result_data[i * p + j] = sum;
5048 }
5049 }
5050
5051 let left_requires_grad =
5053 matches!(f1.borrow().get("requires_grad"), Some(Value::Bool(true)));
5054 let right_requires_grad =
5055 matches!(f2.borrow().get("requires_grad"), Some(Value::Bool(true)));
5056
5057 let mut fields = std::collections::HashMap::new();
5059 let shape_arr = Value::Array(Rc::new(RefCell::new(vec![
5060 Value::Int(m as i64),
5061 Value::Int(p as i64),
5062 ])));
5063 let data_arr = Value::Array(Rc::new(RefCell::new(
5064 result_data.into_iter().map(Value::Float).collect(),
5065 )));
5066 fields.insert("__shape__".to_string(), shape_arr.clone());
5067 fields.insert("__data__".to_string(), data_arr.clone());
5068 fields.insert("shape".to_string(), shape_arr);
5069 fields.insert("data".to_string(), data_arr);
5070 fields.insert(
5071 "__requires_grad__".to_string(),
5072 Value::Bool(left_requires_grad || right_requires_grad),
5073 );
5074 fields.insert(
5075 "requires_grad".to_string(),
5076 Value::Bool(left_requires_grad || right_requires_grad),
5077 );
5078
5079 if left_requires_grad {
5081 fields.insert(
5083 "_grad_left".to_string(),
5084 Value::Struct {
5085 name: "Tensor".to_string(),
5086 fields: f1.clone(),
5087 },
5088 );
5089 }
5090 if right_requires_grad {
5091 fields.insert(
5092 "_grad_right".to_string(),
5093 Value::Struct {
5094 name: "Tensor".to_string(),
5095 fields: f2.clone(),
5096 },
5097 );
5098 }
5099 fields.insert(
5100 "_op".to_string(),
5101 Value::String(Rc::new("matmul".to_string())),
5102 );
5103
5104 Ok(Value::Struct {
5105 name: "Tensor".to_string(),
5106 fields: Rc::new(RefCell::new(fields)),
5107 })
5108 }
5109 BinOp::Hadamard if n1 == "Tensor" && n2 == "Tensor" => {
5111 let f1_ref = f1.borrow();
5113 let f2_ref = f2.borrow();
5114 let shape1 = match f1_ref.get("shape") {
5116 Some(Value::Array(arr)) => arr.borrow().clone(),
5117 _ => return Err(RuntimeError::new("left tensor has no shape")),
5118 };
5119 let data1 = tensor_data_from_fields(&f1_ref)
5120 .ok_or_else(|| RuntimeError::new("left tensor has no data"))?;
5121 let data2 = tensor_data_from_fields(&f2_ref)
5122 .ok_or_else(|| RuntimeError::new("right tensor has no data"))?;
5123 drop(f1_ref);
5124 drop(f2_ref);
5125
5126 let result_data: Vec<Value> = data1
5128 .iter()
5129 .zip(data2.iter())
5130 .map(|(a, b)| Value::Float(a * b))
5131 .collect();
5132
5133 let mut fields = std::collections::HashMap::new();
5134 fields.insert(
5135 "shape".to_string(),
5136 Value::Array(Rc::new(RefCell::new(shape1))),
5137 );
5138 fields.insert(
5139 "data".to_string(),
5140 Value::Array(Rc::new(RefCell::new(result_data))),
5141 );
5142 fields.insert("requires_grad".to_string(), Value::Bool(false));
5143 Ok(Value::Struct {
5144 name: "Tensor".to_string(),
5145 fields: Rc::new(RefCell::new(fields)),
5146 })
5147 }
5148 BinOp::Add if n1 == "Tensor" && n2 == "Tensor" => {
5150 let f1_ref = f1.borrow();
5152 let f2_ref = f2.borrow();
5153 let shape1: Vec<i64> = tensor_shape_from_fields(&f1_ref)
5155 .ok_or_else(|| RuntimeError::new("left tensor has no shape"))?
5156 .iter()
5157 .map(|&x| x as i64)
5158 .collect();
5159 let shape2: Vec<i64> = tensor_shape_from_fields(&f2_ref)
5160 .ok_or_else(|| RuntimeError::new("right tensor has no shape"))?
5161 .iter()
5162 .map(|&x| x as i64)
5163 .collect();
5164 let data1 = tensor_data_from_fields(&f1_ref)
5165 .ok_or_else(|| RuntimeError::new("left tensor has no data"))?;
5166 let data2 = tensor_data_from_fields(&f2_ref)
5167 .ok_or_else(|| RuntimeError::new("right tensor has no data"))?;
5168 drop(f1_ref);
5169 drop(f2_ref);
5170
5171 let result_data: Vec<f64>;
5173 let result_shape: Vec<Value>;
5174
5175 let size1: i64 = shape1.iter().product();
5177 let size2: i64 = shape2.iter().product();
5178
5179 if size1 == size2 {
5180 result_data = data1.iter().zip(data2.iter()).map(|(a, b)| a + b).collect();
5182 result_shape = shape1.into_iter().map(Value::Int).collect();
5183 } else if size1 > size2 && size1 % size2 == 0 {
5184 result_data = data1
5186 .iter()
5187 .enumerate()
5188 .map(|(i, a)| a + data2[i % data2.len()])
5189 .collect();
5190 result_shape = shape1.into_iter().map(Value::Int).collect();
5191 } else if size2 > size1 && size2 % size1 == 0 {
5192 result_data = data2
5194 .iter()
5195 .enumerate()
5196 .map(|(i, b)| data1[i % data1.len()] + b)
5197 .collect();
5198 result_shape = shape2.into_iter().map(Value::Int).collect();
5199 } else {
5200 result_data = data1.iter().zip(data2.iter()).map(|(a, b)| a + b).collect();
5202 result_shape = shape1.into_iter().map(Value::Int).collect();
5203 }
5204
5205 let mut fields = std::collections::HashMap::new();
5206 fields.insert(
5207 "shape".to_string(),
5208 Value::Array(Rc::new(RefCell::new(result_shape))),
5209 );
5210 fields.insert(
5211 "data".to_string(),
5212 Value::Array(Rc::new(RefCell::new(
5213 result_data.into_iter().map(Value::Float).collect(),
5214 ))),
5215 );
5216 fields.insert("requires_grad".to_string(), Value::Bool(false));
5217 Ok(Value::Struct {
5218 name: "Tensor".to_string(),
5219 fields: Rc::new(RefCell::new(fields)),
5220 })
5221 }
5222 BinOp::TensorProd if n1 == "Qubit" && n2 == "Qubit" => {
5224 let get_state = |f: &Rc<RefCell<HashMap<String, Value>>>| -> (u64, usize) {
5227 let fields = f.borrow();
5228 let state_id = match fields.get("__state_id__") {
5229 Some(Value::Int(v)) => *v as u64,
5230 _ => 0,
5231 };
5232 let idx = match fields.get("__qubit_idx__") {
5233 Some(Value::Int(v)) => *v as usize,
5234 _ => 0,
5235 };
5236 (state_id, idx)
5237 };
5238
5239 let (state_id1, _idx1) = get_state(&f1);
5240 let (state_id2, _idx2) = get_state(&f2);
5241
5242 use crate::stdlib::{get_quantum_state, store_quantum_state, create_qregister_value};
5244
5245 let state1 = get_quantum_state(state_id1);
5246 let state2 = get_quantum_state(state_id2);
5247
5248 let n_qubits = match (&state1, &state2) {
5249 (Some(s1), Some(s2)) => {
5250 let combined = s1.tensor_product(s2);
5252 let total = combined.num_qubits();
5253 let new_id = store_quantum_state(combined);
5254 return Ok(create_qregister_value(new_id, total));
5255 }
5256 _ => 2, };
5258
5259 Ok(create_qregister_value(0, n_qubits))
5261 }
5262 _ => Err(RuntimeError::new("Invalid struct operation")),
5263 },
5264 (l, r) => Err(RuntimeError::new(format!(
5265 "Type mismatch in binary operation: {:?} {:?} {:?}",
5266 l, op, r
5267 ))),
5268 }
5269 }
5270
5271 fn int_binary_op(&self, a: i64, b: i64, op: &BinOp) -> Result<Value, RuntimeError> {
5272 Ok(match op {
5273 BinOp::Add => Value::Int(a + b),
5274 BinOp::Sub => Value::Int(a - b),
5275 BinOp::Mul => Value::Int(a * b),
5276 BinOp::Div => {
5277 if b == 0 {
5278 return Err(RuntimeError::division_by_zero());
5279 }
5280 Value::Int(a / b)
5281 }
5282 BinOp::Rem => {
5283 if b == 0 {
5284 return Err(RuntimeError::division_by_zero());
5285 }
5286 Value::Int(a % b)
5287 }
5288 BinOp::Pow => Value::Int(a.pow(b as u32)),
5289 BinOp::Eq => Value::Bool(a == b),
5290 BinOp::Ne => Value::Bool(a != b),
5291 BinOp::Lt => Value::Bool(a < b),
5292 BinOp::Le => Value::Bool(a <= b),
5293 BinOp::Gt => Value::Bool(a > b),
5294 BinOp::Ge => Value::Bool(a >= b),
5295 BinOp::BitAnd => Value::Int(a & b),
5296 BinOp::BitOr => Value::Int(a | b),
5297 BinOp::BitXor => Value::Int(a ^ b),
5298 BinOp::Shl => Value::Int(a << b),
5299 BinOp::Shr => Value::Int(a >> b),
5300 _ => return Err(RuntimeError::new("Invalid integer operation")),
5301 })
5302 }
5303
5304 fn float_binary_op(&self, a: f64, b: f64, op: &BinOp) -> Result<Value, RuntimeError> {
5305 Ok(match op {
5306 BinOp::Add => Value::Float(a + b),
5307 BinOp::Sub => Value::Float(a - b),
5308 BinOp::Mul => Value::Float(a * b),
5309 BinOp::Div => Value::Float(a / b),
5310 BinOp::Rem => Value::Float(a % b),
5311 BinOp::Pow => Value::Float(a.powf(b)),
5312 BinOp::Eq => Value::Bool(a == b),
5313 BinOp::Ne => Value::Bool(a != b),
5314 BinOp::Lt => Value::Bool(a < b),
5315 BinOp::Le => Value::Bool(a <= b),
5316 BinOp::Gt => Value::Bool(a > b),
5317 BinOp::Ge => Value::Bool(a >= b),
5318 _ => return Err(RuntimeError::new("Invalid float operation")),
5319 })
5320 }
5321
5322 fn eval_unary(&mut self, op: &UnaryOp, expr: &Expr) -> Result<Value, RuntimeError> {
5323 let val = self.evaluate(expr)?;
5324 let val = self.resolve_constant(val);
5326 match (op, &val) {
5327 (UnaryOp::Neg, Value::Int(n)) => Ok(Value::Int(-n)),
5328 (UnaryOp::Neg, Value::Float(n)) => Ok(Value::Float(-n)),
5329 (UnaryOp::Not, Value::Bool(b)) => Ok(Value::Bool(!b)),
5330 (UnaryOp::Not, Value::Int(n)) => Ok(Value::Int(!n)),
5331 (UnaryOp::Not, Value::Evidential { value, evidence }) => {
5333 match value.as_ref() {
5335 Value::Bool(b) => Ok(Value::Evidential {
5336 value: Box::new(Value::Bool(!b)),
5337 evidence: evidence.clone(),
5338 }),
5339 other => {
5340 let truthy = self.is_truthy(other);
5341 Ok(Value::Evidential {
5342 value: Box::new(Value::Bool(!truthy)),
5343 evidence: evidence.clone(),
5344 })
5345 }
5346 }
5347 }
5348 (UnaryOp::Not, Value::String(s)) => Ok(Value::Bool(s.is_empty())),
5350 (UnaryOp::Not, Value::Array(arr)) => Ok(Value::Bool(arr.borrow().is_empty())),
5352 (UnaryOp::Not, Value::Null) => Ok(Value::Bool(true)),
5354 (UnaryOp::Ref, _) => Ok(Value::Ref(Rc::new(RefCell::new(val)))),
5355 (UnaryOp::RefMut, _) => Ok(Value::Ref(Rc::new(RefCell::new(val)))),
5356 (UnaryOp::Deref, Value::Ref(r)) => Ok(r.borrow().clone()),
5357 (UnaryOp::Deref, Value::Struct { name, fields }) if name == "Rc" => {
5358 let borrowed = fields.borrow();
5360 if let Some(value) = borrowed.get("_value") {
5361 Ok(value.clone())
5362 } else {
5363 Err(RuntimeError::new("Rc has no value"))
5364 }
5365 }
5366 (UnaryOp::Deref, other) => {
5367 let unwrapped = Self::unwrap_all(&val);
5369 if let Value::Ref(r) = &unwrapped {
5370 return Ok(r.borrow().clone());
5371 }
5372 Ok(unwrapped)
5375 }
5376 _ => Err(RuntimeError::new(format!(
5377 "Invalid unary {:?} on {:?}",
5378 op,
5379 std::mem::discriminant(&val)
5380 ))),
5381 }
5382 }
5383
5384 fn eval_call(&mut self, func_expr: &Expr, args: &[Expr]) -> Result<Value, RuntimeError> {
5385 if let Expr::Path(path) = func_expr {
5387 let qualified_name = path
5388 .segments
5389 .iter()
5390 .map(|s| s.ident.name.as_str())
5391 .collect::<Vec<_>>()
5392 .join("·");
5393
5394 if qualified_name == "Self" {
5396 if let Some(ref self_type) = self.current_self_type {
5397 let tuple_arity = if let Some(TypeDef::Struct(struct_def)) =
5399 self.types.get(self_type)
5400 {
5401 if let crate::ast::StructFields::Tuple(field_types) = &struct_def.fields {
5402 Some((self_type.clone(), field_types.len()))
5403 } else {
5404 None
5405 }
5406 } else {
5407 None
5408 };
5409
5410 if let Some((type_name, expected_arity)) = tuple_arity {
5411 let arg_values: Vec<Value> = args
5413 .iter()
5414 .map(|a| self.evaluate(a))
5415 .collect::<Result<_, _>>()?;
5416
5417 if arg_values.len() != expected_arity {
5418 return Err(RuntimeError::new(format!(
5419 "Tuple struct {} expects {} fields, got {}",
5420 type_name,
5421 expected_arity,
5422 arg_values.len()
5423 )));
5424 }
5425
5426 let mut fields = HashMap::new();
5428 for (i, value) in arg_values.into_iter().enumerate() {
5429 fields.insert(i.to_string(), value);
5430 }
5431 return Ok(Value::Struct {
5432 name: type_name,
5433 fields: Rc::new(RefCell::new(fields)),
5434 });
5435 }
5436 }
5437 }
5438
5439 if path.segments.len() == 1 {
5441 let type_name = &path.segments[0].ident.name;
5442 let tuple_arity =
5444 if let Some(TypeDef::Struct(struct_def)) = self.types.get(type_name) {
5445 if let crate::ast::StructFields::Tuple(field_types) = &struct_def.fields {
5446 Some((type_name.clone(), field_types.len()))
5447 } else {
5448 None
5449 }
5450 } else {
5451 None
5452 };
5453
5454 if let Some((struct_name, expected_arity)) = tuple_arity {
5455 let arg_values: Vec<Value> = args
5456 .iter()
5457 .map(|a| self.evaluate(a))
5458 .collect::<Result<_, _>>()?;
5459
5460 if arg_values.len() != expected_arity {
5461 return Err(RuntimeError::new(format!(
5462 "Tuple struct {} expects {} fields, got {}",
5463 struct_name,
5464 expected_arity,
5465 arg_values.len()
5466 )));
5467 }
5468
5469 let mut fields = HashMap::new();
5470 for (i, value) in arg_values.into_iter().enumerate() {
5471 fields.insert(i.to_string(), value);
5472 }
5473 return Ok(Value::Struct {
5474 name: struct_name,
5475 fields: Rc::new(RefCell::new(fields)),
5476 });
5477 }
5478 }
5479
5480 if qualified_name == "Default·default" && args.is_empty() {
5483 if let Some(type_name) = self.current_self_type.clone() {
5484 let default_fn_name = format!("{}·default", type_name);
5486 crate::sigil_debug!(
5487 "DEBUG Default::default() looking for '{}', self_type='{}'",
5488 default_fn_name,
5489 type_name
5490 );
5491 let func_clone = self
5492 .globals
5493 .borrow()
5494 .get(&default_fn_name)
5495 .map(|v| v.clone());
5496 if let Some(Value::Function(f)) = func_clone {
5497 crate::sigil_debug!(
5498 "DEBUG Found function '{}', calling it",
5499 default_fn_name
5500 );
5501 crate::sigil_debug!(
5502 "DEBUG current_self_type before call: {:?}",
5503 self.current_self_type
5504 );
5505 let result = self.call_function(&f, vec![]);
5507 crate::sigil_debug!(
5508 "DEBUG Default call result: {:?}",
5509 result
5510 .as_ref()
5511 .map(|v| self.format_value(v))
5512 .unwrap_or_else(|e| format!("ERR: {:?}", e))
5513 );
5514 return result;
5515 }
5516 if let Some(struct_def) = self.default_structs.get(&type_name).cloned() {
5518 let mut fields = HashMap::new();
5519 if let StructFields::Named(field_defs) = &struct_def.fields {
5520 for field in field_defs {
5521 let default_val = if let Some(default_expr) = &field.default {
5522 self.evaluate(default_expr)?
5523 } else {
5524 Value::Null
5525 };
5526 fields.insert(field.name.name.clone(), default_val);
5527 }
5528 }
5529 return Ok(Value::Struct {
5530 name: type_name,
5531 fields: Rc::new(RefCell::new(fields)),
5532 });
5533 }
5534 }
5535 }
5536
5537 if qualified_name.ends_with("·default") && args.is_empty() {
5539 let type_name = qualified_name.strip_suffix("·default").unwrap();
5540 let default_fn_name = format!("{}·default", type_name);
5542 let func_clone = self
5543 .globals
5544 .borrow()
5545 .get(&default_fn_name)
5546 .map(|v| v.clone());
5547 if let Some(Value::Function(f)) = func_clone {
5548 let old_self_type = self.current_self_type.clone();
5550 self.current_self_type = Some(type_name.to_string());
5551
5552 let result = self.call_function(&f, vec![]);
5554
5555 self.current_self_type = old_self_type;
5557 return result;
5558 }
5559 if let Some(struct_def) = self.default_structs.get(type_name).cloned() {
5561 let mut fields = HashMap::new();
5562 if let StructFields::Named(field_defs) = &struct_def.fields {
5563 for field in field_defs {
5564 let default_val = if let Some(default_expr) = &field.default {
5565 self.evaluate(default_expr)?
5566 } else {
5567 Value::Null
5569 };
5570 fields.insert(field.name.name.clone(), default_val);
5571 }
5572 }
5573 return Ok(Value::Struct {
5574 name: type_name.to_string(),
5575 fields: Rc::new(RefCell::new(fields)),
5576 });
5577 }
5578 }
5579
5580 if qualified_name.contains("Command") || qualified_name.contains("Analyze") {
5583 eprintln!("DEBUG variant lookup: qualified_name='{}'", qualified_name);
5584 eprintln!(
5585 " found in variant_constructors: {}",
5586 self.variant_constructors.contains_key(&qualified_name)
5587 );
5588 for (k, v) in &self.variant_constructors {
5590 if k.contains("Command") {
5591 eprintln!(" registered: '{}' -> {:?}", k, v);
5592 }
5593 }
5594 }
5595 if let Some((enum_name, variant_name, arity)) =
5596 self.variant_constructors.get(&qualified_name).cloned()
5597 {
5598 let arg_values: Vec<Value> = args
5599 .iter()
5600 .map(|a| self.evaluate(a))
5601 .collect::<Result<_, _>>()?;
5602
5603 if arg_values.len() != arity {
5604 return Err(RuntimeError::new(format!(
5605 "{} expects {} arguments, got {}",
5606 qualified_name,
5607 arity,
5608 arg_values.len()
5609 )));
5610 }
5611
5612 if arity == 0 {
5613 return Ok(Value::Variant {
5614 enum_name,
5615 variant_name,
5616 fields: None,
5617 });
5618 } else {
5619 if enum_name == "Command" || enum_name == "Result" {
5621 eprintln!(
5622 "DEBUG creating {}::{} variant with {} args",
5623 enum_name,
5624 variant_name,
5625 arg_values.len()
5626 );
5627 for (i, v) in arg_values.iter().enumerate() {
5628 eprintln!(" arg[{}]: {}", i, self.format_value(v));
5629 }
5630 }
5631 return Ok(Value::Variant {
5632 enum_name,
5633 variant_name,
5634 fields: Some(Rc::new(arg_values)),
5635 });
5636 }
5637 }
5638
5639 let segments: Vec<&str> = path
5641 .segments
5642 .iter()
5643 .map(|s| s.ident.name.as_str())
5644 .collect();
5645 match segments.as_slice() {
5646 ["Map", "new"] | ["HashMap", "new"] => {
5647 return Ok(Value::Struct {
5649 name: "Map".to_string(),
5650 fields: Rc::new(RefCell::new(HashMap::new())),
5651 });
5652 }
5653 ["String", "new"] => {
5654 return Ok(Value::String(Rc::new(String::new())));
5655 }
5656 ["Vec", "new"] | ["Array", "new"] => {
5657 return Ok(Value::Array(Rc::new(RefCell::new(Vec::new()))));
5658 }
5659 ["Box", "new"] => {
5660 if args.len() == 1 {
5662 return self.evaluate(&args[0]);
5663 }
5664 return Err(RuntimeError::new("Box::new expects 1 argument"));
5665 }
5666 ["char", "from_u32"] => {
5667 if args.len() == 1 {
5669 let arg = self.evaluate(&args[0])?;
5670 let code = match arg {
5671 Value::Int(i) => i as u32,
5672 _ => return Err(RuntimeError::new("char::from_u32 expects u32")),
5673 };
5674 if let Some(c) = char::from_u32(code) {
5675 return Ok(Value::Variant {
5677 enum_name: "Option".to_string(),
5678 variant_name: "Some".to_string(),
5679 fields: Some(Rc::new(vec![Value::Char(c)])),
5680 });
5681 } else {
5682 return Ok(Value::Variant {
5684 enum_name: "Option".to_string(),
5685 variant_name: "None".to_string(),
5686 fields: None,
5687 });
5688 }
5689 }
5690 return Err(RuntimeError::new("char::from_u32 expects 1 argument"));
5691 }
5692 ["parking_lot", "Mutex", "new"]
5694 | ["std", "sync", "Mutex", "new"]
5695 | ["Mutex", "new"] => {
5696 if args.len() == 1 {
5697 let inner = self.evaluate(&args[0])?;
5698 return Ok(Value::Struct {
5699 name: "Mutex".to_string(),
5700 fields: Rc::new(RefCell::new(HashMap::from([(
5701 "__inner__".to_string(),
5702 inner,
5703 )]))),
5704 });
5705 }
5706 return Err(RuntimeError::new("Mutex::new expects 1 argument"));
5707 }
5708 ["parking_lot", "RwLock", "new"]
5710 | ["std", "sync", "RwLock", "new"]
5711 | ["RwLock", "new"] => {
5712 if args.len() == 1 {
5713 let inner = self.evaluate(&args[0])?;
5714 return Ok(Value::Struct {
5715 name: "RwLock".to_string(),
5716 fields: Rc::new(RefCell::new(HashMap::from([(
5717 "__inner__".to_string(),
5718 inner,
5719 )]))),
5720 });
5721 }
5722 return Err(RuntimeError::new("RwLock::new expects 1 argument"));
5723 }
5724 ["std", "sync", "Barrier", "new"] | ["Barrier", "new"] => {
5726 if args.len() == 1 {
5727 let count = self.evaluate(&args[0])?;
5728 return Ok(Value::Struct {
5729 name: "Barrier".to_string(),
5730 fields: Rc::new(RefCell::new(HashMap::from([(
5731 "__count__".to_string(),
5732 count,
5733 )]))),
5734 });
5735 }
5736 return Err(RuntimeError::new("Barrier::new expects 1 argument"));
5737 }
5738 ["std", "sync", "Arc", "new"] | ["Arc", "new"] => {
5740 if args.len() == 1 {
5741 let inner = self.evaluate(&args[0])?;
5742 return Ok(Value::Ref(Rc::new(RefCell::new(inner))));
5743 }
5744 return Err(RuntimeError::new("Arc::new expects 1 argument"));
5745 }
5746 ["std", "sync", "atomic", "AtomicU64", "new"] | ["AtomicU64", "new"] => {
5748 if args.len() == 1 {
5749 let inner = self.evaluate(&args[0])?;
5750 return Ok(Value::Struct {
5751 name: "AtomicU64".to_string(),
5752 fields: Rc::new(RefCell::new(HashMap::from([(
5753 "__value__".to_string(),
5754 inner,
5755 )]))),
5756 });
5757 }
5758 return Err(RuntimeError::new("AtomicU64::new expects 1 argument"));
5759 }
5760 ["std", "sync", "atomic", "AtomicUsize", "new"] | ["AtomicUsize", "new"] => {
5761 if args.len() == 1 {
5762 let inner = self.evaluate(&args[0])?;
5763 return Ok(Value::Struct {
5764 name: "AtomicUsize".to_string(),
5765 fields: Rc::new(RefCell::new(HashMap::from([(
5766 "__value__".to_string(),
5767 inner,
5768 )]))),
5769 });
5770 }
5771 return Err(RuntimeError::new("AtomicUsize::new expects 1 argument"));
5772 }
5773 ["std", "sync", "atomic", "AtomicBool", "new"] | ["AtomicBool", "new"] => {
5774 if args.len() == 1 {
5775 let inner = self.evaluate(&args[0])?;
5776 return Ok(Value::Struct {
5777 name: "AtomicBool".to_string(),
5778 fields: Rc::new(RefCell::new(HashMap::from([(
5779 "__value__".to_string(),
5780 inner,
5781 )]))),
5782 });
5783 }
5784 return Err(RuntimeError::new("AtomicBool::new expects 1 argument"));
5785 }
5786 ["Linear", "new"] => {
5788 if args.is_empty() {
5789 let turbofish_generics: Option<(i64, i64)> =
5791 if let Some(seg) = path.segments.first() {
5792 if let Some(generics) = &seg.generics {
5793 let mut const_values: Vec<i64> = Vec::new();
5794 for generic in generics {
5795 if let crate::ast::TypeExpr::ConstExpr(expr) = generic {
5796 if let crate::ast::Expr::Literal(
5797 crate::ast::Literal::Int { value, .. },
5798 ) = expr.as_ref()
5799 {
5800 if let Ok(n) = value.parse::<i64>() {
5801 const_values.push(n);
5802 }
5803 }
5804 }
5805 if let crate::ast::TypeExpr::Path(inner_path) = generic {
5806 if let Some(inner_seg) = inner_path.segments.first() {
5807 if let Ok(n) = inner_seg.ident.name.parse::<i64>() {
5808 const_values.push(n);
5809 }
5810 }
5811 }
5812 }
5813 if const_values.len() >= 2 {
5814 Some((const_values[0], const_values[1]))
5815 } else {
5816 None
5817 }
5818 } else {
5819 None
5820 }
5821 } else {
5822 None
5823 };
5824
5825 let (in_features, out_features) = if let Some((i, o)) = turbofish_generics {
5827 (i, o)
5828 } else if let Some((name, generics)) =
5829 self.type_context.struct_generics.borrow().clone()
5830 {
5831 if name == "Linear" && generics.len() >= 2 {
5832 (generics[0], generics[1])
5833 } else {
5834 return Err(RuntimeError::new(
5835 "Linear::new requires type annotation like Linear<IN, OUT>",
5836 ));
5837 }
5838 } else {
5839 return Err(RuntimeError::new(
5840 "Linear::new requires type annotation like Linear<IN, OUT>",
5841 ));
5842 };
5843
5844 let weight_data: Vec<Value> = (0..(out_features * in_features))
5846 .map(|_| Value::Float(rand::random::<f64>() * 2.0 - 1.0))
5847 .collect();
5848 let weight_shape = vec![Value::Int(out_features), Value::Int(in_features)];
5849 let mut weight_fields = HashMap::new();
5850 weight_fields.insert(
5851 "data".to_string(),
5852 Value::Array(Rc::new(RefCell::new(weight_data))),
5853 );
5854 weight_fields.insert(
5855 "shape".to_string(),
5856 Value::Array(Rc::new(RefCell::new(weight_shape))),
5857 );
5858 weight_fields.insert("requires_grad".to_string(), Value::Bool(true));
5859 weight_fields.insert(
5860 "grad".to_string(),
5861 Value::Variant {
5862 enum_name: "Option".to_string(),
5863 variant_name: "None".to_string(),
5864 fields: None,
5865 },
5866 );
5867
5868 let bias_data: Vec<Value> = (0..out_features)
5870 .map(|_| Value::Float(rand::random::<f64>() * 2.0 - 1.0))
5871 .collect();
5872 let bias_shape = vec![Value::Int(out_features)];
5873 let mut bias_fields = HashMap::new();
5874 bias_fields.insert(
5875 "data".to_string(),
5876 Value::Array(Rc::new(RefCell::new(bias_data))),
5877 );
5878 bias_fields.insert(
5879 "shape".to_string(),
5880 Value::Array(Rc::new(RefCell::new(bias_shape))),
5881 );
5882 bias_fields.insert("requires_grad".to_string(), Value::Bool(true));
5883 bias_fields.insert(
5884 "grad".to_string(),
5885 Value::Variant {
5886 enum_name: "Option".to_string(),
5887 variant_name: "None".to_string(),
5888 fields: None,
5889 },
5890 );
5891
5892 let mut linear_fields = HashMap::new();
5894 linear_fields.insert(
5895 "weight".to_string(),
5896 Value::Struct {
5897 name: "Tensor".to_string(),
5898 fields: Rc::new(RefCell::new(weight_fields)),
5899 },
5900 );
5901 linear_fields.insert(
5902 "bias".to_string(),
5903 Value::Struct {
5904 name: "Tensor".to_string(),
5905 fields: Rc::new(RefCell::new(bias_fields)),
5906 },
5907 );
5908
5909 return Ok(Value::Struct {
5910 name: "Linear".to_string(),
5911 fields: Rc::new(RefCell::new(linear_fields)),
5912 });
5913 }
5914 return Err(RuntimeError::new("Linear::new takes no arguments"));
5915 }
5916 ["ReLU", "new"] => {
5918 if args.is_empty() {
5919 return Ok(Value::Struct {
5920 name: "ReLU".to_string(),
5921 fields: Rc::new(RefCell::new(HashMap::new())),
5922 });
5923 }
5924 return Err(RuntimeError::new("ReLU::new takes no arguments"));
5925 }
5926 ["Sequential", "new"] => {
5928 let user_ctor = self.globals.borrow().get("Sequential·new").map(|v| v.clone());
5930 if let Some(Value::Function(func)) = user_ctor {
5931 let mut evaluated_args = Vec::new();
5932 for arg in args {
5933 evaluated_args.push(self.evaluate(arg)?);
5934 }
5935 return self.call_function(&func, evaluated_args);
5936 }
5937 if args.len() == 1 {
5938 let layers = self.evaluate(&args[0])?;
5939 let mut fields = HashMap::new();
5940 fields.insert("layers".to_string(), layers);
5941 return Ok(Value::Struct {
5942 name: "Sequential".to_string(),
5943 fields: Rc::new(RefCell::new(fields)),
5944 });
5945 }
5946 return Err(RuntimeError::new(
5947 "Sequential::new expects an array of layers",
5948 ));
5949 }
5950 _ => {}
5951 }
5952 }
5953
5954 let type_name_for_self = if let Expr::Path(path) = func_expr {
5956 if path.segments.len() >= 2 {
5957 let first = &path.segments[0].ident.name;
5959 if self.types.contains_key(first) {
5961 Some(first.clone())
5962 } else {
5963 None
5964 }
5965 } else {
5966 None
5967 }
5968 } else {
5969 None
5970 };
5971
5972 if let Expr::Path(path) = func_expr {
5974 let path_str = path
5975 .segments
5976 .iter()
5977 .map(|s| s.ident.name.as_str())
5978 .collect::<Vec<_>>()
5979 .join("·");
5980 if path_str.contains("Result") {
5981 eprintln!(
5982 "DEBUG func lookup: path='{}', looking up in globals...",
5983 path_str
5984 );
5985 }
5986 }
5987 let func = self.evaluate(func_expr)?;
5988 if let Expr::Path(path) = func_expr {
5990 let path_str = path
5991 .segments
5992 .iter()
5993 .map(|s| s.ident.name.as_str())
5994 .collect::<Vec<_>>()
5995 .join("·");
5996 if path_str.contains("Result") {
5997 eprintln!(
5998 "DEBUG func lookup result: path='{}', value={}",
5999 path_str,
6000 self.format_value(&func)
6001 );
6002 }
6003 }
6004
6005 let mut mut_ref_sync: Vec<(String, Rc<RefCell<Value>>)> = Vec::new();
6008
6009 let mut arg_entries: Vec<(Option<String>, Value)> = Vec::new();
6012 for arg in args.iter() {
6013 let (arg_name, inner_arg) = if let Expr::NamedArg { name, value } = arg {
6015 (Some(name.name.clone()), value.as_ref())
6016 } else {
6017 (None, arg)
6018 };
6019
6020 let val = self.evaluate(inner_arg)?;
6021
6022 if let Expr::Unary {
6024 op: crate::ast::UnaryOp::RefMut,
6025 expr,
6026 } = inner_arg
6027 {
6028 if let Expr::Path(path) = expr.as_ref() {
6029 if path.segments.len() == 1 {
6030 let var_name = path.segments[0].ident.name.clone();
6031 if let Value::Ref(r) = &val {
6032 mut_ref_sync.push((var_name, r.clone()));
6033 }
6034 }
6035 }
6036 }
6037
6038 arg_entries.push((arg_name, val));
6039 }
6040
6041 let old_self_type = self.current_self_type.clone();
6044 if let Some(type_name) = type_name_for_self {
6045 self.current_self_type = Some(type_name);
6046 }
6047
6048 let turbofish_type_args: Vec<String> = if let Expr::Path(path) = func_expr {
6051 path.segments
6052 .iter()
6053 .filter_map(|seg| seg.generics.as_ref())
6054 .flat_map(|generics| {
6055 generics.iter().filter_map(|ty| {
6056 if let crate::ast::TypeExpr::Path(tp) = ty {
6057 Some(
6058 tp.segments
6059 .iter()
6060 .map(|s| s.ident.name.as_str())
6061 .collect::<Vec<_>>()
6062 .join("·"),
6063 )
6064 } else {
6065 None
6066 }
6067 })
6068 })
6069 .collect()
6070 } else {
6071 Vec::new()
6072 };
6073
6074 let turbofish_const_bindings: Vec<(String, Value)> = if let Expr::Path(path) = func_expr {
6077 let mut bindings = Vec::new();
6078 for seg in &path.segments {
6079 if let Some(generics) = &seg.generics {
6080 if let Some(param_names) = self.const_generic_params.get(seg.ident.name.as_str()).cloned() {
6081 let mut idx = 0;
6082 for generic in generics {
6083 if idx >= param_names.len() { break; }
6084 let val = match generic {
6085 crate::ast::TypeExpr::ConstExpr(expr) => {
6086 if let crate::ast::Expr::Literal(crate::ast::Literal::Int { value, .. }) = expr.as_ref() {
6087 value.parse::<i64>().ok()
6088 } else { None }
6089 }
6090 crate::ast::TypeExpr::Path(inner_path) => {
6091 if let Some(inner_seg) = inner_path.segments.first() {
6092 inner_seg.ident.name.parse::<i64>().ok()
6093 } else { None }
6094 }
6095 _ => None,
6096 };
6097 if let Some(v) = val {
6098 bindings.push((param_names[idx].clone(), Value::Int(v)));
6099 idx += 1;
6100 }
6101 }
6102 }
6103 }
6104 }
6105 bindings
6106 } else {
6107 Vec::new()
6108 };
6109
6110 let old_generic_bindings = self.generic_type_bindings.clone();
6112 if !turbofish_type_args.is_empty() {
6113 if let Value::Function(ref f) = func {
6114 for (param_name, concrete_type) in
6115 f.generic_params.iter().zip(turbofish_type_args.iter())
6116 {
6117 self.generic_type_bindings
6118 .insert(param_name.clone(), concrete_type.clone());
6119 }
6120 }
6121 }
6122
6123 let prev_struct_generics = self.type_context.struct_generics.borrow().clone();
6127 if !turbofish_const_bindings.is_empty() {
6128 if let Expr::Path(path) = func_expr {
6129 if let Some(seg) = path.segments.first() {
6130 let type_name = seg.ident.name.clone();
6131 let const_values: Vec<i64> = turbofish_const_bindings.iter()
6132 .filter_map(|(_, v)| if let Value::Int(n) = v { Some(*n) } else { None })
6133 .collect();
6134 if !const_values.is_empty() {
6135 *self.type_context.struct_generics.borrow_mut() = Some((type_name, const_values));
6136 }
6137 }
6138 }
6139 }
6140
6141 let result = match func {
6142 Value::Function(f) => {
6143 let f = if turbofish_const_bindings.is_empty() {
6145 f
6146 } else {
6147 let wrapper_env = Rc::new(RefCell::new(
6148 Environment::with_parent(f.closure.clone())
6149 ));
6150 for (name, value) in &turbofish_const_bindings {
6151 wrapper_env.borrow_mut().define(name.clone(), value.clone());
6152 }
6153 Rc::new(Function {
6154 name: f.name.clone(),
6155 params: f.params.clone(),
6156 body: f.body.clone(),
6157 closure: wrapper_env,
6158 generic_params: f.generic_params.clone(),
6159 })
6160 };
6161 let arg_values = Self::reorder_named_args(&f.params, arg_entries)?;
6163 self.call_function(&f, arg_values)
6164 }
6165 Value::BuiltIn(b) => {
6166 let arg_values: Vec<Value> = arg_entries.into_iter().map(|(_, v)| v).collect();
6168 self.call_builtin(&b, arg_values)
6169 }
6170 Value::Struct { ref name, .. } if name.starts_with("__constructor__") => {
6172 let actual_type = name.strip_prefix("__constructor__").unwrap();
6173 Ok(Value::Struct {
6175 name: actual_type.to_string(),
6176 fields: Rc::new(RefCell::new(HashMap::new())),
6177 })
6178 }
6179 Value::Ref(r) => {
6181 let inner = r.borrow().clone();
6182 match inner {
6183 Value::Function(f) => {
6184 let arg_values = Self::reorder_named_args(&f.params, arg_entries)?;
6185 self.call_function(&f, arg_values)
6186 }
6187 Value::BuiltIn(b) => {
6188 let arg_values: Vec<Value> = arg_entries.into_iter().map(|(_, v)| v).collect();
6189 self.call_builtin(&b, arg_values)
6190 }
6191 _ => {
6192 crate::sigil_debug!(
6193 "DEBUG Cannot call non-function (deref'd Ref): {:?}",
6194 inner
6195 );
6196 Err(RuntimeError::new("Cannot call non-function"))
6197 }
6198 }
6199 }
6200 _ => {
6201 crate::sigil_debug!(
6202 "DEBUG Cannot call non-function: {:?}, expr: {:?}",
6203 func,
6204 func_expr
6205 );
6206 Err(RuntimeError::new("Cannot call non-function"))
6207 }
6208 };
6209
6210 for (var_name, ref_val) in mut_ref_sync {
6213 let current_value = ref_val.borrow().clone();
6214 let _ = self.environment.borrow_mut().set(&var_name, current_value);
6215 }
6216
6217 self.current_self_type = old_self_type;
6219 self.generic_type_bindings = old_generic_bindings;
6220 *self.type_context.struct_generics.borrow_mut() = prev_struct_generics;
6221
6222 result
6223 }
6224
6225 pub fn call_function(
6226 &mut self,
6227 func: &Function,
6228 args: Vec<Value>,
6229 ) -> Result<Value, RuntimeError> {
6230 if func.name.as_ref().map_or(false, |n| {
6232 n.contains("read_source")
6233 || n.contains("parse_file")
6234 || n.contains("load_from_file")
6235 || n.contains("read_to_string")
6236 }) {
6237 crate::sigil_debug!(
6238 "DEBUG call_function: name={:?}, params={:?}",
6239 func.name,
6240 func.params
6241 );
6242 for (i, arg) in args.iter().enumerate() {
6243 crate::sigil_debug!(" arg[{}] = {:?}", i, arg);
6244 }
6245 }
6246 if args.len() != func.params.len() {
6247 return Err(RuntimeError::new(format!(
6248 "Expected {} arguments, got {} (func={:?}, params={:?})",
6249 func.params.len(),
6250 args.len(),
6251 func.name,
6252 func.params
6253 )));
6254 }
6255
6256 if func.params.iter().any(|p| p == "name") {
6258 for arg in &args {
6259 let unwrapped = Self::unwrap_all(arg);
6260 if let Value::String(s) = &unwrapped {
6261 if s.len() <= 10 {
6262 crate::sigil_debug!("DEBUG call_function(name='{}')", s);
6263 }
6264 }
6265 }
6266 }
6267
6268 let env = Rc::new(RefCell::new(Environment::with_parent(func.closure.clone())));
6270
6271 for (param, value) in func.params.iter().zip(args) {
6273 let value = self.resolve_constant(value);
6274 if param == "path" {
6276 crate::sigil_debug!(
6277 "DEBUG call_function func={:?} binding param 'path' = {:?}",
6278 func.name,
6279 value
6280 );
6281 }
6282 env.borrow_mut().define(param.clone(), value);
6283 }
6284
6285 let prev_env = self.environment.clone();
6287 self.environment = env;
6288
6289 let prev_linear_consumed = std::mem::take(&mut *self.linear_state.consumed.borrow_mut());
6292 let prev_linear_vars = std::mem::take(&mut *self.linear_state.vars.borrow_mut());
6293
6294 let result = match self.evaluate(&func.body) {
6295 Ok(val) => Ok(val),
6296 Err(e) if e.message == "return" => {
6297 Ok(self.return_value.take().unwrap_or(Value::Null))
6299 }
6300 Err(e) => Err(e),
6301 };
6302
6303 if result.is_ok() {
6305 let unused_var = {
6306 let vars = self.linear_state.vars.borrow();
6307 let consumed = self.linear_state.consumed.borrow();
6308 vars.iter()
6309 .find(|v| !consumed.contains(*v))
6310 .cloned()
6311 };
6312 if let Some(var_name) = unused_var {
6313 *self.linear_state.consumed.borrow_mut() = prev_linear_consumed;
6314 *self.linear_state.vars.borrow_mut() = prev_linear_vars;
6315 self.environment = prev_env;
6316 return Err(RuntimeError::new(format!(
6317 "linear variable '{}' was declared but never used (linear types must be consumed exactly once)",
6318 var_name
6319 )));
6320 }
6321 }
6322
6323 *self.linear_state.consumed.borrow_mut() = prev_linear_consumed;
6325 *self.linear_state.vars.borrow_mut() = prev_linear_vars;
6326
6327 self.environment = prev_env;
6328 result
6329 }
6330
6331 fn call_builtin(
6332 &mut self,
6333 builtin: &BuiltInFn,
6334 args: Vec<Value>,
6335 ) -> Result<Value, RuntimeError> {
6336 if let Some(arity) = builtin.arity {
6337 if args.len() != arity {
6338 return Err(RuntimeError::new(format!(
6339 "{}() expects {} arguments, got {}",
6340 builtin.name,
6341 arity,
6342 args.len()
6343 )));
6344 }
6345 }
6346 let args: Vec<Value> = args.into_iter().map(|v| self.resolve_constant(v)).collect();
6348 (builtin.func)(self, args)
6349 }
6350
6351 fn resolve_constant(&mut self, val: Value) -> Value {
6354 match &val {
6355 Value::BuiltIn(b) if b.arity == Some(0) => {
6356 (b.func)(self, vec![]).unwrap_or(val)
6357 }
6358 _ => val,
6359 }
6360 }
6361
6362 fn reorder_named_args(
6365 params: &[String],
6366 arg_entries: Vec<(Option<String>, Value)>,
6367 ) -> Result<Vec<Value>, RuntimeError> {
6368 if arg_entries.iter().all(|(name, _)| name.is_none()) {
6370 return Ok(arg_entries.into_iter().map(|(_, v)| v).collect());
6371 }
6372
6373 let mut result: Vec<Option<Value>> = vec![None; params.len()];
6375 let mut positional_idx = 0;
6376
6377 for (arg_name, value) in arg_entries {
6378 if let Some(name) = arg_name {
6379 if let Some(pos) = params.iter().position(|p| p == &name) {
6381 if result[pos].is_some() {
6382 return Err(RuntimeError::new(format!(
6383 "argument '{}' specified multiple times",
6384 name
6385 )));
6386 }
6387 result[pos] = Some(value);
6388 } else {
6389 return Err(RuntimeError::new(format!(
6390 "unknown parameter name: '{}'",
6391 name
6392 )));
6393 }
6394 } else {
6395 while positional_idx < result.len() && result[positional_idx].is_some() {
6397 positional_idx += 1;
6398 }
6399 if positional_idx >= result.len() {
6400 return Err(RuntimeError::new("too many positional arguments"));
6401 }
6402 result[positional_idx] = Some(value);
6403 positional_idx += 1;
6404 }
6405 }
6406
6407 for (i, slot) in result.iter().enumerate() {
6409 if slot.is_none() {
6410 return Err(RuntimeError::new(format!(
6411 "missing argument for parameter '{}'",
6412 params[i]
6413 )));
6414 }
6415 }
6416
6417 Ok(result.into_iter().map(|v| v.unwrap()).collect())
6418 }
6419
6420 pub fn await_value(&mut self, value: Value) -> Result<Value, RuntimeError> {
6422 match value {
6423 Value::Future(fut) => {
6424 let mut fut_inner = fut.borrow_mut();
6425 self.poll_future(&mut fut_inner)
6426 }
6427 other => Ok(other),
6429 }
6430 }
6431
6432 fn unwrap_result_or_option(
6436 &self,
6437 value: Value,
6438 propagate_errors: bool,
6439 panic_on_error: bool,
6440 ) -> Result<Value, RuntimeError> {
6441 let (is_ok_or_some, is_err, is_none, inner_val) = match &value {
6443 Value::Struct { name, fields } if name == "Ok" || name == "Some" => {
6444 let borrowed = fields.borrow();
6445 let inner = borrowed.get("0").or(borrowed.get("value")).cloned();
6446 (true, false, false, inner)
6447 }
6448 Value::Struct { name, fields } if name == "Err" => {
6449 let borrowed = fields.borrow();
6450 let inner = borrowed.get("0").or(borrowed.get("value")).cloned();
6451 (false, true, false, inner)
6452 }
6453 Value::Struct { name, .. } if name == "None" => (false, false, true, None),
6454 _ => return Ok(value),
6455 };
6456
6457 if is_ok_or_some {
6458 Ok(inner_val.unwrap_or(value))
6459 } else if is_err {
6460 let msg = format!("Error: {:?}", inner_val);
6461 if panic_on_error {
6462 panic!("{}", msg);
6463 } else if propagate_errors {
6464 Err(RuntimeError::new(msg))
6465 } else {
6466 Ok(inner_val.unwrap_or(value))
6467 }
6468 } else if is_none {
6469 if panic_on_error {
6470 panic!("Unwrapped None");
6471 } else if propagate_errors {
6472 Err(RuntimeError::new("Unwrapped None".to_string()))
6473 } else {
6474 Ok(value)
6475 }
6476 } else {
6477 Ok(value)
6478 }
6479 }
6480
6481 fn poll_future(&mut self, fut: &mut FutureInner) -> Result<Value, RuntimeError> {
6483 match &fut.state {
6485 FutureState::Ready(v) => return Ok((**v).clone()),
6486 FutureState::Failed(e) => return Err(RuntimeError::new(e.clone())),
6487 _ => {}
6488 }
6489
6490 if let Some(complete_at) = fut.complete_at {
6492 if std::time::Instant::now() >= complete_at {
6493 fut.state = FutureState::Ready(Box::new(Value::Null));
6494 return Ok(Value::Null);
6495 } else {
6496 let remaining = complete_at - std::time::Instant::now();
6498 std::thread::sleep(remaining);
6499 fut.state = FutureState::Ready(Box::new(Value::Null));
6500 return Ok(Value::Null);
6501 }
6502 }
6503
6504 if let Some(computation) = fut.computation.take() {
6506 fut.state = FutureState::Running;
6507
6508 match computation {
6509 FutureComputation::Immediate(v) => {
6510 fut.state = FutureState::Ready(v.clone());
6511 Ok((*v).clone())
6512 }
6513 FutureComputation::Timer(duration) => {
6514 std::thread::sleep(duration);
6516 fut.state = FutureState::Ready(Box::new(Value::Null));
6517 Ok(Value::Null)
6518 }
6519 FutureComputation::Lazy { func, args } => {
6520 match self.call_function(&func, args) {
6522 Ok(result) => {
6523 fut.state = FutureState::Ready(Box::new(result.clone()));
6524 Ok(result)
6525 }
6526 Err(e) => {
6527 fut.state = FutureState::Failed(e.message.clone());
6528 Err(e)
6529 }
6530 }
6531 }
6532 FutureComputation::Join(futures) => {
6533 let mut results = Vec::new();
6535 for f in futures {
6536 let mut f_inner = f.borrow_mut();
6537 results.push(self.poll_future(&mut f_inner)?);
6538 }
6539 let result = Value::Array(Rc::new(RefCell::new(results)));
6540 fut.state = FutureState::Ready(Box::new(result.clone()));
6541 Ok(result)
6542 }
6543 FutureComputation::Race(futures) => {
6544 for f in futures {
6547 let f_inner = f.borrow_mut();
6548 if matches!(f_inner.state, FutureState::Ready(_)) {
6549 if let FutureState::Ready(v) = &f_inner.state {
6550 fut.state = FutureState::Ready(v.clone());
6551 return Ok((**v).clone());
6552 }
6553 }
6554 }
6555 Err(RuntimeError::new("No futures ready in race"))
6557 }
6558 }
6559 } else {
6560 match &fut.state {
6562 FutureState::Ready(v) => Ok((**v).clone()),
6563 FutureState::Failed(e) => Err(RuntimeError::new(e.clone())),
6564 _ => Err(RuntimeError::new("Future has no computation")),
6565 }
6566 }
6567 }
6568
6569 pub fn make_future_immediate(&self, value: Value) -> Value {
6571 Value::Future(Rc::new(RefCell::new(FutureInner {
6572 state: FutureState::Ready(Box::new(value)),
6573 computation: None,
6574 complete_at: None,
6575 })))
6576 }
6577
6578 pub fn make_future_lazy(&self, func: Rc<Function>, args: Vec<Value>) -> Value {
6580 Value::Future(Rc::new(RefCell::new(FutureInner {
6581 state: FutureState::Pending,
6582 computation: Some(FutureComputation::Lazy { func, args }),
6583 complete_at: None,
6584 })))
6585 }
6586
6587 pub fn make_future_timer(&self, duration: std::time::Duration) -> Value {
6589 Value::Future(Rc::new(RefCell::new(FutureInner {
6590 state: FutureState::Pending,
6591 computation: Some(FutureComputation::Timer(duration)),
6592 complete_at: Some(std::time::Instant::now() + duration),
6593 })))
6594 }
6595
6596 fn eval_array(&mut self, elements: &[Expr]) -> Result<Value, RuntimeError> {
6597 let values: Vec<Value> = elements
6598 .iter()
6599 .map(|e| self.evaluate(e))
6600 .collect::<Result<_, _>>()?;
6601 Ok(Value::Array(Rc::new(RefCell::new(values))))
6602 }
6603
6604 fn eval_tuple(&mut self, elements: &[Expr]) -> Result<Value, RuntimeError> {
6605 let values: Vec<Value> = elements
6606 .iter()
6607 .map(|e| self.evaluate(e))
6608 .collect::<Result<_, _>>()?;
6609 Ok(Value::Tuple(Rc::new(values)))
6610 }
6611
6612 fn eval_block(&mut self, block: &Block) -> Result<Value, RuntimeError> {
6613 let env = Rc::new(RefCell::new(Environment::with_parent(
6614 self.environment.clone(),
6615 )));
6616 let prev_env = self.environment.clone();
6617 self.environment = env;
6618
6619 let mut result = Value::Null;
6620
6621 for stmt in &block.stmts {
6622 match stmt {
6623 Stmt::Let { pattern, ty, init } => {
6624 if let Some(type_expr) = ty {
6626 if let Some(shape) = self.extract_tensor_shape(type_expr) {
6627 *self.type_context.tensor_shape.borrow_mut() = Some(shape);
6628 }
6629 if let Some((name, generics)) = self.extract_struct_generics(type_expr) {
6631 *self.type_context.struct_generics.borrow_mut() =
6632 Some((name, generics));
6633 }
6634 }
6635 let value = match init {
6636 Some(expr) => self.evaluate(expr)?,
6637 None => Value::Null,
6638 };
6639 *self.type_context.tensor_shape.borrow_mut() = None;
6641 *self.type_context.struct_generics.borrow_mut() = None;
6642 if let Some(type_expr) = ty {
6644 if matches!(type_expr, crate::ast::TypeExpr::Linear(_)) {
6645 if let Pattern::Ident { name, .. } = pattern {
6647 self.linear_state
6648 .vars
6649 .borrow_mut()
6650 .insert(name.name.clone());
6651 }
6652 }
6653 }
6654 if let Some(type_expr) = ty {
6656 if let Some((type_name, type_params)) = self.extract_type_params(type_expr)
6657 {
6658 self.check_generic_type_match(&type_name, &type_params, &value)?;
6659 if type_name == "Vec" && !type_params.is_empty() {
6661 if let Pattern::Ident { name, .. } = pattern {
6662 self.var_types.borrow_mut().insert(
6663 name.name.clone(),
6664 (type_name.clone(), type_params.clone()),
6665 );
6666 }
6667 }
6668 }
6669 }
6670 self.bind_pattern(pattern, value)?;
6671 }
6672 Stmt::LetElse {
6673 pattern,
6674 init,
6675 else_branch,
6676 ..
6677 } => {
6678 let value = self.evaluate(init)?;
6679 if self.bind_pattern(pattern, value.clone()).is_err() {
6681 return self.evaluate(else_branch);
6682 }
6683 }
6684 Stmt::Expr(expr) => {
6685 result = self.evaluate(expr)?;
6686 }
6687 Stmt::Semi(expr) => {
6688 self.evaluate(expr)?;
6689 result = Value::Null;
6690 }
6691 Stmt::Item(item) => {
6692 self.execute_item(item)?;
6693 }
6694 }
6695 }
6696
6697 if let Some(expr) = &block.expr {
6698 result = self.evaluate(expr)?;
6699 }
6700
6701 let values_to_drop: Vec<(String, Value)> = self
6704 .environment
6705 .borrow()
6706 .values
6707 .iter()
6708 .filter_map(|(name, value)| {
6709 if let Value::Struct {
6710 name: struct_name, ..
6711 } = value
6712 {
6713 if self.drop_types.contains(struct_name) {
6714 return Some((name.clone(), value.clone()));
6715 }
6716 }
6717 None
6718 })
6719 .collect();
6720
6721 for (_var_name, value) in values_to_drop {
6723 if let Value::Struct {
6724 name: struct_name, ..
6725 } = &value
6726 {
6727 let drop_fn_name = format!("{}·drop", struct_name);
6728 let drop_fn = self.globals.borrow().get(&drop_fn_name).map(|v| v.clone());
6730 if let Some(Value::Function(f)) = drop_fn {
6731 let _ = self.call_function(&f, vec![value.clone()]);
6733 }
6734 }
6735 }
6736
6737 self.environment = prev_env;
6738 Ok(result)
6739 }
6740
6741 fn extract_tensor_shape(&self, type_expr: &crate::ast::TypeExpr) -> Option<Vec<i64>> {
6743 use crate::ast::TypeExpr;
6744
6745 match type_expr {
6746 TypeExpr::Path(path) => {
6747 if let Some(segment) = path.segments.first() {
6749 if segment.ident.name == "Tensor" {
6750 if let Some(generics) = &segment.generics {
6752 if let Some(first_generic) = generics.first() {
6753 return self.extract_shape_from_type(first_generic);
6754 }
6755 }
6756 }
6757 }
6758 None
6759 }
6760 TypeExpr::Linear(inner) => {
6761 self.extract_tensor_shape(inner)
6763 }
6764 _ => None,
6765 }
6766 }
6767
6768 fn extract_shape_from_type(&self, type_expr: &crate::ast::TypeExpr) -> Option<Vec<i64>> {
6770 use crate::ast::{Expr, Literal, TypeExpr};
6771
6772 match type_expr {
6773 TypeExpr::ConstExpr(expr) => {
6775 if let Expr::Array(elements) = expr.as_ref() {
6776 let mut dims = Vec::new();
6777 for elem in elements {
6778 match elem {
6779 Expr::Literal(Literal::Int { value, .. }) => {
6780 if let Ok(n) = value.parse::<i64>() {
6781 dims.push(n);
6782 }
6783 }
6784 _ => {}
6785 }
6786 }
6787 if dims.is_empty() {
6788 None
6789 } else {
6790 Some(dims)
6791 }
6792 } else {
6793 None
6794 }
6795 }
6796 TypeExpr::Array { size, element: _ } => {
6798 if let Expr::Literal(Literal::Int { value, .. }) = size.as_ref() {
6799 if let Ok(n) = value.parse::<i64>() {
6800 Some(vec![n])
6801 } else {
6802 None
6803 }
6804 } else {
6805 None
6806 }
6807 }
6808 TypeExpr::Slice(inner) => {
6810 if let TypeExpr::ConstExpr(expr) = inner.as_ref() {
6813 if let Expr::Literal(Literal::Int { value, .. }) = expr.as_ref() {
6814 if let Ok(n) = value.parse::<i64>() {
6815 return Some(vec![n]);
6816 }
6817 }
6818 }
6819 None
6820 }
6821 TypeExpr::Tuple(dims) => {
6823 let mut shape = Vec::new();
6824 for dim in dims {
6825 if let TypeExpr::Path(path) = dim {
6826 if let Some(seg) = path.segments.first() {
6827 if let Ok(n) = seg.ident.name.parse::<i64>() {
6828 shape.push(n);
6829 }
6830 }
6831 }
6832 }
6833 if shape.is_empty() {
6834 None
6835 } else {
6836 Some(shape)
6837 }
6838 }
6839 TypeExpr::Path(path) => {
6841 if let Some(seg) = path.segments.first() {
6844 let name = &seg.ident.name;
6846 if name.starts_with('[') && name.ends_with(']') {
6848 let inner = &name[1..name.len() - 1];
6849 let dims: Vec<i64> = inner
6850 .split(',')
6851 .filter_map(|s| s.trim().parse().ok())
6852 .collect();
6853 if !dims.is_empty() {
6854 return Some(dims);
6855 }
6856 }
6857 }
6858 None
6859 }
6860 _ => None,
6861 }
6862 }
6863
6864 fn extract_struct_generics(
6866 &self,
6867 type_expr: &crate::ast::TypeExpr,
6868 ) -> Option<(String, Vec<i64>)> {
6869 use crate::ast::{Expr, Literal, TypeExpr};
6870
6871 let inner_type = if let TypeExpr::Linear(inner) = type_expr {
6873 inner.as_ref()
6874 } else {
6875 type_expr
6876 };
6877
6878 if let TypeExpr::Path(path) = inner_type {
6879 if let Some(segment) = path.segments.first() {
6880 let struct_name = segment.ident.name.clone();
6881 if let Some(generics) = &segment.generics {
6882 let mut const_values: Vec<i64> = Vec::new();
6883 for generic in generics {
6885 if let TypeExpr::ConstExpr(expr) = generic {
6887 if let Expr::Literal(Literal::Int { value, .. }) = expr.as_ref() {
6888 if let Ok(n) = value.parse::<i64>() {
6889 const_values.push(n);
6890 }
6891 }
6892 }
6893 if let TypeExpr::Path(inner_path) = generic {
6895 if let Some(inner_seg) = inner_path.segments.first() {
6896 if let Ok(n) = inner_seg.ident.name.parse::<i64>() {
6897 const_values.push(n);
6898 }
6899 }
6900 }
6901 }
6902 if !const_values.is_empty() {
6903 return Some((struct_name, const_values));
6904 }
6905 }
6906 }
6907 }
6908 None
6909 }
6910
6911 fn wrap_with_const_generics(
6915 func: &Rc<Function>,
6916 fields: &Rc<RefCell<HashMap<String, Value>>>,
6917 ) -> Rc<Function> {
6918 let const_bindings: Vec<(String, Value)> = fields.borrow()
6919 .iter()
6920 .filter_map(|(k, v)| {
6921 if k.starts_with("__const_") && k.ends_with("__") {
6922 let param_name = k.strip_prefix("__const_")
6923 .and_then(|s| s.strip_suffix("__"));
6924 param_name.map(|name| (name.to_string(), v.clone()))
6925 } else {
6926 None
6927 }
6928 })
6929 .collect();
6930
6931 if const_bindings.is_empty() {
6932 return func.clone();
6933 }
6934
6935 let wrapper_env = Rc::new(RefCell::new(
6937 Environment::with_parent(func.closure.clone())
6938 ));
6939 for (name, value) in &const_bindings {
6940 wrapper_env.borrow_mut().define(name.clone(), value.clone());
6941 }
6942 Rc::new(Function {
6943 name: func.name.clone(),
6944 params: func.params.clone(),
6945 body: func.body.clone(),
6946 closure: wrapper_env,
6947 generic_params: func.generic_params.clone(),
6948 })
6949 }
6950
6951 fn bind_pattern(&mut self, pattern: &Pattern, value: Value) -> Result<(), RuntimeError> {
6952 match pattern {
6953 Pattern::Ident { name, mutable, evidentiality } => {
6954 if name.name != "_" {
6956 if name.name == "path" {
6958 crate::sigil_debug!("DEBUG bind_pattern: binding 'path' = {:?}", value);
6959 }
6960 if *mutable {
6962 self.mutable_vars.borrow_mut().insert(name.name.clone());
6963 }
6964 let bound_value = if evidentiality.is_some() {
6966 match value {
6967 Value::Evidential { value: inner, .. } => *inner,
6968 other => other,
6969 }
6970 } else {
6971 value
6972 };
6973 self.environment
6974 .borrow_mut()
6975 .define(name.name.clone(), bound_value);
6976 }
6977 Ok(())
6978 }
6979 Pattern::Tuple(patterns) => {
6980 let unwrapped = Self::unwrap_all(&value);
6982 crate::sigil_debug!(
6983 "DEBUG bind_pattern Tuple: patterns.len()={}, value type={:?}",
6984 patterns.len(),
6985 std::mem::discriminant(&unwrapped)
6986 );
6987 match unwrapped {
6988 Value::Tuple(values) => {
6989 if patterns.len() != values.len() {
6990 return Err(RuntimeError::new("Tuple pattern size mismatch"));
6991 }
6992 for (i, (p, v)) in patterns.iter().zip(values.iter()).enumerate() {
6993 crate::sigil_debug!(
6994 "DEBUG binding tuple element {}: {:?} = {}",
6995 i,
6996 p,
6997 self.format_value(v)
6998 );
6999 self.bind_pattern(p, v.clone())?;
7000 }
7001 Ok(())
7002 }
7003 Value::Null => {
7004 Ok(())
7006 }
7007 Value::Array(arr) if arr.borrow().len() == patterns.len() => {
7008 let vals = arr.borrow();
7010 for (p, v) in patterns.iter().zip(vals.iter()) {
7011 self.bind_pattern(p, v.clone())?;
7012 }
7013 Ok(())
7014 }
7015 _ => Err(RuntimeError::new("Expected tuple")),
7016 }
7017 }
7018 Pattern::Wildcard => Ok(()),
7019 Pattern::Struct { path, fields, .. } => {
7020 let unwrapped = Self::unwrap_all(&value);
7022 match &unwrapped {
7024 Value::Struct {
7025 fields: struct_fields,
7026 ..
7027 } => {
7028 for field_pat in fields {
7029 let field_name = &field_pat.name.name;
7030 let field_val = struct_fields
7032 .borrow()
7033 .get(field_name)
7034 .cloned()
7035 .unwrap_or(Value::Null);
7036 if let Some(pat) = &field_pat.pattern {
7037 self.bind_pattern(pat, field_val)?;
7038 } else {
7039 self.environment
7041 .borrow_mut()
7042 .define(field_name.clone(), field_val);
7043 }
7044 }
7045 Ok(())
7046 }
7047 Value::Variant {
7048 enum_name,
7049 variant_name,
7050 fields: variant_fields,
7051 } => {
7052 let pattern_variant = path
7054 .segments
7055 .last()
7056 .map(|s| s.ident.name.as_str())
7057 .unwrap_or("");
7058 if pattern_variant == variant_name
7059 || path.segments.iter().any(|s| s.ident.name == *variant_name)
7060 {
7061 if let Some(inner_fields) = variant_fields {
7064 if inner_fields.len() == 1 {
7065 if let Value::Struct {
7067 fields: inner_struct,
7068 ..
7069 } = &inner_fields[0]
7070 {
7071 for field_pat in fields {
7072 let field_name = &field_pat.name.name;
7073 let field_val = inner_struct
7075 .borrow()
7076 .get(field_name)
7077 .cloned()
7078 .unwrap_or(Value::Null);
7079 if let Some(pat) = &field_pat.pattern {
7080 self.bind_pattern(pat, field_val)?;
7081 } else {
7082 self.environment
7083 .borrow_mut()
7084 .define(field_name.clone(), field_val);
7085 }
7086 }
7087 return Ok(());
7088 }
7089 }
7090 for field_pat in fields {
7093 let field_name = &field_pat.name.name;
7094 let field_val = inner_fields.iter().find_map(|f| {
7098 if let Value::Struct { fields: fs, .. } = f {
7099 fs.borrow().get(field_name).cloned()
7100 } else {
7101 None
7102 }
7103 });
7104 if let Some(val) = field_val {
7105 if let Some(pat) = &field_pat.pattern {
7106 self.bind_pattern(pat, val)?;
7107 } else {
7108 self.environment
7109 .borrow_mut()
7110 .define(field_name.clone(), val);
7111 }
7112 }
7113 }
7114 }
7115 Ok(())
7116 } else {
7117 crate::sigil_debug!(
7118 "DEBUG variant name mismatch: pattern={}, actual={}",
7119 pattern_variant,
7120 variant_name
7121 );
7122 Err(RuntimeError::new(format!(
7123 "Variant name mismatch: expected {} but got {}::{}",
7124 pattern_variant, enum_name, variant_name
7125 )))
7126 }
7127 }
7128 _ => {
7129 crate::sigil_debug!(
7130 "DEBUG struct pattern bind: expected struct/variant but got {:?}",
7131 std::mem::discriminant(&unwrapped)
7132 );
7133 Err(RuntimeError::new(
7134 "Expected struct or variant value for struct pattern",
7135 ))
7136 }
7137 }
7138 }
7139 Pattern::Path(_path) => {
7140 Ok(())
7143 }
7144 Pattern::TupleStruct { path, fields } => {
7145 let unwrapped = Self::unwrap_all(&value);
7148 let path_str = path
7149 .segments
7150 .iter()
7151 .map(|s| s.ident.name.as_str())
7152 .collect::<Vec<_>>()
7153 .join("::");
7154 crate::sigil_debug!(
7155 "DEBUG bind_pattern TupleStruct: path={}, value type={:?}",
7156 path_str,
7157 std::mem::discriminant(&unwrapped)
7158 );
7159 if let Value::Variant {
7160 variant_name,
7161 fields: variant_fields,
7162 enum_name,
7163 } = &unwrapped
7164 {
7165 crate::sigil_debug!(
7166 "DEBUG Variant {}::{}, fields={}",
7167 enum_name,
7168 variant_name,
7169 if variant_fields.is_some() {
7170 format!("Some(len={})", variant_fields.as_ref().unwrap().len())
7171 } else {
7172 "None".to_string()
7173 }
7174 );
7175 let pattern_variant = path
7176 .segments
7177 .last()
7178 .map(|s| s.ident.name.as_str())
7179 .unwrap_or("");
7180 if pattern_variant == variant_name {
7181 if let Some(inner_fields) = variant_fields {
7183 if fields.len() == 1 && inner_fields.len() == 1 {
7184 self.bind_pattern(&fields[0], inner_fields[0].clone())?;
7185 } else {
7186 for (pat, val) in fields.iter().zip(inner_fields.iter()) {
7187 self.bind_pattern(pat, val.clone())?;
7188 }
7189 }
7190 } else if !fields.is_empty() {
7191 crate::sigil_debug!(
7193 "DEBUG TupleStruct: pattern expects {} fields but variant has none",
7194 fields.len()
7195 );
7196 }
7197 }
7198 Ok(())
7199 } else {
7200 if let Value::Tuple(tuple_vals) = &value {
7202 for (pat, val) in fields.iter().zip(tuple_vals.iter()) {
7203 self.bind_pattern(pat, val.clone())?;
7204 }
7205 Ok(())
7206 } else {
7207 Err(RuntimeError::new(
7208 "Expected variant or tuple for tuple struct pattern",
7209 ))
7210 }
7211 }
7212 }
7213 Pattern::Literal(_) => {
7214 Ok(())
7216 }
7217 Pattern::Rest => {
7218 Ok(())
7220 }
7221 Pattern::Range { .. } => {
7222 Ok(())
7224 }
7225 Pattern::Or(patterns) => {
7226 for p in patterns {
7228 if self.pattern_matches(p, &value)? {
7229 return self.bind_pattern(p, value.clone());
7230 }
7231 }
7232 Err(RuntimeError::new("Or pattern didn't match any alternative"))
7234 }
7235 Pattern::RefBinding { name, .. } => {
7236 Err(RuntimeError::new(format!(
7238 "Rust's `ref {}` pattern is not supported in Sigil. \
7239 Variables bind by value. Use `≔ {} = &expr` for explicit references",
7240 name.name, name.name
7241 )))
7242 }
7243 Pattern::Ref { pattern: inner, .. } => {
7244 let unwrapped = match &value {
7246 Value::Ref(r) => r.borrow().clone(),
7247 other => other.clone(),
7248 };
7249 self.bind_pattern(inner, unwrapped)
7250 }
7251 _ => Err(RuntimeError::new(format!(
7252 "Unsupported pattern: {:?}",
7253 pattern
7254 ))),
7255 }
7256 }
7257
7258 fn eval_if(
7259 &mut self,
7260 condition: &Expr,
7261 then_branch: &Block,
7262 else_branch: &Option<Box<Expr>>,
7263 ) -> Result<Value, RuntimeError> {
7264 let cond = self.evaluate(condition)?;
7265 if self.is_truthy(&cond) {
7266 self.eval_block(then_branch)
7267 } else if let Some(else_expr) = else_branch {
7268 self.evaluate(else_expr)
7269 } else {
7270 Ok(Value::Null)
7271 }
7272 }
7273
7274 fn eval_match(&mut self, expr: &Expr, arms: &[MatchArm]) -> Result<Value, RuntimeError> {
7275 if arms.len() >= 2 {
7277 let mut first_type: Option<String> = None;
7278 for arm in arms {
7279 if let Some(arm_type) = self.infer_expr_type(&arm.body) {
7280 if let Some(ref expected) = first_type {
7281 if &arm_type != expected {
7282 return Err(RuntimeError::new(format!(
7283 "match arms have incompatible types: expected '{}', found '{}'",
7284 expected, arm_type
7285 )));
7286 }
7287 } else {
7288 first_type = Some(arm_type);
7289 }
7290 }
7291 }
7292 }
7293
7294 let value = self.evaluate(expr)?;
7295
7296 let unwrapped = Self::unwrap_all(&value);
7298 if let Value::String(s) = &unwrapped {
7299 if s.len() <= 10 {
7300 crate::sigil_debug!("DEBUG eval_match: string='{}', arms={}", s, arms.len());
7301 }
7302 }
7303
7304 for arm in arms {
7305 if self.pattern_matches(&arm.pattern, &value)? {
7306 let env = Rc::new(RefCell::new(Environment::with_parent(
7308 self.environment.clone(),
7309 )));
7310 let prev_env = self.environment.clone();
7311 self.environment = env;
7312
7313 if let Err(e) = self.bind_pattern(&arm.pattern, value.clone()) {
7316 self.environment = prev_env;
7317 return Err(e);
7318 }
7319
7320 if let Some(guard) = &arm.guard {
7322 let guard_val = self.evaluate(guard)?;
7323 if !self.is_truthy(&guard_val) {
7324 self.environment = prev_env;
7326 continue;
7327 }
7328 }
7329
7330 let result = self.evaluate(&arm.body);
7332
7333 self.environment = prev_env;
7334 return result;
7335 }
7336 }
7337
7338 eprintln!(
7340 "DEBUG No matching pattern for value: {} (discriminant: {:?})",
7341 self.format_value(&value),
7342 std::mem::discriminant(&value)
7343 );
7344 match &value {
7346 Value::Struct { name, fields } => {
7347 eprintln!(
7348 " Struct: name='{}', fields={:?}",
7349 name,
7350 fields.borrow().keys().collect::<Vec<_>>()
7351 );
7352 }
7353 Value::Variant {
7354 enum_name,
7355 variant_name,
7356 fields,
7357 } => {
7358 eprintln!(
7359 " Variant: {}::{}, fields={:?}",
7360 enum_name, variant_name, fields
7361 );
7362 }
7363 _ => {}
7364 }
7365 for (i, arm) in arms.iter().enumerate() {
7367 eprintln!("DEBUG arm {}: {:?}", i, arm.pattern);
7368 }
7369 Err(RuntimeError::new(format!(
7370 "No matching pattern for {}",
7371 self.format_value(&value)
7372 )))
7373 }
7374
7375 fn pattern_matches(&mut self, pattern: &Pattern, value: &Value) -> Result<bool, RuntimeError> {
7376 if let Pattern::Ident { evidentiality: Some(ev), .. } = pattern {
7378 return match (ev, value) {
7379 (Evidentiality::Known, Value::Evidential { evidence: Evidence::Known, .. }) => Ok(true),
7381 (Evidentiality::Uncertain, Value::Evidential { evidence: Evidence::Uncertain, .. }) => Ok(true),
7382 (Evidentiality::Reported, Value::Evidential { evidence: Evidence::Reported, .. }) => Ok(true),
7383 (Evidentiality::Predicted, Value::Evidential { evidence: Evidence::Predicted, .. }) => Ok(true),
7384 (Evidentiality::Paradox, Value::Evidential { evidence: Evidence::Paradox, .. }) => Ok(true),
7385 (Evidentiality::Known, v) if !matches!(v, Value::Evidential { .. } | Value::Null) => Ok(true),
7387 (Evidentiality::Uncertain, v) if !matches!(v, Value::Null) => Ok(true),
7390 _ => Ok(false),
7391 };
7392 }
7393
7394 let value = Self::unwrap_all(value);
7396
7397 if let Value::String(s) = &value {
7399 if **s == "fn" {
7400 crate::sigil_debug!("DEBUG pattern_matches: value='fn', pattern={:?}", pattern);
7401 }
7402 }
7403
7404 match (pattern, &value) {
7405 (Pattern::Wildcard, _) => Ok(true),
7406 (Pattern::Ident { .. }, _) => Ok(true),
7407 (Pattern::Literal(lit), val) => {
7408 let lit_val = self.eval_literal(lit)?;
7409 let result = self.values_equal(&lit_val, val);
7410 if matches!(lit, Literal::Null) || matches!(val, Value::Null) {
7412 crate::sigil_debug!(
7413 "DEBUG literal pattern: lit={:?}, lit_val={}, val={}, result={}",
7414 lit,
7415 self.format_value(&lit_val),
7416 self.format_value(val),
7417 result
7418 );
7419 }
7420 Ok(result)
7421 }
7422 (Pattern::Tuple(patterns), Value::Tuple(values)) => {
7423 if patterns.len() != values.len() {
7424 return Ok(false);
7425 }
7426 for (p, v) in patterns.iter().zip(values.iter()) {
7427 if !self.pattern_matches(p, v)? {
7428 return Ok(false);
7429 }
7430 }
7431 Ok(true)
7432 }
7433 (
7435 Pattern::Path(path),
7436 Value::Variant {
7437 variant_name,
7438 fields,
7439 ..
7440 },
7441 ) => {
7442 let pattern_variant = path
7443 .segments
7444 .last()
7445 .map(|s| s.ident.name.as_str())
7446 .unwrap_or("");
7447 Ok(pattern_variant == variant_name && fields.is_none())
7449 }
7450 (
7452 Pattern::TupleStruct {
7453 path,
7454 fields: pat_fields,
7455 },
7456 Value::Variant {
7457 variant_name,
7458 fields,
7459 ..
7460 },
7461 ) => {
7462 let pattern_variant = path
7463 .segments
7464 .last()
7465 .map(|s| s.ident.name.as_str())
7466 .unwrap_or("");
7467 if pattern_variant != variant_name {
7468 return Ok(false);
7469 }
7470 if let Some(variant_fields) = fields {
7472 if pat_fields.len() != variant_fields.len() {
7473 return Ok(false);
7474 }
7475 for (p, v) in pat_fields.iter().zip(variant_fields.iter()) {
7476 if !self.pattern_matches(p, v)? {
7477 return Ok(false);
7478 }
7479 }
7480 Ok(true)
7481 } else {
7482 Ok(pat_fields.is_empty())
7484 }
7485 }
7486 (
7488 Pattern::Struct {
7489 path,
7490 fields: pat_fields,
7491 rest,
7492 },
7493 Value::Struct {
7494 name: struct_name,
7495 fields: struct_fields,
7496 },
7497 ) => {
7498 let pattern_name = path
7499 .segments
7500 .iter()
7501 .map(|s| s.ident.name.as_str())
7502 .collect::<Vec<_>>()
7503 .join("::");
7504 if pattern_name != *struct_name {
7505 return Ok(false);
7506 }
7507 let borrowed = struct_fields.borrow();
7509 for field_pat in pat_fields {
7510 let field_name = &field_pat.name.name;
7511 if let Some(field_val) = borrowed.get(field_name) {
7512 if let Some(sub_pat) = &field_pat.pattern {
7513 if !self.pattern_matches(sub_pat, field_val)? {
7514 return Ok(false);
7515 }
7516 }
7517 } else if !rest {
7519 return Ok(false);
7521 }
7522 }
7523 Ok(true)
7524 }
7525 (
7527 Pattern::Struct {
7528 path,
7529 fields: pat_fields,
7530 rest,
7531 },
7532 Value::Variant {
7533 variant_name,
7534 fields: variant_fields,
7535 ..
7536 },
7537 ) => {
7538 let pattern_variant = path
7539 .segments
7540 .last()
7541 .map(|s| s.ident.name.as_str())
7542 .unwrap_or("");
7543 if pattern_variant != variant_name {
7544 return Ok(false);
7545 }
7546 if let Some(inner_fields) = variant_fields {
7548 if inner_fields.len() == 1 {
7549 if let Value::Struct {
7550 fields: inner_struct,
7551 ..
7552 } = &inner_fields[0]
7553 {
7554 let borrowed = inner_struct.borrow();
7555 for field_pat in pat_fields {
7556 let field_name = &field_pat.name.name;
7557 if let Some(field_val) = borrowed.get(field_name) {
7558 if let Some(sub_pat) = &field_pat.pattern {
7559 if !self.pattern_matches(sub_pat, field_val)? {
7560 return Ok(false);
7561 }
7562 }
7563 } else if !rest {
7564 return Ok(false);
7565 }
7566 }
7567 return Ok(true);
7568 }
7569 }
7570 }
7571 Ok(pat_fields.is_empty() || *rest)
7573 }
7574 (Pattern::Or(patterns), val) => {
7576 for p in patterns {
7577 if self.pattern_matches(p, val)? {
7578 return Ok(true);
7579 }
7580 }
7581 Ok(false)
7582 }
7583 (Pattern::Rest, _) => Ok(true),
7585 (
7587 Pattern::Range {
7588 start,
7589 end,
7590 inclusive,
7591 },
7592 val,
7593 ) => {
7594 let extract_char = |pat: &Option<Box<Pattern>>| -> Option<char> {
7596 match pat {
7597 Some(p) => match p.as_ref() {
7598 Pattern::Literal(Literal::Char(c)) => Some(*c),
7599 _ => None,
7600 },
7601 None => None,
7602 }
7603 };
7604 let extract_int = |pat: &Option<Box<Pattern>>| -> Option<i64> {
7606 match pat {
7607 Some(p) => match p.as_ref() {
7608 Pattern::Literal(Literal::Int { value, .. }) => value.parse().ok(),
7609 _ => None,
7610 },
7611 None => None,
7612 }
7613 };
7614
7615 match val {
7616 Value::Char(c) => {
7617 let start_val = extract_char(start);
7618 let end_val = extract_char(end);
7619 let in_range = match (start_val, end_val, *inclusive) {
7620 (Some(s), Some(e), true) => *c >= s && *c <= e,
7621 (Some(s), Some(e), false) => *c >= s && *c < e,
7622 (Some(s), None, _) => *c >= s,
7623 (None, Some(e), true) => *c <= e,
7624 (None, Some(e), false) => *c < e,
7625 (None, None, _) => true,
7626 };
7627 Ok(in_range)
7628 }
7629 Value::Int(i) => {
7630 let start_val = extract_int(start);
7631 let end_val = extract_int(end);
7632 let in_range = match (start_val, end_val, *inclusive) {
7633 (Some(s), Some(e), true) => *i >= s && *i <= e,
7634 (Some(s), Some(e), false) => *i >= s && *i < e,
7635 (Some(s), None, _) => *i >= s,
7636 (None, Some(e), true) => *i <= e,
7637 (None, Some(e), false) => *i < e,
7638 (None, None, _) => true,
7639 };
7640 Ok(in_range)
7641 }
7642 _ => Ok(false),
7643 }
7644 }
7645 (Pattern::Literal(Literal::String(s)), Value::String(vs)) => Ok(s == vs.as_str()),
7647 (Pattern::Literal(Literal::Char(c)), Value::Char(vc)) => Ok(c == vc),
7648 (Pattern::Ref { pattern: inner, .. }, val) => {
7650 let unwrapped = match val {
7651 Value::Ref(r) => r.borrow().clone(),
7652 other => other.clone(),
7653 };
7654 self.pattern_matches(inner, &unwrapped)
7655 }
7656 _ => Ok(false),
7657 }
7658 }
7659
7660 fn values_equal(&self, a: &Value, b: &Value) -> bool {
7661 let a_unwrapped = match a {
7663 Value::Ref(r) => r.borrow().clone(),
7664 _ => a.clone(),
7665 };
7666 let b_unwrapped = match b {
7667 Value::Ref(r) => r.borrow().clone(),
7668 _ => b.clone(),
7669 };
7670 match (&a_unwrapped, &b_unwrapped) {
7671 (Value::Null, Value::Null) => true,
7672 (Value::Bool(a), Value::Bool(b)) => a == b,
7673 (Value::Int(a), Value::Int(b)) => a == b,
7674 (Value::Float(a), Value::Float(b)) => (a - b).abs() < f64::EPSILON,
7675 (Value::String(a), Value::String(b)) => {
7676 let result = **a == **b;
7677 if a.len() <= 5 && b.len() <= 5 {
7679 crate::sigil_debug!("DEBUG values_equal: '{}' == '{}' -> {}", a, b, result);
7680 }
7681 result
7682 }
7683 (Value::Char(a), Value::Char(b)) => a == b,
7684 _ => false,
7685 }
7686 }
7687
7688 fn eval_for(
7689 &mut self,
7690 pattern: &Pattern,
7691 iter: &Expr,
7692 body: &Block,
7693 ) -> Result<Value, RuntimeError> {
7694 let iterable_raw = self.evaluate(iter)?;
7695 let iterable = Self::unwrap_all(&iterable_raw);
7696 let items = match iterable {
7697 Value::Array(arr) => arr.borrow().clone(),
7698 Value::Tuple(t) => (*t).clone(),
7699 Value::String(s) => s.chars().map(Value::Char).collect(),
7700 Value::Map(m) => {
7701 m.borrow()
7703 .iter()
7704 .map(|(k, v)| {
7705 Value::Tuple(Rc::new(vec![Value::String(Rc::new(k.clone())), v.clone()]))
7706 })
7707 .collect()
7708 }
7709 Value::Variant {
7710 fields: Some(f), ..
7711 } => (*f).clone(),
7712 _ => {
7713 return Err(RuntimeError::new(format!(
7714 "Cannot iterate over non-iterable: {:?}",
7715 iterable_raw
7716 )))
7717 }
7718 };
7719
7720 let mut result = Value::Null;
7721 for item in items {
7722 let env = Rc::new(RefCell::new(Environment::with_parent(
7723 self.environment.clone(),
7724 )));
7725 let prev_env = self.environment.clone();
7726 self.environment = env;
7727
7728 self.bind_pattern(pattern, item)?;
7729
7730 match self.eval_block(body) {
7731 Ok(val) => result = val,
7732 Err(e) if e.message == "break" => {
7733 self.environment = prev_env;
7734 break;
7735 }
7736 Err(e) if e.message == "continue" => {
7737 self.environment = prev_env;
7738 continue;
7739 }
7740 Err(e) => {
7741 self.environment = prev_env;
7742 return Err(e);
7743 }
7744 }
7745
7746 self.environment = prev_env;
7747 }
7748
7749 Ok(result)
7750 }
7751
7752 fn eval_while(&mut self, condition: &Expr, body: &Block) -> Result<Value, RuntimeError> {
7753 let mut result = Value::Null;
7754 loop {
7755 let cond = self.evaluate(condition)?;
7756 if !self.is_truthy(&cond) {
7757 break;
7758 }
7759
7760 match self.eval_block(body) {
7761 Ok(val) => result = val,
7762 Err(e) if e.message == "break" => break,
7763 Err(e) if e.message == "continue" => continue,
7764 Err(e) => return Err(e),
7765 }
7766 }
7767 Ok(result)
7768 }
7769
7770 fn eval_loop(&mut self, body: &Block) -> Result<Value, RuntimeError> {
7771 loop {
7772 match self.eval_block(body) {
7773 Ok(_) => {}
7774 Err(e) if e.message == "break" => break,
7775 Err(e) if e.message == "continue" => continue,
7776 Err(e) => return Err(e),
7777 }
7778 }
7779 Ok(Value::Null)
7780 }
7781
7782 fn eval_return(&mut self, value: &Option<Box<Expr>>) -> Result<Value, RuntimeError> {
7783 let val = match value {
7784 Some(expr) => self.evaluate(expr)?,
7785 None => Value::Null,
7786 };
7787 self.return_value = Some(val);
7789 Err(RuntimeError::new("return"))
7790 }
7791
7792 fn eval_break(&mut self, _value: &Option<Box<Expr>>) -> Result<Value, RuntimeError> {
7793 Err(RuntimeError::new("break"))
7795 }
7796
7797 fn eval_index(&mut self, expr: &Expr, index: &Expr) -> Result<Value, RuntimeError> {
7798 let collection = self.evaluate(expr)?;
7799
7800 let collection = match collection {
7802 Value::Ref(r) => r.borrow().clone(),
7803 other => other,
7804 };
7805
7806 if let Expr::Range {
7808 start,
7809 end,
7810 inclusive,
7811 } = index
7812 {
7813 let start_val = match start {
7814 Some(e) => match self.evaluate(e)? {
7815 Value::Int(n) => n as usize,
7816 _ => return Err(RuntimeError::new("Slice start must be an integer")),
7817 },
7818 None => 0,
7819 };
7820
7821 return match &collection {
7822 Value::Array(arr) => {
7823 let arr = arr.borrow();
7824 let len = arr.len();
7825 let end_val = match end {
7826 Some(e) => match self.evaluate(e)? {
7827 Value::Int(n) => {
7828 let n = n as usize;
7829 if *inclusive {
7830 n + 1
7831 } else {
7832 n
7833 }
7834 }
7835 _ => return Err(RuntimeError::new("Slice end must be an integer")),
7836 },
7837 None => len, };
7839 let end_val = end_val.min(len);
7840 let start_val = start_val.min(len);
7841 let sliced: Vec<Value> = arr[start_val..end_val].to_vec();
7842 Ok(Value::Array(Rc::new(RefCell::new(sliced))))
7843 }
7844 Value::String(s) => {
7845 let len = s.len();
7846 let end_val = match end {
7847 Some(e) => match self.evaluate(e)? {
7848 Value::Int(n) => {
7849 let n = n as usize;
7850 if *inclusive {
7851 n + 1
7852 } else {
7853 n
7854 }
7855 }
7856 _ => return Err(RuntimeError::new("Slice end must be an integer")),
7857 },
7858 None => len, };
7860 let end_val = end_val.min(len);
7861 let start_val = start_val.min(len);
7862 let sliced = &s[start_val..end_val];
7864 Ok(Value::String(Rc::new(sliced.to_string())))
7865 }
7866 _ => Err(RuntimeError::new("Cannot slice this type")),
7867 };
7868 }
7869
7870 let idx = self.evaluate(index)?;
7871
7872 match (collection, idx) {
7873 (Value::Array(arr), Value::Int(i)) => {
7874 let arr = arr.borrow();
7875 let len = arr.len();
7876
7877 let is_typed_vec = if let Some(var_name) = Self::extract_root_var(expr) {
7880 self.var_types
7881 .borrow()
7882 .get(&var_name)
7883 .map(|(type_name, _)| type_name == "Vec")
7884 .unwrap_or(false)
7885 } else {
7886 false
7887 };
7888
7889 let idx = if i < 0 {
7890 if is_typed_vec {
7891 return Err(RuntimeError::new(format!(
7892 "negative index {} is invalid",
7893 i
7894 )));
7895 }
7896 let positive_idx = (len as i64 + i) as usize;
7898 if positive_idx >= len {
7899 return Err(RuntimeError::index_out_of_bounds(i, len));
7900 }
7901 positive_idx
7902 } else {
7903 i as usize
7904 };
7905
7906 let result = arr
7907 .get(idx)
7908 .cloned()
7909 .ok_or_else(|| RuntimeError::index_out_of_bounds(i, len));
7910 if let Ok(ref v) = result {
7911 crate::sigil_debug!(
7912 "DEBUG eval_index: arr[{}] = {:?}",
7913 idx,
7914 std::mem::discriminant(v)
7915 );
7916 }
7917 result
7918 }
7919 (Value::Tuple(t), Value::Int(i)) => {
7920 if i < 0 {
7922 return Err(RuntimeError::new(format!(
7923 "negative index {} is invalid",
7924 i
7925 )));
7926 }
7927 let len = t.len();
7928 let idx = i as usize;
7929 t.get(idx)
7930 .cloned()
7931 .ok_or_else(|| RuntimeError::index_out_of_bounds(i, len))
7932 }
7933 (Value::String(s), Value::Int(i)) => {
7934 if i < 0 {
7936 return Err(RuntimeError::new(format!(
7937 "negative index {} is invalid",
7938 i
7939 )));
7940 }
7941 let len = s.len();
7942 let idx = i as usize;
7943 s.chars()
7944 .nth(idx)
7945 .map(Value::Char)
7946 .ok_or_else(|| RuntimeError::index_out_of_bounds(i, len))
7947 }
7948 (Value::Array(arr), Value::Tuple(range_tuple)) if range_tuple.len() == 2 => {
7950 let arr = arr.borrow();
7951 let start = match &range_tuple[0] {
7952 Value::Int(n) => *n as usize,
7953 _ => return Err(RuntimeError::new("Range start must be integer")),
7954 };
7955 let end = match &range_tuple[1] {
7956 Value::Null => arr.len(), Value::Int(n) => *n as usize,
7958 _ => return Err(RuntimeError::new("Range end must be integer or None")),
7959 };
7960 let start = start.min(arr.len());
7961 let end = end.min(arr.len());
7962 let sliced: Vec<Value> = arr[start..end].to_vec();
7963 Ok(Value::Array(Rc::new(RefCell::new(sliced))))
7964 }
7965 (Value::String(s), Value::Tuple(range_tuple)) if range_tuple.len() == 2 => {
7966 let start = match &range_tuple[0] {
7967 Value::Int(n) => *n as usize,
7968 _ => return Err(RuntimeError::new("Range start must be integer")),
7969 };
7970 let end = match &range_tuple[1] {
7971 Value::Null => s.len(), Value::Int(n) => *n as usize,
7973 _ => return Err(RuntimeError::new("Range end must be integer or None")),
7974 };
7975 let start = start.min(s.len());
7976 let end = end.min(s.len());
7977 let sliced = &s[start..end];
7978 Ok(Value::String(Rc::new(sliced.to_string())))
7979 }
7980 (Value::Struct { name, fields }, Value::Int(i)) if name == "Tensor" => {
7982 let fields_ref = fields.borrow();
7983
7984 let shape: Vec<i64> = match fields_ref.get("shape") {
7986 Some(Value::Array(arr)) => arr
7987 .borrow()
7988 .iter()
7989 .filter_map(|v| match v {
7990 Value::Int(n) => Some(*n),
7991 _ => None,
7992 })
7993 .collect(),
7994 _ => vec![],
7995 };
7996 let data: Vec<f64> = match fields_ref.get("data") {
7997 Some(Value::Array(arr)) => arr
7998 .borrow()
7999 .iter()
8000 .filter_map(|v| match v {
8001 Value::Float(f) => Some(*f),
8002 Value::Int(n) => Some(*n as f64),
8003 _ => None,
8004 })
8005 .collect(),
8006 _ => vec![],
8007 };
8008 drop(fields_ref);
8009
8010 let idx = if i < 0 { shape[0] + i } else { i } as usize;
8011
8012 if shape.len() == 1 {
8013 if idx < data.len() {
8015 Ok(Value::Float(data[idx]))
8016 } else {
8017 Err(RuntimeError::index_out_of_bounds(i, data.len()))
8018 }
8019 } else if shape.len() >= 2 {
8020 let row_size: usize = shape[1..].iter().map(|&d| d as usize).product();
8022 let start = idx * row_size;
8023 let end = start + row_size;
8024
8025 if end <= data.len() {
8026 let row_data: Vec<Value> =
8027 data[start..end].iter().map(|&f| Value::Float(f)).collect();
8028 let row_shape: Vec<Value> =
8029 shape[1..].iter().map(|&d| Value::Int(d)).collect();
8030
8031 let mut new_fields = std::collections::HashMap::new();
8032 new_fields.insert(
8033 "shape".to_string(),
8034 Value::Array(Rc::new(RefCell::new(row_shape))),
8035 );
8036 new_fields.insert(
8037 "data".to_string(),
8038 Value::Array(Rc::new(RefCell::new(row_data))),
8039 );
8040 new_fields.insert("requires_grad".to_string(), Value::Bool(false));
8041
8042 Ok(Value::Struct {
8043 name: "Tensor".to_string(),
8044 fields: Rc::new(RefCell::new(new_fields)),
8045 })
8046 } else {
8047 Err(RuntimeError::index_out_of_bounds(i, shape[0] as usize))
8048 }
8049 } else {
8050 Err(RuntimeError::new("Cannot index scalar tensor"))
8052 }
8053 }
8054 (coll, idx) => {
8055 crate::sigil_debug!(
8056 "DEBUG Cannot index: collection={:?}, index={:?}",
8057 std::mem::discriminant(&coll),
8058 std::mem::discriminant(&idx)
8059 );
8060 Err(RuntimeError::new("Cannot index"))
8061 }
8062 }
8063 }
8064
8065 fn eval_field(&mut self, expr: &Expr, field: &Ident) -> Result<Value, RuntimeError> {
8066 if field.name == "items" {
8067 crate::sigil_debug!("DEBUG eval_field: accessing .items on expr={:?}", expr);
8068 }
8069 if field.name == "evidence" {
8071 crate::sigil_debug!("DEBUG eval_field: accessing .evidence");
8072 }
8073 let value = self.evaluate(expr)?;
8074 if field.name == "items" {
8075 crate::sigil_debug!(
8076 "DEBUG eval_field: .items receiver value={:?}",
8077 std::mem::discriminant(&value)
8078 );
8079 }
8080 if field.name == "evidence" {
8081 crate::sigil_debug!(
8082 "DEBUG eval_field: .evidence receiver value type={:?}",
8083 std::mem::discriminant(&value)
8084 );
8085 }
8086 fn get_field(val: &Value, field_name: &str) -> Result<Value, RuntimeError> {
8088 if field_name == "evidence" {
8090 crate::sigil_debug!(
8091 "DEBUG get_field 'evidence' on value type: {:?}",
8092 std::mem::discriminant(val)
8093 );
8094 }
8095 match val {
8096 Value::Struct { name, fields } => {
8097 let field_val = fields.borrow().get(field_name).cloned();
8098 if field_val.is_none() && field_name == "path" {
8099 crate::sigil_debug!(
8100 "DEBUG Unknown field 'path': struct={}, available={:?}",
8101 name,
8102 fields.borrow().keys().collect::<Vec<_>>()
8103 );
8104 }
8105 if field_name == "evidence" || name.contains("IrPattern") {
8107 crate::sigil_debug!("DEBUG get_field on Struct: name={}, field={}, available={:?}, found={}",
8108 name, field_name, fields.borrow().keys().collect::<Vec<_>>(), field_val.is_some());
8109 }
8110 match field_val {
8112 Some(v) => Ok(v),
8113 None => Err(RuntimeError::new(format!(
8114 "no field '{}' on struct '{}'",
8115 field_name, name
8116 ))),
8117 }
8118 }
8119 Value::Tuple(t) => {
8120 let idx: usize = field_name
8122 .parse()
8123 .map_err(|_| RuntimeError::new("Invalid tuple index"))?;
8124 t.get(idx)
8125 .cloned()
8126 .ok_or_else(|| RuntimeError::new("Tuple index out of bounds"))
8127 }
8128 Value::Ref(r) => {
8129 get_field(&r.borrow(), field_name)
8131 }
8132 Value::Evidential { value, .. } => {
8133 get_field(value, field_name)
8135 }
8136 Value::Affective { value, .. } => {
8137 get_field(value, field_name)
8139 }
8140 Value::Map(map) => {
8141 map.borrow()
8143 .get(field_name)
8144 .cloned()
8145 .ok_or_else(|| RuntimeError::new(format!("no field '{}' in map", field_name)))
8146 }
8147 Value::Variant {
8148 fields: variant_fields,
8149 ..
8150 } => {
8151 if let Some(inner_fields) = variant_fields {
8154 for f in inner_fields.iter() {
8156 if let Value::Struct {
8157 fields: struct_fields,
8158 ..
8159 } = f
8160 {
8161 if let Some(field_val) =
8162 struct_fields.borrow().get(field_name).cloned()
8163 {
8164 return Ok(field_val);
8165 }
8166 }
8167 }
8168 Ok(Value::Null)
8170 } else {
8171 Ok(Value::Null)
8173 }
8174 }
8175 other => {
8176 crate::sigil_warn!(
8178 "WARN: Cannot access field '{}' on non-struct - returning null",
8179 field_name
8180 );
8181 Ok(Value::Null)
8182 }
8183 }
8184 }
8185 get_field(&value, &field.name)
8186 }
8187
8188 fn extract_root_var(expr: &Expr) -> Option<String> {
8190 match expr {
8191 Expr::Path(path) if path.segments.len() == 1 => {
8192 Some(path.segments[0].ident.name.clone())
8193 }
8194 Expr::MethodCall { receiver, .. } => Self::extract_root_var(receiver),
8195 _ => None,
8196 }
8197 }
8198
8199 fn eval_method_call(
8200 &mut self,
8201 receiver: &Expr,
8202 method: &Ident,
8203 args: &[Expr],
8204 ) -> Result<Value, RuntimeError> {
8205 if (method.name == "push" || method.name == "push_str") && args.len() == 1 {
8207 let recv_val = self.evaluate(receiver)?;
8208 let recv_unwrapped = Self::unwrap_all(&recv_val);
8209 if let Value::String(s) = &recv_unwrapped {
8210 let arg = self.evaluate(&args[0])?;
8211 let arg_unwrapped = Self::unwrap_all(&arg);
8212 let new_s = match arg_unwrapped {
8213 Value::Char(c) => {
8214 let mut new_str = (**s).clone();
8215 new_str.push(c);
8216 new_str
8217 }
8218 Value::String(ref add_s) => {
8219 let mut new_str = (**s).clone();
8220 new_str.push_str(add_s);
8221 new_str
8222 }
8223 _ => return Err(RuntimeError::new("push expects char or string argument")),
8224 };
8225 let new_val = Value::String(Rc::new(new_s));
8226
8227 if let Some(root_var) = Self::extract_root_var(receiver) {
8229 self.environment
8230 .borrow_mut()
8231 .set(&root_var, new_val.clone())?;
8232 return Ok(new_val);
8234 }
8235
8236 if let Expr::Field {
8238 expr: base_expr,
8239 field: field_ident,
8240 } = receiver
8241 {
8242 let base = self.evaluate(base_expr)?;
8243 if let Value::Struct { fields, .. } = base {
8244 fields
8245 .borrow_mut()
8246 .insert(field_ident.name.clone(), new_val.clone());
8247 return Ok(new_val);
8249 }
8250 }
8251 return Ok(new_val);
8253 }
8254 }
8255
8256 let recv_raw = self.evaluate(receiver)?;
8257 let recv = Self::unwrap_value(&recv_raw).clone();
8259
8260 static METHOD_COUNT: std::sync::atomic::AtomicUsize =
8262 std::sync::atomic::AtomicUsize::new(0);
8263 let count = METHOD_COUNT.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
8264 if count < 500 {
8265 let recv_type = match &recv {
8266 Value::Struct { name, .. } => format!("Struct({})", name),
8267 Value::String(s) => format!(
8268 "String('{}')",
8269 if s.len() <= 20 { s.as_str() } else { "<long>" }
8270 ),
8271 Value::Ref(r) => format!("Ref({:?})", std::mem::discriminant(&*r.borrow())),
8272 other => format!("{:?}", std::mem::discriminant(other)),
8273 };
8274 if recv_type.contains("Lexer")
8275 || method.name.contains("keyword")
8276 || method.name.contains("lex")
8277 {
8278 crate::sigil_debug!("DEBUG method #{}: {}.{}()", count, recv_type, method.name);
8279 }
8280 }
8281 let mut arg_entries: Vec<(Option<String>, Value)> = Vec::new();
8283 for arg in args.iter() {
8284 let (arg_name, inner_arg) = if let Expr::NamedArg { name, value } = arg {
8285 (Some(name.name.clone()), value.as_ref())
8286 } else {
8287 (None, arg)
8288 };
8289 let val = self.evaluate(inner_arg)?;
8290 arg_entries.push((arg_name, val));
8291 }
8292 let arg_values: Vec<Value> = arg_entries.iter().map(|(_, v)| v.clone()).collect();
8294
8295 if method.name == "cloned" || method.name == "clone" {
8297 let recv_type = match &recv {
8298 Value::Struct { name, .. } => format!("Struct({})", name),
8299 Value::Variant {
8300 enum_name,
8301 variant_name,
8302 ..
8303 } => format!("Variant({}::{})", enum_name, variant_name),
8304 Value::String(_) => "String".to_string(),
8305 Value::Ref(r) => format!("Ref({:?})", std::mem::discriminant(&*r.borrow())),
8306 Value::Null => "Null".to_string(),
8307 other => format!("{:?}", std::mem::discriminant(other)),
8308 };
8309 crate::sigil_debug!("DEBUG {}: recv_type={}", method.name, recv_type);
8310 }
8311
8312 if method.name == "as_str" {
8314 let recv_unwrapped = Self::unwrap_all(&recv);
8315 if let Value::String(s) = &recv_unwrapped {
8316 crate::sigil_debug!("DEBUG as_str CALL: recv='{}' len={}", s, s.len());
8317 } else {
8318 crate::sigil_debug!("DEBUG as_str CALL: recv={:?} (not string)", recv_unwrapped);
8319 }
8320 }
8321
8322 if method.name == "keyword_or_ident" {
8324 let recv_type = match &recv {
8325 Value::Struct { name, .. } => format!("Struct({})", name),
8326 Value::String(_) => "String".to_string(),
8327 Value::Ref(r) => format!(
8328 "Ref({})",
8329 match &*r.borrow() {
8330 Value::Struct { name, .. } => format!("Struct({})", name),
8331 other => format!("{:?}", std::mem::discriminant(other)),
8332 }
8333 ),
8334 other => format!("{:?}", std::mem::discriminant(other)),
8335 };
8336 crate::sigil_debug!("DEBUG keyword_or_ident: recv_type={}", recv_type);
8337 }
8338
8339 for arg in &arg_values {
8341 let unwrapped = Self::unwrap_all(arg);
8342 if let Value::String(s) = &unwrapped {
8343 if **s == "fn" {
8344 let recv_type = match &recv {
8345 Value::Struct { name, .. } => format!("Struct({})", name),
8346 Value::String(_) => "String".to_string(),
8347 Value::Ref(_) => "Ref".to_string(),
8348 other => format!("{:?}", std::mem::discriminant(other)),
8349 };
8350 crate::sigil_debug!(
8351 "DEBUG method call with 'fn': method={}, recv_type={}",
8352 method.name,
8353 recv_type
8354 );
8355 }
8356 }
8357 }
8358
8359 match (&recv, method.name.as_str()) {
8361 (Value::Array(arr), "len") => Ok(Value::Int(arr.borrow().len() as i64)),
8362 (Value::Array(arr), "capacity") => Ok(Value::Int(arr.borrow().capacity() as i64)),
8363 (Value::Array(arr), "as_slice") => {
8364 Ok(Value::Array(Rc::new(RefCell::new(arr.borrow().clone()))))
8366 }
8367 (Value::Array(arr), "push") => {
8368 if arg_values.len() != 1 {
8369 return Err(RuntimeError::new("push expects 1 argument"));
8370 }
8371 if let Some(var_name) = Self::extract_root_var(receiver) {
8373 if let Some((type_name, type_params)) = self.var_types.borrow().get(&var_name) {
8374 if type_name == "Vec" && !type_params.is_empty() {
8375 let expected_type = &type_params[0];
8376 let actual_type = self.value_type_name(&arg_values[0]);
8377 if &actual_type != expected_type {
8378 return Err(RuntimeError::new(format!(
8379 "type mismatch: expected Vec<{}>.push({}), found {}",
8380 expected_type, expected_type, actual_type
8381 )));
8382 }
8383 }
8384 }
8385 }
8386 arr.borrow_mut().push(arg_values[0].clone());
8387 Ok(Value::Null)
8388 }
8389 (Value::Array(arr), "pop") => {
8390 match arr.borrow_mut().pop() {
8391 Some(value) => {
8392 Ok(Value::Variant {
8394 enum_name: "Option".to_string(),
8395 variant_name: "Some".to_string(),
8396 fields: Some(Rc::new(vec![value])),
8397 })
8398 }
8399 None => {
8400 Ok(Value::Variant {
8402 enum_name: "Option".to_string(),
8403 variant_name: "None".to_string(),
8404 fields: None,
8405 })
8406 }
8407 }
8408 }
8409 (Value::Array(arr), "clear") => {
8410 arr.borrow_mut().clear();
8411 Ok(Value::Null)
8412 }
8413 (Value::Array(arr), "extend") => {
8414 if arg_values.len() != 1 {
8415 return Err(RuntimeError::new("extend expects 1 argument"));
8416 }
8417 match &arg_values[0] {
8418 Value::Array(other) => {
8419 arr.borrow_mut().extend(other.borrow().iter().cloned());
8420 Ok(Value::Null)
8421 }
8422 _ => Err(RuntimeError::new("extend expects array argument")),
8423 }
8424 }
8425 (Value::Array(arr), "reverse") => {
8426 arr.borrow_mut().reverse();
8427 Ok(Value::Array(arr.clone()))
8428 }
8429 (Value::Array(arr), "↓")
8430 | (Value::Array(arr), "skip")
8431 | (Value::Array(arr), "drop") => {
8432 let n = match arg_values.first() {
8435 Some(Value::Int(i)) => *i as usize,
8436 _ => 1,
8437 };
8438 let v: Vec<Value> = arr.borrow().iter().skip(n).cloned().collect();
8439 Ok(Value::Array(Rc::new(RefCell::new(v))))
8440 }
8441 (Value::Array(arr), "take") => {
8442 let n = match arg_values.first() {
8444 Some(Value::Int(i)) => *i as usize,
8445 _ => 1,
8446 };
8447 let v: Vec<Value> = arr.borrow().iter().take(n).cloned().collect();
8448 Ok(Value::Array(Rc::new(RefCell::new(v))))
8449 }
8450 (Value::Array(arr), "step_by") => {
8451 let n = match arg_values.first() {
8452 Some(Value::Int(i)) if *i > 0 => *i as usize,
8453 _ => 1,
8454 };
8455 let v: Vec<Value> = arr.borrow().iter().step_by(n).cloned().collect();
8456 Ok(Value::Array(Rc::new(RefCell::new(v))))
8457 }
8458 (Value::Array(arr), "contains") => {
8459 if arg_values.len() != 1 {
8460 return Err(RuntimeError::new("contains expects 1 argument"));
8461 }
8462 let target = &arg_values[0];
8463 let found = arr.borrow().iter().any(|v| self.values_equal(v, target));
8464 Ok(Value::Bool(found))
8465 }
8466 (Value::Array(arr), "position") => {
8467 if arg_values.len() != 1 {
8470 return Err(RuntimeError::new("position expects 1 argument (closure)"));
8471 }
8472 match &arg_values[0] {
8473 Value::Function(f) => {
8474 for (i, val) in arr.borrow().iter().enumerate() {
8475 let result = self.call_function(f, vec![val.clone()])?;
8476 if matches!(result, Value::Bool(true)) {
8477 return Ok(Value::Variant {
8478 enum_name: "Option".to_string(),
8479 variant_name: "Some".to_string(),
8480 fields: Some(Rc::new(vec![Value::Int(i as i64)])),
8481 });
8482 }
8483 }
8484 Ok(Value::Variant {
8485 enum_name: "Option".to_string(),
8486 variant_name: "None".to_string(),
8487 fields: None,
8488 })
8489 }
8490 _ => Err(RuntimeError::new("position expects closure argument")),
8491 }
8492 }
8493 (Value::Array(arr), "remove") => {
8494 if arg_values.len() != 1 {
8497 return Err(RuntimeError::new("remove expects 1 argument (index)"));
8498 }
8499 let index = match &arg_values[0] {
8500 Value::Int(i) => *i as usize,
8501 _ => return Err(RuntimeError::new("remove() index must be integer")),
8502 };
8503 let mut borrowed = arr.borrow_mut();
8504 if index >= borrowed.len() {
8505 return Err(RuntimeError::new(format!(
8506 "remove index {} out of bounds for array of length {}",
8507 index,
8508 borrowed.len()
8509 )));
8510 }
8511 Ok(borrowed.remove(index))
8512 }
8513 (Value::Array(arr), "insert") => {
8514 if arg_values.len() != 2 {
8517 return Err(RuntimeError::new("insert expects 2 arguments (index, value)"));
8518 }
8519 let index = match &arg_values[0] {
8520 Value::Int(i) => *i as usize,
8521 _ => return Err(RuntimeError::new("insert() index must be integer")),
8522 };
8523 let mut borrowed = arr.borrow_mut();
8524 if index > borrowed.len() {
8525 return Err(RuntimeError::new(format!(
8526 "insert index {} out of bounds for array of length {}",
8527 index,
8528 borrowed.len()
8529 )));
8530 }
8531 borrowed.insert(index, arg_values[1].clone());
8532 Ok(Value::Null)
8533 }
8534 (Value::Array(arr), "index_of") => {
8535 if arg_values.len() != 1 {
8538 return Err(RuntimeError::new("index_of expects 1 argument"));
8539 }
8540 let target = &arg_values[0];
8541 let idx = arr.borrow().iter().position(|v| self.values_equal(v, target));
8542 match idx {
8543 Some(i) => Ok(Value::Int(i as i64)),
8544 None => Ok(Value::Int(-1)),
8545 }
8546 }
8547 (Value::Array(arr), "swap") => {
8548 if arg_values.len() != 2 {
8550 return Err(RuntimeError::new("swap expects 2 arguments"));
8551 }
8552 let i = match &arg_values[0] {
8553 Value::Int(i) => *i as usize,
8554 _ => return Err(RuntimeError::new("swap indices must be integers")),
8555 };
8556 let j = match &arg_values[1] {
8557 Value::Int(j) => *j as usize,
8558 _ => return Err(RuntimeError::new("swap indices must be integers")),
8559 };
8560 let mut borrowed = arr.borrow_mut();
8561 if i >= borrowed.len() || j >= borrowed.len() {
8562 return Err(RuntimeError::new("swap index out of bounds"));
8563 }
8564 borrowed.swap(i, j);
8565 Ok(Value::Null)
8566 }
8567 (Value::Array(arr), "truncate") => {
8568 if arg_values.len() != 1 {
8570 return Err(RuntimeError::new("truncate expects 1 argument"));
8571 }
8572 let len = match &arg_values[0] {
8573 Value::Int(i) => *i as usize,
8574 _ => return Err(RuntimeError::new("truncate length must be integer")),
8575 };
8576 arr.borrow_mut().truncate(len);
8577 Ok(Value::Null)
8578 }
8579 (Value::Array(arr), "retain") => {
8580 if arg_values.len() != 1 {
8583 return Err(RuntimeError::new("retain expects 1 argument (closure)"));
8584 }
8585 match &arg_values[0] {
8586 Value::Function(f) => {
8587 let kept: Vec<Value> = arr.borrow().iter().filter(|val| {
8588 matches!(self.call_function(f, vec![(*val).clone()]), Ok(Value::Bool(true)))
8589 }).cloned().collect();
8590 *arr.borrow_mut() = kept;
8591 Ok(Value::Null)
8592 }
8593 _ => Err(RuntimeError::new("retain expects closure argument")),
8594 }
8595 }
8596 (Value::Array(arr), "dedup") => {
8597 let mut borrowed = arr.borrow_mut();
8599 borrowed.dedup_by(|a, b| {
8600 format!("{}", a) == format!("{}", b)
8602 });
8603 Ok(Value::Null)
8604 }
8605 (Value::Tuple(t), "to_string") | (Value::Tuple(t), "string") => {
8607 let s: Vec<String> = t.iter().map(|v| format!("{}", v)).collect();
8608 Ok(Value::String(Rc::new(format!("({})", s.join(", ")))))
8609 }
8610 (Value::Tuple(t), "len") => Ok(Value::Int(t.len() as i64)),
8611 (Value::Tuple(t), "first") => t
8612 .first()
8613 .cloned()
8614 .ok_or_else(|| RuntimeError::new("empty tuple")),
8615 (Value::Tuple(t), "last") => t
8616 .last()
8617 .cloned()
8618 .ok_or_else(|| RuntimeError::new("empty tuple")),
8619 (Value::Tuple(t), "get") => {
8620 let idx = match arg_values.first() {
8621 Some(Value::Int(i)) => *i as usize,
8622 _ => return Err(RuntimeError::new("get expects integer index")),
8623 };
8624 t.get(idx)
8625 .cloned()
8626 .ok_or_else(|| RuntimeError::new("tuple index out of bounds"))
8627 }
8628 (Value::Array(arr), "first") | (Value::Array(arr), "next") => {
8629 Ok(arr.borrow().first().cloned().unwrap_or(Value::Null))
8630 }
8631 (Value::Array(arr), "last") => arr
8632 .borrow()
8633 .last()
8634 .cloned()
8635 .ok_or_else(|| RuntimeError::new("empty array")),
8636 (Value::Array(arr), "iter") | (Value::Array(arr), "into_iter") => {
8637 Ok(Value::Array(arr.clone()))
8639 }
8640 (Value::Array(arr), "↦") | (Value::Array(arr), "map") => {
8641 if arg_values.len() != 1 {
8644 return Err(RuntimeError::new("map expects 1 argument (closure)"));
8645 }
8646 match &arg_values[0] {
8647 Value::Function(f) => {
8648 let mut results = Vec::new();
8649 for val in arr.borrow().iter() {
8650 let result = self.call_function(f, vec![val.clone()])?;
8651 results.push(result);
8652 }
8653 Ok(Value::Array(Rc::new(RefCell::new(results))))
8654 }
8655 _ => Err(RuntimeError::new("map expects closure argument")),
8656 }
8657 }
8658 (Value::Array(arr), "⊛")
8659 | (Value::Array(arr), "filter")
8660 | (Value::Array(arr), "select")
8661 | (Value::Array(arr), "where") => {
8662 if arg_values.len() != 1 {
8665 return Err(RuntimeError::new("filter expects 1 argument (closure)"));
8666 }
8667 match &arg_values[0] {
8668 Value::Function(f) => {
8669 let mut results = Vec::new();
8670 for val in arr.borrow().iter() {
8671 let keep = self.call_function(f, vec![val.clone()])?;
8672 if matches!(keep, Value::Bool(true)) {
8673 results.push(val.clone());
8674 }
8675 }
8676 Ok(Value::Array(Rc::new(RefCell::new(results))))
8677 }
8678 _ => Err(RuntimeError::new("filter expects closure argument")),
8679 }
8680 }
8681 (Value::Array(arr), "∃")
8682 | (Value::Array(arr), "any")
8683 | (Value::Array(arr), "some")
8684 | (Value::Array(arr), "exists") => {
8685 if arg_values.len() != 1 {
8688 return Err(RuntimeError::new("any expects 1 argument (closure)"));
8689 }
8690 match &arg_values[0] {
8691 Value::Function(f) => {
8692 for val in arr.borrow().iter() {
8693 let result = self.call_function(f, vec![val.clone()])?;
8694 if matches!(result, Value::Bool(true)) {
8695 return Ok(Value::Bool(true));
8696 }
8697 }
8698 Ok(Value::Bool(false))
8699 }
8700 _ => Err(RuntimeError::new("any expects closure argument")),
8701 }
8702 }
8703 (Value::Array(arr), "∀∶")
8704 | (Value::Array(arr), "all")
8705 | (Value::Array(arr), "every")
8706 | (Value::Array(arr), "forall") => {
8707 if arg_values.len() != 1 {
8710 return Err(RuntimeError::new("all expects 1 argument (closure)"));
8711 }
8712 match &arg_values[0] {
8713 Value::Function(f) => {
8714 for val in arr.borrow().iter() {
8715 let result = self.call_function(f, vec![val.clone()])?;
8716 if !matches!(result, Value::Bool(true)) {
8717 return Ok(Value::Bool(false));
8718 }
8719 }
8720 Ok(Value::Bool(true))
8721 }
8722 _ => Err(RuntimeError::new("all expects closure argument")),
8723 }
8724 }
8725 (Value::Array(arr), "∃?") | (Value::Array(arr), "find") => {
8726 if arg_values.len() != 1 {
8729 return Err(RuntimeError::new("find expects 1 argument (closure)"));
8730 }
8731 match &arg_values[0] {
8732 Value::Function(f) => {
8733 for val in arr.borrow().iter() {
8734 let result = self.call_function(f, vec![val.clone()])?;
8735 if matches!(result, Value::Bool(true)) {
8736 return Ok(Value::Variant {
8737 enum_name: "Option".to_string(),
8738 variant_name: "Some".to_string(),
8739 fields: Some(Rc::new(vec![val.clone()])),
8740 });
8741 }
8742 }
8743 Ok(Value::Variant {
8744 enum_name: "Option".to_string(),
8745 variant_name: "None".to_string(),
8746 fields: None,
8747 })
8748 }
8749 _ => Err(RuntimeError::new("find expects closure argument")),
8750 }
8751 }
8752 (Value::Array(arr), "ι")
8753 | (Value::Array(arr), "enumerate")
8754 | (Value::Array(arr), "indexed") => {
8755 let enumerated: Vec<Value> = arr
8758 .borrow()
8759 .iter()
8760 .enumerate()
8761 .map(|(i, v)| Value::Tuple(Rc::new(vec![Value::Int(i as i64), v.clone()])))
8762 .collect();
8763 Ok(Value::Array(Rc::new(RefCell::new(enumerated))))
8764 }
8765 (Value::Array(arr), "⊗") | (Value::Array(arr), "zip") => {
8766 if arg_values.len() != 1 {
8769 return Err(RuntimeError::new("zip expects 1 argument"));
8770 }
8771 match &arg_values[0] {
8772 Value::Array(other) => {
8773 let a = arr.borrow();
8774 let b = other.borrow();
8775 let zipped: Vec<Value> = a
8776 .iter()
8777 .zip(b.iter())
8778 .map(|(x, y)| Value::Tuple(Rc::new(vec![x.clone(), y.clone()])))
8779 .collect();
8780 Ok(Value::Array(Rc::new(RefCell::new(zipped))))
8781 }
8782 _ => Err(RuntimeError::new("zip expects array argument")),
8783 }
8784 }
8785 (Value::Array(arr), "⊕")
8797 | (Value::Array(arr), "fold")
8798 | (Value::Array(arr), "reduce") => {
8799 if arg_values.len() != 2 {
8802 return Err(RuntimeError::new(
8803 "fold expects 2 arguments (initial, accumulator)",
8804 ));
8805 }
8806 let mut acc = arg_values[0].clone();
8807 match &arg_values[1] {
8808 Value::Function(f) => {
8809 for val in arr.borrow().iter() {
8810 acc = self.call_function(f, vec![acc, val.clone()])?;
8811 }
8812 Ok(acc)
8813 }
8814 _ => Err(RuntimeError::new(
8815 "fold expects function as second argument",
8816 )),
8817 }
8818 }
8819 (Value::Array(arr), "⤳")
8820 | (Value::Array(arr), "flat_map")
8821 | (Value::Array(arr), "flatMap") => {
8822 if arg_values.len() != 1 {
8825 return Err(RuntimeError::new("flat_map expects 1 argument (function)"));
8826 }
8827 match &arg_values[0] {
8828 Value::Function(f) => {
8829 let mut results = Vec::new();
8830 for val in arr.borrow().iter() {
8831 let mapped = self.call_function(f, vec![val.clone()])?;
8832 match mapped {
8834 Value::Array(inner) => {
8835 results.extend(inner.borrow().iter().cloned());
8836 }
8837 other => results.push(other),
8838 }
8839 }
8840 Ok(Value::Array(Rc::new(RefCell::new(results))))
8841 }
8842 _ => Err(RuntimeError::new("flat_map expects function argument")),
8843 }
8844 }
8845 (Value::Array(arr), "⊏") | (Value::Array(arr), "flatten") => {
8846 let mut results = Vec::new();
8849 for val in arr.borrow().iter() {
8850 match val {
8851 Value::Array(inner) => {
8852 results.extend(inner.borrow().iter().cloned());
8853 }
8854 other => results.push(other.clone()),
8855 }
8856 }
8857 Ok(Value::Array(Rc::new(RefCell::new(results))))
8858 }
8859 (Value::Array(arr), "∀")
8860 | (Value::Array(arr), "for_each")
8861 | (Value::Array(arr), "forEach") => {
8862 if arg_values.len() != 1 {
8865 return Err(RuntimeError::new("for_each expects 1 argument (function)"));
8866 }
8867 match &arg_values[0] {
8868 Value::Function(f) => {
8869 for val in arr.borrow().iter() {
8870 self.call_function(f, vec![val.clone()])?;
8871 }
8872 Ok(Value::Null)
8873 }
8874 _ => Err(RuntimeError::new("for_each expects function argument")),
8875 }
8876 }
8877 (Value::Array(arr), "⊙") | (Value::Array(arr), "peek") => {
8878 if arg_values.len() != 1 {
8881 return Err(RuntimeError::new("peek expects 1 argument (function)"));
8882 }
8883 match &arg_values[0] {
8884 Value::Function(f) => {
8885 for val in arr.borrow().iter() {
8886 self.call_function(f, vec![val.clone()])?;
8887 }
8888 Ok(Value::Array(arr.clone()))
8889 }
8890 _ => Err(RuntimeError::new("peek expects function argument")),
8891 }
8892 }
8893 (Value::Array(arr), "⊴")
8894 | (Value::Array(arr), "sorted")
8895 | (Value::Array(arr), "sort") => {
8896 let mut v = arr.borrow().clone();
8899 if arg_values.is_empty() {
8900 v.sort_by(|a, b| self.compare_values(a, b, &None));
8902 } else if let Some(Value::Function(f)) = arg_values.first() {
8903 v.sort_by(
8905 |a, b| match self.call_function(f, vec![a.clone(), b.clone()]) {
8906 Ok(Value::Int(n)) => {
8907 if n < 0 {
8908 std::cmp::Ordering::Less
8909 } else if n > 0 {
8910 std::cmp::Ordering::Greater
8911 } else {
8912 std::cmp::Ordering::Equal
8913 }
8914 }
8915 _ => std::cmp::Ordering::Equal,
8916 },
8917 );
8918 }
8919 Ok(Value::Array(Rc::new(RefCell::new(v))))
8920 }
8921 (Value::Array(arr), "◉") | (Value::Array(arr), "distinct") => {
8922 let mut seen = Vec::new();
8925 let mut results = Vec::new();
8926 for val in arr.borrow().iter() {
8927 let is_dup = seen.iter().any(|v| self.values_equal(v, val));
8928 if !is_dup {
8929 seen.push(val.clone());
8930 results.push(val.clone());
8931 }
8932 }
8933 Ok(Value::Array(Rc::new(RefCell::new(results))))
8934 }
8935 (Value::Array(arr), "↑")
8936 | (Value::Array(arr), "limit")
8937 | (Value::Array(arr), "take") => {
8938 let n = match arg_values.first() {
8941 Some(Value::Int(i)) => *i as usize,
8942 _ => return Err(RuntimeError::new("limit expects integer argument")),
8943 };
8944 let v: Vec<Value> = arr.borrow().iter().take(n).cloned().collect();
8945 Ok(Value::Array(Rc::new(RefCell::new(v))))
8946 }
8947 (Value::Array(arr), "↑⦂")
8948 | (Value::Array(arr), "take_while")
8949 | (Value::Array(arr), "takeWhile") => {
8950 if arg_values.len() != 1 {
8953 return Err(RuntimeError::new(
8954 "take_while expects 1 argument (predicate)",
8955 ));
8956 }
8957 match &arg_values[0] {
8958 Value::Function(f) => {
8959 let mut results = Vec::new();
8960 for val in arr.borrow().iter() {
8961 let keep = self.call_function(f, vec![val.clone()])?;
8962 if matches!(keep, Value::Bool(true)) {
8963 results.push(val.clone());
8964 } else {
8965 break;
8966 }
8967 }
8968 Ok(Value::Array(Rc::new(RefCell::new(results))))
8969 }
8970 _ => Err(RuntimeError::new("take_while expects function argument")),
8971 }
8972 }
8973 (Value::Array(arr), "↓⦂")
8974 | (Value::Array(arr), "drop_while")
8975 | (Value::Array(arr), "dropWhile")
8976 | (Value::Array(arr), "skip_while")
8977 | (Value::Array(arr), "skipWhile") => {
8978 if arg_values.len() != 1 {
8981 return Err(RuntimeError::new(
8982 "drop_while expects 1 argument (predicate)",
8983 ));
8984 }
8985 match &arg_values[0] {
8986 Value::Function(f) => {
8987 let mut results = Vec::new();
8988 let mut dropping = true;
8989 for val in arr.borrow().iter() {
8990 if dropping {
8991 let skip = self.call_function(f, vec![val.clone()])?;
8992 if !matches!(skip, Value::Bool(true)) {
8993 dropping = false;
8994 results.push(val.clone());
8995 }
8996 } else {
8997 results.push(val.clone());
8998 }
8999 }
9000 Ok(Value::Array(Rc::new(RefCell::new(results))))
9001 }
9002 _ => Err(RuntimeError::new("drop_while expects function argument")),
9003 }
9004 }
9005 (Value::Array(arr), "∑") | (Value::Array(arr), "sum") => {
9006 let mut total = 0i64;
9009 let mut has_float = false;
9010 let mut float_total = 0.0f64;
9011 for val in arr.borrow().iter() {
9012 match val {
9013 Value::Int(n) => {
9014 if has_float {
9015 float_total += *n as f64;
9016 } else {
9017 total += n;
9018 }
9019 }
9020 Value::Float(n) => {
9021 if !has_float {
9022 float_total = total as f64;
9023 has_float = true;
9024 }
9025 float_total += n;
9026 }
9027 _ => {}
9028 }
9029 }
9030 if has_float {
9031 Ok(Value::Float(float_total))
9032 } else {
9033 Ok(Value::Int(total))
9034 }
9035 }
9036 (Value::Array(arr), "∏") | (Value::Array(arr), "product") => {
9037 let mut total = 1i64;
9040 let mut has_float = false;
9041 let mut float_total = 1.0f64;
9042 for val in arr.borrow().iter() {
9043 match val {
9044 Value::Int(n) => {
9045 if has_float {
9046 float_total *= *n as f64;
9047 } else {
9048 total *= n;
9049 }
9050 }
9051 Value::Float(n) => {
9052 if !has_float {
9053 float_total = total as f64;
9054 has_float = true;
9055 }
9056 float_total *= n;
9057 }
9058 _ => {}
9059 }
9060 }
9061 if has_float {
9062 Ok(Value::Float(float_total))
9063 } else {
9064 Ok(Value::Int(total))
9065 }
9066 }
9067 (Value::Array(arr), "#")
9068 | (Value::Array(arr), "count")
9069 | (Value::Array(arr), "len") => {
9070 Ok(Value::Int(arr.borrow().len() as i64))
9073 }
9074 (Value::Array(arr), "⊥")
9075 | (Value::Array(arr), "min")
9076 | (Value::Array(arr), "infimum") => {
9077 let borrowed = arr.borrow();
9080 if borrowed.is_empty() {
9081 return Ok(Value::Variant {
9082 enum_name: "Option".to_string(),
9083 variant_name: "None".to_string(),
9084 fields: None,
9085 });
9086 }
9087 let mut min_val = borrowed[0].clone();
9088 for val in borrowed.iter().skip(1) {
9089 if self.compare_values(val, &min_val, &None) == std::cmp::Ordering::Less {
9090 min_val = val.clone();
9091 }
9092 }
9093 Ok(Value::Variant {
9094 enum_name: "Option".to_string(),
9095 variant_name: "Some".to_string(),
9096 fields: Some(Rc::new(vec![min_val])),
9097 })
9098 }
9099 (Value::Array(arr), "⊤")
9100 | (Value::Array(arr), "max")
9101 | (Value::Array(arr), "supremum") => {
9102 let borrowed = arr.borrow();
9105 if borrowed.is_empty() {
9106 return Ok(Value::Variant {
9107 enum_name: "Option".to_string(),
9108 variant_name: "None".to_string(),
9109 fields: None,
9110 });
9111 }
9112 let mut max_val = borrowed[0].clone();
9113 for val in borrowed.iter().skip(1) {
9114 if self.compare_values(val, &max_val, &None) == std::cmp::Ordering::Greater {
9115 max_val = val.clone();
9116 }
9117 }
9118 Ok(Value::Variant {
9119 enum_name: "Option".to_string(),
9120 variant_name: "Some".to_string(),
9121 fields: Some(Rc::new(vec![max_val])),
9122 })
9123 }
9124 (Value::Array(arr), "μ")
9125 | (Value::Array(arr), "average")
9126 | (Value::Array(arr), "avg")
9127 | (Value::Array(arr), "mean") => {
9128 let borrowed = arr.borrow();
9131 if borrowed.is_empty() {
9132 return Ok(Value::Variant {
9133 enum_name: "Option".to_string(),
9134 variant_name: "None".to_string(),
9135 fields: None,
9136 });
9137 }
9138 let mut sum = 0.0f64;
9139 let mut count = 0usize;
9140 for val in borrowed.iter() {
9141 match val {
9142 Value::Int(n) => {
9143 sum += *n as f64;
9144 count += 1;
9145 }
9146 Value::Float(n) => {
9147 sum += n;
9148 count += 1;
9149 }
9150 _ => {}
9151 }
9152 }
9153 if count == 0 {
9154 return Ok(Value::Variant {
9155 enum_name: "Option".to_string(),
9156 variant_name: "None".to_string(),
9157 fields: None,
9158 });
9159 }
9160 Ok(Value::Variant {
9161 enum_name: "Option".to_string(),
9162 variant_name: "Some".to_string(),
9163 fields: Some(Rc::new(vec![Value::Float(sum / count as f64)])),
9164 })
9165 }
9166 (Value::Array(arr), "⫴")
9167 | (Value::Array(arr), "group_by")
9168 | (Value::Array(arr), "groupBy")
9169 | (Value::Array(arr), "grouping_by")
9170 | (Value::Array(arr), "groupingBy") => {
9171 if arg_values.len() != 1 {
9174 return Err(RuntimeError::new(
9175 "group_by expects 1 argument (key function)",
9176 ));
9177 }
9178 match &arg_values[0] {
9179 Value::Function(f) => {
9180 let mut groups: HashMap<String, Vec<Value>> = HashMap::new();
9181 for val in arr.borrow().iter() {
9182 let key = self.call_function(f, vec![val.clone()])?;
9183 let key_str = format!("{}", key);
9184 groups.entry(key_str).or_default().push(val.clone());
9185 }
9186 let mut result_map: HashMap<String, Value> = HashMap::new();
9187 for (k, v) in groups {
9188 result_map.insert(k, Value::Array(Rc::new(RefCell::new(v))));
9189 }
9190 Ok(Value::Map(Rc::new(RefCell::new(result_map))))
9191 }
9192 _ => Err(RuntimeError::new("group_by expects function argument")),
9193 }
9194 }
9195 (Value::Array(arr), "⊘")
9196 | (Value::Array(arr), "partition_by")
9197 | (Value::Array(arr), "partitionBy")
9198 | (Value::Array(arr), "partition") => {
9199 if arg_values.len() != 1 {
9202 return Err(RuntimeError::new(
9203 "partition expects 1 argument (predicate)",
9204 ));
9205 }
9206 match &arg_values[0] {
9207 Value::Function(f) => {
9208 let mut true_list = Vec::new();
9209 let mut false_list = Vec::new();
9210 for val in arr.borrow().iter() {
9211 let result = self.call_function(f, vec![val.clone()])?;
9212 if matches!(result, Value::Bool(true)) {
9213 true_list.push(val.clone());
9214 } else {
9215 false_list.push(val.clone());
9216 }
9217 }
9218 Ok(Value::Tuple(Rc::new(vec![
9219 Value::Array(Rc::new(RefCell::new(true_list))),
9220 Value::Array(Rc::new(RefCell::new(false_list))),
9221 ])))
9222 }
9223 _ => Err(RuntimeError::new("partition expects function argument")),
9224 }
9225 }
9226 (Value::Array(arr), "⋈")
9227 | (Value::Array(arr), "joining")
9228 | (Value::Array(arr), "join") => {
9229 let sep = match arg_values.first() {
9232 Some(Value::String(s)) => s.to_string(),
9233 Some(Value::Char(c)) => c.to_string(),
9234 _ => "".to_string(),
9235 };
9236 let parts: Vec<String> = arr.borrow().iter().map(|v| format!("{}", v)).collect();
9237 Ok(Value::String(Rc::new(parts.join(&sep))))
9238 }
9239 (Value::Array(arr), "∃!")
9240 | (Value::Array(arr), "find_first")
9241 | (Value::Array(arr), "findFirst")
9242 | (Value::Array(arr), "first") => {
9243 match arr.borrow().first() {
9246 Some(v) => Ok(Value::Variant {
9247 enum_name: "Option".to_string(),
9248 variant_name: "Some".to_string(),
9249 fields: Some(Rc::new(vec![v.clone()])),
9250 }),
9251 None => Ok(Value::Variant {
9252 enum_name: "Option".to_string(),
9253 variant_name: "None".to_string(),
9254 fields: None,
9255 }),
9256 }
9257 }
9258 (Value::Array(arr), "∃⁻¹")
9259 | (Value::Array(arr), "find_last")
9260 | (Value::Array(arr), "findLast")
9261 | (Value::Array(arr), "last") => {
9262 match arr.borrow().last() {
9265 Some(v) => Ok(Value::Variant {
9266 enum_name: "Option".to_string(),
9267 variant_name: "Some".to_string(),
9268 fields: Some(Rc::new(vec![v.clone()])),
9269 }),
9270 None => Ok(Value::Variant {
9271 enum_name: "Option".to_string(),
9272 variant_name: "None".to_string(),
9273 fields: None,
9274 }),
9275 }
9276 }
9277 (Value::Array(arr), "∄")
9278 | (Value::Array(arr), "none_match")
9279 | (Value::Array(arr), "noneMatch")
9280 | (Value::Array(arr), "none") => {
9281 if arg_values.is_empty() {
9284 for val in arr.borrow().iter() {
9286 let is_truthy = match val {
9287 Value::Bool(true) => true,
9288 Value::Int(n) if *n != 0 => true,
9289 _ => false,
9290 };
9291 if is_truthy {
9292 return Ok(Value::Bool(false));
9293 }
9294 }
9295 return Ok(Value::Bool(true));
9296 }
9297 match &arg_values[0] {
9298 Value::Function(f) => {
9299 for val in arr.borrow().iter() {
9300 let result = self.call_function(f, vec![val.clone()])?;
9301 if matches!(result, Value::Bool(true)) {
9302 return Ok(Value::Bool(false));
9303 }
9304 }
9305 Ok(Value::Bool(true))
9306 }
9307 _ => Err(RuntimeError::new("none_match expects function argument")),
9308 }
9309 }
9310 (Value::Array(arr), "→[]")
9311 | (Value::Array(arr), "collect")
9312 | (Value::Array(arr), "to_vec")
9313 | (Value::Array(arr), "toList") => {
9314 Ok(Value::Array(Rc::new(RefCell::new(arr.borrow().clone()))))
9317 }
9318 (Value::Array(arr), "→{}")
9319 | (Value::Array(arr), "to_set")
9320 | (Value::Array(arr), "toSet") => {
9321 let mut set = HashSet::new();
9324 for val in arr.borrow().iter() {
9325 set.insert(format!("{}", val));
9326 }
9327 Ok(Value::Set(Rc::new(RefCell::new(set))))
9328 }
9329 (Value::Array(arr), "→⟨⟩")
9330 | (Value::Array(arr), "to_map")
9331 | (Value::Array(arr), "toMap") => {
9332 if arg_values.len() < 2 {
9335 return Err(RuntimeError::new(
9336 "to_map expects 2 arguments (key_fn, value_fn)",
9337 ));
9338 }
9339 match (&arg_values[0], &arg_values[1]) {
9340 (Value::Function(key_fn), Value::Function(val_fn)) => {
9341 let mut result_map: HashMap<String, Value> = HashMap::new();
9342 for val in arr.borrow().iter() {
9343 let key = self.call_function(key_fn, vec![val.clone()])?;
9344 let value = self.call_function(val_fn, vec![val.clone()])?;
9345 result_map.insert(format!("{}", key), value);
9346 }
9347 Ok(Value::Map(Rc::new(RefCell::new(result_map))))
9348 }
9349 _ => Err(RuntimeError::new("to_map expects function arguments")),
9350 }
9351 }
9352 (Value::Array(arr), "⊞")
9353 | (Value::Array(arr), "chunk")
9354 | (Value::Array(arr), "chunked") => {
9355 let size = match arg_values.first() {
9358 Some(Value::Int(n)) if *n > 0 => *n as usize,
9359 _ => return Err(RuntimeError::new("chunk expects positive integer")),
9360 };
9361 let chunks: Vec<Value> = arr
9362 .borrow()
9363 .chunks(size)
9364 .map(|chunk| Value::Array(Rc::new(RefCell::new(chunk.to_vec()))))
9365 .collect();
9366 Ok(Value::Array(Rc::new(RefCell::new(chunks))))
9367 }
9368 (Value::Array(arr), "⌸")
9369 | (Value::Array(arr), "windowed")
9370 | (Value::Array(arr), "windows")
9371 | (Value::Array(arr), "sliding") => {
9372 let size = match arg_values.first() {
9375 Some(Value::Int(n)) if *n > 0 => *n as usize,
9376 _ => return Err(RuntimeError::new("windowed expects positive integer")),
9377 };
9378 let borrowed = arr.borrow();
9379 if borrowed.len() < size {
9380 return Ok(Value::Array(Rc::new(RefCell::new(vec![]))));
9381 }
9382 let windows: Vec<Value> = borrowed
9383 .windows(size)
9384 .map(|w| Value::Array(Rc::new(RefCell::new(w.to_vec()))))
9385 .collect();
9386 Ok(Value::Array(Rc::new(RefCell::new(windows))))
9387 }
9388 (Value::Array(arr), "⫰") | (Value::Array(arr), "interleave") => {
9389 if arg_values.len() != 1 {
9392 return Err(RuntimeError::new("interleave expects 1 argument"));
9393 }
9394 match &arg_values[0] {
9395 Value::Array(other) => {
9396 let a = arr.borrow();
9397 let b = other.borrow();
9398 let mut result = Vec::new();
9399 let max_len = a.len().max(b.len());
9400 for i in 0..max_len {
9401 if i < a.len() {
9402 result.push(a[i].clone());
9403 }
9404 if i < b.len() {
9405 result.push(b[i].clone());
9406 }
9407 }
9408 Ok(Value::Array(Rc::new(RefCell::new(result))))
9409 }
9410 _ => Err(RuntimeError::new("interleave expects array argument")),
9411 }
9412 }
9413 (Value::Array(arr), "⟲")
9414 | (Value::Array(arr), "reversed")
9415 | (Value::Array(arr), "reverse") => {
9416 arr.borrow_mut().reverse();
9419 Ok(Value::Array(arr.clone()))
9420 }
9421 (Value::Array(arr), "⧢")
9422 | (Value::Array(arr), "shuffled")
9423 | (Value::Array(arr), "shuffle") => {
9424 use std::collections::hash_map::DefaultHasher;
9427 use std::hash::{Hash, Hasher};
9428 use std::time::{SystemTime, UNIX_EPOCH};
9429
9430 let mut v = arr.borrow().clone();
9431 let seed = SystemTime::now()
9433 .duration_since(UNIX_EPOCH)
9434 .map(|d| d.as_nanos())
9435 .unwrap_or(0);
9436 let mut hasher = DefaultHasher::new();
9437 seed.hash(&mut hasher);
9438 let mut rng_state = hasher.finish();
9439
9440 for i in (1..v.len()).rev() {
9441 rng_state = rng_state.wrapping_mul(6364136223846793005).wrapping_add(1);
9442 let j = (rng_state as usize) % (i + 1);
9443 v.swap(i, j);
9444 }
9445 Ok(Value::Array(Rc::new(RefCell::new(v))))
9446 }
9447 (Value::Array(arr), "∅?")
9448 | (Value::Array(arr), "is_empty")
9449 | (Value::Array(arr), "isEmpty") => {
9450 Ok(Value::Bool(arr.borrow().is_empty()))
9453 }
9454 (Value::Array(arr), "@") | (Value::Array(arr), "get") | (Value::Array(arr), "at") => {
9455 let idx = match arg_values.first() {
9458 Some(Value::Int(i)) => *i,
9459 _ => return Err(RuntimeError::new("get expects integer index")),
9460 };
9461 let borrowed = arr.borrow();
9462 let actual_idx = if idx < 0 {
9463 (borrowed.len() as i64 + idx) as usize
9464 } else {
9465 idx as usize
9466 };
9467 match borrowed.get(actual_idx) {
9468 Some(v) => Ok(Value::Variant {
9469 enum_name: "Option".to_string(),
9470 variant_name: "Some".to_string(),
9471 fields: Some(Rc::new(vec![v.clone()])),
9472 }),
9473 None => Ok(Value::Variant {
9474 enum_name: "Option".to_string(),
9475 variant_name: "None".to_string(),
9476 fields: None,
9477 }),
9478 }
9479 }
9480 (Value::String(s), "len") => Ok(Value::Int(s.len() as i64)),
9482 (Value::String(s), "chars") => {
9483 let chars: Vec<Value> = s.chars().map(Value::Char).collect();
9484 Ok(Value::Array(Rc::new(RefCell::new(chars))))
9485 }
9486 (Value::String(s), "as_bytes") => {
9487 let bytes: Vec<Value> = s.as_bytes().iter().map(|b| Value::Int(*b as i64)).collect();
9488 Ok(Value::Array(Rc::new(RefCell::new(bytes))))
9489 }
9490 (Value::String(s), "bytes") => {
9491 let bytes: Vec<Value> = s.as_bytes().iter().map(|b| Value::Int(*b as i64)).collect();
9492 Ok(Value::Array(Rc::new(RefCell::new(bytes))))
9493 }
9494 (Value::String(s), "contains") => {
9495 if arg_values.len() != 1 {
9496 return Err(RuntimeError::new("contains expects 1 argument"));
9497 }
9498 match &arg_values[0] {
9499 Value::String(sub) => Ok(Value::Bool(s.contains(sub.as_str()))),
9500 Value::Char(c) => Ok(Value::Bool(s.contains(*c))),
9501 Value::Ref(inner) => {
9502 if let Value::String(sub) = &*inner.borrow() {
9503 Ok(Value::Bool(s.contains(sub.as_str())))
9504 } else {
9505 Err(RuntimeError::new("contains expects string or char"))
9506 }
9507 }
9508 _ => Err(RuntimeError::new("contains expects string or char")),
9509 }
9510 }
9511 (Value::String(s), "as_str") => {
9512 if s.len() <= 10 {
9513 crate::sigil_debug!("DEBUG as_str: '{}'", s);
9514 }
9515 Ok(Value::String(s.clone()))
9516 }
9517 (Value::String(s), "to_string") => Ok(Value::String(s.clone())),
9518 (Value::String(s), "into") => Ok(Value::String(s.clone())), (Value::String(s), "starts_with") => {
9520 if arg_values.len() != 1 {
9521 return Err(RuntimeError::new("starts_with expects 1 argument"));
9522 }
9523 match &arg_values[0] {
9524 Value::String(prefix) => Ok(Value::Bool(s.starts_with(prefix.as_str()))),
9525 _ => Err(RuntimeError::new("starts_with expects string")),
9526 }
9527 }
9528 (Value::String(s), "ends_with") => {
9529 if arg_values.len() != 1 {
9530 return Err(RuntimeError::new("ends_with expects 1 argument"));
9531 }
9532 match &arg_values[0] {
9533 Value::String(suffix) => Ok(Value::Bool(s.ends_with(suffix.as_str()))),
9534 _ => Err(RuntimeError::new("ends_with expects string")),
9535 }
9536 }
9537 (Value::String(s), "strip_prefix") => {
9538 if arg_values.len() != 1 {
9539 return Err(RuntimeError::new("strip_prefix expects 1 argument"));
9540 }
9541 match &arg_values[0] {
9542 Value::String(prefix) => match s.strip_prefix(prefix.as_str()) {
9543 Some(stripped) => Ok(Value::String(Rc::new(stripped.to_string()))),
9544 None => Ok(Value::Null),
9545 },
9546 _ => Err(RuntimeError::new("strip_prefix expects string")),
9547 }
9548 }
9549 (Value::String(s), "strip_suffix") => {
9550 if arg_values.len() != 1 {
9551 return Err(RuntimeError::new("strip_suffix expects 1 argument"));
9552 }
9553 match &arg_values[0] {
9554 Value::String(suffix) => match s.strip_suffix(suffix.as_str()) {
9555 Some(stripped) => Ok(Value::String(Rc::new(stripped.to_string()))),
9556 None => Ok(Value::Null),
9557 },
9558 _ => Err(RuntimeError::new("strip_suffix expects string")),
9559 }
9560 }
9561 (Value::String(s), "is_empty") => Ok(Value::Bool(s.is_empty())),
9562 (Value::String(s), "capacity") => Ok(Value::Int(s.capacity() as i64)),
9563 (Value::String(s), "find") => {
9564 if arg_values.len() != 1 {
9565 return Err(RuntimeError::new("find expects 1 argument"));
9566 }
9567 match &arg_values[0] {
9568 Value::Char(c) => match s.find(*c) {
9569 Some(idx) => Ok(Value::Variant {
9570 enum_name: "Option".to_string(),
9571 variant_name: "Some".to_string(),
9572 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
9573 }),
9574 None => Ok(Value::Variant {
9575 enum_name: "Option".to_string(),
9576 variant_name: "None".to_string(),
9577 fields: None,
9578 }),
9579 },
9580 Value::String(pattern) => match s.find(pattern.as_str()) {
9581 Some(idx) => Ok(Value::Variant {
9582 enum_name: "Option".to_string(),
9583 variant_name: "Some".to_string(),
9584 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
9585 }),
9586 None => Ok(Value::Variant {
9587 enum_name: "Option".to_string(),
9588 variant_name: "None".to_string(),
9589 fields: None,
9590 }),
9591 },
9592 Value::Function(f) => {
9593 for (idx, c) in s.chars().enumerate() {
9594 let result = self.call_function(f, vec![Value::Char(c)])?;
9595 if let Value::Bool(true) = result {
9596 return Ok(Value::Variant {
9597 enum_name: "Option".to_string(),
9598 variant_name: "Some".to_string(),
9599 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
9600 });
9601 }
9602 }
9603 Ok(Value::Variant {
9604 enum_name: "Option".to_string(),
9605 variant_name: "None".to_string(),
9606 fields: None,
9607 })
9608 }
9609 _ => Err(RuntimeError::new("find expects a char, string, or closure")),
9610 }
9611 }
9612 (Value::String(s), "clone") => Ok(Value::String(Rc::new((**s).clone()))),
9613 (Value::String(s), "concat") => {
9614 if arg_values.len() != 1 {
9615 return Err(RuntimeError::new("concat expects 1 argument"));
9616 }
9617 match &arg_values[0] {
9618 Value::String(other) => {
9619 let mut result = (**s).clone();
9620 result.push_str(other);
9621 Ok(Value::String(Rc::new(result)))
9622 }
9623 _ => Err(RuntimeError::new("concat expects string argument")),
9624 }
9625 }
9626 (Value::String(s), "as_ptr") => {
9627 Ok(Value::String(s.clone()))
9629 }
9630 (Value::String(_), "is_null") => Ok(Value::Bool(false)),
9631 (Value::Null, "is_null") => Ok(Value::Bool(true)),
9632 (Value::String(s), "char_at") => {
9633 if arg_values.len() != 1 {
9634 return Err(RuntimeError::new("char_at expects 1 argument"));
9635 }
9636 let idx = match &arg_values[0] {
9637 Value::Int(i) => *i as usize,
9638 _ => return Err(RuntimeError::new("char_at expects integer index")),
9639 };
9640 if idx < s.len() {
9643 let remaining = &s[idx..];
9645 match remaining.chars().next() {
9646 Some(c) => Ok(Value::Char(c)),
9647 None => Ok(Value::Null),
9648 }
9649 } else {
9650 Ok(Value::Null) }
9652 }
9653 (Value::String(s), "chars") => {
9654 let chars: Vec<Value> = s.chars().map(Value::Char).collect();
9655 Ok(Value::Array(Rc::new(RefCell::new(chars))))
9656 }
9657 (Value::String(s), "bytes") => {
9658 let bytes: Vec<Value> = s.bytes().map(|b| Value::Int(b as i64)).collect();
9659 Ok(Value::Array(Rc::new(RefCell::new(bytes))))
9660 }
9661 (Value::String(s), "split") => {
9662 if arg_values.len() != 1 {
9663 return Err(RuntimeError::new("split expects 1 argument"));
9664 }
9665 match &arg_values[0] {
9666 Value::String(sep) => {
9667 let parts: Vec<Value> = s
9668 .split(sep.as_str())
9669 .map(|p| Value::String(Rc::new(p.to_string())))
9670 .collect();
9671 Ok(Value::Array(Rc::new(RefCell::new(parts))))
9672 }
9673 Value::Char(sep) => {
9674 let parts: Vec<Value> = s
9675 .split(*sep)
9676 .map(|p| Value::String(Rc::new(p.to_string())))
9677 .collect();
9678 Ok(Value::Array(Rc::new(RefCell::new(parts))))
9679 }
9680 _ => Err(RuntimeError::new("split expects string or char separator")),
9681 }
9682 }
9683 (Value::Char(c), "len_utf8") => Ok(Value::Int(c.len_utf8() as i64)),
9685 (Value::Char(c), "is_alphabetic") => Ok(Value::Bool(c.is_alphabetic())),
9686 (Value::Char(c), "is_alphanumeric") => Ok(Value::Bool(c.is_alphanumeric())),
9687 (Value::Char(c), "is_ascii_alphanumeric") => Ok(Value::Bool(c.is_ascii_alphanumeric())),
9688 (Value::Char(c), "is_ascii_alphabetic") => Ok(Value::Bool(c.is_ascii_alphabetic())),
9689 (Value::Char(c), "is_ascii_digit") => Ok(Value::Bool(c.is_ascii_digit())),
9690 (Value::Char(c), "is_ascii_hexdigit") => Ok(Value::Bool(c.is_ascii_hexdigit())),
9691 (Value::Char(c), "is_ascii") => Ok(Value::Bool(c.is_ascii())),
9692 (Value::Char(c), "is_digit") => {
9693 let radix = if arg_values.is_empty() {
9694 10
9695 } else {
9696 match &arg_values[0] {
9697 Value::Int(n) => *n as u32,
9698 _ => 10,
9699 }
9700 };
9701 Ok(Value::Bool(c.is_digit(radix)))
9702 }
9703 (Value::Char(c), "is_numeric") => Ok(Value::Bool(c.is_numeric())),
9704 (Value::Char(c), "is_whitespace") => Ok(Value::Bool(c.is_whitespace())),
9705 (Value::Char(c), "is_uppercase") => Ok(Value::Bool(c.is_uppercase())),
9706 (Value::Char(c), "is_lowercase") => Ok(Value::Bool(c.is_lowercase())),
9707 (Value::Char(c), "to_uppercase") => {
9708 let upper: String = c.to_uppercase().collect();
9709 Ok(Value::String(Rc::new(upper)))
9710 }
9711 (Value::Char(c), "to_lowercase") => {
9712 let lower: String = c.to_lowercase().collect();
9713 Ok(Value::String(Rc::new(lower)))
9714 }
9715 (Value::Char(c), "to_string") => Ok(Value::String(Rc::new(c.to_string()))),
9716 (Value::Char(c), "to_digit") => {
9717 let radix = if arg_values.is_empty() {
9718 10
9719 } else {
9720 match &arg_values[0] {
9721 Value::Int(n) => *n as u32,
9722 _ => 10,
9723 }
9724 };
9725 match c.to_digit(radix) {
9726 Some(d) => Ok(Value::Int(d as i64)),
9727 None => Ok(Value::Null),
9728 }
9729 }
9730 (Value::Char(c), "to_ascii_uppercase") => Ok(Value::Char(c.to_ascii_uppercase())),
9731 (Value::Char(c), "to_ascii_lowercase") => Ok(Value::Char(c.to_ascii_lowercase())),
9732 (Value::Char(c), "clone") => Ok(Value::Char(*c)),
9733 (Value::String(s), "upper")
9734 | (Value::String(s), "uppercase")
9735 | (Value::String(s), "to_uppercase") => Ok(Value::String(Rc::new(s.to_uppercase()))),
9736 (Value::String(s), "lower")
9737 | (Value::String(s), "lowercase")
9738 | (Value::String(s), "to_lowercase") => Ok(Value::String(Rc::new(s.to_lowercase()))),
9739 (Value::String(s), "trim") => Ok(Value::String(Rc::new(s.trim().to_string()))),
9740 (Value::String(s), "len") => Ok(Value::Int(s.len() as i64)),
9741 (Value::String(s), "is_empty") => Ok(Value::Bool(s.is_empty())),
9742 (Value::String(s), "capacity") => Ok(Value::Int(s.capacity() as i64)),
9743 (Value::String(s), "exists") => {
9745 Ok(Value::Bool(std::path::Path::new(s.as_str()).exists()))
9746 }
9747 (Value::String(s), "is_dir") => {
9748 Ok(Value::Bool(std::path::Path::new(s.as_str()).is_dir()))
9749 }
9750 (Value::String(s), "is_file") => {
9751 Ok(Value::Bool(std::path::Path::new(s.as_str()).is_file()))
9752 }
9753 (Value::String(s), "join") => {
9754 if arg_values.len() != 1 {
9756 return Err(RuntimeError::new(&format!(
9757 "join expects 1 argument, got {}",
9758 arg_values.len()
9759 )));
9760 }
9761 let other = match &arg_values[0] {
9762 Value::String(s2) => s2.as_str().to_string(),
9763 other => {
9764 return Err(RuntimeError::new(&format!(
9765 "join expects String argument, got {:?}",
9766 other
9767 )))
9768 }
9769 };
9770 let path = std::path::Path::new(s.as_str()).join(&other);
9771 Ok(Value::String(Rc::new(path.to_string_lossy().to_string())))
9772 }
9773 (Value::String(s), "parent") => {
9774 let path = std::path::Path::new(s.as_str());
9776 match path.parent() {
9777 Some(p) => Ok(Value::String(Rc::new(p.to_string_lossy().to_string()))),
9778 None => Ok(Value::Null),
9779 }
9780 }
9781 (Value::String(s), "file_name") => {
9782 let path = std::path::Path::new(s.as_str());
9784 match path.file_name() {
9785 Some(n) => Ok(Value::String(Rc::new(n.to_string_lossy().to_string()))),
9786 None => Ok(Value::Null),
9787 }
9788 }
9789 (Value::String(s), "extension") => {
9790 let path = std::path::Path::new(s.as_str());
9792 match path.extension() {
9793 Some(e) => Ok(Value::String(Rc::new(e.to_string_lossy().to_string()))),
9794 None => Ok(Value::Null),
9795 }
9796 }
9797 (Value::String(_), "and_then") | (Value::String(_), "or_else") => {
9799 Ok(recv.clone())
9801 }
9802 (Value::String(s), "first") => s
9803 .chars()
9804 .next()
9805 .map(Value::Char)
9806 .ok_or_else(|| RuntimeError::new("empty string")),
9807 (Value::String(s), "last") => s
9808 .chars()
9809 .last()
9810 .map(Value::Char)
9811 .ok_or_else(|| RuntimeError::new("empty string")),
9812 (Value::Array(arr), "is_empty") => Ok(Value::Bool(arr.borrow().is_empty())),
9813 (Value::Array(arr), "clone") => {
9814 Ok(Value::Array(Rc::new(RefCell::new(arr.borrow().clone()))))
9815 }
9816 (Value::Array(arr), "collect") => {
9817 Ok(Value::Array(arr.clone()))
9820 }
9821 (Value::Array(arr), "join") => {
9822 let separator = if arg_values.is_empty() {
9823 String::new()
9824 } else {
9825 match &arg_values[0] {
9826 Value::String(s) => (**s).clone(),
9827 _ => return Err(RuntimeError::new("join separator must be string")),
9828 }
9829 };
9830 let parts: Vec<String> =
9831 arr.borrow().iter().map(|v| self.format_value(v)).collect();
9832 Ok(Value::String(Rc::new(parts.join(&separator))))
9833 }
9834 (Value::Map(m), "insert") => {
9836 if arg_values.len() != 2 {
9837 return Err(RuntimeError::new("insert expects 2 arguments"));
9838 }
9839 let key = match &arg_values[0] {
9840 Value::String(s) => (**s).clone(),
9841 _ => format!("{}", arg_values[0]),
9842 };
9843 m.borrow_mut().insert(key, arg_values[1].clone());
9844 Ok(Value::Null)
9845 }
9846 (Value::Map(m), "get") => {
9847 if arg_values.len() != 1 {
9848 return Err(RuntimeError::new("get expects 1 argument"));
9849 }
9850 let key = match &arg_values[0] {
9851 Value::String(s) => (**s).clone(),
9852 _ => format!("{}", arg_values[0]),
9853 };
9854 Ok(m.borrow().get(&key).cloned().unwrap_or(Value::Null))
9855 }
9856 (Value::Map(m), "contains_key") => {
9857 if arg_values.len() != 1 {
9858 return Err(RuntimeError::new("contains_key expects 1 argument"));
9859 }
9860 let key = match &arg_values[0] {
9861 Value::String(s) => (**s).clone(),
9862 _ => format!("{}", arg_values[0]),
9863 };
9864 Ok(Value::Bool(m.borrow().contains_key(&key)))
9865 }
9866 (Value::Map(m), "len") => Ok(Value::Int(m.borrow().len() as i64)),
9867 (Value::Map(m), "is_empty") => Ok(Value::Bool(m.borrow().is_empty())),
9868 (Value::Map(m), "keys") => {
9869 let keys: Vec<Value> = m
9870 .borrow()
9871 .keys()
9872 .map(|k| Value::String(Rc::new(k.clone())))
9873 .collect();
9874 Ok(Value::Array(Rc::new(RefCell::new(keys))))
9875 }
9876 (Value::Map(m), "values") => {
9877 let values: Vec<Value> = m.borrow().values().cloned().collect();
9878 Ok(Value::Array(Rc::new(RefCell::new(values))))
9879 }
9880 (Value::Ref(r), "cloned") => {
9882 Ok(r.borrow().clone())
9884 }
9885 (Value::Ref(r), "borrow") => {
9886 Ok(recv.clone())
9888 }
9889 (Value::Ref(r), "borrow_mut") => {
9890 Ok(recv.clone())
9892 }
9893 (Value::Ref(r), _) => {
9895 let inner = r.borrow().clone();
9897 if let Value::Struct { name, fields } = &inner {
9898 let qualified_name = format!("{}·{}", name, method.name);
9900 let func = self
9901 .globals
9902 .borrow()
9903 .get(&qualified_name)
9904 .map(|v| v.clone());
9905 if let Some(func) = func {
9906 if let Value::Function(f) = func {
9907 let f = Self::wrap_with_const_generics(&f, fields);
9908 let old_self_type = self.current_self_type.take();
9910 self.current_self_type = Some(name.clone());
9911
9912 let reordered = if f.params.len() > 1 {
9915 Self::reorder_named_args(
9916 &f.params[1..].to_vec(),
9917 arg_entries.clone(),
9918 )?
9919 } else {
9920 arg_values.clone()
9921 };
9922 let mut all_args = vec![recv.clone()];
9923 all_args.extend(reordered);
9924 let result = self.call_function(&f, all_args);
9925
9926 self.current_self_type = old_self_type;
9928 return result;
9929 } else if let Value::BuiltIn(b) = func {
9930 let mut all_args = vec![recv.clone()];
9931 all_args.extend(arg_values.clone());
9932 return (b.func)(self, all_args);
9933 }
9934 }
9935
9936 if name == "Self" {
9938 let field_names: Vec<String> = fields.borrow().keys().cloned().collect();
9939
9940 for (type_name, type_def) in &self.types {
9942 if let TypeDef::Struct(struct_def) = type_def {
9943 let def_fields: Vec<String> = match &struct_def.fields {
9944 crate::ast::StructFields::Named(fs) => {
9945 fs.iter().map(|f| f.name.name.clone()).collect()
9946 }
9947 _ => continue,
9948 };
9949
9950 let matches = field_names.iter().all(|f| def_fields.contains(f));
9952 if matches {
9953 let qualified_name = format!("{}·{}", type_name, method.name);
9954 let func = self
9955 .globals
9956 .borrow()
9957 .get(&qualified_name)
9958 .map(|v| v.clone());
9959 if let Some(func) = func {
9960 if let Value::Function(f) = func {
9961 let f = Self::wrap_with_const_generics(&f, fields);
9962 let old_self_type = self.current_self_type.take();
9964 self.current_self_type = Some(type_name.clone());
9965
9966 let reordered = if f.params.len() > 1 {
9968 Self::reorder_named_args(
9969 &f.params[1..].to_vec(),
9970 arg_entries.clone(),
9971 )?
9972 } else {
9973 arg_values.clone()
9974 };
9975 let mut all_args = vec![recv.clone()];
9976 all_args.extend(reordered);
9977 let result = self.call_function(&f, all_args);
9978
9979 self.current_self_type = old_self_type;
9981 return result;
9982 } else if let Value::BuiltIn(b) = func {
9983 let mut all_args = vec![recv.clone()];
9984 all_args.extend(arg_values.clone());
9985 return (b.func)(self, all_args);
9986 }
9987 }
9988 }
9989 }
9990 }
9991 }
9992
9993 if name == "PathBuf" || name == "Path" {
9995 if let Some(Value::String(path)) = fields.borrow().get("path").cloned() {
9996 match method.name.as_str() {
9997 "exists" => {
9998 return Ok(Value::Bool(
9999 std::path::Path::new(path.as_str()).exists(),
10000 ))
10001 }
10002 "is_dir" => {
10003 return Ok(Value::Bool(
10004 std::path::Path::new(path.as_str()).is_dir(),
10005 ))
10006 }
10007 "is_file" => {
10008 return Ok(Value::Bool(
10009 std::path::Path::new(path.as_str()).is_file(),
10010 ))
10011 }
10012 "join" => {
10013 if let Some(Value::String(other)) = arg_values.first() {
10014 let new_path = std::path::Path::new(path.as_str())
10015 .join(other.as_str());
10016 let mut new_fields = std::collections::HashMap::new();
10017 new_fields.insert(
10018 "path".to_string(),
10019 Value::String(Rc::new(
10020 new_path.to_string_lossy().to_string(),
10021 )),
10022 );
10023 return Ok(Value::Struct {
10024 name: "PathBuf".to_string(),
10025 fields: Rc::new(RefCell::new(new_fields)),
10026 });
10027 }
10028 return Err(RuntimeError::new("join requires string argument"));
10029 }
10030 "parent" => {
10031 let p = std::path::Path::new(path.as_str());
10032 return match p.parent() {
10033 Some(par) => {
10034 let mut new_fields = std::collections::HashMap::new();
10035 new_fields.insert(
10036 "path".to_string(),
10037 Value::String(Rc::new(
10038 par.to_string_lossy().to_string(),
10039 )),
10040 );
10041 Ok(Value::Struct {
10042 name: "PathBuf".to_string(),
10043 fields: Rc::new(RefCell::new(new_fields)),
10044 })
10045 }
10046 None => Ok(Value::Null),
10047 };
10048 }
10049 "file_name" => {
10050 let p = std::path::Path::new(path.as_str());
10051 return match p.file_name() {
10052 Some(n) => Ok(Value::String(Rc::new(
10053 n.to_string_lossy().to_string(),
10054 ))),
10055 None => Ok(Value::Null),
10056 };
10057 }
10058 "extension" => {
10059 let p = std::path::Path::new(path.as_str());
10060 return match p.extension() {
10061 Some(e) => Ok(Value::String(Rc::new(
10062 e.to_string_lossy().to_string(),
10063 ))),
10064 None => Ok(Value::Null),
10065 };
10066 }
10067 "to_string" | "display" | "to_str" => {
10068 return Ok(Value::String(path.clone()));
10069 }
10070 _ => {}
10071 }
10072 }
10073 }
10074
10075 return Err(RuntimeError::new(format!(
10077 "no method '{}' on type '&{}'",
10078 method.name, name
10079 )));
10080 }
10081 if let Value::String(s) = &inner {
10084 match method.name.as_str() {
10085 "to_string" => return Ok(Value::String(s.clone())),
10086 "len" => return Ok(Value::Int(s.len() as i64)),
10087 "is_empty" => return Ok(Value::Bool(s.is_empty())),
10088 "capacity" => return Ok(Value::Int(s.capacity() as i64)),
10089 "as_str" => return Ok(Value::String(s.clone())),
10090 "starts_with" => {
10091 let prefix = match arg_values.first() {
10092 Some(Value::String(p)) => p.as_str(),
10093 Some(Value::Char(c)) => return Ok(Value::Bool(s.starts_with(*c))),
10094 _ => {
10095 return Err(RuntimeError::new(
10096 "starts_with expects string or char",
10097 ))
10098 }
10099 };
10100 return Ok(Value::Bool(s.starts_with(prefix)));
10101 }
10102 "ends_with" => {
10103 let suffix = match arg_values.first() {
10104 Some(Value::String(p)) => p.as_str(),
10105 Some(Value::Char(c)) => return Ok(Value::Bool(s.ends_with(*c))),
10106 _ => {
10107 return Err(RuntimeError::new(
10108 "ends_with expects string or char",
10109 ))
10110 }
10111 };
10112 return Ok(Value::Bool(s.ends_with(suffix)));
10113 }
10114 "contains" => {
10115 let substr = match arg_values.first() {
10116 Some(Value::String(p)) => p.as_str(),
10117 Some(Value::Char(c)) => return Ok(Value::Bool(s.contains(*c))),
10118 _ => {
10119 return Err(RuntimeError::new(
10120 "contains expects string or char",
10121 ))
10122 }
10123 };
10124 return Ok(Value::Bool(s.contains(substr)));
10125 }
10126 "trim" => return Ok(Value::String(Rc::new(s.trim().to_string()))),
10127 "to_lowercase" => return Ok(Value::String(Rc::new(s.to_lowercase()))),
10128 "to_uppercase" => return Ok(Value::String(Rc::new(s.to_uppercase()))),
10129 "chars" => {
10130 let chars: Vec<Value> = s.chars().map(Value::Char).collect();
10131 return Ok(Value::Array(Rc::new(RefCell::new(chars))));
10132 }
10133 "split" => {
10134 let delim = match arg_values.first() {
10135 Some(Value::String(d)) => d.as_str().to_string(),
10136 Some(Value::Char(c)) => c.to_string(),
10137 _ => " ".to_string(),
10138 };
10139 let parts: Vec<Value> = s
10140 .split(&delim)
10141 .map(|p| Value::String(Rc::new(p.to_string())))
10142 .collect();
10143 return Ok(Value::Array(Rc::new(RefCell::new(parts))));
10144 }
10145 "replace" => {
10146 if arg_values.len() != 2 {
10147 return Err(RuntimeError::new("replace expects 2 arguments"));
10148 }
10149 let from = match &arg_values[0] {
10150 Value::String(f) => f.as_str().to_string(),
10151 Value::Char(c) => c.to_string(),
10152 _ => return Err(RuntimeError::new("replace expects strings")),
10153 };
10154 let to = match &arg_values[1] {
10155 Value::String(t) => t.as_str().to_string(),
10156 Value::Char(c) => c.to_string(),
10157 _ => return Err(RuntimeError::new("replace expects strings")),
10158 };
10159 return Ok(Value::String(Rc::new(s.replace(&from, &to))));
10160 }
10161 _ => {}
10162 }
10163 }
10164 if let Value::Array(arr) = &inner {
10166 match method.name.as_str() {
10167 "len" => return Ok(Value::Int(arr.borrow().len() as i64)),
10168 "is_empty" => return Ok(Value::Bool(arr.borrow().is_empty())),
10169 "push" => {
10170 if arg_values.len() != 1 {
10171 return Err(RuntimeError::new("push expects 1 argument"));
10172 }
10173 if let Some(var_name) = Self::extract_root_var(receiver) {
10175 if let Some((type_name, type_params)) =
10176 self.var_types.borrow().get(&var_name)
10177 {
10178 if type_name == "Vec" && !type_params.is_empty() {
10179 let expected_type = &type_params[0];
10180 let actual_type = self.value_type_name(&arg_values[0]);
10181 if &actual_type != expected_type {
10182 return Err(RuntimeError::new(format!(
10183 "type mismatch: expected Vec<{}>.push({}), found {}",
10184 expected_type, expected_type, actual_type
10185 )));
10186 }
10187 }
10188 }
10189 }
10190 arr.borrow_mut().push(arg_values[0].clone());
10191 return Ok(Value::Null);
10192 }
10193 "pop" => {
10194 return arr
10195 .borrow_mut()
10196 .pop()
10197 .ok_or_else(|| RuntimeError::new("pop on empty array"));
10198 }
10199 "contains" => {
10200 if arg_values.len() != 1 {
10201 return Err(RuntimeError::new("contains expects 1 argument"));
10202 }
10203 let target = &arg_values[0];
10204 let found = arr.borrow().iter().any(|v| self.values_equal(v, target));
10205 return Ok(Value::Bool(found));
10206 }
10207 "first" | "next" => {
10208 return Ok(arr.borrow().first().cloned().unwrap_or(Value::Null));
10209 }
10210 "last" => {
10211 return arr
10212 .borrow()
10213 .last()
10214 .cloned()
10215 .ok_or_else(|| RuntimeError::new("empty array"));
10216 }
10217 "iter" | "into_iter" => {
10218 return Ok(Value::Array(arr.clone()));
10219 }
10220 "reverse" => {
10221 arr.borrow_mut().reverse();
10222 return Ok(Value::Array(arr.clone()));
10223 }
10224 "skip" => {
10225 let n = match arg_values.first() {
10226 Some(Value::Int(i)) => *i as usize,
10227 _ => 1,
10228 };
10229 let v: Vec<Value> = arr.borrow().iter().skip(n).cloned().collect();
10230 return Ok(Value::Array(Rc::new(RefCell::new(v))));
10231 }
10232 "take" => {
10233 let n = match arg_values.first() {
10234 Some(Value::Int(i)) => *i as usize,
10235 _ => 1,
10236 };
10237 let v: Vec<Value> = arr.borrow().iter().take(n).cloned().collect();
10238 return Ok(Value::Array(Rc::new(RefCell::new(v))));
10239 }
10240 "get" => {
10241 let idx = match arg_values.first() {
10242 Some(Value::Int(i)) => *i as usize,
10243 _ => return Err(RuntimeError::new("get expects integer index")),
10244 };
10245 return Ok(arr.borrow().get(idx).cloned().unwrap_or(Value::Null));
10246 }
10247 _ => {}
10248 }
10249 }
10250 if method.name == "clone" {
10252 crate::sigil_debug!(
10253 "DEBUG clone: recv_type=Ref({:?})",
10254 std::mem::discriminant(&inner)
10255 );
10256 return Ok(inner.clone());
10257 }
10258 if method.name == "into" {
10260 return Ok(inner.clone());
10261 }
10262 if method.name == "to_string" {
10264 return Ok(Value::String(Rc::new(format!("{}", inner))));
10265 }
10266 if let Value::Struct { name, fields, .. } = &inner {
10268 if name == "PathBuf" || name == "Path" {
10269 let borrowed = fields.borrow();
10270 if let Some(Value::String(path)) = borrowed.get("path") {
10271 match method.name.as_str() {
10272 "exists" => {
10273 return Ok(Value::Bool(
10274 std::path::Path::new(path.as_str()).exists(),
10275 ))
10276 }
10277 "is_dir" => {
10278 return Ok(Value::Bool(
10279 std::path::Path::new(path.as_str()).is_dir(),
10280 ))
10281 }
10282 "is_file" => {
10283 return Ok(Value::Bool(
10284 std::path::Path::new(path.as_str()).is_file(),
10285 ))
10286 }
10287 "join" => {
10288 if let Some(Value::String(other)) = arg_values.first() {
10289 let new_path = std::path::Path::new(path.as_str())
10290 .join(other.as_str());
10291 let mut new_fields = std::collections::HashMap::new();
10292 new_fields.insert(
10293 "path".to_string(),
10294 Value::String(Rc::new(
10295 new_path.to_string_lossy().to_string(),
10296 )),
10297 );
10298 return Ok(Value::Struct {
10299 name: "PathBuf".to_string(),
10300 fields: Rc::new(RefCell::new(new_fields)),
10301 });
10302 }
10303 return Err(RuntimeError::new("join requires string argument"));
10304 }
10305 "parent" => {
10306 let p = std::path::Path::new(path.as_str());
10307 return match p.parent() {
10308 Some(par) => {
10309 let mut new_fields = std::collections::HashMap::new();
10310 new_fields.insert(
10311 "path".to_string(),
10312 Value::String(Rc::new(
10313 par.to_string_lossy().to_string(),
10314 )),
10315 );
10316 Ok(Value::Struct {
10317 name: "PathBuf".to_string(),
10318 fields: Rc::new(RefCell::new(new_fields)),
10319 })
10320 }
10321 None => Ok(Value::Null),
10322 };
10323 }
10324 "file_name" => {
10325 let p = std::path::Path::new(path.as_str());
10326 return match p.file_name() {
10327 Some(n) => Ok(Value::String(Rc::new(
10328 n.to_string_lossy().to_string(),
10329 ))),
10330 None => Ok(Value::Null),
10331 };
10332 }
10333 "extension" => {
10334 let p = std::path::Path::new(path.as_str());
10335 return match p.extension() {
10336 Some(e) => Ok(Value::String(Rc::new(
10337 e.to_string_lossy().to_string(),
10338 ))),
10339 None => Ok(Value::Null),
10340 };
10341 }
10342 "to_string" | "display" => {
10343 return Ok(Value::String(path.clone()));
10344 }
10345 _ => {}
10346 }
10347 }
10348 }
10349 }
10350 if let Value::String(s) = &inner {
10352 match method.name.as_str() {
10353 "exists" => {
10354 return Ok(Value::Bool(std::path::Path::new(s.as_str()).exists()))
10355 }
10356 "is_dir" => {
10357 return Ok(Value::Bool(std::path::Path::new(s.as_str()).is_dir()))
10358 }
10359 "is_file" => {
10360 return Ok(Value::Bool(std::path::Path::new(s.as_str()).is_file()))
10361 }
10362 "join" => {
10363 if let Some(Value::String(other)) = arg_values.first() {
10364 let path = std::path::Path::new(s.as_str()).join(other.as_str());
10365 return Ok(Value::String(Rc::new(
10366 path.to_string_lossy().to_string(),
10367 )));
10368 }
10369 return Err(RuntimeError::new("join requires string argument"));
10370 }
10371 "parent" => {
10372 let path = std::path::Path::new(s.as_str());
10373 return match path.parent() {
10374 Some(p) => {
10375 Ok(Value::String(Rc::new(p.to_string_lossy().to_string())))
10376 }
10377 None => Ok(Value::Null),
10378 };
10379 }
10380 "file_name" => {
10381 let path = std::path::Path::new(s.as_str());
10382 return match path.file_name() {
10383 Some(n) => {
10384 Ok(Value::String(Rc::new(n.to_string_lossy().to_string())))
10385 }
10386 None => Ok(Value::Null),
10387 };
10388 }
10389 "extension" => {
10390 let path = std::path::Path::new(s.as_str());
10391 return match path.extension() {
10392 Some(e) => {
10393 Ok(Value::String(Rc::new(e.to_string_lossy().to_string())))
10394 }
10395 None => Ok(Value::Null),
10396 };
10397 }
10398 _ => {}
10399 }
10400 }
10401 if let Value::String(_) = inner {
10404 let recv_unwrapped = inner.clone();
10407 match (&recv_unwrapped, method.name.as_str()) {
10408 (Value::String(s), "find") => {
10409 if arg_values.len() != 1 {
10410 return Err(RuntimeError::new("find expects 1 argument"));
10411 }
10412 match &arg_values[0] {
10413 Value::Char(c) => {
10414 return match s.find(*c) {
10415 Some(idx) => Ok(Value::Variant {
10416 enum_name: "Option".to_string(),
10417 variant_name: "Some".to_string(),
10418 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
10419 }),
10420 None => Ok(Value::Variant {
10421 enum_name: "Option".to_string(),
10422 variant_name: "None".to_string(),
10423 fields: None,
10424 }),
10425 }
10426 }
10427 Value::String(pattern) => {
10428 return match s.find(pattern.as_str()) {
10429 Some(idx) => Ok(Value::Variant {
10430 enum_name: "Option".to_string(),
10431 variant_name: "Some".to_string(),
10432 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
10433 }),
10434 None => Ok(Value::Variant {
10435 enum_name: "Option".to_string(),
10436 variant_name: "None".to_string(),
10437 fields: None,
10438 }),
10439 }
10440 }
10441 Value::Function(f) => {
10442 for (idx, c) in s.chars().enumerate() {
10443 let result = self.call_function(f, vec![Value::Char(c)])?;
10444 if let Value::Bool(true) = result {
10445 return Ok(Value::Variant {
10446 enum_name: "Option".to_string(),
10447 variant_name: "Some".to_string(),
10448 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
10449 });
10450 }
10451 }
10452 return Ok(Value::Variant {
10453 enum_name: "Option".to_string(),
10454 variant_name: "None".to_string(),
10455 fields: None,
10456 });
10457 }
10458 _ => {
10459 return Err(RuntimeError::new(
10460 "find expects a char, string, or closure",
10461 ))
10462 }
10463 }
10464 }
10465 (Value::String(s), "trim") => {
10466 return Ok(Value::String(Rc::new(s.trim().to_string())))
10467 }
10468 (Value::String(s), "is_empty") => return Ok(Value::Bool(s.is_empty())),
10469 (Value::String(s), "len") => return Ok(Value::Int(s.len() as i64)),
10470 (Value::String(s), "to_string") => return Ok(Value::String(s.clone())),
10471 (Value::String(s), "chars") => {
10472 let chars: Vec<Value> = s.chars().map(Value::Char).collect();
10473 return Ok(Value::Array(Rc::new(RefCell::new(chars))));
10474 }
10475 (Value::String(s), "starts_with") => {
10476 if let Some(Value::String(prefix)) = arg_values.first() {
10477 return Ok(Value::Bool(s.starts_with(prefix.as_str())));
10478 }
10479 return Err(RuntimeError::new("starts_with expects string argument"));
10480 }
10481 _ => {}
10482 }
10483 }
10484 {
10487 static DEREF_CTR: std::sync::atomic::AtomicUsize =
10488 std::sync::atomic::AtomicUsize::new(0);
10489 let id = DEREF_CTR.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
10490 let inner_name = format!("__ref_deref_{}", id);
10491 self.environment.borrow_mut().define(inner_name.clone(), inner.clone());
10492 let deref_expr = Expr::Path(TypePath {
10493 segments: vec![PathSegment {
10494 ident: Ident {
10495 name: inner_name.clone(),
10496 span: Default::default(),
10497 evidentiality: None,
10498 affect: None,
10499 },
10500 generics: None,
10501 }],
10502 });
10503 let result = self.eval_method_call(&deref_expr, method, args);
10504 let _ = self.environment.borrow_mut().set(&inner_name, Value::Null);
10505 result
10506 }
10507 }
10508 (Value::Struct { name, fields }, _) => {
10510 if method.name == "clone" {
10512 return Ok(recv.clone());
10514 }
10515 if name == "PathBuf" || name == "Path" {
10517 let borrowed = fields.borrow();
10518 if let Some(Value::String(path)) = borrowed.get("path") {
10519 match method.name.as_str() {
10520 "exists" => {
10521 return Ok(Value::Bool(
10522 std::path::Path::new(path.as_str()).exists(),
10523 ))
10524 }
10525 "is_dir" => {
10526 return Ok(Value::Bool(
10527 std::path::Path::new(path.as_str()).is_dir(),
10528 ))
10529 }
10530 "is_file" => {
10531 return Ok(Value::Bool(
10532 std::path::Path::new(path.as_str()).is_file(),
10533 ))
10534 }
10535 "join" => {
10536 if let Some(Value::String(other)) = arg_values.first() {
10537 let new_path =
10538 std::path::Path::new(path.as_str()).join(other.as_str());
10539 let mut new_fields = std::collections::HashMap::new();
10540 new_fields.insert(
10541 "path".to_string(),
10542 Value::String(Rc::new(
10543 new_path.to_string_lossy().to_string(),
10544 )),
10545 );
10546 return Ok(Value::Struct {
10547 name: "PathBuf".to_string(),
10548 fields: Rc::new(RefCell::new(new_fields)),
10549 });
10550 }
10551 return Err(RuntimeError::new("join requires string argument"));
10552 }
10553 "parent" => {
10554 let p = std::path::Path::new(path.as_str());
10555 return match p.parent() {
10556 Some(par) => {
10557 let mut new_fields = std::collections::HashMap::new();
10558 new_fields.insert(
10559 "path".to_string(),
10560 Value::String(Rc::new(
10561 par.to_string_lossy().to_string(),
10562 )),
10563 );
10564 Ok(Value::Struct {
10565 name: "PathBuf".to_string(),
10566 fields: Rc::new(RefCell::new(new_fields)),
10567 })
10568 }
10569 None => Ok(Value::Null),
10570 };
10571 }
10572 "file_name" => {
10573 let p = std::path::Path::new(path.as_str());
10574 return match p.file_name() {
10575 Some(n) => {
10576 Ok(Value::String(Rc::new(n.to_string_lossy().to_string())))
10577 }
10578 None => Ok(Value::Null),
10579 };
10580 }
10581 "extension" => {
10582 let p = std::path::Path::new(path.as_str());
10583 return match p.extension() {
10584 Some(e) => {
10585 Ok(Value::String(Rc::new(e.to_string_lossy().to_string())))
10586 }
10587 None => Ok(Value::Null),
10588 };
10589 }
10590 "to_string" | "display" => {
10591 return Ok(Value::String(path.clone()));
10592 }
10593 _ => {}
10594 }
10595 }
10596 }
10597 if name == "Rc" {
10599 let borrowed = fields.borrow();
10600 if let Some(value) = borrowed.get("_value") {
10601 match method.name.as_str() {
10602 "clone" => {
10603 let mut new_fields = HashMap::new();
10605 new_fields.insert("_value".to_string(), value.clone());
10606 return Ok(Value::Struct {
10607 name: "Rc".to_string(),
10608 fields: Rc::new(RefCell::new(new_fields)),
10609 });
10610 }
10611 _ => {}
10612 }
10613 }
10614 }
10615 if name == "Cell" {
10617 match method.name.as_str() {
10618 "get" => {
10619 let borrowed = fields.borrow();
10620 if let Some(value) = borrowed.get("_value") {
10621 return Ok(value.clone());
10622 }
10623 return Err(RuntimeError::new("Cell has no value"));
10624 }
10625 "set" => {
10626 if arg_values.len() != 1 {
10627 return Err(RuntimeError::new("set expects 1 argument"));
10628 }
10629 fields
10630 .borrow_mut()
10631 .insert("_value".to_string(), arg_values[0].clone());
10632 return Ok(Value::Null);
10633 }
10634 _ => {}
10635 }
10636 }
10637 if name == "Duration" {
10639 let borrowed = fields.borrow();
10640 let secs = match borrowed.get("secs") {
10641 Some(Value::Int(s)) => *s,
10642 _ => 0,
10643 };
10644 let nanos = match borrowed.get("nanos") {
10645 Some(Value::Int(n)) => *n,
10646 _ => 0,
10647 };
10648 match method.name.as_str() {
10649 "as_secs" => return Ok(Value::Int(secs)),
10650 "as_millis" => return Ok(Value::Int(secs * 1000 + nanos / 1_000_000)),
10651 "as_micros" => return Ok(Value::Int(secs * 1_000_000 + nanos / 1000)),
10652 "as_nanos" => return Ok(Value::Int(secs * 1_000_000_000 + nanos)),
10653 "subsec_nanos" => return Ok(Value::Int(nanos)),
10654 "subsec_millis" => return Ok(Value::Int(nanos / 1_000_000)),
10655 "is_zero" => return Ok(Value::Bool(secs == 0 && nanos == 0)),
10656 _ => {}
10657 }
10658 }
10659 if name == "Mutex" {
10661 match method.name.as_str() {
10662 "lock" => {
10663 let borrowed = fields.borrow();
10666 if let Some(inner) = borrowed.get("__inner__") {
10667 return Ok(Value::Ref(Rc::new(RefCell::new(inner.clone()))));
10669 }
10670 return Err(RuntimeError::new("Mutex has no inner value"));
10671 }
10672 "try_lock" => {
10673 let borrowed = fields.borrow();
10675 if let Some(inner) = borrowed.get("__inner__") {
10676 let guard = Value::Ref(Rc::new(RefCell::new(inner.clone())));
10677 return Ok(Value::Variant {
10678 enum_name: "Option".to_string(),
10679 variant_name: "Some".to_string(),
10680 fields: Some(Rc::new(vec![guard])),
10681 });
10682 }
10683 return Ok(Value::Variant {
10684 enum_name: "Option".to_string(),
10685 variant_name: "None".to_string(),
10686 fields: None,
10687 });
10688 }
10689 "into_inner" => {
10690 let borrowed = fields.borrow();
10692 if let Some(inner) = borrowed.get("__inner__") {
10693 return Ok(inner.clone());
10694 }
10695 return Err(RuntimeError::new("Mutex has no inner value"));
10696 }
10697 "get_mut" => {
10698 let borrowed = fields.borrow();
10700 if let Some(inner) = borrowed.get("__inner__") {
10701 return Ok(Value::Ref(Rc::new(RefCell::new(inner.clone()))));
10702 }
10703 return Err(RuntimeError::new("Mutex has no inner value"));
10704 }
10705 _ => {}
10706 }
10707 }
10708 if name == "RwLock" {
10710 match method.name.as_str() {
10711 "read" => {
10712 let borrowed = fields.borrow();
10714 if let Some(inner) = borrowed.get("__inner__") {
10715 return Ok(Value::Ref(Rc::new(RefCell::new(inner.clone()))));
10716 }
10717 return Err(RuntimeError::new("RwLock has no inner value"));
10718 }
10719 "write" => {
10720 let borrowed = fields.borrow();
10722 if let Some(inner) = borrowed.get("__inner__") {
10723 return Ok(Value::Ref(Rc::new(RefCell::new(inner.clone()))));
10724 }
10725 return Err(RuntimeError::new("RwLock has no inner value"));
10726 }
10727 "try_read" => {
10728 let borrowed = fields.borrow();
10729 if let Some(inner) = borrowed.get("__inner__") {
10730 let guard = Value::Ref(Rc::new(RefCell::new(inner.clone())));
10731 return Ok(Value::Variant {
10732 enum_name: "Option".to_string(),
10733 variant_name: "Some".to_string(),
10734 fields: Some(Rc::new(vec![guard])),
10735 });
10736 }
10737 return Ok(Value::Variant {
10738 enum_name: "Option".to_string(),
10739 variant_name: "None".to_string(),
10740 fields: None,
10741 });
10742 }
10743 "try_write" => {
10744 let borrowed = fields.borrow();
10745 if let Some(inner) = borrowed.get("__inner__") {
10746 let guard = Value::Ref(Rc::new(RefCell::new(inner.clone())));
10747 return Ok(Value::Variant {
10748 enum_name: "Option".to_string(),
10749 variant_name: "Some".to_string(),
10750 fields: Some(Rc::new(vec![guard])),
10751 });
10752 }
10753 return Ok(Value::Variant {
10754 enum_name: "Option".to_string(),
10755 variant_name: "None".to_string(),
10756 fields: None,
10757 });
10758 }
10759 "into_inner" => {
10760 let borrowed = fields.borrow();
10761 if let Some(inner) = borrowed.get("__inner__") {
10762 return Ok(inner.clone());
10763 }
10764 return Err(RuntimeError::new("RwLock has no inner value"));
10765 }
10766 _ => {}
10767 }
10768 }
10769 if name == "OnceLock" {
10771 match method.name.as_str() {
10772 "get_or_init" => {
10773 let is_initialized = {
10775 let borrowed = fields.borrow();
10776 matches!(borrowed.get("initialized"), Some(Value::Bool(true)))
10777 };
10778 if is_initialized {
10779 let borrowed = fields.borrow();
10780 return Ok(borrowed.get("value").cloned().unwrap_or(Value::Null));
10781 }
10782 let init_val = if !arg_values.is_empty() {
10784 match &arg_values[0] {
10785 Value::Function(f) => self.call_function(f, vec![])?,
10786 Value::BuiltIn(b) => (b.func)(self, vec![])?,
10787 other => other.clone(),
10789 }
10790 } else {
10791 Value::Null
10792 };
10793 {
10795 let mut borrowed = fields.borrow_mut();
10796 borrowed.insert("initialized".to_string(), Value::Bool(true));
10797 borrowed.insert("value".to_string(), init_val.clone());
10798 }
10799 return Ok(init_val);
10800 }
10801 "get" => {
10802 let borrowed = fields.borrow();
10804 if matches!(borrowed.get("initialized"), Some(Value::Bool(true))) {
10805 let val = borrowed.get("value").cloned().unwrap_or(Value::Null);
10806 return Ok(Value::Variant {
10807 enum_name: "Option".to_string(),
10808 variant_name: "Some".to_string(),
10809 fields: Some(Rc::new(vec![val])),
10810 });
10811 }
10812 return Ok(Value::Variant {
10813 enum_name: "Option".to_string(),
10814 variant_name: "None".to_string(),
10815 fields: None,
10816 });
10817 }
10818 "set" => {
10819 let is_initialized = {
10821 let borrowed = fields.borrow();
10822 matches!(borrowed.get("initialized"), Some(Value::Bool(true)))
10823 };
10824 if is_initialized {
10825 let err_val = if !arg_values.is_empty() { arg_values[0].clone() } else { Value::Null };
10826 return Ok(Value::Variant {
10827 enum_name: "Result".to_string(),
10828 variant_name: "Err".to_string(),
10829 fields: Some(Rc::new(vec![err_val])),
10830 });
10831 }
10832 let val = if !arg_values.is_empty() { arg_values[0].clone() } else { Value::Null };
10833 {
10834 let mut borrowed = fields.borrow_mut();
10835 borrowed.insert("initialized".to_string(), Value::Bool(true));
10836 borrowed.insert("value".to_string(), val);
10837 }
10838 return Ok(Value::Variant {
10839 enum_name: "Result".to_string(),
10840 variant_name: "Ok".to_string(),
10841 fields: Some(Rc::new(vec![Value::Null])),
10842 });
10843 }
10844 _ => {}
10845 }
10846 }
10847 if name == "Barrier" {
10849 match method.name.as_str() {
10850 "wait" => {
10851 let mut result_fields = HashMap::new();
10854 result_fields.insert("__type__".to_string(), Value::String(Rc::new("BarrierWaitResult".to_string())));
10855 result_fields.insert("is_leader".to_string(), Value::Bool(true)); return Ok(Value::Map(Rc::new(RefCell::new(result_fields))));
10857 }
10858 "is_leader" => {
10859 return Ok(Value::Bool(true));
10861 }
10862 _ => {}
10863 }
10864 }
10865 if name == "Client" || name == "HttpClient" {
10867 match method.name.as_str() {
10868 "get" => {
10869 if let Some(url) = arg_values.first() {
10871 let url_str = match url {
10872 Value::String(s) => s.to_string(),
10873 _ => return Err(RuntimeError::new("get() requires a URL string")),
10874 };
10875 let mut response_fields = HashMap::new();
10877 response_fields.insert("__type__".to_string(), Value::String(Rc::new("Response".to_string())));
10878 response_fields.insert("url".to_string(), Value::String(Rc::new(url_str)));
10879 response_fields.insert("status".to_string(), Value::Int(200));
10880 response_fields.insert("body".to_string(), Value::String(Rc::new("{}".to_string())));
10881 response_fields.insert("__evidence__".to_string(), Value::String(Rc::new("reported".to_string())));
10882 return Ok(Value::Struct {
10883 name: "Response".to_string(),
10884 fields: Rc::new(RefCell::new(response_fields)),
10885 });
10886 }
10887 return Err(RuntimeError::new("get() requires a URL argument"));
10888 }
10889 "post" => {
10890 if arg_values.len() >= 1 {
10892 let url_str = match &arg_values[0] {
10893 Value::String(s) => s.to_string(),
10894 _ => return Err(RuntimeError::new("post() requires a URL string")),
10895 };
10896 let mut response_fields = HashMap::new();
10897 response_fields.insert("__type__".to_string(), Value::String(Rc::new("Response".to_string())));
10898 response_fields.insert("url".to_string(), Value::String(Rc::new(url_str)));
10899 response_fields.insert("status".to_string(), Value::Int(200));
10900 response_fields.insert("body".to_string(), Value::String(Rc::new("{}".to_string())));
10901 response_fields.insert("__evidence__".to_string(), Value::String(Rc::new("reported".to_string())));
10902 return Ok(Value::Struct {
10903 name: "Response".to_string(),
10904 fields: Rc::new(RefCell::new(response_fields)),
10905 });
10906 }
10907 return Err(RuntimeError::new("post() requires a URL argument"));
10908 }
10909 _ => {}
10910 }
10911 }
10912 if name == "Response" {
10914 match method.name.as_str() {
10915 "verify" => {
10916 let borrowed = fields.borrow();
10919 let mut verified_fields = HashMap::new();
10920 for (k, v) in borrowed.iter() {
10921 if k != "__evidence__" {
10922 verified_fields.insert(k.clone(), v.clone());
10923 }
10924 }
10925 verified_fields.insert("__evidence__".to_string(), Value::String(Rc::new("known".to_string())));
10926 return Ok(Value::Struct {
10927 name: "Response".to_string(),
10928 fields: Rc::new(RefCell::new(verified_fields)),
10929 });
10930 }
10931 "body" => {
10932 let borrowed = fields.borrow();
10934 return Ok(borrowed.get("body").cloned().unwrap_or(Value::String(Rc::new("".to_string()))));
10935 }
10936 "status" => {
10937 let borrowed = fields.borrow();
10939 return Ok(borrowed.get("status").cloned().unwrap_or(Value::Int(0)));
10940 }
10941 "json" => {
10942 let borrowed = fields.borrow();
10944 if let Some(Value::String(body)) = borrowed.get("body") {
10945 return Ok(Value::String(body.clone()));
10947 }
10948 return Ok(Value::Null);
10949 }
10950 _ => {}
10951 }
10952 }
10953 if name == "AtomicU64"
10955 || name == "AtomicUsize"
10956 || name == "AtomicI64"
10957 || name == "AtomicIsize"
10958 {
10959 match method.name.as_str() {
10960 "load" => {
10961 let borrowed = fields.borrow();
10963 if let Some(val) = borrowed.get("__value__") {
10964 return Ok(val.clone());
10965 }
10966 return Ok(Value::Int(0));
10967 }
10968 "store" => {
10969 if let Some(new_val) = arg_values.first() {
10971 fields
10972 .borrow_mut()
10973 .insert("__value__".to_string(), new_val.clone());
10974 return Ok(Value::Null);
10975 }
10976 return Err(RuntimeError::new("store requires a value"));
10977 }
10978 "fetch_add" => {
10979 if let Some(Value::Int(n)) = arg_values.first() {
10981 let mut borrowed = fields.borrow_mut();
10982 let old = match borrowed.get("__value__") {
10983 Some(Value::Int(v)) => *v,
10984 _ => 0,
10985 };
10986 borrowed.insert("__value__".to_string(), Value::Int(old + n));
10987 return Ok(Value::Int(old));
10988 }
10989 return Err(RuntimeError::new("fetch_add requires integer"));
10990 }
10991 "fetch_sub" => {
10992 if let Some(Value::Int(n)) = arg_values.first() {
10993 let mut borrowed = fields.borrow_mut();
10994 let old = match borrowed.get("__value__") {
10995 Some(Value::Int(v)) => *v,
10996 _ => 0,
10997 };
10998 borrowed.insert("__value__".to_string(), Value::Int(old - n));
10999 return Ok(Value::Int(old));
11000 }
11001 return Err(RuntimeError::new("fetch_sub requires integer"));
11002 }
11003 "swap" => {
11004 if let Some(new_val) = arg_values.first() {
11005 let mut borrowed = fields.borrow_mut();
11006 let old =
11007 borrowed.get("__value__").cloned().unwrap_or(Value::Int(0));
11008 borrowed.insert("__value__".to_string(), new_val.clone());
11009 return Ok(old);
11010 }
11011 return Err(RuntimeError::new("swap requires a value"));
11012 }
11013 "compare_exchange" | "compare_and_swap" => {
11014 if arg_values.len() >= 2 {
11016 let current = &arg_values[0];
11017 let new_val = &arg_values[1];
11018 let mut borrowed = fields.borrow_mut();
11019 let actual =
11020 borrowed.get("__value__").cloned().unwrap_or(Value::Int(0));
11021 if self.values_equal(&actual, current) {
11022 borrowed.insert("__value__".to_string(), new_val.clone());
11023 return Ok(Value::Variant {
11024 enum_name: "Result".to_string(),
11025 variant_name: "Ok".to_string(),
11026 fields: Some(Rc::new(vec![actual])),
11027 });
11028 } else {
11029 return Ok(Value::Variant {
11030 enum_name: "Result".to_string(),
11031 variant_name: "Err".to_string(),
11032 fields: Some(Rc::new(vec![actual])),
11033 });
11034 }
11035 }
11036 return Err(RuntimeError::new(
11037 "compare_exchange requires two arguments",
11038 ));
11039 }
11040 _ => {}
11041 }
11042 }
11043 if name == "AtomicBool" {
11045 match method.name.as_str() {
11046 "load" => {
11047 let borrowed = fields.borrow();
11048 if let Some(val) = borrowed.get("__value__") {
11049 return Ok(val.clone());
11050 }
11051 return Ok(Value::Bool(false));
11052 }
11053 "store" => {
11054 if let Some(new_val) = arg_values.first() {
11055 fields
11056 .borrow_mut()
11057 .insert("__value__".to_string(), new_val.clone());
11058 return Ok(Value::Null);
11059 }
11060 return Err(RuntimeError::new("store requires a value"));
11061 }
11062 "swap" => {
11063 if let Some(new_val) = arg_values.first() {
11064 let mut borrowed = fields.borrow_mut();
11065 let old = borrowed
11066 .get("__value__")
11067 .cloned()
11068 .unwrap_or(Value::Bool(false));
11069 borrowed.insert("__value__".to_string(), new_val.clone());
11070 return Ok(old);
11071 }
11072 return Err(RuntimeError::new("swap requires a value"));
11073 }
11074 "fetch_and" => {
11075 if let Some(Value::Bool(b)) = arg_values.first() {
11076 let mut borrowed = fields.borrow_mut();
11077 let old = match borrowed.get("__value__") {
11078 Some(Value::Bool(v)) => *v,
11079 _ => false,
11080 };
11081 borrowed.insert("__value__".to_string(), Value::Bool(old && *b));
11082 return Ok(Value::Bool(old));
11083 }
11084 return Err(RuntimeError::new("fetch_and requires boolean"));
11085 }
11086 "fetch_or" => {
11087 if let Some(Value::Bool(b)) = arg_values.first() {
11088 let mut borrowed = fields.borrow_mut();
11089 let old = match borrowed.get("__value__") {
11090 Some(Value::Bool(v)) => *v,
11091 _ => false,
11092 };
11093 borrowed.insert("__value__".to_string(), Value::Bool(old || *b));
11094 return Ok(Value::Bool(old));
11095 }
11096 return Err(RuntimeError::new("fetch_or requires boolean"));
11097 }
11098 _ => {}
11099 }
11100 }
11101 if method.name == "to_string" {
11102 let user_method_name = format!("{}·to_string", name);
11104 let user_fn = self.globals.borrow().get(&user_method_name).map(|v| v.clone());
11105 if let Some(Value::Function(func)) = user_fn {
11106 let self_val = Value::Struct {
11107 name: name.clone(),
11108 fields: fields.clone(),
11109 };
11110 return self.call_function(&func, vec![self_val]);
11111 }
11112 let field_str = fields
11114 .borrow()
11115 .iter()
11116 .map(|(k, v)| format!("{}: {}", k, v))
11117 .collect::<Vec<_>>()
11118 .join(", ");
11119 return Ok(Value::String(Rc::new(format!(
11120 "{} {{ {} }}",
11121 name, field_str
11122 ))));
11123 }
11124
11125 if name.starts_with("Pattern::") {
11127 match method.name.as_str() {
11128 "evidentiality" => {
11129 if let Some(ev) = fields.borrow().get("evidentiality") {
11131 return Ok(ev.clone());
11132 }
11133 return Ok(Value::Null);
11134 }
11135 "name" | "binding_name" => {
11136 if let Some(n) = fields.borrow().get("name") {
11138 let result = match &n {
11141 Value::Struct {
11142 fields: inner_fields,
11143 ..
11144 } => {
11145 if let Some(inner_name) = inner_fields.borrow().get("name")
11146 {
11147 crate::sigil_debug!("DEBUG binding_name: returning inner name {} from {}", inner_name, name);
11148 inner_name.clone()
11149 } else {
11150 crate::sigil_debug!(
11151 "DEBUG binding_name: returning struct {} from {}",
11152 n,
11153 name
11154 );
11155 n.clone()
11156 }
11157 }
11158 _ => {
11159 crate::sigil_debug!(
11160 "DEBUG binding_name: returning {} from {}",
11161 n,
11162 name
11163 );
11164 n.clone()
11165 }
11166 };
11167 return Ok(result);
11168 }
11169 crate::sigil_debug!(
11170 "DEBUG binding_name: 'name' field not found in {}, fields: {:?}",
11171 name,
11172 fields.borrow().keys().collect::<Vec<_>>()
11173 );
11174 return Ok(Value::Null);
11176 }
11177 "mutable" => {
11178 if let Some(m) = fields.borrow().get("mutable") {
11180 return Ok(m.clone());
11181 }
11182 return Ok(Value::Bool(false));
11183 }
11184 "is_ident" => {
11185 return Ok(Value::Bool(name == "Pattern::Ident"));
11186 }
11187 "is_wildcard" => {
11188 return Ok(Value::Bool(name == "Pattern::Wildcard"));
11189 }
11190 "clone" => {
11191 return Ok(recv.clone());
11192 }
11193 _ => {}
11194 }
11195 }
11196
11197 if name == "PathBuf" || name == "Path" {
11199 match method.name.as_str() {
11200 "exists" => {
11201 let path = match fields.borrow().get("path") {
11203 Some(Value::String(s)) => s.to_string(),
11204 _ => return Err(RuntimeError::new("PathBuf has no path field")),
11205 };
11206 return Ok(Value::Bool(std::path::Path::new(&path).exists()));
11207 }
11208 "is_dir" => {
11209 let path = match fields.borrow().get("path") {
11210 Some(Value::String(s)) => s.to_string(),
11211 _ => return Err(RuntimeError::new("PathBuf has no path field")),
11212 };
11213 return Ok(Value::Bool(std::path::Path::new(&path).is_dir()));
11214 }
11215 "is_file" => {
11216 let path = match fields.borrow().get("path") {
11217 Some(Value::String(s)) => s.to_string(),
11218 _ => return Err(RuntimeError::new("PathBuf has no path field")),
11219 };
11220 return Ok(Value::Bool(std::path::Path::new(&path).is_file()));
11221 }
11222 "extension" => {
11223 let path = match fields.borrow().get("path") {
11224 Some(Value::String(s)) => s.to_string(),
11225 _ => return Err(RuntimeError::new("PathBuf has no path field")),
11226 };
11227 match std::path::Path::new(&path).extension() {
11228 Some(ext) => {
11229 let ext_str = ext.to_string_lossy().to_string();
11231 let mut ext_fields = HashMap::new();
11232 ext_fields.insert(
11233 "value".to_string(),
11234 Value::String(Rc::new(ext_str)),
11235 );
11236 return Ok(Value::Variant {
11237 enum_name: "Option".to_string(),
11238 variant_name: "Some".to_string(),
11239 fields: Some(Rc::new(vec![Value::Struct {
11240 name: "OsStr".to_string(),
11241 fields: Rc::new(RefCell::new(ext_fields)),
11242 }])),
11243 });
11244 }
11245 None => {
11246 return Ok(Value::Variant {
11247 enum_name: "Option".to_string(),
11248 variant_name: "None".to_string(),
11249 fields: None,
11250 });
11251 }
11252 }
11253 }
11254 "file_name" => {
11255 let path = match fields.borrow().get("path") {
11256 Some(Value::String(s)) => s.to_string(),
11257 _ => return Err(RuntimeError::new("PathBuf has no path field")),
11258 };
11259 match std::path::Path::new(&path).file_name() {
11260 Some(fname) => {
11261 let fname_str = fname.to_string_lossy().to_string();
11262 let mut fname_fields = HashMap::new();
11263 fname_fields.insert(
11264 "value".to_string(),
11265 Value::String(Rc::new(fname_str)),
11266 );
11267 return Ok(Value::Variant {
11268 enum_name: "Option".to_string(),
11269 variant_name: "Some".to_string(),
11270 fields: Some(Rc::new(vec![Value::Struct {
11271 name: "OsStr".to_string(),
11272 fields: Rc::new(RefCell::new(fname_fields)),
11273 }])),
11274 });
11275 }
11276 None => {
11277 return Ok(Value::Variant {
11278 enum_name: "Option".to_string(),
11279 variant_name: "None".to_string(),
11280 fields: None,
11281 });
11282 }
11283 }
11284 }
11285 "parent" => {
11286 let path = match fields.borrow().get("path") {
11287 Some(Value::String(s)) => s.to_string(),
11288 _ => return Err(RuntimeError::new("PathBuf has no path field")),
11289 };
11290 match std::path::Path::new(&path).parent() {
11291 Some(parent) => {
11292 let mut parent_fields = HashMap::new();
11293 parent_fields.insert(
11294 "path".to_string(),
11295 Value::String(Rc::new(
11296 parent.to_string_lossy().to_string(),
11297 )),
11298 );
11299 return Ok(Value::Variant {
11300 enum_name: "Option".to_string(),
11301 variant_name: "Some".to_string(),
11302 fields: Some(Rc::new(vec![Value::Struct {
11303 name: "Path".to_string(),
11304 fields: Rc::new(RefCell::new(parent_fields)),
11305 }])),
11306 });
11307 }
11308 None => {
11309 return Ok(Value::Variant {
11310 enum_name: "Option".to_string(),
11311 variant_name: "None".to_string(),
11312 fields: None,
11313 });
11314 }
11315 }
11316 }
11317 "to_str" => {
11318 let path = match fields.borrow().get("path") {
11320 Some(Value::String(s)) => s.clone(),
11321 _ => return Err(RuntimeError::new("PathBuf has no path field")),
11322 };
11323 return Ok(Value::Variant {
11325 enum_name: "Option".to_string(),
11326 variant_name: "Some".to_string(),
11327 fields: Some(Rc::new(vec![Value::String(path)])),
11328 });
11329 }
11330 "to_string_lossy" => {
11331 let path = match fields.borrow().get("path") {
11332 Some(Value::String(s)) => s.clone(),
11333 _ => return Err(RuntimeError::new("PathBuf has no path field")),
11334 };
11335 return Ok(Value::String(path));
11336 }
11337 "join" => {
11338 if arg_values.is_empty() {
11340 return Err(RuntimeError::new("join expects 1 argument"));
11341 }
11342 let base = match fields.borrow().get("path") {
11343 Some(Value::String(s)) => s.to_string(),
11344 _ => return Err(RuntimeError::new("PathBuf has no path field")),
11345 };
11346 let component = match &arg_values[0] {
11347 Value::String(s) => s.to_string(),
11348 Value::Struct { name: n, fields: f }
11349 if n == "PathBuf" || n == "Path" =>
11350 {
11351 match f.borrow().get("path") {
11352 Some(Value::String(s)) => s.to_string(),
11353 _ => {
11354 return Err(RuntimeError::new(
11355 "PathBuf has no path field",
11356 ))
11357 }
11358 }
11359 }
11360 _ => {
11361 return Err(RuntimeError::new("join expects string or PathBuf"))
11362 }
11363 };
11364 let joined = std::path::Path::new(&base).join(&component);
11365 let mut new_fields = HashMap::new();
11366 new_fields.insert(
11367 "path".to_string(),
11368 Value::String(Rc::new(joined.to_string_lossy().to_string())),
11369 );
11370 return Ok(Value::Struct {
11371 name: "PathBuf".to_string(),
11372 fields: Rc::new(RefCell::new(new_fields)),
11373 });
11374 }
11375 "display" => {
11376 let path = match fields.borrow().get("path") {
11377 Some(Value::String(s)) => s.clone(),
11378 _ => return Err(RuntimeError::new("PathBuf has no path field")),
11379 };
11380 return Ok(Value::String(path));
11381 }
11382 "to_path_buf" => {
11383 return Ok(recv.clone());
11385 }
11386 _ => {}
11387 }
11388 }
11389
11390 if name == "OsStr" {
11392 match method.name.as_str() {
11393 "to_str" => {
11394 let val = match fields.borrow().get("value") {
11395 Some(Value::String(s)) => s.clone(),
11396 _ => return Err(RuntimeError::new("OsStr has no value field")),
11397 };
11398 return Ok(Value::Variant {
11399 enum_name: "Option".to_string(),
11400 variant_name: "Some".to_string(),
11401 fields: Some(Rc::new(vec![Value::String(val)])),
11402 });
11403 }
11404 "to_string_lossy" => {
11405 let val = match fields.borrow().get("value") {
11406 Some(Value::String(s)) => s.clone(),
11407 _ => return Err(RuntimeError::new("OsStr has no value field")),
11408 };
11409 return Ok(Value::String(val));
11410 }
11411 "to_lowercase" => {
11412 let val = match fields.borrow().get("value") {
11413 Some(Value::String(s)) => s.to_lowercase(),
11414 _ => return Err(RuntimeError::new("OsStr has no value field")),
11415 };
11416 return Ok(Value::String(Rc::new(val)));
11417 }
11418 "as_str" => {
11419 let val = match fields.borrow().get("value") {
11420 Some(Value::String(s)) => s.clone(),
11421 _ => return Err(RuntimeError::new("OsStr has no value field")),
11422 };
11423 return Ok(Value::String(val));
11424 }
11425 _ => {}
11426 }
11427 }
11428
11429 if name == "DirEntry" {
11431 match method.name.as_str() {
11432 "path" => {
11433 let path = match fields.borrow().get("path") {
11434 Some(Value::String(s)) => s.clone(),
11435 _ => return Err(RuntimeError::new("DirEntry has no path field")),
11436 };
11437 let mut path_fields = HashMap::new();
11438 path_fields.insert("path".to_string(), Value::String(path));
11439 return Ok(Value::Struct {
11440 name: "PathBuf".to_string(),
11441 fields: Rc::new(RefCell::new(path_fields)),
11442 });
11443 }
11444 "file_name" => {
11445 let path = match fields.borrow().get("path") {
11446 Some(Value::String(s)) => s.to_string(),
11447 _ => return Err(RuntimeError::new("DirEntry has no path field")),
11448 };
11449 let fname = std::path::Path::new(&path)
11450 .file_name()
11451 .map(|f| f.to_string_lossy().to_string())
11452 .unwrap_or_default();
11453 let mut fname_fields = HashMap::new();
11454 fname_fields.insert("value".to_string(), Value::String(Rc::new(fname)));
11455 return Ok(Value::Struct {
11456 name: "OsStr".to_string(),
11457 fields: Rc::new(RefCell::new(fname_fields)),
11458 });
11459 }
11460 _ => {}
11461 }
11462 }
11463
11464 if name == "Map" {
11466 match method.name.as_str() {
11467 "get" => {
11468 if arg_values.len() != 1 {
11470 return Err(RuntimeError::new("Map.get expects 1 argument"));
11471 }
11472 let key = match &arg_values[0] {
11473 Value::String(s) => s.to_string(),
11474 Value::Int(n) => n.to_string(),
11475 other => format!("{:?}", other),
11476 };
11477 if let Some(val) = fields.borrow().get(&key) {
11478 return Ok(val.clone());
11479 }
11480 return Ok(Value::Null);
11481 }
11482 "insert" => {
11483 if arg_values.len() != 2 {
11485 return Err(RuntimeError::new("Map.insert expects 2 arguments"));
11486 }
11487 let key = match &arg_values[0] {
11488 Value::String(s) => s.to_string(),
11489 Value::Int(n) => n.to_string(),
11490 other => format!("{:?}", other),
11491 };
11492 crate::sigil_debug!(
11493 "DEBUG Map.insert: key='{}', value={}",
11494 key,
11495 arg_values[1]
11496 );
11497 fields.borrow_mut().insert(key, arg_values[1].clone());
11498 return Ok(Value::Null);
11499 }
11500 "contains_key" => {
11501 if arg_values.len() != 1 {
11502 return Err(RuntimeError::new(
11503 "Map.contains_key expects 1 argument",
11504 ));
11505 }
11506 let key = match &arg_values[0] {
11507 Value::String(s) => s.to_string(),
11508 Value::Int(n) => n.to_string(),
11509 other => format!("{:?}", other),
11510 };
11511 return Ok(Value::Bool(fields.borrow().contains_key(&key)));
11512 }
11513 "len" => {
11514 return Ok(Value::Int(fields.borrow().len() as i64));
11515 }
11516 "is_empty" => {
11517 return Ok(Value::Bool(fields.borrow().is_empty()));
11518 }
11519 "keys" => {
11520 let keys: Vec<Value> = fields
11521 .borrow()
11522 .keys()
11523 .map(|k| Value::String(Rc::new(k.clone())))
11524 .collect();
11525 return Ok(Value::Array(Rc::new(RefCell::new(keys))));
11526 }
11527 "values" => {
11528 let vals: Vec<Value> = fields.borrow().values().cloned().collect();
11529 return Ok(Value::Array(Rc::new(RefCell::new(vals))));
11530 }
11531 "clone" => {
11532 return Ok(recv.clone());
11533 }
11534 _ => {}
11535 }
11536 }
11537
11538 if name == "HyperLogLog" {
11540 match method.name.as_str() {
11541 "insert" => {
11542 if arg_values.len() != 1 {
11544 return Err(RuntimeError::new(
11545 "HyperLogLog.insert expects 1 argument",
11546 ));
11547 }
11548 let hash = match &arg_values[0] {
11550 Value::String(s) => {
11551 use std::collections::hash_map::DefaultHasher;
11552 use std::hash::{Hash, Hasher};
11553 let mut hasher = DefaultHasher::new();
11554 s.hash(&mut hasher);
11555 hasher.finish()
11556 }
11557 Value::Int(n) => {
11558 use std::collections::hash_map::DefaultHasher;
11559 use std::hash::{Hash, Hasher};
11560 let mut hasher = DefaultHasher::new();
11561 n.hash(&mut hasher);
11562 hasher.finish()
11563 }
11564 other => {
11565 use std::collections::hash_map::DefaultHasher;
11566 use std::hash::{Hash, Hasher};
11567 let mut hasher = DefaultHasher::new();
11568 format!("{:?}", other).hash(&mut hasher);
11569 hasher.finish()
11570 }
11571 };
11572 let precision = match fields.borrow().get("__precision__") {
11574 Some(Value::Int(p)) => *p as u32,
11575 _ => 14,
11576 };
11577 let idx = (hash >> (64 - precision)) as usize;
11578 let remaining = hash << precision | (1 << (precision - 1));
11579 let leading_zeros = remaining.leading_zeros() + 1;
11580 if let Some(Value::Array(regs)) = fields.borrow().get("__registers__") {
11582 let mut regs_borrow = regs.borrow_mut();
11583 if idx < regs_borrow.len() {
11584 let current = match ®s_borrow[idx] {
11585 Value::Int(v) => *v as u32,
11586 _ => 0,
11587 };
11588 if leading_zeros > current {
11589 regs_borrow[idx] = Value::Int(leading_zeros as i64);
11590 }
11591 }
11592 }
11593 let count_val = fields.borrow().get("__count__").cloned();
11595 if let Some(Value::Int(c)) = count_val {
11596 fields
11597 .borrow_mut()
11598 .insert("__count__".to_string(), Value::Int(c + 1));
11599 }
11600 return Ok(Value::Null);
11601 }
11602 "count" => {
11603 if let Some(Value::Array(regs)) = fields.borrow().get("__registers__") {
11605 let regs_borrow = regs.borrow();
11606 let m = regs_borrow.len() as f64;
11607 let mut sum = 0.0;
11609 let mut zeros = 0;
11610 for reg in regs_borrow.iter() {
11611 let val = match reg {
11612 Value::Int(v) => *v as i32,
11613 _ => 0,
11614 };
11615 sum += 2.0_f64.powi(-val);
11616 if val == 0 {
11617 zeros += 1;
11618 }
11619 }
11620 let alpha = 0.7213 / (1.0 + 1.079 / m);
11622 let estimate = alpha * m * m / sum;
11623 let result = if estimate <= 2.5 * m && zeros > 0 {
11625 m * (m / zeros as f64).ln()
11626 } else {
11627 estimate
11628 };
11629 return Ok(Value::Int(result.round() as i64));
11630 }
11631 return Ok(Value::Int(0));
11632 }
11633 _ => {}
11634 }
11635 }
11636
11637 if name == "BloomFilter" {
11639 match method.name.as_str() {
11640 "insert" => {
11641 if arg_values.len() != 1 {
11642 return Err(RuntimeError::new(
11643 "BloomFilter.insert expects 1 argument",
11644 ));
11645 }
11646 let size = match fields.borrow().get("__size__") {
11647 Some(Value::Int(s)) => *s as usize,
11648 _ => 1024,
11649 };
11650 let num_hashes = match fields.borrow().get("__num_hashes__") {
11651 Some(Value::Int(n)) => *n as usize,
11652 _ => 3,
11653 };
11654 let base_hash = match &arg_values[0] {
11656 Value::String(s) => {
11657 use std::collections::hash_map::DefaultHasher;
11658 use std::hash::{Hash, Hasher};
11659 let mut hasher = DefaultHasher::new();
11660 s.hash(&mut hasher);
11661 hasher.finish()
11662 }
11663 Value::Int(n) => *n as u64,
11664 other => {
11665 use std::collections::hash_map::DefaultHasher;
11666 use std::hash::{Hash, Hasher};
11667 let mut hasher = DefaultHasher::new();
11668 format!("{:?}", other).hash(&mut hasher);
11669 hasher.finish()
11670 }
11671 };
11672 if let Some(Value::Array(bits)) = fields.borrow().get("__bits__") {
11674 let mut bits_borrow = bits.borrow_mut();
11675 for i in 0..num_hashes {
11676 let h = (base_hash
11677 .wrapping_add(i as u64 * base_hash.rotate_left(17)))
11678 % size as u64;
11679 bits_borrow[h as usize] = Value::Bool(true);
11680 }
11681 }
11682 return Ok(Value::Null);
11683 }
11684 "contains" => {
11685 if arg_values.len() != 1 {
11686 return Err(RuntimeError::new(
11687 "BloomFilter.contains expects 1 argument",
11688 ));
11689 }
11690 let size = match fields.borrow().get("__size__") {
11691 Some(Value::Int(s)) => *s as usize,
11692 _ => 1024,
11693 };
11694 let num_hashes = match fields.borrow().get("__num_hashes__") {
11695 Some(Value::Int(n)) => *n as usize,
11696 _ => 3,
11697 };
11698 let base_hash = match &arg_values[0] {
11699 Value::String(s) => {
11700 use std::collections::hash_map::DefaultHasher;
11701 use std::hash::{Hash, Hasher};
11702 let mut hasher = DefaultHasher::new();
11703 s.hash(&mut hasher);
11704 hasher.finish()
11705 }
11706 Value::Int(n) => *n as u64,
11707 other => {
11708 use std::collections::hash_map::DefaultHasher;
11709 use std::hash::{Hash, Hasher};
11710 let mut hasher = DefaultHasher::new();
11711 format!("{:?}", other).hash(&mut hasher);
11712 hasher.finish()
11713 }
11714 };
11715 if let Some(Value::Array(bits)) = fields.borrow().get("__bits__") {
11717 let bits_borrow = bits.borrow();
11718 for i in 0..num_hashes {
11719 let h = (base_hash
11720 .wrapping_add(i as u64 * base_hash.rotate_left(17)))
11721 % size as u64;
11722 match &bits_borrow[h as usize] {
11723 Value::Bool(true) => {}
11724 _ => return Ok(Value::Bool(false)),
11725 }
11726 }
11727 return Ok(Value::Bool(true));
11728 }
11729 return Ok(Value::Bool(false));
11730 }
11731 _ => {}
11732 }
11733 }
11734
11735 if name == "CountMinSketch" {
11737 match method.name.as_str() {
11738 "insert" => {
11739 if arg_values.len() != 1 {
11740 return Err(RuntimeError::new(
11741 "CountMinSketch.insert expects 1 argument",
11742 ));
11743 }
11744 let depth = match fields.borrow().get("__depth__") {
11745 Some(Value::Int(d)) => *d as usize,
11746 _ => 4,
11747 };
11748 let width = match fields.borrow().get("__width__") {
11749 Some(Value::Int(w)) => *w as usize,
11750 _ => 1024,
11751 };
11752 let base_hash = match &arg_values[0] {
11753 Value::String(s) => {
11754 use std::collections::hash_map::DefaultHasher;
11755 use std::hash::{Hash, Hasher};
11756 let mut hasher = DefaultHasher::new();
11757 s.hash(&mut hasher);
11758 hasher.finish()
11759 }
11760 Value::Int(n) => *n as u64,
11761 other => {
11762 use std::collections::hash_map::DefaultHasher;
11763 use std::hash::{Hash, Hasher};
11764 let mut hasher = DefaultHasher::new();
11765 format!("{:?}", other).hash(&mut hasher);
11766 hasher.finish()
11767 }
11768 };
11769 if let Some(Value::Array(counters)) = fields.borrow().get("__counters__") {
11771 let counters_borrow = counters.borrow();
11772 for i in 0..depth {
11773 let h = (base_hash.wrapping_add(i as u64 * 0x517cc1b727220a95))
11774 % width as u64;
11775 if let Value::Array(row) = &counters_borrow[i] {
11776 let mut row_borrow = row.borrow_mut();
11777 if let Value::Int(c) = &row_borrow[h as usize] {
11778 row_borrow[h as usize] = Value::Int(c + 1);
11779 }
11780 }
11781 }
11782 }
11783 return Ok(Value::Null);
11784 }
11785 "frequency" => {
11786 if arg_values.len() != 1 {
11787 return Err(RuntimeError::new(
11788 "CountMinSketch.frequency expects 1 argument",
11789 ));
11790 }
11791 let depth = match fields.borrow().get("__depth__") {
11792 Some(Value::Int(d)) => *d as usize,
11793 _ => 4,
11794 };
11795 let width = match fields.borrow().get("__width__") {
11796 Some(Value::Int(w)) => *w as usize,
11797 _ => 1024,
11798 };
11799 let base_hash = match &arg_values[0] {
11800 Value::String(s) => {
11801 use std::collections::hash_map::DefaultHasher;
11802 use std::hash::{Hash, Hasher};
11803 let mut hasher = DefaultHasher::new();
11804 s.hash(&mut hasher);
11805 hasher.finish()
11806 }
11807 Value::Int(n) => *n as u64,
11808 other => {
11809 use std::collections::hash_map::DefaultHasher;
11810 use std::hash::{Hash, Hasher};
11811 let mut hasher = DefaultHasher::new();
11812 format!("{:?}", other).hash(&mut hasher);
11813 hasher.finish()
11814 }
11815 };
11816 let mut min_count = i64::MAX;
11818 if let Some(Value::Array(counters)) = fields.borrow().get("__counters__") {
11819 let counters_borrow = counters.borrow();
11820 for i in 0..depth {
11821 let h = (base_hash.wrapping_add(i as u64 * 0x517cc1b727220a95))
11822 % width as u64;
11823 if let Value::Array(row) = &counters_borrow[i] {
11824 let row_borrow = row.borrow();
11825 if let Value::Int(c) = &row_borrow[h as usize] {
11826 if *c < min_count {
11827 min_count = *c;
11828 }
11829 }
11830 }
11831 }
11832 }
11833 return Ok(Value::Int(if min_count == i64::MAX {
11834 0
11835 } else {
11836 min_count
11837 }));
11838 }
11839 _ => {}
11840 }
11841 }
11842
11843 if name == "MerkleTree" {
11845 match method.name.as_str() {
11846 "insert" => {
11847 if arg_values.len() != 1 {
11848 return Err(RuntimeError::new(
11849 "MerkleTree.insert expects 1 argument",
11850 ));
11851 }
11852 let data = match &arg_values[0] {
11854 Value::String(s) => s.as_bytes().to_vec(),
11855 Value::Int(n) => n.to_le_bytes().to_vec(),
11856 other => format!("{:?}", other).into_bytes(),
11857 };
11858 use std::collections::hash_map::DefaultHasher;
11859 use std::hash::{Hash, Hasher};
11860 let mut hasher = DefaultHasher::new();
11861 data.hash(&mut hasher);
11862 let leaf_hash = format!("{:016x}", hasher.finish());
11863 if let Some(Value::Array(leaves)) = fields.borrow().get("_leaves") {
11864 leaves.borrow_mut().push(Value::String(Rc::new(leaf_hash)));
11865 }
11866 if let Some(Value::Array(leaves)) = fields.borrow().get("_leaves") {
11868 let leaves_borrow = leaves.borrow();
11869 let combined: String = leaves_borrow
11870 .iter()
11871 .filter_map(|v| match v {
11872 Value::String(s) => Some(s.to_string()),
11873 _ => None,
11874 })
11875 .collect();
11876 let mut root_hasher = DefaultHasher::new();
11877 combined.hash(&mut root_hasher);
11878 let root = format!("{:016x}", root_hasher.finish());
11879 fields
11880 .borrow_mut()
11881 .insert("_root".to_string(), Value::String(Rc::new(root)));
11882 }
11883 return Ok(Value::Null);
11884 }
11885 "verify" => {
11886 use std::collections::hash_map::DefaultHasher;
11888 use std::hash::{Hash, Hasher};
11889 if let (Some(Value::Array(leaves)), Some(Value::String(root))) = (
11890 fields.borrow().get("_leaves").cloned(),
11891 fields.borrow().get("_root").cloned(),
11892 ) {
11893 let leaves_borrow = leaves.borrow();
11894 let combined: String = leaves_borrow
11895 .iter()
11896 .filter_map(|v| match v {
11897 Value::String(s) => Some(s.to_string()),
11898 _ => None,
11899 })
11900 .collect();
11901 let mut hasher = DefaultHasher::new();
11902 combined.hash(&mut hasher);
11903 let computed_root = format!("{:016x}", hasher.finish());
11904 return Ok(Value::Bool(*root == computed_root));
11905 }
11906 return Ok(Value::Bool(false));
11907 }
11908 "root" => {
11909 if let Some(root) = fields.borrow().get("_root").cloned() {
11911 return Ok(root);
11912 }
11913 return Ok(Value::Null);
11914 }
11915 "prove_inclusion" => {
11916 if arg_values.len() != 1 {
11918 return Err(RuntimeError::new(
11919 "MerkleTree.prove_inclusion expects 1 argument",
11920 ));
11921 }
11922 let idx = match &arg_values[0] {
11923 Value::Int(i) => *i as usize,
11924 _ => {
11925 return Err(RuntimeError::new(
11926 "prove_inclusion requires integer index",
11927 ))
11928 }
11929 };
11930 let mut proof_fields = std::collections::HashMap::new();
11932 proof_fields.insert("_index".to_string(), Value::Int(idx as i64));
11933 if let Some(root) = fields.borrow().get("_root").cloned() {
11934 proof_fields.insert("_root".to_string(), root);
11935 }
11936 if let Some(leaves) = fields.borrow().get("_leaves").cloned() {
11937 proof_fields.insert("_leaves".to_string(), leaves);
11938 }
11939 proof_fields.insert("_valid".to_string(), Value::Bool(true));
11940 return Ok(Value::Struct {
11941 name: "MerkleProof".to_string(),
11942 fields: Rc::new(RefCell::new(proof_fields)),
11943 });
11944 }
11945 _ => {}
11946 }
11947 }
11948
11949 if name == "MerkleProof" {
11951 match method.name.as_str() {
11952 "verify" => {
11953 if let Some(Value::Bool(valid)) = fields.borrow().get("_valid") {
11955 return Ok(Value::Bool(*valid));
11956 }
11957 return Ok(Value::Bool(false));
11958 }
11959 _ => {}
11960 }
11961 }
11962
11963 if name == "UntrustedData" {
11965 match method.name.as_str() {
11966 "verify" => {
11967 fields
11969 .borrow_mut()
11970 .insert("_verified".to_string(), Value::Bool(true));
11971 if let Some(val) = fields.borrow().get("value").cloned() {
11973 return Ok(val);
11974 }
11975 return Ok(Value::Bool(true));
11976 }
11977 _ => {}
11978 }
11979 }
11980
11981 if name == "QHCompressed" {
11983 match method.name.as_str() {
11984 "size" => {
11985 if let Some(Value::Int(size)) = fields.borrow().get("_compressed_size")
11986 {
11987 return Ok(Value::Int(*size));
11988 }
11989 return Ok(Value::Int(1)); }
11991 _ => {}
11992 }
11993 }
11994
11995 if name == "Superposition" {
11997 match method.name.as_str() {
11998 "observe" => {
11999 if let Some(Value::Array(values)) = fields.borrow().get("_values") {
12002 let values_borrow = values.borrow();
12003 if !values_borrow.is_empty() {
12004 return Ok(values_borrow[0].clone());
12007 }
12008 }
12009 if let Some(Value::Array(states)) = fields.borrow().get("states") {
12011 let states_borrow = states.borrow();
12012 if !states_borrow.is_empty() {
12013 return Ok(states_borrow[0].clone());
12014 }
12015 }
12016 return Ok(Value::Null);
12017 }
12018 _ => {}
12019 }
12020 }
12021
12022 {
12025 let user_method_name = format!("{}·{}", name, method.name);
12026 let user_fn = self.globals.borrow().get(&user_method_name).map(|v| v.clone());
12027 if let Some(Value::Function(func)) = user_fn {
12028 let func = Self::wrap_with_const_generics(&func, fields);
12029 let old_self_type = self.current_self_type.take();
12030 self.current_self_type = Some(name.clone());
12031
12032 let reordered = if func.params.len() > 1 {
12034 Self::reorder_named_args(&func.params[1..].to_vec(), arg_entries.clone())?
12035 } else {
12036 arg_values.clone()
12037 };
12038 let self_val = Value::Struct {
12039 name: name.clone(),
12040 fields: fields.clone(),
12041 };
12042 let mut all_args = vec![self_val];
12043 all_args.extend(reordered);
12044 let result = self.call_function(&func, all_args);
12045
12046 self.current_self_type = old_self_type;
12047 return result;
12048 }
12049 }
12050
12051 if name == "ReLU" && method.name == "forward" {
12053 if let Some(input) = arg_values.first() {
12054 if let Value::Struct {
12056 name: tensor_name,
12057 fields: tensor_fields,
12058 } = input
12059 {
12060 if tensor_name == "Tensor" {
12061 let tensor_ref = tensor_fields.borrow();
12062 let shape = tensor_ref.get("shape").cloned();
12063 let data: Vec<f64> = match tensor_ref.get("data") {
12064 Some(Value::Array(arr)) => arr
12065 .borrow()
12066 .iter()
12067 .map(|v| match v {
12068 Value::Float(f) => *f,
12069 Value::Int(n) => *n as f64,
12070 _ => 0.0,
12071 })
12072 .collect(),
12073 _ => vec![],
12074 };
12075 drop(tensor_ref);
12076
12077 let relu_data: Vec<Value> = data
12079 .iter()
12080 .map(|x| Value::Float(if *x > 0.0 { *x } else { 0.0 }))
12081 .collect();
12082
12083 let mut result_fields = HashMap::new();
12084 if let Some(s) = shape {
12085 result_fields.insert("shape".to_string(), s);
12086 }
12087 result_fields.insert(
12088 "data".to_string(),
12089 Value::Array(Rc::new(RefCell::new(relu_data))),
12090 );
12091 result_fields
12092 .insert("requires_grad".to_string(), Value::Bool(false));
12093 return Ok(Value::Struct {
12094 name: "Tensor".to_string(),
12095 fields: Rc::new(RefCell::new(result_fields)),
12096 });
12097 }
12098 }
12099 }
12100 return Err(RuntimeError::new("ReLU.forward expects a Tensor"));
12101 }
12102
12103 if name == "Sequential" && method.name == "forward" {
12105 if let Some(input) = arg_values.first().cloned() {
12106 let layers = fields.borrow().get("layers").cloned();
12107 if let Some(Value::Array(layers_arr)) = layers {
12108 let mut current = input;
12109 for layer in layers_arr.borrow().iter() {
12110 if let Value::Struct {
12111 name: layer_name,
12112 fields: layer_fields,
12113 } = layer
12114 {
12115 if layer_name == "ReLU" {
12117 if let Value::Struct {
12119 name: tn,
12120 fields: tf,
12121 } = ¤t
12122 {
12123 if tn == "Tensor" {
12124 let tf_ref = tf.borrow();
12125 let shape = tf_ref.get("shape").cloned();
12126 let data: Vec<f64> = match tf_ref.get("data") {
12127 Some(Value::Array(arr)) => arr
12128 .borrow()
12129 .iter()
12130 .map(|v| match v {
12131 Value::Float(f) => *f,
12132 Value::Int(n) => *n as f64,
12133 _ => 0.0,
12134 })
12135 .collect(),
12136 _ => vec![],
12137 };
12138 drop(tf_ref);
12139
12140 let relu_data: Vec<Value> = data
12141 .iter()
12142 .map(|x| {
12143 Value::Float(if *x > 0.0 {
12144 *x
12145 } else {
12146 0.0
12147 })
12148 })
12149 .collect();
12150
12151 let mut result_fields = HashMap::new();
12152 if let Some(s) = shape {
12153 result_fields.insert("shape".to_string(), s);
12154 }
12155 result_fields.insert(
12156 "data".to_string(),
12157 Value::Array(Rc::new(RefCell::new(relu_data))),
12158 );
12159 result_fields.insert(
12160 "requires_grad".to_string(),
12161 Value::Bool(false),
12162 );
12163 current = Value::Struct {
12164 name: "Tensor".to_string(),
12165 fields: Rc::new(RefCell::new(result_fields)),
12166 };
12167 }
12168 }
12169 } else if layer_name == "Linear" {
12170 let layer_ref = layer_fields.borrow();
12172 let weight = layer_ref.get("weight").cloned();
12173 let bias = layer_ref.get("bias").cloned();
12174 drop(layer_ref);
12175
12176 if let (Some(w), Some(b)) = (weight, bias) {
12177 if let (
12180 Value::Struct {
12181 fields: w_fields, ..
12182 },
12183 Value::Struct {
12184 fields: x_fields, ..
12185 },
12186 Value::Struct {
12187 fields: b_fields, ..
12188 },
12189 ) = (&w, ¤t, &b)
12190 {
12191 let w_shape: Vec<usize> =
12193 match w_fields.borrow().get("shape") {
12194 Some(Value::Array(arr)) => arr
12195 .borrow()
12196 .iter()
12197 .filter_map(|v| match v {
12198 Value::Int(n) => Some(*n as usize),
12199 _ => None,
12200 })
12201 .collect(),
12202 _ => vec![],
12203 };
12204 let w_data: Vec<f64> =
12205 match w_fields.borrow().get("data") {
12206 Some(Value::Array(arr)) => arr
12207 .borrow()
12208 .iter()
12209 .filter_map(|v| match v {
12210 Value::Float(f) => Some(*f),
12211 Value::Int(n) => Some(*n as f64),
12212 _ => None,
12213 })
12214 .collect(),
12215 _ => vec![],
12216 };
12217
12218 let x_data: Vec<f64> =
12220 match x_fields.borrow().get("data") {
12221 Some(Value::Array(arr)) => arr
12222 .borrow()
12223 .iter()
12224 .filter_map(|v| match v {
12225 Value::Float(f) => Some(*f),
12226 Value::Int(n) => Some(*n as f64),
12227 _ => None,
12228 })
12229 .collect(),
12230 _ => vec![],
12231 };
12232
12233 let b_data: Vec<f64> =
12235 match b_fields.borrow().get("data") {
12236 Some(Value::Array(arr)) => arr
12237 .borrow()
12238 .iter()
12239 .filter_map(|v| match v {
12240 Value::Float(f) => Some(*f),
12241 Value::Int(n) => Some(*n as f64),
12242 _ => None,
12243 })
12244 .collect(),
12245 _ => vec![],
12246 };
12247
12248 let out_size =
12250 if w_shape.len() >= 2 { w_shape[0] } else { 1 };
12251 let in_size = if w_shape.len() >= 2 {
12252 w_shape[1]
12253 } else if !w_shape.is_empty() {
12254 w_shape[0]
12255 } else {
12256 1
12257 };
12258
12259 let mut result = vec![0.0; out_size];
12260 for i in 0..out_size {
12261 let mut sum = 0.0;
12262 for j in 0..in_size {
12263 if i * in_size + j < w_data.len()
12264 && j < x_data.len()
12265 {
12266 sum +=
12267 w_data[i * in_size + j] * x_data[j];
12268 }
12269 }
12270 if i < b_data.len() {
12272 sum += b_data[i];
12273 }
12274 result[i] = sum;
12275 }
12276
12277 let mut result_fields = HashMap::new();
12279 result_fields.insert(
12280 "shape".to_string(),
12281 Value::Array(Rc::new(RefCell::new(vec![
12282 Value::Int(out_size as i64),
12283 ]))),
12284 );
12285 result_fields.insert(
12286 "data".to_string(),
12287 Value::Array(Rc::new(RefCell::new(
12288 result
12289 .into_iter()
12290 .map(Value::Float)
12291 .collect(),
12292 ))),
12293 );
12294 result_fields.insert(
12295 "requires_grad".to_string(),
12296 Value::Bool(false),
12297 );
12298 current = Value::Struct {
12299 name: "Tensor".to_string(),
12300 fields: Rc::new(RefCell::new(result_fields)),
12301 };
12302 }
12303 }
12304 }
12305 }
12306 }
12307 return Ok(current);
12308 }
12309 }
12310 return Err(RuntimeError::new("Sequential.forward expects input tensor"));
12311 }
12312
12313 let qualified_name = format!("{}·{}", name, method.name);
12314
12315 if name == "Parser" && (method.name == "parse_file" || method.name == "read_source")
12317 {
12318 crate::sigil_debug!("DEBUG Parser method call: {}", qualified_name);
12319 for (i, arg) in arg_values.iter().enumerate() {
12320 crate::sigil_debug!(" arg_value[{}] = {:?}", i, arg);
12321 }
12322 }
12323
12324 if name == "Lexer" {
12326 if method.name == "lex_ident_or_keyword" {
12328 for (i, arg) in arg_values.iter().enumerate() {
12329 let unwrapped = Self::unwrap_all(arg);
12330 if let Value::Char(c) = &unwrapped {
12331 crate::sigil_debug!(
12332 "DEBUG Lexer·lex_ident_or_keyword arg[{}]='{}'",
12333 i,
12334 c
12335 );
12336 }
12337 }
12338 }
12339 crate::sigil_debug!("DEBUG Lexer method call: {}", qualified_name);
12340 }
12341 for arg in &arg_values {
12343 let unwrapped = Self::unwrap_all(arg);
12344 if let Value::String(s) = &unwrapped {
12345 if **s == "fn" {
12346 crate::sigil_debug!(
12347 "DEBUG struct method with 'fn': {} recv_name={}",
12348 method.name,
12349 name
12350 );
12351 }
12352 }
12353 }
12354
12355 let func = self
12356 .globals
12357 .borrow()
12358 .get(&qualified_name)
12359 .map(|v| v.clone());
12360 if let Some(func) = func {
12361 if let Value::Function(f) = func {
12362 let f = Self::wrap_with_const_generics(&f, fields);
12363 let old_self_type = self.current_self_type.take();
12365 self.current_self_type = Some(name.clone());
12366
12367 let reordered = if f.params.len() > 1 {
12370 Self::reorder_named_args(&f.params[1..].to_vec(), arg_entries.clone())?
12371 } else {
12372 arg_values.clone()
12373 };
12374 let mut all_args = vec![recv.clone()];
12375 all_args.extend(reordered);
12376 let result = self.call_function(&f, all_args);
12377
12378 self.current_self_type = old_self_type;
12380 return result;
12381 } else if let Value::BuiltIn(b) = func {
12382 let mut all_args = vec![recv.clone()];
12383 all_args.extend(arg_values.clone());
12384 return (b.func)(self, all_args);
12385 }
12386 }
12387
12388 if name == "Self" {
12390 let field_names: Vec<String> = fields.borrow().keys().cloned().collect();
12392
12393 for (type_name, type_def) in &self.types {
12395 if let TypeDef::Struct(struct_def) = type_def {
12396 let def_fields: Vec<String> = match &struct_def.fields {
12398 crate::ast::StructFields::Named(fs) => {
12399 fs.iter().map(|f| f.name.name.clone()).collect()
12400 }
12401 _ => continue,
12402 };
12403
12404 let matches = field_names.iter().all(|f| def_fields.contains(f));
12406 if matches {
12407 let qualified_name = format!("{}·{}", type_name, method.name);
12408 let func = self
12409 .globals
12410 .borrow()
12411 .get(&qualified_name)
12412 .map(|v| v.clone());
12413 if let Some(func) = func {
12414 if let Value::Function(f) = func {
12415 let f = Self::wrap_with_const_generics(&f, fields);
12416 let old_self_type = self.current_self_type.take();
12418 self.current_self_type = Some(type_name.clone());
12419
12420 let reordered = if f.params.len() > 1 {
12422 Self::reorder_named_args(
12423 &f.params[1..].to_vec(),
12424 arg_entries.clone(),
12425 )?
12426 } else {
12427 arg_values.clone()
12428 };
12429 let mut all_args = vec![recv.clone()];
12430 all_args.extend(reordered);
12431 let result = self.call_function(&f, all_args);
12432
12433 self.current_self_type = old_self_type;
12435 return result;
12436 } else if let Value::BuiltIn(b) = func {
12437 let mut all_args = vec![recv.clone()];
12438 all_args.extend(arg_values.clone());
12439 return (b.func)(self, all_args);
12440 }
12441 }
12442 }
12443 }
12444 }
12445 }
12446
12447 Err(RuntimeError::new(format!(
12449 "no method '{}' on struct '{}'",
12450 method.name, name
12451 )))
12452 }
12453 (
12455 Value::Variant {
12456 enum_name,
12457 variant_name,
12458 fields,
12459 },
12460 _,
12461 ) => {
12462 if enum_name == "Option" {
12464 match method.name.as_str() {
12465 "cloned" => {
12466 return Ok(recv.clone());
12469 }
12470 "is_some" => {
12471 return Ok(Value::Bool(variant_name == "Some"));
12472 }
12473 "is_none" => {
12474 return Ok(Value::Bool(variant_name == "None"));
12475 }
12476 "unwrap" => {
12477 crate::sigil_debug!(
12478 "DEBUG Option.unwrap: variant={}, fields={:?}",
12479 variant_name,
12480 fields
12481 );
12482 if variant_name == "Some" {
12483 if let Some(f) = fields {
12484 let result = f.first().cloned().unwrap_or(Value::Null);
12485 crate::sigil_debug!(
12486 "DEBUG Option.unwrap: returning {:?}",
12487 result
12488 );
12489 return Ok(result);
12490 }
12491 }
12492 return Err(RuntimeError::new("unwrap on None"));
12493 }
12494 "unwrap_or" => {
12495 if variant_name == "Some" {
12496 if let Some(f) = fields {
12497 return Ok(f.first().cloned().unwrap_or(Value::Null));
12498 }
12499 }
12500 return Ok(arg_values.first().cloned().unwrap_or(Value::Null));
12501 }
12502 "map" => {
12503 if variant_name == "Some" {
12505 if let Some(f) = fields {
12506 if let Some(inner) = f.first() {
12507 if let Some(Value::Function(func)) = arg_values.first() {
12508 let result =
12509 self.call_function(func, vec![inner.clone()])?;
12510 return Ok(Value::Variant {
12511 enum_name: "Option".to_string(),
12512 variant_name: "Some".to_string(),
12513 fields: Some(Rc::new(vec![result])),
12514 });
12515 }
12516 }
12517 }
12518 }
12519 return Ok(Value::Variant {
12520 enum_name: "Option".to_string(),
12521 variant_name: "None".to_string(),
12522 fields: None,
12523 });
12524 }
12525 "and_then" => {
12526 crate::sigil_debug!(
12528 "DEBUG and_then: variant={}, has_fields={}, arg_count={}",
12529 variant_name,
12530 fields.is_some(),
12531 arg_values.len()
12532 );
12533 if let Some(arg) = arg_values.first() {
12534 crate::sigil_debug!(
12535 "DEBUG and_then: arg type = {:?}",
12536 std::mem::discriminant(arg)
12537 );
12538 }
12539 if variant_name == "Some" {
12540 if let Some(f) = fields {
12541 if let Some(inner) = f.first() {
12542 crate::sigil_debug!("DEBUG and_then: inner = {:?}", inner);
12543 if let Some(Value::Function(func)) = arg_values.first() {
12544 let result =
12545 self.call_function(func, vec![inner.clone()])?;
12546 crate::sigil_debug!(
12547 "DEBUG and_then: result = {:?}",
12548 result
12549 );
12550 return Ok(result);
12552 } else {
12553 crate::sigil_debug!(
12554 "DEBUG and_then: arg is not a Function!"
12555 );
12556 }
12557 }
12558 }
12559 }
12560 return Ok(Value::Variant {
12562 enum_name: "Option".to_string(),
12563 variant_name: "None".to_string(),
12564 fields: None,
12565 });
12566 }
12567 "or_else" => {
12568 if variant_name == "Some" {
12570 return Ok(recv.clone());
12572 }
12573 if let Some(Value::Function(func)) = arg_values.first() {
12575 return self.call_function(func, vec![]);
12576 }
12577 return Ok(recv.clone());
12578 }
12579 "ok_or" | "ok_or_else" => {
12580 if variant_name == "Some" {
12582 if let Some(f) = fields {
12583 if let Some(inner) = f.first() {
12584 return Ok(Value::Variant {
12585 enum_name: "Result".to_string(),
12586 variant_name: "Ok".to_string(),
12587 fields: Some(Rc::new(vec![inner.clone()])),
12588 });
12589 }
12590 }
12591 }
12592 let err_val = arg_values
12594 .first()
12595 .cloned()
12596 .unwrap_or(Value::String(Rc::new("None".to_string())));
12597 return Ok(Value::Variant {
12598 enum_name: "Result".to_string(),
12599 variant_name: "Err".to_string(),
12600 fields: Some(Rc::new(vec![err_val])),
12601 });
12602 }
12603 _ => {}
12604 }
12605 }
12606 if enum_name == "Result" {
12608 match method.name.as_str() {
12609 "is_ok" => {
12610 return Ok(Value::Bool(variant_name == "Ok"));
12611 }
12612 "is_err" => {
12613 return Ok(Value::Bool(variant_name == "Err"));
12614 }
12615 "ok" => {
12616 if variant_name == "Ok" {
12619 let inner = fields
12620 .as_ref()
12621 .and_then(|f| f.first().cloned())
12622 .unwrap_or(Value::Null);
12623 return Ok(Value::Variant {
12624 enum_name: "Option".to_string(),
12625 variant_name: "Some".to_string(),
12626 fields: Some(Rc::new(vec![inner])),
12627 });
12628 }
12629 return Ok(Value::Variant {
12630 enum_name: "Option".to_string(),
12631 variant_name: "None".to_string(),
12632 fields: None,
12633 });
12634 }
12635 "err" => {
12636 if variant_name == "Err" {
12639 let inner = fields
12640 .as_ref()
12641 .and_then(|f| f.first().cloned())
12642 .unwrap_or(Value::Null);
12643 return Ok(Value::Variant {
12644 enum_name: "Option".to_string(),
12645 variant_name: "Some".to_string(),
12646 fields: Some(Rc::new(vec![inner])),
12647 });
12648 }
12649 return Ok(Value::Variant {
12650 enum_name: "Option".to_string(),
12651 variant_name: "None".to_string(),
12652 fields: None,
12653 });
12654 }
12655 "unwrap" => {
12656 if variant_name == "Ok" {
12657 if let Some(f) = fields {
12658 return Ok(f.first().cloned().unwrap_or(Value::Null));
12659 }
12660 }
12661 return Err(RuntimeError::new("unwrap on Err"));
12662 }
12663 "unwrap_or" => {
12664 if variant_name == "Ok" {
12665 if let Some(f) = fields {
12666 return Ok(f.first().cloned().unwrap_or(Value::Null));
12667 }
12668 }
12669 return Ok(arg_values.first().cloned().unwrap_or(Value::Null));
12670 }
12671 "map" => {
12672 if variant_name == "Ok" {
12674 if let Some(Value::Function(f)) = arg_values.first() {
12675 let inner = fields
12676 .as_ref()
12677 .and_then(|f| f.first().cloned())
12678 .unwrap_or(Value::Null);
12679 let result = self.call_function(f, vec![inner])?;
12680 return Ok(Value::Variant {
12681 enum_name: "Result".to_string(),
12682 variant_name: "Ok".to_string(),
12683 fields: Some(Rc::new(vec![result])),
12684 });
12685 }
12686 }
12687 return Ok(recv.clone());
12689 }
12690 "map_err" => {
12691 if variant_name == "Err" {
12693 if let Some(Value::Function(f)) = arg_values.first() {
12694 let inner = fields
12695 .as_ref()
12696 .and_then(|f| f.first().cloned())
12697 .unwrap_or(Value::Null);
12698 let result = self.call_function(f, vec![inner])?;
12699 return Ok(Value::Variant {
12700 enum_name: "Result".to_string(),
12701 variant_name: "Err".to_string(),
12702 fields: Some(Rc::new(vec![result])),
12703 });
12704 }
12705 }
12706 return Ok(recv.clone());
12708 }
12709 "and_then" => {
12710 if variant_name == "Ok" {
12712 if let Some(Value::Function(f)) = arg_values.first() {
12713 let inner = fields
12714 .as_ref()
12715 .and_then(|f| f.first().cloned())
12716 .unwrap_or(Value::Null);
12717 return self.call_function(f, vec![inner]);
12718 }
12719 }
12720 return Ok(recv.clone());
12722 }
12723 _ => {}
12724 }
12725 }
12726 crate::sigil_debug!(
12728 "DEBUG variant method call: enum_name={}, variant_name={}, method={}",
12729 enum_name,
12730 variant_name,
12731 method.name
12732 );
12733
12734 if enum_name == "Type" {
12736 match method.name.as_str() {
12737 "is_never" => {
12738 return Ok(Value::Bool(variant_name == "Never"));
12740 }
12741 "to_string" => {
12742 let type_str = match variant_name.as_str() {
12744 "Bool" => "bool".to_string(),
12745 "Int" => "i64".to_string(),
12746 "Float" => "f64".to_string(),
12747 "Str" => "str".to_string(),
12748 "Char" => "char".to_string(),
12749 "Unit" => "()".to_string(),
12750 "Never" => "!".to_string(),
12751 "Error" => "<error>".to_string(),
12752 other => format!("Type::{}", other),
12753 };
12754 return Ok(Value::String(Rc::new(type_str)));
12755 }
12756 _ => {}
12757 }
12758 }
12759
12760 if enum_name == "Pattern" {
12761 match method.name.as_str() {
12762 "evidentiality" => {
12763 if variant_name == "Ident" {
12765 if let Some(f) = fields {
12766 for field_val in f.iter() {
12769 if let Value::Struct { fields: inner, .. } = field_val {
12770 if let Some(ev) = inner.borrow().get("evidentiality") {
12771 return Ok(ev.clone());
12772 }
12773 }
12774 }
12775 if f.len() > 2 {
12777 return Ok(f[2].clone());
12778 }
12779 }
12780 }
12781 return Ok(Value::Null);
12783 }
12784 "name" => {
12785 if variant_name == "Ident" {
12787 if let Some(f) = fields {
12788 for field_val in f.iter() {
12789 if let Value::Struct { fields: inner, .. } = field_val {
12790 if let Some(n) = inner.borrow().get("name") {
12791 return Ok(n.clone());
12792 }
12793 }
12794 }
12795 if let Some(n) = f.first() {
12797 return Ok(n.clone());
12798 }
12799 }
12800 }
12801 return Ok(Value::Null);
12802 }
12803 "mutable" => {
12804 if variant_name == "Ident" {
12806 if let Some(f) = fields {
12807 for field_val in f.iter() {
12808 if let Value::Struct { fields: inner, .. } = field_val {
12809 if let Some(m) = inner.borrow().get("mutable") {
12810 return Ok(m.clone());
12811 }
12812 }
12813 }
12814 if f.len() > 1 {
12816 return Ok(f[1].clone());
12817 }
12818 }
12819 }
12820 return Ok(Value::Bool(false));
12821 }
12822 _ => {}
12823 }
12824 }
12825 if method.name == "clone" {
12827 return Ok(recv.clone());
12828 }
12829
12830 let qualified_name = format!("{}·{}", enum_name, method.name);
12831 let func = self
12832 .globals
12833 .borrow()
12834 .get(&qualified_name)
12835 .map(|v| v.clone());
12836 if let Some(func) = func {
12837 if let Value::Function(f) = func {
12838 let mut all_args = vec![recv.clone()];
12839 all_args.extend(arg_values.clone());
12840 return self.call_function(&f, all_args);
12841 } else if let Value::BuiltIn(b) = func {
12842 let mut all_args = vec![recv.clone()];
12843 all_args.extend(arg_values.clone());
12844 return (b.func)(self, all_args);
12845 }
12846 }
12847 Err(RuntimeError::new(format!(
12849 "no method '{}' on enum '{}'",
12850 method.name, enum_name
12851 )))
12852 }
12853 (Value::Null, "len_utf8") => Ok(Value::Int(0)),
12855 (Value::Null, "is_ascii") => Ok(Value::Bool(false)),
12856 (Value::Null, "is_alphabetic") => Ok(Value::Bool(false)),
12857 (Value::Null, "is_alphanumeric") => Ok(Value::Bool(false)),
12858 (Value::Null, "is_numeric") | (Value::Null, "is_digit") => Ok(Value::Bool(false)),
12859 (Value::Null, "is_whitespace") => Ok(Value::Bool(false)),
12860 (Value::Null, "is_uppercase") => Ok(Value::Bool(false)),
12861 (Value::Null, "is_lowercase") => Ok(Value::Bool(false)),
12862 (Value::Null, "len") => Ok(Value::Int(0)),
12863 (Value::Null, "is_empty") => Ok(Value::Bool(true)),
12864 (Value::Null, "to_string") => Ok(Value::String(Rc::new("".to_string()))),
12865 (Value::Null, "clone") => Ok(Value::Null),
12866 (Value::Null, "is_some") => Ok(Value::Bool(false)),
12867 (Value::Null, "is_none") => Ok(Value::Bool(true)),
12868 (Value::Null, "unwrap_or") => {
12869 if arg_values.is_empty() {
12870 Ok(Value::Null)
12871 } else {
12872 Ok(arg_values[0].clone())
12873 }
12874 }
12875 (Value::Char(c), "unwrap_or") => Ok(Value::Char(*c)),
12877 (Value::Int(n), "unwrap_or") => Ok(Value::Int(*n)),
12878 (Value::Float(n), "unwrap_or") => Ok(Value::Float(*n)),
12879 (Value::String(s), "unwrap_or") => Ok(Value::String(s.clone())),
12880 (Value::Bool(b), "unwrap_or") => Ok(Value::Bool(*b)),
12881 (Value::Int(n), "to_string") | (Value::Int(n), "string") => {
12883 Ok(Value::String(Rc::new(n.to_string())))
12884 }
12885 (Value::Int(n), "abs") => Ok(Value::Int(n.abs())),
12886 (Value::Int(n), "to_float") | (Value::Int(n), "float") => Ok(Value::Float(*n as f64)),
12887 (Value::Int(n), "duration_since") => {
12888 let other_ns = match arg_values.first() {
12891 Some(Value::Int(i)) => *i,
12892 Some(Value::Struct { fields, .. }) => {
12893 let borrowed = fields.borrow();
12894 let secs = match borrowed.get("secs") {
12895 Some(Value::Int(s)) => *s,
12896 _ => 0,
12897 };
12898 let nanos = match borrowed.get("nanos") {
12899 Some(Value::Int(n)) => *n,
12900 _ => 0,
12901 };
12902 secs * 1_000_000_000 + nanos
12903 }
12904 _ => 0,
12905 };
12906 let diff_ns = n - other_ns;
12907 let mut fields = std::collections::HashMap::new();
12908 fields.insert("secs".to_string(), Value::Int(diff_ns / 1_000_000_000));
12909 fields.insert("nanos".to_string(), Value::Int(diff_ns % 1_000_000_000));
12910 Ok(Value::Variant {
12911 enum_name: "Result".to_string(),
12912 variant_name: "Ok".to_string(),
12913 fields: Some(Rc::new(vec![Value::Struct {
12914 name: "Duration".to_string(),
12915 fields: Rc::new(RefCell::new(fields)),
12916 }])),
12917 })
12918 }
12919 (Value::Float(n), "to_string") | (Value::Float(n), "string") => {
12921 Ok(Value::String(Rc::new(n.to_string())))
12922 }
12923 (Value::Float(n), "to_int") | (Value::Float(n), "int") => Ok(Value::Int(*n as i64)),
12924 (Value::Float(n), "abs") => Ok(Value::Float(n.abs())),
12926 (Value::Float(n), "exp") => Ok(Value::Float(n.exp())),
12927 (Value::Float(n), "exp2") => Ok(Value::Float(n.exp2())),
12928 (Value::Float(n), "ln") => Ok(Value::Float(n.ln())),
12929 (Value::Float(n), "log2") => Ok(Value::Float(n.log2())),
12930 (Value::Float(n), "log10") => Ok(Value::Float(n.log10())),
12931 (Value::Float(n), "sqrt") => Ok(Value::Float(n.sqrt())),
12932 (Value::Float(n), "cbrt") => Ok(Value::Float(n.cbrt())),
12933 (Value::Float(n), "sin") => Ok(Value::Float(n.sin())),
12934 (Value::Float(n), "cos") => Ok(Value::Float(n.cos())),
12935 (Value::Float(n), "tan") => Ok(Value::Float(n.tan())),
12936 (Value::Float(n), "asin") => Ok(Value::Float(n.asin())),
12937 (Value::Float(n), "acos") => Ok(Value::Float(n.acos())),
12938 (Value::Float(n), "atan") => Ok(Value::Float(n.atan())),
12939 (Value::Float(n), "sinh") => Ok(Value::Float(n.sinh())),
12940 (Value::Float(n), "cosh") => Ok(Value::Float(n.cosh())),
12941 (Value::Float(n), "tanh") => Ok(Value::Float(n.tanh())),
12942 (Value::Float(n), "asinh") => Ok(Value::Float(n.asinh())),
12943 (Value::Float(n), "acosh") => Ok(Value::Float(n.acosh())),
12944 (Value::Float(n), "atanh") => Ok(Value::Float(n.atanh())),
12945 (Value::Float(n), "floor") => Ok(Value::Float(n.floor())),
12946 (Value::Float(n), "ceil") => Ok(Value::Float(n.ceil())),
12947 (Value::Float(n), "round") => Ok(Value::Float(n.round())),
12948 (Value::Float(n), "trunc") => Ok(Value::Float(n.trunc())),
12949 (Value::Float(n), "fract") => Ok(Value::Float(n.fract())),
12950 (Value::Float(n), "signum") => Ok(Value::Float(n.signum())),
12951 (Value::Float(n), "is_nan") => Ok(Value::Bool(n.is_nan())),
12952 (Value::Float(n), "is_infinite") => Ok(Value::Bool(n.is_infinite())),
12953 (Value::Float(n), "is_finite") => Ok(Value::Bool(n.is_finite())),
12954 (Value::Float(n), "is_normal") => Ok(Value::Bool(n.is_normal())),
12955 (Value::Float(n), "to_bits") => Ok(Value::Int(n.to_bits() as i64)),
12956 (Value::Float(n), "powf") => {
12957 if arg_values.is_empty() {
12958 return Err(RuntimeError::new("powf requires 1 argument"));
12959 }
12960 let exp = match &arg_values[0] {
12961 Value::Float(f) => *f,
12962 Value::Int(i) => *i as f64,
12963 _ => return Err(RuntimeError::new("powf argument must be numeric")),
12964 };
12965 Ok(Value::Float(n.powf(exp)))
12966 }
12967 (Value::Float(n), "powi") => {
12968 if arg_values.is_empty() {
12969 return Err(RuntimeError::new("powi requires 1 argument"));
12970 }
12971 let exp = match &arg_values[0] {
12972 Value::Int(i) => *i as i32,
12973 Value::Float(f) => *f as i32,
12974 _ => return Err(RuntimeError::new("powi argument must be integer")),
12975 };
12976 Ok(Value::Float(n.powi(exp)))
12977 }
12978 (Value::Float(n), "atan2") => {
12979 if arg_values.is_empty() {
12980 return Err(RuntimeError::new("atan2 requires 1 argument"));
12981 }
12982 let other = match &arg_values[0] {
12983 Value::Float(f) => *f,
12984 Value::Int(i) => *i as f64,
12985 _ => return Err(RuntimeError::new("atan2 argument must be numeric")),
12986 };
12987 Ok(Value::Float(n.atan2(other)))
12988 }
12989 (Value::Float(n), "copysign") => {
12990 if arg_values.is_empty() {
12991 return Err(RuntimeError::new("copysign requires 1 argument"));
12992 }
12993 let sign = match &arg_values[0] {
12994 Value::Float(f) => *f,
12995 Value::Int(i) => *i as f64,
12996 _ => return Err(RuntimeError::new("copysign argument must be numeric")),
12997 };
12998 Ok(Value::Float(n.copysign(sign)))
12999 }
13000 (Value::Float(n), "mul_add") => {
13001 if arg_values.len() < 2 {
13002 return Err(RuntimeError::new("mul_add requires 2 arguments"));
13003 }
13004 let a = match &arg_values[0] {
13005 Value::Float(f) => *f,
13006 Value::Int(i) => *i as f64,
13007 _ => return Err(RuntimeError::new("mul_add arguments must be numeric")),
13008 };
13009 let b = match &arg_values[1] {
13010 Value::Float(f) => *f,
13011 Value::Int(i) => *i as f64,
13012 _ => return Err(RuntimeError::new("mul_add arguments must be numeric")),
13013 };
13014 Ok(Value::Float(n.mul_add(a, b)))
13015 }
13016 (Value::Float(n), "max") => {
13017 if arg_values.is_empty() {
13018 return Err(RuntimeError::new("max requires 1 argument"));
13019 }
13020 let other = match &arg_values[0] {
13021 Value::Float(f) => *f,
13022 Value::Int(i) => *i as f64,
13023 _ => return Err(RuntimeError::new("max argument must be numeric")),
13024 };
13025 Ok(Value::Float(n.max(other)))
13026 }
13027 (Value::Float(n), "min") => {
13028 if arg_values.is_empty() {
13029 return Err(RuntimeError::new("min requires 1 argument"));
13030 }
13031 let other = match &arg_values[0] {
13032 Value::Float(f) => *f,
13033 Value::Int(i) => *i as f64,
13034 _ => return Err(RuntimeError::new("min argument must be numeric")),
13035 };
13036 Ok(Value::Float(n.min(other)))
13037 }
13038 (Value::Float(n), "clamp") => {
13039 if arg_values.len() < 2 {
13040 return Err(RuntimeError::new("clamp requires 2 arguments"));
13041 }
13042 let min_val = match &arg_values[0] {
13043 Value::Float(f) => *f,
13044 Value::Int(i) => *i as f64,
13045 _ => return Err(RuntimeError::new("clamp arguments must be numeric")),
13046 };
13047 let max_val = match &arg_values[1] {
13048 Value::Float(f) => *f,
13049 Value::Int(i) => *i as f64,
13050 _ => return Err(RuntimeError::new("clamp arguments must be numeric")),
13051 };
13052 Ok(Value::Float(n.clamp(min_val, max_val)))
13053 }
13054 (Value::Float(n), "log") => {
13055 if arg_values.is_empty() {
13056 return Err(RuntimeError::new("log requires 1 argument (base)"));
13057 }
13058 let base = match &arg_values[0] {
13059 Value::Float(f) => *f,
13060 Value::Int(i) => *i as f64,
13061 _ => return Err(RuntimeError::new("log argument must be numeric")),
13062 };
13063 Ok(Value::Float(n.log(base)))
13064 }
13065 (Value::Int(n), "pow") => {
13067 if arg_values.is_empty() {
13068 return Err(RuntimeError::new("pow requires 1 argument"));
13069 }
13070 let exp = match &arg_values[0] {
13071 Value::Int(i) => *i as u32,
13072 _ => return Err(RuntimeError::new("pow argument must be integer")),
13073 };
13074 Ok(Value::Int(n.pow(exp)))
13075 }
13076 (Value::Int(n), "max") => {
13077 if arg_values.is_empty() {
13078 return Err(RuntimeError::new("max requires 1 argument"));
13079 }
13080 let other = match &arg_values[0] {
13081 Value::Int(i) => *i,
13082 _ => return Err(RuntimeError::new("max argument must be integer")),
13083 };
13084 Ok(Value::Int(std::cmp::max(*n, other)))
13085 }
13086 (Value::Int(n), "min") => {
13087 if arg_values.is_empty() {
13088 return Err(RuntimeError::new("min requires 1 argument"));
13089 }
13090 let other = match &arg_values[0] {
13091 Value::Int(i) => *i,
13092 _ => return Err(RuntimeError::new("min argument must be integer")),
13093 };
13094 Ok(Value::Int(std::cmp::min(*n, other)))
13095 }
13096 (Value::Int(n), "clamp") => {
13097 if arg_values.len() < 2 {
13098 return Err(RuntimeError::new("clamp requires 2 arguments"));
13099 }
13100 let min_val = match &arg_values[0] {
13101 Value::Int(i) => *i,
13102 _ => return Err(RuntimeError::new("clamp arguments must be integer")),
13103 };
13104 let max_val = match &arg_values[1] {
13105 Value::Int(i) => *i,
13106 _ => return Err(RuntimeError::new("clamp arguments must be integer")),
13107 };
13108 Ok(Value::Int((*n).max(min_val).min(max_val)))
13109 }
13110 (Value::Bool(b), "to_string") | (Value::Bool(b), "string") => {
13112 Ok(Value::String(Rc::new(b.to_string())))
13113 }
13114 (Value::Char(c), "to_string") | (Value::Char(c), "string") => {
13116 Ok(Value::String(Rc::new(c.to_string())))
13117 }
13118 (Value::Int(n), "is_null") => {
13120 Ok(Value::Bool(*n == 0))
13122 }
13123 (Value::Int(n), "to_string") | (Value::Int(n), "string") => {
13124 Ok(Value::String(Rc::new(n.to_string())))
13125 }
13126 (Value::Int(n), "abs") => Ok(Value::Int(n.abs())),
13127 _ => {
13128 let recv_type = match &recv {
13130 Value::String(s) => format!("String(len={})", s.len()),
13131 Value::Array(arr) => format!("Array(len={})", arr.borrow().len()),
13132 Value::Struct { name, .. } => format!("Struct({})", name),
13133 Value::Variant {
13134 enum_name,
13135 variant_name,
13136 ..
13137 } => format!("Variant({}::{})", enum_name, variant_name),
13138 Value::Ref(r) => format!("Ref({:?})", std::mem::discriminant(&*r.borrow())),
13139 Value::Null => "Null".to_string(),
13140 other => format!("{:?}", std::mem::discriminant(other)),
13141 };
13142 Err(RuntimeError::new(format!(
13144 "no method '{}' on type '{}'",
13145 method.name, recv_type
13146 )))
13147 }
13148 }
13149 }
13150
13151 fn eval_incorporation(
13154 &mut self,
13155 segments: &[IncorporationSegment],
13156 ) -> Result<Value, RuntimeError> {
13157 if segments.is_empty() {
13158 return Err(RuntimeError::new("empty incorporation chain"));
13159 }
13160
13161 let first = &segments[0];
13163 let mut value = if let Some(args) = &first.args {
13164 let arg_values: Vec<Value> = args
13166 .iter()
13167 .map(|a| self.evaluate(a))
13168 .collect::<Result<_, _>>()?;
13169 self.call_function_by_name(&first.name.name, arg_values)?
13170 } else if first.name.name == "Self" || first.name.name == "This" {
13171 if let Some(self_type) = self.current_self_type.clone() {
13173 if segments.len() > 1 {
13175 let method_segment = &segments[1];
13176 let arg_values: Vec<Value> = method_segment
13177 .args
13178 .as_ref()
13179 .map(|args| {
13180 args.iter()
13181 .map(|a| self.evaluate(a))
13182 .collect::<Result<Vec<_>, _>>()
13183 })
13184 .transpose()?
13185 .unwrap_or_default();
13186
13187 let full_name = format!("{}::{}", self_type, method_segment.name.name);
13189 let result = self.call_function_by_name(&full_name, arg_values)?;
13190
13191 let mut value = result;
13193 for segment in segments.iter().skip(2) {
13194 let seg_args: Vec<Value> = segment
13195 .args
13196 .as_ref()
13197 .map(|args| {
13198 args.iter()
13199 .map(|a| self.evaluate(a))
13200 .collect::<Result<Vec<_>, _>>()
13201 })
13202 .transpose()?
13203 .unwrap_or_default();
13204 value =
13205 self.call_incorporation_method(&value, &segment.name.name, seg_args)?;
13206 }
13207 return Ok(value);
13208 } else {
13209 return Err(RuntimeError::new(format!(
13211 "Self/This requires a method: use {}·method() instead of just {}",
13212 self_type, first.name.name
13213 )));
13214 }
13215 } else {
13216 return Err(RuntimeError::new(format!(
13217 "{} can only be used inside an impl block",
13218 first.name.name
13219 )));
13220 }
13221 } else {
13222 self.environment
13224 .borrow()
13225 .get(&first.name.name)
13226 .ok_or_else(|| RuntimeError::new(format!("undefined: {}", first.name.name)))?
13227 };
13228
13229 for segment in segments.iter().skip(1) {
13231 let arg_values: Vec<Value> = segment
13232 .args
13233 .as_ref()
13234 .map(|args| {
13235 args.iter()
13236 .map(|a| self.evaluate(a))
13237 .collect::<Result<Vec<_>, _>>()
13238 })
13239 .transpose()?
13240 .unwrap_or_default();
13241
13242 value = self.call_incorporation_method(&value, &segment.name.name, arg_values)?;
13244 }
13245
13246 Ok(value)
13247 }
13248
13249 fn call_incorporation_method(
13252 &mut self,
13253 receiver: &Value,
13254 method_name: &str,
13255 args: Vec<Value>,
13256 ) -> Result<Value, RuntimeError> {
13257 match (receiver, method_name) {
13259 (Value::String(s), "len") => Ok(Value::Int(s.len() as i64)),
13261 (Value::String(s), "upper")
13262 | (Value::String(s), "uppercase")
13263 | (Value::String(s), "to_uppercase") => Ok(Value::String(Rc::new(s.to_uppercase()))),
13264 (Value::String(s), "lower")
13265 | (Value::String(s), "lowercase")
13266 | (Value::String(s), "to_lowercase") => Ok(Value::String(Rc::new(s.to_lowercase()))),
13267 (Value::String(s), "trim") => Ok(Value::String(Rc::new(s.trim().to_string()))),
13268 (Value::String(s), "chars") => {
13269 let chars: Vec<Value> = s
13270 .chars()
13271 .map(|c| Value::String(Rc::new(c.to_string())))
13272 .collect();
13273 Ok(Value::Array(Rc::new(RefCell::new(chars))))
13274 }
13275 (Value::String(s), "lines") => {
13276 let lines: Vec<Value> = s
13277 .lines()
13278 .map(|l| Value::String(Rc::new(l.to_string())))
13279 .collect();
13280 Ok(Value::Array(Rc::new(RefCell::new(lines))))
13281 }
13282 (Value::String(s), "bytes") => {
13283 let bytes: Vec<Value> = s.bytes().map(|b| Value::Int(b as i64)).collect();
13284 Ok(Value::Array(Rc::new(RefCell::new(bytes))))
13285 }
13286 (Value::String(s), "parse_int") | (Value::String(s), "to_int") => s
13287 .parse::<i64>()
13288 .map(Value::Int)
13289 .map_err(|_| RuntimeError::new(format!("cannot parse '{}' as int", s))),
13290 (Value::String(s), "parse_float") | (Value::String(s), "to_float") => s
13291 .parse::<f64>()
13292 .map(Value::Float)
13293 .map_err(|_| RuntimeError::new(format!("cannot parse '{}' as float", s))),
13294 (Value::String(s), "as_str") => {
13295 if s.len() <= 10 {
13296 crate::sigil_debug!("DEBUG as_str: '{}'", s);
13297 }
13298 Ok(Value::String(s.clone()))
13299 }
13300 (Value::String(s), "to_string") => Ok(Value::String(s.clone())),
13301 (Value::String(s), "starts_with") => {
13302 if args.len() != 1 {
13303 return Err(RuntimeError::new("starts_with expects 1 argument"));
13304 }
13305 match &args[0] {
13306 Value::String(prefix) => Ok(Value::Bool(s.starts_with(prefix.as_str()))),
13307 _ => Err(RuntimeError::new("starts_with expects string")),
13308 }
13309 }
13310 (Value::String(s), "ends_with") => {
13311 if args.len() != 1 {
13312 return Err(RuntimeError::new("ends_with expects 1 argument"));
13313 }
13314 match &args[0] {
13315 Value::String(suffix) => Ok(Value::Bool(s.ends_with(suffix.as_str()))),
13316 _ => Err(RuntimeError::new("ends_with expects string")),
13317 }
13318 }
13319 (Value::String(s), "is_empty") => Ok(Value::Bool(s.is_empty())),
13320 (Value::String(s), "capacity") => Ok(Value::Int(s.capacity() as i64)),
13321 (Value::String(s), "clone") => Ok(Value::String(Rc::new((**s).clone()))),
13322 (Value::String(s), "first") => s
13323 .chars()
13324 .next()
13325 .map(Value::Char)
13326 .ok_or_else(|| RuntimeError::new("empty string")),
13327 (Value::String(s), "last") => s
13328 .chars()
13329 .last()
13330 .map(Value::Char)
13331 .ok_or_else(|| RuntimeError::new("empty string")),
13332
13333 (Value::Array(arr), "len") => Ok(Value::Int(arr.borrow().len() as i64)),
13335 (Value::Array(arr), "first") | (Value::Array(arr), "next") => {
13336 Ok(arr.borrow().first().cloned().unwrap_or(Value::Null))
13337 }
13338 (Value::Array(arr), "last") => arr
13339 .borrow()
13340 .last()
13341 .cloned()
13342 .ok_or_else(|| RuntimeError::new("empty array")),
13343 (Value::Array(arr), "reverse") | (Value::Array(arr), "rev") => {
13344 arr.borrow_mut().reverse();
13345 Ok(Value::Array(arr.clone()))
13346 }
13347 (Value::Array(arr), "join") => {
13348 let sep = args
13349 .first()
13350 .map(|v| match v {
13351 Value::String(s) => s.to_string(),
13352 _ => "".to_string(),
13353 })
13354 .unwrap_or_default();
13355 let joined = arr
13356 .borrow()
13357 .iter()
13358 .map(|v| format!("{}", v))
13359 .collect::<Vec<_>>()
13360 .join(&sep);
13361 Ok(Value::String(Rc::new(joined)))
13362 }
13363 (Value::Array(arr), "sum") => {
13364 let mut sum = 0i64;
13365 for v in arr.borrow().iter() {
13366 match v {
13367 Value::Int(i) => sum += i,
13368 Value::Float(f) => return Ok(Value::Float(sum as f64 + f)),
13369 _ => {}
13370 }
13371 }
13372 Ok(Value::Int(sum))
13373 }
13374 (Value::Array(arr), "skip") => {
13375 let n = match args.first() {
13376 Some(Value::Int(i)) => *i as usize,
13377 _ => 1,
13378 };
13379 let v: Vec<Value> = arr.borrow().iter().skip(n).cloned().collect();
13380 Ok(Value::Array(Rc::new(RefCell::new(v))))
13381 }
13382 (Value::Array(arr), "take") => {
13383 let n = match args.first() {
13384 Some(Value::Int(i)) => *i as usize,
13385 _ => 1,
13386 };
13387 let v: Vec<Value> = arr.borrow().iter().take(n).cloned().collect();
13388 Ok(Value::Array(Rc::new(RefCell::new(v))))
13389 }
13390 (Value::Array(arr), "step_by") => {
13391 let n = match args.first() {
13392 Some(Value::Int(i)) if *i > 0 => *i as usize,
13393 _ => 1,
13394 };
13395 let v: Vec<Value> = arr.borrow().iter().step_by(n).cloned().collect();
13396 Ok(Value::Array(Rc::new(RefCell::new(v))))
13397 }
13398
13399 (Value::Int(n), "abs") => Ok(Value::Int(n.abs())),
13401 (Value::Float(n), "abs") => Ok(Value::Float(n.abs())),
13402 (Value::Int(n), "to_string") | (Value::Int(n), "string") => {
13403 Ok(Value::String(Rc::new(n.to_string())))
13404 }
13405 (Value::Float(n), "to_string") | (Value::Float(n), "string") => {
13406 Ok(Value::String(Rc::new(n.to_string())))
13407 }
13408 (Value::Int(n), "to_float") | (Value::Int(n), "float") => Ok(Value::Float(*n as f64)),
13409 (Value::Float(n), "to_int") | (Value::Float(n), "int") => Ok(Value::Int(*n as i64)),
13410
13411 (Value::Map(map), field) => map
13413 .borrow()
13414 .get(field)
13415 .cloned()
13416 .ok_or_else(|| RuntimeError::new(format!("no field '{}' in map", field))),
13417 (Value::Struct { fields, .. }, field) => fields
13418 .borrow()
13419 .get(field)
13420 .cloned()
13421 .ok_or_else(|| RuntimeError::new(format!("no field '{}' in struct", field))),
13422
13423 _ => {
13425 let mut all_args = vec![receiver.clone()];
13426 all_args.extend(args);
13427 self.call_function_by_name(method_name, all_args)
13428 }
13429 }
13430 }
13431
13432 pub fn call_function_by_name(
13434 &mut self,
13435 name: &str,
13436 args: Vec<Value>,
13437 ) -> Result<Value, RuntimeError> {
13438 let func_value = self.environment.borrow().get(name);
13440
13441 match func_value {
13442 Some(Value::Function(f)) => self.call_function(&f, args),
13443 Some(Value::BuiltIn(b)) => self.call_builtin(&b, args),
13444 Some(_) => Err(RuntimeError::new(format!("{} is not a function", name))),
13445 None => {
13446 if let Some((enum_name, variant_name, arity)) =
13448 self.variant_constructors.get(name).cloned()
13449 {
13450 if arity == 0 && args.is_empty() {
13451 return Ok(Value::Variant {
13452 enum_name,
13453 variant_name,
13454 fields: None,
13455 });
13456 } else if args.len() == arity {
13457 return Ok(Value::Variant {
13458 enum_name,
13459 variant_name,
13460 fields: Some(Rc::new(args)),
13461 });
13462 } else {
13463 return Err(RuntimeError::new(format!(
13464 "{} expects {} arguments, got {}",
13465 name,
13466 arity,
13467 args.len()
13468 )));
13469 }
13470 }
13471 Err(RuntimeError::new(format!("undefined function: {}", name)))
13472 }
13473 }
13474 }
13475
13476 fn eval_pipe(&mut self, expr: &Expr, operations: &[PipeOp]) -> Result<Value, RuntimeError> {
13477 let mut value = self.evaluate(expr)?;
13478
13479 for op in operations {
13480 value = self.apply_pipe_op(value, op)?;
13481 }
13482
13483 Ok(value)
13484 }
13485
13486 fn apply_pipe_op(&mut self, value: Value, op: &PipeOp) -> Result<Value, RuntimeError> {
13487 let value = Self::unwrap_all(&value);
13489
13490 match op {
13491 PipeOp::Transform(body) => {
13492 let (param_pattern, inner_body) = match body.as_ref() {
13495 Expr::Closure { params, body, .. } => {
13496 let pattern = params.first().map(|p| p.pattern.clone());
13497 (pattern, body.as_ref())
13498 }
13499 _ => (None, body.as_ref()),
13500 };
13501
13502 match value {
13503 Value::Array(arr) => {
13504 let results: Vec<Value> = arr
13505 .borrow()
13506 .iter()
13507 .map(|item| {
13508 if let Some(ref pattern) = param_pattern {
13510 self.bind_pattern(pattern, item.clone())?;
13511 } else {
13512 self.environment
13513 .borrow_mut()
13514 .define("_".to_string(), item.clone());
13515 }
13516 self.evaluate(inner_body)
13517 })
13518 .collect::<Result<_, _>>()?;
13519 Ok(Value::Array(Rc::new(RefCell::new(results))))
13520 }
13521 single => {
13522 if let Some(ref pattern) = param_pattern {
13523 self.bind_pattern(pattern, single)?;
13524 } else {
13525 self.environment
13526 .borrow_mut()
13527 .define("_".to_string(), single);
13528 }
13529 self.evaluate(inner_body)
13530 }
13531 }
13532 }
13533 PipeOp::Filter(predicate) => {
13534 let (param_pattern, inner_pred) = match predicate.as_ref() {
13537 Expr::Closure { params, body, .. } => {
13538 let pattern = params.first().map(|p| p.pattern.clone());
13539 (pattern, body.as_ref())
13540 }
13541 _ => (None, predicate.as_ref()),
13542 };
13543
13544 match value {
13545 Value::Array(arr) => {
13546 let results: Vec<Value> = arr
13547 .borrow()
13548 .iter()
13549 .filter_map(|item| {
13550 if let Some(ref pattern) = param_pattern {
13552 if let Err(e) = self.bind_pattern(pattern, item.clone()) {
13553 return Some(Err(e));
13554 }
13555 } else {
13556 self.environment
13557 .borrow_mut()
13558 .define("_".to_string(), item.clone());
13559 }
13560 match self.evaluate(inner_pred) {
13561 Ok(v) if self.is_truthy(&v) => Some(Ok(item.clone())),
13562 Ok(_) => None,
13563 Err(e) => Some(Err(e)),
13564 }
13565 })
13566 .collect::<Result<_, _>>()?;
13567 Ok(Value::Array(Rc::new(RefCell::new(results))))
13568 }
13569 _ => Err(RuntimeError::new("Filter requires array")),
13570 }
13571 }
13572 PipeOp::Sort(field) => {
13573 match value {
13575 Value::Array(arr) => {
13576 let mut v = arr.borrow().clone();
13577 v.sort_by(|a, b| self.compare_values(a, b, field));
13578 Ok(Value::Array(Rc::new(RefCell::new(v))))
13579 }
13580 Value::Struct { ref name, .. } if name == "Tensor" => self.sum_values(value),
13582 _ => Err(RuntimeError::new("Sort requires array")),
13583 }
13584 }
13585 PipeOp::SortBy(body) => {
13586 match value {
13588 Value::Array(arr) => {
13589 let mut v = arr.borrow().clone();
13590 let (params, inner_body) = match body.as_ref() {
13591 Expr::Closure { params, body, .. } => (params, body.as_ref()),
13592 _ => return Err(RuntimeError::new("SortBy requires closure")),
13593 };
13594 let n = v.len();
13596 for i in 0..n {
13597 for j in 0..n.saturating_sub(1).saturating_sub(i) {
13598 if params.len() >= 2 {
13599 self.bind_pattern(¶ms[0].pattern, v[j].clone())?;
13600 self.bind_pattern(¶ms[1].pattern, v[j + 1].clone())?;
13601 }
13602 let cmp = self.evaluate(inner_body)?;
13603 if matches!(&cmp, Value::Int(n) if *n > 0) {
13604 v.swap(j, j + 1);
13605 }
13606 }
13607 }
13608 Ok(Value::Array(Rc::new(RefCell::new(v))))
13609 }
13610 _ => Err(RuntimeError::new("SortBy requires array")),
13611 }
13612 }
13613 PipeOp::Reduce(body) => {
13614 match value {
13616 Value::Array(arr) => {
13617 let arr = arr.borrow();
13618 if arr.is_empty() {
13619 return Err(RuntimeError::new("Cannot reduce empty array"));
13620 }
13621 let mut acc = arr[0].clone();
13622 for item in arr.iter().skip(1) {
13623 self.environment.borrow_mut().define("acc".to_string(), acc);
13624 self.environment
13625 .borrow_mut()
13626 .define("_".to_string(), item.clone());
13627 acc = self.evaluate(body)?;
13628 }
13629 Ok(acc)
13630 }
13631 _ => Err(RuntimeError::new("Reduce requires array")),
13632 }
13633 }
13634 PipeOp::ReduceWithInit(init_expr, closure) => {
13635 match value {
13637 Value::Array(arr) => {
13638 let items: Vec<Value> = arr.borrow().clone();
13639 let mut acc = self.evaluate(init_expr)?;
13640 let (params, inner_body) = match closure.as_ref() {
13641 Expr::Closure { params, body, .. } => (params, body.as_ref()),
13642 _ => return Err(RuntimeError::new("ReduceWithInit requires closure")),
13643 };
13644 for item in items.iter() {
13645 if params.len() >= 2 {
13646 self.bind_pattern(¶ms[0].pattern, acc)?;
13647 self.bind_pattern(¶ms[1].pattern, item.clone())?;
13648 }
13649 acc = self.evaluate(inner_body)?;
13650 }
13651 Ok(acc)
13652 }
13653 _ => Err(RuntimeError::new("ReduceWithInit requires array")),
13654 }
13655 }
13656 PipeOp::ReduceSum => {
13657 self.sum_values(value)
13659 }
13660 PipeOp::ReduceProd => {
13661 self.product_values(value)
13663 }
13664 PipeOp::ReduceMin => {
13665 self.min_values(value)
13667 }
13668 PipeOp::ReduceMax => {
13669 self.max_values(value)
13671 }
13672 PipeOp::ReduceConcat => {
13673 self.concat_values(value)
13675 }
13676 PipeOp::ReduceAll => {
13677 self.all_values(value)
13679 }
13680 PipeOp::ReduceAny => {
13681 self.any_values(value)
13683 }
13684 PipeOp::Match(arms) => {
13685 for arm in arms {
13687 if self.pattern_matches(&arm.pattern, &value)? {
13688 let prev_env = self.environment.clone();
13690 self.environment =
13691 Rc::new(RefCell::new(Environment::with_parent(prev_env.clone())));
13692
13693 self.bind_pattern(&arm.pattern, value.clone())?;
13695
13696 self.environment
13698 .borrow_mut()
13699 .define("_".to_string(), value.clone());
13700
13701 let guard_passes = if let Some(guard) = &arm.guard {
13703 matches!(self.evaluate(guard)?, Value::Bool(true))
13704 } else {
13705 true
13706 };
13707
13708 if guard_passes {
13709 let result = self.evaluate(&arm.body)?;
13710 self.environment = prev_env;
13711 return Ok(result);
13712 }
13713
13714 self.environment = prev_env;
13716 }
13717 }
13718 Err(RuntimeError::new("No pattern matched in pipe match"))
13719 }
13720 PipeOp::TryMap(mapper) => {
13721 match &value {
13723 Value::Struct { name, fields } if name == "Ok" || name.ends_with("::Ok") => {
13725 let fields = fields.borrow();
13727 fields
13728 .get("0")
13729 .or_else(|| fields.get("value"))
13730 .cloned()
13731 .ok_or_else(|| RuntimeError::new("Ok variant has no value"))
13732 }
13733 Value::Struct { name, fields } if name == "Err" || name.ends_with("::Err") => {
13734 let fields = fields.borrow();
13736 let err_val = fields
13737 .get("0")
13738 .or_else(|| fields.get("error"))
13739 .cloned()
13740 .unwrap_or(Value::Null);
13741 if let Some(mapper_expr) = mapper {
13742 let prev_env = self.environment.clone();
13744 self.environment =
13745 Rc::new(RefCell::new(Environment::with_parent(prev_env.clone())));
13746 self.environment
13747 .borrow_mut()
13748 .define("_".to_string(), err_val);
13749 let mapped = self.evaluate(mapper_expr)?;
13750 self.environment = prev_env;
13751 Err(RuntimeError::new(format!("Error: {:?}", mapped)))
13752 } else {
13753 Err(RuntimeError::new(format!("Error: {:?}", err_val)))
13754 }
13755 }
13756 Value::Struct { name, fields }
13758 if name == "Some" || name.ends_with("::Some") =>
13759 {
13760 let fields = fields.borrow();
13761 fields
13762 .get("0")
13763 .or_else(|| fields.get("value"))
13764 .cloned()
13765 .ok_or_else(|| RuntimeError::new("Some variant has no value"))
13766 }
13767 Value::Struct { name, .. } if name == "None" || name.ends_with("::None") => {
13768 Err(RuntimeError::new("Unwrapped None value"))
13769 }
13770 Value::Null => Err(RuntimeError::new("Unwrapped null value")),
13771 _ => Ok(value),
13773 }
13774 }
13775 PipeOp::Call(callee) => {
13776 if let Expr::Macro { path, tokens } = callee.as_ref() {
13779 let macro_name = path
13780 .segments
13781 .last()
13782 .map(|s| s.ident.name.as_str())
13783 .unwrap_or("");
13784
13785 let macro_def = self.user_macros.borrow().get(macro_name).cloned();
13788 if let Some((params, body, field_map)) = macro_def {
13789 return self.expand_user_macro(¶ms, &body, tokens, Some(value), &field_map);
13790 }
13791 }
13793
13794 if let Expr::Call { func: inner_func, args } = callee.as_ref() {
13797 let func_val = self.evaluate(inner_func)?;
13799
13800 let mut all_args = vec![value];
13802 for arg in args {
13803 all_args.push(self.evaluate(arg)?);
13804 }
13805
13806 return match func_val {
13808 Value::Function(f) => self.call_function(&f, all_args),
13809 Value::BuiltIn(b) => self.call_builtin(&b, all_args),
13810 _ => Err(RuntimeError::new(format!(
13811 "Cannot call non-function value in pipe: {:?}",
13812 func_val
13813 ))),
13814 };
13815 }
13816
13817 let callee_val = self.evaluate(callee)?;
13819 match callee_val {
13820 Value::Function(f) => {
13821 self.call_function(&f, vec![value])
13823 }
13824 Value::BuiltIn(b) => {
13825 self.call_builtin(&b, vec![value])
13827 }
13828 Value::Struct { .. } => {
13829 Ok(value)
13832 }
13833 _ => Err(RuntimeError::new(format!(
13834 "Cannot call non-function value in pipe: {:?}",
13835 callee_val
13836 ))),
13837 }
13838 }
13839 PipeOp::Method {
13840 name,
13841 type_args: _,
13842 args,
13843 } => {
13844 let arg_values: Vec<Value> = args
13845 .iter()
13846 .map(|a| self.evaluate(a))
13847 .collect::<Result<_, _>>()?;
13848
13849 match name.name.as_str() {
13851 "collect" => Ok(value), "sum" | "Σ" => self.sum_values(value),
13853 "product" | "Π" => self.product_values(value),
13854 "len" => match &value {
13855 Value::Array(arr) => Ok(Value::Int(arr.borrow().len() as i64)),
13856 Value::String(s) => Ok(Value::Int(s.len() as i64)),
13857 _ => Err(RuntimeError::new("len requires array or string")),
13858 },
13859 "reverse" => match value {
13860 Value::Array(arr) => {
13861 arr.borrow_mut().reverse();
13862 Ok(Value::Array(arr.clone()))
13863 }
13864 _ => Err(RuntimeError::new("reverse requires array")),
13865 },
13866 "iter" | "into_iter" => {
13867 Ok(value)
13869 }
13870 "enumerate" => {
13871 match &value {
13873 Value::Array(arr) => {
13874 let enumerated: Vec<Value> = arr
13875 .borrow()
13876 .iter()
13877 .enumerate()
13878 .map(|(i, v)| {
13879 Value::Tuple(Rc::new(vec![Value::Int(i as i64), v.clone()]))
13880 })
13881 .collect();
13882 Ok(Value::Array(Rc::new(RefCell::new(enumerated))))
13883 }
13884 _ => Err(RuntimeError::new("enumerate requires array")),
13885 }
13886 }
13887 "first" => match &value {
13888 Value::Array(arr) => arr
13889 .borrow()
13890 .first()
13891 .cloned()
13892 .ok_or_else(|| RuntimeError::new("first on empty array")),
13893 _ => Err(RuntimeError::new("first requires array")),
13894 },
13895 "last" => match &value {
13896 Value::Array(arr) => arr
13897 .borrow()
13898 .last()
13899 .cloned()
13900 .ok_or_else(|| RuntimeError::new("last on empty array")),
13901 _ => Err(RuntimeError::new("last requires array")),
13902 },
13903 "take" => {
13904 if arg_values.len() != 1 {
13905 return Err(RuntimeError::new("take requires 1 argument"));
13906 }
13907 let n = match &arg_values[0] {
13908 Value::Int(n) => *n as usize,
13909 _ => return Err(RuntimeError::new("take requires integer")),
13910 };
13911 match value {
13912 Value::Array(arr) => {
13913 let v: Vec<Value> = arr.borrow().iter().take(n).cloned().collect();
13914 Ok(Value::Array(Rc::new(RefCell::new(v))))
13915 }
13916 _ => Err(RuntimeError::new("take requires array")),
13917 }
13918 }
13919 "skip" => {
13920 if arg_values.len() != 1 {
13921 return Err(RuntimeError::new("skip requires 1 argument"));
13922 }
13923 let n = match &arg_values[0] {
13924 Value::Int(n) => *n as usize,
13925 _ => return Err(RuntimeError::new("skip requires integer")),
13926 };
13927 match value {
13928 Value::Array(arr) => {
13929 let v: Vec<Value> = arr.borrow().iter().skip(n).cloned().collect();
13930 Ok(Value::Array(Rc::new(RefCell::new(v))))
13931 }
13932 _ => Err(RuntimeError::new("skip requires array")),
13933 }
13934 }
13935 "join" => {
13936 let separator = if arg_values.is_empty() {
13938 String::new()
13939 } else {
13940 match &arg_values[0] {
13941 Value::String(s) => (**s).clone(),
13942 _ => {
13943 return Err(RuntimeError::new("join separator must be string"))
13944 }
13945 }
13946 };
13947 match value {
13948 Value::Array(arr) => {
13949 let parts: Vec<String> = arr
13950 .borrow()
13951 .iter()
13952 .map(|v| format!("{}", Self::unwrap_all(v)))
13953 .collect();
13954 Ok(Value::String(Rc::new(parts.join(&separator))))
13955 }
13956 _ => Err(RuntimeError::new("join requires array")),
13957 }
13958 }
13959 "all" => {
13960 match value {
13962 Value::Array(arr) => {
13963 for item in arr.borrow().iter() {
13964 if !self.is_truthy(item) {
13965 return Ok(Value::Bool(false));
13966 }
13967 }
13968 Ok(Value::Bool(true))
13969 }
13970 _ => Err(RuntimeError::new("all requires array")),
13971 }
13972 }
13973 "any" => {
13974 match value {
13976 Value::Array(arr) => {
13977 for item in arr.borrow().iter() {
13978 if self.is_truthy(item) {
13979 return Ok(Value::Bool(true));
13980 }
13981 }
13982 Ok(Value::Bool(false))
13983 }
13984 _ => Err(RuntimeError::new("any requires array")),
13985 }
13986 }
13987 "map" => {
13988 if arg_values.len() != 1 {
13990 return Err(RuntimeError::new("map expects 1 argument (closure)"));
13991 }
13992 match (&value, &arg_values[0]) {
13993 (Value::Array(arr), Value::Function(f)) => {
13994 let mut results = Vec::new();
13995 for val in arr.borrow().iter() {
13996 let result = self.call_function(f, vec![val.clone()])?;
13997 results.push(result);
13998 }
13999 Ok(Value::Array(Rc::new(RefCell::new(results))))
14000 }
14001 (Value::Array(_), _) => {
14002 Err(RuntimeError::new("map expects closure argument"))
14003 }
14004 _ => Err(RuntimeError::new("map requires array")),
14005 }
14006 }
14007 "filter" => {
14008 if arg_values.len() != 1 {
14010 return Err(RuntimeError::new("filter expects 1 argument (closure)"));
14011 }
14012 match (&value, &arg_values[0]) {
14013 (Value::Array(arr), Value::Function(f)) => {
14014 let mut results = Vec::new();
14015 for val in arr.borrow().iter() {
14016 let keep = self.call_function(f, vec![val.clone()])?;
14017 if matches!(keep, Value::Bool(true)) {
14018 results.push(val.clone());
14019 }
14020 }
14021 Ok(Value::Array(Rc::new(RefCell::new(results))))
14022 }
14023 (Value::Array(_), _) => {
14024 Err(RuntimeError::new("filter expects closure argument"))
14025 }
14026 _ => Err(RuntimeError::new("filter requires array")),
14027 }
14028 }
14029 "find" => {
14030 if arg_values.len() != 1 {
14032 return Err(RuntimeError::new("find expects 1 argument (closure)"));
14033 }
14034 match (&value, &arg_values[0]) {
14035 (Value::Array(arr), Value::Function(f)) => {
14036 for val in arr.borrow().iter() {
14037 let matches = self.call_function(f, vec![val.clone()])?;
14038 if matches!(matches, Value::Bool(true)) {
14039 return Ok(val.clone());
14040 }
14041 }
14042 Ok(Value::Variant {
14044 enum_name: "Option".to_string(),
14045 variant_name: "None".to_string(),
14046 fields: None,
14047 })
14048 }
14049 (Value::Array(_), _) => {
14050 Err(RuntimeError::new("find expects closure argument"))
14051 }
14052 _ => Err(RuntimeError::new("find requires array")),
14053 }
14054 }
14055 "fold" => {
14056 if arg_values.len() != 2 {
14058 return Err(RuntimeError::new(
14059 "fold expects 2 arguments (init, closure)",
14060 ));
14061 }
14062 match (&value, &arg_values[1]) {
14063 (Value::Array(arr), Value::Function(f)) => {
14064 let mut acc = arg_values[0].clone();
14065 for val in arr.borrow().iter() {
14066 acc = self.call_function(f, vec![acc, val.clone()])?;
14067 }
14068 Ok(acc)
14069 }
14070 (Value::Array(_), _) => {
14071 Err(RuntimeError::new("fold expects closure as second argument"))
14072 }
14073 _ => Err(RuntimeError::new("fold requires array")),
14074 }
14075 }
14076 _ => {
14077 if let Value::Struct {
14079 name: struct_name,
14080 fields,
14081 } = &value
14082 {
14083 match (struct_name.as_str(), name.name.as_str()) {
14085 ("HyperLogLog", "count") => {
14086 if let Some(Value::Array(regs)) =
14087 fields.borrow().get("__registers__")
14088 {
14089 let regs_borrow = regs.borrow();
14090 let m = regs_borrow.len() as f64;
14091 let mut sum = 0.0;
14092 let mut zeros = 0;
14093 for reg in regs_borrow.iter() {
14094 let val = match reg {
14095 Value::Int(v) => *v as i32,
14096 _ => 0,
14097 };
14098 sum += 2.0_f64.powi(-val);
14099 if val == 0 {
14100 zeros += 1;
14101 }
14102 }
14103 let alpha = 0.7213 / (1.0 + 1.079 / m);
14104 let estimate = alpha * m * m / sum;
14105 let result = if estimate <= 2.5 * m && zeros > 0 {
14106 m * (m / zeros as f64).ln()
14107 } else {
14108 estimate
14109 };
14110 return Ok(Value::Int(result.round() as i64));
14111 }
14112 return Ok(Value::Int(0));
14113 }
14114 ("BloomFilter", "contains") => {
14115 if arg_values.len() != 1 {
14116 return Err(RuntimeError::new(
14117 "BloomFilter.contains expects 1 argument",
14118 ));
14119 }
14120 let size = match fields.borrow().get("__size__") {
14121 Some(Value::Int(s)) => *s as usize,
14122 _ => 1024,
14123 };
14124 let num_hashes = match fields.borrow().get("__num_hashes__") {
14125 Some(Value::Int(n)) => *n as usize,
14126 _ => 3,
14127 };
14128 let base_hash = match &arg_values[0] {
14129 Value::String(s) => {
14130 use std::collections::hash_map::DefaultHasher;
14131 use std::hash::{Hash, Hasher};
14132 let mut hasher = DefaultHasher::new();
14133 s.hash(&mut hasher);
14134 hasher.finish()
14135 }
14136 Value::Int(n) => *n as u64,
14137 other => {
14138 use std::collections::hash_map::DefaultHasher;
14139 use std::hash::{Hash, Hasher};
14140 let mut hasher = DefaultHasher::new();
14141 format!("{:?}", other).hash(&mut hasher);
14142 hasher.finish()
14143 }
14144 };
14145 if let Some(Value::Array(bits)) = fields.borrow().get("__bits__") {
14146 let bits_borrow = bits.borrow();
14147 for i in 0..num_hashes {
14148 let h = (base_hash.wrapping_add(
14149 i as u64 * base_hash.rotate_left(17),
14150 )) % size as u64;
14151 match &bits_borrow[h as usize] {
14152 Value::Bool(true) => {}
14153 _ => return Ok(Value::Bool(false)),
14154 }
14155 }
14156 return Ok(Value::Bool(true));
14157 }
14158 return Ok(Value::Bool(false));
14159 }
14160 ("CountMinSketch", "frequency") => {
14161 if arg_values.len() != 1 {
14162 return Err(RuntimeError::new(
14163 "CountMinSketch.frequency expects 1 argument",
14164 ));
14165 }
14166 let depth = match fields.borrow().get("__depth__") {
14167 Some(Value::Int(d)) => *d as usize,
14168 _ => 4,
14169 };
14170 let width = match fields.borrow().get("__width__") {
14171 Some(Value::Int(w)) => *w as usize,
14172 _ => 1024,
14173 };
14174 let base_hash = match &arg_values[0] {
14175 Value::String(s) => {
14176 use std::collections::hash_map::DefaultHasher;
14177 use std::hash::{Hash, Hasher};
14178 let mut hasher = DefaultHasher::new();
14179 s.hash(&mut hasher);
14180 hasher.finish()
14181 }
14182 Value::Int(n) => *n as u64,
14183 other => {
14184 use std::collections::hash_map::DefaultHasher;
14185 use std::hash::{Hash, Hasher};
14186 let mut hasher = DefaultHasher::new();
14187 format!("{:?}", other).hash(&mut hasher);
14188 hasher.finish()
14189 }
14190 };
14191 let mut min_count = i64::MAX;
14192 if let Some(Value::Array(counters)) =
14193 fields.borrow().get("__counters__")
14194 {
14195 let counters_borrow = counters.borrow();
14196 for i in 0..depth {
14197 let h = (base_hash
14198 .wrapping_add(i as u64 * 0x517cc1b727220a95))
14199 % width as u64;
14200 if let Value::Array(row) = &counters_borrow[i] {
14201 let row_borrow = row.borrow();
14202 if let Value::Int(c) = &row_borrow[h as usize] {
14203 if *c < min_count {
14204 min_count = *c;
14205 }
14206 }
14207 }
14208 }
14209 }
14210 return Ok(Value::Int(if min_count == i64::MAX {
14211 0
14212 } else {
14213 min_count
14214 }));
14215 }
14216 ("MerkleTree", "verify") => {
14217 use std::collections::hash_map::DefaultHasher;
14218 use std::hash::{Hash, Hasher};
14219 if let (Some(Value::Array(leaves)), Some(Value::String(root))) = (
14220 fields.borrow().get("__leaf_hashes__").cloned(),
14221 fields.borrow().get("root").cloned(),
14222 ) {
14223 let leaves_borrow = leaves.borrow();
14224 let combined: String = leaves_borrow
14225 .iter()
14226 .filter_map(|v| match v {
14227 Value::String(s) => Some(s.to_string()),
14228 _ => None,
14229 })
14230 .collect();
14231 let mut hasher = DefaultHasher::new();
14232 combined.hash(&mut hasher);
14233 let computed_root = format!("{:016x}", hasher.finish());
14234 return Ok(Value::Bool(*root == computed_root));
14235 }
14236 return Ok(Value::Bool(false));
14237 }
14238 ("MerkleProof", "verify") => {
14239 if let Some(Value::Bool(valid)) = fields.borrow().get("_valid")
14241 {
14242 return Ok(Value::Bool(*valid));
14243 }
14244 return Ok(Value::Bool(false));
14245 }
14246 ("UntrustedData", "verify") => {
14247 if let Some(val) = fields.borrow().get("value").cloned() {
14249 return Ok(val);
14250 }
14251 return Ok(Value::Bool(true));
14252 }
14253 ("Superposition", "observe") => {
14254 if let Some(Value::Array(values)) =
14257 fields.borrow().get("__values__")
14258 {
14259 let values_borrow = values.borrow();
14260 if !values_borrow.is_empty() {
14261 return Ok(values_borrow[0].clone());
14262 }
14263 }
14264 if let Some(Value::Array(values)) =
14266 fields.borrow().get("__elements__")
14267 {
14268 let values_borrow = values.borrow();
14269 if !values_borrow.is_empty() {
14270 return Ok(values_borrow[0].clone());
14271 }
14272 }
14273 if let Some(Value::Array(values)) =
14275 fields.borrow().get("_values")
14276 {
14277 let values_borrow = values.borrow();
14278 if !values_borrow.is_empty() {
14279 return Ok(values_borrow[0].clone());
14280 }
14281 }
14282 if let Some(Value::Array(states)) =
14284 fields.borrow().get("states")
14285 {
14286 let states_borrow = states.borrow();
14287 if !states_borrow.is_empty() {
14288 return Ok(states_borrow[0].clone());
14289 }
14290 }
14291 return Ok(Value::Null);
14292 }
14293 ("Qubit", "H") => {
14295 let alpha_real = match fields.borrow().get("_alpha_real") {
14297 Some(Value::Float(f)) => *f,
14298 _ => 1.0,
14299 };
14300 let beta_real = match fields.borrow().get("_beta_real") {
14301 Some(Value::Float(f)) => *f,
14302 _ => 0.0,
14303 };
14304 let sqrt2_inv = 1.0 / std::f64::consts::SQRT_2;
14305 let new_alpha = (alpha_real + beta_real) * sqrt2_inv;
14307 let new_beta = (alpha_real - beta_real) * sqrt2_inv;
14308
14309 let mut new_fields = std::collections::HashMap::new();
14310 new_fields
14311 .insert("_alpha_real".to_string(), Value::Float(new_alpha));
14312 new_fields.insert("_alpha_imag".to_string(), Value::Float(0.0));
14313 new_fields
14314 .insert("_beta_real".to_string(), Value::Float(new_beta));
14315 new_fields.insert("_beta_imag".to_string(), Value::Float(0.0));
14316 return Ok(Value::Struct {
14317 name: "Qubit".to_string(),
14318 fields: Rc::new(RefCell::new(new_fields)),
14319 });
14320 }
14321 ("Qubit", "X") => {
14322 let alpha_real = match fields.borrow().get("_alpha_real") {
14324 Some(Value::Float(f)) => *f,
14325 _ => 1.0,
14326 };
14327 let alpha_imag = match fields.borrow().get("_alpha_imag") {
14328 Some(Value::Float(f)) => *f,
14329 _ => 0.0,
14330 };
14331 let beta_real = match fields.borrow().get("_beta_real") {
14332 Some(Value::Float(f)) => *f,
14333 _ => 0.0,
14334 };
14335 let beta_imag = match fields.borrow().get("_beta_imag") {
14336 Some(Value::Float(f)) => *f,
14337 _ => 0.0,
14338 };
14339 let mut new_fields = std::collections::HashMap::new();
14341 new_fields
14342 .insert("_alpha_real".to_string(), Value::Float(beta_real));
14343 new_fields
14344 .insert("_alpha_imag".to_string(), Value::Float(beta_imag));
14345 new_fields
14346 .insert("_beta_real".to_string(), Value::Float(alpha_real));
14347 new_fields
14348 .insert("_beta_imag".to_string(), Value::Float(alpha_imag));
14349 return Ok(Value::Struct {
14350 name: "Qubit".to_string(),
14351 fields: Rc::new(RefCell::new(new_fields)),
14352 });
14353 }
14354 ("Qubit", "measure") => {
14355 let alpha_real = match fields.borrow().get("_alpha_real") {
14358 Some(Value::Float(f)) => *f,
14359 _ => 1.0,
14360 };
14361 let alpha_imag = match fields.borrow().get("_alpha_imag") {
14362 Some(Value::Float(f)) => *f,
14363 _ => 0.0,
14364 };
14365 let beta_real = match fields.borrow().get("_beta_real") {
14366 Some(Value::Float(f)) => *f,
14367 _ => 0.0,
14368 };
14369 let beta_imag = match fields.borrow().get("_beta_imag") {
14370 Some(Value::Float(f)) => *f,
14371 _ => 0.0,
14372 };
14373 let alpha_sq =
14374 alpha_real * alpha_real + alpha_imag * alpha_imag;
14375 let beta_sq = beta_real * beta_real + beta_imag * beta_imag;
14376 let result = if alpha_sq >= beta_sq { 0 } else { 1 };
14379 return Ok(Value::Int(result));
14380 }
14381 ("QRegister", "H_all") => {
14383 let size = match fields.borrow().get("_size") {
14385 Some(Value::Int(n)) => *n as usize,
14386 _ => 1,
14387 };
14388 let state: Vec<f64> = match fields.borrow().get("_state") {
14389 Some(Value::Array(arr)) => arr
14390 .borrow()
14391 .iter()
14392 .filter_map(|v| match v {
14393 Value::Float(f) => Some(*f),
14394 _ => None,
14395 })
14396 .collect(),
14397 _ => vec![1.0],
14398 };
14399
14400 let dim = 1 << size; let amp = 1.0 / (dim as f64).sqrt();
14404 let new_state: Vec<Value> =
14405 (0..dim).map(|_| Value::Float(amp)).collect();
14406
14407 let mut new_fields = HashMap::new();
14408 new_fields.insert("_size".to_string(), Value::Int(size as i64));
14409 new_fields.insert(
14410 "_state".to_string(),
14411 Value::Array(Rc::new(RefCell::new(new_state))),
14412 );
14413
14414 return Ok(Value::Struct {
14415 name: "QRegister".to_string(),
14416 fields: Rc::new(RefCell::new(new_fields)),
14417 });
14418 }
14419 ("QRegister", "measure_all") => {
14420 let size = match fields.borrow().get("_size") {
14422 Some(Value::Int(n)) => *n as usize,
14423 _ => 1,
14424 };
14425 let state: Vec<f64> = match fields.borrow().get("_state") {
14426 Some(Value::Array(arr)) => arr
14427 .borrow()
14428 .iter()
14429 .filter_map(|v| match v {
14430 Value::Float(f) => Some(*f),
14431 _ => None,
14432 })
14433 .collect(),
14434 _ => vec![1.0],
14435 };
14436
14437 let mut max_idx = 0;
14439 let mut max_amp_sq = 0.0;
14440 for (i, amp) in state.iter().enumerate() {
14441 let amp_sq = amp * amp;
14442 if amp_sq > max_amp_sq {
14443 max_amp_sq = amp_sq;
14444 max_idx = i;
14445 }
14446 }
14447
14448 let mut results: Vec<Value> = Vec::new();
14450 for bit in 0..size {
14451 let cbit_value = (max_idx >> (size - 1 - bit)) & 1;
14452 results.push(Value::Int(cbit_value as i64));
14454 }
14455
14456 return Ok(Value::Array(Rc::new(RefCell::new(results))));
14457 }
14458 _ => {}
14459 }
14460 }
14461 if (name.name == "Rx" || name.name == "Ry" || name.name == "Rz") {
14463 if let Value::Struct {
14464 name: sname,
14465 fields,
14466 } = &value
14467 {
14468 if sname == "Qubit" {
14469 let angle = if !arg_values.is_empty() {
14471 match &arg_values[0] {
14472 Value::Float(f) => *f,
14473 Value::Int(n) => *n as f64,
14474 _ => 0.0,
14475 }
14476 } else {
14477 0.0
14478 };
14479
14480 let alpha_real = match fields.borrow().get("_alpha_real") {
14481 Some(Value::Float(f)) => *f,
14482 _ => 1.0,
14483 };
14484 let alpha_imag = match fields.borrow().get("_alpha_imag") {
14485 Some(Value::Float(f)) => *f,
14486 _ => 0.0,
14487 };
14488 let beta_real = match fields.borrow().get("_beta_real") {
14489 Some(Value::Float(f)) => *f,
14490 _ => 0.0,
14491 };
14492 let beta_imag = match fields.borrow().get("_beta_imag") {
14493 Some(Value::Float(f)) => *f,
14494 _ => 0.0,
14495 };
14496
14497 let (
14498 new_alpha_real,
14499 new_alpha_imag,
14500 new_beta_real,
14501 new_beta_imag,
14502 ) = match name.name.as_str() {
14503 "Rx" => {
14504 let cos_half = (angle / 2.0).cos();
14506 let sin_half = (angle / 2.0).sin();
14507 let nar = cos_half * alpha_real + sin_half * beta_imag;
14510 let nai = cos_half * alpha_imag - sin_half * beta_real;
14511 let nbr = sin_half * alpha_imag + cos_half * beta_real;
14512 let nbi = -sin_half * alpha_real + cos_half * beta_imag;
14513 (nar, nai, nbr, nbi)
14514 }
14515 "Ry" => {
14516 let cos_half = (angle / 2.0).cos();
14518 let sin_half = (angle / 2.0).sin();
14519 let nar = cos_half * alpha_real - sin_half * beta_real;
14520 let nai = cos_half * alpha_imag - sin_half * beta_imag;
14521 let nbr = sin_half * alpha_real + cos_half * beta_real;
14522 let nbi = sin_half * alpha_imag + cos_half * beta_imag;
14523 (nar, nai, nbr, nbi)
14524 }
14525 "Rz" => {
14526 let cos_half = (angle / 2.0).cos();
14528 let sin_half = (angle / 2.0).sin();
14529 let nar = cos_half * alpha_real + sin_half * alpha_imag;
14531 let nai =
14532 -sin_half * alpha_real + cos_half * alpha_imag;
14533 let nbr = cos_half * beta_real - sin_half * beta_imag;
14535 let nbi = sin_half * beta_real + cos_half * beta_imag;
14536 (nar, nai, nbr, nbi)
14537 }
14538 _ => (alpha_real, alpha_imag, beta_real, beta_imag),
14539 };
14540
14541 let mut new_fields = std::collections::HashMap::new();
14542 new_fields.insert(
14543 "_alpha_real".to_string(),
14544 Value::Float(new_alpha_real),
14545 );
14546 new_fields.insert(
14547 "_alpha_imag".to_string(),
14548 Value::Float(new_alpha_imag),
14549 );
14550 new_fields.insert(
14551 "_beta_real".to_string(),
14552 Value::Float(new_beta_real),
14553 );
14554 new_fields.insert(
14555 "_beta_imag".to_string(),
14556 Value::Float(new_beta_imag),
14557 );
14558 return Ok(Value::Struct {
14559 name: "Qubit".to_string(),
14560 fields: Rc::new(RefCell::new(new_fields)),
14561 });
14562 }
14563 }
14564 }
14565 if name.name == "observe" {
14567 if let Value::Struct {
14568 name: sname,
14569 fields,
14570 } = &value
14571 {
14572 if sname == "Superposition" {
14573 if let Some(Value::Array(values)) =
14575 fields.borrow().get("__values__")
14576 {
14577 let values_borrow = values.borrow();
14578 if !values_borrow.is_empty() {
14579 return Ok(values_borrow[0].clone());
14580 }
14581 }
14582 if let Some(Value::Array(values)) =
14584 fields.borrow().get("__elements__")
14585 {
14586 let values_borrow = values.borrow();
14587 if !values_borrow.is_empty() {
14588 return Ok(values_borrow[0].clone());
14589 }
14590 }
14591 if let Some(Value::Array(values)) =
14593 fields.borrow().get("_values")
14594 {
14595 let values_borrow = values.borrow();
14596 if !values_borrow.is_empty() {
14597 return Ok(values_borrow[0].clone());
14598 }
14599 }
14600 if let Some(Value::Array(states)) =
14602 fields.borrow().get("states")
14603 {
14604 let states_borrow = states.borrow();
14605 if !states_borrow.is_empty() {
14606 return Ok(states_borrow[0].clone());
14607 }
14608 }
14609 return Ok(Value::Null);
14610 }
14611 }
14612 }
14613 if name.name == "encode" {
14615 let data_shards = 4i64;
14617 let parity_shards = 3i64;
14618 let total_shards = data_shards + parity_shards;
14619
14620 let shards: Vec<Value> = (0..total_shards)
14622 .map(|i| {
14623 let mut shard_fields = std::collections::HashMap::new();
14624 shard_fields.insert("index".to_string(), Value::Int(i));
14625 shard_fields.insert(
14626 "data".to_string(),
14627 Value::String(Rc::new(format!("shard_{}", i))),
14628 );
14629 Value::Struct {
14630 name: "Shard".to_string(),
14631 fields: Rc::new(RefCell::new(shard_fields)),
14632 }
14633 })
14634 .collect();
14635
14636 let mut holo_fields = std::collections::HashMap::new();
14637 holo_fields.insert(
14638 "shards".to_string(),
14639 Value::Array(Rc::new(RefCell::new(shards))),
14640 );
14641 holo_fields.insert("_data_shards".to_string(), Value::Int(data_shards));
14642 holo_fields
14643 .insert("_parity_shards".to_string(), Value::Int(parity_shards));
14644 holo_fields.insert("_original".to_string(), value.clone());
14645
14646 return Ok(Value::Struct {
14647 name: "Hologram".to_string(),
14648 fields: Rc::new(RefCell::new(holo_fields)),
14649 });
14650 }
14651 if name.name == "requires_grad" {
14653 if let Value::Struct {
14654 name: sname,
14655 fields,
14656 } = &value
14657 {
14658 if sname == "Tensor" {
14659 let requires_grad = if !arg_values.is_empty() {
14661 match &arg_values[0] {
14662 Value::Bool(b) => *b,
14663 _ => true,
14664 }
14665 } else {
14666 true
14667 };
14668 let mut new_fields = fields.borrow().clone();
14670 new_fields.insert(
14671 "requires_grad".to_string(),
14672 Value::Bool(requires_grad),
14673 );
14674 return Ok(Value::Struct {
14675 name: "Tensor".to_string(),
14676 fields: Rc::new(RefCell::new(new_fields)),
14677 });
14678 }
14679 }
14680 }
14681 if name.name == "relu" {
14683 if let Value::Struct {
14684 name: sname,
14685 fields,
14686 } = &value
14687 {
14688 if sname == "Tensor" {
14689 let fields_ref = fields.borrow();
14690 let shape =
14692 fields_ref.get("__shape__").or_else(|| fields_ref.get("shape")).cloned().unwrap_or(Value::Null);
14693 let data: Vec<f64> = match fields_ref.get("__data__").or_else(|| fields_ref.get("data")) {
14695 Some(Value::Array(arr)) => arr
14696 .borrow()
14697 .iter()
14698 .filter_map(|v| match v {
14699 Value::Float(f) => Some(*f),
14700 Value::Int(n) => Some(*n as f64),
14701 _ => None,
14702 })
14703 .collect(),
14704 _ => vec![],
14705 };
14706 drop(fields_ref);
14707 let relu_data: Vec<Value> = data
14709 .iter()
14710 .map(|&x| Value::Float(if x > 0.0 { x } else { 0.0 }))
14711 .collect();
14712 let mut new_fields = std::collections::HashMap::new();
14713 new_fields.insert("__shape__".to_string(), shape.clone());
14715 new_fields.insert("shape".to_string(), shape);
14716 new_fields.insert(
14717 "__data__".to_string(),
14718 Value::Array(Rc::new(RefCell::new(relu_data.clone()))),
14719 );
14720 new_fields.insert(
14721 "data".to_string(),
14722 Value::Array(Rc::new(RefCell::new(relu_data))),
14723 );
14724 new_fields.insert("__requires_grad__".to_string(), Value::Bool(false));
14725 new_fields.insert("requires_grad".to_string(), Value::Bool(false));
14726 new_fields.insert("__grad__".to_string(), Value::Null);
14727 new_fields.insert("grad".to_string(), Value::Null);
14728 return Ok(Value::Struct {
14729 name: "Tensor".to_string(),
14730 fields: Rc::new(RefCell::new(new_fields)),
14731 });
14732 }
14733 }
14734 }
14735 if name.name == "softmax" {
14737 if let Value::Struct {
14738 name: sname,
14739 fields,
14740 } = &value
14741 {
14742 if sname == "Tensor" {
14743 let fields_ref = fields.borrow();
14744 let shape =
14746 fields_ref.get("__shape__").or_else(|| fields_ref.get("shape")).cloned().unwrap_or(Value::Null);
14747 let data: Vec<f64> = match fields_ref.get("__data__").or_else(|| fields_ref.get("data")) {
14749 Some(Value::Array(arr)) => arr
14750 .borrow()
14751 .iter()
14752 .filter_map(|v| match v {
14753 Value::Float(f) => Some(*f),
14754 Value::Int(n) => Some(*n as f64),
14755 _ => None,
14756 })
14757 .collect(),
14758 _ => vec![],
14759 };
14760 drop(fields_ref);
14761 let max_val =
14763 data.iter().cloned().fold(f64::NEG_INFINITY, f64::max);
14764 let exp_vals: Vec<f64> = data
14765 .iter()
14766 .map(|&x| (x - max_val).exp()) .collect();
14768 let sum_exp: f64 = exp_vals.iter().sum();
14769 let softmax_data: Vec<Value> = exp_vals
14770 .iter()
14771 .map(|&e| Value::Float(e / sum_exp))
14772 .collect();
14773 let mut new_fields = std::collections::HashMap::new();
14774 new_fields.insert("__shape__".to_string(), shape.clone());
14776 new_fields.insert("shape".to_string(), shape);
14777 new_fields.insert(
14778 "__data__".to_string(),
14779 Value::Array(Rc::new(RefCell::new(softmax_data.clone()))),
14780 );
14781 new_fields.insert(
14782 "data".to_string(),
14783 Value::Array(Rc::new(RefCell::new(softmax_data))),
14784 );
14785 new_fields.insert("__requires_grad__".to_string(), Value::Bool(false));
14786 new_fields.insert("requires_grad".to_string(), Value::Bool(false));
14787 new_fields.insert("__grad__".to_string(), Value::Null);
14788 new_fields.insert("grad".to_string(), Value::Null);
14789 return Ok(Value::Struct {
14790 name: "Tensor".to_string(),
14791 fields: Rc::new(RefCell::new(new_fields)),
14792 });
14793 }
14794 }
14795 }
14796 if name.name == "reshape" {
14798 if let Value::Struct {
14799 name: sname,
14800 fields,
14801 } = &value
14802 {
14803 if sname == "Tensor" {
14804 let fields_ref = fields.borrow();
14805 let data =
14807 fields_ref.get("__data__").or_else(|| fields_ref.get("data")).cloned().unwrap_or(Value::Null);
14808 drop(fields_ref);
14809 let new_shape = if !arg_values.is_empty() {
14811 match &arg_values[0] {
14812 Value::Array(arr) => Value::Array(arr.clone()),
14813 _ => arg_values[0].clone(),
14814 }
14815 } else {
14816 Value::Array(Rc::new(RefCell::new(vec![])))
14817 };
14818 let mut new_fields = std::collections::HashMap::new();
14819 new_fields.insert("__shape__".to_string(), new_shape.clone());
14821 new_fields.insert("shape".to_string(), new_shape);
14822 new_fields.insert("__data__".to_string(), data.clone());
14823 new_fields.insert("data".to_string(), data);
14824 new_fields.insert("__requires_grad__".to_string(), Value::Bool(false));
14825 new_fields.insert("requires_grad".to_string(), Value::Bool(false));
14826 new_fields.insert("__grad__".to_string(), Value::Null);
14827 new_fields.insert("grad".to_string(), Value::Null);
14828 return Ok(Value::Struct {
14829 name: "Tensor".to_string(),
14830 fields: Rc::new(RefCell::new(new_fields)),
14831 });
14832 }
14833 }
14834 }
14835 if name.name == "flatten" {
14837 if let Value::Struct {
14838 name: sname,
14839 fields,
14840 } = &value
14841 {
14842 if sname == "Tensor" {
14843 let fields_ref = fields.borrow();
14844 let data =
14846 fields_ref.get("__data__").or_else(|| fields_ref.get("data")).cloned().unwrap_or(Value::Null);
14847 let total_size: i64 = match &data {
14848 Value::Array(arr) => arr.borrow().len() as i64,
14849 _ => 0,
14850 };
14851 drop(fields_ref);
14852 let new_shape = Value::Array(Rc::new(RefCell::new(vec![Value::Int(total_size)])));
14853 let mut new_fields = std::collections::HashMap::new();
14854 new_fields.insert("__shape__".to_string(), new_shape.clone());
14856 new_fields.insert("shape".to_string(), new_shape);
14857 new_fields.insert("__data__".to_string(), data.clone());
14858 new_fields.insert("data".to_string(), data);
14859 new_fields.insert("__requires_grad__".to_string(), Value::Bool(false));
14860 new_fields.insert("requires_grad".to_string(), Value::Bool(false));
14861 new_fields.insert("__grad__".to_string(), Value::Null);
14862 new_fields.insert("grad".to_string(), Value::Null);
14863 return Ok(Value::Struct {
14864 name: "Tensor".to_string(),
14865 fields: Rc::new(RefCell::new(new_fields)),
14866 });
14867 }
14868 }
14869 }
14870 if name.name == "backward" {
14872 if let Value::Struct {
14873 name: sname,
14874 fields,
14875 } = &value
14876 {
14877 if sname == "Tensor" {
14878 self.backward_propagate(fields.clone())?;
14880 return Ok(Value::Null);
14881 }
14882 }
14883 if let Value::Float(_) = &value {
14885 return Ok(Value::Null);
14886 }
14887 }
14888
14889 if name.name == "scatter" {
14895 if arg_values.len() >= 2 {
14896 let n = match &arg_values[0] {
14897 Value::Int(n) => *n as usize,
14898 _ => 7,
14899 };
14900 let k = match &arg_values[1] {
14901 Value::Int(k) => *k as usize,
14902 _ => 4,
14903 };
14904 let original_value: i64 = match &value {
14907 Value::Int(v) => *v,
14908 Value::Struct { fields, .. } => {
14909 let fields_ref = fields.borrow();
14910 match fields_ref.get("__value__").or_else(|| fields_ref.get("value")) {
14912 Some(Value::Int(v)) => *v,
14913 _ => 0,
14914 }
14915 }
14916 _ => 0,
14917 };
14918
14919 let mut coeffs: Vec<i64> = vec![original_value];
14924 for i in 1..k {
14925 coeffs.push(
14927 (original_value
14928 .wrapping_mul(17)
14929 .wrapping_add(i as i64 * 31))
14930 % 997,
14931 );
14932 }
14933
14934 fn eval_poly(coeffs: &[i64], x: i64) -> i64 {
14937 let mut result: i64 = 0;
14938 let mut x_power: i64 = 1;
14939 for coeff in coeffs {
14940 result = result.wrapping_add(coeff.wrapping_mul(x_power));
14941 x_power = x_power.wrapping_mul(x);
14942 }
14943 result
14944 }
14945
14946 let mut shards = Vec::new();
14947 for i in 0..n {
14948 let x = (i + 1) as i64; let encoded_data = eval_poly(&coeffs, x);
14950
14951 let mut shard_fields = std::collections::HashMap::new();
14952 shard_fields.insert("index".to_string(), Value::Int(x));
14953 shard_fields
14954 .insert("data".to_string(), Value::Int(encoded_data));
14955 shard_fields
14956 .insert("_k_threshold".to_string(), Value::Int(k as i64));
14957 shard_fields.insert(
14958 "_original".to_string(),
14959 Value::Int(original_value),
14960 );
14961 shards.push(Value::Struct {
14962 name: "Shard".to_string(),
14963 fields: Rc::new(RefCell::new(shard_fields)),
14964 });
14965 }
14966 return Ok(Value::Array(Rc::new(RefCell::new(shards))));
14967 }
14968 }
14969
14970 if name.name == "measure" {
14972 match &value {
14973 Value::Struct {
14974 name: sname,
14975 fields,
14976 } if sname == "QHState" => {
14977 let fields_ref = fields.borrow();
14978 let inner =
14979 fields_ref.get("value").cloned().unwrap_or(Value::Null);
14980 match inner {
14982 Value::Array(arr) => {
14983 return Ok(arr
14984 .borrow()
14985 .first()
14986 .cloned()
14987 .unwrap_or(Value::Null));
14988 }
14989 _ => return Ok(inner),
14990 }
14991 }
14992 _ => return Ok(value.clone()),
14993 }
14994 }
14995
14996 if name.name == "observe" {
14998 match &value {
14999 Value::Struct {
15000 name: sname,
15001 fields,
15002 } => {
15003 let fields_ref = fields.borrow();
15004 if sname == "Superposition" {
15005 if let Some(Value::Array(states)) = fields_ref.get("states")
15007 {
15008 return Ok(states
15009 .borrow()
15010 .first()
15011 .cloned()
15012 .unwrap_or(Value::Null));
15013 }
15014 }
15015 if let Some(v) = fields_ref.get("value") {
15017 return Ok(v.clone());
15018 }
15019 drop(fields_ref);
15020 return Ok(value.clone());
15021 }
15022 _ => return Ok(value.clone()),
15023 }
15024 }
15025
15026 if name.name == "interfere" {
15028 if !arg_values.is_empty() {
15029 let mut fields = std::collections::HashMap::new();
15031 fields.insert("_state_a".to_string(), value.clone());
15032 fields.insert("_state_b".to_string(), arg_values[0].clone());
15033 fields.insert("_is_superposition".to_string(), Value::Bool(true));
15034 let inner_a = match &value {
15036 Value::Struct { fields: f, .. } => {
15037 f.borrow().get("value").cloned()
15038 }
15039 _ => None,
15040 };
15041 fields
15042 .insert("value".to_string(), inner_a.unwrap_or(Value::Int(2)));
15043 return Ok(Value::Struct {
15044 name: "QHState".to_string(),
15045 fields: Rc::new(RefCell::new(fields)),
15046 });
15047 }
15048 }
15049
15050 if name.name == "apply_noise" {
15052 let rate = if !arg_values.is_empty() {
15053 match &arg_values[0] {
15054 Value::Float(f) => *f,
15055 _ => 0.1,
15056 }
15057 } else {
15058 0.1
15059 };
15060 match &value {
15062 Value::Struct {
15063 name: sname,
15064 fields,
15065 } => {
15066 let mut new_fields = fields.borrow().clone();
15067 new_fields
15068 .insert("_noise_rate".to_string(), Value::Float(rate));
15069 new_fields.insert("_noisy".to_string(), Value::Bool(true));
15070 return Ok(Value::Struct {
15071 name: sname.clone(),
15072 fields: Rc::new(RefCell::new(new_fields)),
15073 });
15074 }
15075 _ => return Ok(value.clone()),
15076 }
15077 }
15078
15079 if name.name == "error_correct" {
15081 match &value {
15082 Value::Struct {
15083 name: sname,
15084 fields,
15085 } => {
15086 let mut new_fields = fields.borrow().clone();
15087 new_fields.remove("_noisy");
15088 new_fields.remove("_noise_rate");
15089 new_fields.insert("_corrected".to_string(), Value::Bool(true));
15090 return Ok(Value::Struct {
15091 name: sname.clone(),
15092 fields: Rc::new(RefCell::new(new_fields)),
15093 });
15094 }
15095 _ => return Ok(value.clone()),
15096 }
15097 }
15098
15099 if name.name == "teleport" {
15101 if arg_values.len() >= 2 {
15102 let inner = match &value {
15105 Value::Struct { fields, .. } => {
15106 let f = fields.borrow();
15107 f.get("__value__")
15108 .or_else(|| f.get("value"))
15109 .cloned()
15110 .unwrap_or(value.clone())
15111 }
15112 _ => value.clone(),
15113 };
15114 let mut fields = std::collections::HashMap::new();
15115 fields.insert("__value__".to_string(), inner);
15116 fields.insert("_teleported".to_string(), Value::Bool(true));
15117 return Ok(Value::Struct {
15118 name: "QHState".to_string(),
15119 fields: Rc::new(RefCell::new(fields)),
15120 });
15121 }
15122 }
15123
15124 if name.name == "qh_compress" {
15126 let size = match &value {
15127 Value::Array(arr) => arr.borrow().len() as i64 / 2,
15128 _ => 1,
15129 };
15130 let mut fields = std::collections::HashMap::new();
15131 fields.insert("data".to_string(), value.clone());
15132 fields.insert("_compressed_size".to_string(), Value::Int(size.max(1)));
15133 return Ok(Value::Struct {
15134 name: "QHCompressed".to_string(),
15135 fields: Rc::new(RefCell::new(fields)),
15136 });
15137 }
15138
15139 if name.name == "quantum_reconstruct" {
15141 fn extract_shard_data(shard: &Value) -> Option<Value> {
15143 if let Value::Struct { fields, .. } = shard {
15144 let fields_ref = fields.borrow();
15145 fields_ref.get("data")
15146 .or_else(|| fields_ref.get("__data__"))
15147 .cloned()
15148 } else {
15149 None
15150 }
15151 }
15152
15153 match &value {
15154 Value::Array(shards) => {
15156 if let Some(first) = shards.borrow().first() {
15157 if let Some(data) = extract_shard_data(first) {
15158 let mut qh_fields = std::collections::HashMap::new();
15159 qh_fields.insert("value".to_string(), data);
15160 qh_fields.insert("_reconstructed".to_string(), Value::Bool(true));
15161 return Ok(Value::Struct {
15162 name: "QHState".to_string(),
15163 fields: Rc::new(RefCell::new(qh_fields)),
15164 });
15165 }
15166 }
15167 let mut qh_fields = std::collections::HashMap::new();
15169 qh_fields.insert("value".to_string(), value.clone());
15170 qh_fields.insert("_reconstructed".to_string(), Value::Bool(true));
15171 return Ok(Value::Struct {
15172 name: "QHState".to_string(),
15173 fields: Rc::new(RefCell::new(qh_fields)),
15174 });
15175 }
15176 Value::Struct { fields, .. } => {
15178 let extracted_data: Option<Value> = {
15180 let fields_ref = fields.borrow();
15181 if let Some(Value::Array(shards)) = fields_ref.get("shards") {
15182 let shards_ref = shards.borrow();
15183 if let Some(first) = shards_ref.first() {
15184 extract_shard_data(first)
15185 } else {
15186 None
15187 }
15188 } else {
15189 None
15190 }
15191 };
15192
15193 if let Some(data) = extracted_data {
15194 let mut qh_fields = std::collections::HashMap::new();
15195 qh_fields.insert("value".to_string(), data);
15196 qh_fields.insert("_reconstructed".to_string(), Value::Bool(true));
15197 return Ok(Value::Struct {
15198 name: "QHState".to_string(),
15199 fields: Rc::new(RefCell::new(qh_fields)),
15200 });
15201 }
15202
15203 let mut qh_fields = std::collections::HashMap::new();
15205 qh_fields.insert("value".to_string(), Value::Int(42));
15206 qh_fields.insert("_reconstructed".to_string(), Value::Bool(true));
15207 return Ok(Value::Struct {
15208 name: "QHState".to_string(),
15209 fields: Rc::new(RefCell::new(qh_fields)),
15210 });
15211 }
15212 _ => {
15213 let mut qh_fields = std::collections::HashMap::new();
15214 qh_fields.insert("value".to_string(), value.clone());
15215 return Ok(Value::Struct {
15216 name: "QHState".to_string(),
15217 fields: Rc::new(RefCell::new(qh_fields)),
15218 });
15219 }
15220 }
15221 }
15222
15223 if name.name == "partial_trace" {
15225 match &value {
15226 Value::Struct {
15227 name: sname,
15228 fields,
15229 } if sname == "Entangled" => {
15230 let fields_ref = fields.borrow();
15231 let a = fields_ref.get("0").cloned().unwrap_or(Value::Null);
15232 let b = fields_ref.get("1").cloned().unwrap_or(Value::Null);
15233 let system = match a {
15235 Value::Struct { name, fields } => {
15236 let mut new_fields = fields.borrow().clone();
15237 new_fields
15238 .insert("_is_pure".to_string(), Value::Bool(false));
15239 Value::Struct {
15240 name,
15241 fields: Rc::new(RefCell::new(new_fields)),
15242 }
15243 }
15244 _ => a,
15245 };
15246 return Ok(Value::Tuple(Rc::new(vec![system, b])));
15247 }
15248 _ => {
15249 return Ok(Value::Tuple(Rc::new(vec![
15250 value.clone(),
15251 Value::Null,
15252 ])))
15253 }
15254 }
15255 }
15256
15257 if name.name == "verify" {
15259 match &value {
15261 Value::Struct { fields, .. } => {
15262 let fields_ref = fields.borrow();
15263 if let Some(v) = fields_ref.get("value") {
15264 return Ok(v.clone());
15265 }
15266 drop(fields_ref);
15267 return Ok(Value::Int(42)); }
15269 _ => return Ok(value.clone()),
15270 }
15271 }
15272
15273 if name.name == "is_pure" {
15275 match &value {
15276 Value::Struct { fields, .. } => {
15277 if let Some(Value::Bool(is_pure)) =
15278 fields.borrow().get("_is_pure")
15279 {
15280 return Ok(Value::Bool(*is_pure));
15281 }
15282 return Ok(Value::Bool(true)); }
15284 _ => return Ok(Value::Bool(true)),
15285 }
15286 }
15287
15288 if name.name == "size" {
15290 match &value {
15291 Value::Struct {
15292 name: sname,
15293 fields,
15294 } if sname == "QHCompressed" => {
15295 if let Some(Value::Int(size)) =
15296 fields.borrow().get("_compressed_size")
15297 {
15298 return Ok(Value::Int(*size));
15299 }
15300 }
15301 _ => {}
15302 }
15303 return Ok(Value::Int(1));
15304 }
15305
15306 Err(RuntimeError::new(format!(
15307 "Unknown pipe method: {}",
15308 name.name
15309 )))
15310 }
15311 }
15312 }
15313 PipeOp::Await => {
15314 self.await_value(value)
15316 }
15317 PipeOp::First => {
15319 match &value {
15321 Value::Array(arr) => arr
15322 .borrow()
15323 .first()
15324 .cloned()
15325 .ok_or_else(|| RuntimeError::new("first (α) on empty array")),
15326 Value::Tuple(t) => t
15327 .first()
15328 .cloned()
15329 .ok_or_else(|| RuntimeError::new("first (α) on empty tuple")),
15330 _ => Err(RuntimeError::new("first (α) requires array or tuple")),
15331 }
15332 }
15333 PipeOp::Last => {
15334 match &value {
15336 Value::Array(arr) => arr
15337 .borrow()
15338 .last()
15339 .cloned()
15340 .ok_or_else(|| RuntimeError::new("last (ω) on empty array")),
15341 Value::Tuple(t) => t
15342 .last()
15343 .cloned()
15344 .ok_or_else(|| RuntimeError::new("last (ω) on empty tuple")),
15345 _ => Err(RuntimeError::new("last (ω) requires array or tuple")),
15346 }
15347 }
15348 PipeOp::Middle => {
15349 match &value {
15351 Value::Array(arr) => {
15352 let arr = arr.borrow();
15353 if arr.is_empty() {
15354 return Err(RuntimeError::new("middle (μ) on empty array"));
15355 }
15356 let mid = arr.len() / 2;
15357 Ok(arr[mid].clone())
15358 }
15359 Value::Tuple(t) => {
15360 if t.is_empty() {
15361 return Err(RuntimeError::new("middle (μ) on empty tuple"));
15362 }
15363 let mid = t.len() / 2;
15364 Ok(t[mid].clone())
15365 }
15366 _ => Err(RuntimeError::new("middle (μ) requires array or tuple")),
15367 }
15368 }
15369 PipeOp::Choice => {
15370 use std::time::{SystemTime, UNIX_EPOCH};
15372 match &value {
15373 Value::Array(arr) => {
15374 let arr = arr.borrow();
15375 if arr.is_empty() {
15376 return Err(RuntimeError::new("choice (χ) on empty array"));
15377 }
15378 let seed = SystemTime::now()
15379 .duration_since(UNIX_EPOCH)
15380 .unwrap_or(std::time::Duration::ZERO)
15381 .as_nanos() as u64;
15382 let idx = ((seed.wrapping_mul(1103515245).wrapping_add(12345)) >> 16)
15383 as usize
15384 % arr.len();
15385 Ok(arr[idx].clone())
15386 }
15387 Value::Tuple(t) => {
15388 if t.is_empty() {
15389 return Err(RuntimeError::new("choice (χ) on empty tuple"));
15390 }
15391 let seed = SystemTime::now()
15392 .duration_since(UNIX_EPOCH)
15393 .unwrap_or(std::time::Duration::ZERO)
15394 .as_nanos() as u64;
15395 let idx = ((seed.wrapping_mul(1103515245).wrapping_add(12345)) >> 16)
15396 as usize
15397 % t.len();
15398 Ok(t[idx].clone())
15399 }
15400 _ => Err(RuntimeError::new("choice (χ) requires array or tuple")),
15401 }
15402 }
15403 PipeOp::Nth(index_expr) => {
15404 let index = match self.evaluate(index_expr)? {
15406 Value::Int(n) => n,
15407 _ => return Err(RuntimeError::new("nth (ν) index must be integer")),
15408 };
15409 match &value {
15410 Value::Array(arr) => {
15411 let arr = arr.borrow();
15412 if index < 0 || index as usize >= arr.len() {
15413 return Err(RuntimeError::new("nth (ν) index out of bounds"));
15414 }
15415 Ok(arr[index as usize].clone())
15416 }
15417 Value::Tuple(t) => {
15418 if index < 0 || index as usize >= t.len() {
15419 return Err(RuntimeError::new("nth (ν) index out of bounds"));
15420 }
15421 Ok(t[index as usize].clone())
15422 }
15423 _ => Err(RuntimeError::new("nth (ν) requires array or tuple")),
15424 }
15425 }
15426 PipeOp::Next => {
15427 match &value {
15430 Value::Array(arr) => arr
15431 .borrow()
15432 .first()
15433 .cloned()
15434 .ok_or_else(|| RuntimeError::new("next (ξ) on empty array")),
15435 Value::Tuple(t) => t
15436 .first()
15437 .cloned()
15438 .ok_or_else(|| RuntimeError::new("next (ξ) on empty tuple")),
15439 _ => Err(RuntimeError::new("next (ξ) requires array or tuple")),
15440 }
15441 }
15442 PipeOp::Named { prefix, body } => {
15443 let method_name = prefix
15445 .iter()
15446 .map(|i| i.name.as_str())
15447 .collect::<Vec<_>>()
15448 .join("·");
15449 match method_name.as_str() {
15450 "map" => {
15451 if let Some(body) = body {
15452 match value {
15453 Value::Array(arr) => {
15454 let results: Vec<Value> = arr
15455 .borrow()
15456 .iter()
15457 .map(|item| {
15458 self.environment
15459 .borrow_mut()
15460 .define("_".to_string(), item.clone());
15461 self.evaluate(body)
15462 })
15463 .collect::<Result<_, _>>()?;
15464 Ok(Value::Array(Rc::new(RefCell::new(results))))
15465 }
15466 _ => Err(RuntimeError::new("map requires array")),
15467 }
15468 } else {
15469 Ok(value)
15470 }
15471 }
15472 "filter" => {
15473 if let Some(body) = body {
15474 match value {
15475 Value::Array(arr) => {
15476 let results: Vec<Value> = arr
15477 .borrow()
15478 .iter()
15479 .filter_map(|item| {
15480 self.environment
15481 .borrow_mut()
15482 .define("_".to_string(), item.clone());
15483 match self.evaluate(body) {
15484 Ok(v) if self.is_truthy(&v) => {
15485 Some(Ok(item.clone()))
15486 }
15487 Ok(_) => None,
15488 Err(e) => Some(Err(e)),
15489 }
15490 })
15491 .collect::<Result<_, _>>()?;
15492 Ok(Value::Array(Rc::new(RefCell::new(results))))
15493 }
15494 _ => Err(RuntimeError::new("filter requires array")),
15495 }
15496 } else {
15497 Ok(value)
15498 }
15499 }
15500 "all" => {
15501 if let Some(body) = body {
15502 match value {
15503 Value::Array(arr) => {
15504 for item in arr.borrow().iter() {
15505 self.environment
15506 .borrow_mut()
15507 .define("_".to_string(), item.clone());
15508 let result = self.evaluate(body)?;
15509 if !self.is_truthy(&result) {
15510 return Ok(Value::Bool(false));
15511 }
15512 }
15513 Ok(Value::Bool(true))
15514 }
15515 _ => Err(RuntimeError::new("all requires array")),
15516 }
15517 } else {
15518 match value {
15520 Value::Array(arr) => {
15521 for item in arr.borrow().iter() {
15522 if !self.is_truthy(item) {
15523 return Ok(Value::Bool(false));
15524 }
15525 }
15526 Ok(Value::Bool(true))
15527 }
15528 _ => Err(RuntimeError::new("all requires array")),
15529 }
15530 }
15531 }
15532 "any" => {
15533 if let Some(body) = body {
15534 match value {
15535 Value::Array(arr) => {
15536 for item in arr.borrow().iter() {
15537 self.environment
15538 .borrow_mut()
15539 .define("_".to_string(), item.clone());
15540 let result = self.evaluate(body)?;
15541 if self.is_truthy(&result) {
15542 return Ok(Value::Bool(true));
15543 }
15544 }
15545 Ok(Value::Bool(false))
15546 }
15547 _ => Err(RuntimeError::new("any requires array")),
15548 }
15549 } else {
15550 match value {
15552 Value::Array(arr) => {
15553 for item in arr.borrow().iter() {
15554 if self.is_truthy(item) {
15555 return Ok(Value::Bool(true));
15556 }
15557 }
15558 Ok(Value::Bool(false))
15559 }
15560 _ => Err(RuntimeError::new("any requires array")),
15561 }
15562 }
15563 }
15564 _ => Err(RuntimeError::new(format!(
15565 "Unknown named morpheme: {}",
15566 method_name
15567 ))),
15568 }
15569 }
15570 PipeOp::Parallel(inner_op) => {
15571 match value {
15574 Value::Array(arr) => {
15575 use std::sync::{Arc, Mutex};
15576
15577 let arr_ref = arr.borrow();
15578 let len = arr_ref.len();
15579 if len == 0 {
15580 return Ok(Value::Array(Rc::new(RefCell::new(vec![]))));
15581 }
15582
15583 match inner_op.as_ref() {
15585 PipeOp::Transform(body) => {
15586 let num_threads = std::thread::available_parallelism()
15588 .map(|p| p.get())
15589 .unwrap_or(4)
15590 .min(len);
15591
15592 let _chunk_size = (len + num_threads - 1) / num_threads;
15594 let _results = Arc::new(Mutex::new(vec![Value::Null; len]));
15595 let items: Vec<Value> = arr_ref.clone();
15596 drop(arr_ref);
15597
15598 let _body_str = format!("{:?}", body);
15600
15601 let mut result_vec = Vec::with_capacity(len);
15605 for item in items.iter() {
15606 self.environment
15607 .borrow_mut()
15608 .define("_".to_string(), item.clone());
15609 result_vec.push(self.evaluate(body)?);
15610 }
15611 Ok(Value::Array(Rc::new(RefCell::new(result_vec))))
15612 }
15613 PipeOp::Filter(predicate) => {
15614 let items: Vec<Value> = arr_ref.clone();
15616 drop(arr_ref);
15617
15618 let mut result_vec = Vec::new();
15619 for item in items.iter() {
15620 self.environment
15621 .borrow_mut()
15622 .define("_".to_string(), item.clone());
15623 let pred_result = self.evaluate(predicate)?;
15624 if self.is_truthy(&pred_result) {
15625 result_vec.push(item.clone());
15626 }
15627 }
15628 Ok(Value::Array(Rc::new(RefCell::new(result_vec))))
15629 }
15630 _ => {
15631 drop(arr_ref);
15633 self.apply_pipe_op(Value::Array(arr), inner_op)
15634 }
15635 }
15636 }
15637 _ => {
15638 self.apply_pipe_op(value, inner_op)
15640 }
15641 }
15642 }
15643 PipeOp::Gpu(inner_op) => {
15644 match value {
15651 Value::Array(arr) => {
15652 #[cfg(debug_assertions)]
15655 eprintln!(
15656 "[GPU] Would execute {:?} on GPU, falling back to CPU",
15657 inner_op
15658 );
15659
15660 self.apply_pipe_op(Value::Array(arr), inner_op)
15661 }
15662 _ => self.apply_pipe_op(value, inner_op),
15663 }
15664 }
15665
15666 PipeOp::Send(data_expr) => {
15672 let data = self.evaluate(data_expr)?;
15675
15676 let response = self.protocol_send(&value, &data)?;
15679
15680 Ok(self.wrap_reported(response))
15682 }
15683
15684 PipeOp::Recv => {
15685 let response = self.protocol_recv(&value)?;
15690
15691 Ok(self.wrap_reported(response))
15693 }
15694
15695 PipeOp::Stream(handler_expr) => {
15696 let handler = self.evaluate(handler_expr)?;
15698
15699 let stream = self.protocol_stream(&value, &handler)?;
15702 Ok(stream)
15703 }
15704
15705 PipeOp::Connect(config_expr) => {
15706 let config = match config_expr {
15708 Some(expr) => Some(self.evaluate(expr)?),
15709 None => None,
15710 };
15711
15712 let connection = self.protocol_connect(&value, config.as_ref())?;
15714 Ok(connection)
15715 }
15716
15717 PipeOp::Close => {
15718 self.protocol_close(&value)?;
15720 Ok(Value::Null)
15721 }
15722
15723 PipeOp::Header {
15724 name,
15725 value: value_expr,
15726 } => {
15727 let header_name = self.evaluate(name)?;
15729 let header_value = self.evaluate(value_expr)?;
15730
15731 self.protocol_add_header(value, &header_name, &header_value)
15733 }
15734
15735 PipeOp::Body(data_expr) => {
15736 let body_data = self.evaluate(data_expr)?;
15738
15739 self.protocol_set_body(value, &body_data)
15741 }
15742
15743 PipeOp::Timeout(ms_expr) => {
15744 let ms = self.evaluate(ms_expr)?;
15746
15747 self.protocol_set_timeout(value, &ms)
15749 }
15750
15751 PipeOp::Retry { count, strategy } => {
15752 let retry_count = self.evaluate(count)?;
15754 let retry_strategy = match strategy {
15755 Some(s) => Some(self.evaluate(s)?),
15756 None => None,
15757 };
15758
15759 self.protocol_set_retry(value, &retry_count, retry_strategy.as_ref())
15761 }
15762
15763 PipeOp::Validate {
15767 predicate,
15768 target_evidence,
15769 } => {
15770 let predicate_result = match predicate.as_ref() {
15773 Expr::Closure { params, body, .. } => {
15774 if let Some(param) = params.first() {
15775 let param_name = match ¶m.pattern {
15776 Pattern::Ident { name, .. } => name.name.clone(),
15777 _ => "it".to_string(),
15778 };
15779 self.environment
15780 .borrow_mut()
15781 .define(param_name, value.clone());
15782 }
15783 self.evaluate(body)?
15784 }
15785 _ => self.evaluate(predicate)?,
15786 };
15787
15788 match predicate_result {
15790 Value::Bool(true) => {
15791 let target_ev = match target_evidence {
15793 Evidentiality::Known => Evidence::Known,
15794 Evidentiality::Uncertain | Evidentiality::Predicted => {
15795 Evidence::Uncertain
15796 }
15797 Evidentiality::Reported => Evidence::Reported,
15798 Evidentiality::Paradox => Evidence::Paradox,
15799 };
15800 let inner = match value {
15801 Value::Evidential { value: v, .. } => *v,
15802 v => v,
15803 };
15804 Ok(Value::Evidential {
15805 value: Box::new(inner),
15806 evidence: target_ev,
15807 })
15808 }
15809 Value::Bool(false) => Err(RuntimeError::new(
15810 "validation failed: predicate returned false",
15811 )),
15812 _ => Err(RuntimeError::new("validation predicate must return bool")),
15813 }
15814 }
15815
15816 PipeOp::Assume {
15817 reason,
15818 target_evidence,
15819 } => {
15820 let reason_str: Rc<String> = if let Some(r) = reason {
15822 match self.evaluate(r)? {
15823 Value::String(s) => s,
15824 _ => Rc::new("<no reason>".to_string()),
15825 }
15826 } else {
15827 Rc::new("<no reason>".to_string())
15828 };
15829
15830 #[cfg(debug_assertions)]
15832 eprintln!(
15833 "[AUDIT] Evidence assumption: {} - reason: {}",
15834 match target_evidence {
15835 Evidentiality::Known => "!",
15836 Evidentiality::Uncertain | Evidentiality::Predicted => "?",
15837 Evidentiality::Reported => "~",
15838 Evidentiality::Paradox => "‽",
15839 },
15840 reason_str
15841 );
15842
15843 let target_ev = match target_evidence {
15844 Evidentiality::Known => Evidence::Known,
15845 Evidentiality::Uncertain | Evidentiality::Predicted => Evidence::Uncertain,
15846 Evidentiality::Reported => Evidence::Reported,
15847 Evidentiality::Paradox => Evidence::Paradox,
15848 };
15849
15850 let inner = match value {
15851 Value::Evidential { value: v, .. } => *v,
15852 v => v,
15853 };
15854
15855 Ok(Value::Evidential {
15856 value: Box::new(inner),
15857 evidence: target_ev,
15858 })
15859 }
15860
15861 PipeOp::AssertEvidence(expected) => {
15862 let actual_evidence = match &value {
15864 Value::Evidential { evidence, .. } => evidence.clone(),
15865 _ => Evidence::Known,
15866 };
15867
15868 let expected_ev = match expected {
15869 Evidentiality::Known => Evidence::Known,
15870 Evidentiality::Uncertain | Evidentiality::Predicted => Evidence::Uncertain,
15871 Evidentiality::Reported => Evidence::Reported,
15872 Evidentiality::Paradox => Evidence::Paradox,
15873 };
15874
15875 let satisfies = match (&actual_evidence, &expected_ev) {
15877 (Evidence::Known, _) => true,
15878 (
15879 Evidence::Uncertain,
15880 Evidence::Uncertain | Evidence::Reported | Evidence::Paradox,
15881 ) => true,
15882 (Evidence::Reported, Evidence::Reported | Evidence::Paradox) => true,
15883 (Evidence::Paradox, Evidence::Paradox) => true,
15884 _ => false,
15885 };
15886
15887 if satisfies {
15888 Ok(value)
15889 } else {
15890 Err(RuntimeError::new(format!(
15891 "evidence assertion failed: expected {:?}, found {:?}",
15892 expected_ev, actual_evidence
15893 )))
15894 }
15895 }
15896
15897 PipeOp::PossibilityExtract => {
15898 match &value {
15901 Value::Array(arr) => {
15902 let arr = arr.borrow();
15903 arr.first()
15904 .cloned()
15905 .ok_or_else(|| RuntimeError::new("possibility (◊) on empty array"))
15906 }
15907 Value::Variant { variant_name, fields, .. } if variant_name == "Some" => {
15908 Ok(fields.as_ref()
15909 .and_then(|f| f.first().cloned())
15910 .unwrap_or(Value::Null))
15911 }
15912 _ => Ok(value),
15913 }
15914 }
15915
15916 PipeOp::NecessityVerify => {
15917 match &value {
15920 Value::Array(arr) => {
15921 let arr = arr.borrow();
15922 if arr.is_empty() {
15923 return Err(RuntimeError::new("necessity (□) verification failed: empty array"));
15924 }
15925 Ok(value.clone())
15926 }
15927 Value::Variant { variant_name, fields, .. } if variant_name == "Some" => {
15928 Ok(fields.as_ref()
15929 .and_then(|f| f.first().cloned())
15930 .unwrap_or(Value::Null))
15931 }
15932 Value::Variant { variant_name, .. } if variant_name == "None" => {
15933 Err(RuntimeError::new("necessity (□) verification failed: None"))
15934 }
15935 _ => Ok(value),
15936 }
15937 }
15938
15939 PipeOp::Also(func) => {
15943 match func.as_ref() {
15946 Expr::Closure { params, body, .. } => {
15947 if let Some(param) = params.first() {
15948 let param_name = match ¶m.pattern {
15949 Pattern::Ident { name, .. } => name.name.clone(),
15950 _ => "it".to_string(),
15951 };
15952 self.environment
15953 .borrow_mut()
15954 .define(param_name, value.clone());
15955 }
15956 let _ = self.evaluate(body);
15958 }
15959 _ => {
15960 let _ = self.evaluate(func);
15962 }
15963 }
15964 Ok(value)
15966 }
15967
15968 PipeOp::Apply(func) => {
15969 match func.as_ref() {
15972 Expr::Closure { params, body, .. } => {
15973 if let Some(param) = params.first() {
15974 let param_name = match ¶m.pattern {
15975 Pattern::Ident { name, .. } => name.name.clone(),
15976 _ => "it".to_string(),
15977 };
15978 self.environment
15979 .borrow_mut()
15980 .define(param_name, value.clone());
15981 }
15982 let _ = self.evaluate(body);
15984 }
15985 _ => {
15986 let _ = self.evaluate(func);
15987 }
15988 }
15989 Ok(value)
15991 }
15992
15993 PipeOp::TakeIf(predicate) => {
15994 let predicate_result = match predicate.as_ref() {
15996 Expr::Closure { params, body, .. } => {
15997 if let Some(param) = params.first() {
15998 let param_name = match ¶m.pattern {
15999 Pattern::Ident { name, .. } => name.name.clone(),
16000 _ => "it".to_string(),
16001 };
16002 self.environment
16003 .borrow_mut()
16004 .define(param_name, value.clone());
16005 }
16006 self.evaluate(body)?
16007 }
16008 _ => self.evaluate(predicate)?,
16009 };
16010
16011 match predicate_result {
16012 Value::Bool(true) => Ok(Value::Variant {
16013 enum_name: "Option".to_string(),
16014 variant_name: "Some".to_string(),
16015 fields: Some(Rc::new(vec![value])),
16016 }),
16017 Value::Bool(false) => Ok(Value::Variant {
16018 enum_name: "Option".to_string(),
16019 variant_name: "None".to_string(),
16020 fields: None,
16021 }),
16022 _ => Err(RuntimeError::new("take_if predicate must return bool")),
16023 }
16024 }
16025
16026 PipeOp::TakeUnless(predicate) => {
16027 let predicate_result = match predicate.as_ref() {
16029 Expr::Closure { params, body, .. } => {
16030 if let Some(param) = params.first() {
16031 let param_name = match ¶m.pattern {
16032 Pattern::Ident { name, .. } => name.name.clone(),
16033 _ => "it".to_string(),
16034 };
16035 self.environment
16036 .borrow_mut()
16037 .define(param_name, value.clone());
16038 }
16039 self.evaluate(body)?
16040 }
16041 _ => self.evaluate(predicate)?,
16042 };
16043
16044 match predicate_result {
16045 Value::Bool(false) => Ok(Value::Variant {
16046 enum_name: "Option".to_string(),
16047 variant_name: "Some".to_string(),
16048 fields: Some(Rc::new(vec![value])),
16049 }),
16050 Value::Bool(true) => Ok(Value::Variant {
16051 enum_name: "Option".to_string(),
16052 variant_name: "None".to_string(),
16053 fields: None,
16054 }),
16055 _ => Err(RuntimeError::new("take_unless predicate must return bool")),
16056 }
16057 }
16058
16059 PipeOp::Let(func) => {
16060 match func.as_ref() {
16062 Expr::Closure { params, body, .. } => {
16063 if let Some(param) = params.first() {
16064 let param_name = match ¶m.pattern {
16065 Pattern::Ident { name, .. } => name.name.clone(),
16066 _ => "it".to_string(),
16067 };
16068 self.environment
16069 .borrow_mut()
16070 .define(param_name, value.clone());
16071 }
16072 self.evaluate(body)
16073 }
16074 _ => self.evaluate(func),
16075 }
16076 }
16077
16078 PipeOp::All(pred) => {
16082 match value {
16084 Value::Array(arr) => {
16085 for elem in arr.borrow().iter() {
16086 self.environment
16087 .borrow_mut()
16088 .define("_".to_string(), elem.clone());
16089 let result = self.evaluate(pred)?;
16090 if !self.is_truthy(&result) {
16091 return Ok(Value::Bool(false));
16092 }
16093 }
16094 Ok(Value::Bool(true))
16095 }
16096 _ => Err(RuntimeError::new("All requires array")),
16097 }
16098 }
16099
16100 PipeOp::Any(pred) => {
16101 match value {
16103 Value::Array(arr) => {
16104 for elem in arr.borrow().iter() {
16105 self.environment
16106 .borrow_mut()
16107 .define("_".to_string(), elem.clone());
16108 let result = self.evaluate(pred)?;
16109 if self.is_truthy(&result) {
16110 return Ok(Value::Bool(true));
16111 }
16112 }
16113 Ok(Value::Bool(false))
16114 }
16115 _ => Err(RuntimeError::new("Any requires array")),
16116 }
16117 }
16118
16119 PipeOp::Compose(f) => {
16120 self.environment.borrow_mut().define("_".to_string(), value);
16122 self.evaluate(f)
16123 }
16124
16125 PipeOp::Zip(other_expr) => {
16126 let other = self.evaluate(other_expr)?;
16128 match (value, other) {
16129 (Value::Array(arr1), Value::Array(arr2)) => {
16130 let zipped: Vec<Value> = arr1
16131 .borrow()
16132 .iter()
16133 .zip(arr2.borrow().iter())
16134 .map(|(a, b)| Value::Tuple(Rc::new(vec![a.clone(), b.clone()])))
16135 .collect();
16136 Ok(Value::Array(Rc::new(RefCell::new(zipped))))
16137 }
16138 _ => Err(RuntimeError::new("Zip requires two arrays")),
16139 }
16140 }
16141
16142 PipeOp::Scan(f) => {
16143 match value {
16145 Value::Array(arr) => {
16146 let arr = arr.borrow();
16147 if arr.is_empty() {
16148 return Ok(Value::Array(Rc::new(RefCell::new(vec![]))));
16149 }
16150 let mut results = vec![arr[0].clone()];
16151 let mut acc = arr[0].clone();
16152 for elem in arr.iter().skip(1) {
16153 self.environment
16154 .borrow_mut()
16155 .define("acc".to_string(), acc.clone());
16156 self.environment
16157 .borrow_mut()
16158 .define("_".to_string(), elem.clone());
16159 acc = self.evaluate(f)?;
16160 results.push(acc.clone());
16161 }
16162 Ok(Value::Array(Rc::new(RefCell::new(results))))
16163 }
16164 _ => Err(RuntimeError::new("Scan requires array")),
16165 }
16166 }
16167
16168 PipeOp::Diff => {
16169 match value {
16171 Value::Array(arr) => {
16172 let arr = arr.borrow();
16173 if arr.len() < 2 {
16174 return Ok(Value::Array(Rc::new(RefCell::new(vec![]))));
16175 }
16176 let mut diffs = Vec::new();
16177 for i in 1..arr.len() {
16178 let diff = self.subtract_values(&arr[i], &arr[i - 1])?;
16179 diffs.push(diff);
16180 }
16181 Ok(Value::Array(Rc::new(RefCell::new(diffs))))
16182 }
16183 _ => Err(RuntimeError::new("Diff requires array")),
16184 }
16185 }
16186
16187 PipeOp::Gradient(var_expr) => {
16188 let _ = var_expr;
16191 Ok(Value::Float(0.0)) }
16193
16194 PipeOp::SortAsc => {
16195 match value {
16197 Value::Array(arr) => {
16198 let mut v = arr.borrow().clone();
16199 v.sort_by(|a, b| self.compare_values(a, b, &None));
16200 Ok(Value::Array(Rc::new(RefCell::new(v))))
16201 }
16202 _ => Err(RuntimeError::new("SortAsc requires array")),
16203 }
16204 }
16205
16206 PipeOp::SortDesc => {
16207 match value {
16209 Value::Array(arr) => {
16210 let mut v = arr.borrow().clone();
16211 v.sort_by(|a, b| self.compare_values(b, a, &None));
16212 Ok(Value::Array(Rc::new(RefCell::new(v))))
16213 }
16214 _ => Err(RuntimeError::new("SortDesc requires array")),
16215 }
16216 }
16217
16218 PipeOp::Reverse => {
16219 match value {
16221 Value::Array(arr) => {
16222 let mut v = arr.borrow().clone();
16223 v.reverse();
16224 Ok(Value::Array(Rc::new(RefCell::new(v))))
16225 }
16226 _ => Err(RuntimeError::new("Reverse requires array")),
16227 }
16228 }
16229
16230 PipeOp::Cycle(n_expr) => {
16231 match value {
16233 Value::Array(arr) => {
16234 let n_val = self.evaluate(n_expr)?;
16235 let n = match n_val {
16236 Value::Int(i) => i as usize,
16237 _ => return Err(RuntimeError::new("Cycle count must be integer")),
16238 };
16239 let arr = arr.borrow();
16240 let cycled: Vec<Value> =
16241 arr.iter().cloned().cycle().take(arr.len() * n).collect();
16242 Ok(Value::Array(Rc::new(RefCell::new(cycled))))
16243 }
16244 _ => Err(RuntimeError::new("Cycle requires array")),
16245 }
16246 }
16247
16248 PipeOp::Windows(n_expr) => {
16249 match value {
16251 Value::Array(arr) => {
16252 let n_val = self.evaluate(n_expr)?;
16253 let n = match n_val {
16254 Value::Int(i) => i as usize,
16255 _ => return Err(RuntimeError::new("Window size must be integer")),
16256 };
16257 let arr = arr.borrow();
16258 let windows: Vec<Value> = arr
16259 .windows(n)
16260 .map(|w| Value::Array(Rc::new(RefCell::new(w.to_vec()))))
16261 .collect();
16262 Ok(Value::Array(Rc::new(RefCell::new(windows))))
16263 }
16264 _ => Err(RuntimeError::new("Windows requires array")),
16265 }
16266 }
16267
16268 PipeOp::Chunks(n_expr) => {
16269 match value {
16271 Value::Array(arr) => {
16272 let n_val = self.evaluate(n_expr)?;
16273 let n = match n_val {
16274 Value::Int(i) => i as usize,
16275 _ => return Err(RuntimeError::new("Chunk size must be integer")),
16276 };
16277 let arr = arr.borrow();
16278 let chunks: Vec<Value> = arr
16279 .chunks(n)
16280 .map(|c| Value::Array(Rc::new(RefCell::new(c.to_vec()))))
16281 .collect();
16282 Ok(Value::Array(Rc::new(RefCell::new(chunks))))
16283 }
16284 _ => Err(RuntimeError::new("Chunks requires array")),
16285 }
16286 }
16287
16288 PipeOp::Flatten => {
16289 match value {
16291 Value::Array(arr) => {
16292 let mut flat = Vec::new();
16293 for elem in arr.borrow().iter() {
16294 match elem {
16295 Value::Array(inner) => {
16296 flat.extend(inner.borrow().iter().cloned());
16297 }
16298 other => flat.push(other.clone()),
16299 }
16300 }
16301 Ok(Value::Array(Rc::new(RefCell::new(flat))))
16302 }
16303 _ => Err(RuntimeError::new("Flatten requires array")),
16304 }
16305 }
16306
16307 PipeOp::Unique => {
16308 match value {
16310 Value::Array(arr) => {
16311 let mut seen = std::collections::HashSet::new();
16312 let mut unique = Vec::new();
16313 for elem in arr.borrow().iter() {
16314 let key = format!("{:?}", elem);
16315 if seen.insert(key) {
16316 unique.push(elem.clone());
16317 }
16318 }
16319 Ok(Value::Array(Rc::new(RefCell::new(unique))))
16320 }
16321 _ => Err(RuntimeError::new("Unique requires array")),
16322 }
16323 }
16324
16325 PipeOp::Enumerate => {
16326 match value {
16328 Value::Array(arr) => {
16329 let enumerated: Vec<Value> = arr
16330 .borrow()
16331 .iter()
16332 .enumerate()
16333 .map(|(i, v)| {
16334 Value::Tuple(Rc::new(vec![Value::Int(i as i64), v.clone()]))
16335 })
16336 .collect();
16337 Ok(Value::Array(Rc::new(RefCell::new(enumerated))))
16338 }
16339 _ => Err(RuntimeError::new("Enumerate requires array")),
16340 }
16341 }
16342
16343 PipeOp::Universal => {
16347 match value {
16351 Value::Struct { name, fields } => {
16353 let fields_ref = fields.borrow();
16354 if name == "Hologram" || name == "EntangledHologram" {
16356 if let Some(v) = fields_ref.get("__value__").or_else(|| fields_ref.get("value")) {
16357 return Ok(v.clone());
16358 }
16359 }
16360 if name == "QHState" {
16362 if let Some(v) = fields_ref.get("__value__").or_else(|| fields_ref.get("value")) {
16363 return Ok(v.clone());
16364 }
16365 }
16366 if name == "Superposition" {
16368 if let Some(Value::Array(states)) = fields_ref.get("states").or_else(|| fields_ref.get("__values__")) {
16369 if let Some(first) = states.borrow().first() {
16370 if let Value::Struct {
16372 fields: inner_fields,
16373 ..
16374 } = first
16375 {
16376 let inner_fields_ref = inner_fields.borrow();
16377 if let Some(v) = inner_fields_ref.get("__value__").or_else(|| inner_fields_ref.get("value")) {
16378 return Ok(v.clone());
16379 }
16380 }
16381 return Ok(first.clone());
16382 }
16383 }
16384 }
16385 if let Some(v) = fields_ref.get("__value__").or_else(|| fields_ref.get("value")) {
16387 return Ok(v.clone());
16388 }
16389 drop(fields_ref);
16390 return Ok(Value::Struct { name, fields });
16391 }
16392 Value::Array(arr) => {
16393 let arr = arr.borrow();
16394 if arr.is_empty() {
16395 return Ok(Value::Int(0));
16396 }
16397 if let Some(Value::Struct { name, .. }) = arr.first() {
16401 if name == "Shard" {
16402 let mut data_values: Vec<Value> = Vec::new();
16404 for shard in arr.iter() {
16405 if let Value::Struct { fields, .. } = shard {
16406 if let Some(data) = fields.borrow().get("data") {
16407 data_values.push(data.clone());
16408 }
16409 }
16410 }
16411
16412 if data_values.is_empty() {
16413 return Ok(Value::Int(0));
16414 }
16415
16416 let mut points: Vec<(i64, i64)> = Vec::new();
16418 let mut has_index_zero = false;
16419 for shard in arr.iter() {
16420 if let Value::Struct { fields, .. } = shard {
16421 let fields_ref = fields.borrow();
16422 let idx = fields_ref.get("index");
16423 let data = fields_ref.get("data");
16424 if let (Some(Value::Int(x)), Some(Value::Int(y))) =
16425 (idx, data)
16426 {
16427 if *x == 0 {
16428 has_index_zero = true;
16429 }
16430 points.push((*x, *y));
16431 }
16432 }
16433 }
16434
16435 if points.is_empty() {
16436 return Ok(Value::Int(0));
16437 }
16438
16439 let first_y = points[0].1;
16441 let all_same = points.iter().all(|(_, y)| *y == first_y);
16442 if all_same {
16443 return Ok(Value::Int(first_y));
16444 }
16445
16446 if has_index_zero {
16451 let mut total: i64 = 0;
16453 for (_, y) in &points {
16454 total += y;
16455 }
16456 return Ok(Value::Int(total));
16457 }
16458
16459 let mut result: f64 = 0.0;
16468 let n = points.len();
16469
16470 for i in 0..n {
16471 let (xi, yi) = points[i];
16472 let mut basis = 1.0f64;
16473
16474 for j in 0..n {
16475 if i != j {
16476 let xj = points[j].0 as f64;
16477 let xi_f = xi as f64;
16478 basis *= xj / (xj - xi_f);
16480 }
16481 }
16482
16483 result += (yi as f64) * basis;
16484 }
16485
16486 return Ok(Value::Int(result.round() as i64));
16488 }
16489 if name == "Hologram" {
16491 if let Value::Struct { fields, .. } = arr.first().unwrap() {
16492 if let Some(value) = fields.borrow().get("value") {
16493 return Ok(value.clone());
16494 }
16495 }
16496 }
16497 }
16498 let mut sum = 0i64;
16500 let mut has_float = false;
16501 let mut float_sum = 0.0f64;
16502 for elem in arr.iter() {
16503 match elem {
16504 Value::Int(i) => {
16505 sum += i;
16506 float_sum += *i as f64;
16507 }
16508 Value::Float(f) => {
16509 has_float = true;
16510 float_sum += f;
16511 }
16512 Value::Struct { fields, .. } => {
16514 if let Some(Value::Int(i)) = fields.borrow().get("value") {
16515 sum += i;
16516 float_sum += *i as f64;
16517 } else if let Some(Value::Float(f)) =
16518 fields.borrow().get("value")
16519 {
16520 has_float = true;
16521 float_sum += *f;
16522 } else if let Some(data) = fields.borrow().get("data") {
16523 return Ok(data.clone());
16525 }
16526 }
16527 _ => {} }
16529 }
16530 if has_float {
16531 Ok(Value::Float(float_sum))
16532 } else {
16533 Ok(Value::Int(sum))
16534 }
16535 }
16536 _ => Err(RuntimeError::new("Universal requires array")),
16537 }
16538 }
16539
16540 PipeOp::Possibility { method, args } => {
16541 let method_result = self.apply_pipe_op(
16547 value.clone(),
16548 &PipeOp::Method {
16549 name: method.clone(),
16550 type_args: None,
16551 args: args.clone(),
16552 },
16553 )?;
16554
16555 Ok(Value::Evidential {
16557 value: Box::new(method_result),
16558 evidence: Evidence::Predicted,
16559 })
16560 }
16561
16562 PipeOp::Necessity { method, args } => {
16563 let method_result = self.apply_pipe_op(
16568 value.clone(),
16569 &PipeOp::Method {
16570 name: method.clone(),
16571 type_args: None,
16572 args: args.clone(),
16573 },
16574 )?;
16575
16576 Ok(Value::Evidential {
16578 value: Box::new(method_result),
16579 evidence: Evidence::Known,
16580 })
16581 }
16582 }
16583 }
16584
16585 fn wrap_reported(&self, value: Value) -> Value {
16592 Value::Evidential {
16593 value: Box::new(value),
16594 evidence: Evidence::Reported,
16595 }
16596 }
16597
16598 fn protocol_send(&mut self, connection: &Value, data: &Value) -> Result<Value, RuntimeError> {
16600 match connection {
16602 Value::Map(obj) => {
16603 let obj = obj.borrow();
16604 if let Some(Value::String(protocol)) = obj.get("__protocol__") {
16605 match protocol.as_str() {
16606 "http" | "https" => {
16607 #[cfg(debug_assertions)]
16610 eprintln!("[HTTP] Would send request with body: {:?}", data);
16611 Ok(Value::Map(Rc::new(RefCell::new({
16612 let mut response = HashMap::new();
16613 response.insert("status".to_string(), Value::Int(200));
16614 response.insert("body".to_string(), data.clone());
16615 response.insert(
16616 "__protocol__".to_string(),
16617 Value::String(Rc::new("http_response".to_string())),
16618 );
16619 response
16620 }))))
16621 }
16622 "ws" | "wss" => {
16623 #[cfg(feature = "websocket")]
16626 {
16627 let url_str = obj.get("url")
16628 .and_then(|v| if let Value::String(s) = v { Some((**s).clone()) } else { None })
16629 .ok_or_else(|| RuntimeError::new("WebSocket connection missing URL"))?;
16630
16631 let message = match data {
16632 Value::String(s) => (**s).clone(),
16633 _ => format!("{}", data),
16634 };
16635
16636 match websocket::send_and_receive(&url_str, &message) {
16638 Ok(response) => Ok(Value::String(Rc::new(response))),
16639 Err(e) => Err(RuntimeError::new(format!("WebSocket error: {}", e))),
16640 }
16641 }
16642 #[cfg(not(feature = "websocket"))]
16643 {
16644 #[cfg(debug_assertions)]
16645 eprintln!("[WebSocket] Would send message: {:?} (feature disabled)", data);
16646 Ok(Value::Bool(true))
16647 }
16648 }
16649 "grpc" => {
16650 #[cfg(debug_assertions)]
16652 eprintln!("[gRPC] Would send message: {:?}", data);
16653 Ok(Value::Map(Rc::new(RefCell::new({
16654 let mut response = HashMap::new();
16655 response.insert("status".to_string(), Value::Int(0)); response.insert("message".to_string(), data.clone());
16657 response.insert(
16658 "__protocol__".to_string(),
16659 Value::String(Rc::new("grpc_response".to_string())),
16660 );
16661 response
16662 }))))
16663 }
16664 "kafka" => {
16665 #[cfg(debug_assertions)]
16667 eprintln!("[Kafka] Would produce message: {:?}", data);
16668 Ok(Value::Map(Rc::new(RefCell::new({
16669 let mut result = HashMap::new();
16670 result.insert("partition".to_string(), Value::Int(0));
16671 result.insert("offset".to_string(), Value::Int(42));
16672 result
16673 }))))
16674 }
16675 _ => Err(RuntimeError::new(format!("Unknown protocol: {}", protocol))),
16676 }
16677 } else {
16678 Err(RuntimeError::new(
16679 "Connection object missing __protocol__ field",
16680 ))
16681 }
16682 }
16683 _ => Err(RuntimeError::new("send requires a connection object")),
16684 }
16685 }
16686
16687 fn protocol_recv(&mut self, connection: &Value) -> Result<Value, RuntimeError> {
16689 match connection {
16690 Value::Map(obj) => {
16691 let obj = obj.borrow();
16692 if let Some(Value::String(protocol)) = obj.get("__protocol__") {
16693 match protocol.as_str() {
16694 "ws" | "wss" => {
16695 #[cfg(debug_assertions)]
16697 eprintln!("[WebSocket] Would receive message");
16698 Ok(Value::String(Rc::new("received message".to_string())))
16699 }
16700 "kafka" => {
16701 #[cfg(debug_assertions)]
16703 eprintln!("[Kafka] Would consume message");
16704 Ok(Value::Map(Rc::new(RefCell::new({
16705 let mut msg = HashMap::new();
16706 msg.insert("key".to_string(), Value::Null);
16707 msg.insert(
16708 "value".to_string(),
16709 Value::String(Rc::new("consumed message".to_string())),
16710 );
16711 msg.insert("partition".to_string(), Value::Int(0));
16712 msg.insert("offset".to_string(), Value::Int(100));
16713 msg
16714 }))))
16715 }
16716 "grpc" => {
16717 #[cfg(debug_assertions)]
16719 eprintln!("[gRPC] Would receive stream message");
16720 Ok(Value::Map(Rc::new(RefCell::new({
16721 let mut msg = HashMap::new();
16722 msg.insert(
16723 "data".to_string(),
16724 Value::String(Rc::new("stream data".to_string())),
16725 );
16726 msg
16727 }))))
16728 }
16729 _ => Err(RuntimeError::new(format!(
16730 "recv not supported for protocol: {}",
16731 protocol
16732 ))),
16733 }
16734 } else {
16735 Err(RuntimeError::new(
16736 "Connection object missing __protocol__ field",
16737 ))
16738 }
16739 }
16740 _ => Err(RuntimeError::new("recv requires a connection object")),
16741 }
16742 }
16743
16744 fn protocol_stream(
16746 &mut self,
16747 connection: &Value,
16748 _handler: &Value,
16749 ) -> Result<Value, RuntimeError> {
16750 match connection {
16752 Value::Map(obj) => {
16753 let obj = obj.borrow();
16754 if let Some(Value::String(protocol)) = obj.get("__protocol__") {
16755 #[cfg(debug_assertions)]
16756 eprintln!("[{}] Would create stream", protocol);
16757
16758 Ok(Value::Map(Rc::new(RefCell::new({
16760 let mut stream = HashMap::new();
16761 stream.insert(
16762 "__type__".to_string(),
16763 Value::String(Rc::new("Stream".to_string())),
16764 );
16765 stream.insert("__protocol__".to_string(), Value::String(protocol.clone()));
16766 stream.insert(
16767 "__evidentiality__".to_string(),
16768 Value::String(Rc::new("reported".to_string())),
16769 );
16770 stream
16771 }))))
16772 } else {
16773 Err(RuntimeError::new(
16774 "Connection object missing __protocol__ field",
16775 ))
16776 }
16777 }
16778 _ => Err(RuntimeError::new("stream requires a connection object")),
16779 }
16780 }
16781
16782 fn protocol_connect(
16784 &mut self,
16785 target: &Value,
16786 _config: Option<&Value>,
16787 ) -> Result<Value, RuntimeError> {
16788 match target {
16789 Value::String(url) => {
16790 let protocol = if url.starts_with("wss://") || url.starts_with("ws://") {
16792 if url.starts_with("wss://") {
16793 "wss"
16794 } else {
16795 "ws"
16796 }
16797 } else if url.starts_with("https://") || url.starts_with("http://") {
16798 if url.starts_with("https://") {
16799 "https"
16800 } else {
16801 "http"
16802 }
16803 } else if url.starts_with("grpc://") || url.starts_with("grpcs://") {
16804 "grpc"
16805 } else if url.starts_with("kafka://") {
16806 "kafka"
16807 } else if url.starts_with("amqp://") || url.starts_with("amqps://") {
16808 "amqp"
16809 } else {
16810 "unknown"
16811 };
16812
16813 #[cfg(debug_assertions)]
16814 eprintln!("[{}] Would connect to: {}", protocol, url);
16815
16816 Ok(Value::Map(Rc::new(RefCell::new({
16818 let mut conn = HashMap::new();
16819 conn.insert(
16820 "__protocol__".to_string(),
16821 Value::String(Rc::new(protocol.to_string())),
16822 );
16823 conn.insert("url".to_string(), Value::String(url.clone()));
16824 conn.insert("connected".to_string(), Value::Bool(true));
16825 conn
16826 }))))
16827 }
16828 Value::Map(obj) => {
16829 let mut conn = obj.borrow().clone();
16831 conn.insert("connected".to_string(), Value::Bool(true));
16832 Ok(Value::Map(Rc::new(RefCell::new(conn))))
16833 }
16834 _ => Err(RuntimeError::new(
16835 "connect requires URL string or config object",
16836 )),
16837 }
16838 }
16839
16840 fn protocol_close(&mut self, connection: &Value) -> Result<(), RuntimeError> {
16842 match connection {
16843 Value::Map(obj) => {
16844 let mut obj = obj.borrow_mut();
16845 if let Some(Value::String(protocol)) = obj.get("__protocol__").cloned() {
16846 #[cfg(debug_assertions)]
16847 eprintln!("[{}] Would close connection", protocol);
16848 obj.insert("connected".to_string(), Value::Bool(false));
16849 Ok(())
16850 } else {
16851 Err(RuntimeError::new(
16852 "Connection object missing __protocol__ field",
16853 ))
16854 }
16855 }
16856 _ => Err(RuntimeError::new("close requires a connection object")),
16857 }
16858 }
16859
16860 fn protocol_add_header(
16862 &mut self,
16863 mut request: Value,
16864 name: &Value,
16865 header_value: &Value,
16866 ) -> Result<Value, RuntimeError> {
16867 let name_str = match name {
16868 Value::String(s) => (**s).clone(),
16869 _ => return Err(RuntimeError::new("Header name must be a string")),
16870 };
16871 let value_str = match header_value {
16872 Value::String(s) => (**s).clone(),
16873 Value::Int(i) => i.to_string(),
16874 _ => return Err(RuntimeError::new("Header value must be string or int")),
16875 };
16876
16877 match &mut request {
16878 Value::Map(obj) => {
16879 let mut obj = obj.borrow_mut();
16880
16881 let headers = obj
16883 .entry("headers".to_string())
16884 .or_insert_with(|| Value::Map(Rc::new(RefCell::new(HashMap::new()))));
16885
16886 if let Value::Map(headers_obj) = headers {
16887 headers_obj
16888 .borrow_mut()
16889 .insert(name_str, Value::String(Rc::new(value_str)));
16890 }
16891 drop(obj);
16892 Ok(request)
16893 }
16894 _ => Err(RuntimeError::new("header requires a request object")),
16895 }
16896 }
16897
16898 fn protocol_set_body(
16900 &mut self,
16901 mut request: Value,
16902 body: &Value,
16903 ) -> Result<Value, RuntimeError> {
16904 match &mut request {
16905 Value::Map(obj) => {
16906 obj.borrow_mut().insert("body".to_string(), body.clone());
16907 Ok(request)
16908 }
16909 _ => Err(RuntimeError::new("body requires a request object")),
16910 }
16911 }
16912
16913 fn protocol_set_timeout(
16915 &mut self,
16916 mut request: Value,
16917 ms: &Value,
16918 ) -> Result<Value, RuntimeError> {
16919 let timeout_ms = match ms {
16920 Value::Int(n) => *n,
16921 Value::Float(f) => *f as i64,
16922 _ => return Err(RuntimeError::new("Timeout must be a number (milliseconds)")),
16923 };
16924
16925 match &mut request {
16926 Value::Map(obj) => {
16927 obj.borrow_mut()
16928 .insert("timeout_ms".to_string(), Value::Int(timeout_ms));
16929 Ok(request)
16930 }
16931 _ => Err(RuntimeError::new("timeout requires a request object")),
16932 }
16933 }
16934
16935 fn protocol_set_retry(
16937 &mut self,
16938 mut request: Value,
16939 count: &Value,
16940 strategy: Option<&Value>,
16941 ) -> Result<Value, RuntimeError> {
16942 let retry_count = match count {
16943 Value::Int(n) => *n,
16944 _ => return Err(RuntimeError::new("Retry count must be an integer")),
16945 };
16946
16947 match &mut request {
16948 Value::Map(obj) => {
16949 let mut obj = obj.borrow_mut();
16950 obj.insert("retry_count".to_string(), Value::Int(retry_count));
16951 if let Some(strat) = strategy {
16952 obj.insert("retry_strategy".to_string(), strat.clone());
16953 }
16954 drop(obj);
16955 Ok(request)
16956 }
16957 _ => Err(RuntimeError::new("retry requires a request object")),
16958 }
16959 }
16960
16961 fn backward_propagate(
16963 &self,
16964 tensor_fields: Rc<RefCell<std::collections::HashMap<String, Value>>>,
16965 ) -> Result<(), RuntimeError> {
16966 let fields_ref = tensor_fields.borrow();
16967
16968 if let Some(Value::Struct {
16970 fields: grad_fields,
16971 ..
16972 }) = fields_ref.get("_grad_left")
16973 {
16974 let shape = grad_fields.borrow().get("shape").cloned();
16976 let data_len = match grad_fields.borrow().get("data") {
16977 Some(Value::Array(arr)) => arr.borrow().len(),
16978 _ => 0,
16979 };
16980
16981 let grad_data: Vec<Value> = vec![Value::Float(1.0); data_len];
16983 let mut grad_tensor_fields = std::collections::HashMap::new();
16984 if let Some(s) = shape {
16985 grad_tensor_fields.insert("shape".to_string(), s);
16986 }
16987 grad_tensor_fields.insert(
16988 "data".to_string(),
16989 Value::Array(Rc::new(RefCell::new(grad_data))),
16990 );
16991 grad_tensor_fields.insert("requires_grad".to_string(), Value::Bool(false));
16992
16993 grad_fields.borrow_mut().insert(
16995 "grad".to_string(),
16996 Value::Variant {
16997 enum_name: "Option".to_string(),
16998 variant_name: "Some".to_string(),
16999 fields: Some(Rc::new(vec![Value::Struct {
17000 name: "Tensor".to_string(),
17001 fields: Rc::new(RefCell::new(grad_tensor_fields)),
17002 }])),
17003 },
17004 );
17005
17006 self.backward_propagate(grad_fields.clone())?;
17008 }
17009
17010 if let Some(Value::Struct {
17011 fields: grad_fields,
17012 ..
17013 }) = fields_ref.get("_grad_input")
17014 {
17015 let shape = grad_fields.borrow().get("shape").cloned();
17017 let data_len = match grad_fields.borrow().get("data") {
17018 Some(Value::Array(arr)) => arr.borrow().len(),
17019 _ => 0,
17020 };
17021
17022 let grad_data: Vec<Value> = vec![Value::Float(1.0); data_len];
17023 let mut grad_tensor_fields = std::collections::HashMap::new();
17024 if let Some(s) = shape {
17025 grad_tensor_fields.insert("shape".to_string(), s);
17026 }
17027 grad_tensor_fields.insert(
17028 "data".to_string(),
17029 Value::Array(Rc::new(RefCell::new(grad_data))),
17030 );
17031 grad_tensor_fields.insert("requires_grad".to_string(), Value::Bool(false));
17032
17033 grad_fields.borrow_mut().insert(
17035 "grad".to_string(),
17036 Value::Variant {
17037 enum_name: "Option".to_string(),
17038 variant_name: "Some".to_string(),
17039 fields: Some(Rc::new(vec![Value::Struct {
17040 name: "Tensor".to_string(),
17041 fields: Rc::new(RefCell::new(grad_tensor_fields)),
17042 }])),
17043 },
17044 );
17045
17046 self.backward_propagate(grad_fields.clone())?;
17047 }
17048
17049 Ok(())
17050 }
17051
17052 fn sum_values(&self, value: Value) -> Result<Value, RuntimeError> {
17053 match value {
17054 Value::Array(arr) => {
17055 let arr = arr.borrow();
17056 if arr.is_empty() {
17057 return Ok(Value::Int(0));
17058 }
17059 let mut sum = match &arr[0] {
17060 Value::Int(_) => Value::Int(0),
17061 Value::Float(_) => Value::Float(0.0),
17062 _ => return Err(RuntimeError::new("Cannot sum non-numeric array")),
17063 };
17064 for item in arr.iter() {
17065 sum = match (&sum, item) {
17066 (Value::Int(a), Value::Int(b)) => Value::Int(a + b),
17067 (Value::Float(a), Value::Float(b)) => Value::Float(a + b),
17068 (Value::Int(a), Value::Float(b)) => Value::Float(*a as f64 + b),
17069 (Value::Float(a), Value::Int(b)) => Value::Float(a + *b as f64),
17070 _ => return Err(RuntimeError::new("Cannot sum non-numeric values")),
17071 };
17072 }
17073 Ok(sum)
17074 }
17075 Value::Struct { name, fields } if name == "Tensor" => {
17077 let fields_ref = fields.borrow();
17078 let requires_grad =
17079 matches!(fields_ref.get("requires_grad"), Some(Value::Bool(true)));
17080 let grad_left = fields_ref.get("_grad_left").cloned();
17081 let data: Vec<f64> = match fields_ref.get("data") {
17082 Some(Value::Array(arr)) => arr
17083 .borrow()
17084 .iter()
17085 .filter_map(|v| match v {
17086 Value::Float(f) => Some(*f),
17087 Value::Int(n) => Some(*n as f64),
17088 _ => None,
17089 })
17090 .collect(),
17091 _ => vec![],
17092 };
17093 drop(fields_ref);
17094 let sum: f64 = data.iter().sum();
17095
17096 if requires_grad {
17098 let mut result_fields = std::collections::HashMap::new();
17099 result_fields.insert(
17100 "shape".to_string(),
17101 Value::Array(Rc::new(RefCell::new(vec![]))),
17102 );
17103 result_fields.insert(
17104 "data".to_string(),
17105 Value::Array(Rc::new(RefCell::new(vec![Value::Float(sum)]))),
17106 );
17107 result_fields.insert("_value".to_string(), Value::Float(sum));
17108 result_fields.insert("requires_grad".to_string(), Value::Bool(true));
17109 result_fields
17110 .insert("_op".to_string(), Value::String(Rc::new("sum".to_string())));
17111 if let Some(grad_input) = grad_left {
17113 result_fields.insert("_grad_left".to_string(), grad_input);
17114 } else {
17115 result_fields.insert(
17117 "_grad_input".to_string(),
17118 Value::Struct {
17119 name: "Tensor".to_string(),
17120 fields: fields.clone(),
17121 },
17122 );
17123 }
17124 Ok(Value::Struct {
17125 name: "Tensor".to_string(),
17126 fields: Rc::new(RefCell::new(result_fields)),
17127 })
17128 } else {
17129 Ok(Value::Float(sum))
17130 }
17131 }
17132 _ => Err(RuntimeError::new("sum requires array")),
17133 }
17134 }
17135
17136 fn product_values(&self, value: Value) -> Result<Value, RuntimeError> {
17137 match value {
17138 Value::Array(arr) => {
17139 let arr = arr.borrow();
17140 if arr.is_empty() {
17141 return Ok(Value::Int(1));
17142 }
17143 let mut prod = match &arr[0] {
17144 Value::Int(_) => Value::Int(1),
17145 Value::Float(_) => Value::Float(1.0),
17146 _ => return Err(RuntimeError::new("Cannot multiply non-numeric array")),
17147 };
17148 for item in arr.iter() {
17149 prod = match (&prod, item) {
17150 (Value::Int(a), Value::Int(b)) => Value::Int(a * b),
17151 (Value::Float(a), Value::Float(b)) => Value::Float(a * b),
17152 (Value::Int(a), Value::Float(b)) => Value::Float(*a as f64 * b),
17153 (Value::Float(a), Value::Int(b)) => Value::Float(a * *b as f64),
17154 _ => return Err(RuntimeError::new("Cannot multiply non-numeric values")),
17155 };
17156 }
17157 Ok(prod)
17158 }
17159 _ => Err(RuntimeError::new("product requires array")),
17160 }
17161 }
17162
17163 fn min_values(&self, value: Value) -> Result<Value, RuntimeError> {
17164 match value {
17165 Value::Array(arr) => {
17166 let arr = arr.borrow();
17167 if arr.is_empty() {
17168 return Err(RuntimeError::new("Cannot find min of empty array"));
17169 }
17170 let mut min = arr[0].clone();
17171 for item in arr.iter().skip(1) {
17172 min = match (&min, item) {
17173 (Value::Int(a), Value::Int(b)) => {
17174 if *b < *a {
17175 Value::Int(*b)
17176 } else {
17177 Value::Int(*a)
17178 }
17179 }
17180 (Value::Float(a), Value::Float(b)) => {
17181 if *b < *a {
17182 Value::Float(*b)
17183 } else {
17184 Value::Float(*a)
17185 }
17186 }
17187 (Value::Int(a), Value::Float(b)) => {
17188 let af = *a as f64;
17189 if *b < af {
17190 Value::Float(*b)
17191 } else {
17192 Value::Float(af)
17193 }
17194 }
17195 (Value::Float(a), Value::Int(b)) => {
17196 let bf = *b as f64;
17197 if bf < *a {
17198 Value::Float(bf)
17199 } else {
17200 Value::Float(*a)
17201 }
17202 }
17203 _ => {
17204 return Err(RuntimeError::new("Cannot find min of non-numeric values"))
17205 }
17206 };
17207 }
17208 Ok(min)
17209 }
17210 _ => Err(RuntimeError::new("min requires array")),
17211 }
17212 }
17213
17214 fn max_values(&self, value: Value) -> Result<Value, RuntimeError> {
17215 match value {
17216 Value::Array(arr) => {
17217 let arr = arr.borrow();
17218 if arr.is_empty() {
17219 return Err(RuntimeError::new("Cannot find max of empty array"));
17220 }
17221 let mut max = arr[0].clone();
17222 for item in arr.iter().skip(1) {
17223 max = match (&max, item) {
17224 (Value::Int(a), Value::Int(b)) => {
17225 if *b > *a {
17226 Value::Int(*b)
17227 } else {
17228 Value::Int(*a)
17229 }
17230 }
17231 (Value::Float(a), Value::Float(b)) => {
17232 if *b > *a {
17233 Value::Float(*b)
17234 } else {
17235 Value::Float(*a)
17236 }
17237 }
17238 (Value::Int(a), Value::Float(b)) => {
17239 let af = *a as f64;
17240 if *b > af {
17241 Value::Float(*b)
17242 } else {
17243 Value::Float(af)
17244 }
17245 }
17246 (Value::Float(a), Value::Int(b)) => {
17247 let bf = *b as f64;
17248 if bf > *a {
17249 Value::Float(bf)
17250 } else {
17251 Value::Float(*a)
17252 }
17253 }
17254 _ => {
17255 return Err(RuntimeError::new("Cannot find max of non-numeric values"))
17256 }
17257 };
17258 }
17259 Ok(max)
17260 }
17261 _ => Err(RuntimeError::new("max requires array")),
17262 }
17263 }
17264
17265 fn concat_values(&self, value: Value) -> Result<Value, RuntimeError> {
17266 match value {
17267 Value::Array(arr) => {
17268 let arr = arr.borrow();
17269 if arr.is_empty() {
17270 return Ok(Value::String(Rc::new(String::new())));
17271 }
17272 match &arr[0] {
17274 Value::String(_) => {
17275 let mut result = String::new();
17276 for item in arr.iter() {
17277 if let Value::String(s) = item {
17278 result.push_str(s);
17279 } else {
17280 return Err(RuntimeError::new(
17281 "concat requires all elements to be strings",
17282 ));
17283 }
17284 }
17285 Ok(Value::String(Rc::new(result)))
17286 }
17287 Value::Array(_) => {
17288 let mut result = Vec::new();
17289 for item in arr.iter() {
17290 if let Value::Array(inner) = item {
17291 result.extend(inner.borrow().iter().cloned());
17292 } else {
17293 return Err(RuntimeError::new(
17294 "concat requires all elements to be arrays",
17295 ));
17296 }
17297 }
17298 Ok(Value::Array(Rc::new(RefCell::new(result))))
17299 }
17300 _ => Err(RuntimeError::new("concat requires strings or arrays")),
17301 }
17302 }
17303 _ => Err(RuntimeError::new("concat requires array")),
17304 }
17305 }
17306
17307 fn all_values(&self, value: Value) -> Result<Value, RuntimeError> {
17308 match value {
17309 Value::Array(arr) => {
17310 let arr = arr.borrow();
17311 for item in arr.iter() {
17312 match item {
17313 Value::Bool(b) => {
17314 if !*b {
17315 return Ok(Value::Bool(false));
17316 }
17317 }
17318 _ => return Err(RuntimeError::new("all requires array of booleans")),
17319 }
17320 }
17321 Ok(Value::Bool(true))
17322 }
17323 _ => Err(RuntimeError::new("all requires array")),
17324 }
17325 }
17326
17327 fn any_values(&self, value: Value) -> Result<Value, RuntimeError> {
17328 match value {
17329 Value::Array(arr) => {
17330 let arr = arr.borrow();
17331 for item in arr.iter() {
17332 match item {
17333 Value::Bool(b) => {
17334 if *b {
17335 return Ok(Value::Bool(true));
17336 }
17337 }
17338 _ => return Err(RuntimeError::new("any requires array of booleans")),
17339 }
17340 }
17341 Ok(Value::Bool(false))
17342 }
17343 _ => Err(RuntimeError::new("any requires array")),
17344 }
17345 }
17346
17347 fn compare_values(&self, a: &Value, b: &Value, _field: &Option<Ident>) -> std::cmp::Ordering {
17348 match (a, b) {
17350 (Value::Int(a), Value::Int(b)) => a.cmp(b),
17351 (Value::Float(a), Value::Float(b)) => {
17352 a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal)
17353 }
17354 (Value::String(a), Value::String(b)) => a.cmp(b),
17355 _ => std::cmp::Ordering::Equal,
17356 }
17357 }
17358
17359 fn subtract_values(&self, a: &Value, b: &Value) -> Result<Value, RuntimeError> {
17361 match (a, b) {
17362 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a - b)),
17363 (Value::Float(a), Value::Float(b)) => Ok(Value::Float(a - b)),
17364 (Value::Int(a), Value::Float(b)) => Ok(Value::Float(*a as f64 - b)),
17365 (Value::Float(a), Value::Int(b)) => Ok(Value::Float(a - *b as f64)),
17366 _ => Err(RuntimeError::new(format!(
17367 "Cannot subtract {:?} from {:?}",
17368 b, a
17369 ))),
17370 }
17371 }
17372
17373 fn eval_closure(
17374 &mut self,
17375 params: &[ClosureParam],
17376 body: &Expr,
17377 ) -> Result<Value, RuntimeError> {
17378 let param_names: Vec<String> = params
17379 .iter()
17380 .map(|p| Self::extract_param_name(&p.pattern))
17381 .collect();
17382
17383 Ok(Value::Function(Rc::new(Function {
17384 name: None,
17385 params: param_names,
17386 body: body.clone(),
17387 closure: self.environment.clone(),
17388 generic_params: Vec::new(),
17389 })))
17390 }
17391
17392 fn eval_struct_literal(
17393 &mut self,
17394 path: &TypePath,
17395 fields: &[FieldInit],
17396 rest: &Option<Box<Expr>>,
17397 ) -> Result<Value, RuntimeError> {
17398 let raw_name = path
17399 .segments
17400 .iter()
17401 .map(|s| s.ident.name.as_str())
17402 .collect::<Vec<_>>()
17403 .join("·"); let name = if raw_name == "Self" || raw_name == "This" {
17407 if let Some(ref self_type) = self.current_self_type {
17408 self_type.clone()
17409 } else {
17410 raw_name
17412 }
17413 } else {
17414 raw_name.replace("::", "·")
17416 };
17417
17418 let mut field_values = HashMap::new();
17419
17420 if let Some(rest_expr) = rest {
17422 let prev_self_type = self.current_self_type.clone();
17424 self.current_self_type = Some(name.clone());
17425
17426 let rest_value = self.evaluate(rest_expr)?;
17427
17428 self.current_self_type = prev_self_type;
17429
17430 if let Value::Struct {
17432 fields: rest_fields,
17433 ..
17434 } = rest_value
17435 {
17436 for (k, v) in rest_fields.borrow().iter() {
17437 field_values.insert(k.clone(), v.clone());
17438 }
17439 }
17440 }
17441
17442 for field in fields {
17444 let value = match &field.value {
17445 Some(expr) => self.evaluate(expr)?,
17446 None => self
17447 .environment
17448 .borrow()
17449 .get(&field.name.name)
17450 .ok_or_else(|| {
17451 RuntimeError::new(format!("Unknown variable: {}", field.name.name))
17452 })?,
17453 };
17454 field_values.insert(field.name.name.clone(), value);
17455 }
17456
17457 if path.segments.len() >= 2 {
17460 let enum_name_segments: Vec<&str> = path.segments[..path.segments.len() - 1]
17461 .iter()
17462 .map(|s| s.ident.name.as_str())
17463 .collect();
17464 let variant_name = &path.segments.last().unwrap().ident.name;
17465
17466 let enum_name_direct = enum_name_segments.join("::");
17468 let enum_name_qualified = enum_name_segments.join("·");
17469
17470 let enum_def_opt = self
17472 .types
17473 .get(&enum_name_direct)
17474 .or_else(|| self.types.get(&enum_name_qualified));
17475
17476 if let Some(TypeDef::Enum(enum_def)) = enum_def_opt {
17477 for variant in &enum_def.variants {
17479 if &variant.name.name == variant_name {
17480 let inner_struct = Value::Struct {
17483 name: format!("{}::{}", enum_name_direct, variant_name),
17484 fields: Rc::new(RefCell::new(field_values)),
17485 };
17486 return Ok(Value::Variant {
17487 enum_name: enum_name_direct,
17488 variant_name: variant_name.clone(),
17489 fields: Some(Rc::new(vec![inner_struct])),
17490 });
17491 }
17492 }
17493 }
17494 }
17495
17496 if let Some(TypeDef::Struct(struct_def)) = self.types.get(&name) {
17498 if let crate::ast::StructFields::Named(def_fields) = &struct_def.fields {
17499 for def_field in def_fields {
17500 if !field_values.contains_key(&def_field.name.name) {
17501 return Err(RuntimeError::new(format!(
17502 "missing field '{}' in struct '{}'",
17503 def_field.name.name, name
17504 )));
17505 }
17506 }
17507 }
17508 }
17509
17510 if let Some(segment) = path.segments.first() {
17513 if let Some(generics) = &segment.generics {
17514 let base_name = &segment.ident.name;
17515 if let Some(param_names) = self.const_generic_params.get(base_name.as_str()).cloned() {
17516 let mut idx = 0;
17517 for generic in generics {
17518 if idx >= param_names.len() { break; }
17519 let val = match generic {
17520 crate::ast::TypeExpr::ConstExpr(expr) => {
17521 if let crate::ast::Expr::Literal(crate::ast::Literal::Int { value, .. }) = expr.as_ref() {
17522 value.parse::<i64>().ok()
17523 } else { None }
17524 }
17525 crate::ast::TypeExpr::Path(inner_path) => {
17526 if let Some(inner_seg) = inner_path.segments.first() {
17527 inner_seg.ident.name.parse::<i64>().ok()
17528 } else { None }
17529 }
17530 _ => None,
17531 };
17532 if let Some(v) = val {
17533 field_values.insert(
17534 format!("__const_{}__", param_names[idx]),
17535 Value::Int(v),
17536 );
17537 idx += 1;
17538 }
17539 }
17540 }
17541 }
17542 }
17543
17544 if let Some((ctx_name, ctx_values)) = self.type_context.struct_generics.borrow().clone() {
17546 if ctx_name == name {
17547 if let Some(param_names) = self.const_generic_params.get(&name).cloned() {
17548 for (param_name, value) in param_names.iter().zip(ctx_values.iter()) {
17549 let key = format!("__const_{}__", param_name);
17550 if !field_values.contains_key(&key) {
17551 field_values.insert(key, Value::Int(*value));
17552 }
17553 }
17554 }
17555 }
17556 }
17557
17558 if let Some(param_names) = self.const_generic_params.get(&name).cloned() {
17562 for param_name in ¶m_names {
17563 let key = format!("__const_{}__", param_name);
17564 if !field_values.contains_key(&key) {
17565 if let Some(val) = self.environment.borrow().get(param_name) {
17566 if let Value::Int(_) = &val {
17567 field_values.insert(key, val);
17568 }
17569 }
17570 }
17571 }
17572 }
17573
17574 Ok(Value::Struct {
17575 name,
17576 fields: Rc::new(RefCell::new(field_values)),
17577 })
17578 }
17579
17580 fn extract_evidence(value: &Value) -> Option<Evidence> {
17582 match value {
17583 Value::Evidential { evidence, .. } => Some(*evidence),
17584 _ => None,
17585 }
17586 }
17587
17588 fn extract_affect(value: &Value) -> Option<&RuntimeAffect> {
17590 match value {
17591 Value::Affective { affect, .. } => Some(affect),
17592 _ => None,
17593 }
17594 }
17595
17596 fn affect_to_evidence(affect: &RuntimeAffect) -> Option<Evidence> {
17600 if affect.sarcasm {
17602 return Some(Evidence::Uncertain);
17603 }
17604
17605 match affect.confidence {
17607 Some(RuntimeConfidence::High) => Some(Evidence::Known),
17608 Some(RuntimeConfidence::Low) => Some(Evidence::Uncertain),
17609 Some(RuntimeConfidence::Medium) | None => None,
17610 }
17611 }
17612
17613 fn combine_evidence(a: Option<Evidence>, b: Option<Evidence>) -> Option<Evidence> {
17616 match (a, b) {
17617 (None, None) => None,
17618 (Some(e), None) | (None, Some(e)) => Some(e),
17619 (Some(a), Some(b)) => {
17620 let rank = |e: Evidence| match e {
17621 Evidence::Known => 0,
17622 Evidence::Uncertain => 1,
17623 Evidence::Predicted => 2,
17624 Evidence::Reported => 3,
17625 Evidence::Paradox => 4,
17626 };
17627 if rank(a) >= rank(b) {
17628 Some(a)
17629 } else {
17630 Some(b)
17631 }
17632 }
17633 }
17634 }
17635
17636 fn unwrap_evidential(value: &Value) -> &Value {
17638 match value {
17639 Value::Evidential { value: inner, .. } => Self::unwrap_evidential(inner),
17640 _ => value,
17641 }
17642 }
17643
17644 fn unwrap_affective(value: &Value) -> &Value {
17646 match value {
17647 Value::Affective { value: inner, .. } => Self::unwrap_affective(inner),
17648 _ => value,
17649 }
17650 }
17651
17652 fn unwrap_value(value: &Value) -> &Value {
17654 match value {
17655 Value::Evidential { value: inner, .. } => Self::unwrap_value(inner),
17656 Value::Affective { value: inner, .. } => Self::unwrap_value(inner),
17657 _ => value,
17658 }
17659 }
17660
17661 fn unwrap_all(value: &Value) -> Value {
17663 match value {
17664 Value::Evidential { value: inner, .. } => Self::unwrap_all(inner),
17665 Value::Affective { value: inner, .. } => Self::unwrap_all(inner),
17666 Value::Ref(r) => Self::unwrap_all(&r.borrow()),
17667 _ => value.clone(),
17668 }
17669 }
17670
17671 fn eval_evidential(&mut self, expr: &Expr, ev: &Evidentiality) -> Result<Value, RuntimeError> {
17672 let value = self.evaluate(expr)?;
17673
17674 if matches!(ev, Evidentiality::Uncertain) {
17678 let unwrapped = match &value {
17680 Value::Evidential { value: inner, .. } => inner.as_ref().clone(),
17681 other => other.clone(),
17682 };
17683 match &unwrapped {
17684 Value::Variant { enum_name, variant_name, fields, .. }
17685 if (enum_name == "Result" || enum_name == "Option")
17686 && (variant_name == "Ok" || variant_name == "Some") =>
17687 {
17688 let inner_val = fields.as_ref()
17690 .and_then(|f| f.first().cloned())
17691 .unwrap_or(Value::Null);
17692 return Ok(inner_val);
17693 }
17694 Value::Variant { enum_name, variant_name, .. }
17695 if (enum_name == "Result" && variant_name == "Err")
17696 || (enum_name == "Option" && variant_name == "None") =>
17697 {
17698 self.return_value = Some(unwrapped);
17700 return Err(RuntimeError::new("return"));
17701 }
17702 Value::Null => {
17703 self.return_value = Some(Value::Null);
17704 return Err(RuntimeError::new("return"));
17705 }
17706 _ => {}
17707 }
17708 }
17709
17710 if let Value::Null = &value {
17714 return Ok(Value::Null);
17715 }
17716
17717 let inner = match value {
17718 Value::Evidential { value: inner, .. } => *inner, other => other,
17720 };
17721
17722 let evidence = match ev {
17723 Evidentiality::Known => Evidence::Known,
17724 Evidentiality::Uncertain | Evidentiality::Predicted => Evidence::Uncertain,
17725 Evidentiality::Reported => Evidence::Reported,
17726 Evidentiality::Paradox => Evidence::Paradox,
17727 };
17728 Ok(Value::Evidential {
17729 value: Box::new(inner),
17730 evidence,
17731 })
17732 }
17733
17734 fn expand_user_macro(
17740 &mut self,
17741 params: &[String],
17742 body: &str,
17743 tokens: &str,
17744 pipe_value: Option<Value>,
17745 field_map: &HashMap<String, String>,
17746 ) -> Result<Value, RuntimeError> {
17747 let mut substitutions: HashMap<String, String> = HashMap::new();
17749
17750 if let Some(ref val) = pipe_value {
17752 substitutions.insert("__pipe".to_string(), self.value_to_source(val));
17753
17754 if !params.is_empty() && tokens.trim().is_empty() {
17757 substitutions.insert(params[0].clone(), self.value_to_source(val));
17758 }
17759 }
17760
17761 let tokens = tokens.trim();
17763 if !params.is_empty() && !tokens.is_empty() {
17764 let args = self.split_macro_args(tokens);
17766
17767 let mut named_matched = false;
17772 for arg in &args {
17773 let trimmed = arg.trim();
17774 if let Some(colon_pos) = trimmed.find(':') {
17775 let key = trimmed[..colon_pos].trim();
17776 let value = trimmed[colon_pos + 1..].trim();
17777 if let Some(param_name) = field_map.get(key) {
17779 substitutions.insert(param_name.clone(), value.to_string());
17780 named_matched = true;
17781 } else if params.contains(&key.to_string()) {
17782 substitutions.insert(key.to_string(), value.to_string());
17784 named_matched = true;
17785 }
17786 }
17787 }
17788
17789 if !named_matched {
17791 for (i, param) in params.iter().enumerate() {
17792 if i < args.len() {
17793 substitutions.insert(param.clone(), args[i].trim().to_string());
17794 }
17795 }
17796 }
17797 }
17798
17799 let mut expanded = body.to_string();
17801 for (param, value) in &substitutions {
17802 let pattern = format!("${}", param);
17804 expanded = expanded.replace(&pattern, value);
17805 }
17806
17807 if let Some(ref val) = pipe_value {
17810 let pipe_source = self.value_to_source(val);
17811 expanded = expanded.replace("__pipe", &pipe_source);
17814 }
17815
17816 let expr_source = format!("rite __macro_expand__() {{ {} }}", expanded);
17818 let mut parser = crate::Parser::new(&expr_source);
17819 match parser.parse_file() {
17820 Ok(file) => {
17821 for item in &file.items {
17823 if let Item::Function(func) = &item.node {
17824 if func.name.name == "__macro_expand__" {
17825 let fn_value = self.create_function(func)?;
17827 if let Value::Function(f) = fn_value {
17828 return self.call_function(&f, Vec::new());
17829 }
17830 return Err(RuntimeError::new("Macro expansion failed: function not created"));
17831 }
17832 }
17833 }
17834 Err(RuntimeError::new("Macro expansion failed: no function created"))
17835 }
17836 Err(e) => Err(RuntimeError::new(format!(
17837 "Macro expansion parse error: {:?}",
17838 e
17839 ))),
17840 }
17841 }
17842
17843 fn value_to_source(&self, val: &Value) -> String {
17845 match val {
17846 Value::Int(n) => n.to_string(),
17847 Value::Float(f) => format!("{:?}", f),
17848 Value::Bool(b) => b.to_string(),
17849 Value::String(s) => format!("\"{}\"", s),
17850 Value::Null => "null".to_string(),
17851 Value::Char(c) => format!("'{}'", c),
17852 Value::Array(arr) => {
17853 let arr = arr.borrow();
17854 let items: Vec<String> = arr.iter().map(|v| self.value_to_source(v)).collect();
17855 format!("[{}]", items.join(", "))
17856 }
17857 Value::Struct { name, fields } => {
17858 let fields = fields.borrow();
17859 let field_strs: Vec<String> = fields.iter()
17860 .map(|(k, v)| format!("{}: {}", k, self.value_to_source(v)))
17861 .collect();
17862 format!("{} {{ {} }}", name, field_strs.join(", "))
17863 }
17864 Value::Variant { enum_name, variant_name, fields } => {
17865 if let Some(f) = fields {
17866 let args: Vec<String> = f.iter().map(|v| self.value_to_source(v)).collect();
17867 format!("{}·{}({})", enum_name, variant_name, args.join(", "))
17868 } else {
17869 format!("{}·{}", enum_name, variant_name)
17870 }
17871 }
17872 _ => format!("{}", val),
17873 }
17874 }
17875
17876 fn split_macro_args(&self, tokens: &str) -> Vec<String> {
17878 let mut args = Vec::new();
17879 let mut current = String::new();
17880 let mut depth = 0;
17881
17882 for c in tokens.chars() {
17883 match c {
17884 '(' | '[' | '{' => {
17885 depth += 1;
17886 current.push(c);
17887 }
17888 ')' | ']' | '}' => {
17889 depth -= 1;
17890 current.push(c);
17891 }
17892 ',' if depth == 0 => {
17893 args.push(current.trim().to_string());
17894 current = String::new();
17895 }
17896 _ => current.push(c),
17897 }
17898 }
17899 if !current.is_empty() {
17900 args.push(current.trim().to_string());
17901 }
17902 args
17903 }
17904
17905 fn eval_format_macro(&mut self, tokens: &str) -> Result<Value, RuntimeError> {
17907 let tokens = tokens.trim();
17912 if !tokens.starts_with('"') {
17913 return Ok(Value::String(Rc::new(tokens.to_string())));
17915 }
17916
17917 let mut in_escape = false;
17919 let mut format_end = 1;
17920 for (i, c) in tokens[1..].char_indices() {
17921 if in_escape {
17922 in_escape = false;
17923 } else if c == '\\' {
17924 in_escape = true;
17925 } else if c == '"' {
17926 format_end = i + 2; break;
17928 }
17929 }
17930
17931 let format_str = &tokens[1..format_end - 1]; crate::sigil_debug!("DEBUG format_str: '{}'", format_str);
17933 let args_str = if format_end < tokens.len() {
17934 tokens[format_end..].trim_start_matches(',').trim()
17935 } else {
17936 ""
17937 };
17938
17939 let mut arg_values: Vec<String> = Vec::new();
17941 if !args_str.is_empty() {
17942 let mut depth = 0;
17944 let mut current_arg = String::new();
17945 for c in args_str.chars() {
17946 match c {
17947 '(' | '[' | '{' => {
17948 depth += 1;
17949 current_arg.push(c);
17950 }
17951 ')' | ']' | '}' => {
17952 depth -= 1;
17953 current_arg.push(c);
17954 }
17955 ',' if depth == 0 => {
17956 let arg = current_arg.trim().to_string();
17957 if !arg.is_empty() {
17958 let mut parser = crate::parser::Parser::new(&arg);
17960 match parser.parse_expr() {
17961 Ok(expr) => match self.evaluate(&expr) {
17962 Ok(val) => arg_values.push(self.format_value(&val)),
17963 Err(_) => arg_values.push(arg),
17964 },
17965 Err(_) => arg_values.push(arg),
17966 }
17967 }
17968 current_arg.clear();
17969 }
17970 _ => current_arg.push(c),
17971 }
17972 }
17973 let arg = current_arg.trim().to_string();
17975 if !arg.is_empty() {
17976 let mut parser = crate::parser::Parser::new(&arg);
17977 match parser.parse_expr() {
17978 Ok(expr) => match self.evaluate(&expr) {
17979 Ok(val) => arg_values.push(self.format_value(&val)),
17980 Err(_) => arg_values.push(arg),
17981 },
17982 Err(_) => arg_values.push(arg),
17983 }
17984 }
17985 }
17986
17987 let mut result = String::new();
17989 let mut arg_idx = 0;
17990 let mut chars = format_str.chars().peekable();
17991
17992 while let Some(c) = chars.next() {
17993 if c == '{' {
17994 if chars.peek() == Some(&'{') {
17995 chars.next();
17997 result.push('{');
17998 } else {
17999 let mut placeholder = String::new();
18001 while let Some(pc) = chars.next() {
18002 if pc == '}' {
18003 break;
18004 }
18005 placeholder.push(pc);
18006 }
18007 if arg_idx < arg_values.len() {
18009 result.push_str(&arg_values[arg_idx]);
18010 arg_idx += 1;
18011 } else {
18012 result.push_str(&format!("{{{}}}", placeholder));
18013 }
18014 }
18015 } else if c == '}' {
18016 if chars.peek() == Some(&'}') {
18017 chars.next();
18019 result.push('}');
18020 } else {
18021 result.push('}');
18022 }
18023 } else if c == '\\' {
18024 if let Some(next) = chars.next() {
18026 match next {
18027 'n' => result.push('\n'),
18028 't' => result.push('\t'),
18029 'r' => result.push('\r'),
18030 '\\' => result.push('\\'),
18031 '"' => result.push('"'),
18032 _ => {
18033 result.push('\\');
18034 result.push(next);
18035 }
18036 }
18037 }
18038 } else {
18039 result.push(c);
18040 }
18041 }
18042
18043 Ok(Value::String(Rc::new(result)))
18044 }
18045
18046 fn infer_expr_type(&self, expr: &Expr) -> Option<String> {
18049 match expr {
18050 Expr::Literal(lit) => match lit {
18051 Literal::Int { .. } => Some("i32".to_string()),
18052 Literal::Float { .. } => Some("f64".to_string()),
18053 Literal::String(_) | Literal::RawString(_) => Some("String".to_string()),
18054 Literal::Bool(_) => Some("bool".to_string()),
18055 Literal::Char(_) => Some("char".to_string()),
18056 Literal::Null => Some("null".to_string()),
18057 _ => None,
18058 },
18059 Expr::Array(elements) => {
18060 if let Some(first) = elements.first() {
18062 if let Some(elem_type) = self.infer_expr_type(first) {
18063 return Some(format!("[{}]", elem_type));
18064 }
18065 }
18066 Some("[_]".to_string())
18067 }
18068 Expr::Tuple(elements) => {
18069 let types: Vec<String> = elements
18070 .iter()
18071 .filter_map(|e| self.infer_expr_type(e))
18072 .collect();
18073 Some(format!("({})", types.join(", ")))
18074 }
18075 Expr::Block(block) => {
18076 if let Some(ref e) = block.expr {
18078 return self.infer_expr_type(e);
18079 }
18080 Some("()".to_string())
18081 }
18082 Expr::If {
18083 then_branch,
18084 else_branch,
18085 ..
18086 } => {
18087 if let Some(ref e) = then_branch.expr {
18089 if let Some(t) = self.infer_expr_type(e) {
18090 return Some(t);
18091 }
18092 }
18093 if let Some(e) = else_branch {
18094 return self.infer_expr_type(e);
18095 }
18096 None
18097 }
18098 _ => None, }
18100 }
18101
18102 fn value_type_name(&self, value: &Value) -> String {
18104 match value {
18105 Value::Int(_) => "i32".to_string(),
18106 Value::Float(_) => "f64".to_string(),
18107 Value::String(_) => "String".to_string(),
18108 Value::Bool(_) => "bool".to_string(),
18109 Value::Char(_) => "char".to_string(),
18110 Value::Null => "null".to_string(),
18111 Value::Array(_) => "Array".to_string(),
18112 Value::Tuple(_) => "Tuple".to_string(),
18113 Value::Struct { name, .. } => name.clone(),
18114 Value::Variant { enum_name, .. } => enum_name.clone(),
18115 Value::Function(_) => "Function".to_string(),
18116 Value::BuiltIn(_) => "BuiltIn".to_string(),
18117 Value::Ref(_) => "Ref".to_string(),
18118 _ => "unknown".to_string(),
18119 }
18120 }
18121
18122 fn extract_type_params(
18125 &self,
18126 type_expr: &crate::ast::TypeExpr,
18127 ) -> Option<(String, Vec<String>)> {
18128 use crate::ast::TypeExpr;
18129
18130 if let TypeExpr::Path(path) = type_expr {
18131 if let Some(segment) = path.segments.first() {
18132 let type_name = segment.ident.name.clone();
18133 if let Some(generics) = &segment.generics {
18134 let mut type_params: Vec<String> = Vec::new();
18135 for generic in generics {
18136 if let TypeExpr::Path(inner_path) = generic {
18137 if let Some(inner_seg) = inner_path.segments.first() {
18138 type_params.push(inner_seg.ident.name.clone());
18139 }
18140 }
18141 }
18142 return Some((type_name, type_params));
18143 }
18144 return Some((type_name, vec![]));
18145 }
18146 }
18147 None
18148 }
18149
18150 fn check_generic_type_match(
18152 &self,
18153 type_name: &str,
18154 type_params: &[String],
18155 value: &Value,
18156 ) -> Result<(), RuntimeError> {
18157 match (type_name, value) {
18158 (
18160 "Option",
18161 Value::Variant {
18162 enum_name,
18163 variant_name,
18164 fields,
18165 },
18166 ) if enum_name == "Option" && variant_name == "Some" => {
18167 if let (Some(expected_type), Some(fields)) = (type_params.first(), fields) {
18168 if let Some(inner_value) = fields.first() {
18169 let actual_type = self.value_type_name(inner_value);
18170 if &actual_type != expected_type {
18171 return Err(RuntimeError::new(format!(
18172 "type mismatch: expected Option<{}>, found Some({})",
18173 expected_type, actual_type
18174 )));
18175 }
18176 }
18177 }
18178 }
18179 (
18181 "Result",
18182 Value::Variant {
18183 enum_name,
18184 variant_name,
18185 fields,
18186 },
18187 ) if enum_name == "Result" && variant_name == "Ok" => {
18188 if let (Some(expected_type), Some(fields)) = (type_params.first(), fields) {
18189 if let Some(inner_value) = fields.first() {
18190 let actual_type = self.value_type_name(inner_value);
18191 if &actual_type != expected_type {
18192 return Err(RuntimeError::new(format!(
18193 "type mismatch: expected Result<{}, _>, found Ok({})",
18194 expected_type, actual_type
18195 )));
18196 }
18197 }
18198 }
18199 }
18200 (
18202 "Result",
18203 Value::Variant {
18204 enum_name,
18205 variant_name,
18206 fields,
18207 },
18208 ) if enum_name == "Result" && variant_name == "Err" => {
18209 if let (Some(expected_type), Some(fields)) = (type_params.get(1), fields) {
18210 if let Some(inner_value) = fields.first() {
18211 let actual_type = self.value_type_name(inner_value);
18212 if &actual_type != expected_type {
18213 return Err(RuntimeError::new(format!(
18214 "type mismatch: expected Result<_, {}>, found Err({})",
18215 expected_type, actual_type
18216 )));
18217 }
18218 }
18219 }
18220 }
18221 _ => {} }
18223 Ok(())
18224 }
18225
18226 fn format_value(&self, value: &Value) -> String {
18228 match value {
18229 Value::String(s) => s.to_string(),
18230 Value::Int(n) => n.to_string(),
18231 Value::Float(f) => f.to_string(),
18232 Value::Bool(b) => b.to_string(),
18233 Value::Char(c) => c.to_string(),
18234 Value::Null => "null".to_string(),
18235 Value::Array(arr) => {
18236 let items: Vec<String> =
18237 arr.borrow().iter().map(|v| self.format_value(v)).collect();
18238 format!("[{}]", items.join(", "))
18239 }
18240 Value::Tuple(items) => {
18241 let formatted: Vec<String> = items.iter().map(|v| self.format_value(v)).collect();
18242 format!("({})", formatted.join(", "))
18243 }
18244 Value::Struct { name, fields } => {
18245 let field_strs: Vec<String> = fields
18246 .borrow()
18247 .iter()
18248 .map(|(k, v)| format!("{}: {}", k, self.format_value(v)))
18249 .collect();
18250 format!("{} {{ {} }}", name, field_strs.join(", "))
18251 }
18252 Value::Variant {
18253 enum_name,
18254 variant_name,
18255 fields,
18256 } => match fields {
18257 Some(f) if !f.is_empty() => {
18258 let formatted: Vec<String> = f.iter().map(|v| self.format_value(v)).collect();
18259 format!("{}::{}({})", enum_name, variant_name, formatted.join(", "))
18260 }
18261 _ => format!("{}::{}", enum_name, variant_name),
18262 },
18263 Value::Evidential {
18264 value: inner,
18265 evidence,
18266 } => {
18267 format!("{:?}{}", evidence, self.format_value(inner))
18268 }
18269 Value::Ref(r) => self.format_value(&r.borrow()),
18270 _ => format!("{:?}", value),
18271 }
18272 }
18273
18274 fn eval_vec_macro(&mut self, tokens: &str) -> Result<Value, RuntimeError> {
18276 let mut depth = 0;
18279 let mut semicolon_pos = None;
18280 for (i, c) in tokens.chars().enumerate() {
18281 match c {
18282 '(' | '[' | '{' => depth += 1,
18283 ')' | ']' | '}' => depth -= 1,
18284 ';' if depth == 0 => {
18285 semicolon_pos = Some(i);
18286 break;
18287 }
18288 _ => {}
18289 }
18290 }
18291
18292 if let Some(pos) = semicolon_pos {
18293 let value_str = tokens[..pos].trim();
18295 let count_str = tokens[pos + 1..].trim();
18296
18297 let mut parser = crate::parser::Parser::new(value_str);
18298 let value_expr = parser.parse_expr().map_err(|e| RuntimeError::new(format!("vec! fill value parse error: {}", e)))?;
18299 let value = self.evaluate(&value_expr)?;
18300
18301 let mut parser = crate::parser::Parser::new(count_str);
18302 let count_expr = parser.parse_expr().map_err(|e| RuntimeError::new(format!("vec! fill count parse error: {}", e)))?;
18303 let count_val = self.evaluate(&count_expr)?;
18304 let count = match count_val {
18305 Value::Int(n) => n as usize,
18306 _ => return Err(RuntimeError::new(format!("vec! fill count must be integer, got {:?}", count_val))),
18307 };
18308
18309 let elements: Vec<Value> = (0..count).map(|_| value.clone()).collect();
18310 return Ok(Value::Array(Rc::new(RefCell::new(elements))));
18311 }
18312
18313 let mut elements = Vec::new();
18315 depth = 0;
18316 let mut current = String::new();
18317
18318 for c in tokens.chars() {
18319 match c {
18320 '(' | '[' | '{' => {
18321 depth += 1;
18322 current.push(c);
18323 }
18324 ')' | ']' | '}' => {
18325 depth -= 1;
18326 current.push(c);
18327 }
18328 ',' if depth == 0 => {
18329 let elem = current.trim().to_string();
18330 if !elem.is_empty() {
18331 let mut parser = crate::parser::Parser::new(&elem);
18332 if let Ok(expr) = parser.parse_expr() {
18333 elements.push(self.evaluate(&expr)?);
18334 }
18335 }
18336 current.clear();
18337 }
18338 _ => current.push(c),
18339 }
18340 }
18341
18342 let elem = current.trim().to_string();
18344 if !elem.is_empty() {
18345 let mut parser = crate::parser::Parser::new(&elem);
18346 if let Ok(expr) = parser.parse_expr() {
18347 elements.push(self.evaluate(&expr)?);
18348 }
18349 }
18350
18351 Ok(Value::Array(Rc::new(RefCell::new(elements))))
18352 }
18353
18354 fn eval_range(
18355 &mut self,
18356 start: &Option<Box<Expr>>,
18357 end: &Option<Box<Expr>>,
18358 inclusive: bool,
18359 ) -> Result<Value, RuntimeError> {
18360 let start_val = match start {
18361 Some(e) => match self.evaluate(e)? {
18362 Value::Int(n) => n,
18363 _ => return Err(RuntimeError::new("Range requires integer bounds")),
18364 },
18365 None => 0,
18366 };
18367
18368 let end_val = match end {
18369 Some(e) => match self.evaluate(e)? {
18370 Value::Int(n) => n,
18371 _ => return Err(RuntimeError::new("Range requires integer bounds")),
18372 },
18373 None => {
18374 return Ok(Value::Tuple(Rc::new(vec![
18377 Value::Int(start_val),
18378 Value::Null, ])));
18380 }
18381 };
18382
18383 let values: Vec<Value> = if inclusive {
18384 (start_val..=end_val).map(Value::Int).collect()
18385 } else {
18386 (start_val..end_val).map(Value::Int).collect()
18387 };
18388
18389 Ok(Value::Array(Rc::new(RefCell::new(values))))
18390 }
18391
18392 fn is_truthy(&self, value: &Value) -> bool {
18393 match value {
18394 Value::Null => false,
18395 Value::Bool(b) => *b,
18396 Value::Int(n) => *n != 0,
18397 Value::Float(n) => *n != 0.0,
18398 Value::String(s) => !s.is_empty(),
18399 Value::Array(arr) => !arr.borrow().is_empty(),
18400 Value::Empty => false,
18401 Value::Evidential { value, .. } => self.is_truthy(value),
18402 _ => true,
18403 }
18404 }
18405}
18406
18407impl Default for Interpreter {
18408 fn default() -> Self {
18409 Self::new()
18410 }
18411}
18412
18413#[cfg(test)]
18414mod tests {
18415 use super::*;
18416 use crate::Parser;
18417
18418 fn run(source: &str) -> Result<Value, RuntimeError> {
18419 let mut parser = Parser::new(source);
18420 let file = parser
18421 .parse_file()
18422 .map_err(|e| RuntimeError::new(e.to_string()))?;
18423 let mut interp = Interpreter::new();
18424 interp.execute(&file)
18425 }
18426
18427 #[test]
18428 fn test_arithmetic() {
18429 assert!(matches!(run("rite main() { ⤺ 2 + 3; }"), Ok(Value::Int(5))));
18430 assert!(matches!(
18431 run("rite main() { ⤺ 10 - 4; }"),
18432 Ok(Value::Int(6))
18433 ));
18434 assert!(matches!(
18435 run("rite main() { ⤺ 3 * 4; }"),
18436 Ok(Value::Int(12))
18437 ));
18438 assert!(matches!(
18439 run("rite main() { ⤺ 15 / 3; }"),
18440 Ok(Value::Int(5))
18441 ));
18442 assert!(matches!(
18443 run("rite main() { ⤺ 2 ** 10; }"),
18444 Ok(Value::Int(1024))
18445 ));
18446 }
18447
18448 #[test]
18449 fn test_variables() {
18450 assert!(matches!(
18451 run("rite main() { ≔ x = 42; ⤺ x; }"),
18452 Ok(Value::Int(42))
18453 ));
18454 }
18455
18456 #[test]
18457 fn test_conditionals() {
18458 assert!(matches!(
18459 run("rite main() { ⎇ true { ⤺ 1; } ⎉ { ⤺ 2; } }"),
18460 Ok(Value::Int(1))
18461 ));
18462 assert!(matches!(
18463 run("rite main() { ⎇ false { ⤺ 1; } ⎉ { ⤺ 2; } }"),
18464 Ok(Value::Int(2))
18465 ));
18466 }
18467
18468 #[test]
18469 fn test_arrays() {
18470 assert!(matches!(
18471 run("rite main() { ⤺ [1, 2, 3][1]; }"),
18472 Ok(Value::Int(2))
18473 ));
18474 }
18475
18476 #[test]
18477 fn test_functions() {
18478 let result = run("
18479 rite double(x: i64) → i64 { ⤺ x * 2; }
18480 rite main() { ⤺ double(21); }
18481 ");
18482 assert!(matches!(result, Ok(Value::Int(42))));
18483 }
18484
18485 #[test]
18486 fn test_pipe_transform() {
18487 let result = run("rite main() { ⤺ [1, 2, 3]|τ{_ * 2}|sum; }");
18488 assert!(matches!(result, Ok(Value::Int(12))));
18489 }
18490
18491 #[test]
18492 fn test_pipe_filter() {
18493 let result = run("rite main() { ⤺ [1, 2, 3, 4, 5]|φ{_ > 2}|sum; }");
18494 assert!(matches!(result, Ok(Value::Int(12)))); }
18496
18497 #[test]
18498 fn test_interpolation_evidentiality_propagation() {
18499 let result = run(r#"
18502 rite main() {
18503 ≔ rep = reported(42);
18504
18505 // Interpolating a reported value should make the string reported
18506 ≔ s = f"Value: {rep}";
18507 ⤺ s;
18508 }
18509 "#);
18510
18511 match result {
18512 Ok(Value::Evidential {
18513 evidence: Evidence::Reported,
18514 value,
18515 }) => {
18516 assert!(matches!(*value, Value::String(_)));
18518 }
18519 Ok(other) => panic!("Expected Evidential Reported, got {:?}", other),
18520 Err(e) => panic!("Error: {:?}", e),
18521 }
18522 }
18523
18524 #[test]
18525 fn test_interpolation_worst_evidence_wins() {
18526 let result = run(r#"
18528 rite main() {
18529 ≔ k = known(1); // Known is best
18530 ≔ u = uncertain(2); // Uncertain is worse
18531
18532 // Combining known and uncertain should yield uncertain
18533 ≔ s = f"{k} and {u}";
18534 ⤺ s;
18535 }
18536 "#);
18537
18538 match result {
18539 Ok(Value::Evidential {
18540 evidence: Evidence::Uncertain,
18541 ..
18542 }) => (),
18543 Ok(other) => panic!("Expected Evidential Uncertain, got {:?}", other),
18544 Err(e) => panic!("Error: {:?}", e),
18545 }
18546 }
18547
18548 #[test]
18549 fn test_interpolation_no_evidential_plain_string() {
18550 let result = run(r#"
18552 rite main() {
18553 ≔ x = 42;
18554 ≔ s = f"Value: {x}";
18555 ⤺ s;
18556 }
18557 "#);
18558
18559 match result {
18560 Ok(Value::String(s)) => {
18561 assert_eq!(*s, "Value: 42");
18562 }
18563 Ok(other) => panic!("Expected plain String, got {:?}", other),
18564 Err(e) => panic!("Error: {:?}", e),
18565 }
18566 }
18567}