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#[derive(Clone)]
17pub enum Value {
18 Null,
20 Bool(bool),
22 Int(i64),
24 Float(f64),
26 String(Rc<String>),
28 Char(char),
30 Array(Rc<RefCell<Vec<Value>>>),
32 Tuple(Rc<Vec<Value>>),
34 Struct {
36 name: String,
37 fields: Rc<RefCell<HashMap<String, Value>>>,
38 },
39 Variant {
41 enum_name: String,
42 variant_name: String,
43 fields: Option<Rc<Vec<Value>>>,
44 },
45 Function(Rc<Function>),
47 BuiltIn(Rc<BuiltInFn>),
49 Ref(Rc<RefCell<Value>>),
51 Infinity,
53 Empty,
54 Evidential {
56 value: Box<Value>,
57 evidence: Evidence,
58 },
59 Affective {
61 value: Box<Value>,
62 affect: RuntimeAffect,
63 },
64 Map(Rc<RefCell<HashMap<String, Value>>>),
66 Set(Rc<RefCell<std::collections::HashSet<String>>>),
68 Channel(Arc<ChannelInner>),
70 ThreadHandle(Arc<Mutex<Option<JoinHandle<Value>>>>),
72 Actor(Arc<ActorInner>),
74 Future(Rc<RefCell<FutureInner>>),
76 VariantConstructor {
78 enum_name: String,
79 variant_name: String,
80 },
81 DefaultConstructor {
83 type_name: String,
84 },
85 Range {
87 start: Option<i64>,
88 end: Option<i64>,
89 inclusive: bool,
90 },
91}
92
93#[derive(Clone)]
95pub enum FutureState {
96 Pending,
98 Running,
100 Ready(Box<Value>),
102 Failed(String),
104}
105
106pub struct FutureInner {
108 pub state: FutureState,
110 pub computation: Option<FutureComputation>,
112 pub complete_at: Option<std::time::Instant>,
114}
115
116impl Clone for FutureInner {
117 fn clone(&self) -> Self {
118 FutureInner {
119 state: self.state.clone(),
120 computation: self.computation.clone(),
121 complete_at: self.complete_at,
122 }
123 }
124}
125
126#[derive(Clone)]
128pub enum FutureComputation {
129 Immediate(Box<Value>),
131 Timer(std::time::Duration),
133 Lazy {
135 func: Rc<Function>,
136 args: Vec<Value>,
137 },
138 Join(Vec<Rc<RefCell<FutureInner>>>),
140 Race(Vec<Rc<RefCell<FutureInner>>>),
142}
143
144pub struct ChannelInner {
146 pub sender: Mutex<mpsc::Sender<Value>>,
147 pub receiver: Mutex<mpsc::Receiver<Value>>,
148}
149
150impl Clone for ChannelInner {
151 fn clone(&self) -> Self {
152 panic!("Channels cannot be cloned directly - use channel_clone()")
155 }
156}
157
158pub struct ActorInner {
161 pub name: String,
162 pub message_queue: Mutex<Vec<(String, String)>>, pub message_count: std::sync::atomic::AtomicUsize,
164}
165
166#[derive(Debug, Clone, Copy, PartialEq, Eq)]
168pub enum Evidence {
169 Known, Uncertain, Reported, Predicted, Paradox, }
175
176#[derive(Debug, Clone, PartialEq)]
178pub struct RuntimeAffect {
179 pub sentiment: Option<RuntimeSentiment>,
180 pub sarcasm: bool, pub intensity: Option<RuntimeIntensity>,
182 pub formality: Option<RuntimeFormality>,
183 pub emotion: Option<RuntimeEmotion>,
184 pub confidence: Option<RuntimeConfidence>,
185}
186
187#[derive(Debug, Clone, Copy, PartialEq, Eq)]
188pub enum RuntimeSentiment {
189 Positive, Negative, Neutral, }
193
194#[derive(Debug, Clone, Copy, PartialEq, Eq)]
195pub enum RuntimeIntensity {
196 Up, Down, Max, }
200
201#[derive(Debug, Clone, Copy, PartialEq, Eq)]
202pub enum RuntimeFormality {
203 Formal, Informal, }
206
207#[derive(Debug, Clone, Copy, PartialEq, Eq)]
208pub enum RuntimeEmotion {
209 Joy, Sadness, Anger, Fear, Surprise, Love, }
216
217#[derive(Debug, Clone, Copy, PartialEq, Eq)]
218pub enum RuntimeConfidence {
219 High, Medium, Low, }
223
224pub struct Function {
226 pub name: Option<String>,
227 pub params: Vec<String>,
228 pub body: Expr,
229 pub closure: Rc<RefCell<Environment>>,
230}
231
232pub struct BuiltInFn {
234 pub name: String,
235 pub arity: Option<usize>, pub func: fn(&mut Interpreter, Vec<Value>) -> Result<Value, RuntimeError>,
237}
238
239impl fmt::Debug for Value {
240 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
241 match self {
242 Value::Null => write!(f, "null"),
243 Value::Bool(b) => write!(f, "{}", b),
244 Value::Int(n) => write!(f, "{}", n),
245 Value::Float(n) => write!(f, "{}", n),
246 Value::String(s) => write!(f, "\"{}\"", s),
247 Value::Char(c) => write!(f, "'{}'", c),
248 Value::Array(arr) => {
249 let arr = arr.borrow();
250 write!(f, "[")?;
251 for (i, v) in arr.iter().enumerate() {
252 if i > 0 {
253 write!(f, ", ")?;
254 }
255 write!(f, "{:?}", v)?;
256 }
257 write!(f, "]")
258 }
259 Value::Tuple(vals) => {
260 write!(f, "(")?;
261 for (i, v) in vals.iter().enumerate() {
262 if i > 0 {
263 write!(f, ", ")?;
264 }
265 write!(f, "{:?}", v)?;
266 }
267 write!(f, ")")
268 }
269 Value::Struct { name, fields } => {
270 write!(f, "{} {{ ", name)?;
271 let fields = fields.borrow();
272 for (i, (k, v)) in fields.iter().enumerate() {
273 if i > 0 {
274 write!(f, ", ")?;
275 }
276 write!(f, "{}: {:?}", k, v)?;
277 }
278 write!(f, " }}")
279 }
280 Value::Variant {
281 enum_name,
282 variant_name,
283 fields,
284 } => {
285 write!(f, "{}::{}", enum_name, variant_name)?;
286 if let Some(fields) = fields {
287 write!(f, "(")?;
288 for (i, v) in fields.iter().enumerate() {
289 if i > 0 {
290 write!(f, ", ")?;
291 }
292 write!(f, "{:?}", v)?;
293 }
294 write!(f, ")")?;
295 }
296 Ok(())
297 }
298 Value::Function(func) => {
299 write!(f, "<fn {}>", func.name.as_deref().unwrap_or("anonymous"))
300 }
301 Value::BuiltIn(b) => write!(f, "<builtin {}>", b.name),
302 Value::Ref(r) => write!(f, "&{:?}", r.borrow()),
303 Value::Infinity => write!(f, "∞"),
304 Value::Empty => write!(f, "∅"),
305 Value::Evidential { value, evidence } => {
306 write!(f, "{:?}", value)?;
307 match evidence {
308 Evidence::Known => write!(f, "!"),
309 Evidence::Uncertain => write!(f, "?"),
310 Evidence::Reported => write!(f, "~"),
311 Evidence::Predicted => write!(f, "◊"),
312 Evidence::Paradox => write!(f, "‽"),
313 }
314 }
315 Value::Map(map) => {
316 let map = map.borrow();
317 write!(f, "{{")?;
318 for (i, (k, v)) in map.iter().enumerate() {
319 if i > 0 {
320 write!(f, ", ")?;
321 }
322 write!(f, "{:?}: {:?}", k, v)?;
323 }
324 write!(f, "}}")
325 }
326 Value::Set(set) => {
327 let set = set.borrow();
328 write!(f, "Set{{")?;
329 for (i, k) in set.iter().enumerate() {
330 if i > 0 {
331 write!(f, ", ")?;
332 }
333 write!(f, "{:?}", k)?;
334 }
335 write!(f, "}}")
336 }
337 Value::Channel(_) => write!(f, "<channel>"),
338 Value::ThreadHandle(_) => write!(f, "<thread>"),
339 Value::Actor(actor) => write!(f, "<actor {}>", actor.name),
340 Value::Future(fut) => {
341 let fut = fut.borrow();
342 match &fut.state {
343 FutureState::Pending => write!(f, "<future pending>"),
344 FutureState::Running => write!(f, "<future running>"),
345 FutureState::Ready(v) => write!(f, "<future ready: {:?}>", v),
346 FutureState::Failed(e) => write!(f, "<future failed: {}>", e),
347 }
348 }
349 Value::Affective { value, affect } => {
350 write!(f, "{:?}", value)?;
351 if let Some(s) = &affect.sentiment {
352 match s {
353 RuntimeSentiment::Positive => write!(f, "⊕")?,
354 RuntimeSentiment::Negative => write!(f, "⊖")?,
355 RuntimeSentiment::Neutral => write!(f, "⊜")?,
356 }
357 }
358 if affect.sarcasm {
359 write!(f, "⸮")?;
360 }
361 if let Some(i) = &affect.intensity {
362 match i {
363 RuntimeIntensity::Up => write!(f, "↑")?,
364 RuntimeIntensity::Down => write!(f, "↓")?,
365 RuntimeIntensity::Max => write!(f, "⇈")?,
366 }
367 }
368 if let Some(fo) = &affect.formality {
369 match fo {
370 RuntimeFormality::Formal => write!(f, "♔")?,
371 RuntimeFormality::Informal => write!(f, "♟")?,
372 }
373 }
374 if let Some(e) = &affect.emotion {
375 match e {
376 RuntimeEmotion::Joy => write!(f, "☺")?,
377 RuntimeEmotion::Sadness => write!(f, "☹")?,
378 RuntimeEmotion::Anger => write!(f, "⚡")?,
379 RuntimeEmotion::Fear => write!(f, "❄")?,
380 RuntimeEmotion::Surprise => write!(f, "✦")?,
381 RuntimeEmotion::Love => write!(f, "♡")?,
382 }
383 }
384 if let Some(c) = &affect.confidence {
385 match c {
386 RuntimeConfidence::High => write!(f, "◉")?,
387 RuntimeConfidence::Medium => write!(f, "◎")?,
388 RuntimeConfidence::Low => write!(f, "○")?,
389 }
390 }
391 Ok(())
392 }
393 Value::VariantConstructor {
394 enum_name,
395 variant_name,
396 } => {
397 write!(f, "<constructor {}::{}>", enum_name, variant_name)
398 }
399 Value::DefaultConstructor { type_name } => {
400 write!(f, "<default {}>", type_name)
401 }
402 Value::Range {
403 start,
404 end,
405 inclusive,
406 } => match (start, end) {
407 (Some(s), Some(e)) => {
408 if *inclusive {
409 write!(f, "{}..={}", s, e)
410 } else {
411 write!(f, "{}..{}", s, e)
412 }
413 }
414 (Some(s), None) => write!(f, "{}..", s),
415 (None, Some(e)) => {
416 if *inclusive {
417 write!(f, "..={}", e)
418 } else {
419 write!(f, "..{}", e)
420 }
421 }
422 (None, None) => write!(f, ".."),
423 },
424 }
425 }
426}
427
428impl fmt::Display for Value {
429 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
430 match self {
431 Value::Null => write!(f, "null"),
432 Value::Bool(b) => write!(f, "{}", b),
433 Value::Int(n) => write!(f, "{}", n),
434 Value::Float(n) => {
435 let rounded = n.round();
438 let is_close_to_int = (n - rounded).abs() < 1e-10;
439 let display_val = if is_close_to_int { rounded } else { *n };
440 if display_val.fract() == 0.0 && !display_val.is_nan() && !display_val.is_infinite() {
442 write!(f, "{}.0", display_val as i64)
443 } else {
444 write!(f, "{}", display_val)
445 }
446 }
447 Value::String(s) => write!(f, "{}", s),
448 Value::Char(c) => write!(f, "{}", c),
449 Value::Array(arr) => {
450 let arr = arr.borrow();
451 write!(f, "[")?;
452 for (i, v) in arr.iter().enumerate() {
453 if i > 0 {
454 write!(f, ", ")?;
455 }
456 write!(f, "{}", v)?;
457 }
458 write!(f, "]")
459 }
460 Value::Evidential { value, .. } => write!(f, "{}", value),
461 Value::Affective { value, affect } => {
462 let mut suffix = String::new();
464 if let Some(sent) = &affect.sentiment {
465 suffix.push(match sent {
466 RuntimeSentiment::Positive => '⊕',
467 RuntimeSentiment::Negative => '⊖',
468 RuntimeSentiment::Neutral => '⊜',
469 });
470 }
471 if affect.sarcasm {
472 suffix.push('⸮');
473 }
474 if let Some(int) = &affect.intensity {
475 suffix.push(match int {
476 RuntimeIntensity::Up => '↑',
477 RuntimeIntensity::Down => '↓',
478 RuntimeIntensity::Max => '⇈',
479 });
480 }
481 if let Some(form) = &affect.formality {
482 suffix.push(match form {
483 RuntimeFormality::Formal => '♔',
484 RuntimeFormality::Informal => '♟',
485 });
486 }
487 if let Some(emo) = &affect.emotion {
488 suffix.push(match emo {
489 RuntimeEmotion::Joy => '☺',
490 RuntimeEmotion::Sadness => '☹',
491 RuntimeEmotion::Anger => '⚡',
492 RuntimeEmotion::Fear => '❄',
493 RuntimeEmotion::Surprise => '✦',
494 RuntimeEmotion::Love => '♡',
495 });
496 }
497 if let Some(conf) = &affect.confidence {
498 suffix.push(match conf {
499 RuntimeConfidence::High => '◉',
500 RuntimeConfidence::Medium => '◎',
501 RuntimeConfidence::Low => '○',
502 });
503 }
504 write!(f, "{}{}", value, suffix)
505 }
506 _ => write!(f, "{:?}", self),
507 }
508 }
509}
510
511impl Value {
512 pub fn as_tensor_scalar(&self) -> Option<f64> {
516 match self {
517 Value::Struct { name, fields } if name == "Tensor" => {
518 tensor_scalar_from_fields(&fields.borrow())
519 }
520 Value::Float(f) => Some(*f),
521 Value::Int(n) => Some(*n as f64),
522 _ => None,
523 }
524 }
525
526 pub fn as_tensor_data(&self) -> Option<Vec<f64>> {
529 match self {
530 Value::Struct { name, fields } if name == "Tensor" => {
531 tensor_data_from_fields(&fields.borrow())
532 }
533 _ => None,
534 }
535 }
536
537 pub fn as_tensor_shape(&self) -> Option<Vec<usize>> {
540 match self {
541 Value::Struct { name, fields } if name == "Tensor" => {
542 tensor_shape_from_fields(&fields.borrow())
543 }
544 _ => None,
545 }
546 }
547}
548
549fn tensor_scalar_from_fields(fields: &HashMap<String, Value>) -> Option<f64> {
559 if let Some(val) = fields.get("_value") {
561 match val {
562 Value::Float(f) => return Some(*f),
563 Value::Int(n) => return Some(*n as f64),
564 _ => {}
565 }
566 }
567 if let Some(Value::Array(arr)) = fields.get("data") {
569 if let Some(first) = arr.borrow().first() {
570 match first {
571 Value::Float(f) => return Some(*f),
572 Value::Int(n) => return Some(*n as f64),
573 _ => {}
574 }
575 }
576 }
577 None
578}
579
580fn tensor_data_from_fields(fields: &HashMap<String, Value>) -> Option<Vec<f64>> {
582 if let Some(Value::Array(arr)) = fields.get("data") {
583 Some(arr.borrow().iter().map(|v| match v {
584 Value::Float(f) => *f,
585 Value::Int(n) => *n as f64,
586 _ => 0.0,
587 }).collect())
588 } else {
589 None
590 }
591}
592
593fn tensor_shape_from_fields(fields: &HashMap<String, Value>) -> Option<Vec<usize>> {
595 if let Some(Value::Array(arr)) = fields.get("shape") {
596 Some(arr.borrow().iter().map(|v| match v {
597 Value::Int(n) => *n as usize,
598 _ => 0,
599 }).collect())
600 } else {
601 None
602 }
603}
604
605#[derive(Debug, Clone, Copy, PartialEq, Eq)]
607pub enum RuntimeErrorCode {
608 DivisionByZero,
610 IndexOutOfBounds,
612 UndefinedVariable,
614 TypeError,
616 InvalidOperation,
618 AssertionFailed,
620 Overflow,
622 StackOverflow,
624 ControlFlowError,
626 LinearTypeViolation,
628 Generic,
630}
631
632impl RuntimeErrorCode {
633 pub fn code(&self) -> &'static str {
634 match self {
635 RuntimeErrorCode::DivisionByZero => "R0001",
636 RuntimeErrorCode::IndexOutOfBounds => "R0002",
637 RuntimeErrorCode::UndefinedVariable => "R0003",
638 RuntimeErrorCode::TypeError => "R0004",
639 RuntimeErrorCode::InvalidOperation => "R0005",
640 RuntimeErrorCode::AssertionFailed => "R0006",
641 RuntimeErrorCode::Overflow => "R0007",
642 RuntimeErrorCode::StackOverflow => "R0008",
643 RuntimeErrorCode::ControlFlowError => "R0009",
644 RuntimeErrorCode::LinearTypeViolation => "R0010",
645 RuntimeErrorCode::Generic => "R0000",
646 }
647 }
648}
649
650#[derive(Debug)]
652pub struct RuntimeError {
653 pub message: String,
654 pub span: Option<Span>,
655 pub code: RuntimeErrorCode,
656}
657
658impl RuntimeError {
659 pub fn new(message: impl Into<String>) -> Self {
660 Self {
661 message: message.into(),
662 span: None,
663 code: RuntimeErrorCode::Generic,
664 }
665 }
666
667 pub fn with_span(message: impl Into<String>, span: Span) -> Self {
668 Self {
669 message: message.into(),
670 span: Some(span),
671 code: RuntimeErrorCode::Generic,
672 }
673 }
674
675 pub fn with_code(mut self, code: RuntimeErrorCode) -> Self {
676 self.code = code;
677 self
678 }
679
680 pub fn division_by_zero() -> Self {
684 Self::new("division by zero")
685 .with_code(RuntimeErrorCode::DivisionByZero)
686 }
687
688 pub fn linear_type_violation(var_name: &str) -> Self {
690 Self::new(format!(
691 "linear value '{}' used twice (no-cloning theorem violation)",
692 var_name
693 )).with_code(RuntimeErrorCode::LinearTypeViolation)
694 }
695
696 pub fn index_out_of_bounds(index: i64, len: usize) -> Self {
698 Self::new(format!("index {} out of bounds for length {}", index, len))
699 .with_code(RuntimeErrorCode::IndexOutOfBounds)
700 }
701
702 pub fn undefined_variable(name: &str) -> Self {
704 Self::new(format!("undefined variable: `{}`", name))
705 .with_code(RuntimeErrorCode::UndefinedVariable)
706 }
707
708 pub fn type_error(expected: &str, found: &str) -> Self {
710 Self::new(format!("expected {}, found {}", expected, found))
711 .with_code(RuntimeErrorCode::TypeError)
712 }
713
714 pub fn invalid_operation(op: &str, context: &str) -> Self {
716 Self::new(format!("{} is not valid for {}", op, context))
717 .with_code(RuntimeErrorCode::InvalidOperation)
718 }
719
720 pub fn assertion_failed(msg: Option<&str>) -> Self {
722 let message = match msg {
723 Some(m) => format!("assertion failed: {}", m),
724 None => "assertion failed".to_string(),
725 };
726 Self::new(message).with_code(RuntimeErrorCode::AssertionFailed)
727 }
728}
729
730impl fmt::Display for RuntimeError {
731 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
732 write!(f, "[{}] Runtime error: {}", self.code.code(), self.message)?;
733 if let Some(span) = self.span {
734 write!(f, " at {}", span)?;
735 }
736 Ok(())
737 }
738}
739
740#[derive(Debug, Clone)]
742pub enum ControlFlow {
743 Return(Value),
744 Break(Option<Value>),
745 Continue,
746}
747
748impl From<ControlFlow> for RuntimeError {
749 fn from(cf: ControlFlow) -> Self {
750 match cf {
751 ControlFlow::Return(_) => RuntimeError::new("return outside function")
752 .with_code(RuntimeErrorCode::ControlFlowError),
753 ControlFlow::Break(_) => RuntimeError::new("break outside loop")
754 .with_code(RuntimeErrorCode::ControlFlowError),
755 ControlFlow::Continue => RuntimeError::new("continue outside loop")
756 .with_code(RuntimeErrorCode::ControlFlowError),
757 }
758 }
759}
760
761pub type EvalResult = Result<Value, EvalError>;
763
764#[derive(Debug)]
766pub enum EvalError {
767 Runtime(RuntimeError),
768 Control(ControlFlow),
769}
770
771impl From<RuntimeError> for EvalError {
772 fn from(e: RuntimeError) -> Self {
773 EvalError::Runtime(e)
774 }
775}
776
777impl From<ControlFlow> for EvalError {
778 fn from(cf: ControlFlow) -> Self {
779 EvalError::Control(cf)
780 }
781}
782
783impl fmt::Display for EvalError {
784 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
785 match self {
786 EvalError::Runtime(e) => write!(f, "{}", e),
787 EvalError::Control(cf) => write!(f, "Unexpected control flow: {:?}", cf),
788 }
789 }
790}
791
792#[derive(Clone)]
794pub struct Environment {
795 values: HashMap<String, Value>,
796 parent: Option<Rc<RefCell<Environment>>>,
797}
798
799impl Environment {
800 pub fn new() -> Self {
801 Self {
802 values: HashMap::new(),
803 parent: None,
804 }
805 }
806
807 pub fn with_parent(parent: Rc<RefCell<Environment>>) -> Self {
808 Self {
809 values: HashMap::new(),
810 parent: Some(parent),
811 }
812 }
813
814 pub fn define(&mut self, name: String, value: Value) {
815 self.values.insert(name, value);
816 }
817
818 pub fn get(&self, name: &str) -> Option<Value> {
819 if let Some(value) = self.values.get(name) {
820 Some(value.clone())
821 } else if let Some(ref parent) = self.parent {
822 parent.borrow().get(name)
823 } else {
824 None
825 }
826 }
827
828 pub fn set(&mut self, name: &str, value: Value) -> Result<(), RuntimeError> {
829 if self.values.contains_key(name) {
830 self.values.insert(name.to_string(), value);
831 Ok(())
832 } else if let Some(ref parent) = self.parent {
833 parent.borrow_mut().set(name, value)
834 } else {
835 Err(RuntimeError::undefined_variable(name))
836 }
837 }
838}
839
840impl Default for Environment {
841 fn default() -> Self {
842 Self::new()
843 }
844}
845
846#[derive(Default)]
848pub struct LinearTypeState {
849 pub consumed: RefCell<HashSet<String>>,
851 pub vars: RefCell<HashSet<String>>,
853}
854
855#[derive(Default)]
857pub struct TypeConstructionContext {
858 pub tensor_shape: RefCell<Option<Vec<i64>>>,
860 pub struct_generics: RefCell<Option<(String, Vec<i64>)>>,
862}
863
864pub struct Interpreter {
866 pub globals: Rc<RefCell<Environment>>,
868 pub environment: Rc<RefCell<Environment>>,
870 pub types: HashMap<String, TypeDef>,
872 pub variant_constructors: HashMap<String, (String, String, usize)>,
874 pub default_structs: HashMap<String, StructDef>,
876 pub output: Vec<String>,
878 return_value: Option<Value>,
880 pub program_args: Option<Vec<String>>,
882 pub current_module: Option<String>,
884 pub current_self_type: Option<String>,
886 pub current_source_dir: Option<String>,
888 pub loaded_crates: HashSet<String>,
890 pub loading_crates: HashSet<String>,
892 pub project_root: Option<PathBuf>,
894 pub workspace_members: HashMap<String, PathBuf>,
896 pub drop_types: HashSet<String>,
898 pub linear_state: LinearTypeState,
900 pub mutable_vars: RefCell<HashSet<String>>,
902 pub var_types: RefCell<HashMap<String, (String, Vec<String>)>>,
904 pub type_context: TypeConstructionContext,
906}
907
908#[derive(Clone)]
910pub enum TypeDef {
911 Struct(StructDef),
912 Enum(EnumDef),
913}
914
915impl Interpreter {
916 pub fn new() -> Self {
917 let globals = Rc::new(RefCell::new(Environment::new()));
918 let environment = globals.clone();
919
920 let mut interp = Self {
921 globals: globals.clone(),
922 environment,
923 types: HashMap::new(),
924 variant_constructors: HashMap::new(),
925 default_structs: HashMap::new(),
926 return_value: None,
927 output: Vec::new(),
928 program_args: None,
929 current_module: None,
930 current_self_type: None,
931 current_source_dir: None,
932 loaded_crates: HashSet::new(),
933 loading_crates: HashSet::new(),
934 project_root: None,
935 workspace_members: HashMap::new(),
936 drop_types: HashSet::new(),
937 linear_state: LinearTypeState::default(),
938 mutable_vars: RefCell::new(HashSet::new()),
939 var_types: RefCell::new(HashMap::new()),
940 type_context: TypeConstructionContext::default(),
941 };
942
943 interp.register_builtins();
945
946 interp
947 }
948
949 pub fn set_program_args(&mut self, args: Vec<String>) {
951 self.program_args = Some(args);
952 }
953
954 pub fn set_current_module(&mut self, module: Option<String>) {
956 self.current_module = module;
957 }
958
959 pub fn set_current_source_dir(&mut self, dir: Option<String>) {
961 self.current_source_dir = dir;
962 }
963
964 pub fn get_program_args(&self) -> Vec<String> {
966 self.program_args
967 .clone()
968 .unwrap_or_else(|| std::env::args().collect())
969 }
970
971 pub fn discover_project(&mut self, source_dir: &str) -> Result<(), RuntimeError> {
974 let mut current = PathBuf::from(source_dir);
975
976 loop {
978 let sigil_toml = current.join("Sigil.toml");
979 if sigil_toml.exists() {
980 if let Ok(result) = self.try_parse_workspace_toml(&sigil_toml) {
981 if result {
982 return Ok(());
983 }
984 }
986 }
987
988 let sigil_toml_lower = current.join("sigil.toml");
990 if sigil_toml_lower.exists() {
991 if let Ok(result) = self.try_parse_workspace_toml(&sigil_toml_lower) {
992 if result {
993 return Ok(());
994 }
995 }
997 }
998
999 if !current.pop() {
1000 crate::sigil_debug!(
1002 "DEBUG discover_project: no workspace Sigil.toml found from {}",
1003 source_dir
1004 );
1005 return Ok(());
1006 }
1007 }
1008 }
1009
1010 fn try_parse_workspace_toml(&mut self, path: &PathBuf) -> Result<bool, RuntimeError> {
1013 let content = std::fs::read_to_string(path)
1014 .map_err(|e| RuntimeError::new(format!("Failed to read Sigil.toml: {}", e)))?;
1015
1016 let toml_value: toml::Value = content
1017 .parse()
1018 .map_err(|e| RuntimeError::new(format!("Failed to parse Sigil.toml: {}", e)))?;
1019
1020 if let Some(workspace) = toml_value.get("workspace") {
1022 if workspace
1023 .get("members")
1024 .and_then(|m| m.as_array())
1025 .is_some()
1026 {
1027 return self.parse_sigil_toml(path).map(|_| true);
1029 }
1030 }
1031
1032 crate::sigil_debug!(
1034 "DEBUG try_parse_workspace_toml: {:?} is not a workspace config",
1035 path
1036 );
1037 Ok(false)
1038 }
1039
1040 fn parse_sigil_toml(&mut self, path: &PathBuf) -> Result<(), RuntimeError> {
1042 let content = std::fs::read_to_string(path)
1043 .map_err(|e| RuntimeError::new(format!("Failed to read Sigil.toml: {}", e)))?;
1044
1045 let toml_value: toml::Value = content
1046 .parse()
1047 .map_err(|e| RuntimeError::new(format!("Failed to parse Sigil.toml: {}", e)))?;
1048
1049 self.project_root = path.parent().map(|p| p.to_path_buf());
1050
1051 if let Some(workspace) = toml_value.get("workspace") {
1053 if let Some(members) = workspace.get("members").and_then(|m| m.as_array()) {
1054 for member in members {
1055 if let Some(member_path) = member.as_str() {
1056 let crate_name = std::path::Path::new(member_path)
1058 .file_name()
1059 .and_then(|n| n.to_str())
1060 .map(|n| n.replace("-", "_"))
1061 .unwrap_or_default();
1062
1063 if !crate_name.is_empty() {
1064 crate::sigil_debug!(
1065 "DEBUG parse_sigil_toml: registered workspace member: {} -> {}",
1066 &crate_name,
1067 member_path
1068 );
1069 self.workspace_members
1070 .insert(crate_name, PathBuf::from(member_path));
1071 }
1072 }
1073 }
1074 }
1075 }
1076
1077 crate::sigil_debug!(
1078 "DEBUG parse_sigil_toml: loaded {} workspace members from {:?}",
1079 self.workspace_members.len(),
1080 path
1081 );
1082
1083 Ok(())
1084 }
1085
1086 pub fn load_crate(&mut self, crate_name: &str) -> Result<bool, RuntimeError> {
1088 if self.loaded_crates.contains(crate_name) {
1090 return Ok(true);
1091 }
1092
1093 if self.loading_crates.contains(crate_name) {
1095 return Err(RuntimeError::new(format!(
1096 "Circular dependency detected: crate '{}' is already being loaded",
1097 crate_name
1098 )));
1099 }
1100
1101 let crate_path = match self.workspace_members.get(crate_name) {
1103 Some(p) => p.clone(),
1104 None => {
1105 crate::sigil_debug!(
1106 "DEBUG load_crate: crate '{}' not found in workspace members",
1107 crate_name
1108 );
1109 return Ok(false);
1110 }
1111 };
1112
1113 let project_root = match &self.project_root {
1114 Some(r) => r.clone(),
1115 None => {
1116 crate::sigil_debug!("DEBUG load_crate: no project root set");
1117 return Ok(false);
1118 }
1119 };
1120
1121 let lib_path = project_root.join(&crate_path).join("src").join("lib.sigil");
1123
1124 if !lib_path.exists() {
1125 crate::sigil_debug!("DEBUG load_crate: lib.sigil not found at {:?}", lib_path);
1126 return Ok(false);
1127 }
1128
1129 self.loading_crates.insert(crate_name.to_string());
1131
1132 crate::sigil_debug!(
1133 "DEBUG load_crate: loading crate '{}' from {:?}",
1134 crate_name,
1135 lib_path
1136 );
1137
1138 let source = std::fs::read_to_string(&lib_path)
1140 .map_err(|e| RuntimeError::new(format!("Failed to read {:?}: {}", lib_path, e)))?;
1141
1142 let prev_module = self.current_module.clone();
1144 let prev_source_dir = self.current_source_dir.clone();
1145
1146 self.current_module = Some(crate_name.to_string());
1148 self.current_source_dir = lib_path.parent().map(|p| p.to_string_lossy().to_string());
1149
1150 let mut parser = crate::Parser::new(&source);
1152
1153 match parser.parse_file() {
1154 Ok(parsed_file) => {
1155 for item in &parsed_file.items {
1157 if let Err(e) = self.execute_item(&item.node) {
1158 crate::sigil_warn!("Warning: error loading crate '{}': {}", crate_name, e);
1159 }
1160 }
1161 }
1162 Err(e) => {
1163 crate::sigil_warn!("Warning: failed to parse crate '{}': {:?}", crate_name, e);
1164 }
1165 }
1166
1167 self.current_module = prev_module;
1169 self.current_source_dir = prev_source_dir;
1170
1171 self.loading_crates.remove(crate_name);
1173 self.loaded_crates.insert(crate_name.to_string());
1174
1175 crate::sigil_debug!(
1176 "DEBUG load_crate: successfully loaded crate '{}'",
1177 crate_name
1178 );
1179
1180 Ok(true)
1181 }
1182
1183 fn register_builtins(&mut self) {
1184 self.globals
1186 .borrow_mut()
1187 .define("PhantomData".to_string(), Value::Null);
1188
1189 self.define_builtin("print", None, |interp, args| {
1191 let output: Vec<String> = args.iter().map(|v| format!("{}", v)).collect();
1192 let line = output.join(" ");
1193 println!("{}", line);
1194 interp.output.push(line);
1195 Ok(Value::Null)
1196 });
1197
1198 self.define_builtin("type_of", Some(1), |_, args| {
1200 let type_name = match &args[0] {
1201 Value::Null => "null",
1202 Value::Bool(_) => "bool",
1203 Value::Int(_) => "i64",
1204 Value::Float(_) => "f64",
1205 Value::String(_) => "str",
1206 Value::Char(_) => "char",
1207 Value::Array(_) => "array",
1208 Value::Tuple(_) => "tuple",
1209 Value::Struct { name, .. } => name,
1210 Value::Variant { enum_name, .. } => enum_name,
1211 Value::Function(_) => "fn",
1212 Value::BuiltIn(_) => "builtin",
1213 Value::Ref(_) => "ref",
1214 Value::Infinity => "infinity",
1215 Value::Empty => "empty",
1216 Value::Evidential { .. } => "evidential",
1217 Value::Affective { .. } => "affective",
1218 Value::Map(_) => "map",
1219 Value::Set(_) => "set",
1220 Value::Channel(_) => "channel",
1221 Value::ThreadHandle(_) => "thread",
1222 Value::Actor(_) => "actor",
1223 Value::Future(_) => "future",
1224 Value::VariantConstructor { .. } => "variant_constructor",
1225 Value::DefaultConstructor { .. } => "default_constructor",
1226 Value::Range { .. } => "range",
1227 };
1228 Ok(Value::String(Rc::new(type_name.to_string())))
1229 });
1230
1231 self.define_builtin("len", Some(1), |_, args| match &args[0] {
1233 Value::Array(arr) => Ok(Value::Int(arr.borrow().len() as i64)),
1234 Value::String(s) => Ok(Value::Int(s.len() as i64)),
1235 Value::Tuple(t) => Ok(Value::Int(t.len() as i64)),
1236 _ => Err(RuntimeError::new("len() requires array, string, or tuple")),
1237 });
1238
1239 self.define_builtin("push", Some(2), |_, args| match &args[0] {
1240 Value::Array(arr) => {
1241 arr.borrow_mut().push(args[1].clone());
1242 Ok(Value::Null)
1243 }
1244 _ => Err(RuntimeError::new("push() requires array")),
1245 });
1246
1247 self.define_builtin("pop", Some(1), |_, args| match &args[0] {
1248 Value::Array(arr) => arr
1249 .borrow_mut()
1250 .pop()
1251 .ok_or_else(|| RuntimeError::new("pop() on empty array")),
1252 _ => Err(RuntimeError::new("pop() requires array")),
1253 });
1254
1255 self.define_builtin("abs", Some(1), |_, args| match &args[0] {
1257 Value::Int(n) => Ok(Value::Int(n.abs())),
1258 Value::Float(n) => Ok(Value::Float(n.abs())),
1259 _ => Err(RuntimeError::new("abs() requires number")),
1260 });
1261
1262 self.define_builtin("sqrt", Some(1), |_, args| match &args[0] {
1263 Value::Int(n) => Ok(Value::Float((*n as f64).sqrt())),
1264 Value::Float(n) => Ok(Value::Float(n.sqrt())),
1265 _ => Err(RuntimeError::new("sqrt() requires number")),
1266 });
1267
1268 self.define_builtin("sin", Some(1), |_, args| match &args[0] {
1269 Value::Int(n) => Ok(Value::Float((*n as f64).sin())),
1270 Value::Float(n) => Ok(Value::Float(n.sin())),
1271 _ => Err(RuntimeError::new("sin() requires number")),
1272 });
1273
1274 self.define_builtin("cos", Some(1), |_, args| match &args[0] {
1275 Value::Int(n) => Ok(Value::Float((*n as f64).cos())),
1276 Value::Float(n) => Ok(Value::Float(n.cos())),
1277 _ => Err(RuntimeError::new("cos() requires number")),
1278 });
1279
1280 self.define_builtin("known", Some(1), |_, args| {
1282 Ok(Value::Evidential {
1283 value: Box::new(args[0].clone()),
1284 evidence: Evidence::Known,
1285 })
1286 });
1287
1288 self.define_builtin("uncertain", Some(1), |_, args| {
1289 Ok(Value::Evidential {
1290 value: Box::new(args[0].clone()),
1291 evidence: Evidence::Uncertain,
1292 })
1293 });
1294
1295 self.define_builtin("reported", Some(1), |_, args| {
1296 Ok(Value::Evidential {
1297 value: Box::new(args[0].clone()),
1298 evidence: Evidence::Reported,
1299 })
1300 });
1301
1302 self.globals.borrow_mut().define(
1304 "Box·new".to_string(),
1305 Value::BuiltIn(Rc::new(BuiltInFn {
1306 name: "Box·new".to_string(),
1307 arity: Some(1),
1308 func: |_, args| Ok(args[0].clone()),
1309 })),
1310 );
1311
1312 self.globals.borrow_mut().define(
1314 "Map·new".to_string(),
1315 Value::BuiltIn(Rc::new(BuiltInFn {
1316 name: "Map·new".to_string(),
1317 arity: Some(0),
1318 func: |_, _| Ok(Value::Map(Rc::new(RefCell::new(HashMap::new())))),
1319 })),
1320 );
1321
1322 self.define_builtin("range", Some(2), |_, args| {
1324 let start = match &args[0] {
1325 Value::Int(n) => *n,
1326 _ => return Err(RuntimeError::new("range() requires integers")),
1327 };
1328 let end = match &args[1] {
1329 Value::Int(n) => *n,
1330 _ => return Err(RuntimeError::new("range() requires integers")),
1331 };
1332 let values: Vec<Value> = (start..end).map(Value::Int).collect();
1333 Ok(Value::Array(Rc::new(RefCell::new(values))))
1334 });
1335
1336 self.globals.borrow_mut().define(
1338 "ExitCode·SUCCESS".to_string(),
1339 Value::Variant {
1340 enum_name: "ExitCode".to_string(),
1341 variant_name: "SUCCESS".to_string(),
1342 fields: Some(Rc::new(vec![Value::Int(0)])),
1343 },
1344 );
1345 self.globals.borrow_mut().define(
1346 "ExitCode·FAILURE".to_string(),
1347 Value::Variant {
1348 enum_name: "ExitCode".to_string(),
1349 variant_name: "FAILURE".to_string(),
1350 fields: Some(Rc::new(vec![Value::Int(1)])),
1351 },
1352 );
1353
1354 self.define_builtin("PathBuf·from", Some(1), |_, args| {
1356 let arg = match &args[0] {
1358 Value::Ref(r) => r.borrow().clone(),
1359 other => other.clone(),
1360 };
1361 let path = match &arg {
1362 Value::String(s2) => s2.as_str().to_string(),
1363 _ => return Err(RuntimeError::new("PathBuf::from expects a string")),
1364 };
1365 let mut fields = HashMap::new();
1367 fields.insert("path".to_string(), Value::String(Rc::new(path)));
1368 Ok(Value::Struct {
1369 name: "PathBuf".to_string(),
1370 fields: Rc::new(RefCell::new(fields)),
1371 })
1372 });
1373
1374 self.define_builtin("Path·new", Some(1), |_, args| {
1376 let arg = match &args[0] {
1378 Value::Ref(r) => r.borrow().clone(),
1379 other => other.clone(),
1380 };
1381 let path = match &arg {
1382 Value::String(s2) => s2.as_str().to_string(),
1383 _ => return Err(RuntimeError::new("Path::new expects a string")),
1384 };
1385 let mut fields = HashMap::new();
1386 fields.insert("path".to_string(), Value::String(Rc::new(path)));
1387 Ok(Value::Struct {
1388 name: "Path".to_string(),
1389 fields: Rc::new(RefCell::new(fields)),
1390 })
1391 });
1392
1393 self.define_builtin("std·fs·read_to_string", Some(1), |interp, args| {
1395 fn unwrap_refs(v: &Value) -> Value {
1397 match v {
1398 Value::Ref(r) => unwrap_refs(&r.borrow()),
1399 other => other.clone(),
1400 }
1401 }
1402 let arg = unwrap_refs(&args[0]);
1403 crate::sigil_debug!("DEBUG read_to_string: arg = {:?}", arg);
1404 crate::sigil_debug!(
1406 "DEBUG read_to_string: env has path = {:?}",
1407 interp.environment.borrow().get("path")
1408 );
1409 let path = match &arg {
1410 Value::String(s) => s.to_string(),
1411 Value::Struct { name, fields, .. } => {
1413 crate::sigil_debug!("DEBUG read_to_string: struct name = {}", name);
1414 fields
1415 .borrow()
1416 .get("path")
1417 .and_then(|v| {
1418 if let Value::String(s) = v {
1419 Some(s.to_string())
1420 } else {
1421 None
1422 }
1423 })
1424 .ok_or_else(|| RuntimeError::new("Expected path field in struct"))?
1425 }
1426 Value::Variant {
1428 enum_name,
1429 variant_name,
1430 fields,
1431 } if enum_name == "Option" && variant_name == "Some" => {
1432 if let Some(fields) = fields {
1433 if let Some(Value::String(s)) = fields.first() {
1434 s.to_string()
1435 } else {
1436 return Err(RuntimeError::new(
1437 "read_to_string: Option::Some does not contain a string",
1438 ));
1439 }
1440 } else {
1441 return Err(RuntimeError::new(
1442 "read_to_string: Option::Some has no fields",
1443 ));
1444 }
1445 }
1446 _ => {
1447 return Err(RuntimeError::new(&format!(
1448 "read_to_string expects a path string or PathBuf, got {:?}",
1449 arg
1450 )))
1451 }
1452 };
1453 match std::fs::read_to_string(&path) {
1454 Ok(content) => Ok(Value::Variant {
1455 enum_name: "Result".to_string(),
1456 variant_name: "Ok".to_string(),
1457 fields: Some(Rc::new(vec![Value::String(Rc::new(content))])),
1458 }),
1459 Err(e) => Ok(Value::Variant {
1460 enum_name: "Result".to_string(),
1461 variant_name: "Err".to_string(),
1462 fields: Some(Rc::new(vec![Value::String(Rc::new(e.to_string()))])),
1463 }),
1464 }
1465 });
1466
1467 self.define_builtin("fs·read_to_string", Some(1), |_, args| {
1469 let arg = match &args[0] {
1470 Value::Ref(r) => r.borrow().clone(),
1471 other => other.clone(),
1472 };
1473 let path = match &arg {
1474 Value::String(s) => s.to_string(),
1475 Value::Struct { fields, .. } => fields
1476 .borrow()
1477 .get("path")
1478 .and_then(|v| {
1479 if let Value::String(s) = v {
1480 Some(s.to_string())
1481 } else {
1482 None
1483 }
1484 })
1485 .ok_or_else(|| RuntimeError::new("Expected path field in struct"))?,
1486 _ => {
1487 return Err(RuntimeError::new(
1488 "read_to_string expects a path string or PathBuf",
1489 ))
1490 }
1491 };
1492 match std::fs::read_to_string(&path) {
1493 Ok(content) => Ok(Value::Variant {
1494 enum_name: "Result".to_string(),
1495 variant_name: "Ok".to_string(),
1496 fields: Some(Rc::new(vec![Value::String(Rc::new(content))])),
1497 }),
1498 Err(e) => Ok(Value::Variant {
1499 enum_name: "Result".to_string(),
1500 variant_name: "Err".to_string(),
1501 fields: Some(Rc::new(vec![Value::String(Rc::new(e.to_string()))])),
1502 }),
1503 }
1504 });
1505
1506 self.define_builtin("std·fs·read_dir", Some(1), |_, args| {
1508 fn unwrap_refs(v: &Value) -> Value {
1509 match v {
1510 Value::Ref(r) => unwrap_refs(&r.borrow()),
1511 other => other.clone(),
1512 }
1513 }
1514 let arg = unwrap_refs(&args[0]);
1515 let path = match &arg {
1516 Value::String(s) => s.to_string(),
1517 Value::Struct { name, fields, .. } if name == "Path" || name == "PathBuf" => fields
1518 .borrow()
1519 .get("path")
1520 .and_then(|v| {
1521 if let Value::String(s) = v {
1522 Some(s.to_string())
1523 } else {
1524 None
1525 }
1526 })
1527 .ok_or_else(|| RuntimeError::new("Expected path field in struct"))?,
1528 _ => {
1529 return Err(RuntimeError::new(&format!(
1530 "read_dir expects a path, got {:?}",
1531 arg
1532 )))
1533 }
1534 };
1535 match std::fs::read_dir(&path) {
1536 Ok(entries) => {
1537 let entry_values: Vec<Value> = entries
1539 .filter_map(|e| e.ok())
1540 .map(|e| {
1541 let entry_path = e.path().to_string_lossy().to_string();
1542 let mut fields = HashMap::new();
1543 fields.insert("path".to_string(), Value::String(Rc::new(entry_path)));
1544 Value::Variant {
1546 enum_name: "Result".to_string(),
1547 variant_name: "Ok".to_string(),
1548 fields: Some(Rc::new(vec![Value::Struct {
1549 name: "DirEntry".to_string(),
1550 fields: Rc::new(RefCell::new(fields)),
1551 }])),
1552 }
1553 })
1554 .collect();
1555 Ok(Value::Variant {
1557 enum_name: "Result".to_string(),
1558 variant_name: "Ok".to_string(),
1559 fields: Some(Rc::new(vec![Value::Array(Rc::new(RefCell::new(
1560 entry_values,
1561 )))])),
1562 })
1563 }
1564 Err(e) => Ok(Value::Variant {
1565 enum_name: "Result".to_string(),
1566 variant_name: "Err".to_string(),
1567 fields: Some(Rc::new(vec![Value::String(Rc::new(e.to_string()))])),
1568 }),
1569 }
1570 });
1571
1572 self.define_builtin("fs·read_dir", Some(1), |_, args| {
1574 fn unwrap_refs(v: &Value) -> Value {
1575 match v {
1576 Value::Ref(r) => unwrap_refs(&r.borrow()),
1577 other => other.clone(),
1578 }
1579 }
1580 let arg = unwrap_refs(&args[0]);
1581 let path = match &arg {
1582 Value::String(s) => s.to_string(),
1583 Value::Struct { name, fields, .. } if name == "Path" || name == "PathBuf" => fields
1584 .borrow()
1585 .get("path")
1586 .and_then(|v| {
1587 if let Value::String(s) = v {
1588 Some(s.to_string())
1589 } else {
1590 None
1591 }
1592 })
1593 .ok_or_else(|| RuntimeError::new("Expected path field in struct"))?,
1594 _ => {
1595 return Err(RuntimeError::new(&format!(
1596 "read_dir expects a path, got {:?}",
1597 arg
1598 )))
1599 }
1600 };
1601 match std::fs::read_dir(&path) {
1602 Ok(entries) => {
1603 let entry_values: Vec<Value> = entries
1604 .filter_map(|e| e.ok())
1605 .map(|e| {
1606 let entry_path = e.path().to_string_lossy().to_string();
1607 let mut fields = HashMap::new();
1608 fields.insert("path".to_string(), Value::String(Rc::new(entry_path)));
1609 Value::Variant {
1610 enum_name: "Result".to_string(),
1611 variant_name: "Ok".to_string(),
1612 fields: Some(Rc::new(vec![Value::Struct {
1613 name: "DirEntry".to_string(),
1614 fields: Rc::new(RefCell::new(fields)),
1615 }])),
1616 }
1617 })
1618 .collect();
1619 Ok(Value::Variant {
1620 enum_name: "Result".to_string(),
1621 variant_name: "Ok".to_string(),
1622 fields: Some(Rc::new(vec![Value::Array(Rc::new(RefCell::new(
1623 entry_values,
1624 )))])),
1625 })
1626 }
1627 Err(e) => Ok(Value::Variant {
1628 enum_name: "Result".to_string(),
1629 variant_name: "Err".to_string(),
1630 fields: Some(Rc::new(vec![Value::String(Rc::new(e.to_string()))])),
1631 }),
1632 }
1633 });
1634
1635 self.define_builtin("std·env·var", Some(1), |_, args| {
1637 fn unwrap_refs(v: &Value) -> Value {
1638 match v {
1639 Value::Ref(r) => unwrap_refs(&r.borrow()),
1640 other => other.clone(),
1641 }
1642 }
1643 let arg = unwrap_refs(&args[0]);
1644 let var_name = match &arg {
1645 Value::String(s) => s.to_string(),
1646 _ => return Err(RuntimeError::new("env::var expects a string")),
1647 };
1648 match std::env::var(&var_name) {
1649 Ok(value) => Ok(Value::Variant {
1650 enum_name: "Result".to_string(),
1651 variant_name: "Ok".to_string(),
1652 fields: Some(Rc::new(vec![Value::String(Rc::new(value))])),
1653 }),
1654 Err(_) => Ok(Value::Variant {
1655 enum_name: "Result".to_string(),
1656 variant_name: "Err".to_string(),
1657 fields: Some(Rc::new(vec![Value::String(Rc::new(
1658 "Environment variable not found".to_string(),
1659 ))])),
1660 }),
1661 }
1662 });
1663
1664 self.define_builtin("env·var", Some(1), |_, args| {
1666 fn unwrap_refs(v: &Value) -> Value {
1667 match v {
1668 Value::Ref(r) => unwrap_refs(&r.borrow()),
1669 other => other.clone(),
1670 }
1671 }
1672 let arg = unwrap_refs(&args[0]);
1673 let var_name = match &arg {
1674 Value::String(s) => s.to_string(),
1675 _ => return Err(RuntimeError::new("env::var expects a string")),
1676 };
1677 match std::env::var(&var_name) {
1678 Ok(value) => Ok(Value::Variant {
1679 enum_name: "Result".to_string(),
1680 variant_name: "Ok".to_string(),
1681 fields: Some(Rc::new(vec![Value::String(Rc::new(value))])),
1682 }),
1683 Err(_) => Ok(Value::Variant {
1684 enum_name: "Result".to_string(),
1685 variant_name: "Err".to_string(),
1686 fields: Some(Rc::new(vec![Value::String(Rc::new(
1687 "Environment variable not found".to_string(),
1688 ))])),
1689 }),
1690 }
1691 });
1692
1693 self.define_builtin("std·env·args", Some(0), |interp, _| {
1696 let args = interp.get_program_args();
1697 let arg_values: Vec<Value> = args
1698 .iter()
1699 .map(|s| Value::String(Rc::new(s.clone())))
1700 .collect();
1701 Ok(Value::Array(Rc::new(RefCell::new(arg_values))))
1702 });
1703
1704 self.define_builtin("env·args", Some(0), |interp, _| {
1706 let args = interp.get_program_args();
1707 let arg_values: Vec<Value> = args
1708 .iter()
1709 .map(|s| Value::String(Rc::new(s.clone())))
1710 .collect();
1711 Ok(Value::Array(Rc::new(RefCell::new(arg_values))))
1712 });
1713
1714 self.define_builtin("fs_read", Some(1), |_, args| {
1720 let path = match &args[0] {
1721 Value::String(s) => s.to_string(),
1722 _ => return Err(RuntimeError::new("fs_read requires a string path")),
1723 };
1724 match std::fs::read_to_string(&path) {
1725 Ok(content) => Ok(Value::String(Rc::new(content))),
1726 Err(e) => {
1727 crate::sigil_debug!("DEBUG fs_read error for '{}': {}", path, e);
1728 Ok(Value::Null)
1729 }
1730 }
1731 });
1732
1733 self.define_builtin("fs_list", Some(1), |_, args| {
1735 let path = match &args[0] {
1736 Value::String(s) => s.to_string(),
1737 _ => return Err(RuntimeError::new("fs_list requires a string path")),
1738 };
1739 match std::fs::read_dir(&path) {
1740 Ok(entries) => {
1741 let files: Vec<Value> = entries
1742 .filter_map(|e| e.ok())
1743 .map(|e| {
1744 Value::String(Rc::new(e.file_name().to_string_lossy().to_string()))
1745 })
1746 .collect();
1747 Ok(Value::Array(Rc::new(RefCell::new(files))))
1748 }
1749 Err(e) => {
1750 crate::sigil_debug!("DEBUG fs_list error for '{}': {}", path, e);
1751 Ok(Value::Array(Rc::new(RefCell::new(Vec::new()))))
1752 }
1753 }
1754 });
1755
1756 self.define_builtin("fs_is_dir", Some(1), |_, args| {
1758 let path = match &args[0] {
1759 Value::String(s) => s.to_string(),
1760 _ => return Err(RuntimeError::new("fs_is_dir requires a string path")),
1761 };
1762 Ok(Value::Bool(std::path::Path::new(&path).is_dir()))
1763 });
1764
1765 self.define_builtin("fs_is_file", Some(1), |_, args| {
1767 let path = match &args[0] {
1768 Value::String(s) => s.to_string(),
1769 _ => return Err(RuntimeError::new("fs_is_file requires a string path")),
1770 };
1771 Ok(Value::Bool(std::path::Path::new(&path).is_file()))
1772 });
1773
1774 self.define_builtin("fs_exists", Some(1), |_, args| {
1776 let path = match &args[0] {
1777 Value::String(s) => s.to_string(),
1778 _ => return Err(RuntimeError::new("fs_exists requires a string path")),
1779 };
1780 Ok(Value::Bool(std::path::Path::new(&path).exists()))
1781 });
1782
1783 self.define_builtin("path_extension", Some(1), |_, args| {
1785 let path = match &args[0] {
1786 Value::String(s) => s.to_string(),
1787 _ => return Err(RuntimeError::new("path_extension requires a string path")),
1788 };
1789 let ext = std::path::Path::new(&path)
1790 .extension()
1791 .and_then(|e| e.to_str())
1792 .map(|s| s.to_string());
1793 match ext {
1794 Some(e) => Ok(Value::String(Rc::new(e))),
1795 None => Ok(Value::Null),
1796 }
1797 });
1798
1799 self.define_builtin("path_join", Some(2), |_, args| {
1801 let base = match &args[0] {
1802 Value::String(s) => s.to_string(),
1803 _ => return Err(RuntimeError::new("path_join requires string paths")),
1804 };
1805 let part = match &args[1] {
1806 Value::String(s) => s.to_string(),
1807 _ => return Err(RuntimeError::new("path_join requires string paths")),
1808 };
1809 let joined = std::path::Path::new(&base).join(&part);
1810 Ok(Value::String(Rc::new(joined.to_string_lossy().to_string())))
1811 });
1812
1813 self.define_builtin("path_parent", Some(1), |_, args| {
1815 let path = match &args[0] {
1816 Value::String(s) => s.to_string(),
1817 _ => return Err(RuntimeError::new("path_parent requires a string path")),
1818 };
1819 match std::path::Path::new(&path).parent() {
1820 Some(p) => Ok(Value::String(Rc::new(p.to_string_lossy().to_string()))),
1821 None => Ok(Value::Null),
1822 }
1823 });
1824
1825 self.define_builtin("path_file_name", Some(1), |_, args| {
1827 let path = match &args[0] {
1828 Value::String(s) => s.to_string(),
1829 _ => return Err(RuntimeError::new("path_file_name requires a string path")),
1830 };
1831 match std::path::Path::new(&path).file_name() {
1832 Some(n) => Ok(Value::String(Rc::new(n.to_string_lossy().to_string()))),
1833 None => Ok(Value::Null),
1834 }
1835 });
1836
1837 self.define_builtin("TreeSitterParser·new", Some(1), |_, args| {
1843 use crate::tree_sitter_support::{TSLanguage, TSParser};
1844
1845 let lang_str = match &args[0] {
1847 Value::String(s) => s.to_string(),
1848 Value::Variant {
1849 enum_name,
1850 variant_name,
1851 ..
1852 } => {
1853 format!("{}::{}", enum_name, variant_name)
1855 }
1856 other => format!("{:?}", other),
1857 };
1858
1859 let language = match TSLanguage::from_str(&lang_str) {
1861 Some(lang) => lang,
1862 None => {
1863 return Ok(Value::Variant {
1864 enum_name: "Result".to_string(),
1865 variant_name: "Err".to_string(),
1866 fields: Some(Rc::new(vec![Value::Struct {
1867 name: "ParseError".to_string(),
1868 fields: Rc::new(RefCell::new({
1869 let mut f = HashMap::new();
1870 f.insert(
1871 "kind".to_string(),
1872 Value::String(Rc::new("ParserNotFound".to_string())),
1873 );
1874 f.insert(
1875 "message".to_string(),
1876 Value::String(Rc::new(format!(
1877 "Unsupported language: {}",
1878 lang_str
1879 ))),
1880 );
1881 f
1882 })),
1883 }])),
1884 });
1885 }
1886 };
1887
1888 match TSParser::new(language) {
1890 Ok(_) => {
1891 let mut fields = HashMap::new();
1893 fields.insert("language".to_string(), Value::String(Rc::new(lang_str)));
1894 fields.insert(
1895 "_ts_language".to_string(),
1896 Value::String(Rc::new(format!("{:?}", language))),
1897 );
1898
1899 Ok(Value::Variant {
1900 enum_name: "Result".to_string(),
1901 variant_name: "Ok".to_string(),
1902 fields: Some(Rc::new(vec![Value::Struct {
1903 name: "TreeSitterParser".to_string(),
1904 fields: Rc::new(RefCell::new(fields)),
1905 }])),
1906 })
1907 }
1908 Err(e) => Ok(Value::Variant {
1909 enum_name: "Result".to_string(),
1910 variant_name: "Err".to_string(),
1911 fields: Some(Rc::new(vec![Value::Struct {
1912 name: "ParseError".to_string(),
1913 fields: Rc::new(RefCell::new({
1914 let mut f = HashMap::new();
1915 f.insert(
1916 "kind".to_string(),
1917 Value::String(Rc::new("ParserNotFound".to_string())),
1918 );
1919 f.insert("message".to_string(), Value::String(Rc::new(e)));
1920 f
1921 })),
1922 }])),
1923 }),
1924 }
1925 });
1926
1927 self.define_builtin("tree_sitter_parse", Some(2), |_, args| {
1929 use crate::tree_sitter_support::{node_to_value, parse_source};
1930
1931 let lang_str = match &args[0] {
1933 Value::String(s) => s.to_string(),
1934 Value::Variant {
1935 enum_name,
1936 variant_name,
1937 ..
1938 } => {
1939 format!("{}::{}", enum_name, variant_name)
1940 }
1941 other => format!("{:?}", other),
1942 };
1943
1944 let source = match &args[1] {
1945 Value::String(s) => s.to_string(),
1946 _ => {
1947 return Err(RuntimeError::new(
1948 "tree_sitter_parse expects source code string as second argument",
1949 ))
1950 }
1951 };
1952
1953 match parse_source(&lang_str, &source) {
1955 Ok(tree) => {
1956 let root = tree.root_node();
1958 let root_fields = node_to_value(&root);
1959
1960 let mut tree_fields = HashMap::new();
1962 tree_fields.insert(
1963 "root".to_string(),
1964 Value::Struct {
1965 name: "SyntaxNode".to_string(),
1966 fields: Rc::new(RefCell::new(root_fields)),
1967 },
1968 );
1969 tree_fields.insert("source".to_string(), Value::String(Rc::new(source)));
1970
1971 Ok(Value::Variant {
1972 enum_name: "Result".to_string(),
1973 variant_name: "Ok".to_string(),
1974 fields: Some(Rc::new(vec![Value::Struct {
1975 name: "TSTree".to_string(),
1976 fields: Rc::new(RefCell::new(tree_fields)),
1977 }])),
1978 })
1979 }
1980 Err(e) => Ok(Value::Variant {
1981 enum_name: "Result".to_string(),
1982 variant_name: "Err".to_string(),
1983 fields: Some(Rc::new(vec![Value::Struct {
1984 name: "ParseError".to_string(),
1985 fields: Rc::new(RefCell::new({
1986 let mut f = HashMap::new();
1987 f.insert(
1988 "kind".to_string(),
1989 Value::String(Rc::new("SyntaxError".to_string())),
1990 );
1991 f.insert("message".to_string(), Value::String(Rc::new(e)));
1992 f
1993 })),
1994 }])),
1995 }),
1996 }
1997 });
1998
1999 self.define_builtin("tree_sitter_supported_languages", Some(0), |_, _| {
2001 use crate::tree_sitter_support::supported_languages;
2002
2003 let languages: Vec<Value> = supported_languages()
2004 .iter()
2005 .map(|s| Value::String(Rc::new(s.to_string())))
2006 .collect();
2007
2008 Ok(Value::Array(Rc::new(RefCell::new(languages))))
2009 });
2010
2011 self.define_builtin("tree_sitter_node_text", Some(2), |_, args| {
2013 let (start_byte, end_byte) = match &args[0] {
2015 Value::Struct { fields, .. } => {
2016 let fields = fields.borrow();
2017 let start = match fields.get("start_byte") {
2018 Some(Value::Int(n)) => *n as usize,
2019 _ => return Err(RuntimeError::new("Node missing start_byte field")),
2020 };
2021 let end = match fields.get("end_byte") {
2022 Some(Value::Int(n)) => *n as usize,
2023 _ => return Err(RuntimeError::new("Node missing end_byte field")),
2024 };
2025 (start, end)
2026 }
2027 _ => {
2028 return Err(RuntimeError::new(
2029 "tree_sitter_node_text expects a SyntaxNode struct",
2030 ))
2031 }
2032 };
2033
2034 let source = match &args[1] {
2035 Value::String(s) => s.to_string(),
2036 _ => {
2037 return Err(RuntimeError::new(
2038 "tree_sitter_node_text expects source string as second argument",
2039 ))
2040 }
2041 };
2042
2043 if end_byte <= source.len() && start_byte <= end_byte {
2044 Ok(Value::String(Rc::new(
2045 source[start_byte..end_byte].to_string(),
2046 )))
2047 } else {
2048 Err(RuntimeError::new("Byte range out of bounds"))
2049 }
2050 });
2051
2052 let rc_new = Value::BuiltIn(Rc::new(BuiltInFn {
2054 name: "Rc·new".to_string(),
2055 arity: Some(1),
2056 func: |_, args| {
2057 let mut fields = HashMap::new();
2058 fields.insert("_value".to_string(), args[0].clone());
2059 Ok(Value::Struct {
2060 name: "Rc".to_string(),
2061 fields: std::rc::Rc::new(RefCell::new(fields)),
2062 })
2063 },
2064 }));
2065 self.globals
2066 .borrow_mut()
2067 .define("Rc·new".to_string(), rc_new);
2068
2069 let cell_new = Value::BuiltIn(Rc::new(BuiltInFn {
2071 name: "Cell·new".to_string(),
2072 arity: Some(1),
2073 func: |_, args| {
2074 let mut fields = HashMap::new();
2075 fields.insert("_value".to_string(), args[0].clone());
2076 Ok(Value::Struct {
2077 name: "Cell".to_string(),
2078 fields: std::rc::Rc::new(RefCell::new(fields)),
2079 })
2080 },
2081 }));
2082 self.globals
2083 .borrow_mut()
2084 .define("Cell·new".to_string(), cell_new);
2085 }
2086
2087 fn define_builtin(
2088 &mut self,
2089 name: &str,
2090 arity: Option<usize>,
2091 func: fn(&mut Interpreter, Vec<Value>) -> Result<Value, RuntimeError>,
2092 ) {
2093 let builtin = Value::BuiltIn(Rc::new(BuiltInFn {
2094 name: name.to_string(),
2095 arity,
2096 func,
2097 }));
2098 self.globals.borrow_mut().define(name.to_string(), builtin);
2099 }
2100
2101 pub fn execute(&mut self, file: &SourceFile) -> Result<Value, RuntimeError> {
2103 let mut result = Value::Null;
2104
2105 for item in &file.items {
2106 result = self.execute_item(&item.node)?;
2107 }
2108
2109 let main_fn = self.globals.borrow().get("main").and_then(|v| {
2111 if let Value::Function(f) = v {
2112 Some(f.clone())
2113 } else {
2114 None
2115 }
2116 });
2117 if let Some(f) = main_fn {
2118 if f.params.is_empty() {
2121 result = self.call_function(&f, vec![])?;
2122 }
2123 }
2124
2125 Ok(result)
2126 }
2127
2128 pub fn execute_definitions(&mut self, file: &SourceFile) -> Result<Value, RuntimeError> {
2131 let mut result = Value::Null;
2132
2133 for item in &file.items {
2134 result = self.execute_item(&item.node)?;
2135 }
2136
2137 Ok(result)
2138 }
2139
2140 fn execute_item(&mut self, item: &Item) -> Result<Value, RuntimeError> {
2141 match item {
2142 Item::Function(func) => {
2143 let fn_value = self.create_function(func)?;
2144 let fn_name = func.name.name.clone();
2145
2146 self.globals
2148 .borrow_mut()
2149 .define(fn_name.clone(), fn_value.clone());
2150
2151 if let Some(ref module) = self.current_module {
2153 let qualified_name = format!("{}·{}", module, fn_name);
2154 self.globals.borrow_mut().define(qualified_name, fn_value);
2155 }
2156
2157 Ok(Value::Null)
2158 }
2159 Item::Struct(s) => {
2160 self.types
2162 .insert(s.name.name.clone(), TypeDef::Struct(s.clone()));
2163
2164 if let Some(ref module) = self.current_module {
2166 let qualified_name = format!("{}·{}", module, s.name.name);
2167 self.types
2168 .insert(qualified_name, TypeDef::Struct(s.clone()));
2169 }
2170
2171 if matches!(&s.fields, crate::ast::StructFields::Unit) {
2173 let unit_value = Value::Struct {
2174 name: s.name.name.clone(),
2175 fields: Rc::new(RefCell::new(HashMap::new())),
2176 };
2177 self.globals
2178 .borrow_mut()
2179 .define(s.name.name.clone(), unit_value.clone());
2180
2181 if let Some(ref module) = self.current_module {
2183 let qualified_name = format!("{}·{}", module, s.name.name);
2184 self.globals.borrow_mut().define(qualified_name, unit_value);
2185 }
2186 }
2187
2188 let has_default = s
2190 .attrs
2191 .derives
2192 .iter()
2193 .any(|d| matches!(d, DeriveTrait::Default));
2194 if has_default {
2195 self.default_structs.insert(s.name.name.clone(), s.clone());
2196 if let Some(ref module) = self.current_module {
2197 let qualified_name = format!("{}·{}", module, s.name.name);
2198 self.default_structs.insert(qualified_name, s.clone());
2199 }
2200 }
2201
2202 Ok(Value::Null)
2203 }
2204 Item::Enum(e) => {
2205 self.types
2207 .insert(e.name.name.clone(), TypeDef::Enum(e.clone()));
2208
2209 if let Some(ref module) = self.current_module {
2211 let qualified_name = format!("{}·{}", module, e.name.name);
2212 self.types.insert(qualified_name, TypeDef::Enum(e.clone()));
2213 }
2214
2215 let enum_name = e.name.name.clone();
2218 for variant in &e.variants {
2219 let variant_name = variant.name.name.clone();
2220 let qualified_name = format!("{}·{}", enum_name, variant_name);
2221
2222 let arity = match &variant.fields {
2223 crate::ast::StructFields::Unit => 0,
2224 crate::ast::StructFields::Tuple(types) => types.len(),
2225 crate::ast::StructFields::Named(fields) => fields.len(),
2226 };
2227
2228 self.variant_constructors.insert(
2230 qualified_name.clone(),
2231 (enum_name.clone(), variant_name.clone(), arity),
2232 );
2233 }
2234 Ok(Value::Null)
2235 }
2236 Item::Const(c) => {
2237 let value = self.evaluate(&c.value)?;
2238 self.globals.borrow_mut().define(c.name.name.clone(), value);
2239 Ok(Value::Null)
2240 }
2241 Item::Static(s) => {
2242 let value = self.evaluate(&s.value)?;
2243 self.globals.borrow_mut().define(s.name.name.clone(), value);
2244 Ok(Value::Null)
2245 }
2246 Item::ExternBlock(extern_block) => {
2247 for item in &extern_block.items {
2249 if let ExternItem::Function(func) = item {
2250 let name = func.name.name.clone();
2251 match name.as_str() {
2253 "sigil_read_file" => {
2254 self.define_builtin("sigil_read_file", Some(2), |_, args| {
2255 let path = match &args[0] {
2257 Value::String(s) => (**s).clone(),
2258 _ => {
2259 return Err(RuntimeError::new(
2260 "sigil_read_file expects string path",
2261 ))
2262 }
2263 };
2264 match std::fs::read_to_string(&path) {
2265 Ok(content) => {
2266 Ok(Value::String(Rc::new(content)))
2268 }
2269 Err(_) => Ok(Value::Null),
2270 }
2271 });
2272 }
2273 "sigil_file_len" => {
2274 self.define_builtin("sigil_file_len", Some(0), |_, _| {
2275 Ok(Value::Int(0))
2277 });
2278 }
2279 "sigil_write_file" => {
2280 self.define_builtin("sigil_write_file", Some(4), |_, args| {
2281 let path = match &args[0] {
2282 Value::String(s) => (**s).clone(),
2283 _ => {
2284 return Err(RuntimeError::new(
2285 "sigil_write_file expects string path",
2286 ))
2287 }
2288 };
2289 let content = match &args[2] {
2290 Value::String(s) => (**s).clone(),
2291 _ => {
2292 return Err(RuntimeError::new(
2293 "sigil_write_file expects string content",
2294 ))
2295 }
2296 };
2297 match std::fs::write(&path, &content) {
2298 Ok(_) => Ok(Value::Bool(true)),
2299 Err(_) => Ok(Value::Bool(false)),
2300 }
2301 });
2302 }
2303 "write" => {
2304 self.define_builtin("write", Some(3), |_, args| {
2305 let fd = match &args[0] {
2307 Value::Int(n) => *n,
2308 _ => 1,
2309 };
2310 let content = match &args[1] {
2311 Value::String(s) => (**s).clone(),
2312 _ => format!("{}", args[1]),
2313 };
2314 if fd == 1 {
2315 print!("{}", content);
2316 } else if fd == 2 {
2317 eprint!("{}", content);
2318 }
2319 Ok(Value::Int(content.len() as i64))
2320 });
2321 }
2322 _ => {
2323 }
2325 }
2326 }
2327 }
2328 Ok(Value::Null)
2329 }
2330 Item::Impl(impl_block) => {
2331 let type_name = match &impl_block.self_ty {
2333 TypeExpr::Path(path) => path
2334 .segments
2335 .iter()
2336 .map(|s| s.ident.name.as_str())
2337 .collect::<Vec<_>>()
2338 .join("·"),
2339 _ => return Ok(Value::Null), };
2341
2342 if let Some(trait_path) = &impl_block.trait_ {
2344 let trait_name = trait_path
2345 .segments
2346 .iter()
2347 .map(|s| s.ident.name.as_str())
2348 .collect::<Vec<_>>()
2349 .join("·");
2350 if trait_name == "Drop" {
2351 self.drop_types.insert(type_name.clone());
2352 }
2353 }
2354
2355 for impl_item in &impl_block.items {
2357 if let ImplItem::Function(func) = impl_item {
2358 let fn_value = self.create_function(func)?;
2359 let qualified_name = format!("{}·{}", type_name, func.name.name);
2360 if type_name == "Lexer" && func.name.name.contains("keyword") {
2362 crate::sigil_debug!("DEBUG registering: {}", qualified_name);
2363 }
2364 self.globals
2365 .borrow_mut()
2366 .define(qualified_name.clone(), fn_value.clone());
2367
2368 if let Some(ref module) = self.current_module {
2370 let fully_qualified = format!("{}·{}", module, qualified_name);
2371 self.globals.borrow_mut().define(fully_qualified, fn_value);
2372 }
2373 }
2374 }
2375 Ok(Value::Null)
2376 }
2377 Item::Module(module) => {
2378 let module_name = &module.name.name;
2380
2381 if let Some(items) = &module.items {
2382 for item in items {
2385 match &item.node {
2386 Item::Const(c) => {
2387 let value = self.evaluate(&c.value)?;
2388 let qualified_name = format!("{}·{}", module_name, c.name.name);
2389 self.globals.borrow_mut().define(qualified_name, value);
2390 }
2391 Item::Static(s) => {
2392 let value = self.evaluate(&s.value)?;
2393 let qualified_name = format!("{}·{}", module_name, s.name.name);
2394 self.globals.borrow_mut().define(qualified_name, value);
2395 }
2396 Item::Function(func) => {
2397 let fn_value = self.create_function(func)?;
2398 let qualified_name = format!("{}·{}", module_name, func.name.name);
2399 self.globals.borrow_mut().define(qualified_name, fn_value);
2400 }
2401 Item::Struct(s) => {
2402 let qualified_name = format!("{}·{}", module_name, s.name.name);
2403 self.types
2404 .insert(qualified_name, TypeDef::Struct(s.clone()));
2405 }
2406 Item::Enum(e) => {
2407 let qualified_name = format!("{}·{}", module_name, e.name.name);
2408 self.types.insert(qualified_name, TypeDef::Enum(e.clone()));
2409 }
2410 Item::Impl(impl_block) => {
2411 let type_name = match &impl_block.self_ty {
2414 TypeExpr::Path(path) => path
2415 .segments
2416 .iter()
2417 .map(|s| s.ident.name.as_str())
2418 .collect::<Vec<_>>()
2419 .join("·"),
2420 _ => continue, };
2422
2423 let qualified_type = if type_name.contains("·") {
2426 type_name.clone()
2427 } else {
2428 format!("{}·{}", module_name, type_name)
2429 };
2430
2431 if let Some(trait_path) = &impl_block.trait_ {
2433 let trait_name = trait_path
2434 .segments
2435 .iter()
2436 .map(|s| s.ident.name.as_str())
2437 .collect::<Vec<_>>()
2438 .join("·");
2439 if trait_name == "Drop" {
2440 self.drop_types.insert(qualified_type.clone());
2441 }
2442 }
2443
2444 for impl_item in &impl_block.items {
2446 if let ImplItem::Function(func) = impl_item {
2447 let fn_value = self.create_function(func)?;
2448 let qualified_name =
2450 format!("{}·{}", qualified_type, func.name.name);
2451 self.globals
2452 .borrow_mut()
2453 .define(qualified_name.clone(), fn_value.clone());
2454
2455 let local_name = format!("{}·{}", type_name, func.name.name);
2458 if local_name != qualified_name {
2459 self.globals
2460 .borrow_mut()
2461 .define(local_name, fn_value.clone());
2462 }
2463 }
2464 }
2465 }
2466 Item::Module(nested_mod) => {
2467 let nested_name = format!("{}·{}", module_name, nested_mod.name.name);
2469 if let Some(nested_items) = &nested_mod.items {
2470 let prev_module = self.current_module.clone();
2473 self.current_module = Some(nested_name.clone());
2474 for nested_item in nested_items {
2475 if let Err(e) = self.execute_item(&nested_item.node) {
2476 crate::sigil_warn!(
2477 "Warning: error in nested module {}: {}",
2478 nested_name,
2479 e
2480 );
2481 }
2482 }
2483 self.current_module = prev_module;
2484 }
2485 }
2486 _ => {} }
2488 }
2489 } else {
2490 if let Some(ref source_dir) = self.current_source_dir {
2492 let module_path =
2493 std::path::Path::new(source_dir).join(format!("{}.sigil", module_name));
2494
2495 if module_path.exists() {
2496 crate::sigil_debug!(
2497 "DEBUG Loading external module: {}",
2498 module_path.display()
2499 );
2500
2501 match std::fs::read_to_string(&module_path) {
2502 Ok(source) => {
2503 let mut parser = crate::Parser::new(&source);
2505 match parser.parse_file() {
2506 Ok(parsed_file) => {
2507 let prev_module = self.current_module.clone();
2509
2510 self.current_module = Some(module_name.clone());
2512
2513 for item in &parsed_file.items {
2515 if let Err(e) = self.execute_item(&item.node) {
2516 crate::sigil_warn!(
2517 "Warning: error in module {}: {}",
2518 module_name,
2519 e
2520 );
2521 }
2522 }
2523
2524 self.current_module = prev_module;
2526 }
2527 Err(e) => {
2528 crate::sigil_warn!(
2529 "Warning: failed to parse module {}: {:?}",
2530 module_name,
2531 e
2532 );
2533 }
2534 }
2535 }
2536 Err(e) => {
2537 crate::sigil_warn!(
2538 "Warning: failed to read module file {}: {}",
2539 module_path.display(),
2540 e
2541 );
2542 }
2543 }
2544 } else {
2545 crate::sigil_debug!(
2546 "DEBUG Module file not found: {} (source_dir={})",
2547 module_path.display(),
2548 source_dir
2549 );
2550 }
2551 } else {
2552 crate::sigil_debug!(
2553 "DEBUG No source_dir set, cannot load external module: {}",
2554 module_name
2555 );
2556 }
2557 }
2558 Ok(Value::Null)
2559 }
2560 Item::Use(use_decl) => {
2561 self.process_use_tree(&use_decl.tree, &[])?;
2563 Ok(Value::Null)
2564 }
2565 _ => Ok(Value::Null), }
2567 }
2568
2569 fn process_use_tree(
2571 &mut self,
2572 tree: &crate::ast::UseTree,
2573 prefix: &[String],
2574 ) -> Result<(), RuntimeError> {
2575 use crate::ast::UseTree;
2576 match tree {
2577 UseTree::Path {
2578 prefix: path_prefix,
2579 suffix,
2580 } => {
2581 let mut new_prefix = prefix.to_vec();
2583 new_prefix.push(path_prefix.name.clone());
2584 self.process_use_tree(suffix, &new_prefix)
2585 }
2586 UseTree::Name(name) => {
2587 let mut path = prefix.to_vec();
2589 path.push(name.name.clone());
2590 let qualified = path.join("·");
2591 let simple_name = name.name.clone();
2592
2593 if !prefix.is_empty() {
2596 let crate_name = &prefix[0];
2597 if !self.types.contains_key(&qualified)
2598 && self.globals.borrow().get(&qualified).is_none()
2599 && !self.loaded_crates.contains(crate_name)
2600 {
2601 if let Err(e) = self.load_crate(crate_name) {
2603 crate::sigil_debug!(
2604 "DEBUG process_use_tree: failed to load crate '{}': {}",
2605 crate_name,
2606 e
2607 );
2608 }
2609 }
2610 }
2611
2612 if let Some(type_def) = self.types.get(&qualified).cloned() {
2615 self.types.insert(simple_name.clone(), type_def);
2616 }
2617 let func = self.globals.borrow().get(&qualified).map(|v| v.clone());
2619 if let Some(val) = func {
2620 self.globals.borrow_mut().define(simple_name.clone(), val);
2621 }
2622
2623 let method_prefix = format!("{}·", qualified);
2627 let matching_methods: Vec<(String, Value)> = {
2628 let globals = self.globals.borrow();
2629 globals
2630 .values
2631 .iter()
2632 .filter(|(k, _)| k.starts_with(&method_prefix))
2633 .map(|(k, v)| {
2634 let method_suffix = k.strip_prefix(&method_prefix).unwrap();
2636 let new_name = format!("{}·{}", simple_name, method_suffix);
2637 (new_name, v.clone())
2638 })
2639 .collect()
2640 };
2641 for (name, val) in matching_methods {
2642 self.globals.borrow_mut().define(name, val);
2643 }
2644 Ok(())
2645 }
2646 UseTree::Rename { name, alias } => {
2647 let mut path = prefix.to_vec();
2649 path.push(name.name.clone());
2650 let qualified = path.join("·");
2651 let alias_name = alias.name.clone();
2652
2653 if let Some(type_def) = self.types.get(&qualified).cloned() {
2654 self.types.insert(alias_name.clone(), type_def);
2655 }
2656 let func = self.globals.borrow().get(&qualified).map(|v| v.clone());
2657 if let Some(val) = func {
2658 self.globals.borrow_mut().define(alias_name, val);
2659 }
2660 Ok(())
2661 }
2662 UseTree::Glob => {
2663 let path_prefix = prefix.join("·");
2665 let matching_types: Vec<(String, TypeDef)> = self
2667 .types
2668 .iter()
2669 .filter(|(k, _)| k.starts_with(&path_prefix) && k.len() > path_prefix.len())
2670 .map(|(k, v)| {
2671 let suffix = k
2672 .strip_prefix(&path_prefix)
2673 .unwrap()
2674 .trim_start_matches('·');
2675 (suffix.to_string(), v.clone())
2676 })
2677 .filter(|(k, _)| !k.contains('·')) .collect();
2679 for (name, def) in matching_types {
2680 self.types.insert(name, def);
2681 }
2682 let matching_funcs: Vec<(String, Value)> = {
2684 let globals = self.globals.borrow();
2685 globals
2686 .values
2687 .iter()
2688 .filter(|(k, _)| k.starts_with(&path_prefix) && k.len() > path_prefix.len())
2689 .map(|(k, v)| {
2690 let suffix = k
2691 .strip_prefix(&path_prefix)
2692 .unwrap()
2693 .trim_start_matches('·');
2694 (suffix.to_string(), v.clone())
2695 })
2696 .filter(|(k, _)| !k.contains('·'))
2697 .collect()
2698 };
2699 for (name, val) in matching_funcs {
2700 self.globals.borrow_mut().define(name, val);
2701 }
2702 Ok(())
2703 }
2704 UseTree::Group(trees) => {
2705 for tree in trees {
2707 self.process_use_tree(tree, prefix)?;
2708 }
2709 Ok(())
2710 }
2711 }
2712 }
2713
2714 fn create_function(&self, func: &crate::ast::Function) -> Result<Value, RuntimeError> {
2715 let params: Vec<String> = func
2716 .params
2717 .iter()
2718 .map(|p| Self::extract_param_name(&p.pattern))
2719 .collect();
2720
2721 let body = func
2722 .body
2723 .as_ref()
2724 .map(|b| Expr::Block(b.clone()))
2725 .unwrap_or(Expr::Literal(Literal::Bool(false)));
2726
2727 Ok(Value::Function(Rc::new(Function {
2728 name: Some(func.name.name.clone()),
2729 params,
2730 body,
2731 closure: self.environment.clone(),
2732 })))
2733 }
2734
2735 fn extract_param_name(pattern: &Pattern) -> String {
2737 match pattern {
2738 Pattern::Ident { name, .. } => name.name.clone(),
2739 Pattern::Ref { pattern: inner, .. } => Self::extract_param_name(inner),
2741 Pattern::RefBinding { name, .. } => name.name.clone(),
2743 _ => "_".to_string(),
2744 }
2745 }
2746
2747 pub fn evaluate(&mut self, expr: &Expr) -> Result<Value, RuntimeError> {
2749 match expr {
2750 Expr::Literal(lit) => self.eval_literal(lit),
2751 Expr::Path(path) => self.eval_path(path),
2752 Expr::Binary { left, op, right } => self.eval_binary(left, op, right),
2753 Expr::Unary { op, expr } => self.eval_unary(op, expr),
2754 Expr::Call { func, args } => self.eval_call(func, args),
2755 Expr::Array(elements) => self.eval_array(elements),
2756 Expr::Tuple(elements) => self.eval_tuple(elements),
2757 Expr::Block(block) => self.eval_block(block),
2758 Expr::If {
2759 condition,
2760 then_branch,
2761 else_branch,
2762 } => self.eval_if(condition, then_branch, else_branch),
2763 Expr::Match { expr, arms } => self.eval_match(expr, arms),
2764 Expr::For {
2765 pattern,
2766 iter,
2767 body,
2768 ..
2769 } => self.eval_for(pattern, iter, body),
2770 Expr::While {
2771 condition, body, ..
2772 } => self.eval_while(condition, body),
2773 Expr::Loop { body, .. } => self.eval_loop(body),
2774 Expr::Return(value) => self.eval_return(value),
2775 Expr::Break { value, .. } => self.eval_break(value),
2776 Expr::Continue { .. } => Err(RuntimeError::new("continue")),
2777 Expr::Index { expr, index } => self.eval_index(expr, index),
2778 Expr::Field { expr, field } => self.eval_field(expr, field),
2779 Expr::MethodCall {
2780 receiver,
2781 method,
2782 args,
2783 ..
2784 } => self.eval_method_call(receiver, method, args),
2785 Expr::Incorporation { segments } => self.eval_incorporation(segments),
2788 Expr::Pipe { expr, operations } => self.eval_pipe(expr, operations),
2789 Expr::Closure { params, body, .. } => self.eval_closure(params, body),
2790 Expr::Struct { path, fields, rest } => self.eval_struct_literal(path, fields, rest),
2791 Expr::Evidential {
2792 expr,
2793 evidentiality,
2794 } => self.eval_evidential(expr, evidentiality),
2795 Expr::Range {
2796 start,
2797 end,
2798 inclusive,
2799 } => {
2800 crate::sigil_debug!("DEBUG evaluate: Expr::Range being evaluated standalone");
2801 self.eval_range(start, end, *inclusive)
2802 }
2803 Expr::Assign { target, value } => self.eval_assign(target, value),
2804 Expr::Let { pattern, value } => {
2805 let val = self.evaluate(value)?;
2808 if self.pattern_matches(pattern, &val)? {
2810 self.bind_pattern(pattern, val)?;
2812 Ok(Value::Bool(true))
2813 } else {
2814 Ok(Value::Bool(false))
2816 }
2817 }
2818 Expr::Await {
2819 expr: inner,
2820 evidentiality,
2821 } => {
2822 let value = self.evaluate(inner)?;
2823 let awaited = self.await_value(value)?;
2824 match evidentiality {
2826 Some(Evidentiality::Uncertain) => {
2827 self.unwrap_result_or_option(awaited, true, false)
2829 }
2830 Some(Evidentiality::Known) => {
2831 self.unwrap_result_or_option(awaited, true, true)
2833 }
2834 Some(Evidentiality::Reported)
2835 | Some(Evidentiality::Paradox)
2836 | Some(Evidentiality::Predicted) => {
2837 self.unwrap_result_or_option(awaited, false, false)
2839 }
2840 None => Ok(awaited),
2841 }
2842 }
2843 Expr::Macro { path, tokens } => {
2845 let macro_name = path
2846 .segments
2847 .last()
2848 .map(|s| s.ident.name.as_str())
2849 .unwrap_or("");
2850 crate::sigil_debug!(
2851 "DEBUG Expr::Macro: name='{}', tokens='{}'",
2852 macro_name,
2853 tokens
2854 );
2855
2856 match macro_name {
2857 "format" => self.eval_format_macro(tokens),
2858 "println" => {
2859 let formatted = self.eval_format_macro(tokens)?;
2860 if let Value::String(s) = formatted {
2861 println!("{}", s);
2862 }
2863 Ok(Value::Null)
2864 }
2865 "eprintln" => {
2866 let formatted = self.eval_format_macro(tokens)?;
2867 if let Value::String(s) = formatted {
2868 eprintln!("{}", s);
2869 }
2870 Ok(Value::Null)
2871 }
2872 "print" => {
2873 let formatted = self.eval_format_macro(tokens)?;
2874 if let Value::String(s) = formatted {
2875 print!("{}", s);
2876 }
2877 Ok(Value::Null)
2878 }
2879 "eprint" => {
2880 let formatted = self.eval_format_macro(tokens)?;
2881 if let Value::String(s) = formatted {
2882 eprint!("{}", s);
2883 }
2884 Ok(Value::Null)
2885 }
2886 "vec" => {
2887 self.eval_vec_macro(tokens)
2889 }
2890 "panic" => {
2891 let formatted = self.eval_format_macro(tokens)?;
2892 let msg = if let Value::String(s) = formatted {
2893 s.to_string()
2894 } else {
2895 "panic!".to_string()
2896 };
2897 Err(RuntimeError::new(format!("panic: {}", msg)))
2898 }
2899 "assert" => {
2900 let condition = self.eval_format_macro(tokens)?;
2902 if self.is_truthy(&condition) {
2903 Ok(Value::Null)
2904 } else {
2905 Err(RuntimeError::new("assertion failed"))
2906 }
2907 }
2908 _ => {
2909 Ok(Value::String(Rc::new(tokens.clone())))
2911 }
2912 }
2913 }
2914 Expr::Unsafe(block) => self.eval_block(block),
2916 Expr::Async { block, .. } => self.eval_block(block),
2918 Expr::Try(inner) => {
2920 let value = self.evaluate(inner)?;
2921 match &value {
2924 Value::Variant {
2925 enum_name,
2926 variant_name,
2927 fields,
2928 } => {
2929 match (enum_name.as_str(), variant_name.as_str()) {
2930 ("Result", "Ok") => {
2931 if let Some(f) = fields {
2932 Ok(f.first().cloned().unwrap_or(Value::Null))
2933 } else {
2934 Ok(Value::Null)
2935 }
2936 }
2937 ("Result", "Err") => {
2938 crate::sigil_debug!(
2939 "DEBUG Try propagating Result::Err with fields: {:?}",
2940 fields
2941 );
2942 let err_msg = if let Some(f) = fields {
2943 let first = f.first().cloned().unwrap_or(Value::Null);
2944 crate::sigil_debug!("DEBUG Try error first value: {}", first);
2945 match &first {
2947 Value::Struct { name, fields: sf } => {
2948 let field_str = sf
2949 .borrow()
2950 .iter()
2951 .map(|(k, v)| format!("{}: {}", k, v))
2952 .collect::<Vec<_>>()
2953 .join(", ");
2954 format!("{} {{ {} }}", name, field_str)
2955 }
2956 Value::Variant {
2957 enum_name: en,
2958 variant_name: vn,
2959 fields: vf,
2960 } => {
2961 let vf_str = vf
2962 .as_ref()
2963 .map(|vs| {
2964 vs.iter()
2965 .map(|v| format!("{}", v))
2966 .collect::<Vec<_>>()
2967 .join(", ")
2968 })
2969 .unwrap_or_default();
2970 format!("{}::{} {{ {} }}", en, vn, vf_str)
2971 }
2972 _ => format!("{}", first),
2973 }
2974 } else {
2975 "error".to_string()
2976 };
2977 Err(RuntimeError::new(format!("try failed: {}", err_msg)))
2978 }
2979 ("Option", "Some") => {
2980 if let Some(f) = fields {
2981 Ok(f.first().cloned().unwrap_or(Value::Null))
2982 } else {
2983 Ok(Value::Null)
2984 }
2985 }
2986 ("Option", "None") => Err(RuntimeError::new("try failed: None")),
2987 _ => Ok(value), }
2989 }
2990 _ => Ok(value), }
2992 }
2993 Expr::Cast { expr, ty } => {
2995 let value = self.evaluate(expr)?;
2996 let type_name = match ty {
2998 TypeExpr::Path(path) => {
2999 if !path.segments.is_empty() {
3000 path.segments
3001 .last()
3002 .map(|s| s.ident.name.as_str())
3003 .unwrap_or("")
3004 } else {
3005 ""
3006 }
3007 }
3008 _ => "",
3009 };
3010 match (value, type_name) {
3011 (Value::Char(c), "u8") => Ok(Value::Int(c as i64)),
3013 (Value::Char(c), "u16") => Ok(Value::Int(c as i64)),
3014 (Value::Char(c), "u32") => Ok(Value::Int(c as i64)),
3015 (Value::Char(c), "u64") => Ok(Value::Int(c as i64)),
3016 (Value::Char(c), "i8") => Ok(Value::Int(c as i64)),
3017 (Value::Char(c), "i16") => Ok(Value::Int(c as i64)),
3018 (Value::Char(c), "i32") => Ok(Value::Int(c as i64)),
3019 (Value::Char(c), "i64") => Ok(Value::Int(c as i64)),
3020 (Value::Char(c), "usize") => Ok(Value::Int(c as i64)),
3021 (Value::Char(c), "isize") => Ok(Value::Int(c as i64)),
3022 (Value::Int(i), "u8") => Ok(Value::Int(i)),
3024 (Value::Int(i), "u16") => Ok(Value::Int(i)),
3025 (Value::Int(i), "u32") => Ok(Value::Int(i)),
3026 (Value::Int(i), "u64") => Ok(Value::Int(i)),
3027 (Value::Int(i), "i8") => Ok(Value::Int(i)),
3028 (Value::Int(i), "i16") => Ok(Value::Int(i)),
3029 (Value::Int(i), "i32") => Ok(Value::Int(i)),
3030 (Value::Int(i), "i64") => Ok(Value::Int(i)),
3031 (Value::Int(i), "usize") => Ok(Value::Int(i)),
3032 (Value::Int(i), "isize") => Ok(Value::Int(i)),
3033 (Value::Float(f), "i32") => Ok(Value::Int(f as i64)),
3035 (Value::Float(f), "i64") => Ok(Value::Int(f as i64)),
3036 (Value::Float(f), "u32") => Ok(Value::Int(f as i64)),
3037 (Value::Float(f), "u64") => Ok(Value::Int(f as i64)),
3038 (Value::Int(i), "f32") => Ok(Value::Float(i as f64)),
3040 (Value::Int(i), "f64") => Ok(Value::Float(i as f64)),
3041 (Value::Int(i), "char") => {
3043 if let Some(c) = char::from_u32(i as u32) {
3044 Ok(Value::Char(c))
3045 } else {
3046 Err(RuntimeError::new(format!("invalid char code: {}", i)))
3047 }
3048 }
3049 (v, _) => Ok(v),
3051 }
3052 }
3053 _ => Err(RuntimeError::new(format!(
3054 "Unsupported expression: {:?}",
3055 expr
3056 ))),
3057 }
3058 }
3059
3060 fn eval_assign(&mut self, target: &Expr, value: &Expr) -> Result<Value, RuntimeError> {
3061 let val = self.evaluate(value)?;
3062
3063 match target {
3064 Expr::Path(path) if path.segments.len() == 1 => {
3065 let name = &path.segments[0].ident.name;
3066 if !self.mutable_vars.borrow().contains(name) {
3068 if self.environment.borrow().get(name).is_some() {
3070 return Err(RuntimeError::new(format!(
3071 "cannot assign to immutable variable '{}'",
3072 name
3073 )));
3074 }
3075 }
3076 self.environment.borrow_mut().set(name, val.clone())?;
3077 Ok(val)
3078 }
3079 Expr::Index { expr, index } => {
3080 let idx = self.evaluate(index)?;
3082 let idx = match idx {
3083 Value::Int(i) => i as usize,
3084 _ => return Err(RuntimeError::new("Index must be an integer")),
3085 };
3086
3087 if let Expr::Path(path) = expr.as_ref() {
3089 if path.segments.len() == 1 {
3090 let name = &path.segments[0].ident.name;
3091 let current = self.environment.borrow().get(name).ok_or_else(|| {
3092 RuntimeError::new(format!("Undefined variable: {}", name))
3093 })?;
3094
3095 if let Value::Array(arr) = current {
3096 let borrowed = arr.borrow();
3097 let mut new_arr = borrowed.clone();
3098 drop(borrowed);
3099 if idx < new_arr.len() {
3100 new_arr[idx] = val.clone();
3101 self.environment
3102 .borrow_mut()
3103 .set(name, Value::Array(Rc::new(RefCell::new(new_arr))))?;
3104 return Ok(val);
3105 }
3106 }
3107 }
3108 }
3109 Err(RuntimeError::new("Invalid index assignment target"))
3110 }
3111 Expr::Field { expr, field } => {
3112 match expr.as_ref() {
3115 Expr::Path(path) if path.segments.len() == 1 => {
3116 let var_name = &path.segments[0].ident.name;
3117 let current = self.environment.borrow().get(var_name).ok_or_else(|| {
3118 RuntimeError::new(format!("Undefined variable: {}", var_name))
3119 })?;
3120
3121 match current {
3122 Value::Struct { fields, .. } => {
3123 fields.borrow_mut().insert(field.name.clone(), val.clone());
3124 Ok(val)
3125 }
3126 Value::Ref(r) => {
3127 let mut borrowed = r.borrow_mut();
3128 if let Value::Struct { fields, .. } = &mut *borrowed {
3129 fields.borrow_mut().insert(field.name.clone(), val.clone());
3130 Ok(val)
3131 } else {
3132 Err(RuntimeError::new("Cannot assign field on non-struct ref"))
3133 }
3134 }
3135 _ => Err(RuntimeError::new("Cannot assign field on non-struct")),
3136 }
3137 }
3138 _ => {
3139 let struct_val = self.evaluate(expr)?;
3141 match struct_val {
3142 Value::Struct { fields, .. } => {
3143 fields.borrow_mut().insert(field.name.clone(), val.clone());
3144 Ok(val)
3145 }
3146 Value::Ref(r) => {
3147 let mut borrowed = r.borrow_mut();
3148 if let Value::Struct { fields, .. } = &mut *borrowed {
3149 fields.borrow_mut().insert(field.name.clone(), val.clone());
3150 Ok(val)
3151 } else {
3152 Err(RuntimeError::new("Cannot assign field on non-struct"))
3153 }
3154 }
3155 _ => Err(RuntimeError::new("Cannot assign field on non-struct")),
3156 }
3157 }
3158 }
3159 }
3160 Expr::Unary {
3161 op: UnaryOp::Deref,
3162 expr: inner,
3163 } => {
3164 let ptr_val = self.evaluate(inner)?;
3167 match ptr_val {
3168 Value::Ref(r) => {
3169 *r.borrow_mut() = val.clone();
3170 Ok(val)
3171 }
3172 _ => Err(RuntimeError::new(
3173 "Cannot dereference assign to non-reference",
3174 )),
3175 }
3176 }
3177 Expr::Deref(inner) => {
3178 let ptr_val = self.evaluate(inner)?;
3181 match ptr_val {
3182 Value::Ref(r) => {
3183 *r.borrow_mut() = val.clone();
3184 Ok(val)
3185 }
3186 _ => Err(RuntimeError::new(
3187 "Cannot dereference assign to non-reference",
3188 )),
3189 }
3190 }
3191 _ => Err(RuntimeError::new("Invalid assignment target")),
3192 }
3193 }
3194
3195 fn eval_literal(&mut self, lit: &Literal) -> Result<Value, RuntimeError> {
3196 match lit {
3197 Literal::Int { value, base, .. } => {
3198 let n = self.parse_int(value, base)?;
3199 Ok(Value::Int(n))
3200 }
3201 Literal::Float { value, .. } => {
3202 let n: f64 = value
3203 .parse()
3204 .map_err(|_| RuntimeError::new(format!("Invalid float: {}", value)))?;
3205 Ok(Value::Float(n))
3206 }
3207 Literal::String(s) => Ok(Value::String(Rc::new(s.clone()))),
3208 Literal::MultiLineString(s) => Ok(Value::String(Rc::new(s.clone()))),
3209 Literal::RawString(s) => Ok(Value::String(Rc::new(s.clone()))),
3210 Literal::ByteString(bytes) => {
3211 let arr: Vec<Value> = bytes.iter().map(|&b| Value::Int(b as i64)).collect();
3213 Ok(Value::Array(Rc::new(RefCell::new(arr))))
3214 }
3215 Literal::InterpolatedString { parts } => {
3216 let mut result = String::new();
3218 let mut combined_evidence: Option<Evidence> = None;
3219
3220 for part in parts {
3221 match part {
3222 InterpolationPart::Text(s) => result.push_str(s),
3223 InterpolationPart::Expr(expr) => {
3224 let value = self.evaluate(expr)?;
3225
3226 combined_evidence = Self::combine_evidence(
3228 combined_evidence,
3229 Self::extract_evidence(&value),
3230 );
3231
3232 if let Some(affect) = Self::extract_affect(&value) {
3234 combined_evidence = Self::combine_evidence(
3235 combined_evidence,
3236 Self::affect_to_evidence(affect),
3237 );
3238 }
3239
3240 let display_value = Self::unwrap_value(&value);
3242 result.push_str(&format!("{}", display_value));
3243 }
3244 }
3245 }
3246
3247 let string_value = Value::String(Rc::new(result));
3249 match combined_evidence {
3250 Some(evidence) => Ok(Value::Evidential {
3251 value: Box::new(string_value),
3252 evidence,
3253 }),
3254 None => Ok(string_value),
3255 }
3256 }
3257 Literal::SigilStringSql(s) => {
3258 Ok(Value::String(Rc::new(s.clone())))
3261 }
3262 Literal::SigilStringRoute(s) => {
3263 Ok(Value::String(Rc::new(s.clone())))
3266 }
3267 Literal::Char(c) => Ok(Value::Char(*c)),
3268 Literal::ByteChar(b) => Ok(Value::Int(*b as i64)),
3269 Literal::Bool(b) => Ok(Value::Bool(*b)),
3270 Literal::Null => Ok(Value::Null),
3271 Literal::Empty => Ok(Value::Empty),
3272 Literal::Infinity => Ok(Value::Infinity),
3273 Literal::Circle => Ok(Value::Int(0)), }
3275 }
3276
3277 fn parse_int(&self, value: &str, base: &NumBase) -> Result<i64, RuntimeError> {
3278 let (radix, prefix_len) = match base {
3279 NumBase::Binary => (2, 2), NumBase::Octal => (8, 2), NumBase::Decimal => (10, 0),
3282 NumBase::Hex => (16, 2), NumBase::Vigesimal => (20, 2), NumBase::Sexagesimal => (60, 2), NumBase::Duodecimal => (12, 2), NumBase::Explicit(b) => (*b as u32, 0),
3287 };
3288
3289 let clean = value[prefix_len..].replace('_', "");
3290 i64::from_str_radix(&clean, radix)
3291 .map_err(|_| RuntimeError::new(format!("Invalid integer: {}", value)))
3292 }
3293
3294 fn eval_path(&self, path: &TypePath) -> Result<Value, RuntimeError> {
3295 if path.segments.len() == 1 {
3296 let name = &path.segments[0].ident.name;
3297 if let Some(val) = self.environment.borrow().get(name) {
3301 if self.linear_state.vars.borrow().contains(name) {
3303 if self.linear_state.consumed.borrow().contains(name) {
3305 return Err(RuntimeError::linear_type_violation(name));
3306 }
3307 self.linear_state.consumed.borrow_mut().insert(name.clone());
3309 }
3310 return Ok(val);
3311 }
3312 if name == "_" {
3314 return Ok(Value::Null);
3315 }
3316 if name == "Self" {
3318 if let Some(ref self_type) = self.current_self_type {
3319 if let Some(TypeDef::Struct(struct_def)) = self.types.get(self_type) {
3321 if matches!(struct_def.fields, crate::ast::StructFields::Unit) {
3322 return Ok(Value::Struct {
3323 name: self_type.clone(),
3324 fields: Rc::new(RefCell::new(HashMap::new())),
3325 });
3326 }
3327 }
3328 return Ok(Value::Struct {
3330 name: self_type.clone(),
3331 fields: Rc::new(RefCell::new(HashMap::new())),
3332 });
3333 }
3334 }
3335 if name.len() <= 2 {
3336 crate::sigil_debug!("DEBUG Undefined variable '{}' (len={})", name, name.len());
3337 }
3338 Err(RuntimeError::undefined_variable(name))
3339 } else {
3340 let full_name = path
3343 .segments
3344 .iter()
3345 .map(|s| s.ident.name.as_str())
3346 .collect::<Vec<_>>()
3347 .join("·");
3348
3349 if let Some(val) = self.environment.borrow().get(&full_name) {
3350 return Ok(val);
3351 }
3352
3353 if let Some(val) = self.globals.borrow().get(&full_name) {
3355 return Ok(val);
3356 }
3357
3358 if let Some(ref current_mod) = self.current_module {
3361 let crate_name = current_mod.split('·').next().unwrap_or(current_mod);
3363 let crate_qualified = format!("{}·{}", crate_name, full_name);
3364 if full_name.contains("execute") {
3365 crate::sigil_debug!(
3366 "DEBUG eval_path: Looking for '{}' with crate_qualified='{}'",
3367 full_name,
3368 crate_qualified
3369 );
3370 }
3371 if let Some(val) = self.globals.borrow().get(&crate_qualified) {
3372 crate::sigil_debug!(
3373 "DEBUG eval_path: FOUND '{}' via crate_qualified",
3374 crate_qualified
3375 );
3376 return Ok(val);
3377 }
3378 } else if full_name.contains("execute") {
3379 crate::sigil_debug!(
3380 "DEBUG eval_path: current_module is None, can't resolve '{}'",
3381 full_name
3382 );
3383 }
3384
3385 if full_name.ends_with("·new") {
3387 crate::sigil_debug!(
3388 "DEBUG eval_path: Looking for '{}' - NOT FOUND in globals",
3389 full_name
3390 );
3391 }
3392
3393 if path.segments.len() >= 2 {
3397 let variant_name = &path.segments.last().unwrap().ident.name;
3398
3399 let type_segments: Vec<&str> = path.segments[..path.segments.len() - 1]
3401 .iter()
3402 .map(|s| s.ident.name.as_str())
3403 .collect();
3404
3405 let type_name_direct = type_segments.join("::");
3410 let type_name_qualified = type_segments.join("·");
3411
3412 let enum_def_and_name = self
3414 .types
3415 .get(&type_name_direct)
3416 .map(|td| (td, type_name_direct.clone()))
3417 .or_else(|| {
3418 self.types
3419 .get(&type_name_qualified)
3420 .map(|td| (td, type_name_qualified.clone()))
3421 });
3422
3423 if let Some((TypeDef::Enum(enum_def), actual_enum_name)) = enum_def_and_name {
3424 for variant in &enum_def.variants {
3425 if &variant.name.name == variant_name {
3426 if matches!(variant.fields, crate::ast::StructFields::Unit) {
3428 return Ok(Value::Variant {
3429 enum_name: actual_enum_name,
3430 variant_name: variant_name.clone(),
3431 fields: None,
3432 });
3433 }
3434 }
3435 }
3436 }
3437
3438 for (actual_type_name, type_def) in &self.types {
3440 if let TypeDef::Enum(enum_def) = type_def {
3441 let matches = actual_type_name == &type_name_direct
3444 || actual_type_name == &type_name_qualified
3445 || actual_type_name.ends_with(&format!("·{}", type_name_direct));
3446
3447 if matches {
3448 for variant in &enum_def.variants {
3449 if &variant.name.name == variant_name {
3450 if matches!(variant.fields, crate::ast::StructFields::Unit) {
3451 return Ok(Value::Variant {
3452 enum_name: actual_type_name.clone(),
3453 variant_name: variant_name.clone(),
3454 fields: None,
3455 });
3456 }
3457 }
3458 }
3459 }
3460 }
3461 }
3462 }
3463
3464 let last_name = &path.segments.last().unwrap().ident.name;
3466 if let Some(val) = self.environment.borrow().get(last_name) {
3467 if last_name == "new" {
3469 crate::sigil_debug!(
3470 "DEBUG eval_path: FALLBACK from '{}' to '{}' - found in env",
3471 full_name,
3472 last_name
3473 );
3474 }
3475 return Ok(val);
3476 }
3477
3478 if path.segments.len() == 2 && path.segments[0].ident.name == "Self" {
3480 if let Some(ref self_type) = self.current_self_type {
3481 let qualified = format!("{}·{}", self_type, last_name);
3483 if let Some(val) = self.globals.borrow().get(&qualified) {
3484 return Ok(val);
3485 }
3486 }
3487 }
3488
3489 if let Some((enum_name, variant_name, arity)) =
3491 self.variant_constructors.get(&full_name).cloned()
3492 {
3493 if arity == 0 {
3496 return Ok(Value::Variant {
3497 enum_name,
3498 variant_name,
3499 fields: None,
3500 });
3501 }
3502 }
3506
3507 if path.segments.len() == 2 {
3509 let type_name = &path.segments[0].ident.name;
3510 let method_name = &path.segments[1].ident.name;
3511
3512 let is_method = method_name
3514 .chars()
3515 .next()
3516 .map_or(false, |c| c.is_lowercase())
3517 || method_name == "new"
3518 || method_name == "default"
3519 || method_name == "from"
3520 || method_name == "try_from"
3521 || method_name == "into"
3522 || method_name == "with_capacity"
3523 || method_name == "from_str";
3524
3525 if is_method {
3526 return Ok(Value::Struct {
3529 name: format!("__constructor__{}", type_name),
3530 fields: Rc::new(RefCell::new(HashMap::new())),
3531 });
3532 } else {
3533 if let Some(TypeDef::Enum(enum_def)) = self.types.get(type_name) {
3535 let variant_exists = enum_def.variants.iter().any(|v| v.name.name == *method_name);
3537 if !variant_exists {
3538 return Err(RuntimeError::new(format!(
3539 "no variant '{}' on enum '{}'",
3540 method_name,
3541 type_name
3542 )));
3543 }
3544 }
3545 return Ok(Value::Variant {
3547 enum_name: type_name.clone(),
3548 variant_name: method_name.clone(),
3549 fields: None,
3550 });
3551 }
3552 }
3553
3554 Err(RuntimeError::new(format!(
3555 "Undefined: {} (tried {} and {})",
3556 full_name, full_name, last_name
3557 )))
3558 }
3559 }
3560
3561 fn eval_binary(
3562 &mut self,
3563 left: &Expr,
3564 op: &BinOp,
3565 right: &Expr,
3566 ) -> Result<Value, RuntimeError> {
3567 let lhs = self.evaluate(left)?;
3568
3569 match op {
3571 BinOp::And => {
3572 if !self.is_truthy(&lhs) {
3573 return Ok(Value::Bool(false));
3574 }
3575 let rhs = self.evaluate(right)?;
3576 return Ok(Value::Bool(self.is_truthy(&rhs)));
3577 }
3578 BinOp::Or => {
3579 if self.is_truthy(&lhs) {
3580 return Ok(Value::Bool(true));
3581 }
3582 let rhs = self.evaluate(right)?;
3583 return Ok(Value::Bool(self.is_truthy(&rhs)));
3584 }
3585 _ => {}
3586 }
3587
3588 let rhs = self.evaluate(right)?;
3589
3590 let lhs = Self::unwrap_all(&lhs);
3592 let rhs = Self::unwrap_all(&rhs);
3593
3594 if matches!(op, BinOp::Mul)
3596 && (matches!(lhs, Value::Null)
3597 || matches!(rhs, Value::Null)
3598 || matches!(lhs, Value::Struct { .. })
3599 || matches!(rhs, Value::Struct { .. }))
3600 {
3601 crate::sigil_debug!("DEBUG eval_binary Mul: left={:?}, right={:?}", left, right);
3602 crate::sigil_debug!(
3603 "DEBUG eval_binary Mul: lhs={}, rhs={}",
3604 self.format_value(&lhs),
3605 self.format_value(&rhs)
3606 );
3607 }
3608
3609 match (lhs, rhs) {
3610 (Value::Int(a), Value::Int(b)) => self.int_binary_op(a, b, op),
3611 (Value::Float(a), Value::Float(b)) => self.float_binary_op(a, b, op),
3612 (Value::Int(a), Value::Float(b)) => self.float_binary_op(a as f64, b, op),
3613 (Value::Float(a), Value::Int(b)) => self.float_binary_op(a, b as f64, op),
3614 (Value::String(a), Value::String(b)) => match op {
3615 BinOp::Add | BinOp::Concat => Ok(Value::String(Rc::new(format!("{}{}", a, b)))),
3616 BinOp::Eq => Ok(Value::Bool(*a == *b)),
3617 BinOp::Ne => Ok(Value::Bool(*a != *b)),
3618 _ => Err(RuntimeError::new("Invalid string operation")),
3619 },
3620 (Value::Bool(a), Value::Bool(b)) => match op {
3621 BinOp::Eq => Ok(Value::Bool(a == b)),
3622 BinOp::Ne => Ok(Value::Bool(a != b)),
3623 _ => Err(RuntimeError::new("Invalid boolean operation")),
3624 },
3625 (Value::Array(a), Value::Array(b)) => match op {
3626 BinOp::Concat => {
3627 let mut result = a.borrow().clone();
3628 result.extend(b.borrow().iter().cloned());
3629 Ok(Value::Array(Rc::new(RefCell::new(result))))
3630 }
3631 BinOp::Convolve => {
3632 let mut result = a.borrow().clone();
3634 result.extend(b.borrow().iter().cloned());
3635 Ok(Value::Array(Rc::new(RefCell::new(result))))
3636 }
3637 BinOp::Eq => Ok(Value::Bool(Rc::ptr_eq(&a, &b))),
3638 BinOp::Ne => Ok(Value::Bool(!Rc::ptr_eq(&a, &b))),
3639 _ => Err(RuntimeError::new("Invalid array operation")),
3640 },
3641 (Value::Null, Value::Null) => match op {
3643 BinOp::Eq => Ok(Value::Bool(true)),
3644 BinOp::Ne => Ok(Value::Bool(false)),
3645 _ => {
3646 crate::sigil_debug!("DEBUG: null op {:?} on (Null, Null)", op);
3647 Err(RuntimeError::new(format!(
3648 "Invalid null operation: {:?} on (Null, Null)",
3649 op
3650 )))
3651 }
3652 },
3653 (Value::Null, other) | (other, Value::Null) => match op {
3654 BinOp::Eq => Ok(Value::Bool(false)),
3655 BinOp::Ne => Ok(Value::Bool(true)),
3656 _ => {
3657 crate::sigil_debug!(
3658 "DEBUG: null op {:?} with other={}",
3659 op,
3660 self.format_value(&other)
3661 );
3662 Err(RuntimeError::new(format!(
3663 "Invalid null operation: {:?}",
3664 op
3665 )))
3666 }
3667 },
3668 (Value::Char(a), Value::Char(b)) => match op {
3670 BinOp::Eq => Ok(Value::Bool(a == b)),
3671 BinOp::Ne => Ok(Value::Bool(a != b)),
3672 BinOp::Lt => Ok(Value::Bool(a < b)),
3673 BinOp::Le => Ok(Value::Bool(a <= b)),
3674 BinOp::Gt => Ok(Value::Bool(a > b)),
3675 BinOp::Ge => Ok(Value::Bool(a >= b)),
3676 _ => Err(RuntimeError::new("Invalid char operation")),
3677 },
3678 (Value::String(a), Value::Char(b)) => match op {
3680 BinOp::Add | BinOp::Concat => Ok(Value::String(Rc::new(format!("{}{}", a, b)))),
3681 _ => Err(RuntimeError::new("Invalid string/char operation")),
3682 },
3683 (Value::Char(a), Value::String(b)) => match op {
3684 BinOp::Add | BinOp::Concat => Ok(Value::String(Rc::new(format!("{}{}", a, b)))),
3685 _ => Err(RuntimeError::new("Invalid char/string operation")),
3686 },
3687 (
3689 Value::Variant {
3690 enum_name: e1,
3691 variant_name: v1,
3692 fields: f1,
3693 },
3694 Value::Variant {
3695 enum_name: e2,
3696 variant_name: v2,
3697 fields: f2,
3698 },
3699 ) => match op {
3700 BinOp::Eq => {
3701 let eq = e1 == e2
3702 && v1 == v2
3703 && match (f1, f2) {
3704 (None, None) => true,
3705 (Some(a), Some(b)) => Rc::ptr_eq(&a, &b),
3706 _ => false,
3707 };
3708 Ok(Value::Bool(eq))
3709 }
3710 BinOp::Ne => {
3711 let eq = e1 == e2
3712 && v1 == v2
3713 && match (f1, f2) {
3714 (None, None) => true,
3715 (Some(a), Some(b)) => Rc::ptr_eq(&a, &b),
3716 _ => false,
3717 };
3718 Ok(Value::Bool(!eq))
3719 }
3720 _ => Err(RuntimeError::new("Invalid variant operation")),
3721 },
3722 (
3724 Value::Struct {
3725 name: n1,
3726 fields: f1,
3727 },
3728 Value::Struct {
3729 name: n2,
3730 fields: f2,
3731 },
3732 ) => match op {
3733 BinOp::Eq => Ok(Value::Bool(n1 == n2 && Rc::ptr_eq(&f1, &f2))),
3734 BinOp::Ne => Ok(Value::Bool(n1 != n2 || !Rc::ptr_eq(&f1, &f2))),
3735 BinOp::Mul if n1 == "Tensor" && n2 == "Tensor" => {
3737 let val1 = tensor_scalar_from_fields(&f1.borrow())
3739 .ok_or_else(|| RuntimeError::new("left tensor has no scalar data"))?;
3740 let val2 = tensor_scalar_from_fields(&f2.borrow())
3741 .ok_or_else(|| RuntimeError::new("right tensor has no scalar data"))?;
3742 let result = val1 * val2;
3744 let mut fields = std::collections::HashMap::new();
3745 fields.insert("shape".to_string(), Value::Array(Rc::new(RefCell::new(vec![]))));
3746 fields.insert("data".to_string(), Value::Array(Rc::new(RefCell::new(vec![Value::Float(result)]))));
3747 fields.insert("requires_grad".to_string(), Value::Bool(false));
3748 fields.insert("_value".to_string(), Value::Float(result));
3749 fields.insert("_op".to_string(), Value::String(Rc::new("mul".to_string())));
3751 fields.insert("_operand1".to_string(), Value::Float(val1));
3752 fields.insert("_operand2".to_string(), Value::Float(val2));
3753 Ok(Value::Struct {
3754 name: "Tensor".to_string(),
3755 fields: Rc::new(RefCell::new(fields)),
3756 })
3757 }
3758 BinOp::MatMul if n1 == "Tensor" && n2 == "Tensor" => {
3760 let f1_ref = f1.borrow();
3762 let f2_ref = f2.borrow();
3763 let shape1 = tensor_shape_from_fields(&f1_ref)
3764 .ok_or_else(|| RuntimeError::new("left tensor has no shape"))?;
3765 let shape2 = tensor_shape_from_fields(&f2_ref)
3766 .ok_or_else(|| RuntimeError::new("right tensor has no shape"))?;
3767 let data1 = tensor_data_from_fields(&f1_ref)
3768 .ok_or_else(|| RuntimeError::new("left tensor has no data"))?;
3769 let data2 = tensor_data_from_fields(&f2_ref)
3770 .ok_or_else(|| RuntimeError::new("right tensor has no data"))?;
3771 drop(f1_ref);
3772 drop(f2_ref);
3773
3774 let m = if shape1.len() >= 2 { shape1[0] } else { 1 };
3776 let n1_dim = if shape1.len() >= 2 { shape1[1] } else if !shape1.is_empty() { shape1[0] } else { 1 };
3777 let p = if shape2.len() >= 2 { shape2[1] } else { 1 };
3778
3779 let mut result_data = vec![0.0; m * p];
3781 for i in 0..m {
3782 for j in 0..p {
3783 let mut sum = 0.0;
3784 for k in 0..n1_dim {
3785 let a_idx = i * n1_dim + k;
3786 let b_idx = k * p + j;
3787 if a_idx < data1.len() && b_idx < data2.len() {
3788 sum += data1[a_idx] * data2[b_idx];
3789 }
3790 }
3791 result_data[i * p + j] = sum;
3792 }
3793 }
3794
3795 let left_requires_grad = matches!(f1.borrow().get("requires_grad"), Some(Value::Bool(true)));
3797 let right_requires_grad = matches!(f2.borrow().get("requires_grad"), Some(Value::Bool(true)));
3798
3799 let mut fields = std::collections::HashMap::new();
3801 fields.insert("shape".to_string(), Value::Array(Rc::new(RefCell::new(vec![
3802 Value::Int(m as i64),
3803 Value::Int(p as i64),
3804 ]))));
3805 fields.insert("data".to_string(), Value::Array(Rc::new(RefCell::new(
3806 result_data.into_iter().map(Value::Float).collect()
3807 ))));
3808 fields.insert("requires_grad".to_string(), Value::Bool(left_requires_grad || right_requires_grad));
3809
3810 if left_requires_grad {
3812 fields.insert("_grad_left".to_string(), Value::Struct {
3814 name: "Tensor".to_string(),
3815 fields: f1.clone(),
3816 });
3817 }
3818 if right_requires_grad {
3819 fields.insert("_grad_right".to_string(), Value::Struct {
3820 name: "Tensor".to_string(),
3821 fields: f2.clone(),
3822 });
3823 }
3824 fields.insert("_op".to_string(), Value::String(Rc::new("matmul".to_string())));
3825
3826 Ok(Value::Struct {
3827 name: "Tensor".to_string(),
3828 fields: Rc::new(RefCell::new(fields)),
3829 })
3830 }
3831 BinOp::Hadamard if n1 == "Tensor" && n2 == "Tensor" => {
3833 let f1_ref = f1.borrow();
3835 let f2_ref = f2.borrow();
3836 let shape1 = match f1_ref.get("shape") {
3838 Some(Value::Array(arr)) => arr.borrow().clone(),
3839 _ => return Err(RuntimeError::new("left tensor has no shape")),
3840 };
3841 let data1 = tensor_data_from_fields(&f1_ref)
3842 .ok_or_else(|| RuntimeError::new("left tensor has no data"))?;
3843 let data2 = tensor_data_from_fields(&f2_ref)
3844 .ok_or_else(|| RuntimeError::new("right tensor has no data"))?;
3845 drop(f1_ref);
3846 drop(f2_ref);
3847
3848 let result_data: Vec<Value> = data1.iter().zip(data2.iter())
3850 .map(|(a, b)| Value::Float(a * b))
3851 .collect();
3852
3853 let mut fields = std::collections::HashMap::new();
3854 fields.insert("shape".to_string(), Value::Array(Rc::new(RefCell::new(shape1))));
3855 fields.insert("data".to_string(), Value::Array(Rc::new(RefCell::new(result_data))));
3856 fields.insert("requires_grad".to_string(), Value::Bool(false));
3857 Ok(Value::Struct {
3858 name: "Tensor".to_string(),
3859 fields: Rc::new(RefCell::new(fields)),
3860 })
3861 }
3862 BinOp::Add if n1 == "Tensor" && n2 == "Tensor" => {
3864 let f1_ref = f1.borrow();
3866 let f2_ref = f2.borrow();
3867 let shape1: Vec<i64> = tensor_shape_from_fields(&f1_ref)
3869 .ok_or_else(|| RuntimeError::new("left tensor has no shape"))?
3870 .iter().map(|&x| x as i64).collect();
3871 let shape2: Vec<i64> = tensor_shape_from_fields(&f2_ref)
3872 .ok_or_else(|| RuntimeError::new("right tensor has no shape"))?
3873 .iter().map(|&x| x as i64).collect();
3874 let data1 = tensor_data_from_fields(&f1_ref)
3875 .ok_or_else(|| RuntimeError::new("left tensor has no data"))?;
3876 let data2 = tensor_data_from_fields(&f2_ref)
3877 .ok_or_else(|| RuntimeError::new("right tensor has no data"))?;
3878 drop(f1_ref);
3879 drop(f2_ref);
3880
3881 let result_data: Vec<f64>;
3883 let result_shape: Vec<Value>;
3884
3885 let size1: i64 = shape1.iter().product();
3887 let size2: i64 = shape2.iter().product();
3888
3889 if size1 == size2 {
3890 result_data = data1.iter().zip(data2.iter())
3892 .map(|(a, b)| a + b)
3893 .collect();
3894 result_shape = shape1.into_iter().map(Value::Int).collect();
3895 } else if size1 > size2 && size1 % size2 == 0 {
3896 result_data = data1.iter().enumerate()
3898 .map(|(i, a)| a + data2[i % data2.len()])
3899 .collect();
3900 result_shape = shape1.into_iter().map(Value::Int).collect();
3901 } else if size2 > size1 && size2 % size1 == 0 {
3902 result_data = data2.iter().enumerate()
3904 .map(|(i, b)| data1[i % data1.len()] + b)
3905 .collect();
3906 result_shape = shape2.into_iter().map(Value::Int).collect();
3907 } else {
3908 result_data = data1.iter().zip(data2.iter())
3910 .map(|(a, b)| a + b)
3911 .collect();
3912 result_shape = shape1.into_iter().map(Value::Int).collect();
3913 }
3914
3915 let mut fields = std::collections::HashMap::new();
3916 fields.insert("shape".to_string(), Value::Array(Rc::new(RefCell::new(result_shape))));
3917 fields.insert("data".to_string(), Value::Array(Rc::new(RefCell::new(
3918 result_data.into_iter().map(Value::Float).collect()
3919 ))));
3920 fields.insert("requires_grad".to_string(), Value::Bool(false));
3921 Ok(Value::Struct {
3922 name: "Tensor".to_string(),
3923 fields: Rc::new(RefCell::new(fields)),
3924 })
3925 }
3926 BinOp::TensorProd if n1 == "Qubit" && n2 == "Qubit" => {
3928 let alpha1 = match f1.borrow().get("_alpha_real") {
3932 Some(Value::Float(f)) => *f,
3933 _ => 1.0,
3934 };
3935 let beta1 = match f1.borrow().get("_beta_real") {
3936 Some(Value::Float(f)) => *f,
3937 _ => 0.0,
3938 };
3939 let alpha2 = match f2.borrow().get("_alpha_real") {
3940 Some(Value::Float(f)) => *f,
3941 _ => 1.0,
3942 };
3943 let beta2 = match f2.borrow().get("_beta_real") {
3944 Some(Value::Float(f)) => *f,
3945 _ => 0.0,
3946 };
3947
3948 let amp00 = alpha1 * alpha2;
3950 let amp01 = alpha1 * beta2;
3951 let amp10 = beta1 * alpha2;
3952 let amp11 = beta1 * beta2;
3953
3954 let mut reg_fields = HashMap::new();
3955 reg_fields.insert("_size".to_string(), Value::Int(2));
3956 reg_fields.insert("_state".to_string(), Value::Array(Rc::new(RefCell::new(vec![
3957 Value::Float(amp00),
3958 Value::Float(amp01),
3959 Value::Float(amp10),
3960 Value::Float(amp11),
3961 ]))));
3962
3963 Ok(Value::Struct {
3964 name: "QRegister".to_string(),
3965 fields: Rc::new(RefCell::new(reg_fields)),
3966 })
3967 }
3968 _ => Err(RuntimeError::new("Invalid struct operation")),
3969 },
3970 (l, r) => Err(RuntimeError::new(format!(
3971 "Type mismatch in binary operation: {:?} {:?} {:?}",
3972 l, op, r
3973 ))),
3974 }
3975 }
3976
3977 fn int_binary_op(&self, a: i64, b: i64, op: &BinOp) -> Result<Value, RuntimeError> {
3978 Ok(match op {
3979 BinOp::Add => Value::Int(a + b),
3980 BinOp::Sub => Value::Int(a - b),
3981 BinOp::Mul => Value::Int(a * b),
3982 BinOp::Div => {
3983 if b == 0 {
3984 return Err(RuntimeError::division_by_zero());
3985 }
3986 Value::Int(a / b)
3987 }
3988 BinOp::Rem => {
3989 if b == 0 {
3990 return Err(RuntimeError::division_by_zero());
3991 }
3992 Value::Int(a % b)
3993 }
3994 BinOp::Pow => Value::Int(a.pow(b as u32)),
3995 BinOp::Eq => Value::Bool(a == b),
3996 BinOp::Ne => Value::Bool(a != b),
3997 BinOp::Lt => Value::Bool(a < b),
3998 BinOp::Le => Value::Bool(a <= b),
3999 BinOp::Gt => Value::Bool(a > b),
4000 BinOp::Ge => Value::Bool(a >= b),
4001 BinOp::BitAnd => Value::Int(a & b),
4002 BinOp::BitOr => Value::Int(a | b),
4003 BinOp::BitXor => Value::Int(a ^ b),
4004 BinOp::Shl => Value::Int(a << b),
4005 BinOp::Shr => Value::Int(a >> b),
4006 _ => return Err(RuntimeError::new("Invalid integer operation")),
4007 })
4008 }
4009
4010 fn float_binary_op(&self, a: f64, b: f64, op: &BinOp) -> Result<Value, RuntimeError> {
4011 Ok(match op {
4012 BinOp::Add => Value::Float(a + b),
4013 BinOp::Sub => Value::Float(a - b),
4014 BinOp::Mul => Value::Float(a * b),
4015 BinOp::Div => Value::Float(a / b),
4016 BinOp::Rem => Value::Float(a % b),
4017 BinOp::Pow => Value::Float(a.powf(b)),
4018 BinOp::Eq => Value::Bool((a - b).abs() < f64::EPSILON),
4019 BinOp::Ne => Value::Bool((a - b).abs() >= f64::EPSILON),
4020 BinOp::Lt => Value::Bool(a < b),
4021 BinOp::Le => Value::Bool(a <= b),
4022 BinOp::Gt => Value::Bool(a > b),
4023 BinOp::Ge => Value::Bool(a >= b),
4024 _ => return Err(RuntimeError::new("Invalid float operation")),
4025 })
4026 }
4027
4028 fn eval_unary(&mut self, op: &UnaryOp, expr: &Expr) -> Result<Value, RuntimeError> {
4029 let val = self.evaluate(expr)?;
4030 match (op, &val) {
4031 (UnaryOp::Neg, Value::Int(n)) => Ok(Value::Int(-n)),
4032 (UnaryOp::Neg, Value::Float(n)) => Ok(Value::Float(-n)),
4033 (UnaryOp::Not, Value::Bool(b)) => Ok(Value::Bool(!b)),
4034 (UnaryOp::Not, Value::Int(n)) => Ok(Value::Int(!n)),
4035 (UnaryOp::Not, Value::Evidential { value, evidence }) => {
4037 match value.as_ref() {
4039 Value::Bool(b) => Ok(Value::Evidential {
4040 value: Box::new(Value::Bool(!b)),
4041 evidence: evidence.clone(),
4042 }),
4043 other => {
4044 let truthy = self.is_truthy(other);
4045 Ok(Value::Evidential {
4046 value: Box::new(Value::Bool(!truthy)),
4047 evidence: evidence.clone(),
4048 })
4049 }
4050 }
4051 }
4052 (UnaryOp::Not, Value::String(s)) => Ok(Value::Bool(s.is_empty())),
4054 (UnaryOp::Not, Value::Array(arr)) => Ok(Value::Bool(arr.borrow().is_empty())),
4056 (UnaryOp::Not, Value::Null) => Ok(Value::Bool(true)),
4058 (UnaryOp::Ref, _) => Ok(Value::Ref(Rc::new(RefCell::new(val)))),
4059 (UnaryOp::RefMut, _) => Ok(Value::Ref(Rc::new(RefCell::new(val)))),
4060 (UnaryOp::Deref, Value::Ref(r)) => Ok(r.borrow().clone()),
4061 (UnaryOp::Deref, Value::Struct { name, fields }) if name == "Rc" => {
4062 let borrowed = fields.borrow();
4064 if let Some(value) = borrowed.get("_value") {
4065 Ok(value.clone())
4066 } else {
4067 Err(RuntimeError::new("Rc has no value"))
4068 }
4069 }
4070 (UnaryOp::Deref, other) => {
4071 let unwrapped = Self::unwrap_all(&val);
4073 if let Value::Ref(r) = &unwrapped {
4074 return Ok(r.borrow().clone());
4075 }
4076 Ok(unwrapped)
4079 }
4080 _ => Err(RuntimeError::new(format!(
4081 "Invalid unary {:?} on {:?}",
4082 op,
4083 std::mem::discriminant(&val)
4084 ))),
4085 }
4086 }
4087
4088 fn eval_call(&mut self, func_expr: &Expr, args: &[Expr]) -> Result<Value, RuntimeError> {
4089 if let Expr::Path(path) = func_expr {
4091 let qualified_name = path
4092 .segments
4093 .iter()
4094 .map(|s| s.ident.name.as_str())
4095 .collect::<Vec<_>>()
4096 .join("·");
4097
4098 if qualified_name == "Self" {
4100 if let Some(ref self_type) = self.current_self_type {
4101 let tuple_arity = if let Some(TypeDef::Struct(struct_def)) =
4103 self.types.get(self_type)
4104 {
4105 if let crate::ast::StructFields::Tuple(field_types) = &struct_def.fields {
4106 Some((self_type.clone(), field_types.len()))
4107 } else {
4108 None
4109 }
4110 } else {
4111 None
4112 };
4113
4114 if let Some((type_name, expected_arity)) = tuple_arity {
4115 let arg_values: Vec<Value> = args
4117 .iter()
4118 .map(|a| self.evaluate(a))
4119 .collect::<Result<_, _>>()?;
4120
4121 if arg_values.len() != expected_arity {
4122 return Err(RuntimeError::new(format!(
4123 "Tuple struct {} expects {} fields, got {}",
4124 type_name,
4125 expected_arity,
4126 arg_values.len()
4127 )));
4128 }
4129
4130 let mut fields = HashMap::new();
4132 for (i, value) in arg_values.into_iter().enumerate() {
4133 fields.insert(i.to_string(), value);
4134 }
4135 return Ok(Value::Struct {
4136 name: type_name,
4137 fields: Rc::new(RefCell::new(fields)),
4138 });
4139 }
4140 }
4141 }
4142
4143 if path.segments.len() == 1 {
4145 let type_name = &path.segments[0].ident.name;
4146 let tuple_arity =
4148 if let Some(TypeDef::Struct(struct_def)) = self.types.get(type_name) {
4149 if let crate::ast::StructFields::Tuple(field_types) = &struct_def.fields {
4150 Some((type_name.clone(), field_types.len()))
4151 } else {
4152 None
4153 }
4154 } else {
4155 None
4156 };
4157
4158 if let Some((struct_name, expected_arity)) = tuple_arity {
4159 let arg_values: Vec<Value> = args
4160 .iter()
4161 .map(|a| self.evaluate(a))
4162 .collect::<Result<_, _>>()?;
4163
4164 if arg_values.len() != expected_arity {
4165 return Err(RuntimeError::new(format!(
4166 "Tuple struct {} expects {} fields, got {}",
4167 struct_name,
4168 expected_arity,
4169 arg_values.len()
4170 )));
4171 }
4172
4173 let mut fields = HashMap::new();
4174 for (i, value) in arg_values.into_iter().enumerate() {
4175 fields.insert(i.to_string(), value);
4176 }
4177 return Ok(Value::Struct {
4178 name: struct_name,
4179 fields: Rc::new(RefCell::new(fields)),
4180 });
4181 }
4182 }
4183
4184 if qualified_name == "Default·default" && args.is_empty() {
4187 if let Some(type_name) = self.current_self_type.clone() {
4188 let default_fn_name = format!("{}·default", type_name);
4190 crate::sigil_debug!(
4191 "DEBUG Default::default() looking for '{}', self_type='{}'",
4192 default_fn_name,
4193 type_name
4194 );
4195 let func_clone = self
4196 .globals
4197 .borrow()
4198 .get(&default_fn_name)
4199 .map(|v| v.clone());
4200 if let Some(Value::Function(f)) = func_clone {
4201 crate::sigil_debug!(
4202 "DEBUG Found function '{}', calling it",
4203 default_fn_name
4204 );
4205 crate::sigil_debug!(
4206 "DEBUG current_self_type before call: {:?}",
4207 self.current_self_type
4208 );
4209 let result = self.call_function(&f, vec![]);
4211 crate::sigil_debug!(
4212 "DEBUG Default call result: {:?}",
4213 result
4214 .as_ref()
4215 .map(|v| self.format_value(v))
4216 .unwrap_or_else(|e| format!("ERR: {:?}", e))
4217 );
4218 return result;
4219 }
4220 if let Some(struct_def) = self.default_structs.get(&type_name).cloned() {
4222 let mut fields = HashMap::new();
4223 if let StructFields::Named(field_defs) = &struct_def.fields {
4224 for field in field_defs {
4225 let default_val = if let Some(default_expr) = &field.default {
4226 self.evaluate(default_expr)?
4227 } else {
4228 Value::Null
4229 };
4230 fields.insert(field.name.name.clone(), default_val);
4231 }
4232 }
4233 return Ok(Value::Struct {
4234 name: type_name,
4235 fields: Rc::new(RefCell::new(fields)),
4236 });
4237 }
4238 }
4239 }
4240
4241 if qualified_name.ends_with("·default") && args.is_empty() {
4243 let type_name = qualified_name.strip_suffix("·default").unwrap();
4244 let default_fn_name = format!("{}·default", type_name);
4246 let func_clone = self
4247 .globals
4248 .borrow()
4249 .get(&default_fn_name)
4250 .map(|v| v.clone());
4251 if let Some(Value::Function(f)) = func_clone {
4252 return self.call_function(&f, vec![]);
4254 }
4255 if let Some(struct_def) = self.default_structs.get(type_name).cloned() {
4257 let mut fields = HashMap::new();
4258 if let StructFields::Named(field_defs) = &struct_def.fields {
4259 for field in field_defs {
4260 let default_val = if let Some(default_expr) = &field.default {
4261 self.evaluate(default_expr)?
4262 } else {
4263 Value::Null
4265 };
4266 fields.insert(field.name.name.clone(), default_val);
4267 }
4268 }
4269 return Ok(Value::Struct {
4270 name: type_name.to_string(),
4271 fields: Rc::new(RefCell::new(fields)),
4272 });
4273 }
4274 }
4275
4276 if let Some((enum_name, variant_name, arity)) =
4278 self.variant_constructors.get(&qualified_name).cloned()
4279 {
4280 let arg_values: Vec<Value> = args
4281 .iter()
4282 .map(|a| self.evaluate(a))
4283 .collect::<Result<_, _>>()?;
4284
4285 if arg_values.len() != arity {
4286 return Err(RuntimeError::new(format!(
4287 "{} expects {} arguments, got {}",
4288 qualified_name,
4289 arity,
4290 arg_values.len()
4291 )));
4292 }
4293
4294 if arity == 0 {
4295 return Ok(Value::Variant {
4296 enum_name,
4297 variant_name,
4298 fields: None,
4299 });
4300 } else {
4301 if enum_name == "Item" {
4302 crate::sigil_debug!(
4303 "DEBUG creating Item::{} variant with {} fields",
4304 variant_name,
4305 arg_values.len()
4306 );
4307 }
4308 return Ok(Value::Variant {
4309 enum_name,
4310 variant_name,
4311 fields: Some(Rc::new(arg_values)),
4312 });
4313 }
4314 }
4315
4316 let segments: Vec<&str> = path
4318 .segments
4319 .iter()
4320 .map(|s| s.ident.name.as_str())
4321 .collect();
4322 match segments.as_slice() {
4323 ["Map", "new"] | ["HashMap", "new"] => {
4324 return Ok(Value::Struct {
4326 name: "Map".to_string(),
4327 fields: Rc::new(RefCell::new(HashMap::new())),
4328 });
4329 }
4330 ["String", "new"] => {
4331 return Ok(Value::String(Rc::new(String::new())));
4332 }
4333 ["Vec", "new"] | ["Array", "new"] => {
4334 return Ok(Value::Array(Rc::new(RefCell::new(Vec::new()))));
4335 }
4336 ["Box", "new"] => {
4337 if args.len() == 1 {
4339 return self.evaluate(&args[0]);
4340 }
4341 return Err(RuntimeError::new("Box::new expects 1 argument"));
4342 }
4343 ["char", "from_u32"] => {
4344 if args.len() == 1 {
4346 let arg = self.evaluate(&args[0])?;
4347 let code = match arg {
4348 Value::Int(i) => i as u32,
4349 _ => return Err(RuntimeError::new("char::from_u32 expects u32")),
4350 };
4351 if let Some(c) = char::from_u32(code) {
4352 return Ok(Value::Variant {
4354 enum_name: "Option".to_string(),
4355 variant_name: "Some".to_string(),
4356 fields: Some(Rc::new(vec![Value::Char(c)])),
4357 });
4358 } else {
4359 return Ok(Value::Variant {
4361 enum_name: "Option".to_string(),
4362 variant_name: "None".to_string(),
4363 fields: None,
4364 });
4365 }
4366 }
4367 return Err(RuntimeError::new("char::from_u32 expects 1 argument"));
4368 }
4369 ["parking_lot", "Mutex", "new"]
4371 | ["std", "sync", "Mutex", "new"]
4372 | ["Mutex", "new"] => {
4373 if args.len() == 1 {
4374 let inner = self.evaluate(&args[0])?;
4375 return Ok(Value::Struct {
4376 name: "Mutex".to_string(),
4377 fields: Rc::new(RefCell::new(HashMap::from([(
4378 "__inner__".to_string(),
4379 inner,
4380 )]))),
4381 });
4382 }
4383 return Err(RuntimeError::new("Mutex::new expects 1 argument"));
4384 }
4385 ["parking_lot", "RwLock", "new"]
4387 | ["std", "sync", "RwLock", "new"]
4388 | ["RwLock", "new"] => {
4389 if args.len() == 1 {
4390 let inner = self.evaluate(&args[0])?;
4391 return Ok(Value::Struct {
4392 name: "RwLock".to_string(),
4393 fields: Rc::new(RefCell::new(HashMap::from([(
4394 "__inner__".to_string(),
4395 inner,
4396 )]))),
4397 });
4398 }
4399 return Err(RuntimeError::new("RwLock::new expects 1 argument"));
4400 }
4401 ["std", "sync", "Arc", "new"] | ["Arc", "new"] => {
4403 if args.len() == 1 {
4404 let inner = self.evaluate(&args[0])?;
4405 return Ok(Value::Ref(Rc::new(RefCell::new(inner))));
4406 }
4407 return Err(RuntimeError::new("Arc::new expects 1 argument"));
4408 }
4409 ["std", "sync", "atomic", "AtomicU64", "new"] | ["AtomicU64", "new"] => {
4411 if args.len() == 1 {
4412 let inner = self.evaluate(&args[0])?;
4413 return Ok(Value::Struct {
4414 name: "AtomicU64".to_string(),
4415 fields: Rc::new(RefCell::new(HashMap::from([(
4416 "__value__".to_string(),
4417 inner,
4418 )]))),
4419 });
4420 }
4421 return Err(RuntimeError::new("AtomicU64::new expects 1 argument"));
4422 }
4423 ["std", "sync", "atomic", "AtomicUsize", "new"] | ["AtomicUsize", "new"] => {
4424 if args.len() == 1 {
4425 let inner = self.evaluate(&args[0])?;
4426 return Ok(Value::Struct {
4427 name: "AtomicUsize".to_string(),
4428 fields: Rc::new(RefCell::new(HashMap::from([(
4429 "__value__".to_string(),
4430 inner,
4431 )]))),
4432 });
4433 }
4434 return Err(RuntimeError::new("AtomicUsize::new expects 1 argument"));
4435 }
4436 ["std", "sync", "atomic", "AtomicBool", "new"] | ["AtomicBool", "new"] => {
4437 if args.len() == 1 {
4438 let inner = self.evaluate(&args[0])?;
4439 return Ok(Value::Struct {
4440 name: "AtomicBool".to_string(),
4441 fields: Rc::new(RefCell::new(HashMap::from([(
4442 "__value__".to_string(),
4443 inner,
4444 )]))),
4445 });
4446 }
4447 return Err(RuntimeError::new("AtomicBool::new expects 1 argument"));
4448 }
4449 ["Linear", "new"] => {
4451 if args.is_empty() {
4452 let turbofish_generics: Option<(i64, i64)> = if let Some(seg) = path.segments.first() {
4454 if let Some(generics) = &seg.generics {
4455 let mut const_values: Vec<i64> = Vec::new();
4456 for generic in generics {
4457 if let crate::ast::TypeExpr::ConstExpr(expr) = generic {
4458 if let crate::ast::Expr::Literal(crate::ast::Literal::Int { value, .. }) = expr.as_ref() {
4459 if let Ok(n) = value.parse::<i64>() {
4460 const_values.push(n);
4461 }
4462 }
4463 }
4464 if let crate::ast::TypeExpr::Path(inner_path) = generic {
4465 if let Some(inner_seg) = inner_path.segments.first() {
4466 if let Ok(n) = inner_seg.ident.name.parse::<i64>() {
4467 const_values.push(n);
4468 }
4469 }
4470 }
4471 }
4472 if const_values.len() >= 2 {
4473 Some((const_values[0], const_values[1]))
4474 } else {
4475 None
4476 }
4477 } else {
4478 None
4479 }
4480 } else {
4481 None
4482 };
4483
4484 let (in_features, out_features) = if let Some((i, o)) = turbofish_generics {
4486 (i, o)
4487 } else if let Some((name, generics)) = self.type_context.struct_generics.borrow().clone() {
4488 if name == "Linear" && generics.len() >= 2 {
4489 (generics[0], generics[1])
4490 } else {
4491 return Err(RuntimeError::new("Linear::new requires type annotation like Linear<IN, OUT>"));
4492 }
4493 } else {
4494 return Err(RuntimeError::new("Linear::new requires type annotation like Linear<IN, OUT>"));
4495 };
4496
4497 let weight_data: Vec<Value> = (0..(out_features * in_features))
4499 .map(|_| Value::Float(rand::random::<f64>() * 2.0 - 1.0))
4500 .collect();
4501 let weight_shape = vec![Value::Int(out_features), Value::Int(in_features)];
4502 let mut weight_fields = HashMap::new();
4503 weight_fields.insert("data".to_string(), Value::Array(Rc::new(RefCell::new(weight_data))));
4504 weight_fields.insert("shape".to_string(), Value::Array(Rc::new(RefCell::new(weight_shape))));
4505 weight_fields.insert("requires_grad".to_string(), Value::Bool(true));
4506 weight_fields.insert("grad".to_string(), Value::Variant {
4507 enum_name: "Option".to_string(),
4508 variant_name: "None".to_string(),
4509 fields: None,
4510 });
4511
4512 let bias_data: Vec<Value> = (0..out_features)
4514 .map(|_| Value::Float(rand::random::<f64>() * 2.0 - 1.0))
4515 .collect();
4516 let bias_shape = vec![Value::Int(out_features)];
4517 let mut bias_fields = HashMap::new();
4518 bias_fields.insert("data".to_string(), Value::Array(Rc::new(RefCell::new(bias_data))));
4519 bias_fields.insert("shape".to_string(), Value::Array(Rc::new(RefCell::new(bias_shape))));
4520 bias_fields.insert("requires_grad".to_string(), Value::Bool(true));
4521 bias_fields.insert("grad".to_string(), Value::Variant {
4522 enum_name: "Option".to_string(),
4523 variant_name: "None".to_string(),
4524 fields: None,
4525 });
4526
4527 let mut linear_fields = HashMap::new();
4529 linear_fields.insert("weight".to_string(), Value::Struct {
4530 name: "Tensor".to_string(),
4531 fields: Rc::new(RefCell::new(weight_fields)),
4532 });
4533 linear_fields.insert("bias".to_string(), Value::Struct {
4534 name: "Tensor".to_string(),
4535 fields: Rc::new(RefCell::new(bias_fields)),
4536 });
4537
4538 return Ok(Value::Struct {
4539 name: "Linear".to_string(),
4540 fields: Rc::new(RefCell::new(linear_fields)),
4541 });
4542 }
4543 return Err(RuntimeError::new("Linear::new takes no arguments"));
4544 }
4545 ["ReLU", "new"] => {
4547 if args.is_empty() {
4548 return Ok(Value::Struct {
4549 name: "ReLU".to_string(),
4550 fields: Rc::new(RefCell::new(HashMap::new())),
4551 });
4552 }
4553 return Err(RuntimeError::new("ReLU::new takes no arguments"));
4554 }
4555 ["Sequential", "new"] => {
4557 if args.len() == 1 {
4558 let layers = self.evaluate(&args[0])?;
4559 let mut fields = HashMap::new();
4560 fields.insert("layers".to_string(), layers);
4561 return Ok(Value::Struct {
4562 name: "Sequential".to_string(),
4563 fields: Rc::new(RefCell::new(fields)),
4564 });
4565 }
4566 return Err(RuntimeError::new("Sequential::new expects an array of layers"));
4567 }
4568 _ => {}
4569 }
4570 }
4571
4572 let type_name_for_self = if let Expr::Path(path) = func_expr {
4574 if path.segments.len() >= 2 {
4575 let first = &path.segments[0].ident.name;
4577 if self.types.contains_key(first) {
4579 Some(first.clone())
4580 } else {
4581 None
4582 }
4583 } else {
4584 None
4585 }
4586 } else {
4587 None
4588 };
4589
4590 let func = self.evaluate(func_expr)?;
4591
4592 let mut mut_ref_sync: Vec<(String, Rc<RefCell<Value>>)> = Vec::new();
4595
4596 let mut arg_values: Vec<Value> = Vec::new();
4597 for arg in args.iter() {
4598 let val = self.evaluate(arg)?;
4599
4600 if let Expr::Unary {
4602 op: crate::ast::UnaryOp::RefMut,
4603 expr,
4604 } = arg
4605 {
4606 if let Expr::Path(path) = expr.as_ref() {
4607 if path.segments.len() == 1 {
4608 let var_name = path.segments[0].ident.name.clone();
4609 if let Value::Ref(r) = &val {
4610 mut_ref_sync.push((var_name, r.clone()));
4611 }
4612 }
4613 }
4614 }
4615
4616 arg_values.push(val);
4617 }
4618
4619 let old_self_type = self.current_self_type.clone();
4622 if let Some(type_name) = type_name_for_self {
4623 self.current_self_type = Some(type_name);
4624 }
4625
4626 let result = match func {
4627 Value::Function(f) => self.call_function(&f, arg_values),
4628 Value::BuiltIn(b) => self.call_builtin(&b, arg_values),
4629 Value::Struct { ref name, .. } if name.starts_with("__constructor__") => {
4631 let actual_type = name.strip_prefix("__constructor__").unwrap();
4632 Ok(Value::Struct {
4634 name: actual_type.to_string(),
4635 fields: Rc::new(RefCell::new(HashMap::new())),
4636 })
4637 }
4638 _ => {
4639 crate::sigil_debug!(
4640 "DEBUG Cannot call non-function: {:?}, expr: {:?}",
4641 func,
4642 func_expr
4643 );
4644 Err(RuntimeError::new("Cannot call non-function"))
4645 }
4646 };
4647
4648 for (var_name, ref_val) in mut_ref_sync {
4651 let current_value = ref_val.borrow().clone();
4652 let _ = self.environment.borrow_mut().set(&var_name, current_value);
4653 }
4654
4655 self.current_self_type = old_self_type;
4657
4658 result
4659 }
4660
4661 pub fn call_function(
4662 &mut self,
4663 func: &Function,
4664 args: Vec<Value>,
4665 ) -> Result<Value, RuntimeError> {
4666 if func.name.as_ref().map_or(false, |n| {
4668 n.contains("read_source")
4669 || n.contains("parse_file")
4670 || n.contains("load_from_file")
4671 || n.contains("read_to_string")
4672 }) {
4673 crate::sigil_debug!(
4674 "DEBUG call_function: name={:?}, params={:?}",
4675 func.name,
4676 func.params
4677 );
4678 for (i, arg) in args.iter().enumerate() {
4679 crate::sigil_debug!(" arg[{}] = {:?}", i, arg);
4680 }
4681 }
4682 if args.len() != func.params.len() {
4683 return Err(RuntimeError::new(format!(
4684 "Expected {} arguments, got {} (func={:?}, params={:?})",
4685 func.params.len(),
4686 args.len(),
4687 func.name,
4688 func.params
4689 )));
4690 }
4691
4692 if func.params.iter().any(|p| p == "name") {
4694 for arg in &args {
4695 let unwrapped = Self::unwrap_all(arg);
4696 if let Value::String(s) = &unwrapped {
4697 if s.len() <= 10 {
4698 crate::sigil_debug!("DEBUG call_function(name='{}')", s);
4699 }
4700 }
4701 }
4702 }
4703
4704 let env = Rc::new(RefCell::new(Environment::with_parent(func.closure.clone())));
4706
4707 for (param, value) in func.params.iter().zip(args) {
4709 if param == "path" {
4711 crate::sigil_debug!(
4712 "DEBUG call_function func={:?} binding param 'path' = {:?}",
4713 func.name,
4714 value
4715 );
4716 }
4717 env.borrow_mut().define(param.clone(), value);
4718 }
4719
4720 let prev_env = self.environment.clone();
4722 self.environment = env;
4723
4724 let result = match self.evaluate(&func.body) {
4725 Ok(val) => Ok(val),
4726 Err(e) if e.message == "return" => {
4727 Ok(self.return_value.take().unwrap_or(Value::Null))
4729 }
4730 Err(e) => Err(e),
4731 };
4732
4733 self.environment = prev_env;
4734 result
4735 }
4736
4737 fn call_builtin(
4738 &mut self,
4739 builtin: &BuiltInFn,
4740 args: Vec<Value>,
4741 ) -> Result<Value, RuntimeError> {
4742 if let Some(arity) = builtin.arity {
4743 if args.len() != arity {
4744 return Err(RuntimeError::new(format!(
4745 "{}() expects {} arguments, got {}",
4746 builtin.name,
4747 arity,
4748 args.len()
4749 )));
4750 }
4751 }
4752 (builtin.func)(self, args)
4753 }
4754
4755 pub fn await_value(&mut self, value: Value) -> Result<Value, RuntimeError> {
4757 match value {
4758 Value::Future(fut) => {
4759 let mut fut_inner = fut.borrow_mut();
4760 self.poll_future(&mut fut_inner)
4761 }
4762 other => Ok(other),
4764 }
4765 }
4766
4767 fn unwrap_result_or_option(
4771 &self,
4772 value: Value,
4773 propagate_errors: bool,
4774 panic_on_error: bool,
4775 ) -> Result<Value, RuntimeError> {
4776 let (is_ok_or_some, is_err, is_none, inner_val) = match &value {
4778 Value::Struct { name, fields } if name == "Ok" || name == "Some" => {
4779 let borrowed = fields.borrow();
4780 let inner = borrowed.get("0").or(borrowed.get("value")).cloned();
4781 (true, false, false, inner)
4782 }
4783 Value::Struct { name, fields } if name == "Err" => {
4784 let borrowed = fields.borrow();
4785 let inner = borrowed.get("0").or(borrowed.get("value")).cloned();
4786 (false, true, false, inner)
4787 }
4788 Value::Struct { name, .. } if name == "None" => (false, false, true, None),
4789 _ => return Ok(value),
4790 };
4791
4792 if is_ok_or_some {
4793 Ok(inner_val.unwrap_or(value))
4794 } else if is_err {
4795 let msg = format!("Error: {:?}", inner_val);
4796 if panic_on_error {
4797 panic!("{}", msg);
4798 } else if propagate_errors {
4799 Err(RuntimeError::new(msg))
4800 } else {
4801 Ok(inner_val.unwrap_or(value))
4802 }
4803 } else if is_none {
4804 if panic_on_error {
4805 panic!("Unwrapped None");
4806 } else if propagate_errors {
4807 Err(RuntimeError::new("Unwrapped None".to_string()))
4808 } else {
4809 Ok(value)
4810 }
4811 } else {
4812 Ok(value)
4813 }
4814 }
4815
4816 fn poll_future(&mut self, fut: &mut FutureInner) -> Result<Value, RuntimeError> {
4818 match &fut.state {
4820 FutureState::Ready(v) => return Ok((**v).clone()),
4821 FutureState::Failed(e) => return Err(RuntimeError::new(e.clone())),
4822 _ => {}
4823 }
4824
4825 if let Some(complete_at) = fut.complete_at {
4827 if std::time::Instant::now() >= complete_at {
4828 fut.state = FutureState::Ready(Box::new(Value::Null));
4829 return Ok(Value::Null);
4830 } else {
4831 let remaining = complete_at - std::time::Instant::now();
4833 std::thread::sleep(remaining);
4834 fut.state = FutureState::Ready(Box::new(Value::Null));
4835 return Ok(Value::Null);
4836 }
4837 }
4838
4839 if let Some(computation) = fut.computation.take() {
4841 fut.state = FutureState::Running;
4842
4843 match computation {
4844 FutureComputation::Immediate(v) => {
4845 fut.state = FutureState::Ready(v.clone());
4846 Ok((*v).clone())
4847 }
4848 FutureComputation::Timer(duration) => {
4849 std::thread::sleep(duration);
4851 fut.state = FutureState::Ready(Box::new(Value::Null));
4852 Ok(Value::Null)
4853 }
4854 FutureComputation::Lazy { func, args } => {
4855 match self.call_function(&func, args) {
4857 Ok(result) => {
4858 fut.state = FutureState::Ready(Box::new(result.clone()));
4859 Ok(result)
4860 }
4861 Err(e) => {
4862 fut.state = FutureState::Failed(e.message.clone());
4863 Err(e)
4864 }
4865 }
4866 }
4867 FutureComputation::Join(futures) => {
4868 let mut results = Vec::new();
4870 for f in futures {
4871 let mut f_inner = f.borrow_mut();
4872 results.push(self.poll_future(&mut f_inner)?);
4873 }
4874 let result = Value::Array(Rc::new(RefCell::new(results)));
4875 fut.state = FutureState::Ready(Box::new(result.clone()));
4876 Ok(result)
4877 }
4878 FutureComputation::Race(futures) => {
4879 for f in futures {
4882 let f_inner = f.borrow_mut();
4883 if matches!(f_inner.state, FutureState::Ready(_)) {
4884 if let FutureState::Ready(v) = &f_inner.state {
4885 fut.state = FutureState::Ready(v.clone());
4886 return Ok((**v).clone());
4887 }
4888 }
4889 }
4890 Err(RuntimeError::new("No futures ready in race"))
4892 }
4893 }
4894 } else {
4895 match &fut.state {
4897 FutureState::Ready(v) => Ok((**v).clone()),
4898 FutureState::Failed(e) => Err(RuntimeError::new(e.clone())),
4899 _ => Err(RuntimeError::new("Future has no computation")),
4900 }
4901 }
4902 }
4903
4904 pub fn make_future_immediate(&self, value: Value) -> Value {
4906 Value::Future(Rc::new(RefCell::new(FutureInner {
4907 state: FutureState::Ready(Box::new(value)),
4908 computation: None,
4909 complete_at: None,
4910 })))
4911 }
4912
4913 pub fn make_future_lazy(&self, func: Rc<Function>, args: Vec<Value>) -> Value {
4915 Value::Future(Rc::new(RefCell::new(FutureInner {
4916 state: FutureState::Pending,
4917 computation: Some(FutureComputation::Lazy { func, args }),
4918 complete_at: None,
4919 })))
4920 }
4921
4922 pub fn make_future_timer(&self, duration: std::time::Duration) -> Value {
4924 Value::Future(Rc::new(RefCell::new(FutureInner {
4925 state: FutureState::Pending,
4926 computation: Some(FutureComputation::Timer(duration)),
4927 complete_at: Some(std::time::Instant::now() + duration),
4928 })))
4929 }
4930
4931 fn eval_array(&mut self, elements: &[Expr]) -> Result<Value, RuntimeError> {
4932 let values: Vec<Value> = elements
4933 .iter()
4934 .map(|e| self.evaluate(e))
4935 .collect::<Result<_, _>>()?;
4936 Ok(Value::Array(Rc::new(RefCell::new(values))))
4937 }
4938
4939 fn eval_tuple(&mut self, elements: &[Expr]) -> Result<Value, RuntimeError> {
4940 let values: Vec<Value> = elements
4941 .iter()
4942 .map(|e| self.evaluate(e))
4943 .collect::<Result<_, _>>()?;
4944 Ok(Value::Tuple(Rc::new(values)))
4945 }
4946
4947 fn eval_block(&mut self, block: &Block) -> Result<Value, RuntimeError> {
4948 let env = Rc::new(RefCell::new(Environment::with_parent(
4949 self.environment.clone(),
4950 )));
4951 let prev_env = self.environment.clone();
4952 self.environment = env;
4953
4954 let mut result = Value::Null;
4955
4956 for stmt in &block.stmts {
4957 match stmt {
4958 Stmt::Let { pattern, ty, init } => {
4959 if let Some(type_expr) = ty {
4961 if let Some(shape) = self.extract_tensor_shape(type_expr) {
4962 *self.type_context.tensor_shape.borrow_mut() = Some(shape);
4963 }
4964 if let Some((name, generics)) = self.extract_struct_generics(type_expr) {
4966 *self.type_context.struct_generics.borrow_mut() = Some((name, generics));
4967 }
4968 }
4969 let value = match init {
4970 Some(expr) => self.evaluate(expr)?,
4971 None => Value::Null,
4972 };
4973 *self.type_context.tensor_shape.borrow_mut() = None;
4975 *self.type_context.struct_generics.borrow_mut() = None;
4976 if let Some(type_expr) = ty {
4978 if matches!(type_expr, crate::ast::TypeExpr::Linear(_)) {
4979 if let Pattern::Ident { name, .. } = pattern {
4981 self.linear_state.vars.borrow_mut().insert(name.name.clone());
4982 }
4983 }
4984 }
4985 if let Some(type_expr) = ty {
4987 if let Some((type_name, type_params)) = self.extract_type_params(type_expr) {
4988 self.check_generic_type_match(&type_name, &type_params, &value)?;
4989 if type_name == "Vec" && !type_params.is_empty() {
4991 if let Pattern::Ident { name, .. } = pattern {
4992 self.var_types.borrow_mut().insert(
4993 name.name.clone(),
4994 (type_name.clone(), type_params.clone())
4995 );
4996 }
4997 }
4998 }
4999 }
5000 self.bind_pattern(pattern, value)?;
5001 }
5002 Stmt::LetElse {
5003 pattern,
5004 init,
5005 else_branch,
5006 ..
5007 } => {
5008 let value = self.evaluate(init)?;
5009 if self.bind_pattern(pattern, value.clone()).is_err() {
5011 return self.evaluate(else_branch);
5012 }
5013 }
5014 Stmt::Expr(expr) => {
5015 result = self.evaluate(expr)?;
5016 }
5017 Stmt::Semi(expr) => {
5018 self.evaluate(expr)?;
5019 result = Value::Null;
5020 }
5021 Stmt::Item(item) => {
5022 self.execute_item(item)?;
5023 }
5024 }
5025 }
5026
5027 if let Some(expr) = &block.expr {
5028 result = self.evaluate(expr)?;
5029 }
5030
5031 let values_to_drop: Vec<(String, Value)> = self
5034 .environment
5035 .borrow()
5036 .values
5037 .iter()
5038 .filter_map(|(name, value)| {
5039 if let Value::Struct {
5040 name: struct_name, ..
5041 } = value
5042 {
5043 if self.drop_types.contains(struct_name) {
5044 return Some((name.clone(), value.clone()));
5045 }
5046 }
5047 None
5048 })
5049 .collect();
5050
5051 for (_var_name, value) in values_to_drop {
5053 if let Value::Struct {
5054 name: struct_name, ..
5055 } = &value
5056 {
5057 let drop_fn_name = format!("{}·drop", struct_name);
5058 let drop_fn = self.globals.borrow().get(&drop_fn_name).map(|v| v.clone());
5060 if let Some(Value::Function(f)) = drop_fn {
5061 let _ = self.call_function(&f, vec![value.clone()]);
5063 }
5064 }
5065 }
5066
5067 self.environment = prev_env;
5068 Ok(result)
5069 }
5070
5071 fn extract_tensor_shape(&self, type_expr: &crate::ast::TypeExpr) -> Option<Vec<i64>> {
5073 use crate::ast::TypeExpr;
5074
5075 match type_expr {
5076 TypeExpr::Path(path) => {
5077 if let Some(segment) = path.segments.first() {
5079 if segment.ident.name == "Tensor" {
5080 if let Some(generics) = &segment.generics {
5082 if let Some(first_generic) = generics.first() {
5083 return self.extract_shape_from_type(first_generic);
5084 }
5085 }
5086 }
5087 }
5088 None
5089 }
5090 TypeExpr::Linear(inner) => {
5091 self.extract_tensor_shape(inner)
5093 }
5094 _ => None,
5095 }
5096 }
5097
5098 fn extract_shape_from_type(&self, type_expr: &crate::ast::TypeExpr) -> Option<Vec<i64>> {
5100 use crate::ast::{TypeExpr, Expr, Literal};
5101
5102 match type_expr {
5103 TypeExpr::ConstExpr(expr) => {
5105 if let Expr::Array(elements) = expr.as_ref() {
5106 let mut dims = Vec::new();
5107 for elem in elements {
5108 match elem {
5109 Expr::Literal(Literal::Int { value, .. }) => {
5110 if let Ok(n) = value.parse::<i64>() {
5111 dims.push(n);
5112 }
5113 }
5114 _ => {}
5115 }
5116 }
5117 if dims.is_empty() { None } else { Some(dims) }
5118 } else {
5119 None
5120 }
5121 }
5122 TypeExpr::Array { size, element: _ } => {
5124 if let Expr::Literal(Literal::Int { value, .. }) = size.as_ref() {
5125 if let Ok(n) = value.parse::<i64>() {
5126 Some(vec![n])
5127 } else {
5128 None
5129 }
5130 } else {
5131 None
5132 }
5133 }
5134 TypeExpr::Slice(inner) => {
5136 if let TypeExpr::ConstExpr(expr) = inner.as_ref() {
5139 if let Expr::Literal(Literal::Int { value, .. }) = expr.as_ref() {
5140 if let Ok(n) = value.parse::<i64>() {
5141 return Some(vec![n]);
5142 }
5143 }
5144 }
5145 None
5146 }
5147 TypeExpr::Tuple(dims) => {
5149 let mut shape = Vec::new();
5150 for dim in dims {
5151 if let TypeExpr::Path(path) = dim {
5152 if let Some(seg) = path.segments.first() {
5153 if let Ok(n) = seg.ident.name.parse::<i64>() {
5154 shape.push(n);
5155 }
5156 }
5157 }
5158 }
5159 if shape.is_empty() { None } else { Some(shape) }
5160 }
5161 TypeExpr::Path(path) => {
5163 if let Some(seg) = path.segments.first() {
5166 let name = &seg.ident.name;
5168 if name.starts_with('[') && name.ends_with(']') {
5170 let inner = &name[1..name.len()-1];
5171 let dims: Vec<i64> = inner.split(',')
5172 .filter_map(|s| s.trim().parse().ok())
5173 .collect();
5174 if !dims.is_empty() {
5175 return Some(dims);
5176 }
5177 }
5178 }
5179 None
5180 }
5181 _ => None,
5182 }
5183 }
5184
5185 fn extract_struct_generics(&self, type_expr: &crate::ast::TypeExpr) -> Option<(String, Vec<i64>)> {
5187 use crate::ast::{TypeExpr, Expr, Literal};
5188
5189 let inner_type = if let TypeExpr::Linear(inner) = type_expr {
5191 inner.as_ref()
5192 } else {
5193 type_expr
5194 };
5195
5196 if let TypeExpr::Path(path) = inner_type {
5197 if let Some(segment) = path.segments.first() {
5198 let struct_name = segment.ident.name.clone();
5199 if let Some(generics) = &segment.generics {
5200 let mut const_values: Vec<i64> = Vec::new();
5201 for generic in generics {
5203 if let TypeExpr::ConstExpr(expr) = generic {
5205 if let Expr::Literal(Literal::Int { value, .. }) = expr.as_ref() {
5206 if let Ok(n) = value.parse::<i64>() {
5207 const_values.push(n);
5208 }
5209 }
5210 }
5211 if let TypeExpr::Path(inner_path) = generic {
5213 if let Some(inner_seg) = inner_path.segments.first() {
5214 if let Ok(n) = inner_seg.ident.name.parse::<i64>() {
5215 const_values.push(n);
5216 }
5217 }
5218 }
5219 }
5220 if !const_values.is_empty() {
5221 return Some((struct_name, const_values));
5222 }
5223 }
5224 }
5225 }
5226 None
5227 }
5228
5229 fn bind_pattern(&mut self, pattern: &Pattern, value: Value) -> Result<(), RuntimeError> {
5230 match pattern {
5231 Pattern::Ident { name, mutable, .. } => {
5232 if name.name != "_" {
5234 if name.name == "path" {
5236 crate::sigil_debug!("DEBUG bind_pattern: binding 'path' = {:?}", value);
5237 }
5238 if *mutable {
5240 self.mutable_vars.borrow_mut().insert(name.name.clone());
5241 }
5242 self.environment
5243 .borrow_mut()
5244 .define(name.name.clone(), value);
5245 }
5246 Ok(())
5247 }
5248 Pattern::Tuple(patterns) => {
5249 let unwrapped = Self::unwrap_all(&value);
5251 crate::sigil_debug!(
5252 "DEBUG bind_pattern Tuple: patterns.len()={}, value type={:?}",
5253 patterns.len(),
5254 std::mem::discriminant(&unwrapped)
5255 );
5256 match unwrapped {
5257 Value::Tuple(values) => {
5258 if patterns.len() != values.len() {
5259 return Err(RuntimeError::new("Tuple pattern size mismatch"));
5260 }
5261 for (i, (p, v)) in patterns.iter().zip(values.iter()).enumerate() {
5262 crate::sigil_debug!(
5263 "DEBUG binding tuple element {}: {:?} = {}",
5264 i,
5265 p,
5266 self.format_value(v)
5267 );
5268 self.bind_pattern(p, v.clone())?;
5269 }
5270 Ok(())
5271 }
5272 Value::Null => {
5273 Ok(())
5275 }
5276 Value::Array(arr) if arr.borrow().len() == patterns.len() => {
5277 let vals = arr.borrow();
5279 for (p, v) in patterns.iter().zip(vals.iter()) {
5280 self.bind_pattern(p, v.clone())?;
5281 }
5282 Ok(())
5283 }
5284 _ => Err(RuntimeError::new("Expected tuple")),
5285 }
5286 }
5287 Pattern::Wildcard => Ok(()),
5288 Pattern::Struct { path, fields, .. } => {
5289 let unwrapped = Self::unwrap_all(&value);
5291 match &unwrapped {
5293 Value::Struct {
5294 fields: struct_fields,
5295 ..
5296 } => {
5297 for field_pat in fields {
5298 let field_name = &field_pat.name.name;
5299 let field_val = struct_fields
5301 .borrow()
5302 .get(field_name)
5303 .cloned()
5304 .unwrap_or(Value::Null);
5305 if let Some(pat) = &field_pat.pattern {
5306 self.bind_pattern(pat, field_val)?;
5307 } else {
5308 self.environment
5310 .borrow_mut()
5311 .define(field_name.clone(), field_val);
5312 }
5313 }
5314 Ok(())
5315 }
5316 Value::Variant {
5317 enum_name,
5318 variant_name,
5319 fields: variant_fields,
5320 } => {
5321 let pattern_variant = path
5323 .segments
5324 .last()
5325 .map(|s| s.ident.name.as_str())
5326 .unwrap_or("");
5327 if pattern_variant == variant_name
5328 || path.segments.iter().any(|s| s.ident.name == *variant_name)
5329 {
5330 if let Some(inner_fields) = variant_fields {
5333 if inner_fields.len() == 1 {
5334 if let Value::Struct {
5336 fields: inner_struct,
5337 ..
5338 } = &inner_fields[0]
5339 {
5340 for field_pat in fields {
5341 let field_name = &field_pat.name.name;
5342 let field_val = inner_struct
5344 .borrow()
5345 .get(field_name)
5346 .cloned()
5347 .unwrap_or(Value::Null);
5348 if let Some(pat) = &field_pat.pattern {
5349 self.bind_pattern(pat, field_val)?;
5350 } else {
5351 self.environment
5352 .borrow_mut()
5353 .define(field_name.clone(), field_val);
5354 }
5355 }
5356 return Ok(());
5357 }
5358 }
5359 for field_pat in fields {
5362 let field_name = &field_pat.name.name;
5363 let field_val = inner_fields.iter().find_map(|f| {
5367 if let Value::Struct { fields: fs, .. } = f {
5368 fs.borrow().get(field_name).cloned()
5369 } else {
5370 None
5371 }
5372 });
5373 if let Some(val) = field_val {
5374 if let Some(pat) = &field_pat.pattern {
5375 self.bind_pattern(pat, val)?;
5376 } else {
5377 self.environment
5378 .borrow_mut()
5379 .define(field_name.clone(), val);
5380 }
5381 }
5382 }
5383 }
5384 Ok(())
5385 } else {
5386 crate::sigil_debug!(
5387 "DEBUG variant name mismatch: pattern={}, actual={}",
5388 pattern_variant,
5389 variant_name
5390 );
5391 Err(RuntimeError::new(format!(
5392 "Variant name mismatch: expected {} but got {}::{}",
5393 pattern_variant, enum_name, variant_name
5394 )))
5395 }
5396 }
5397 _ => {
5398 crate::sigil_debug!(
5399 "DEBUG struct pattern bind: expected struct/variant but got {:?}",
5400 std::mem::discriminant(&unwrapped)
5401 );
5402 Err(RuntimeError::new(
5403 "Expected struct or variant value for struct pattern",
5404 ))
5405 }
5406 }
5407 }
5408 Pattern::Path(_path) => {
5409 Ok(())
5412 }
5413 Pattern::TupleStruct { path, fields } => {
5414 let unwrapped = Self::unwrap_all(&value);
5417 let path_str = path
5418 .segments
5419 .iter()
5420 .map(|s| s.ident.name.as_str())
5421 .collect::<Vec<_>>()
5422 .join("::");
5423 crate::sigil_debug!(
5424 "DEBUG bind_pattern TupleStruct: path={}, value type={:?}",
5425 path_str,
5426 std::mem::discriminant(&unwrapped)
5427 );
5428 if let Value::Variant {
5429 variant_name,
5430 fields: variant_fields,
5431 enum_name,
5432 } = &unwrapped
5433 {
5434 crate::sigil_debug!(
5435 "DEBUG Variant {}::{}, fields={}",
5436 enum_name,
5437 variant_name,
5438 if variant_fields.is_some() {
5439 format!("Some(len={})", variant_fields.as_ref().unwrap().len())
5440 } else {
5441 "None".to_string()
5442 }
5443 );
5444 let pattern_variant = path
5445 .segments
5446 .last()
5447 .map(|s| s.ident.name.as_str())
5448 .unwrap_or("");
5449 if pattern_variant == variant_name {
5450 if let Some(inner_fields) = variant_fields {
5452 if fields.len() == 1 && inner_fields.len() == 1 {
5453 self.bind_pattern(&fields[0], inner_fields[0].clone())?;
5454 } else {
5455 for (pat, val) in fields.iter().zip(inner_fields.iter()) {
5456 self.bind_pattern(pat, val.clone())?;
5457 }
5458 }
5459 } else if !fields.is_empty() {
5460 crate::sigil_debug!(
5462 "DEBUG TupleStruct: pattern expects {} fields but variant has none",
5463 fields.len()
5464 );
5465 }
5466 }
5467 Ok(())
5468 } else {
5469 if let Value::Tuple(tuple_vals) = &value {
5471 for (pat, val) in fields.iter().zip(tuple_vals.iter()) {
5472 self.bind_pattern(pat, val.clone())?;
5473 }
5474 Ok(())
5475 } else {
5476 Err(RuntimeError::new(
5477 "Expected variant or tuple for tuple struct pattern",
5478 ))
5479 }
5480 }
5481 }
5482 Pattern::Literal(_) => {
5483 Ok(())
5485 }
5486 Pattern::Rest => {
5487 Ok(())
5489 }
5490 Pattern::Range { .. } => {
5491 Ok(())
5493 }
5494 Pattern::Or(patterns) => {
5495 for p in patterns {
5497 if self.pattern_matches(p, &value)? {
5498 return self.bind_pattern(p, value.clone());
5499 }
5500 }
5501 Err(RuntimeError::new("Or pattern didn't match any alternative"))
5503 }
5504 _ => Err(RuntimeError::new(format!(
5505 "Unsupported pattern: {:?}",
5506 pattern
5507 ))),
5508 }
5509 }
5510
5511 fn eval_if(
5512 &mut self,
5513 condition: &Expr,
5514 then_branch: &Block,
5515 else_branch: &Option<Box<Expr>>,
5516 ) -> Result<Value, RuntimeError> {
5517 let cond = self.evaluate(condition)?;
5518 if self.is_truthy(&cond) {
5519 self.eval_block(then_branch)
5520 } else if let Some(else_expr) = else_branch {
5521 self.evaluate(else_expr)
5522 } else {
5523 Ok(Value::Null)
5524 }
5525 }
5526
5527 fn eval_match(&mut self, expr: &Expr, arms: &[MatchArm]) -> Result<Value, RuntimeError> {
5528 if arms.len() >= 2 {
5530 let mut first_type: Option<String> = None;
5531 for arm in arms {
5532 if let Some(arm_type) = self.infer_expr_type(&arm.body) {
5533 if let Some(ref expected) = first_type {
5534 if &arm_type != expected {
5535 return Err(RuntimeError::new(format!(
5536 "match arms have incompatible types: expected '{}', found '{}'",
5537 expected, arm_type
5538 )));
5539 }
5540 } else {
5541 first_type = Some(arm_type);
5542 }
5543 }
5544 }
5545 }
5546
5547 let value = self.evaluate(expr)?;
5548
5549 let unwrapped = Self::unwrap_all(&value);
5551 if let Value::String(s) = &unwrapped {
5552 if s.len() <= 10 {
5553 crate::sigil_debug!("DEBUG eval_match: string='{}', arms={}", s, arms.len());
5554 }
5555 }
5556
5557 for arm in arms {
5558 if self.pattern_matches(&arm.pattern, &value)? {
5559 let env = Rc::new(RefCell::new(Environment::with_parent(
5561 self.environment.clone(),
5562 )));
5563 let prev_env = self.environment.clone();
5564 self.environment = env;
5565
5566 if let Err(e) = self.bind_pattern(&arm.pattern, value.clone()) {
5569 self.environment = prev_env;
5570 return Err(e);
5571 }
5572
5573 if let Some(guard) = &arm.guard {
5575 let guard_val = self.evaluate(guard)?;
5576 if !self.is_truthy(&guard_val) {
5577 self.environment = prev_env;
5579 continue;
5580 }
5581 }
5582
5583 let result = self.evaluate(&arm.body);
5585
5586 self.environment = prev_env;
5587 return result;
5588 }
5589 }
5590
5591 crate::sigil_debug!(
5593 "DEBUG No matching pattern for value: {} (discriminant: {:?})",
5594 self.format_value(&value),
5595 std::mem::discriminant(&value)
5596 );
5597 for (i, arm) in arms.iter().enumerate() {
5599 crate::sigil_debug!("DEBUG arm {}: {:?}", i, arm.pattern);
5600 }
5601 Err(RuntimeError::new(format!(
5602 "No matching pattern for {}",
5603 self.format_value(&value)
5604 )))
5605 }
5606
5607 fn pattern_matches(&mut self, pattern: &Pattern, value: &Value) -> Result<bool, RuntimeError> {
5608 let value = Self::unwrap_all(value);
5610
5611 if let Value::String(s) = &value {
5613 if **s == "fn" {
5614 crate::sigil_debug!("DEBUG pattern_matches: value='fn', pattern={:?}", pattern);
5615 }
5616 }
5617
5618 match (pattern, &value) {
5619 (Pattern::Wildcard, _) => Ok(true),
5620 (
5622 Pattern::Ident {
5623 evidentiality: Some(Evidentiality::Uncertain),
5624 name,
5625 ..
5626 },
5627 val,
5628 ) => {
5629 let matches = match val {
5631 Value::Null => false,
5632 Value::Variant { variant_name, .. } if variant_name == "None" => false,
5633 _ => true,
5634 };
5635 crate::sigil_debug!(
5636 "DEBUG pattern_matches ?{}: value={} => {}",
5637 name.name,
5638 self.format_value(val),
5639 matches
5640 );
5641 Ok(matches)
5642 }
5643 (Pattern::Ident { .. }, _) => Ok(true),
5644 (Pattern::Literal(lit), val) => {
5645 let lit_val = self.eval_literal(lit)?;
5646 let result = self.values_equal(&lit_val, val);
5647 if matches!(lit, Literal::Null) || matches!(val, Value::Null) {
5649 crate::sigil_debug!(
5650 "DEBUG literal pattern: lit={:?}, lit_val={}, val={}, result={}",
5651 lit,
5652 self.format_value(&lit_val),
5653 self.format_value(val),
5654 result
5655 );
5656 }
5657 Ok(result)
5658 }
5659 (Pattern::Tuple(patterns), Value::Tuple(values)) => {
5660 if patterns.len() != values.len() {
5661 return Ok(false);
5662 }
5663 for (p, v) in patterns.iter().zip(values.iter()) {
5664 if !self.pattern_matches(p, v)? {
5665 return Ok(false);
5666 }
5667 }
5668 Ok(true)
5669 }
5670 (
5672 Pattern::Path(path),
5673 Value::Variant {
5674 variant_name,
5675 fields,
5676 ..
5677 },
5678 ) => {
5679 let pattern_variant = path
5680 .segments
5681 .last()
5682 .map(|s| s.ident.name.as_str())
5683 .unwrap_or("");
5684 Ok(pattern_variant == variant_name && fields.is_none())
5686 }
5687 (
5689 Pattern::TupleStruct {
5690 path,
5691 fields: pat_fields,
5692 },
5693 Value::Variant {
5694 variant_name,
5695 fields,
5696 ..
5697 },
5698 ) => {
5699 let pattern_variant = path
5700 .segments
5701 .last()
5702 .map(|s| s.ident.name.as_str())
5703 .unwrap_or("");
5704 if pattern_variant != variant_name {
5705 return Ok(false);
5706 }
5707 if let Some(variant_fields) = fields {
5709 if pat_fields.len() != variant_fields.len() {
5710 return Ok(false);
5711 }
5712 for (p, v) in pat_fields.iter().zip(variant_fields.iter()) {
5713 if !self.pattern_matches(p, v)? {
5714 return Ok(false);
5715 }
5716 }
5717 Ok(true)
5718 } else {
5719 Ok(pat_fields.is_empty())
5721 }
5722 }
5723 (
5725 Pattern::Struct {
5726 path,
5727 fields: pat_fields,
5728 rest,
5729 },
5730 Value::Struct {
5731 name: struct_name,
5732 fields: struct_fields,
5733 },
5734 ) => {
5735 let pattern_name = path
5736 .segments
5737 .iter()
5738 .map(|s| s.ident.name.as_str())
5739 .collect::<Vec<_>>()
5740 .join("::");
5741 if pattern_name != *struct_name {
5742 return Ok(false);
5743 }
5744 let borrowed = struct_fields.borrow();
5746 for field_pat in pat_fields {
5747 let field_name = &field_pat.name.name;
5748 if let Some(field_val) = borrowed.get(field_name) {
5749 if let Some(sub_pat) = &field_pat.pattern {
5750 if !self.pattern_matches(sub_pat, field_val)? {
5751 return Ok(false);
5752 }
5753 }
5754 } else if !rest {
5756 return Ok(false);
5758 }
5759 }
5760 Ok(true)
5761 }
5762 (
5764 Pattern::Struct {
5765 path,
5766 fields: pat_fields,
5767 rest,
5768 },
5769 Value::Variant {
5770 variant_name,
5771 fields: variant_fields,
5772 ..
5773 },
5774 ) => {
5775 let pattern_variant = path
5776 .segments
5777 .last()
5778 .map(|s| s.ident.name.as_str())
5779 .unwrap_or("");
5780 if pattern_variant != variant_name {
5781 return Ok(false);
5782 }
5783 if let Some(inner_fields) = variant_fields {
5785 if inner_fields.len() == 1 {
5786 if let Value::Struct {
5787 fields: inner_struct,
5788 ..
5789 } = &inner_fields[0]
5790 {
5791 let borrowed = inner_struct.borrow();
5792 for field_pat in pat_fields {
5793 let field_name = &field_pat.name.name;
5794 if let Some(field_val) = borrowed.get(field_name) {
5795 if let Some(sub_pat) = &field_pat.pattern {
5796 if !self.pattern_matches(sub_pat, field_val)? {
5797 return Ok(false);
5798 }
5799 }
5800 } else if !rest {
5801 return Ok(false);
5802 }
5803 }
5804 return Ok(true);
5805 }
5806 }
5807 }
5808 Ok(pat_fields.is_empty() || *rest)
5810 }
5811 (Pattern::Or(patterns), val) => {
5813 for p in patterns {
5814 if self.pattern_matches(p, val)? {
5815 return Ok(true);
5816 }
5817 }
5818 Ok(false)
5819 }
5820 (Pattern::Rest, _) => Ok(true),
5822 (
5824 Pattern::Range {
5825 start,
5826 end,
5827 inclusive,
5828 },
5829 val,
5830 ) => {
5831 let extract_char = |pat: &Option<Box<Pattern>>| -> Option<char> {
5833 match pat {
5834 Some(p) => match p.as_ref() {
5835 Pattern::Literal(Literal::Char(c)) => Some(*c),
5836 _ => None,
5837 },
5838 None => None,
5839 }
5840 };
5841 let extract_int = |pat: &Option<Box<Pattern>>| -> Option<i64> {
5843 match pat {
5844 Some(p) => match p.as_ref() {
5845 Pattern::Literal(Literal::Int { value, .. }) => value.parse().ok(),
5846 _ => None,
5847 },
5848 None => None,
5849 }
5850 };
5851
5852 match val {
5853 Value::Char(c) => {
5854 let start_val = extract_char(start);
5855 let end_val = extract_char(end);
5856 let in_range = match (start_val, end_val, *inclusive) {
5857 (Some(s), Some(e), true) => *c >= s && *c <= e,
5858 (Some(s), Some(e), false) => *c >= s && *c < e,
5859 (Some(s), None, _) => *c >= s,
5860 (None, Some(e), true) => *c <= e,
5861 (None, Some(e), false) => *c < e,
5862 (None, None, _) => true,
5863 };
5864 Ok(in_range)
5865 }
5866 Value::Int(i) => {
5867 let start_val = extract_int(start);
5868 let end_val = extract_int(end);
5869 let in_range = match (start_val, end_val, *inclusive) {
5870 (Some(s), Some(e), true) => *i >= s && *i <= e,
5871 (Some(s), Some(e), false) => *i >= s && *i < e,
5872 (Some(s), None, _) => *i >= s,
5873 (None, Some(e), true) => *i <= e,
5874 (None, Some(e), false) => *i < e,
5875 (None, None, _) => true,
5876 };
5877 Ok(in_range)
5878 }
5879 _ => Ok(false),
5880 }
5881 }
5882 (Pattern::Literal(Literal::String(s)), Value::String(vs)) => Ok(s == vs.as_str()),
5884 (Pattern::Literal(Literal::Char(c)), Value::Char(vc)) => Ok(c == vc),
5885 _ => Ok(false),
5886 }
5887 }
5888
5889 fn values_equal(&self, a: &Value, b: &Value) -> bool {
5890 let a_unwrapped = match a {
5892 Value::Ref(r) => r.borrow().clone(),
5893 _ => a.clone(),
5894 };
5895 let b_unwrapped = match b {
5896 Value::Ref(r) => r.borrow().clone(),
5897 _ => b.clone(),
5898 };
5899 match (&a_unwrapped, &b_unwrapped) {
5900 (Value::Null, Value::Null) => true,
5901 (Value::Bool(a), Value::Bool(b)) => a == b,
5902 (Value::Int(a), Value::Int(b)) => a == b,
5903 (Value::Float(a), Value::Float(b)) => (a - b).abs() < f64::EPSILON,
5904 (Value::String(a), Value::String(b)) => {
5905 let result = **a == **b;
5906 if a.len() <= 5 && b.len() <= 5 {
5908 crate::sigil_debug!("DEBUG values_equal: '{}' == '{}' -> {}", a, b, result);
5909 }
5910 result
5911 }
5912 (Value::Char(a), Value::Char(b)) => a == b,
5913 _ => false,
5914 }
5915 }
5916
5917 fn eval_for(
5918 &mut self,
5919 pattern: &Pattern,
5920 iter: &Expr,
5921 body: &Block,
5922 ) -> Result<Value, RuntimeError> {
5923 let iterable_raw = self.evaluate(iter)?;
5924 let iterable = Self::unwrap_all(&iterable_raw);
5925 let items = match iterable {
5926 Value::Array(arr) => arr.borrow().clone(),
5927 Value::Tuple(t) => (*t).clone(),
5928 Value::String(s) => s.chars().map(Value::Char).collect(),
5929 Value::Map(m) => {
5930 m.borrow()
5932 .iter()
5933 .map(|(k, v)| {
5934 Value::Tuple(Rc::new(vec![Value::String(Rc::new(k.clone())), v.clone()]))
5935 })
5936 .collect()
5937 }
5938 Value::Variant {
5939 fields: Some(f), ..
5940 } => (*f).clone(),
5941 _ => {
5942 return Err(RuntimeError::new(format!(
5943 "Cannot iterate over non-iterable: {:?}",
5944 iterable_raw
5945 )))
5946 }
5947 };
5948
5949 let mut result = Value::Null;
5950 for item in items {
5951 let env = Rc::new(RefCell::new(Environment::with_parent(
5952 self.environment.clone(),
5953 )));
5954 let prev_env = self.environment.clone();
5955 self.environment = env;
5956
5957 self.bind_pattern(pattern, item)?;
5958
5959 match self.eval_block(body) {
5960 Ok(val) => result = val,
5961 Err(e) if e.message == "break" => {
5962 self.environment = prev_env;
5963 break;
5964 }
5965 Err(e) if e.message == "continue" => {
5966 self.environment = prev_env;
5967 continue;
5968 }
5969 Err(e) => {
5970 self.environment = prev_env;
5971 return Err(e);
5972 }
5973 }
5974
5975 self.environment = prev_env;
5976 }
5977
5978 Ok(result)
5979 }
5980
5981 fn eval_while(&mut self, condition: &Expr, body: &Block) -> Result<Value, RuntimeError> {
5982 let mut result = Value::Null;
5983 loop {
5984 let cond = self.evaluate(condition)?;
5985 if !self.is_truthy(&cond) {
5986 break;
5987 }
5988
5989 match self.eval_block(body) {
5990 Ok(val) => result = val,
5991 Err(e) if e.message == "break" => break,
5992 Err(e) if e.message == "continue" => continue,
5993 Err(e) => return Err(e),
5994 }
5995 }
5996 Ok(result)
5997 }
5998
5999 fn eval_loop(&mut self, body: &Block) -> Result<Value, RuntimeError> {
6000 loop {
6001 match self.eval_block(body) {
6002 Ok(_) => {}
6003 Err(e) if e.message == "break" => break,
6004 Err(e) if e.message == "continue" => continue,
6005 Err(e) => return Err(e),
6006 }
6007 }
6008 Ok(Value::Null)
6009 }
6010
6011 fn eval_return(&mut self, value: &Option<Box<Expr>>) -> Result<Value, RuntimeError> {
6012 let val = match value {
6013 Some(expr) => self.evaluate(expr)?,
6014 None => Value::Null,
6015 };
6016 self.return_value = Some(val);
6018 Err(RuntimeError::new("return"))
6019 }
6020
6021 fn eval_break(&mut self, _value: &Option<Box<Expr>>) -> Result<Value, RuntimeError> {
6022 Err(RuntimeError::new("break"))
6024 }
6025
6026 fn eval_index(&mut self, expr: &Expr, index: &Expr) -> Result<Value, RuntimeError> {
6027 let collection = self.evaluate(expr)?;
6028
6029 let collection = match collection {
6031 Value::Ref(r) => r.borrow().clone(),
6032 other => other,
6033 };
6034
6035 if let Expr::Range {
6037 start,
6038 end,
6039 inclusive,
6040 } = index
6041 {
6042 let start_val = match start {
6043 Some(e) => match self.evaluate(e)? {
6044 Value::Int(n) => n as usize,
6045 _ => return Err(RuntimeError::new("Slice start must be an integer")),
6046 },
6047 None => 0,
6048 };
6049
6050 return match &collection {
6051 Value::Array(arr) => {
6052 let arr = arr.borrow();
6053 let len = arr.len();
6054 let end_val = match end {
6055 Some(e) => match self.evaluate(e)? {
6056 Value::Int(n) => {
6057 let n = n as usize;
6058 if *inclusive {
6059 n + 1
6060 } else {
6061 n
6062 }
6063 }
6064 _ => return Err(RuntimeError::new("Slice end must be an integer")),
6065 },
6066 None => len, };
6068 let end_val = end_val.min(len);
6069 let start_val = start_val.min(len);
6070 let sliced: Vec<Value> = arr[start_val..end_val].to_vec();
6071 Ok(Value::Array(Rc::new(RefCell::new(sliced))))
6072 }
6073 Value::String(s) => {
6074 let len = s.len();
6075 let end_val = match end {
6076 Some(e) => match self.evaluate(e)? {
6077 Value::Int(n) => {
6078 let n = n as usize;
6079 if *inclusive {
6080 n + 1
6081 } else {
6082 n
6083 }
6084 }
6085 _ => return Err(RuntimeError::new("Slice end must be an integer")),
6086 },
6087 None => len, };
6089 let end_val = end_val.min(len);
6090 let start_val = start_val.min(len);
6091 let sliced = &s[start_val..end_val];
6093 Ok(Value::String(Rc::new(sliced.to_string())))
6094 }
6095 _ => Err(RuntimeError::new("Cannot slice this type")),
6096 };
6097 }
6098
6099 let idx = self.evaluate(index)?;
6100
6101 match (collection, idx) {
6102 (Value::Array(arr), Value::Int(i)) => {
6103 let arr = arr.borrow();
6104 let len = arr.len();
6105
6106 let is_typed_vec = if let Some(var_name) = Self::extract_root_var(expr) {
6109 self.var_types.borrow().get(&var_name)
6110 .map(|(type_name, _)| type_name == "Vec")
6111 .unwrap_or(false)
6112 } else {
6113 false
6114 };
6115
6116 let idx = if i < 0 {
6117 if is_typed_vec {
6118 return Err(RuntimeError::new(format!(
6119 "negative index {} is invalid",
6120 i
6121 )));
6122 }
6123 let positive_idx = (len as i64 + i) as usize;
6125 if positive_idx >= len {
6126 return Err(RuntimeError::index_out_of_bounds(i, len));
6127 }
6128 positive_idx
6129 } else {
6130 i as usize
6131 };
6132
6133 let result = arr
6134 .get(idx)
6135 .cloned()
6136 .ok_or_else(|| RuntimeError::index_out_of_bounds(i, len));
6137 if let Ok(ref v) = result {
6138 crate::sigil_debug!(
6139 "DEBUG eval_index: arr[{}] = {:?}",
6140 idx,
6141 std::mem::discriminant(v)
6142 );
6143 }
6144 result
6145 }
6146 (Value::Tuple(t), Value::Int(i)) => {
6147 if i < 0 {
6149 return Err(RuntimeError::new(format!(
6150 "negative index {} is invalid",
6151 i
6152 )));
6153 }
6154 let len = t.len();
6155 let idx = i as usize;
6156 t.get(idx)
6157 .cloned()
6158 .ok_or_else(|| RuntimeError::index_out_of_bounds(i, len))
6159 }
6160 (Value::String(s), Value::Int(i)) => {
6161 if i < 0 {
6163 return Err(RuntimeError::new(format!(
6164 "negative index {} is invalid",
6165 i
6166 )));
6167 }
6168 let len = s.len();
6169 let idx = i as usize;
6170 s.chars()
6171 .nth(idx)
6172 .map(Value::Char)
6173 .ok_or_else(|| RuntimeError::index_out_of_bounds(i, len))
6174 }
6175 (Value::Array(arr), Value::Tuple(range_tuple)) if range_tuple.len() == 2 => {
6177 let arr = arr.borrow();
6178 let start = match &range_tuple[0] {
6179 Value::Int(n) => *n as usize,
6180 _ => return Err(RuntimeError::new("Range start must be integer")),
6181 };
6182 let end = match &range_tuple[1] {
6183 Value::Null => arr.len(), Value::Int(n) => *n as usize,
6185 _ => return Err(RuntimeError::new("Range end must be integer or None")),
6186 };
6187 let start = start.min(arr.len());
6188 let end = end.min(arr.len());
6189 let sliced: Vec<Value> = arr[start..end].to_vec();
6190 Ok(Value::Array(Rc::new(RefCell::new(sliced))))
6191 }
6192 (Value::String(s), Value::Tuple(range_tuple)) if range_tuple.len() == 2 => {
6193 let start = match &range_tuple[0] {
6194 Value::Int(n) => *n as usize,
6195 _ => return Err(RuntimeError::new("Range start must be integer")),
6196 };
6197 let end = match &range_tuple[1] {
6198 Value::Null => s.len(), Value::Int(n) => *n as usize,
6200 _ => return Err(RuntimeError::new("Range end must be integer or None")),
6201 };
6202 let start = start.min(s.len());
6203 let end = end.min(s.len());
6204 let sliced = &s[start..end];
6205 Ok(Value::String(Rc::new(sliced.to_string())))
6206 }
6207 (Value::Struct { name, fields }, Value::Int(i)) if name == "Tensor" => {
6209 let fields_ref = fields.borrow();
6210
6211 let shape: Vec<i64> = match fields_ref.get("shape") {
6213 Some(Value::Array(arr)) => {
6214 arr.borrow().iter().filter_map(|v| match v {
6215 Value::Int(n) => Some(*n),
6216 _ => None,
6217 }).collect()
6218 }
6219 _ => vec![],
6220 };
6221 let data: Vec<f64> = match fields_ref.get("data") {
6222 Some(Value::Array(arr)) => {
6223 arr.borrow().iter().filter_map(|v| match v {
6224 Value::Float(f) => Some(*f),
6225 Value::Int(n) => Some(*n as f64),
6226 _ => None,
6227 }).collect()
6228 }
6229 _ => vec![],
6230 };
6231 drop(fields_ref);
6232
6233 let idx = if i < 0 { shape[0] + i } else { i } as usize;
6234
6235 if shape.len() == 1 {
6236 if idx < data.len() {
6238 Ok(Value::Float(data[idx]))
6239 } else {
6240 Err(RuntimeError::index_out_of_bounds(i, data.len()))
6241 }
6242 } else if shape.len() >= 2 {
6243 let row_size: usize = shape[1..].iter().map(|&d| d as usize).product();
6245 let start = idx * row_size;
6246 let end = start + row_size;
6247
6248 if end <= data.len() {
6249 let row_data: Vec<Value> = data[start..end].iter()
6250 .map(|&f| Value::Float(f))
6251 .collect();
6252 let row_shape: Vec<Value> = shape[1..].iter()
6253 .map(|&d| Value::Int(d))
6254 .collect();
6255
6256 let mut new_fields = std::collections::HashMap::new();
6257 new_fields.insert("shape".to_string(), Value::Array(Rc::new(RefCell::new(row_shape))));
6258 new_fields.insert("data".to_string(), Value::Array(Rc::new(RefCell::new(row_data))));
6259 new_fields.insert("requires_grad".to_string(), Value::Bool(false));
6260
6261 Ok(Value::Struct {
6262 name: "Tensor".to_string(),
6263 fields: Rc::new(RefCell::new(new_fields)),
6264 })
6265 } else {
6266 Err(RuntimeError::index_out_of_bounds(i, shape[0] as usize))
6267 }
6268 } else {
6269 Err(RuntimeError::new("Cannot index scalar tensor"))
6271 }
6272 }
6273 (coll, idx) => {
6274 crate::sigil_debug!(
6275 "DEBUG Cannot index: collection={:?}, index={:?}",
6276 std::mem::discriminant(&coll),
6277 std::mem::discriminant(&idx)
6278 );
6279 Err(RuntimeError::new("Cannot index"))
6280 }
6281 }
6282 }
6283
6284 fn eval_field(&mut self, expr: &Expr, field: &Ident) -> Result<Value, RuntimeError> {
6285 if field.name == "items" {
6286 crate::sigil_debug!("DEBUG eval_field: accessing .items on expr={:?}", expr);
6287 }
6288 if field.name == "evidence" {
6290 crate::sigil_debug!("DEBUG eval_field: accessing .evidence");
6291 }
6292 let value = self.evaluate(expr)?;
6293 if field.name == "items" {
6294 crate::sigil_debug!(
6295 "DEBUG eval_field: .items receiver value={:?}",
6296 std::mem::discriminant(&value)
6297 );
6298 }
6299 if field.name == "evidence" {
6300 crate::sigil_debug!(
6301 "DEBUG eval_field: .evidence receiver value type={:?}",
6302 std::mem::discriminant(&value)
6303 );
6304 }
6305 fn get_field(val: &Value, field_name: &str) -> Result<Value, RuntimeError> {
6307 if field_name == "evidence" {
6309 crate::sigil_debug!(
6310 "DEBUG get_field 'evidence' on value type: {:?}",
6311 std::mem::discriminant(val)
6312 );
6313 }
6314 match val {
6315 Value::Struct { name, fields } => {
6316 let field_val = fields.borrow().get(field_name).cloned();
6317 if field_val.is_none() && field_name == "path" {
6318 crate::sigil_debug!(
6319 "DEBUG Unknown field 'path': struct={}, available={:?}",
6320 name,
6321 fields.borrow().keys().collect::<Vec<_>>()
6322 );
6323 }
6324 if field_name == "evidence" || name.contains("IrPattern") {
6326 crate::sigil_debug!("DEBUG get_field on Struct: name={}, field={}, available={:?}, found={}",
6327 name, field_name, fields.borrow().keys().collect::<Vec<_>>(), field_val.is_some());
6328 }
6329 match field_val {
6331 Some(v) => Ok(v),
6332 None => {
6333 Err(RuntimeError::new(format!(
6334 "no field '{}' on struct '{}'",
6335 field_name,
6336 name
6337 )))
6338 }
6339 }
6340 }
6341 Value::Tuple(t) => {
6342 let idx: usize = field_name
6344 .parse()
6345 .map_err(|_| RuntimeError::new("Invalid tuple index"))?;
6346 t.get(idx)
6347 .cloned()
6348 .ok_or_else(|| RuntimeError::new("Tuple index out of bounds"))
6349 }
6350 Value::Ref(r) => {
6351 get_field(&r.borrow(), field_name)
6353 }
6354 Value::Evidential { value, .. } => {
6355 get_field(value, field_name)
6357 }
6358 Value::Affective { value, .. } => {
6359 get_field(value, field_name)
6361 }
6362 Value::Variant {
6363 fields: variant_fields,
6364 ..
6365 } => {
6366 if let Some(inner_fields) = variant_fields {
6369 for f in inner_fields.iter() {
6371 if let Value::Struct {
6372 fields: struct_fields,
6373 ..
6374 } = f
6375 {
6376 if let Some(field_val) =
6377 struct_fields.borrow().get(field_name).cloned()
6378 {
6379 return Ok(field_val);
6380 }
6381 }
6382 }
6383 Ok(Value::Null)
6385 } else {
6386 Ok(Value::Null)
6388 }
6389 }
6390 other => {
6391 crate::sigil_warn!(
6393 "WARN: Cannot access field '{}' on non-struct - returning null",
6394 field_name
6395 );
6396 Ok(Value::Null)
6397 }
6398 }
6399 }
6400 get_field(&value, &field.name)
6401 }
6402
6403 fn extract_root_var(expr: &Expr) -> Option<String> {
6405 match expr {
6406 Expr::Path(path) if path.segments.len() == 1 => {
6407 Some(path.segments[0].ident.name.clone())
6408 }
6409 Expr::MethodCall { receiver, .. } => Self::extract_root_var(receiver),
6410 _ => None,
6411 }
6412 }
6413
6414 fn eval_method_call(
6415 &mut self,
6416 receiver: &Expr,
6417 method: &Ident,
6418 args: &[Expr],
6419 ) -> Result<Value, RuntimeError> {
6420 if (method.name == "push" || method.name == "push_str") && args.len() == 1 {
6422 let recv_val = self.evaluate(receiver)?;
6423 let recv_unwrapped = Self::unwrap_all(&recv_val);
6424 if let Value::String(s) = &recv_unwrapped {
6425 let arg = self.evaluate(&args[0])?;
6426 let arg_unwrapped = Self::unwrap_all(&arg);
6427 let new_s = match arg_unwrapped {
6428 Value::Char(c) => {
6429 let mut new_str = (**s).clone();
6430 new_str.push(c);
6431 new_str
6432 }
6433 Value::String(ref add_s) => {
6434 let mut new_str = (**s).clone();
6435 new_str.push_str(add_s);
6436 new_str
6437 }
6438 _ => return Err(RuntimeError::new("push expects char or string argument")),
6439 };
6440 let new_val = Value::String(Rc::new(new_s));
6441
6442 if let Some(root_var) = Self::extract_root_var(receiver) {
6444 self.environment
6445 .borrow_mut()
6446 .set(&root_var, new_val.clone())?;
6447 return Ok(new_val);
6449 }
6450
6451 if let Expr::Field {
6453 expr: base_expr,
6454 field: field_ident,
6455 } = receiver
6456 {
6457 let base = self.evaluate(base_expr)?;
6458 if let Value::Struct { fields, .. } = base {
6459 fields
6460 .borrow_mut()
6461 .insert(field_ident.name.clone(), new_val.clone());
6462 return Ok(new_val);
6464 }
6465 }
6466 return Ok(new_val);
6468 }
6469 }
6470
6471 let recv_raw = self.evaluate(receiver)?;
6472 let recv = Self::unwrap_value(&recv_raw).clone();
6474
6475 static METHOD_COUNT: std::sync::atomic::AtomicUsize =
6477 std::sync::atomic::AtomicUsize::new(0);
6478 let count = METHOD_COUNT.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
6479 if count < 500 {
6480 let recv_type = match &recv {
6481 Value::Struct { name, .. } => format!("Struct({})", name),
6482 Value::String(s) => format!(
6483 "String('{}')",
6484 if s.len() <= 20 { s.as_str() } else { "<long>" }
6485 ),
6486 Value::Ref(r) => format!("Ref({:?})", std::mem::discriminant(&*r.borrow())),
6487 other => format!("{:?}", std::mem::discriminant(other)),
6488 };
6489 if recv_type.contains("Lexer")
6490 || method.name.contains("keyword")
6491 || method.name.contains("lex")
6492 {
6493 crate::sigil_debug!("DEBUG method #{}: {}.{}()", count, recv_type, method.name);
6494 }
6495 }
6496 let arg_values: Vec<Value> = args
6497 .iter()
6498 .map(|a| self.evaluate(a))
6499 .collect::<Result<_, _>>()?;
6500
6501 if method.name == "cloned" || method.name == "clone" {
6503 let recv_type = match &recv {
6504 Value::Struct { name, .. } => format!("Struct({})", name),
6505 Value::Variant {
6506 enum_name,
6507 variant_name,
6508 ..
6509 } => format!("Variant({}::{})", enum_name, variant_name),
6510 Value::String(_) => "String".to_string(),
6511 Value::Ref(r) => format!("Ref({:?})", std::mem::discriminant(&*r.borrow())),
6512 Value::Null => "Null".to_string(),
6513 other => format!("{:?}", std::mem::discriminant(other)),
6514 };
6515 crate::sigil_debug!("DEBUG {}: recv_type={}", method.name, recv_type);
6516 }
6517
6518 if method.name == "as_str" {
6520 let recv_unwrapped = Self::unwrap_all(&recv);
6521 if let Value::String(s) = &recv_unwrapped {
6522 crate::sigil_debug!("DEBUG as_str CALL: recv='{}' len={}", s, s.len());
6523 } else {
6524 crate::sigil_debug!("DEBUG as_str CALL: recv={:?} (not string)", recv_unwrapped);
6525 }
6526 }
6527
6528 if method.name == "keyword_or_ident" {
6530 let recv_type = match &recv {
6531 Value::Struct { name, .. } => format!("Struct({})", name),
6532 Value::String(_) => "String".to_string(),
6533 Value::Ref(r) => format!(
6534 "Ref({})",
6535 match &*r.borrow() {
6536 Value::Struct { name, .. } => format!("Struct({})", name),
6537 other => format!("{:?}", std::mem::discriminant(other)),
6538 }
6539 ),
6540 other => format!("{:?}", std::mem::discriminant(other)),
6541 };
6542 crate::sigil_debug!("DEBUG keyword_or_ident: recv_type={}", recv_type);
6543 }
6544
6545 for arg in &arg_values {
6547 let unwrapped = Self::unwrap_all(arg);
6548 if let Value::String(s) = &unwrapped {
6549 if **s == "fn" {
6550 let recv_type = match &recv {
6551 Value::Struct { name, .. } => format!("Struct({})", name),
6552 Value::String(_) => "String".to_string(),
6553 Value::Ref(_) => "Ref".to_string(),
6554 other => format!("{:?}", std::mem::discriminant(other)),
6555 };
6556 crate::sigil_debug!(
6557 "DEBUG method call with 'fn': method={}, recv_type={}",
6558 method.name,
6559 recv_type
6560 );
6561 }
6562 }
6563 }
6564
6565 match (&recv, method.name.as_str()) {
6567 (Value::Array(arr), "len") => Ok(Value::Int(arr.borrow().len() as i64)),
6568 (Value::Array(arr), "push") => {
6569 if arg_values.len() != 1 {
6570 return Err(RuntimeError::new("push expects 1 argument"));
6571 }
6572 if let Some(var_name) = Self::extract_root_var(receiver) {
6574 if let Some((type_name, type_params)) = self.var_types.borrow().get(&var_name) {
6575 if type_name == "Vec" && !type_params.is_empty() {
6576 let expected_type = &type_params[0];
6577 let actual_type = self.value_type_name(&arg_values[0]);
6578 if &actual_type != expected_type {
6579 return Err(RuntimeError::new(format!(
6580 "type mismatch: expected Vec<{}>.push({}), found {}",
6581 expected_type, expected_type, actual_type
6582 )));
6583 }
6584 }
6585 }
6586 }
6587 arr.borrow_mut().push(arg_values[0].clone());
6588 Ok(Value::Null)
6589 }
6590 (Value::Array(arr), "pop") => arr
6591 .borrow_mut()
6592 .pop()
6593 .ok_or_else(|| RuntimeError::new("pop on empty array")),
6594 (Value::Array(arr), "extend") => {
6595 if arg_values.len() != 1 {
6596 return Err(RuntimeError::new("extend expects 1 argument"));
6597 }
6598 match &arg_values[0] {
6599 Value::Array(other) => {
6600 arr.borrow_mut().extend(other.borrow().iter().cloned());
6601 Ok(Value::Null)
6602 }
6603 _ => Err(RuntimeError::new("extend expects array argument")),
6604 }
6605 }
6606 (Value::Array(arr), "reverse") => {
6607 let mut v = arr.borrow().clone();
6608 v.reverse();
6609 Ok(Value::Array(Rc::new(RefCell::new(v))))
6610 }
6611 (Value::Array(arr), "skip") => {
6612 let n = match arg_values.first() {
6613 Some(Value::Int(i)) => *i as usize,
6614 _ => 1,
6615 };
6616 let v: Vec<Value> = arr.borrow().iter().skip(n).cloned().collect();
6617 Ok(Value::Array(Rc::new(RefCell::new(v))))
6618 }
6619 (Value::Array(arr), "take") => {
6620 let n = match arg_values.first() {
6621 Some(Value::Int(i)) => *i as usize,
6622 _ => 1,
6623 };
6624 let v: Vec<Value> = arr.borrow().iter().take(n).cloned().collect();
6625 Ok(Value::Array(Rc::new(RefCell::new(v))))
6626 }
6627 (Value::Array(arr), "step_by") => {
6628 let n = match arg_values.first() {
6629 Some(Value::Int(i)) if *i > 0 => *i as usize,
6630 _ => 1,
6631 };
6632 let v: Vec<Value> = arr.borrow().iter().step_by(n).cloned().collect();
6633 Ok(Value::Array(Rc::new(RefCell::new(v))))
6634 }
6635 (Value::Array(arr), "contains") => {
6636 if arg_values.len() != 1 {
6637 return Err(RuntimeError::new("contains expects 1 argument"));
6638 }
6639 let target = &arg_values[0];
6640 let found = arr.borrow().iter().any(|v| self.values_equal(v, target));
6641 Ok(Value::Bool(found))
6642 }
6643 (Value::Tuple(t), "to_string") | (Value::Tuple(t), "string") => {
6645 let s: Vec<String> = t.iter().map(|v| format!("{}", v)).collect();
6646 Ok(Value::String(Rc::new(format!("({})", s.join(", ")))))
6647 }
6648 (Value::Tuple(t), "len") => Ok(Value::Int(t.len() as i64)),
6649 (Value::Tuple(t), "first") => t
6650 .first()
6651 .cloned()
6652 .ok_or_else(|| RuntimeError::new("empty tuple")),
6653 (Value::Tuple(t), "last") => t
6654 .last()
6655 .cloned()
6656 .ok_or_else(|| RuntimeError::new("empty tuple")),
6657 (Value::Tuple(t), "get") => {
6658 let idx = match arg_values.first() {
6659 Some(Value::Int(i)) => *i as usize,
6660 _ => return Err(RuntimeError::new("get expects integer index")),
6661 };
6662 t.get(idx)
6663 .cloned()
6664 .ok_or_else(|| RuntimeError::new("tuple index out of bounds"))
6665 }
6666 (Value::Array(arr), "first") | (Value::Array(arr), "next") => {
6667 Ok(arr.borrow().first().cloned().unwrap_or(Value::Null))
6668 }
6669 (Value::Array(arr), "last") => arr
6670 .borrow()
6671 .last()
6672 .cloned()
6673 .ok_or_else(|| RuntimeError::new("empty array")),
6674 (Value::Array(arr), "iter") | (Value::Array(arr), "into_iter") => {
6675 Ok(Value::Array(arr.clone()))
6677 }
6678 (Value::Array(arr), "map") => {
6679 if arg_values.len() != 1 {
6681 return Err(RuntimeError::new("map expects 1 argument (closure)"));
6682 }
6683 match &arg_values[0] {
6684 Value::Function(f) => {
6685 let mut results = Vec::new();
6686 for val in arr.borrow().iter() {
6687 let result = self.call_function(f, vec![val.clone()])?;
6688 results.push(result);
6689 }
6690 Ok(Value::Array(Rc::new(RefCell::new(results))))
6691 }
6692 _ => Err(RuntimeError::new("map expects closure argument")),
6693 }
6694 }
6695 (Value::Array(arr), "filter") => {
6696 if arg_values.len() != 1 {
6698 return Err(RuntimeError::new("filter expects 1 argument (closure)"));
6699 }
6700 match &arg_values[0] {
6701 Value::Function(f) => {
6702 let mut results = Vec::new();
6703 for val in arr.borrow().iter() {
6704 let keep = self.call_function(f, vec![val.clone()])?;
6705 if matches!(keep, Value::Bool(true)) {
6706 results.push(val.clone());
6707 }
6708 }
6709 Ok(Value::Array(Rc::new(RefCell::new(results))))
6710 }
6711 _ => Err(RuntimeError::new("filter expects closure argument")),
6712 }
6713 }
6714 (Value::Array(arr), "any") => {
6715 if arg_values.len() != 1 {
6717 return Err(RuntimeError::new("any expects 1 argument (closure)"));
6718 }
6719 match &arg_values[0] {
6720 Value::Function(f) => {
6721 for val in arr.borrow().iter() {
6722 let result = self.call_function(f, vec![val.clone()])?;
6723 if matches!(result, Value::Bool(true)) {
6724 return Ok(Value::Bool(true));
6725 }
6726 }
6727 Ok(Value::Bool(false))
6728 }
6729 _ => Err(RuntimeError::new("any expects closure argument")),
6730 }
6731 }
6732 (Value::Array(arr), "all") => {
6733 if arg_values.len() != 1 {
6735 return Err(RuntimeError::new("all expects 1 argument (closure)"));
6736 }
6737 match &arg_values[0] {
6738 Value::Function(f) => {
6739 for val in arr.borrow().iter() {
6740 let result = self.call_function(f, vec![val.clone()])?;
6741 if !matches!(result, Value::Bool(true)) {
6742 return Ok(Value::Bool(false));
6743 }
6744 }
6745 Ok(Value::Bool(true))
6746 }
6747 _ => Err(RuntimeError::new("all expects closure argument")),
6748 }
6749 }
6750 (Value::Array(arr), "find") => {
6751 if arg_values.len() != 1 {
6753 return Err(RuntimeError::new("find expects 1 argument (closure)"));
6754 }
6755 match &arg_values[0] {
6756 Value::Function(f) => {
6757 for val in arr.borrow().iter() {
6758 let result = self.call_function(f, vec![val.clone()])?;
6759 if matches!(result, Value::Bool(true)) {
6760 return Ok(Value::Variant {
6761 enum_name: "Option".to_string(),
6762 variant_name: "Some".to_string(),
6763 fields: Some(Rc::new(vec![val.clone()])),
6764 });
6765 }
6766 }
6767 Ok(Value::Variant {
6768 enum_name: "Option".to_string(),
6769 variant_name: "None".to_string(),
6770 fields: None,
6771 })
6772 }
6773 _ => Err(RuntimeError::new("find expects closure argument")),
6774 }
6775 }
6776 (Value::Array(arr), "enumerate") => {
6777 let enumerated: Vec<Value> = arr
6779 .borrow()
6780 .iter()
6781 .enumerate()
6782 .map(|(i, v)| Value::Tuple(Rc::new(vec![Value::Int(i as i64), v.clone()])))
6783 .collect();
6784 Ok(Value::Array(Rc::new(RefCell::new(enumerated))))
6785 }
6786 (Value::Array(arr), "zip") => {
6787 if arg_values.len() != 1 {
6789 return Err(RuntimeError::new("zip expects 1 argument"));
6790 }
6791 match &arg_values[0] {
6792 Value::Array(other) => {
6793 let a = arr.borrow();
6794 let b = other.borrow();
6795 let zipped: Vec<Value> = a
6796 .iter()
6797 .zip(b.iter())
6798 .map(|(x, y)| Value::Tuple(Rc::new(vec![x.clone(), y.clone()])))
6799 .collect();
6800 Ok(Value::Array(Rc::new(RefCell::new(zipped))))
6801 }
6802 _ => Err(RuntimeError::new("zip expects array argument")),
6803 }
6804 }
6805 (Value::String(s), "len") => Ok(Value::Int(s.len() as i64)),
6806 (Value::String(s), "chars") => {
6807 let chars: Vec<Value> = s.chars().map(Value::Char).collect();
6808 Ok(Value::Array(Rc::new(RefCell::new(chars))))
6809 }
6810 (Value::String(s), "contains") => {
6811 if arg_values.len() != 1 {
6812 return Err(RuntimeError::new("contains expects 1 argument"));
6813 }
6814 match &arg_values[0] {
6815 Value::String(sub) => Ok(Value::Bool(s.contains(sub.as_str()))),
6816 Value::Char(c) => Ok(Value::Bool(s.contains(*c))),
6817 Value::Ref(inner) => {
6818 if let Value::String(sub) = &*inner.borrow() {
6819 Ok(Value::Bool(s.contains(sub.as_str())))
6820 } else {
6821 Err(RuntimeError::new("contains expects string or char"))
6822 }
6823 }
6824 _ => Err(RuntimeError::new("contains expects string or char")),
6825 }
6826 }
6827 (Value::String(s), "as_str") => {
6828 if s.len() <= 10 {
6829 crate::sigil_debug!("DEBUG as_str: '{}'", s);
6830 }
6831 Ok(Value::String(s.clone()))
6832 }
6833 (Value::String(s), "to_string") => Ok(Value::String(s.clone())),
6834 (Value::String(s), "into") => Ok(Value::String(s.clone())), (Value::String(s), "starts_with") => {
6836 if arg_values.len() != 1 {
6837 return Err(RuntimeError::new("starts_with expects 1 argument"));
6838 }
6839 match &arg_values[0] {
6840 Value::String(prefix) => Ok(Value::Bool(s.starts_with(prefix.as_str()))),
6841 _ => Err(RuntimeError::new("starts_with expects string")),
6842 }
6843 }
6844 (Value::String(s), "ends_with") => {
6845 if arg_values.len() != 1 {
6846 return Err(RuntimeError::new("ends_with expects 1 argument"));
6847 }
6848 match &arg_values[0] {
6849 Value::String(suffix) => Ok(Value::Bool(s.ends_with(suffix.as_str()))),
6850 _ => Err(RuntimeError::new("ends_with expects string")),
6851 }
6852 }
6853 (Value::String(s), "strip_prefix") => {
6854 if arg_values.len() != 1 {
6855 return Err(RuntimeError::new("strip_prefix expects 1 argument"));
6856 }
6857 match &arg_values[0] {
6858 Value::String(prefix) => match s.strip_prefix(prefix.as_str()) {
6859 Some(stripped) => Ok(Value::String(Rc::new(stripped.to_string()))),
6860 None => Ok(Value::Null),
6861 },
6862 _ => Err(RuntimeError::new("strip_prefix expects string")),
6863 }
6864 }
6865 (Value::String(s), "strip_suffix") => {
6866 if arg_values.len() != 1 {
6867 return Err(RuntimeError::new("strip_suffix expects 1 argument"));
6868 }
6869 match &arg_values[0] {
6870 Value::String(suffix) => match s.strip_suffix(suffix.as_str()) {
6871 Some(stripped) => Ok(Value::String(Rc::new(stripped.to_string()))),
6872 None => Ok(Value::Null),
6873 },
6874 _ => Err(RuntimeError::new("strip_suffix expects string")),
6875 }
6876 }
6877 (Value::String(s), "is_empty") => Ok(Value::Bool(s.is_empty())),
6878 (Value::String(s), "find") => {
6879 if arg_values.len() != 1 {
6880 return Err(RuntimeError::new("find expects 1 argument"));
6881 }
6882 match &arg_values[0] {
6883 Value::Char(c) => match s.find(*c) {
6884 Some(idx) => Ok(Value::Variant {
6885 enum_name: "Option".to_string(),
6886 variant_name: "Some".to_string(),
6887 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
6888 }),
6889 None => Ok(Value::Variant {
6890 enum_name: "Option".to_string(),
6891 variant_name: "None".to_string(),
6892 fields: None,
6893 }),
6894 },
6895 Value::String(pattern) => match s.find(pattern.as_str()) {
6896 Some(idx) => Ok(Value::Variant {
6897 enum_name: "Option".to_string(),
6898 variant_name: "Some".to_string(),
6899 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
6900 }),
6901 None => Ok(Value::Variant {
6902 enum_name: "Option".to_string(),
6903 variant_name: "None".to_string(),
6904 fields: None,
6905 }),
6906 },
6907 Value::Function(f) => {
6908 for (idx, c) in s.chars().enumerate() {
6909 let result = self.call_function(f, vec![Value::Char(c)])?;
6910 if let Value::Bool(true) = result {
6911 return Ok(Value::Variant {
6912 enum_name: "Option".to_string(),
6913 variant_name: "Some".to_string(),
6914 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
6915 });
6916 }
6917 }
6918 Ok(Value::Variant {
6919 enum_name: "Option".to_string(),
6920 variant_name: "None".to_string(),
6921 fields: None,
6922 })
6923 }
6924 _ => Err(RuntimeError::new("find expects a char, string, or closure")),
6925 }
6926 }
6927 (Value::String(s), "clone") => Ok(Value::String(Rc::new((**s).clone()))),
6928 (Value::String(s), "concat") => {
6929 if arg_values.len() != 1 {
6930 return Err(RuntimeError::new("concat expects 1 argument"));
6931 }
6932 match &arg_values[0] {
6933 Value::String(other) => {
6934 let mut result = (**s).clone();
6935 result.push_str(other);
6936 Ok(Value::String(Rc::new(result)))
6937 }
6938 _ => Err(RuntimeError::new("concat expects string argument")),
6939 }
6940 }
6941 (Value::String(s), "as_ptr") => {
6942 Ok(Value::String(s.clone()))
6944 }
6945 (Value::String(_), "is_null") => Ok(Value::Bool(false)),
6946 (Value::Null, "is_null") => Ok(Value::Bool(true)),
6947 (Value::String(s), "char_at") => {
6948 if arg_values.len() != 1 {
6949 return Err(RuntimeError::new("char_at expects 1 argument"));
6950 }
6951 let idx = match &arg_values[0] {
6952 Value::Int(i) => *i as usize,
6953 _ => return Err(RuntimeError::new("char_at expects integer index")),
6954 };
6955 if idx < s.len() {
6958 let remaining = &s[idx..];
6960 match remaining.chars().next() {
6961 Some(c) => Ok(Value::Char(c)),
6962 None => Ok(Value::Null),
6963 }
6964 } else {
6965 Ok(Value::Null) }
6967 }
6968 (Value::String(s), "chars") => {
6969 let chars: Vec<Value> = s.chars().map(Value::Char).collect();
6970 Ok(Value::Array(Rc::new(RefCell::new(chars))))
6971 }
6972 (Value::String(s), "bytes") => {
6973 let bytes: Vec<Value> = s.bytes().map(|b| Value::Int(b as i64)).collect();
6974 Ok(Value::Array(Rc::new(RefCell::new(bytes))))
6975 }
6976 (Value::String(s), "split") => {
6977 if arg_values.len() != 1 {
6978 return Err(RuntimeError::new("split expects 1 argument"));
6979 }
6980 match &arg_values[0] {
6981 Value::String(sep) => {
6982 let parts: Vec<Value> = s
6983 .split(sep.as_str())
6984 .map(|p| Value::String(Rc::new(p.to_string())))
6985 .collect();
6986 Ok(Value::Array(Rc::new(RefCell::new(parts))))
6987 }
6988 Value::Char(sep) => {
6989 let parts: Vec<Value> = s
6990 .split(*sep)
6991 .map(|p| Value::String(Rc::new(p.to_string())))
6992 .collect();
6993 Ok(Value::Array(Rc::new(RefCell::new(parts))))
6994 }
6995 _ => Err(RuntimeError::new("split expects string or char separator")),
6996 }
6997 }
6998 (Value::Char(c), "len_utf8") => Ok(Value::Int(c.len_utf8() as i64)),
7000 (Value::Char(c), "is_alphabetic") => Ok(Value::Bool(c.is_alphabetic())),
7001 (Value::Char(c), "is_alphanumeric") => Ok(Value::Bool(c.is_alphanumeric())),
7002 (Value::Char(c), "is_ascii_alphanumeric") => Ok(Value::Bool(c.is_ascii_alphanumeric())),
7003 (Value::Char(c), "is_ascii_alphabetic") => Ok(Value::Bool(c.is_ascii_alphabetic())),
7004 (Value::Char(c), "is_ascii_digit") => Ok(Value::Bool(c.is_ascii_digit())),
7005 (Value::Char(c), "is_ascii_hexdigit") => Ok(Value::Bool(c.is_ascii_hexdigit())),
7006 (Value::Char(c), "is_ascii") => Ok(Value::Bool(c.is_ascii())),
7007 (Value::Char(c), "is_digit") => {
7008 let radix = if arg_values.is_empty() {
7009 10
7010 } else {
7011 match &arg_values[0] {
7012 Value::Int(n) => *n as u32,
7013 _ => 10,
7014 }
7015 };
7016 Ok(Value::Bool(c.is_digit(radix)))
7017 }
7018 (Value::Char(c), "is_numeric") => Ok(Value::Bool(c.is_numeric())),
7019 (Value::Char(c), "is_whitespace") => Ok(Value::Bool(c.is_whitespace())),
7020 (Value::Char(c), "is_uppercase") => Ok(Value::Bool(c.is_uppercase())),
7021 (Value::Char(c), "is_lowercase") => Ok(Value::Bool(c.is_lowercase())),
7022 (Value::Char(c), "to_uppercase") => {
7023 let upper: String = c.to_uppercase().collect();
7024 Ok(Value::String(Rc::new(upper)))
7025 }
7026 (Value::Char(c), "to_lowercase") => {
7027 let lower: String = c.to_lowercase().collect();
7028 Ok(Value::String(Rc::new(lower)))
7029 }
7030 (Value::Char(c), "to_string") => Ok(Value::String(Rc::new(c.to_string()))),
7031 (Value::Char(c), "to_digit") => {
7032 let radix = if arg_values.is_empty() {
7033 10
7034 } else {
7035 match &arg_values[0] {
7036 Value::Int(n) => *n as u32,
7037 _ => 10,
7038 }
7039 };
7040 match c.to_digit(radix) {
7041 Some(d) => Ok(Value::Int(d as i64)),
7042 None => Ok(Value::Null),
7043 }
7044 }
7045 (Value::Char(c), "to_ascii_uppercase") => Ok(Value::Char(c.to_ascii_uppercase())),
7046 (Value::Char(c), "to_ascii_lowercase") => Ok(Value::Char(c.to_ascii_lowercase())),
7047 (Value::Char(c), "clone") => Ok(Value::Char(*c)),
7048 (Value::String(s), "upper")
7049 | (Value::String(s), "uppercase")
7050 | (Value::String(s), "to_uppercase") => Ok(Value::String(Rc::new(s.to_uppercase()))),
7051 (Value::String(s), "lower")
7052 | (Value::String(s), "lowercase")
7053 | (Value::String(s), "to_lowercase") => Ok(Value::String(Rc::new(s.to_lowercase()))),
7054 (Value::String(s), "trim") => Ok(Value::String(Rc::new(s.trim().to_string()))),
7055 (Value::String(s), "len") => Ok(Value::Int(s.len() as i64)),
7056 (Value::String(s), "is_empty") => Ok(Value::Bool(s.is_empty())),
7057 (Value::String(s), "exists") => {
7059 Ok(Value::Bool(std::path::Path::new(s.as_str()).exists()))
7060 }
7061 (Value::String(s), "is_dir") => {
7062 Ok(Value::Bool(std::path::Path::new(s.as_str()).is_dir()))
7063 }
7064 (Value::String(s), "is_file") => {
7065 Ok(Value::Bool(std::path::Path::new(s.as_str()).is_file()))
7066 }
7067 (Value::String(s), "join") => {
7068 if arg_values.len() != 1 {
7070 return Err(RuntimeError::new(&format!(
7071 "join expects 1 argument, got {}",
7072 arg_values.len()
7073 )));
7074 }
7075 let other = match &arg_values[0] {
7076 Value::String(s2) => s2.as_str().to_string(),
7077 other => {
7078 return Err(RuntimeError::new(&format!(
7079 "join expects String argument, got {:?}",
7080 other
7081 )))
7082 }
7083 };
7084 let path = std::path::Path::new(s.as_str()).join(&other);
7085 Ok(Value::String(Rc::new(path.to_string_lossy().to_string())))
7086 }
7087 (Value::String(s), "parent") => {
7088 let path = std::path::Path::new(s.as_str());
7090 match path.parent() {
7091 Some(p) => Ok(Value::String(Rc::new(p.to_string_lossy().to_string()))),
7092 None => Ok(Value::Null),
7093 }
7094 }
7095 (Value::String(s), "file_name") => {
7096 let path = std::path::Path::new(s.as_str());
7098 match path.file_name() {
7099 Some(n) => Ok(Value::String(Rc::new(n.to_string_lossy().to_string()))),
7100 None => Ok(Value::Null),
7101 }
7102 }
7103 (Value::String(s), "extension") => {
7104 let path = std::path::Path::new(s.as_str());
7106 match path.extension() {
7107 Some(e) => Ok(Value::String(Rc::new(e.to_string_lossy().to_string()))),
7108 None => Ok(Value::Null),
7109 }
7110 }
7111 (Value::String(_), "and_then") | (Value::String(_), "or_else") => {
7113 Ok(recv.clone())
7115 }
7116 (Value::String(s), "first") => s
7117 .chars()
7118 .next()
7119 .map(Value::Char)
7120 .ok_or_else(|| RuntimeError::new("empty string")),
7121 (Value::String(s), "last") => s
7122 .chars()
7123 .last()
7124 .map(Value::Char)
7125 .ok_or_else(|| RuntimeError::new("empty string")),
7126 (Value::Array(arr), "is_empty") => Ok(Value::Bool(arr.borrow().is_empty())),
7127 (Value::Array(arr), "clone") => {
7128 Ok(Value::Array(Rc::new(RefCell::new(arr.borrow().clone()))))
7129 }
7130 (Value::Array(arr), "collect") => {
7131 Ok(Value::Array(arr.clone()))
7134 }
7135 (Value::Array(arr), "join") => {
7136 let separator = if arg_values.is_empty() {
7137 String::new()
7138 } else {
7139 match &arg_values[0] {
7140 Value::String(s) => (**s).clone(),
7141 _ => return Err(RuntimeError::new("join separator must be string")),
7142 }
7143 };
7144 let parts: Vec<String> =
7145 arr.borrow().iter().map(|v| self.format_value(v)).collect();
7146 Ok(Value::String(Rc::new(parts.join(&separator))))
7147 }
7148 (Value::Map(m), "insert") => {
7150 if arg_values.len() != 2 {
7151 return Err(RuntimeError::new("insert expects 2 arguments"));
7152 }
7153 let key = match &arg_values[0] {
7154 Value::String(s) => (**s).clone(),
7155 _ => format!("{}", arg_values[0]),
7156 };
7157 m.borrow_mut().insert(key, arg_values[1].clone());
7158 Ok(Value::Null)
7159 }
7160 (Value::Map(m), "get") => {
7161 if arg_values.len() != 1 {
7162 return Err(RuntimeError::new("get expects 1 argument"));
7163 }
7164 let key = match &arg_values[0] {
7165 Value::String(s) => (**s).clone(),
7166 _ => format!("{}", arg_values[0]),
7167 };
7168 Ok(m.borrow().get(&key).cloned().unwrap_or(Value::Null))
7169 }
7170 (Value::Map(m), "contains_key") => {
7171 if arg_values.len() != 1 {
7172 return Err(RuntimeError::new("contains_key expects 1 argument"));
7173 }
7174 let key = match &arg_values[0] {
7175 Value::String(s) => (**s).clone(),
7176 _ => format!("{}", arg_values[0]),
7177 };
7178 Ok(Value::Bool(m.borrow().contains_key(&key)))
7179 }
7180 (Value::Map(m), "len") => Ok(Value::Int(m.borrow().len() as i64)),
7181 (Value::Map(m), "is_empty") => Ok(Value::Bool(m.borrow().is_empty())),
7182 (Value::Map(m), "keys") => {
7183 let keys: Vec<Value> = m
7184 .borrow()
7185 .keys()
7186 .map(|k| Value::String(Rc::new(k.clone())))
7187 .collect();
7188 Ok(Value::Array(Rc::new(RefCell::new(keys))))
7189 }
7190 (Value::Map(m), "values") => {
7191 let values: Vec<Value> = m.borrow().values().cloned().collect();
7192 Ok(Value::Array(Rc::new(RefCell::new(values))))
7193 }
7194 (Value::Ref(r), "cloned") => {
7196 Ok(r.borrow().clone())
7198 }
7199 (Value::Ref(r), "borrow") => {
7200 Ok(recv.clone())
7202 }
7203 (Value::Ref(r), "borrow_mut") => {
7204 Ok(recv.clone())
7206 }
7207 (Value::Ref(r), _) => {
7209 let inner = r.borrow().clone();
7211 if let Value::Struct { name, fields } = &inner {
7212 let qualified_name = format!("{}·{}", name, method.name);
7214 let func = self
7215 .globals
7216 .borrow()
7217 .get(&qualified_name)
7218 .map(|v| v.clone());
7219 if let Some(func) = func {
7220 if let Value::Function(f) = func {
7221 let old_self_type = self.current_self_type.take();
7223 self.current_self_type = Some(name.clone());
7224
7225 let mut all_args = vec![recv.clone()];
7227 all_args.extend(arg_values.clone());
7228 let result = self.call_function(&f, all_args);
7229
7230 self.current_self_type = old_self_type;
7232 return result;
7233 } else if let Value::BuiltIn(b) = func {
7234 let mut all_args = vec![recv.clone()];
7235 all_args.extend(arg_values.clone());
7236 return (b.func)(self, all_args);
7237 }
7238 }
7239
7240 if name == "Self" {
7242 let field_names: Vec<String> = fields.borrow().keys().cloned().collect();
7243
7244 for (type_name, type_def) in &self.types {
7246 if let TypeDef::Struct(struct_def) = type_def {
7247 let def_fields: Vec<String> = match &struct_def.fields {
7248 crate::ast::StructFields::Named(fs) => {
7249 fs.iter().map(|f| f.name.name.clone()).collect()
7250 }
7251 _ => continue,
7252 };
7253
7254 let matches = field_names.iter().all(|f| def_fields.contains(f));
7256 if matches {
7257 let qualified_name = format!("{}·{}", type_name, method.name);
7258 let func = self
7259 .globals
7260 .borrow()
7261 .get(&qualified_name)
7262 .map(|v| v.clone());
7263 if let Some(func) = func {
7264 if let Value::Function(f) = func {
7265 let old_self_type = self.current_self_type.take();
7267 self.current_self_type = Some(type_name.clone());
7268
7269 let mut all_args = vec![recv.clone()];
7270 all_args.extend(arg_values.clone());
7271 let result = self.call_function(&f, all_args);
7272
7273 self.current_self_type = old_self_type;
7275 return result;
7276 } else if let Value::BuiltIn(b) = func {
7277 let mut all_args = vec![recv.clone()];
7278 all_args.extend(arg_values.clone());
7279 return (b.func)(self, all_args);
7280 }
7281 }
7282 }
7283 }
7284 }
7285 }
7286
7287 if name == "PathBuf" || name == "Path" {
7289 if let Some(Value::String(path)) = fields.borrow().get("path").cloned() {
7290 match method.name.as_str() {
7291 "exists" => {
7292 return Ok(Value::Bool(
7293 std::path::Path::new(path.as_str()).exists(),
7294 ))
7295 }
7296 "is_dir" => {
7297 return Ok(Value::Bool(
7298 std::path::Path::new(path.as_str()).is_dir(),
7299 ))
7300 }
7301 "is_file" => {
7302 return Ok(Value::Bool(
7303 std::path::Path::new(path.as_str()).is_file(),
7304 ))
7305 }
7306 "join" => {
7307 if let Some(Value::String(other)) = arg_values.first() {
7308 let new_path = std::path::Path::new(path.as_str())
7309 .join(other.as_str());
7310 let mut new_fields = std::collections::HashMap::new();
7311 new_fields.insert(
7312 "path".to_string(),
7313 Value::String(Rc::new(
7314 new_path.to_string_lossy().to_string(),
7315 )),
7316 );
7317 return Ok(Value::Struct {
7318 name: "PathBuf".to_string(),
7319 fields: Rc::new(RefCell::new(new_fields)),
7320 });
7321 }
7322 return Err(RuntimeError::new("join requires string argument"));
7323 }
7324 "parent" => {
7325 let p = std::path::Path::new(path.as_str());
7326 return match p.parent() {
7327 Some(par) => {
7328 let mut new_fields = std::collections::HashMap::new();
7329 new_fields.insert(
7330 "path".to_string(),
7331 Value::String(Rc::new(
7332 par.to_string_lossy().to_string(),
7333 )),
7334 );
7335 Ok(Value::Struct {
7336 name: "PathBuf".to_string(),
7337 fields: Rc::new(RefCell::new(new_fields)),
7338 })
7339 }
7340 None => Ok(Value::Null),
7341 };
7342 }
7343 "file_name" => {
7344 let p = std::path::Path::new(path.as_str());
7345 return match p.file_name() {
7346 Some(n) => Ok(Value::String(Rc::new(
7347 n.to_string_lossy().to_string(),
7348 ))),
7349 None => Ok(Value::Null),
7350 };
7351 }
7352 "extension" => {
7353 let p = std::path::Path::new(path.as_str());
7354 return match p.extension() {
7355 Some(e) => Ok(Value::String(Rc::new(
7356 e.to_string_lossy().to_string(),
7357 ))),
7358 None => Ok(Value::Null),
7359 };
7360 }
7361 "to_string" | "display" | "to_str" => {
7362 return Ok(Value::String(path.clone()));
7363 }
7364 _ => {}
7365 }
7366 }
7367 }
7368
7369 return Err(RuntimeError::new(format!(
7371 "no method '{}' on type '&{}'",
7372 method.name,
7373 name
7374 )));
7375 }
7376 if let Value::String(s) = &inner {
7379 match method.name.as_str() {
7380 "to_string" => return Ok(Value::String(s.clone())),
7381 "len" => return Ok(Value::Int(s.len() as i64)),
7382 "is_empty" => return Ok(Value::Bool(s.is_empty())),
7383 "as_str" => return Ok(Value::String(s.clone())),
7384 "starts_with" => {
7385 let prefix = match arg_values.first() {
7386 Some(Value::String(p)) => p.as_str(),
7387 Some(Value::Char(c)) => return Ok(Value::Bool(s.starts_with(*c))),
7388 _ => {
7389 return Err(RuntimeError::new(
7390 "starts_with expects string or char",
7391 ))
7392 }
7393 };
7394 return Ok(Value::Bool(s.starts_with(prefix)));
7395 }
7396 "ends_with" => {
7397 let suffix = match arg_values.first() {
7398 Some(Value::String(p)) => p.as_str(),
7399 Some(Value::Char(c)) => return Ok(Value::Bool(s.ends_with(*c))),
7400 _ => {
7401 return Err(RuntimeError::new(
7402 "ends_with expects string or char",
7403 ))
7404 }
7405 };
7406 return Ok(Value::Bool(s.ends_with(suffix)));
7407 }
7408 "contains" => {
7409 let substr = match arg_values.first() {
7410 Some(Value::String(p)) => p.as_str(),
7411 Some(Value::Char(c)) => return Ok(Value::Bool(s.contains(*c))),
7412 _ => {
7413 return Err(RuntimeError::new(
7414 "contains expects string or char",
7415 ))
7416 }
7417 };
7418 return Ok(Value::Bool(s.contains(substr)));
7419 }
7420 "trim" => return Ok(Value::String(Rc::new(s.trim().to_string()))),
7421 "to_lowercase" => return Ok(Value::String(Rc::new(s.to_lowercase()))),
7422 "to_uppercase" => return Ok(Value::String(Rc::new(s.to_uppercase()))),
7423 "chars" => {
7424 let chars: Vec<Value> = s.chars().map(Value::Char).collect();
7425 return Ok(Value::Array(Rc::new(RefCell::new(chars))));
7426 }
7427 "split" => {
7428 let delim = match arg_values.first() {
7429 Some(Value::String(d)) => d.as_str().to_string(),
7430 Some(Value::Char(c)) => c.to_string(),
7431 _ => " ".to_string(),
7432 };
7433 let parts: Vec<Value> = s
7434 .split(&delim)
7435 .map(|p| Value::String(Rc::new(p.to_string())))
7436 .collect();
7437 return Ok(Value::Array(Rc::new(RefCell::new(parts))));
7438 }
7439 "replace" => {
7440 if arg_values.len() != 2 {
7441 return Err(RuntimeError::new("replace expects 2 arguments"));
7442 }
7443 let from = match &arg_values[0] {
7444 Value::String(f) => f.as_str().to_string(),
7445 Value::Char(c) => c.to_string(),
7446 _ => return Err(RuntimeError::new("replace expects strings")),
7447 };
7448 let to = match &arg_values[1] {
7449 Value::String(t) => t.as_str().to_string(),
7450 Value::Char(c) => c.to_string(),
7451 _ => return Err(RuntimeError::new("replace expects strings")),
7452 };
7453 return Ok(Value::String(Rc::new(s.replace(&from, &to))));
7454 }
7455 _ => {}
7456 }
7457 }
7458 if let Value::Array(arr) = &inner {
7460 match method.name.as_str() {
7461 "len" => return Ok(Value::Int(arr.borrow().len() as i64)),
7462 "is_empty" => return Ok(Value::Bool(arr.borrow().is_empty())),
7463 "push" => {
7464 if arg_values.len() != 1 {
7465 return Err(RuntimeError::new("push expects 1 argument"));
7466 }
7467 if let Some(var_name) = Self::extract_root_var(receiver) {
7469 if let Some((type_name, type_params)) = self.var_types.borrow().get(&var_name) {
7470 if type_name == "Vec" && !type_params.is_empty() {
7471 let expected_type = &type_params[0];
7472 let actual_type = self.value_type_name(&arg_values[0]);
7473 if &actual_type != expected_type {
7474 return Err(RuntimeError::new(format!(
7475 "type mismatch: expected Vec<{}>.push({}), found {}",
7476 expected_type, expected_type, actual_type
7477 )));
7478 }
7479 }
7480 }
7481 }
7482 arr.borrow_mut().push(arg_values[0].clone());
7483 return Ok(Value::Null);
7484 }
7485 "pop" => {
7486 return arr
7487 .borrow_mut()
7488 .pop()
7489 .ok_or_else(|| RuntimeError::new("pop on empty array"));
7490 }
7491 "contains" => {
7492 if arg_values.len() != 1 {
7493 return Err(RuntimeError::new("contains expects 1 argument"));
7494 }
7495 let target = &arg_values[0];
7496 let found = arr.borrow().iter().any(|v| self.values_equal(v, target));
7497 return Ok(Value::Bool(found));
7498 }
7499 "first" | "next" => {
7500 return Ok(arr.borrow().first().cloned().unwrap_or(Value::Null));
7501 }
7502 "last" => {
7503 return arr
7504 .borrow()
7505 .last()
7506 .cloned()
7507 .ok_or_else(|| RuntimeError::new("empty array"));
7508 }
7509 "iter" | "into_iter" => {
7510 return Ok(Value::Array(arr.clone()));
7511 }
7512 "reverse" => {
7513 let mut v = arr.borrow().clone();
7514 v.reverse();
7515 return Ok(Value::Array(Rc::new(RefCell::new(v))));
7516 }
7517 "skip" => {
7518 let n = match arg_values.first() {
7519 Some(Value::Int(i)) => *i as usize,
7520 _ => 1,
7521 };
7522 let v: Vec<Value> = arr.borrow().iter().skip(n).cloned().collect();
7523 return Ok(Value::Array(Rc::new(RefCell::new(v))));
7524 }
7525 "take" => {
7526 let n = match arg_values.first() {
7527 Some(Value::Int(i)) => *i as usize,
7528 _ => 1,
7529 };
7530 let v: Vec<Value> = arr.borrow().iter().take(n).cloned().collect();
7531 return Ok(Value::Array(Rc::new(RefCell::new(v))));
7532 }
7533 "get" => {
7534 let idx = match arg_values.first() {
7535 Some(Value::Int(i)) => *i as usize,
7536 _ => return Err(RuntimeError::new("get expects integer index")),
7537 };
7538 return Ok(arr.borrow().get(idx).cloned().unwrap_or(Value::Null));
7539 }
7540 _ => {}
7541 }
7542 }
7543 if method.name == "clone" {
7545 crate::sigil_debug!(
7546 "DEBUG clone: recv_type=Ref({:?})",
7547 std::mem::discriminant(&inner)
7548 );
7549 return Ok(inner.clone());
7550 }
7551 if method.name == "into" {
7553 return Ok(inner.clone());
7554 }
7555 if method.name == "to_string" {
7557 return Ok(Value::String(Rc::new(format!("{}", inner))));
7558 }
7559 if let Value::Struct { name, fields, .. } = &inner {
7561 if name == "PathBuf" || name == "Path" {
7562 let borrowed = fields.borrow();
7563 if let Some(Value::String(path)) = borrowed.get("path") {
7564 match method.name.as_str() {
7565 "exists" => {
7566 return Ok(Value::Bool(
7567 std::path::Path::new(path.as_str()).exists(),
7568 ))
7569 }
7570 "is_dir" => {
7571 return Ok(Value::Bool(
7572 std::path::Path::new(path.as_str()).is_dir(),
7573 ))
7574 }
7575 "is_file" => {
7576 return Ok(Value::Bool(
7577 std::path::Path::new(path.as_str()).is_file(),
7578 ))
7579 }
7580 "join" => {
7581 if let Some(Value::String(other)) = arg_values.first() {
7582 let new_path = std::path::Path::new(path.as_str())
7583 .join(other.as_str());
7584 let mut new_fields = std::collections::HashMap::new();
7585 new_fields.insert(
7586 "path".to_string(),
7587 Value::String(Rc::new(
7588 new_path.to_string_lossy().to_string(),
7589 )),
7590 );
7591 return Ok(Value::Struct {
7592 name: "PathBuf".to_string(),
7593 fields: Rc::new(RefCell::new(new_fields)),
7594 });
7595 }
7596 return Err(RuntimeError::new("join requires string argument"));
7597 }
7598 "parent" => {
7599 let p = std::path::Path::new(path.as_str());
7600 return match p.parent() {
7601 Some(par) => {
7602 let mut new_fields = std::collections::HashMap::new();
7603 new_fields.insert(
7604 "path".to_string(),
7605 Value::String(Rc::new(
7606 par.to_string_lossy().to_string(),
7607 )),
7608 );
7609 Ok(Value::Struct {
7610 name: "PathBuf".to_string(),
7611 fields: Rc::new(RefCell::new(new_fields)),
7612 })
7613 }
7614 None => Ok(Value::Null),
7615 };
7616 }
7617 "file_name" => {
7618 let p = std::path::Path::new(path.as_str());
7619 return match p.file_name() {
7620 Some(n) => Ok(Value::String(Rc::new(
7621 n.to_string_lossy().to_string(),
7622 ))),
7623 None => Ok(Value::Null),
7624 };
7625 }
7626 "extension" => {
7627 let p = std::path::Path::new(path.as_str());
7628 return match p.extension() {
7629 Some(e) => Ok(Value::String(Rc::new(
7630 e.to_string_lossy().to_string(),
7631 ))),
7632 None => Ok(Value::Null),
7633 };
7634 }
7635 "to_string" | "display" => {
7636 return Ok(Value::String(path.clone()));
7637 }
7638 _ => {}
7639 }
7640 }
7641 }
7642 }
7643 if let Value::String(s) = &inner {
7645 match method.name.as_str() {
7646 "exists" => {
7647 return Ok(Value::Bool(std::path::Path::new(s.as_str()).exists()))
7648 }
7649 "is_dir" => {
7650 return Ok(Value::Bool(std::path::Path::new(s.as_str()).is_dir()))
7651 }
7652 "is_file" => {
7653 return Ok(Value::Bool(std::path::Path::new(s.as_str()).is_file()))
7654 }
7655 "join" => {
7656 if let Some(Value::String(other)) = arg_values.first() {
7657 let path = std::path::Path::new(s.as_str()).join(other.as_str());
7658 return Ok(Value::String(Rc::new(
7659 path.to_string_lossy().to_string(),
7660 )));
7661 }
7662 return Err(RuntimeError::new("join requires string argument"));
7663 }
7664 "parent" => {
7665 let path = std::path::Path::new(s.as_str());
7666 return match path.parent() {
7667 Some(p) => {
7668 Ok(Value::String(Rc::new(p.to_string_lossy().to_string())))
7669 }
7670 None => Ok(Value::Null),
7671 };
7672 }
7673 "file_name" => {
7674 let path = std::path::Path::new(s.as_str());
7675 return match path.file_name() {
7676 Some(n) => {
7677 Ok(Value::String(Rc::new(n.to_string_lossy().to_string())))
7678 }
7679 None => Ok(Value::Null),
7680 };
7681 }
7682 "extension" => {
7683 let path = std::path::Path::new(s.as_str());
7684 return match path.extension() {
7685 Some(e) => {
7686 Ok(Value::String(Rc::new(e.to_string_lossy().to_string())))
7687 }
7688 None => Ok(Value::Null),
7689 };
7690 }
7691 _ => {}
7692 }
7693 }
7694 if let Value::String(_) = inner {
7697 let recv_unwrapped = inner.clone();
7700 match (&recv_unwrapped, method.name.as_str()) {
7701 (Value::String(s), "find") => {
7702 if arg_values.len() != 1 {
7703 return Err(RuntimeError::new("find expects 1 argument"));
7704 }
7705 match &arg_values[0] {
7706 Value::Char(c) => {
7707 return match s.find(*c) {
7708 Some(idx) => Ok(Value::Variant {
7709 enum_name: "Option".to_string(),
7710 variant_name: "Some".to_string(),
7711 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
7712 }),
7713 None => Ok(Value::Variant {
7714 enum_name: "Option".to_string(),
7715 variant_name: "None".to_string(),
7716 fields: None,
7717 }),
7718 }
7719 }
7720 Value::String(pattern) => {
7721 return match s.find(pattern.as_str()) {
7722 Some(idx) => Ok(Value::Variant {
7723 enum_name: "Option".to_string(),
7724 variant_name: "Some".to_string(),
7725 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
7726 }),
7727 None => Ok(Value::Variant {
7728 enum_name: "Option".to_string(),
7729 variant_name: "None".to_string(),
7730 fields: None,
7731 }),
7732 }
7733 }
7734 Value::Function(f) => {
7735 for (idx, c) in s.chars().enumerate() {
7736 let result = self.call_function(f, vec![Value::Char(c)])?;
7737 if let Value::Bool(true) = result {
7738 return Ok(Value::Variant {
7739 enum_name: "Option".to_string(),
7740 variant_name: "Some".to_string(),
7741 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
7742 });
7743 }
7744 }
7745 return Ok(Value::Variant {
7746 enum_name: "Option".to_string(),
7747 variant_name: "None".to_string(),
7748 fields: None,
7749 });
7750 }
7751 _ => {
7752 return Err(RuntimeError::new(
7753 "find expects a char, string, or closure",
7754 ))
7755 }
7756 }
7757 }
7758 (Value::String(s), "trim") => {
7759 return Ok(Value::String(Rc::new(s.trim().to_string())))
7760 }
7761 (Value::String(s), "is_empty") => return Ok(Value::Bool(s.is_empty())),
7762 (Value::String(s), "len") => return Ok(Value::Int(s.len() as i64)),
7763 (Value::String(s), "to_string") => return Ok(Value::String(s.clone())),
7764 (Value::String(s), "chars") => {
7765 let chars: Vec<Value> = s.chars().map(Value::Char).collect();
7766 return Ok(Value::Array(Rc::new(RefCell::new(chars))));
7767 }
7768 (Value::String(s), "starts_with") => {
7769 if let Some(Value::String(prefix)) = arg_values.first() {
7770 return Ok(Value::Bool(s.starts_with(prefix.as_str())));
7771 }
7772 return Err(RuntimeError::new("starts_with expects string argument"));
7773 }
7774 _ => {}
7775 }
7776 }
7777 Err(RuntimeError::new(format!(
7778 "Cannot call method {} on Ref to non-struct",
7779 method.name
7780 )))
7781 }
7782 (Value::Struct { name, fields }, _) => {
7784 if method.name == "clone" {
7786 return Ok(recv.clone());
7788 }
7789 if name == "PathBuf" || name == "Path" {
7791 let borrowed = fields.borrow();
7792 if let Some(Value::String(path)) = borrowed.get("path") {
7793 match method.name.as_str() {
7794 "exists" => {
7795 return Ok(Value::Bool(
7796 std::path::Path::new(path.as_str()).exists(),
7797 ))
7798 }
7799 "is_dir" => {
7800 return Ok(Value::Bool(
7801 std::path::Path::new(path.as_str()).is_dir(),
7802 ))
7803 }
7804 "is_file" => {
7805 return Ok(Value::Bool(
7806 std::path::Path::new(path.as_str()).is_file(),
7807 ))
7808 }
7809 "join" => {
7810 if let Some(Value::String(other)) = arg_values.first() {
7811 let new_path =
7812 std::path::Path::new(path.as_str()).join(other.as_str());
7813 let mut new_fields = std::collections::HashMap::new();
7814 new_fields.insert(
7815 "path".to_string(),
7816 Value::String(Rc::new(
7817 new_path.to_string_lossy().to_string(),
7818 )),
7819 );
7820 return Ok(Value::Struct {
7821 name: "PathBuf".to_string(),
7822 fields: Rc::new(RefCell::new(new_fields)),
7823 });
7824 }
7825 return Err(RuntimeError::new("join requires string argument"));
7826 }
7827 "parent" => {
7828 let p = std::path::Path::new(path.as_str());
7829 return match p.parent() {
7830 Some(par) => {
7831 let mut new_fields = std::collections::HashMap::new();
7832 new_fields.insert(
7833 "path".to_string(),
7834 Value::String(Rc::new(
7835 par.to_string_lossy().to_string(),
7836 )),
7837 );
7838 Ok(Value::Struct {
7839 name: "PathBuf".to_string(),
7840 fields: Rc::new(RefCell::new(new_fields)),
7841 })
7842 }
7843 None => Ok(Value::Null),
7844 };
7845 }
7846 "file_name" => {
7847 let p = std::path::Path::new(path.as_str());
7848 return match p.file_name() {
7849 Some(n) => {
7850 Ok(Value::String(Rc::new(n.to_string_lossy().to_string())))
7851 }
7852 None => Ok(Value::Null),
7853 };
7854 }
7855 "extension" => {
7856 let p = std::path::Path::new(path.as_str());
7857 return match p.extension() {
7858 Some(e) => {
7859 Ok(Value::String(Rc::new(e.to_string_lossy().to_string())))
7860 }
7861 None => Ok(Value::Null),
7862 };
7863 }
7864 "to_string" | "display" => {
7865 return Ok(Value::String(path.clone()));
7866 }
7867 _ => {}
7868 }
7869 }
7870 }
7871 if name == "Rc" {
7873 let borrowed = fields.borrow();
7874 if let Some(value) = borrowed.get("_value") {
7875 match method.name.as_str() {
7876 "clone" => {
7877 let mut new_fields = HashMap::new();
7879 new_fields.insert("_value".to_string(), value.clone());
7880 return Ok(Value::Struct {
7881 name: "Rc".to_string(),
7882 fields: Rc::new(RefCell::new(new_fields)),
7883 });
7884 }
7885 _ => {}
7886 }
7887 }
7888 }
7889 if name == "Cell" {
7891 match method.name.as_str() {
7892 "get" => {
7893 let borrowed = fields.borrow();
7894 if let Some(value) = borrowed.get("_value") {
7895 return Ok(value.clone());
7896 }
7897 return Err(RuntimeError::new("Cell has no value"));
7898 }
7899 "set" => {
7900 if arg_values.len() != 1 {
7901 return Err(RuntimeError::new("set expects 1 argument"));
7902 }
7903 fields
7904 .borrow_mut()
7905 .insert("_value".to_string(), arg_values[0].clone());
7906 return Ok(Value::Null);
7907 }
7908 _ => {}
7909 }
7910 }
7911 if name == "Duration" {
7913 let borrowed = fields.borrow();
7914 let secs = match borrowed.get("secs") {
7915 Some(Value::Int(s)) => *s,
7916 _ => 0,
7917 };
7918 let nanos = match borrowed.get("nanos") {
7919 Some(Value::Int(n)) => *n,
7920 _ => 0,
7921 };
7922 match method.name.as_str() {
7923 "as_secs" => return Ok(Value::Int(secs)),
7924 "as_millis" => return Ok(Value::Int(secs * 1000 + nanos / 1_000_000)),
7925 "as_micros" => return Ok(Value::Int(secs * 1_000_000 + nanos / 1000)),
7926 "as_nanos" => return Ok(Value::Int(secs * 1_000_000_000 + nanos)),
7927 "subsec_nanos" => return Ok(Value::Int(nanos)),
7928 "subsec_millis" => return Ok(Value::Int(nanos / 1_000_000)),
7929 "is_zero" => return Ok(Value::Bool(secs == 0 && nanos == 0)),
7930 _ => {}
7931 }
7932 }
7933 if name == "Mutex" {
7935 match method.name.as_str() {
7936 "lock" => {
7937 let borrowed = fields.borrow();
7940 if let Some(inner) = borrowed.get("__inner__") {
7941 return Ok(Value::Ref(Rc::new(RefCell::new(inner.clone()))));
7943 }
7944 return Err(RuntimeError::new("Mutex has no inner value"));
7945 }
7946 "try_lock" => {
7947 let borrowed = fields.borrow();
7949 if let Some(inner) = borrowed.get("__inner__") {
7950 let guard = Value::Ref(Rc::new(RefCell::new(inner.clone())));
7951 return Ok(Value::Variant {
7952 enum_name: "Option".to_string(),
7953 variant_name: "Some".to_string(),
7954 fields: Some(Rc::new(vec![guard])),
7955 });
7956 }
7957 return Ok(Value::Variant {
7958 enum_name: "Option".to_string(),
7959 variant_name: "None".to_string(),
7960 fields: None,
7961 });
7962 }
7963 "into_inner" => {
7964 let borrowed = fields.borrow();
7966 if let Some(inner) = borrowed.get("__inner__") {
7967 return Ok(inner.clone());
7968 }
7969 return Err(RuntimeError::new("Mutex has no inner value"));
7970 }
7971 "get_mut" => {
7972 let borrowed = fields.borrow();
7974 if let Some(inner) = borrowed.get("__inner__") {
7975 return Ok(Value::Ref(Rc::new(RefCell::new(inner.clone()))));
7976 }
7977 return Err(RuntimeError::new("Mutex has no inner value"));
7978 }
7979 _ => {}
7980 }
7981 }
7982 if name == "RwLock" {
7984 match method.name.as_str() {
7985 "read" => {
7986 let borrowed = fields.borrow();
7988 if let Some(inner) = borrowed.get("__inner__") {
7989 return Ok(Value::Ref(Rc::new(RefCell::new(inner.clone()))));
7990 }
7991 return Err(RuntimeError::new("RwLock has no inner value"));
7992 }
7993 "write" => {
7994 let borrowed = fields.borrow();
7996 if let Some(inner) = borrowed.get("__inner__") {
7997 return Ok(Value::Ref(Rc::new(RefCell::new(inner.clone()))));
7998 }
7999 return Err(RuntimeError::new("RwLock has no inner value"));
8000 }
8001 "try_read" => {
8002 let borrowed = fields.borrow();
8003 if let Some(inner) = borrowed.get("__inner__") {
8004 let guard = Value::Ref(Rc::new(RefCell::new(inner.clone())));
8005 return Ok(Value::Variant {
8006 enum_name: "Option".to_string(),
8007 variant_name: "Some".to_string(),
8008 fields: Some(Rc::new(vec![guard])),
8009 });
8010 }
8011 return Ok(Value::Variant {
8012 enum_name: "Option".to_string(),
8013 variant_name: "None".to_string(),
8014 fields: None,
8015 });
8016 }
8017 "try_write" => {
8018 let borrowed = fields.borrow();
8019 if let Some(inner) = borrowed.get("__inner__") {
8020 let guard = Value::Ref(Rc::new(RefCell::new(inner.clone())));
8021 return Ok(Value::Variant {
8022 enum_name: "Option".to_string(),
8023 variant_name: "Some".to_string(),
8024 fields: Some(Rc::new(vec![guard])),
8025 });
8026 }
8027 return Ok(Value::Variant {
8028 enum_name: "Option".to_string(),
8029 variant_name: "None".to_string(),
8030 fields: None,
8031 });
8032 }
8033 "into_inner" => {
8034 let borrowed = fields.borrow();
8035 if let Some(inner) = borrowed.get("__inner__") {
8036 return Ok(inner.clone());
8037 }
8038 return Err(RuntimeError::new("RwLock has no inner value"));
8039 }
8040 _ => {}
8041 }
8042 }
8043 if name == "AtomicU64"
8045 || name == "AtomicUsize"
8046 || name == "AtomicI64"
8047 || name == "AtomicIsize"
8048 {
8049 match method.name.as_str() {
8050 "load" => {
8051 let borrowed = fields.borrow();
8053 if let Some(val) = borrowed.get("__value__") {
8054 return Ok(val.clone());
8055 }
8056 return Ok(Value::Int(0));
8057 }
8058 "store" => {
8059 if let Some(new_val) = arg_values.first() {
8061 fields
8062 .borrow_mut()
8063 .insert("__value__".to_string(), new_val.clone());
8064 return Ok(Value::Null);
8065 }
8066 return Err(RuntimeError::new("store requires a value"));
8067 }
8068 "fetch_add" => {
8069 if let Some(Value::Int(n)) = arg_values.first() {
8071 let mut borrowed = fields.borrow_mut();
8072 let old = match borrowed.get("__value__") {
8073 Some(Value::Int(v)) => *v,
8074 _ => 0,
8075 };
8076 borrowed.insert("__value__".to_string(), Value::Int(old + n));
8077 return Ok(Value::Int(old));
8078 }
8079 return Err(RuntimeError::new("fetch_add requires integer"));
8080 }
8081 "fetch_sub" => {
8082 if let Some(Value::Int(n)) = arg_values.first() {
8083 let mut borrowed = fields.borrow_mut();
8084 let old = match borrowed.get("__value__") {
8085 Some(Value::Int(v)) => *v,
8086 _ => 0,
8087 };
8088 borrowed.insert("__value__".to_string(), Value::Int(old - n));
8089 return Ok(Value::Int(old));
8090 }
8091 return Err(RuntimeError::new("fetch_sub requires integer"));
8092 }
8093 "swap" => {
8094 if let Some(new_val) = arg_values.first() {
8095 let mut borrowed = fields.borrow_mut();
8096 let old =
8097 borrowed.get("__value__").cloned().unwrap_or(Value::Int(0));
8098 borrowed.insert("__value__".to_string(), new_val.clone());
8099 return Ok(old);
8100 }
8101 return Err(RuntimeError::new("swap requires a value"));
8102 }
8103 "compare_exchange" | "compare_and_swap" => {
8104 if arg_values.len() >= 2 {
8106 let current = &arg_values[0];
8107 let new_val = &arg_values[1];
8108 let mut borrowed = fields.borrow_mut();
8109 let actual =
8110 borrowed.get("__value__").cloned().unwrap_or(Value::Int(0));
8111 if self.values_equal(&actual, current) {
8112 borrowed.insert("__value__".to_string(), new_val.clone());
8113 return Ok(Value::Variant {
8114 enum_name: "Result".to_string(),
8115 variant_name: "Ok".to_string(),
8116 fields: Some(Rc::new(vec![actual])),
8117 });
8118 } else {
8119 return Ok(Value::Variant {
8120 enum_name: "Result".to_string(),
8121 variant_name: "Err".to_string(),
8122 fields: Some(Rc::new(vec![actual])),
8123 });
8124 }
8125 }
8126 return Err(RuntimeError::new(
8127 "compare_exchange requires two arguments",
8128 ));
8129 }
8130 _ => {}
8131 }
8132 }
8133 if name == "AtomicBool" {
8135 match method.name.as_str() {
8136 "load" => {
8137 let borrowed = fields.borrow();
8138 if let Some(val) = borrowed.get("__value__") {
8139 return Ok(val.clone());
8140 }
8141 return Ok(Value::Bool(false));
8142 }
8143 "store" => {
8144 if let Some(new_val) = arg_values.first() {
8145 fields
8146 .borrow_mut()
8147 .insert("__value__".to_string(), new_val.clone());
8148 return Ok(Value::Null);
8149 }
8150 return Err(RuntimeError::new("store requires a value"));
8151 }
8152 "swap" => {
8153 if let Some(new_val) = arg_values.first() {
8154 let mut borrowed = fields.borrow_mut();
8155 let old = borrowed
8156 .get("__value__")
8157 .cloned()
8158 .unwrap_or(Value::Bool(false));
8159 borrowed.insert("__value__".to_string(), new_val.clone());
8160 return Ok(old);
8161 }
8162 return Err(RuntimeError::new("swap requires a value"));
8163 }
8164 "fetch_and" => {
8165 if let Some(Value::Bool(b)) = arg_values.first() {
8166 let mut borrowed = fields.borrow_mut();
8167 let old = match borrowed.get("__value__") {
8168 Some(Value::Bool(v)) => *v,
8169 _ => false,
8170 };
8171 borrowed.insert("__value__".to_string(), Value::Bool(old && *b));
8172 return Ok(Value::Bool(old));
8173 }
8174 return Err(RuntimeError::new("fetch_and requires boolean"));
8175 }
8176 "fetch_or" => {
8177 if let Some(Value::Bool(b)) = arg_values.first() {
8178 let mut borrowed = fields.borrow_mut();
8179 let old = match borrowed.get("__value__") {
8180 Some(Value::Bool(v)) => *v,
8181 _ => false,
8182 };
8183 borrowed.insert("__value__".to_string(), Value::Bool(old || *b));
8184 return Ok(Value::Bool(old));
8185 }
8186 return Err(RuntimeError::new("fetch_or requires boolean"));
8187 }
8188 _ => {}
8189 }
8190 }
8191 if method.name == "to_string" {
8192 let field_str = fields
8194 .borrow()
8195 .iter()
8196 .map(|(k, v)| format!("{}: {}", k, v))
8197 .collect::<Vec<_>>()
8198 .join(", ");
8199 return Ok(Value::String(Rc::new(format!(
8200 "{} {{ {} }}",
8201 name, field_str
8202 ))));
8203 }
8204
8205 if name.starts_with("Pattern::") {
8207 match method.name.as_str() {
8208 "evidentiality" => {
8209 if let Some(ev) = fields.borrow().get("evidentiality") {
8211 return Ok(ev.clone());
8212 }
8213 return Ok(Value::Null);
8214 }
8215 "name" | "binding_name" => {
8216 if let Some(n) = fields.borrow().get("name") {
8218 let result = match &n {
8221 Value::Struct {
8222 fields: inner_fields,
8223 ..
8224 } => {
8225 if let Some(inner_name) = inner_fields.borrow().get("name")
8226 {
8227 crate::sigil_debug!("DEBUG binding_name: returning inner name {} from {}", inner_name, name);
8228 inner_name.clone()
8229 } else {
8230 crate::sigil_debug!(
8231 "DEBUG binding_name: returning struct {} from {}",
8232 n,
8233 name
8234 );
8235 n.clone()
8236 }
8237 }
8238 _ => {
8239 crate::sigil_debug!(
8240 "DEBUG binding_name: returning {} from {}",
8241 n,
8242 name
8243 );
8244 n.clone()
8245 }
8246 };
8247 return Ok(result);
8248 }
8249 crate::sigil_debug!(
8250 "DEBUG binding_name: 'name' field not found in {}, fields: {:?}",
8251 name,
8252 fields.borrow().keys().collect::<Vec<_>>()
8253 );
8254 return Ok(Value::Null);
8256 }
8257 "mutable" => {
8258 if let Some(m) = fields.borrow().get("mutable") {
8260 return Ok(m.clone());
8261 }
8262 return Ok(Value::Bool(false));
8263 }
8264 "is_ident" => {
8265 return Ok(Value::Bool(name == "Pattern::Ident"));
8266 }
8267 "is_wildcard" => {
8268 return Ok(Value::Bool(name == "Pattern::Wildcard"));
8269 }
8270 "clone" => {
8271 return Ok(recv.clone());
8272 }
8273 _ => {}
8274 }
8275 }
8276
8277 if name == "PathBuf" || name == "Path" {
8279 match method.name.as_str() {
8280 "exists" => {
8281 let path = match fields.borrow().get("path") {
8283 Some(Value::String(s)) => s.to_string(),
8284 _ => return Err(RuntimeError::new("PathBuf has no path field")),
8285 };
8286 return Ok(Value::Bool(std::path::Path::new(&path).exists()));
8287 }
8288 "is_dir" => {
8289 let path = match fields.borrow().get("path") {
8290 Some(Value::String(s)) => s.to_string(),
8291 _ => return Err(RuntimeError::new("PathBuf has no path field")),
8292 };
8293 return Ok(Value::Bool(std::path::Path::new(&path).is_dir()));
8294 }
8295 "is_file" => {
8296 let path = match fields.borrow().get("path") {
8297 Some(Value::String(s)) => s.to_string(),
8298 _ => return Err(RuntimeError::new("PathBuf has no path field")),
8299 };
8300 return Ok(Value::Bool(std::path::Path::new(&path).is_file()));
8301 }
8302 "extension" => {
8303 let path = match fields.borrow().get("path") {
8304 Some(Value::String(s)) => s.to_string(),
8305 _ => return Err(RuntimeError::new("PathBuf has no path field")),
8306 };
8307 match std::path::Path::new(&path).extension() {
8308 Some(ext) => {
8309 let ext_str = ext.to_string_lossy().to_string();
8311 let mut ext_fields = HashMap::new();
8312 ext_fields.insert(
8313 "value".to_string(),
8314 Value::String(Rc::new(ext_str)),
8315 );
8316 return Ok(Value::Variant {
8317 enum_name: "Option".to_string(),
8318 variant_name: "Some".to_string(),
8319 fields: Some(Rc::new(vec![Value::Struct {
8320 name: "OsStr".to_string(),
8321 fields: Rc::new(RefCell::new(ext_fields)),
8322 }])),
8323 });
8324 }
8325 None => {
8326 return Ok(Value::Variant {
8327 enum_name: "Option".to_string(),
8328 variant_name: "None".to_string(),
8329 fields: None,
8330 });
8331 }
8332 }
8333 }
8334 "file_name" => {
8335 let path = match fields.borrow().get("path") {
8336 Some(Value::String(s)) => s.to_string(),
8337 _ => return Err(RuntimeError::new("PathBuf has no path field")),
8338 };
8339 match std::path::Path::new(&path).file_name() {
8340 Some(fname) => {
8341 let fname_str = fname.to_string_lossy().to_string();
8342 let mut fname_fields = HashMap::new();
8343 fname_fields.insert(
8344 "value".to_string(),
8345 Value::String(Rc::new(fname_str)),
8346 );
8347 return Ok(Value::Variant {
8348 enum_name: "Option".to_string(),
8349 variant_name: "Some".to_string(),
8350 fields: Some(Rc::new(vec![Value::Struct {
8351 name: "OsStr".to_string(),
8352 fields: Rc::new(RefCell::new(fname_fields)),
8353 }])),
8354 });
8355 }
8356 None => {
8357 return Ok(Value::Variant {
8358 enum_name: "Option".to_string(),
8359 variant_name: "None".to_string(),
8360 fields: None,
8361 });
8362 }
8363 }
8364 }
8365 "parent" => {
8366 let path = match fields.borrow().get("path") {
8367 Some(Value::String(s)) => s.to_string(),
8368 _ => return Err(RuntimeError::new("PathBuf has no path field")),
8369 };
8370 match std::path::Path::new(&path).parent() {
8371 Some(parent) => {
8372 let mut parent_fields = HashMap::new();
8373 parent_fields.insert(
8374 "path".to_string(),
8375 Value::String(Rc::new(
8376 parent.to_string_lossy().to_string(),
8377 )),
8378 );
8379 return Ok(Value::Variant {
8380 enum_name: "Option".to_string(),
8381 variant_name: "Some".to_string(),
8382 fields: Some(Rc::new(vec![Value::Struct {
8383 name: "Path".to_string(),
8384 fields: Rc::new(RefCell::new(parent_fields)),
8385 }])),
8386 });
8387 }
8388 None => {
8389 return Ok(Value::Variant {
8390 enum_name: "Option".to_string(),
8391 variant_name: "None".to_string(),
8392 fields: None,
8393 });
8394 }
8395 }
8396 }
8397 "to_str" => {
8398 let path = match fields.borrow().get("path") {
8400 Some(Value::String(s)) => s.clone(),
8401 _ => return Err(RuntimeError::new("PathBuf has no path field")),
8402 };
8403 return Ok(Value::Variant {
8405 enum_name: "Option".to_string(),
8406 variant_name: "Some".to_string(),
8407 fields: Some(Rc::new(vec![Value::String(path)])),
8408 });
8409 }
8410 "to_string_lossy" => {
8411 let path = match fields.borrow().get("path") {
8412 Some(Value::String(s)) => s.clone(),
8413 _ => return Err(RuntimeError::new("PathBuf has no path field")),
8414 };
8415 return Ok(Value::String(path));
8416 }
8417 "join" => {
8418 if arg_values.is_empty() {
8420 return Err(RuntimeError::new("join expects 1 argument"));
8421 }
8422 let base = match fields.borrow().get("path") {
8423 Some(Value::String(s)) => s.to_string(),
8424 _ => return Err(RuntimeError::new("PathBuf has no path field")),
8425 };
8426 let component = match &arg_values[0] {
8427 Value::String(s) => s.to_string(),
8428 Value::Struct { name: n, fields: f }
8429 if n == "PathBuf" || n == "Path" =>
8430 {
8431 match f.borrow().get("path") {
8432 Some(Value::String(s)) => s.to_string(),
8433 _ => {
8434 return Err(RuntimeError::new(
8435 "PathBuf has no path field",
8436 ))
8437 }
8438 }
8439 }
8440 _ => {
8441 return Err(RuntimeError::new("join expects string or PathBuf"))
8442 }
8443 };
8444 let joined = std::path::Path::new(&base).join(&component);
8445 let mut new_fields = HashMap::new();
8446 new_fields.insert(
8447 "path".to_string(),
8448 Value::String(Rc::new(joined.to_string_lossy().to_string())),
8449 );
8450 return Ok(Value::Struct {
8451 name: "PathBuf".to_string(),
8452 fields: Rc::new(RefCell::new(new_fields)),
8453 });
8454 }
8455 "display" => {
8456 let path = match fields.borrow().get("path") {
8457 Some(Value::String(s)) => s.clone(),
8458 _ => return Err(RuntimeError::new("PathBuf has no path field")),
8459 };
8460 return Ok(Value::String(path));
8461 }
8462 "to_path_buf" => {
8463 return Ok(recv.clone());
8465 }
8466 _ => {}
8467 }
8468 }
8469
8470 if name == "OsStr" {
8472 match method.name.as_str() {
8473 "to_str" => {
8474 let val = match fields.borrow().get("value") {
8475 Some(Value::String(s)) => s.clone(),
8476 _ => return Err(RuntimeError::new("OsStr has no value field")),
8477 };
8478 return Ok(Value::Variant {
8479 enum_name: "Option".to_string(),
8480 variant_name: "Some".to_string(),
8481 fields: Some(Rc::new(vec![Value::String(val)])),
8482 });
8483 }
8484 "to_string_lossy" => {
8485 let val = match fields.borrow().get("value") {
8486 Some(Value::String(s)) => s.clone(),
8487 _ => return Err(RuntimeError::new("OsStr has no value field")),
8488 };
8489 return Ok(Value::String(val));
8490 }
8491 "to_lowercase" => {
8492 let val = match fields.borrow().get("value") {
8493 Some(Value::String(s)) => s.to_lowercase(),
8494 _ => return Err(RuntimeError::new("OsStr has no value field")),
8495 };
8496 return Ok(Value::String(Rc::new(val)));
8497 }
8498 "as_str" => {
8499 let val = match fields.borrow().get("value") {
8500 Some(Value::String(s)) => s.clone(),
8501 _ => return Err(RuntimeError::new("OsStr has no value field")),
8502 };
8503 return Ok(Value::String(val));
8504 }
8505 _ => {}
8506 }
8507 }
8508
8509 if name == "DirEntry" {
8511 match method.name.as_str() {
8512 "path" => {
8513 let path = match fields.borrow().get("path") {
8514 Some(Value::String(s)) => s.clone(),
8515 _ => return Err(RuntimeError::new("DirEntry has no path field")),
8516 };
8517 let mut path_fields = HashMap::new();
8518 path_fields.insert("path".to_string(), Value::String(path));
8519 return Ok(Value::Struct {
8520 name: "PathBuf".to_string(),
8521 fields: Rc::new(RefCell::new(path_fields)),
8522 });
8523 }
8524 "file_name" => {
8525 let path = match fields.borrow().get("path") {
8526 Some(Value::String(s)) => s.to_string(),
8527 _ => return Err(RuntimeError::new("DirEntry has no path field")),
8528 };
8529 let fname = std::path::Path::new(&path)
8530 .file_name()
8531 .map(|f| f.to_string_lossy().to_string())
8532 .unwrap_or_default();
8533 let mut fname_fields = HashMap::new();
8534 fname_fields.insert("value".to_string(), Value::String(Rc::new(fname)));
8535 return Ok(Value::Struct {
8536 name: "OsStr".to_string(),
8537 fields: Rc::new(RefCell::new(fname_fields)),
8538 });
8539 }
8540 _ => {}
8541 }
8542 }
8543
8544 if name == "Map" {
8546 match method.name.as_str() {
8547 "get" => {
8548 if arg_values.len() != 1 {
8550 return Err(RuntimeError::new("Map.get expects 1 argument"));
8551 }
8552 let key = match &arg_values[0] {
8553 Value::String(s) => s.to_string(),
8554 Value::Int(n) => n.to_string(),
8555 other => format!("{:?}", other),
8556 };
8557 if let Some(val) = fields.borrow().get(&key) {
8558 return Ok(val.clone());
8559 }
8560 return Ok(Value::Null);
8561 }
8562 "insert" => {
8563 if arg_values.len() != 2 {
8565 return Err(RuntimeError::new("Map.insert expects 2 arguments"));
8566 }
8567 let key = match &arg_values[0] {
8568 Value::String(s) => s.to_string(),
8569 Value::Int(n) => n.to_string(),
8570 other => format!("{:?}", other),
8571 };
8572 crate::sigil_debug!(
8573 "DEBUG Map.insert: key='{}', value={}",
8574 key,
8575 arg_values[1]
8576 );
8577 fields.borrow_mut().insert(key, arg_values[1].clone());
8578 return Ok(Value::Null);
8579 }
8580 "contains_key" => {
8581 if arg_values.len() != 1 {
8582 return Err(RuntimeError::new(
8583 "Map.contains_key expects 1 argument",
8584 ));
8585 }
8586 let key = match &arg_values[0] {
8587 Value::String(s) => s.to_string(),
8588 Value::Int(n) => n.to_string(),
8589 other => format!("{:?}", other),
8590 };
8591 return Ok(Value::Bool(fields.borrow().contains_key(&key)));
8592 }
8593 "len" => {
8594 return Ok(Value::Int(fields.borrow().len() as i64));
8595 }
8596 "is_empty" => {
8597 return Ok(Value::Bool(fields.borrow().is_empty()));
8598 }
8599 "keys" => {
8600 let keys: Vec<Value> = fields
8601 .borrow()
8602 .keys()
8603 .map(|k| Value::String(Rc::new(k.clone())))
8604 .collect();
8605 return Ok(Value::Array(Rc::new(RefCell::new(keys))));
8606 }
8607 "values" => {
8608 let vals: Vec<Value> = fields.borrow().values().cloned().collect();
8609 return Ok(Value::Array(Rc::new(RefCell::new(vals))));
8610 }
8611 "clone" => {
8612 return Ok(recv.clone());
8613 }
8614 _ => {}
8615 }
8616 }
8617
8618 if name == "HyperLogLog" {
8620 match method.name.as_str() {
8621 "insert" => {
8622 if arg_values.len() != 1 {
8624 return Err(RuntimeError::new(
8625 "HyperLogLog.insert expects 1 argument",
8626 ));
8627 }
8628 let hash = match &arg_values[0] {
8630 Value::String(s) => {
8631 use std::collections::hash_map::DefaultHasher;
8632 use std::hash::{Hash, Hasher};
8633 let mut hasher = DefaultHasher::new();
8634 s.hash(&mut hasher);
8635 hasher.finish()
8636 }
8637 Value::Int(n) => {
8638 use std::collections::hash_map::DefaultHasher;
8639 use std::hash::{Hash, Hasher};
8640 let mut hasher = DefaultHasher::new();
8641 n.hash(&mut hasher);
8642 hasher.finish()
8643 }
8644 other => {
8645 use std::collections::hash_map::DefaultHasher;
8646 use std::hash::{Hash, Hasher};
8647 let mut hasher = DefaultHasher::new();
8648 format!("{:?}", other).hash(&mut hasher);
8649 hasher.finish()
8650 }
8651 };
8652 let precision = match fields.borrow().get("_precision") {
8654 Some(Value::Int(p)) => *p as u32,
8655 _ => 14,
8656 };
8657 let idx = (hash >> (64 - precision)) as usize;
8658 let remaining = hash << precision | (1 << (precision - 1));
8659 let leading_zeros = remaining.leading_zeros() + 1;
8660 if let Some(Value::Array(regs)) = fields.borrow().get("_registers") {
8662 let mut regs_borrow = regs.borrow_mut();
8663 if idx < regs_borrow.len() {
8664 let current = match ®s_borrow[idx] {
8665 Value::Int(v) => *v as u32,
8666 _ => 0,
8667 };
8668 if leading_zeros > current {
8669 regs_borrow[idx] = Value::Int(leading_zeros as i64);
8670 }
8671 }
8672 }
8673 let count_val = fields.borrow().get("_count").cloned();
8675 if let Some(Value::Int(c)) = count_val {
8676 fields.borrow_mut().insert("_count".to_string(), Value::Int(c + 1));
8677 }
8678 return Ok(Value::Null);
8679 }
8680 "count" => {
8681 if let Some(Value::Array(regs)) = fields.borrow().get("_registers") {
8683 let regs_borrow = regs.borrow();
8684 let m = regs_borrow.len() as f64;
8685 let mut sum = 0.0;
8687 let mut zeros = 0;
8688 for reg in regs_borrow.iter() {
8689 let val = match reg {
8690 Value::Int(v) => *v as i32,
8691 _ => 0,
8692 };
8693 sum += 2.0_f64.powi(-val);
8694 if val == 0 {
8695 zeros += 1;
8696 }
8697 }
8698 let alpha = 0.7213 / (1.0 + 1.079 / m);
8700 let estimate = alpha * m * m / sum;
8701 let result = if estimate <= 2.5 * m && zeros > 0 {
8703 m * (m / zeros as f64).ln()
8704 } else {
8705 estimate
8706 };
8707 return Ok(Value::Int(result.round() as i64));
8708 }
8709 return Ok(Value::Int(0));
8710 }
8711 _ => {}
8712 }
8713 }
8714
8715 if name == "BloomFilter" {
8717 match method.name.as_str() {
8718 "insert" => {
8719 if arg_values.len() != 1 {
8720 return Err(RuntimeError::new(
8721 "BloomFilter.insert expects 1 argument",
8722 ));
8723 }
8724 let size = match fields.borrow().get("_size") {
8725 Some(Value::Int(s)) => *s as usize,
8726 _ => 1024,
8727 };
8728 let num_hashes = match fields.borrow().get("_num_hashes") {
8729 Some(Value::Int(n)) => *n as usize,
8730 _ => 3,
8731 };
8732 let base_hash = match &arg_values[0] {
8734 Value::String(s) => {
8735 use std::collections::hash_map::DefaultHasher;
8736 use std::hash::{Hash, Hasher};
8737 let mut hasher = DefaultHasher::new();
8738 s.hash(&mut hasher);
8739 hasher.finish()
8740 }
8741 Value::Int(n) => *n as u64,
8742 other => {
8743 use std::collections::hash_map::DefaultHasher;
8744 use std::hash::{Hash, Hasher};
8745 let mut hasher = DefaultHasher::new();
8746 format!("{:?}", other).hash(&mut hasher);
8747 hasher.finish()
8748 }
8749 };
8750 if let Some(Value::Array(bits)) = fields.borrow().get("_bits") {
8752 let mut bits_borrow = bits.borrow_mut();
8753 for i in 0..num_hashes {
8754 let h = (base_hash.wrapping_add(i as u64 * base_hash.rotate_left(17)))
8755 % size as u64;
8756 bits_borrow[h as usize] = Value::Bool(true);
8757 }
8758 }
8759 return Ok(Value::Null);
8760 }
8761 "contains" => {
8762 if arg_values.len() != 1 {
8763 return Err(RuntimeError::new(
8764 "BloomFilter.contains expects 1 argument",
8765 ));
8766 }
8767 let size = match fields.borrow().get("_size") {
8768 Some(Value::Int(s)) => *s as usize,
8769 _ => 1024,
8770 };
8771 let num_hashes = match fields.borrow().get("_num_hashes") {
8772 Some(Value::Int(n)) => *n as usize,
8773 _ => 3,
8774 };
8775 let base_hash = match &arg_values[0] {
8776 Value::String(s) => {
8777 use std::collections::hash_map::DefaultHasher;
8778 use std::hash::{Hash, Hasher};
8779 let mut hasher = DefaultHasher::new();
8780 s.hash(&mut hasher);
8781 hasher.finish()
8782 }
8783 Value::Int(n) => *n as u64,
8784 other => {
8785 use std::collections::hash_map::DefaultHasher;
8786 use std::hash::{Hash, Hasher};
8787 let mut hasher = DefaultHasher::new();
8788 format!("{:?}", other).hash(&mut hasher);
8789 hasher.finish()
8790 }
8791 };
8792 if let Some(Value::Array(bits)) = fields.borrow().get("_bits") {
8794 let bits_borrow = bits.borrow();
8795 for i in 0..num_hashes {
8796 let h = (base_hash.wrapping_add(i as u64 * base_hash.rotate_left(17)))
8797 % size as u64;
8798 match &bits_borrow[h as usize] {
8799 Value::Bool(true) => {}
8800 _ => return Ok(Value::Bool(false)),
8801 }
8802 }
8803 return Ok(Value::Bool(true));
8804 }
8805 return Ok(Value::Bool(false));
8806 }
8807 _ => {}
8808 }
8809 }
8810
8811 if name == "CountMinSketch" {
8813 match method.name.as_str() {
8814 "insert" => {
8815 if arg_values.len() != 1 {
8816 return Err(RuntimeError::new(
8817 "CountMinSketch.insert expects 1 argument",
8818 ));
8819 }
8820 let depth = match fields.borrow().get("_depth") {
8821 Some(Value::Int(d)) => *d as usize,
8822 _ => 4,
8823 };
8824 let width = match fields.borrow().get("_width") {
8825 Some(Value::Int(w)) => *w as usize,
8826 _ => 1024,
8827 };
8828 let base_hash = match &arg_values[0] {
8829 Value::String(s) => {
8830 use std::collections::hash_map::DefaultHasher;
8831 use std::hash::{Hash, Hasher};
8832 let mut hasher = DefaultHasher::new();
8833 s.hash(&mut hasher);
8834 hasher.finish()
8835 }
8836 Value::Int(n) => *n as u64,
8837 other => {
8838 use std::collections::hash_map::DefaultHasher;
8839 use std::hash::{Hash, Hasher};
8840 let mut hasher = DefaultHasher::new();
8841 format!("{:?}", other).hash(&mut hasher);
8842 hasher.finish()
8843 }
8844 };
8845 if let Some(Value::Array(counters)) = fields.borrow().get("_counters") {
8847 let counters_borrow = counters.borrow();
8848 for i in 0..depth {
8849 let h = (base_hash.wrapping_add(i as u64 * 0x517cc1b727220a95))
8850 % width as u64;
8851 if let Value::Array(row) = &counters_borrow[i] {
8852 let mut row_borrow = row.borrow_mut();
8853 if let Value::Int(c) = &row_borrow[h as usize] {
8854 row_borrow[h as usize] = Value::Int(c + 1);
8855 }
8856 }
8857 }
8858 }
8859 return Ok(Value::Null);
8860 }
8861 "frequency" => {
8862 if arg_values.len() != 1 {
8863 return Err(RuntimeError::new(
8864 "CountMinSketch.frequency expects 1 argument",
8865 ));
8866 }
8867 let depth = match fields.borrow().get("_depth") {
8868 Some(Value::Int(d)) => *d as usize,
8869 _ => 4,
8870 };
8871 let width = match fields.borrow().get("_width") {
8872 Some(Value::Int(w)) => *w as usize,
8873 _ => 1024,
8874 };
8875 let base_hash = match &arg_values[0] {
8876 Value::String(s) => {
8877 use std::collections::hash_map::DefaultHasher;
8878 use std::hash::{Hash, Hasher};
8879 let mut hasher = DefaultHasher::new();
8880 s.hash(&mut hasher);
8881 hasher.finish()
8882 }
8883 Value::Int(n) => *n as u64,
8884 other => {
8885 use std::collections::hash_map::DefaultHasher;
8886 use std::hash::{Hash, Hasher};
8887 let mut hasher = DefaultHasher::new();
8888 format!("{:?}", other).hash(&mut hasher);
8889 hasher.finish()
8890 }
8891 };
8892 let mut min_count = i64::MAX;
8894 if let Some(Value::Array(counters)) = fields.borrow().get("_counters") {
8895 let counters_borrow = counters.borrow();
8896 for i in 0..depth {
8897 let h = (base_hash.wrapping_add(i as u64 * 0x517cc1b727220a95))
8898 % width as u64;
8899 if let Value::Array(row) = &counters_borrow[i] {
8900 let row_borrow = row.borrow();
8901 if let Value::Int(c) = &row_borrow[h as usize] {
8902 if *c < min_count {
8903 min_count = *c;
8904 }
8905 }
8906 }
8907 }
8908 }
8909 return Ok(Value::Int(if min_count == i64::MAX { 0 } else { min_count }));
8910 }
8911 _ => {}
8912 }
8913 }
8914
8915 if name == "MerkleTree" {
8917 match method.name.as_str() {
8918 "insert" => {
8919 if arg_values.len() != 1 {
8920 return Err(RuntimeError::new(
8921 "MerkleTree.insert expects 1 argument",
8922 ));
8923 }
8924 let data = match &arg_values[0] {
8926 Value::String(s) => s.as_bytes().to_vec(),
8927 Value::Int(n) => n.to_le_bytes().to_vec(),
8928 other => format!("{:?}", other).into_bytes(),
8929 };
8930 use std::collections::hash_map::DefaultHasher;
8931 use std::hash::{Hash, Hasher};
8932 let mut hasher = DefaultHasher::new();
8933 data.hash(&mut hasher);
8934 let leaf_hash = format!("{:016x}", hasher.finish());
8935 if let Some(Value::Array(leaves)) = fields.borrow().get("_leaves") {
8936 leaves.borrow_mut().push(Value::String(Rc::new(leaf_hash)));
8937 }
8938 if let Some(Value::Array(leaves)) = fields.borrow().get("_leaves") {
8940 let leaves_borrow = leaves.borrow();
8941 let combined: String = leaves_borrow
8942 .iter()
8943 .filter_map(|v| match v {
8944 Value::String(s) => Some(s.to_string()),
8945 _ => None,
8946 })
8947 .collect();
8948 let mut root_hasher = DefaultHasher::new();
8949 combined.hash(&mut root_hasher);
8950 let root = format!("{:016x}", root_hasher.finish());
8951 fields
8952 .borrow_mut()
8953 .insert("_root".to_string(), Value::String(Rc::new(root)));
8954 }
8955 return Ok(Value::Null);
8956 }
8957 "verify" => {
8958 use std::collections::hash_map::DefaultHasher;
8960 use std::hash::{Hash, Hasher};
8961 if let (Some(Value::Array(leaves)), Some(Value::String(root))) = (
8962 fields.borrow().get("_leaves").cloned(),
8963 fields.borrow().get("_root").cloned(),
8964 ) {
8965 let leaves_borrow = leaves.borrow();
8966 let combined: String = leaves_borrow
8967 .iter()
8968 .filter_map(|v| match v {
8969 Value::String(s) => Some(s.to_string()),
8970 _ => None,
8971 })
8972 .collect();
8973 let mut hasher = DefaultHasher::new();
8974 combined.hash(&mut hasher);
8975 let computed_root = format!("{:016x}", hasher.finish());
8976 return Ok(Value::Bool(*root == computed_root));
8977 }
8978 return Ok(Value::Bool(false));
8979 }
8980 "root" => {
8981 if let Some(root) = fields.borrow().get("_root").cloned() {
8983 return Ok(root);
8984 }
8985 return Ok(Value::Null);
8986 }
8987 "prove_inclusion" => {
8988 if arg_values.len() != 1 {
8990 return Err(RuntimeError::new(
8991 "MerkleTree.prove_inclusion expects 1 argument",
8992 ));
8993 }
8994 let idx = match &arg_values[0] {
8995 Value::Int(i) => *i as usize,
8996 _ => {
8997 return Err(RuntimeError::new(
8998 "prove_inclusion requires integer index",
8999 ))
9000 }
9001 };
9002 let mut proof_fields = std::collections::HashMap::new();
9004 proof_fields.insert("_index".to_string(), Value::Int(idx as i64));
9005 if let Some(root) = fields.borrow().get("_root").cloned() {
9006 proof_fields.insert("_root".to_string(), root);
9007 }
9008 if let Some(leaves) = fields.borrow().get("_leaves").cloned() {
9009 proof_fields.insert("_leaves".to_string(), leaves);
9010 }
9011 proof_fields.insert("_valid".to_string(), Value::Bool(true));
9012 return Ok(Value::Struct {
9013 name: "MerkleProof".to_string(),
9014 fields: Rc::new(RefCell::new(proof_fields)),
9015 });
9016 }
9017 _ => {}
9018 }
9019 }
9020
9021 if name == "MerkleProof" {
9023 match method.name.as_str() {
9024 "verify" => {
9025 if let Some(Value::Bool(valid)) = fields.borrow().get("_valid") {
9027 return Ok(Value::Bool(*valid));
9028 }
9029 return Ok(Value::Bool(false));
9030 }
9031 _ => {}
9032 }
9033 }
9034
9035 if name == "UntrustedData" {
9037 match method.name.as_str() {
9038 "verify" => {
9039 fields
9041 .borrow_mut()
9042 .insert("_verified".to_string(), Value::Bool(true));
9043 if let Some(val) = fields.borrow().get("value").cloned() {
9045 return Ok(val);
9046 }
9047 return Ok(Value::Bool(true));
9048 }
9049 _ => {}
9050 }
9051 }
9052
9053 if name == "QHCompressed" {
9055 match method.name.as_str() {
9056 "size" => {
9057 if let Some(Value::Int(size)) = fields.borrow().get("_compressed_size") {
9058 return Ok(Value::Int(*size));
9059 }
9060 return Ok(Value::Int(1)); }
9062 _ => {}
9063 }
9064 }
9065
9066 if name == "Superposition" {
9068 match method.name.as_str() {
9069 "observe" => {
9070 if let Some(Value::Array(values)) = fields.borrow().get("_values") {
9073 let values_borrow = values.borrow();
9074 if !values_borrow.is_empty() {
9075 return Ok(values_borrow[0].clone());
9078 }
9079 }
9080 if let Some(Value::Array(states)) = fields.borrow().get("states") {
9082 let states_borrow = states.borrow();
9083 if !states_borrow.is_empty() {
9084 return Ok(states_borrow[0].clone());
9085 }
9086 }
9087 return Ok(Value::Null);
9088 }
9089 _ => {}
9090 }
9091 }
9092
9093 if name == "ReLU" && method.name == "forward" {
9095 if let Some(input) = arg_values.first() {
9096 if let Value::Struct { name: tensor_name, fields: tensor_fields } = input {
9098 if tensor_name == "Tensor" {
9099 let tensor_ref = tensor_fields.borrow();
9100 let shape = tensor_ref.get("shape").cloned();
9101 let data: Vec<f64> = match tensor_ref.get("data") {
9102 Some(Value::Array(arr)) => {
9103 arr.borrow().iter().map(|v| match v {
9104 Value::Float(f) => *f,
9105 Value::Int(n) => *n as f64,
9106 _ => 0.0,
9107 }).collect()
9108 }
9109 _ => vec![],
9110 };
9111 drop(tensor_ref);
9112
9113 let relu_data: Vec<Value> = data.iter()
9115 .map(|x| Value::Float(if *x > 0.0 { *x } else { 0.0 }))
9116 .collect();
9117
9118 let mut result_fields = HashMap::new();
9119 if let Some(s) = shape {
9120 result_fields.insert("shape".to_string(), s);
9121 }
9122 result_fields.insert("data".to_string(), Value::Array(Rc::new(RefCell::new(relu_data))));
9123 result_fields.insert("requires_grad".to_string(), Value::Bool(false));
9124 return Ok(Value::Struct {
9125 name: "Tensor".to_string(),
9126 fields: Rc::new(RefCell::new(result_fields)),
9127 });
9128 }
9129 }
9130 }
9131 return Err(RuntimeError::new("ReLU.forward expects a Tensor"));
9132 }
9133
9134 if name == "Sequential" && method.name == "forward" {
9136 if let Some(input) = arg_values.first().cloned() {
9137 let layers = fields.borrow().get("layers").cloned();
9138 if let Some(Value::Array(layers_arr)) = layers {
9139 let mut current = input;
9140 for layer in layers_arr.borrow().iter() {
9141 if let Value::Struct { name: layer_name, fields: layer_fields } = layer {
9142 if layer_name == "ReLU" {
9144 if let Value::Struct { name: tn, fields: tf } = ¤t {
9146 if tn == "Tensor" {
9147 let tf_ref = tf.borrow();
9148 let shape = tf_ref.get("shape").cloned();
9149 let data: Vec<f64> = match tf_ref.get("data") {
9150 Some(Value::Array(arr)) => {
9151 arr.borrow().iter().map(|v| match v {
9152 Value::Float(f) => *f,
9153 Value::Int(n) => *n as f64,
9154 _ => 0.0,
9155 }).collect()
9156 }
9157 _ => vec![],
9158 };
9159 drop(tf_ref);
9160
9161 let relu_data: Vec<Value> = data.iter()
9162 .map(|x| Value::Float(if *x > 0.0 { *x } else { 0.0 }))
9163 .collect();
9164
9165 let mut result_fields = HashMap::new();
9166 if let Some(s) = shape {
9167 result_fields.insert("shape".to_string(), s);
9168 }
9169 result_fields.insert("data".to_string(), Value::Array(Rc::new(RefCell::new(relu_data))));
9170 result_fields.insert("requires_grad".to_string(), Value::Bool(false));
9171 current = Value::Struct {
9172 name: "Tensor".to_string(),
9173 fields: Rc::new(RefCell::new(result_fields)),
9174 };
9175 }
9176 }
9177 } else if layer_name == "Linear" {
9178 let layer_ref = layer_fields.borrow();
9180 let weight = layer_ref.get("weight").cloned();
9181 let bias = layer_ref.get("bias").cloned();
9182 drop(layer_ref);
9183
9184 if let (Some(w), Some(b)) = (weight, bias) {
9185 if let (
9188 Value::Struct { fields: w_fields, .. },
9189 Value::Struct { fields: x_fields, .. },
9190 Value::Struct { fields: b_fields, .. },
9191 ) = (&w, ¤t, &b) {
9192 let w_shape: Vec<usize> = match w_fields.borrow().get("shape") {
9194 Some(Value::Array(arr)) => arr.borrow().iter().filter_map(|v| match v {
9195 Value::Int(n) => Some(*n as usize),
9196 _ => None,
9197 }).collect(),
9198 _ => vec![],
9199 };
9200 let w_data: Vec<f64> = match w_fields.borrow().get("data") {
9201 Some(Value::Array(arr)) => arr.borrow().iter().filter_map(|v| match v {
9202 Value::Float(f) => Some(*f),
9203 Value::Int(n) => Some(*n as f64),
9204 _ => None,
9205 }).collect(),
9206 _ => vec![],
9207 };
9208
9209 let x_data: Vec<f64> = match x_fields.borrow().get("data") {
9211 Some(Value::Array(arr)) => arr.borrow().iter().filter_map(|v| match v {
9212 Value::Float(f) => Some(*f),
9213 Value::Int(n) => Some(*n as f64),
9214 _ => None,
9215 }).collect(),
9216 _ => vec![],
9217 };
9218
9219 let b_data: Vec<f64> = match b_fields.borrow().get("data") {
9221 Some(Value::Array(arr)) => arr.borrow().iter().filter_map(|v| match v {
9222 Value::Float(f) => Some(*f),
9223 Value::Int(n) => Some(*n as f64),
9224 _ => None,
9225 }).collect(),
9226 _ => vec![],
9227 };
9228
9229 let out_size = if w_shape.len() >= 2 { w_shape[0] } else { 1 };
9231 let in_size = if w_shape.len() >= 2 { w_shape[1] } else if !w_shape.is_empty() { w_shape[0] } else { 1 };
9232
9233 let mut result = vec![0.0; out_size];
9234 for i in 0..out_size {
9235 let mut sum = 0.0;
9236 for j in 0..in_size {
9237 if i * in_size + j < w_data.len() && j < x_data.len() {
9238 sum += w_data[i * in_size + j] * x_data[j];
9239 }
9240 }
9241 if i < b_data.len() {
9243 sum += b_data[i];
9244 }
9245 result[i] = sum;
9246 }
9247
9248 let mut result_fields = HashMap::new();
9250 result_fields.insert("shape".to_string(), Value::Array(Rc::new(RefCell::new(
9251 vec![Value::Int(out_size as i64)]
9252 ))));
9253 result_fields.insert("data".to_string(), Value::Array(Rc::new(RefCell::new(
9254 result.into_iter().map(Value::Float).collect()
9255 ))));
9256 result_fields.insert("requires_grad".to_string(), Value::Bool(false));
9257 current = Value::Struct {
9258 name: "Tensor".to_string(),
9259 fields: Rc::new(RefCell::new(result_fields)),
9260 };
9261 }
9262 }
9263 }
9264 }
9265 }
9266 return Ok(current);
9267 }
9268 }
9269 return Err(RuntimeError::new("Sequential.forward expects input tensor"));
9270 }
9271
9272 let qualified_name = format!("{}·{}", name, method.name);
9273
9274 if name == "Parser" && (method.name == "parse_file" || method.name == "read_source")
9276 {
9277 crate::sigil_debug!("DEBUG Parser method call: {}", qualified_name);
9278 for (i, arg) in arg_values.iter().enumerate() {
9279 crate::sigil_debug!(" arg_value[{}] = {:?}", i, arg);
9280 }
9281 }
9282
9283 if name == "Lexer" {
9285 if method.name == "lex_ident_or_keyword" {
9287 for (i, arg) in arg_values.iter().enumerate() {
9288 let unwrapped = Self::unwrap_all(arg);
9289 if let Value::Char(c) = &unwrapped {
9290 crate::sigil_debug!(
9291 "DEBUG Lexer·lex_ident_or_keyword arg[{}]='{}'",
9292 i,
9293 c
9294 );
9295 }
9296 }
9297 }
9298 crate::sigil_debug!("DEBUG Lexer method call: {}", qualified_name);
9299 }
9300 for arg in &arg_values {
9302 let unwrapped = Self::unwrap_all(arg);
9303 if let Value::String(s) = &unwrapped {
9304 if **s == "fn" {
9305 crate::sigil_debug!(
9306 "DEBUG struct method with 'fn': {} recv_name={}",
9307 method.name,
9308 name
9309 );
9310 }
9311 }
9312 }
9313
9314 let func = self
9315 .globals
9316 .borrow()
9317 .get(&qualified_name)
9318 .map(|v| v.clone());
9319 if let Some(func) = func {
9320 if let Value::Function(f) = func {
9321 let old_self_type = self.current_self_type.take();
9323 self.current_self_type = Some(name.clone());
9324
9325 let mut all_args = vec![recv.clone()];
9327 all_args.extend(arg_values.clone());
9328 let result = self.call_function(&f, all_args);
9329
9330 self.current_self_type = old_self_type;
9332 return result;
9333 } else if let Value::BuiltIn(b) = func {
9334 let mut all_args = vec![recv.clone()];
9335 all_args.extend(arg_values.clone());
9336 return (b.func)(self, all_args);
9337 }
9338 }
9339
9340 if name == "Self" {
9342 let field_names: Vec<String> = fields.borrow().keys().cloned().collect();
9344
9345 for (type_name, type_def) in &self.types {
9347 if let TypeDef::Struct(struct_def) = type_def {
9348 let def_fields: Vec<String> = match &struct_def.fields {
9350 crate::ast::StructFields::Named(fs) => {
9351 fs.iter().map(|f| f.name.name.clone()).collect()
9352 }
9353 _ => continue,
9354 };
9355
9356 let matches = field_names.iter().all(|f| def_fields.contains(f));
9358 if matches {
9359 let qualified_name = format!("{}·{}", type_name, method.name);
9360 let func = self
9361 .globals
9362 .borrow()
9363 .get(&qualified_name)
9364 .map(|v| v.clone());
9365 if let Some(func) = func {
9366 if let Value::Function(f) = func {
9367 let old_self_type = self.current_self_type.take();
9369 self.current_self_type = Some(type_name.clone());
9370
9371 let mut all_args = vec![recv.clone()];
9372 all_args.extend(arg_values.clone());
9373 let result = self.call_function(&f, all_args);
9374
9375 self.current_self_type = old_self_type;
9377 return result;
9378 } else if let Value::BuiltIn(b) = func {
9379 let mut all_args = vec![recv.clone()];
9380 all_args.extend(arg_values.clone());
9381 return (b.func)(self, all_args);
9382 }
9383 }
9384 }
9385 }
9386 }
9387 }
9388
9389 Err(RuntimeError::new(format!(
9391 "no method '{}' on struct '{}'",
9392 method.name,
9393 name
9394 )))
9395 }
9396 (
9398 Value::Variant {
9399 enum_name,
9400 variant_name,
9401 fields,
9402 },
9403 _,
9404 ) => {
9405 if enum_name == "Option" {
9407 match method.name.as_str() {
9408 "cloned" => {
9409 return Ok(recv.clone());
9412 }
9413 "is_some" => {
9414 return Ok(Value::Bool(variant_name == "Some"));
9415 }
9416 "is_none" => {
9417 return Ok(Value::Bool(variant_name == "None"));
9418 }
9419 "unwrap" => {
9420 crate::sigil_debug!(
9421 "DEBUG Option.unwrap: variant={}, fields={:?}",
9422 variant_name,
9423 fields
9424 );
9425 if variant_name == "Some" {
9426 if let Some(f) = fields {
9427 let result = f.first().cloned().unwrap_or(Value::Null);
9428 crate::sigil_debug!(
9429 "DEBUG Option.unwrap: returning {:?}",
9430 result
9431 );
9432 return Ok(result);
9433 }
9434 }
9435 return Err(RuntimeError::new("unwrap on None"));
9436 }
9437 "unwrap_or" => {
9438 if variant_name == "Some" {
9439 if let Some(f) = fields {
9440 return Ok(f.first().cloned().unwrap_or(Value::Null));
9441 }
9442 }
9443 return Ok(arg_values.first().cloned().unwrap_or(Value::Null));
9444 }
9445 "map" => {
9446 if variant_name == "Some" {
9448 if let Some(f) = fields {
9449 if let Some(inner) = f.first() {
9450 if let Some(Value::Function(func)) = arg_values.first() {
9451 let result =
9452 self.call_function(func, vec![inner.clone()])?;
9453 return Ok(Value::Variant {
9454 enum_name: "Option".to_string(),
9455 variant_name: "Some".to_string(),
9456 fields: Some(Rc::new(vec![result])),
9457 });
9458 }
9459 }
9460 }
9461 }
9462 return Ok(Value::Variant {
9463 enum_name: "Option".to_string(),
9464 variant_name: "None".to_string(),
9465 fields: None,
9466 });
9467 }
9468 "and_then" => {
9469 crate::sigil_debug!(
9471 "DEBUG and_then: variant={}, has_fields={}, arg_count={}",
9472 variant_name,
9473 fields.is_some(),
9474 arg_values.len()
9475 );
9476 if let Some(arg) = arg_values.first() {
9477 crate::sigil_debug!(
9478 "DEBUG and_then: arg type = {:?}",
9479 std::mem::discriminant(arg)
9480 );
9481 }
9482 if variant_name == "Some" {
9483 if let Some(f) = fields {
9484 if let Some(inner) = f.first() {
9485 crate::sigil_debug!("DEBUG and_then: inner = {:?}", inner);
9486 if let Some(Value::Function(func)) = arg_values.first() {
9487 let result =
9488 self.call_function(func, vec![inner.clone()])?;
9489 crate::sigil_debug!(
9490 "DEBUG and_then: result = {:?}",
9491 result
9492 );
9493 return Ok(result);
9495 } else {
9496 crate::sigil_debug!(
9497 "DEBUG and_then: arg is not a Function!"
9498 );
9499 }
9500 }
9501 }
9502 }
9503 return Ok(Value::Variant {
9505 enum_name: "Option".to_string(),
9506 variant_name: "None".to_string(),
9507 fields: None,
9508 });
9509 }
9510 "or_else" => {
9511 if variant_name == "Some" {
9513 return Ok(recv.clone());
9515 }
9516 if let Some(Value::Function(func)) = arg_values.first() {
9518 return self.call_function(func, vec![]);
9519 }
9520 return Ok(recv.clone());
9521 }
9522 "ok_or" | "ok_or_else" => {
9523 if variant_name == "Some" {
9525 if let Some(f) = fields {
9526 if let Some(inner) = f.first() {
9527 return Ok(Value::Variant {
9528 enum_name: "Result".to_string(),
9529 variant_name: "Ok".to_string(),
9530 fields: Some(Rc::new(vec![inner.clone()])),
9531 });
9532 }
9533 }
9534 }
9535 let err_val = arg_values
9537 .first()
9538 .cloned()
9539 .unwrap_or(Value::String(Rc::new("None".to_string())));
9540 return Ok(Value::Variant {
9541 enum_name: "Result".to_string(),
9542 variant_name: "Err".to_string(),
9543 fields: Some(Rc::new(vec![err_val])),
9544 });
9545 }
9546 _ => {}
9547 }
9548 }
9549 if enum_name == "Result" {
9551 match method.name.as_str() {
9552 "is_ok" => {
9553 return Ok(Value::Bool(variant_name == "Ok"));
9554 }
9555 "is_err" => {
9556 return Ok(Value::Bool(variant_name == "Err"));
9557 }
9558 "ok" => {
9559 if variant_name == "Ok" {
9562 let inner = fields
9563 .as_ref()
9564 .and_then(|f| f.first().cloned())
9565 .unwrap_or(Value::Null);
9566 return Ok(Value::Variant {
9567 enum_name: "Option".to_string(),
9568 variant_name: "Some".to_string(),
9569 fields: Some(Rc::new(vec![inner])),
9570 });
9571 }
9572 return Ok(Value::Variant {
9573 enum_name: "Option".to_string(),
9574 variant_name: "None".to_string(),
9575 fields: None,
9576 });
9577 }
9578 "err" => {
9579 if variant_name == "Err" {
9582 let inner = fields
9583 .as_ref()
9584 .and_then(|f| f.first().cloned())
9585 .unwrap_or(Value::Null);
9586 return Ok(Value::Variant {
9587 enum_name: "Option".to_string(),
9588 variant_name: "Some".to_string(),
9589 fields: Some(Rc::new(vec![inner])),
9590 });
9591 }
9592 return Ok(Value::Variant {
9593 enum_name: "Option".to_string(),
9594 variant_name: "None".to_string(),
9595 fields: None,
9596 });
9597 }
9598 "unwrap" => {
9599 if variant_name == "Ok" {
9600 if let Some(f) = fields {
9601 return Ok(f.first().cloned().unwrap_or(Value::Null));
9602 }
9603 }
9604 return Err(RuntimeError::new("unwrap on Err"));
9605 }
9606 "unwrap_or" => {
9607 if variant_name == "Ok" {
9608 if let Some(f) = fields {
9609 return Ok(f.first().cloned().unwrap_or(Value::Null));
9610 }
9611 }
9612 return Ok(arg_values.first().cloned().unwrap_or(Value::Null));
9613 }
9614 "map" => {
9615 if variant_name == "Ok" {
9617 if let Some(Value::Function(f)) = arg_values.first() {
9618 let inner = fields
9619 .as_ref()
9620 .and_then(|f| f.first().cloned())
9621 .unwrap_or(Value::Null);
9622 let result = self.call_function(f, vec![inner])?;
9623 return Ok(Value::Variant {
9624 enum_name: "Result".to_string(),
9625 variant_name: "Ok".to_string(),
9626 fields: Some(Rc::new(vec![result])),
9627 });
9628 }
9629 }
9630 return Ok(recv.clone());
9632 }
9633 "map_err" => {
9634 if variant_name == "Err" {
9636 if let Some(Value::Function(f)) = arg_values.first() {
9637 let inner = fields
9638 .as_ref()
9639 .and_then(|f| f.first().cloned())
9640 .unwrap_or(Value::Null);
9641 let result = self.call_function(f, vec![inner])?;
9642 return Ok(Value::Variant {
9643 enum_name: "Result".to_string(),
9644 variant_name: "Err".to_string(),
9645 fields: Some(Rc::new(vec![result])),
9646 });
9647 }
9648 }
9649 return Ok(recv.clone());
9651 }
9652 "and_then" => {
9653 if variant_name == "Ok" {
9655 if let Some(Value::Function(f)) = arg_values.first() {
9656 let inner = fields
9657 .as_ref()
9658 .and_then(|f| f.first().cloned())
9659 .unwrap_or(Value::Null);
9660 return self.call_function(f, vec![inner]);
9661 }
9662 }
9663 return Ok(recv.clone());
9665 }
9666 _ => {}
9667 }
9668 }
9669 crate::sigil_debug!(
9671 "DEBUG variant method call: enum_name={}, variant_name={}, method={}",
9672 enum_name,
9673 variant_name,
9674 method.name
9675 );
9676
9677 if enum_name == "Type" {
9679 match method.name.as_str() {
9680 "is_never" => {
9681 return Ok(Value::Bool(variant_name == "Never"));
9683 }
9684 "to_string" => {
9685 let type_str = match variant_name.as_str() {
9687 "Bool" => "bool".to_string(),
9688 "Int" => "i64".to_string(),
9689 "Float" => "f64".to_string(),
9690 "Str" => "str".to_string(),
9691 "Char" => "char".to_string(),
9692 "Unit" => "()".to_string(),
9693 "Never" => "!".to_string(),
9694 "Error" => "<error>".to_string(),
9695 other => format!("Type::{}", other),
9696 };
9697 return Ok(Value::String(Rc::new(type_str)));
9698 }
9699 _ => {}
9700 }
9701 }
9702
9703 if enum_name == "Pattern" {
9704 match method.name.as_str() {
9705 "evidentiality" => {
9706 if variant_name == "Ident" {
9708 if let Some(f) = fields {
9709 for field_val in f.iter() {
9712 if let Value::Struct { fields: inner, .. } = field_val {
9713 if let Some(ev) = inner.borrow().get("evidentiality") {
9714 return Ok(ev.clone());
9715 }
9716 }
9717 }
9718 if f.len() > 2 {
9720 return Ok(f[2].clone());
9721 }
9722 }
9723 }
9724 return Ok(Value::Null);
9726 }
9727 "name" => {
9728 if variant_name == "Ident" {
9730 if let Some(f) = fields {
9731 for field_val in f.iter() {
9732 if let Value::Struct { fields: inner, .. } = field_val {
9733 if let Some(n) = inner.borrow().get("name") {
9734 return Ok(n.clone());
9735 }
9736 }
9737 }
9738 if let Some(n) = f.first() {
9740 return Ok(n.clone());
9741 }
9742 }
9743 }
9744 return Ok(Value::Null);
9745 }
9746 "mutable" => {
9747 if variant_name == "Ident" {
9749 if let Some(f) = fields {
9750 for field_val in f.iter() {
9751 if let Value::Struct { fields: inner, .. } = field_val {
9752 if let Some(m) = inner.borrow().get("mutable") {
9753 return Ok(m.clone());
9754 }
9755 }
9756 }
9757 if f.len() > 1 {
9759 return Ok(f[1].clone());
9760 }
9761 }
9762 }
9763 return Ok(Value::Bool(false));
9764 }
9765 _ => {}
9766 }
9767 }
9768 if method.name == "clone" {
9770 return Ok(recv.clone());
9771 }
9772
9773 let qualified_name = format!("{}·{}", enum_name, method.name);
9774 let func = self
9775 .globals
9776 .borrow()
9777 .get(&qualified_name)
9778 .map(|v| v.clone());
9779 if let Some(func) = func {
9780 if let Value::Function(f) = func {
9781 let mut all_args = vec![recv.clone()];
9782 all_args.extend(arg_values.clone());
9783 return self.call_function(&f, all_args);
9784 } else if let Value::BuiltIn(b) = func {
9785 let mut all_args = vec![recv.clone()];
9786 all_args.extend(arg_values.clone());
9787 return (b.func)(self, all_args);
9788 }
9789 }
9790 Err(RuntimeError::new(format!(
9792 "no method '{}' on enum '{}'",
9793 method.name,
9794 enum_name
9795 )))
9796 }
9797 (Value::Null, "len_utf8") => Ok(Value::Int(0)),
9799 (Value::Null, "is_ascii") => Ok(Value::Bool(false)),
9800 (Value::Null, "is_alphabetic") => Ok(Value::Bool(false)),
9801 (Value::Null, "is_alphanumeric") => Ok(Value::Bool(false)),
9802 (Value::Null, "is_numeric") | (Value::Null, "is_digit") => Ok(Value::Bool(false)),
9803 (Value::Null, "is_whitespace") => Ok(Value::Bool(false)),
9804 (Value::Null, "is_uppercase") => Ok(Value::Bool(false)),
9805 (Value::Null, "is_lowercase") => Ok(Value::Bool(false)),
9806 (Value::Null, "len") => Ok(Value::Int(0)),
9807 (Value::Null, "is_empty") => Ok(Value::Bool(true)),
9808 (Value::Null, "to_string") => Ok(Value::String(Rc::new("".to_string()))),
9809 (Value::Null, "clone") => Ok(Value::Null),
9810 (Value::Null, "is_some") => Ok(Value::Bool(false)),
9811 (Value::Null, "is_none") => Ok(Value::Bool(true)),
9812 (Value::Null, "unwrap_or") => {
9813 if arg_values.is_empty() {
9814 Ok(Value::Null)
9815 } else {
9816 Ok(arg_values[0].clone())
9817 }
9818 }
9819 (Value::Char(c), "unwrap_or") => Ok(Value::Char(*c)),
9821 (Value::Int(n), "unwrap_or") => Ok(Value::Int(*n)),
9822 (Value::Float(n), "unwrap_or") => Ok(Value::Float(*n)),
9823 (Value::String(s), "unwrap_or") => Ok(Value::String(s.clone())),
9824 (Value::Bool(b), "unwrap_or") => Ok(Value::Bool(*b)),
9825 (Value::Int(n), "to_string") | (Value::Int(n), "string") => {
9827 Ok(Value::String(Rc::new(n.to_string())))
9828 }
9829 (Value::Int(n), "abs") => Ok(Value::Int(n.abs())),
9830 (Value::Int(n), "to_float") | (Value::Int(n), "float") => Ok(Value::Float(*n as f64)),
9831 (Value::Int(n), "duration_since") => {
9832 let other_ns = match arg_values.first() {
9835 Some(Value::Int(i)) => *i,
9836 Some(Value::Struct { fields, .. }) => {
9837 let borrowed = fields.borrow();
9838 let secs = match borrowed.get("secs") {
9839 Some(Value::Int(s)) => *s,
9840 _ => 0,
9841 };
9842 let nanos = match borrowed.get("nanos") {
9843 Some(Value::Int(n)) => *n,
9844 _ => 0,
9845 };
9846 secs * 1_000_000_000 + nanos
9847 }
9848 _ => 0,
9849 };
9850 let diff_ns = n - other_ns;
9851 let mut fields = std::collections::HashMap::new();
9852 fields.insert("secs".to_string(), Value::Int(diff_ns / 1_000_000_000));
9853 fields.insert("nanos".to_string(), Value::Int(diff_ns % 1_000_000_000));
9854 Ok(Value::Variant {
9855 enum_name: "Result".to_string(),
9856 variant_name: "Ok".to_string(),
9857 fields: Some(Rc::new(vec![Value::Struct {
9858 name: "Duration".to_string(),
9859 fields: Rc::new(RefCell::new(fields)),
9860 }])),
9861 })
9862 }
9863 (Value::Float(n), "to_string") | (Value::Float(n), "string") => {
9865 Ok(Value::String(Rc::new(n.to_string())))
9866 }
9867 (Value::Float(n), "abs") => Ok(Value::Float(n.abs())),
9868 (Value::Float(n), "to_int") | (Value::Float(n), "int") => Ok(Value::Int(*n as i64)),
9869 (Value::Bool(b), "to_string") | (Value::Bool(b), "string") => {
9871 Ok(Value::String(Rc::new(b.to_string())))
9872 }
9873 (Value::Char(c), "to_string") | (Value::Char(c), "string") => {
9875 Ok(Value::String(Rc::new(c.to_string())))
9876 }
9877 _ => {
9878 let recv_type = match &recv {
9880 Value::String(s) => format!("String(len={})", s.len()),
9881 Value::Array(arr) => format!("Array(len={})", arr.borrow().len()),
9882 Value::Struct { name, .. } => format!("Struct({})", name),
9883 Value::Variant {
9884 enum_name,
9885 variant_name,
9886 ..
9887 } => format!("Variant({}::{})", enum_name, variant_name),
9888 Value::Ref(r) => format!("Ref({:?})", std::mem::discriminant(&*r.borrow())),
9889 Value::Null => "Null".to_string(),
9890 other => format!("{:?}", std::mem::discriminant(other)),
9891 };
9892 Err(RuntimeError::new(format!(
9894 "no method '{}' on type '{}'",
9895 method.name,
9896 recv_type
9897 )))
9898 }
9899 }
9900 }
9901
9902 fn eval_incorporation(
9905 &mut self,
9906 segments: &[IncorporationSegment],
9907 ) -> Result<Value, RuntimeError> {
9908 if segments.is_empty() {
9909 return Err(RuntimeError::new("empty incorporation chain"));
9910 }
9911
9912 let first = &segments[0];
9914 let mut value = if let Some(args) = &first.args {
9915 let arg_values: Vec<Value> = args
9917 .iter()
9918 .map(|a| self.evaluate(a))
9919 .collect::<Result<_, _>>()?;
9920 self.call_function_by_name(&first.name.name, arg_values)?
9921 } else {
9922 self.environment
9924 .borrow()
9925 .get(&first.name.name)
9926 .ok_or_else(|| RuntimeError::new(format!("undefined: {}", first.name.name)))?
9927 };
9928
9929 for segment in segments.iter().skip(1) {
9931 let arg_values: Vec<Value> = segment
9932 .args
9933 .as_ref()
9934 .map(|args| {
9935 args.iter()
9936 .map(|a| self.evaluate(a))
9937 .collect::<Result<Vec<_>, _>>()
9938 })
9939 .transpose()?
9940 .unwrap_or_default();
9941
9942 value = self.call_incorporation_method(&value, &segment.name.name, arg_values)?;
9944 }
9945
9946 Ok(value)
9947 }
9948
9949 fn call_incorporation_method(
9952 &mut self,
9953 receiver: &Value,
9954 method_name: &str,
9955 args: Vec<Value>,
9956 ) -> Result<Value, RuntimeError> {
9957 match (receiver, method_name) {
9959 (Value::String(s), "len") => Ok(Value::Int(s.len() as i64)),
9961 (Value::String(s), "upper")
9962 | (Value::String(s), "uppercase")
9963 | (Value::String(s), "to_uppercase") => Ok(Value::String(Rc::new(s.to_uppercase()))),
9964 (Value::String(s), "lower")
9965 | (Value::String(s), "lowercase")
9966 | (Value::String(s), "to_lowercase") => Ok(Value::String(Rc::new(s.to_lowercase()))),
9967 (Value::String(s), "trim") => Ok(Value::String(Rc::new(s.trim().to_string()))),
9968 (Value::String(s), "chars") => {
9969 let chars: Vec<Value> = s
9970 .chars()
9971 .map(|c| Value::String(Rc::new(c.to_string())))
9972 .collect();
9973 Ok(Value::Array(Rc::new(RefCell::new(chars))))
9974 }
9975 (Value::String(s), "lines") => {
9976 let lines: Vec<Value> = s
9977 .lines()
9978 .map(|l| Value::String(Rc::new(l.to_string())))
9979 .collect();
9980 Ok(Value::Array(Rc::new(RefCell::new(lines))))
9981 }
9982 (Value::String(s), "bytes") => {
9983 let bytes: Vec<Value> = s.bytes().map(|b| Value::Int(b as i64)).collect();
9984 Ok(Value::Array(Rc::new(RefCell::new(bytes))))
9985 }
9986 (Value::String(s), "parse_int") | (Value::String(s), "to_int") => s
9987 .parse::<i64>()
9988 .map(Value::Int)
9989 .map_err(|_| RuntimeError::new(format!("cannot parse '{}' as int", s))),
9990 (Value::String(s), "parse_float") | (Value::String(s), "to_float") => s
9991 .parse::<f64>()
9992 .map(Value::Float)
9993 .map_err(|_| RuntimeError::new(format!("cannot parse '{}' as float", s))),
9994 (Value::String(s), "as_str") => {
9995 if s.len() <= 10 {
9996 crate::sigil_debug!("DEBUG as_str: '{}'", s);
9997 }
9998 Ok(Value::String(s.clone()))
9999 }
10000 (Value::String(s), "to_string") => Ok(Value::String(s.clone())),
10001 (Value::String(s), "starts_with") => {
10002 if args.len() != 1 {
10003 return Err(RuntimeError::new("starts_with expects 1 argument"));
10004 }
10005 match &args[0] {
10006 Value::String(prefix) => Ok(Value::Bool(s.starts_with(prefix.as_str()))),
10007 _ => Err(RuntimeError::new("starts_with expects string")),
10008 }
10009 }
10010 (Value::String(s), "ends_with") => {
10011 if args.len() != 1 {
10012 return Err(RuntimeError::new("ends_with expects 1 argument"));
10013 }
10014 match &args[0] {
10015 Value::String(suffix) => Ok(Value::Bool(s.ends_with(suffix.as_str()))),
10016 _ => Err(RuntimeError::new("ends_with expects string")),
10017 }
10018 }
10019 (Value::String(s), "is_empty") => Ok(Value::Bool(s.is_empty())),
10020 (Value::String(s), "clone") => Ok(Value::String(Rc::new((**s).clone()))),
10021 (Value::String(s), "first") => s
10022 .chars()
10023 .next()
10024 .map(Value::Char)
10025 .ok_or_else(|| RuntimeError::new("empty string")),
10026 (Value::String(s), "last") => s
10027 .chars()
10028 .last()
10029 .map(Value::Char)
10030 .ok_or_else(|| RuntimeError::new("empty string")),
10031
10032 (Value::Array(arr), "len") => Ok(Value::Int(arr.borrow().len() as i64)),
10034 (Value::Array(arr), "first") | (Value::Array(arr), "next") => {
10035 Ok(arr.borrow().first().cloned().unwrap_or(Value::Null))
10036 }
10037 (Value::Array(arr), "last") => arr
10038 .borrow()
10039 .last()
10040 .cloned()
10041 .ok_or_else(|| RuntimeError::new("empty array")),
10042 (Value::Array(arr), "reverse") | (Value::Array(arr), "rev") => {
10043 let mut v = arr.borrow().clone();
10044 v.reverse();
10045 Ok(Value::Array(Rc::new(RefCell::new(v))))
10046 }
10047 (Value::Array(arr), "join") => {
10048 let sep = args
10049 .first()
10050 .map(|v| match v {
10051 Value::String(s) => s.to_string(),
10052 _ => "".to_string(),
10053 })
10054 .unwrap_or_default();
10055 let joined = arr
10056 .borrow()
10057 .iter()
10058 .map(|v| format!("{}", v))
10059 .collect::<Vec<_>>()
10060 .join(&sep);
10061 Ok(Value::String(Rc::new(joined)))
10062 }
10063 (Value::Array(arr), "sum") => {
10064 let mut sum = 0i64;
10065 for v in arr.borrow().iter() {
10066 match v {
10067 Value::Int(i) => sum += i,
10068 Value::Float(f) => return Ok(Value::Float(sum as f64 + f)),
10069 _ => {}
10070 }
10071 }
10072 Ok(Value::Int(sum))
10073 }
10074 (Value::Array(arr), "skip") => {
10075 let n = match args.first() {
10076 Some(Value::Int(i)) => *i as usize,
10077 _ => 1,
10078 };
10079 let v: Vec<Value> = arr.borrow().iter().skip(n).cloned().collect();
10080 Ok(Value::Array(Rc::new(RefCell::new(v))))
10081 }
10082 (Value::Array(arr), "take") => {
10083 let n = match args.first() {
10084 Some(Value::Int(i)) => *i as usize,
10085 _ => 1,
10086 };
10087 let v: Vec<Value> = arr.borrow().iter().take(n).cloned().collect();
10088 Ok(Value::Array(Rc::new(RefCell::new(v))))
10089 }
10090 (Value::Array(arr), "step_by") => {
10091 let n = match args.first() {
10092 Some(Value::Int(i)) if *i > 0 => *i as usize,
10093 _ => 1,
10094 };
10095 let v: Vec<Value> = arr.borrow().iter().step_by(n).cloned().collect();
10096 Ok(Value::Array(Rc::new(RefCell::new(v))))
10097 }
10098
10099 (Value::Int(n), "abs") => Ok(Value::Int(n.abs())),
10101 (Value::Float(n), "abs") => Ok(Value::Float(n.abs())),
10102 (Value::Int(n), "to_string") | (Value::Int(n), "string") => {
10103 Ok(Value::String(Rc::new(n.to_string())))
10104 }
10105 (Value::Float(n), "to_string") | (Value::Float(n), "string") => {
10106 Ok(Value::String(Rc::new(n.to_string())))
10107 }
10108 (Value::Int(n), "to_float") | (Value::Int(n), "float") => Ok(Value::Float(*n as f64)),
10109 (Value::Float(n), "to_int") | (Value::Float(n), "int") => Ok(Value::Int(*n as i64)),
10110
10111 (Value::Map(map), field) => map
10113 .borrow()
10114 .get(field)
10115 .cloned()
10116 .ok_or_else(|| RuntimeError::new(format!("no field '{}' in map", field))),
10117 (Value::Struct { fields, .. }, field) => fields
10118 .borrow()
10119 .get(field)
10120 .cloned()
10121 .ok_or_else(|| RuntimeError::new(format!("no field '{}' in struct", field))),
10122
10123 _ => {
10125 let mut all_args = vec![receiver.clone()];
10126 all_args.extend(args);
10127 self.call_function_by_name(method_name, all_args)
10128 }
10129 }
10130 }
10131
10132 pub fn call_function_by_name(
10134 &mut self,
10135 name: &str,
10136 args: Vec<Value>,
10137 ) -> Result<Value, RuntimeError> {
10138 let func_value = self.environment.borrow().get(name);
10140
10141 match func_value {
10142 Some(Value::Function(f)) => self.call_function(&f, args),
10143 Some(Value::BuiltIn(b)) => self.call_builtin(&b, args),
10144 Some(_) => Err(RuntimeError::new(format!("{} is not a function", name))),
10145 None => {
10146 if let Some((enum_name, variant_name, arity)) =
10148 self.variant_constructors.get(name).cloned()
10149 {
10150 if arity == 0 && args.is_empty() {
10151 return Ok(Value::Variant {
10152 enum_name,
10153 variant_name,
10154 fields: None,
10155 });
10156 } else if args.len() == arity {
10157 return Ok(Value::Variant {
10158 enum_name,
10159 variant_name,
10160 fields: Some(Rc::new(args)),
10161 });
10162 } else {
10163 return Err(RuntimeError::new(format!(
10164 "{} expects {} arguments, got {}",
10165 name,
10166 arity,
10167 args.len()
10168 )));
10169 }
10170 }
10171 Err(RuntimeError::new(format!("undefined function: {}", name)))
10172 }
10173 }
10174 }
10175
10176 fn eval_pipe(&mut self, expr: &Expr, operations: &[PipeOp]) -> Result<Value, RuntimeError> {
10177 let mut value = self.evaluate(expr)?;
10178
10179 for op in operations {
10180 value = self.apply_pipe_op(value, op)?;
10181 }
10182
10183 Ok(value)
10184 }
10185
10186 fn apply_pipe_op(&mut self, value: Value, op: &PipeOp) -> Result<Value, RuntimeError> {
10187 let value = Self::unwrap_all(&value);
10189
10190 match op {
10191 PipeOp::Transform(body) => {
10192 let (param_pattern, inner_body) = match body.as_ref() {
10195 Expr::Closure { params, body, .. } => {
10196 let pattern = params.first().map(|p| p.pattern.clone());
10197 (pattern, body.as_ref())
10198 }
10199 _ => (None, body.as_ref()),
10200 };
10201
10202 match value {
10203 Value::Array(arr) => {
10204 let results: Vec<Value> = arr
10205 .borrow()
10206 .iter()
10207 .map(|item| {
10208 if let Some(ref pattern) = param_pattern {
10210 self.bind_pattern(pattern, item.clone())?;
10211 } else {
10212 self.environment
10213 .borrow_mut()
10214 .define("_".to_string(), item.clone());
10215 }
10216 self.evaluate(inner_body)
10217 })
10218 .collect::<Result<_, _>>()?;
10219 Ok(Value::Array(Rc::new(RefCell::new(results))))
10220 }
10221 single => {
10222 if let Some(ref pattern) = param_pattern {
10223 self.bind_pattern(pattern, single)?;
10224 } else {
10225 self.environment
10226 .borrow_mut()
10227 .define("_".to_string(), single);
10228 }
10229 self.evaluate(inner_body)
10230 }
10231 }
10232 }
10233 PipeOp::Filter(predicate) => {
10234 let (param_pattern, inner_pred) = match predicate.as_ref() {
10237 Expr::Closure { params, body, .. } => {
10238 let pattern = params.first().map(|p| p.pattern.clone());
10239 (pattern, body.as_ref())
10240 }
10241 _ => (None, predicate.as_ref()),
10242 };
10243
10244 match value {
10245 Value::Array(arr) => {
10246 let results: Vec<Value> = arr
10247 .borrow()
10248 .iter()
10249 .filter_map(|item| {
10250 if let Some(ref pattern) = param_pattern {
10252 if let Err(e) = self.bind_pattern(pattern, item.clone()) {
10253 return Some(Err(e));
10254 }
10255 } else {
10256 self.environment
10257 .borrow_mut()
10258 .define("_".to_string(), item.clone());
10259 }
10260 match self.evaluate(inner_pred) {
10261 Ok(v) if self.is_truthy(&v) => Some(Ok(item.clone())),
10262 Ok(_) => None,
10263 Err(e) => Some(Err(e)),
10264 }
10265 })
10266 .collect::<Result<_, _>>()?;
10267 Ok(Value::Array(Rc::new(RefCell::new(results))))
10268 }
10269 _ => Err(RuntimeError::new("Filter requires array")),
10270 }
10271 }
10272 PipeOp::Sort(field) => {
10273 match value {
10275 Value::Array(arr) => {
10276 let mut v = arr.borrow().clone();
10277 v.sort_by(|a, b| self.compare_values(a, b, field));
10278 Ok(Value::Array(Rc::new(RefCell::new(v))))
10279 }
10280 Value::Struct { ref name, .. } if name == "Tensor" => {
10282 self.sum_values(value)
10283 }
10284 _ => Err(RuntimeError::new("Sort requires array")),
10285 }
10286 }
10287 PipeOp::Reduce(body) => {
10288 match value {
10290 Value::Array(arr) => {
10291 let arr = arr.borrow();
10292 if arr.is_empty() {
10293 return Err(RuntimeError::new("Cannot reduce empty array"));
10294 }
10295 let mut acc = arr[0].clone();
10296 for item in arr.iter().skip(1) {
10297 self.environment.borrow_mut().define("acc".to_string(), acc);
10298 self.environment
10299 .borrow_mut()
10300 .define("_".to_string(), item.clone());
10301 acc = self.evaluate(body)?;
10302 }
10303 Ok(acc)
10304 }
10305 _ => Err(RuntimeError::new("Reduce requires array")),
10306 }
10307 }
10308 PipeOp::ReduceSum => {
10309 self.sum_values(value)
10311 }
10312 PipeOp::ReduceProd => {
10313 self.product_values(value)
10315 }
10316 PipeOp::ReduceMin => {
10317 self.min_values(value)
10319 }
10320 PipeOp::ReduceMax => {
10321 self.max_values(value)
10323 }
10324 PipeOp::ReduceConcat => {
10325 self.concat_values(value)
10327 }
10328 PipeOp::ReduceAll => {
10329 self.all_values(value)
10331 }
10332 PipeOp::ReduceAny => {
10333 self.any_values(value)
10335 }
10336 PipeOp::Match(arms) => {
10337 for arm in arms {
10339 if self.pattern_matches(&arm.pattern, &value)? {
10340 let prev_env = self.environment.clone();
10342 self.environment =
10343 Rc::new(RefCell::new(Environment::with_parent(prev_env.clone())));
10344
10345 self.bind_pattern(&arm.pattern, value.clone())?;
10347
10348 self.environment
10350 .borrow_mut()
10351 .define("_".to_string(), value.clone());
10352
10353 let guard_passes = if let Some(guard) = &arm.guard {
10355 matches!(self.evaluate(guard)?, Value::Bool(true))
10356 } else {
10357 true
10358 };
10359
10360 if guard_passes {
10361 let result = self.evaluate(&arm.body)?;
10362 self.environment = prev_env;
10363 return Ok(result);
10364 }
10365
10366 self.environment = prev_env;
10368 }
10369 }
10370 Err(RuntimeError::new("No pattern matched in pipe match"))
10371 }
10372 PipeOp::TryMap(mapper) => {
10373 match &value {
10375 Value::Struct { name, fields } if name == "Ok" || name.ends_with("::Ok") => {
10377 let fields = fields.borrow();
10379 fields
10380 .get("0")
10381 .or_else(|| fields.get("value"))
10382 .cloned()
10383 .ok_or_else(|| RuntimeError::new("Ok variant has no value"))
10384 }
10385 Value::Struct { name, fields } if name == "Err" || name.ends_with("::Err") => {
10386 let fields = fields.borrow();
10388 let err_val = fields
10389 .get("0")
10390 .or_else(|| fields.get("error"))
10391 .cloned()
10392 .unwrap_or(Value::Null);
10393 if let Some(mapper_expr) = mapper {
10394 let prev_env = self.environment.clone();
10396 self.environment =
10397 Rc::new(RefCell::new(Environment::with_parent(prev_env.clone())));
10398 self.environment
10399 .borrow_mut()
10400 .define("_".to_string(), err_val);
10401 let mapped = self.evaluate(mapper_expr)?;
10402 self.environment = prev_env;
10403 Err(RuntimeError::new(format!("Error: {:?}", mapped)))
10404 } else {
10405 Err(RuntimeError::new(format!("Error: {:?}", err_val)))
10406 }
10407 }
10408 Value::Struct { name, fields }
10410 if name == "Some" || name.ends_with("::Some") =>
10411 {
10412 let fields = fields.borrow();
10413 fields
10414 .get("0")
10415 .or_else(|| fields.get("value"))
10416 .cloned()
10417 .ok_or_else(|| RuntimeError::new("Some variant has no value"))
10418 }
10419 Value::Struct { name, .. } if name == "None" || name.ends_with("::None") => {
10420 Err(RuntimeError::new("Unwrapped None value"))
10421 }
10422 Value::Null => Err(RuntimeError::new("Unwrapped null value")),
10423 _ => Ok(value),
10425 }
10426 }
10427 PipeOp::Call(callee) => {
10428 let callee_val = self.evaluate(callee)?;
10430 match callee_val {
10431 Value::Function(f) => {
10432 self.call_function(&f, vec![value])
10434 }
10435 Value::BuiltIn(b) => {
10436 self.call_builtin(&b, vec![value])
10438 }
10439 Value::Struct { .. } => {
10440 Ok(value)
10443 }
10444 _ => Err(RuntimeError::new(format!(
10445 "Cannot call non-function value in pipe: {:?}",
10446 callee_val
10447 ))),
10448 }
10449 }
10450 PipeOp::Method {
10451 name,
10452 type_args: _,
10453 args,
10454 } => {
10455 let arg_values: Vec<Value> = args
10456 .iter()
10457 .map(|a| self.evaluate(a))
10458 .collect::<Result<_, _>>()?;
10459
10460 match name.name.as_str() {
10462 "collect" => Ok(value), "sum" | "Σ" => self.sum_values(value),
10464 "product" | "Π" => self.product_values(value),
10465 "len" => match &value {
10466 Value::Array(arr) => Ok(Value::Int(arr.borrow().len() as i64)),
10467 Value::String(s) => Ok(Value::Int(s.len() as i64)),
10468 _ => Err(RuntimeError::new("len requires array or string")),
10469 },
10470 "reverse" => match value {
10471 Value::Array(arr) => {
10472 let mut v = arr.borrow().clone();
10473 v.reverse();
10474 Ok(Value::Array(Rc::new(RefCell::new(v))))
10475 }
10476 _ => Err(RuntimeError::new("reverse requires array")),
10477 },
10478 "iter" | "into_iter" => {
10479 Ok(value)
10481 }
10482 "enumerate" => {
10483 match &value {
10485 Value::Array(arr) => {
10486 let enumerated: Vec<Value> = arr
10487 .borrow()
10488 .iter()
10489 .enumerate()
10490 .map(|(i, v)| {
10491 Value::Tuple(Rc::new(vec![Value::Int(i as i64), v.clone()]))
10492 })
10493 .collect();
10494 Ok(Value::Array(Rc::new(RefCell::new(enumerated))))
10495 }
10496 _ => Err(RuntimeError::new("enumerate requires array")),
10497 }
10498 }
10499 "first" => match &value {
10500 Value::Array(arr) => arr
10501 .borrow()
10502 .first()
10503 .cloned()
10504 .ok_or_else(|| RuntimeError::new("first on empty array")),
10505 _ => Err(RuntimeError::new("first requires array")),
10506 },
10507 "last" => match &value {
10508 Value::Array(arr) => arr
10509 .borrow()
10510 .last()
10511 .cloned()
10512 .ok_or_else(|| RuntimeError::new("last on empty array")),
10513 _ => Err(RuntimeError::new("last requires array")),
10514 },
10515 "take" => {
10516 if arg_values.len() != 1 {
10517 return Err(RuntimeError::new("take requires 1 argument"));
10518 }
10519 let n = match &arg_values[0] {
10520 Value::Int(n) => *n as usize,
10521 _ => return Err(RuntimeError::new("take requires integer")),
10522 };
10523 match value {
10524 Value::Array(arr) => {
10525 let v: Vec<Value> = arr.borrow().iter().take(n).cloned().collect();
10526 Ok(Value::Array(Rc::new(RefCell::new(v))))
10527 }
10528 _ => Err(RuntimeError::new("take requires array")),
10529 }
10530 }
10531 "skip" => {
10532 if arg_values.len() != 1 {
10533 return Err(RuntimeError::new("skip requires 1 argument"));
10534 }
10535 let n = match &arg_values[0] {
10536 Value::Int(n) => *n as usize,
10537 _ => return Err(RuntimeError::new("skip requires integer")),
10538 };
10539 match value {
10540 Value::Array(arr) => {
10541 let v: Vec<Value> = arr.borrow().iter().skip(n).cloned().collect();
10542 Ok(Value::Array(Rc::new(RefCell::new(v))))
10543 }
10544 _ => Err(RuntimeError::new("skip requires array")),
10545 }
10546 }
10547 "join" => {
10548 let separator = if arg_values.is_empty() {
10550 String::new()
10551 } else {
10552 match &arg_values[0] {
10553 Value::String(s) => (**s).clone(),
10554 _ => {
10555 return Err(RuntimeError::new("join separator must be string"))
10556 }
10557 }
10558 };
10559 match value {
10560 Value::Array(arr) => {
10561 let parts: Vec<String> = arr
10562 .borrow()
10563 .iter()
10564 .map(|v| format!("{}", Self::unwrap_all(v)))
10565 .collect();
10566 Ok(Value::String(Rc::new(parts.join(&separator))))
10567 }
10568 _ => Err(RuntimeError::new("join requires array")),
10569 }
10570 }
10571 "all" => {
10572 match value {
10574 Value::Array(arr) => {
10575 for item in arr.borrow().iter() {
10576 if !self.is_truthy(item) {
10577 return Ok(Value::Bool(false));
10578 }
10579 }
10580 Ok(Value::Bool(true))
10581 }
10582 _ => Err(RuntimeError::new("all requires array")),
10583 }
10584 }
10585 "any" => {
10586 match value {
10588 Value::Array(arr) => {
10589 for item in arr.borrow().iter() {
10590 if self.is_truthy(item) {
10591 return Ok(Value::Bool(true));
10592 }
10593 }
10594 Ok(Value::Bool(false))
10595 }
10596 _ => Err(RuntimeError::new("any requires array")),
10597 }
10598 }
10599 "map" => {
10600 if arg_values.len() != 1 {
10602 return Err(RuntimeError::new("map expects 1 argument (closure)"));
10603 }
10604 match (&value, &arg_values[0]) {
10605 (Value::Array(arr), Value::Function(f)) => {
10606 let mut results = Vec::new();
10607 for val in arr.borrow().iter() {
10608 let result = self.call_function(f, vec![val.clone()])?;
10609 results.push(result);
10610 }
10611 Ok(Value::Array(Rc::new(RefCell::new(results))))
10612 }
10613 (Value::Array(_), _) => {
10614 Err(RuntimeError::new("map expects closure argument"))
10615 }
10616 _ => Err(RuntimeError::new("map requires array")),
10617 }
10618 }
10619 "filter" => {
10620 if arg_values.len() != 1 {
10622 return Err(RuntimeError::new("filter expects 1 argument (closure)"));
10623 }
10624 match (&value, &arg_values[0]) {
10625 (Value::Array(arr), Value::Function(f)) => {
10626 let mut results = Vec::new();
10627 for val in arr.borrow().iter() {
10628 let keep = self.call_function(f, vec![val.clone()])?;
10629 if matches!(keep, Value::Bool(true)) {
10630 results.push(val.clone());
10631 }
10632 }
10633 Ok(Value::Array(Rc::new(RefCell::new(results))))
10634 }
10635 (Value::Array(_), _) => {
10636 Err(RuntimeError::new("filter expects closure argument"))
10637 }
10638 _ => Err(RuntimeError::new("filter requires array")),
10639 }
10640 }
10641 "fold" => {
10642 if arg_values.len() != 2 {
10644 return Err(RuntimeError::new(
10645 "fold expects 2 arguments (init, closure)",
10646 ));
10647 }
10648 match (&value, &arg_values[1]) {
10649 (Value::Array(arr), Value::Function(f)) => {
10650 let mut acc = arg_values[0].clone();
10651 for val in arr.borrow().iter() {
10652 acc = self.call_function(f, vec![acc, val.clone()])?;
10653 }
10654 Ok(acc)
10655 }
10656 (Value::Array(_), _) => {
10657 Err(RuntimeError::new("fold expects closure as second argument"))
10658 }
10659 _ => Err(RuntimeError::new("fold requires array")),
10660 }
10661 }
10662 _ => {
10663 if let Value::Struct {
10665 name: struct_name,
10666 fields,
10667 } = &value
10668 {
10669 match (struct_name.as_str(), name.name.as_str()) {
10671 ("HyperLogLog", "count") => {
10672 if let Some(Value::Array(regs)) = fields.borrow().get("_registers") {
10673 let regs_borrow = regs.borrow();
10674 let m = regs_borrow.len() as f64;
10675 let mut sum = 0.0;
10676 let mut zeros = 0;
10677 for reg in regs_borrow.iter() {
10678 let val = match reg {
10679 Value::Int(v) => *v as i32,
10680 _ => 0,
10681 };
10682 sum += 2.0_f64.powi(-val);
10683 if val == 0 {
10684 zeros += 1;
10685 }
10686 }
10687 let alpha = 0.7213 / (1.0 + 1.079 / m);
10688 let estimate = alpha * m * m / sum;
10689 let result = if estimate <= 2.5 * m && zeros > 0 {
10690 m * (m / zeros as f64).ln()
10691 } else {
10692 estimate
10693 };
10694 return Ok(Value::Int(result.round() as i64));
10695 }
10696 return Ok(Value::Int(0));
10697 }
10698 ("BloomFilter", "contains") => {
10699 if arg_values.len() != 1 {
10700 return Err(RuntimeError::new(
10701 "BloomFilter.contains expects 1 argument",
10702 ));
10703 }
10704 let size = match fields.borrow().get("_size") {
10705 Some(Value::Int(s)) => *s as usize,
10706 _ => 1024,
10707 };
10708 let num_hashes = match fields.borrow().get("_num_hashes") {
10709 Some(Value::Int(n)) => *n as usize,
10710 _ => 3,
10711 };
10712 let base_hash = match &arg_values[0] {
10713 Value::String(s) => {
10714 use std::collections::hash_map::DefaultHasher;
10715 use std::hash::{Hash, Hasher};
10716 let mut hasher = DefaultHasher::new();
10717 s.hash(&mut hasher);
10718 hasher.finish()
10719 }
10720 Value::Int(n) => *n as u64,
10721 other => {
10722 use std::collections::hash_map::DefaultHasher;
10723 use std::hash::{Hash, Hasher};
10724 let mut hasher = DefaultHasher::new();
10725 format!("{:?}", other).hash(&mut hasher);
10726 hasher.finish()
10727 }
10728 };
10729 if let Some(Value::Array(bits)) = fields.borrow().get("_bits") {
10730 let bits_borrow = bits.borrow();
10731 for i in 0..num_hashes {
10732 let h = (base_hash.wrapping_add(i as u64 * base_hash.rotate_left(17)))
10733 % size as u64;
10734 match &bits_borrow[h as usize] {
10735 Value::Bool(true) => {}
10736 _ => return Ok(Value::Bool(false)),
10737 }
10738 }
10739 return Ok(Value::Bool(true));
10740 }
10741 return Ok(Value::Bool(false));
10742 }
10743 ("CountMinSketch", "frequency") => {
10744 if arg_values.len() != 1 {
10745 return Err(RuntimeError::new(
10746 "CountMinSketch.frequency expects 1 argument",
10747 ));
10748 }
10749 let depth = match fields.borrow().get("_depth") {
10750 Some(Value::Int(d)) => *d as usize,
10751 _ => 4,
10752 };
10753 let width = match fields.borrow().get("_width") {
10754 Some(Value::Int(w)) => *w as usize,
10755 _ => 1024,
10756 };
10757 let base_hash = match &arg_values[0] {
10758 Value::String(s) => {
10759 use std::collections::hash_map::DefaultHasher;
10760 use std::hash::{Hash, Hasher};
10761 let mut hasher = DefaultHasher::new();
10762 s.hash(&mut hasher);
10763 hasher.finish()
10764 }
10765 Value::Int(n) => *n as u64,
10766 other => {
10767 use std::collections::hash_map::DefaultHasher;
10768 use std::hash::{Hash, Hasher};
10769 let mut hasher = DefaultHasher::new();
10770 format!("{:?}", other).hash(&mut hasher);
10771 hasher.finish()
10772 }
10773 };
10774 let mut min_count = i64::MAX;
10775 if let Some(Value::Array(counters)) = fields.borrow().get("_counters") {
10776 let counters_borrow = counters.borrow();
10777 for i in 0..depth {
10778 let h = (base_hash.wrapping_add(i as u64 * 0x517cc1b727220a95))
10779 % width as u64;
10780 if let Value::Array(row) = &counters_borrow[i] {
10781 let row_borrow = row.borrow();
10782 if let Value::Int(c) = &row_borrow[h as usize] {
10783 if *c < min_count {
10784 min_count = *c;
10785 }
10786 }
10787 }
10788 }
10789 }
10790 return Ok(Value::Int(if min_count == i64::MAX { 0 } else { min_count }));
10791 }
10792 ("MerkleTree", "verify") => {
10793 use std::collections::hash_map::DefaultHasher;
10794 use std::hash::{Hash, Hasher};
10795 if let (Some(Value::Array(leaves)), Some(Value::String(root))) = (
10796 fields.borrow().get("_leaves").cloned(),
10797 fields.borrow().get("_root").cloned(),
10798 ) {
10799 let leaves_borrow = leaves.borrow();
10800 let combined: String = leaves_borrow
10801 .iter()
10802 .filter_map(|v| match v {
10803 Value::String(s) => Some(s.to_string()),
10804 _ => None,
10805 })
10806 .collect();
10807 let mut hasher = DefaultHasher::new();
10808 combined.hash(&mut hasher);
10809 let computed_root = format!("{:016x}", hasher.finish());
10810 return Ok(Value::Bool(*root == computed_root));
10811 }
10812 return Ok(Value::Bool(false));
10813 }
10814 ("MerkleProof", "verify") => {
10815 if let Some(Value::Bool(valid)) = fields.borrow().get("_valid") {
10817 return Ok(Value::Bool(*valid));
10818 }
10819 return Ok(Value::Bool(false));
10820 }
10821 ("UntrustedData", "verify") => {
10822 if let Some(val) = fields.borrow().get("value").cloned() {
10824 return Ok(val);
10825 }
10826 return Ok(Value::Bool(true));
10827 }
10828 ("Superposition", "observe") => {
10829 if let Some(Value::Array(values)) = fields.borrow().get("_values") {
10832 let values_borrow = values.borrow();
10833 if !values_borrow.is_empty() {
10834 return Ok(values_borrow[0].clone());
10835 }
10836 }
10837 if let Some(Value::Array(states)) = fields.borrow().get("states") {
10839 let states_borrow = states.borrow();
10840 if !states_borrow.is_empty() {
10841 return Ok(states_borrow[0].clone());
10842 }
10843 }
10844 return Ok(Value::Null);
10845 }
10846 ("Qubit", "H") => {
10848 let alpha_real = match fields.borrow().get("_alpha_real") {
10850 Some(Value::Float(f)) => *f,
10851 _ => 1.0,
10852 };
10853 let beta_real = match fields.borrow().get("_beta_real") {
10854 Some(Value::Float(f)) => *f,
10855 _ => 0.0,
10856 };
10857 let sqrt2_inv = 1.0 / std::f64::consts::SQRT_2;
10858 let new_alpha = (alpha_real + beta_real) * sqrt2_inv;
10860 let new_beta = (alpha_real - beta_real) * sqrt2_inv;
10861
10862 let mut new_fields = std::collections::HashMap::new();
10863 new_fields.insert("_alpha_real".to_string(), Value::Float(new_alpha));
10864 new_fields.insert("_alpha_imag".to_string(), Value::Float(0.0));
10865 new_fields.insert("_beta_real".to_string(), Value::Float(new_beta));
10866 new_fields.insert("_beta_imag".to_string(), Value::Float(0.0));
10867 return Ok(Value::Struct {
10868 name: "Qubit".to_string(),
10869 fields: Rc::new(RefCell::new(new_fields)),
10870 });
10871 }
10872 ("Qubit", "X") => {
10873 let alpha_real = match fields.borrow().get("_alpha_real") {
10875 Some(Value::Float(f)) => *f,
10876 _ => 1.0,
10877 };
10878 let alpha_imag = match fields.borrow().get("_alpha_imag") {
10879 Some(Value::Float(f)) => *f,
10880 _ => 0.0,
10881 };
10882 let beta_real = match fields.borrow().get("_beta_real") {
10883 Some(Value::Float(f)) => *f,
10884 _ => 0.0,
10885 };
10886 let beta_imag = match fields.borrow().get("_beta_imag") {
10887 Some(Value::Float(f)) => *f,
10888 _ => 0.0,
10889 };
10890 let mut new_fields = std::collections::HashMap::new();
10892 new_fields.insert("_alpha_real".to_string(), Value::Float(beta_real));
10893 new_fields.insert("_alpha_imag".to_string(), Value::Float(beta_imag));
10894 new_fields.insert("_beta_real".to_string(), Value::Float(alpha_real));
10895 new_fields.insert("_beta_imag".to_string(), Value::Float(alpha_imag));
10896 return Ok(Value::Struct {
10897 name: "Qubit".to_string(),
10898 fields: Rc::new(RefCell::new(new_fields)),
10899 });
10900 }
10901 ("Qubit", "measure") => {
10902 let alpha_real = match fields.borrow().get("_alpha_real") {
10905 Some(Value::Float(f)) => *f,
10906 _ => 1.0,
10907 };
10908 let alpha_imag = match fields.borrow().get("_alpha_imag") {
10909 Some(Value::Float(f)) => *f,
10910 _ => 0.0,
10911 };
10912 let beta_real = match fields.borrow().get("_beta_real") {
10913 Some(Value::Float(f)) => *f,
10914 _ => 0.0,
10915 };
10916 let beta_imag = match fields.borrow().get("_beta_imag") {
10917 Some(Value::Float(f)) => *f,
10918 _ => 0.0,
10919 };
10920 let alpha_sq = alpha_real * alpha_real + alpha_imag * alpha_imag;
10921 let beta_sq = beta_real * beta_real + beta_imag * beta_imag;
10922 let result = if alpha_sq >= beta_sq { 0 } else { 1 };
10925 return Ok(Value::Int(result));
10926 }
10927 ("QRegister", "H_all") => {
10929 let size = match fields.borrow().get("_size") {
10931 Some(Value::Int(n)) => *n as usize,
10932 _ => 1,
10933 };
10934 let state: Vec<f64> = match fields.borrow().get("_state") {
10935 Some(Value::Array(arr)) => {
10936 arr.borrow().iter().filter_map(|v| match v {
10937 Value::Float(f) => Some(*f),
10938 _ => None,
10939 }).collect()
10940 }
10941 _ => vec![1.0],
10942 };
10943
10944 let dim = 1 << size; let amp = 1.0 / (dim as f64).sqrt();
10948 let new_state: Vec<Value> = (0..dim)
10949 .map(|_| Value::Float(amp))
10950 .collect();
10951
10952 let mut new_fields = HashMap::new();
10953 new_fields.insert("_size".to_string(), Value::Int(size as i64));
10954 new_fields.insert("_state".to_string(), Value::Array(Rc::new(RefCell::new(new_state))));
10955
10956 return Ok(Value::Struct {
10957 name: "QRegister".to_string(),
10958 fields: Rc::new(RefCell::new(new_fields)),
10959 });
10960 }
10961 ("QRegister", "measure_all") => {
10962 let size = match fields.borrow().get("_size") {
10964 Some(Value::Int(n)) => *n as usize,
10965 _ => 1,
10966 };
10967 let state: Vec<f64> = match fields.borrow().get("_state") {
10968 Some(Value::Array(arr)) => {
10969 arr.borrow().iter().filter_map(|v| match v {
10970 Value::Float(f) => Some(*f),
10971 _ => None,
10972 }).collect()
10973 }
10974 _ => vec![1.0],
10975 };
10976
10977 let mut max_idx = 0;
10979 let mut max_amp_sq = 0.0;
10980 for (i, amp) in state.iter().enumerate() {
10981 let amp_sq = amp * amp;
10982 if amp_sq > max_amp_sq {
10983 max_amp_sq = amp_sq;
10984 max_idx = i;
10985 }
10986 }
10987
10988 let mut results: Vec<Value> = Vec::new();
10990 for bit in 0..size {
10991 let cbit_value = (max_idx >> (size - 1 - bit)) & 1;
10992 results.push(Value::Int(cbit_value as i64));
10994 }
10995
10996 return Ok(Value::Array(Rc::new(RefCell::new(results))));
10997 }
10998 _ => {}
10999 }
11000 }
11001 if (name.name == "Rx" || name.name == "Ry" || name.name == "Rz") {
11003 if let Value::Struct { name: sname, fields } = &value {
11004 if sname == "Qubit" {
11005 let angle = if !arg_values.is_empty() {
11007 match &arg_values[0] {
11008 Value::Float(f) => *f,
11009 Value::Int(n) => *n as f64,
11010 _ => 0.0,
11011 }
11012 } else {
11013 0.0
11014 };
11015
11016 let alpha_real = match fields.borrow().get("_alpha_real") {
11017 Some(Value::Float(f)) => *f,
11018 _ => 1.0,
11019 };
11020 let alpha_imag = match fields.borrow().get("_alpha_imag") {
11021 Some(Value::Float(f)) => *f,
11022 _ => 0.0,
11023 };
11024 let beta_real = match fields.borrow().get("_beta_real") {
11025 Some(Value::Float(f)) => *f,
11026 _ => 0.0,
11027 };
11028 let beta_imag = match fields.borrow().get("_beta_imag") {
11029 Some(Value::Float(f)) => *f,
11030 _ => 0.0,
11031 };
11032
11033 let (new_alpha_real, new_alpha_imag, new_beta_real, new_beta_imag) = match name.name.as_str() {
11034 "Rx" => {
11035 let cos_half = (angle / 2.0).cos();
11037 let sin_half = (angle / 2.0).sin();
11038 let nar = cos_half * alpha_real + sin_half * beta_imag;
11041 let nai = cos_half * alpha_imag - sin_half * beta_real;
11042 let nbr = sin_half * alpha_imag + cos_half * beta_real;
11043 let nbi = -sin_half * alpha_real + cos_half * beta_imag;
11044 (nar, nai, nbr, nbi)
11045 }
11046 "Ry" => {
11047 let cos_half = (angle / 2.0).cos();
11049 let sin_half = (angle / 2.0).sin();
11050 let nar = cos_half * alpha_real - sin_half * beta_real;
11051 let nai = cos_half * alpha_imag - sin_half * beta_imag;
11052 let nbr = sin_half * alpha_real + cos_half * beta_real;
11053 let nbi = sin_half * alpha_imag + cos_half * beta_imag;
11054 (nar, nai, nbr, nbi)
11055 }
11056 "Rz" => {
11057 let cos_half = (angle / 2.0).cos();
11059 let sin_half = (angle / 2.0).sin();
11060 let nar = cos_half * alpha_real + sin_half * alpha_imag;
11062 let nai = -sin_half * alpha_real + cos_half * alpha_imag;
11063 let nbr = cos_half * beta_real - sin_half * beta_imag;
11065 let nbi = sin_half * beta_real + cos_half * beta_imag;
11066 (nar, nai, nbr, nbi)
11067 }
11068 _ => (alpha_real, alpha_imag, beta_real, beta_imag),
11069 };
11070
11071 let mut new_fields = std::collections::HashMap::new();
11072 new_fields.insert("_alpha_real".to_string(), Value::Float(new_alpha_real));
11073 new_fields.insert("_alpha_imag".to_string(), Value::Float(new_alpha_imag));
11074 new_fields.insert("_beta_real".to_string(), Value::Float(new_beta_real));
11075 new_fields.insert("_beta_imag".to_string(), Value::Float(new_beta_imag));
11076 return Ok(Value::Struct {
11077 name: "Qubit".to_string(),
11078 fields: Rc::new(RefCell::new(new_fields)),
11079 });
11080 }
11081 }
11082 }
11083 if name.name == "observe" {
11085 if let Value::Struct { name: sname, fields } = &value {
11086 if sname == "Superposition" {
11087 if let Some(Value::Array(values)) = fields.borrow().get("_values") {
11089 let values_borrow = values.borrow();
11090 if !values_borrow.is_empty() {
11091 return Ok(values_borrow[0].clone());
11092 }
11093 }
11094 if let Some(Value::Array(states)) = fields.borrow().get("states") {
11096 let states_borrow = states.borrow();
11097 if !states_borrow.is_empty() {
11098 return Ok(states_borrow[0].clone());
11099 }
11100 }
11101 return Ok(Value::Null);
11102 }
11103 }
11104 }
11105 if name.name == "encode" {
11107 let data_shards = 4i64;
11109 let parity_shards = 3i64;
11110 let total_shards = data_shards + parity_shards;
11111
11112 let shards: Vec<Value> = (0..total_shards)
11114 .map(|i| {
11115 let mut shard_fields = std::collections::HashMap::new();
11116 shard_fields.insert("index".to_string(), Value::Int(i));
11117 shard_fields.insert("data".to_string(), Value::String(Rc::new(format!("shard_{}", i))));
11118 Value::Struct {
11119 name: "Shard".to_string(),
11120 fields: Rc::new(RefCell::new(shard_fields)),
11121 }
11122 })
11123 .collect();
11124
11125 let mut holo_fields = std::collections::HashMap::new();
11126 holo_fields.insert("shards".to_string(), Value::Array(Rc::new(RefCell::new(shards))));
11127 holo_fields.insert("_data_shards".to_string(), Value::Int(data_shards));
11128 holo_fields.insert("_parity_shards".to_string(), Value::Int(parity_shards));
11129 holo_fields.insert("_original".to_string(), value.clone());
11130
11131 return Ok(Value::Struct {
11132 name: "Hologram".to_string(),
11133 fields: Rc::new(RefCell::new(holo_fields)),
11134 });
11135 }
11136 if name.name == "requires_grad" {
11138 if let Value::Struct { name: sname, fields } = &value {
11139 if sname == "Tensor" {
11140 let requires_grad = if !arg_values.is_empty() {
11142 match &arg_values[0] {
11143 Value::Bool(b) => *b,
11144 _ => true,
11145 }
11146 } else {
11147 true
11148 };
11149 let mut new_fields = fields.borrow().clone();
11151 new_fields.insert("requires_grad".to_string(), Value::Bool(requires_grad));
11152 return Ok(Value::Struct {
11153 name: "Tensor".to_string(),
11154 fields: Rc::new(RefCell::new(new_fields)),
11155 });
11156 }
11157 }
11158 }
11159 if name.name == "relu" {
11161 if let Value::Struct { name: sname, fields } = &value {
11162 if sname == "Tensor" {
11163 let fields_ref = fields.borrow();
11164 let shape = fields_ref.get("shape").cloned().unwrap_or(Value::Null);
11165 let data: Vec<f64> = match fields_ref.get("data") {
11166 Some(Value::Array(arr)) => {
11167 arr.borrow().iter().filter_map(|v| match v {
11168 Value::Float(f) => Some(*f),
11169 Value::Int(n) => Some(*n as f64),
11170 _ => None,
11171 }).collect()
11172 }
11173 _ => vec![],
11174 };
11175 drop(fields_ref);
11176 let relu_data: Vec<Value> = data.iter()
11178 .map(|&x| Value::Float(if x > 0.0 { x } else { 0.0 }))
11179 .collect();
11180 let mut new_fields = std::collections::HashMap::new();
11181 new_fields.insert("shape".to_string(), shape);
11182 new_fields.insert("data".to_string(), Value::Array(Rc::new(RefCell::new(relu_data))));
11183 new_fields.insert("requires_grad".to_string(), Value::Bool(false));
11184 return Ok(Value::Struct {
11185 name: "Tensor".to_string(),
11186 fields: Rc::new(RefCell::new(new_fields)),
11187 });
11188 }
11189 }
11190 }
11191 if name.name == "softmax" {
11193 if let Value::Struct { name: sname, fields } = &value {
11194 if sname == "Tensor" {
11195 let fields_ref = fields.borrow();
11196 let shape = fields_ref.get("shape").cloned().unwrap_or(Value::Null);
11197 let data: Vec<f64> = match fields_ref.get("data") {
11198 Some(Value::Array(arr)) => {
11199 arr.borrow().iter().filter_map(|v| match v {
11200 Value::Float(f) => Some(*f),
11201 Value::Int(n) => Some(*n as f64),
11202 _ => None,
11203 }).collect()
11204 }
11205 _ => vec![],
11206 };
11207 drop(fields_ref);
11208 let max_val = data.iter().cloned().fold(f64::NEG_INFINITY, f64::max);
11210 let exp_vals: Vec<f64> = data.iter()
11211 .map(|&x| (x - max_val).exp()) .collect();
11213 let sum_exp: f64 = exp_vals.iter().sum();
11214 let softmax_data: Vec<Value> = exp_vals.iter()
11215 .map(|&e| Value::Float(e / sum_exp))
11216 .collect();
11217 let mut new_fields = std::collections::HashMap::new();
11218 new_fields.insert("shape".to_string(), shape);
11219 new_fields.insert("data".to_string(), Value::Array(Rc::new(RefCell::new(softmax_data))));
11220 new_fields.insert("requires_grad".to_string(), Value::Bool(false));
11221 return Ok(Value::Struct {
11222 name: "Tensor".to_string(),
11223 fields: Rc::new(RefCell::new(new_fields)),
11224 });
11225 }
11226 }
11227 }
11228 if name.name == "reshape" {
11230 if let Value::Struct { name: sname, fields } = &value {
11231 if sname == "Tensor" {
11232 let fields_ref = fields.borrow();
11233 let data = fields_ref.get("data").cloned().unwrap_or(Value::Null);
11234 drop(fields_ref);
11235 let new_shape = if !arg_values.is_empty() {
11237 match &arg_values[0] {
11238 Value::Array(arr) => Value::Array(arr.clone()),
11239 _ => arg_values[0].clone(),
11240 }
11241 } else {
11242 Value::Array(Rc::new(RefCell::new(vec![])))
11243 };
11244 let mut new_fields = std::collections::HashMap::new();
11245 new_fields.insert("shape".to_string(), new_shape);
11246 new_fields.insert("data".to_string(), data);
11247 new_fields.insert("requires_grad".to_string(), Value::Bool(false));
11248 return Ok(Value::Struct {
11249 name: "Tensor".to_string(),
11250 fields: Rc::new(RefCell::new(new_fields)),
11251 });
11252 }
11253 }
11254 }
11255 if name.name == "flatten" {
11257 if let Value::Struct { name: sname, fields } = &value {
11258 if sname == "Tensor" {
11259 let fields_ref = fields.borrow();
11260 let data = fields_ref.get("data").cloned().unwrap_or(Value::Null);
11261 let total_size: i64 = match &data {
11262 Value::Array(arr) => arr.borrow().len() as i64,
11263 _ => 0,
11264 };
11265 drop(fields_ref);
11266 let mut new_fields = std::collections::HashMap::new();
11267 new_fields.insert("shape".to_string(), Value::Array(Rc::new(RefCell::new(vec![Value::Int(total_size)]))));
11268 new_fields.insert("data".to_string(), data);
11269 new_fields.insert("requires_grad".to_string(), Value::Bool(false));
11270 return Ok(Value::Struct {
11271 name: "Tensor".to_string(),
11272 fields: Rc::new(RefCell::new(new_fields)),
11273 });
11274 }
11275 }
11276 }
11277 if name.name == "backward" {
11279 if let Value::Struct { name: sname, fields } = &value {
11280 if sname == "Tensor" {
11281 self.backward_propagate(fields.clone())?;
11283 return Ok(Value::Null);
11284 }
11285 }
11286 if let Value::Float(_) = &value {
11288 return Ok(Value::Null);
11289 }
11290 }
11291
11292 if name.name == "scatter" {
11296 if arg_values.len() >= 2 {
11297 let n = match &arg_values[0] {
11298 Value::Int(n) => *n as usize,
11299 _ => 7,
11300 };
11301 let k = match &arg_values[1] {
11302 Value::Int(k) => *k as usize,
11303 _ => 4,
11304 };
11305 let inner_value = match &value {
11307 Value::Struct { fields, .. } => {
11308 fields.borrow().get("value").cloned().unwrap_or(value.clone())
11309 }
11310 _ => value.clone(),
11311 };
11312 let mut shards = Vec::new();
11313 for i in 0..n {
11314 let mut shard_fields = std::collections::HashMap::new();
11315 shard_fields.insert("index".to_string(), Value::Int(i as i64));
11316 shard_fields.insert("data".to_string(), inner_value.clone());
11317 shard_fields.insert("_k_threshold".to_string(), Value::Int(k as i64));
11318 shards.push(Value::Struct {
11319 name: "Shard".to_string(),
11320 fields: Rc::new(RefCell::new(shard_fields)),
11321 });
11322 }
11323 return Ok(Value::Array(Rc::new(RefCell::new(shards))));
11324 }
11325 }
11326
11327 if name.name == "measure" {
11329 match &value {
11330 Value::Struct { name: sname, fields } if sname == "QHState" => {
11331 let fields_ref = fields.borrow();
11332 let inner = fields_ref.get("value").cloned().unwrap_or(Value::Null);
11333 match inner {
11335 Value::Array(arr) => {
11336 return Ok(arr.borrow().first().cloned().unwrap_or(Value::Null));
11337 }
11338 _ => return Ok(inner),
11339 }
11340 }
11341 _ => return Ok(value.clone()),
11342 }
11343 }
11344
11345 if name.name == "observe" {
11347 match &value {
11348 Value::Struct { name: sname, fields } => {
11349 let fields_ref = fields.borrow();
11350 if sname == "Superposition" {
11351 if let Some(Value::Array(states)) = fields_ref.get("states") {
11353 return Ok(states.borrow().first().cloned().unwrap_or(Value::Null));
11354 }
11355 }
11356 if let Some(v) = fields_ref.get("value") {
11358 return Ok(v.clone());
11359 }
11360 drop(fields_ref);
11361 return Ok(value.clone());
11362 }
11363 _ => return Ok(value.clone()),
11364 }
11365 }
11366
11367 if name.name == "interfere" {
11369 if !arg_values.is_empty() {
11370 let mut fields = std::collections::HashMap::new();
11372 fields.insert("_state_a".to_string(), value.clone());
11373 fields.insert("_state_b".to_string(), arg_values[0].clone());
11374 fields.insert("_is_superposition".to_string(), Value::Bool(true));
11375 let inner_a = match &value {
11377 Value::Struct { fields: f, .. } => f.borrow().get("value").cloned(),
11378 _ => None,
11379 };
11380 fields.insert("value".to_string(), inner_a.unwrap_or(Value::Int(2)));
11381 return Ok(Value::Struct {
11382 name: "QHState".to_string(),
11383 fields: Rc::new(RefCell::new(fields)),
11384 });
11385 }
11386 }
11387
11388 if name.name == "apply_noise" {
11390 let rate = if !arg_values.is_empty() {
11391 match &arg_values[0] {
11392 Value::Float(f) => *f,
11393 _ => 0.1,
11394 }
11395 } else { 0.1 };
11396 match &value {
11398 Value::Struct { name: sname, fields } => {
11399 let mut new_fields = fields.borrow().clone();
11400 new_fields.insert("_noise_rate".to_string(), Value::Float(rate));
11401 new_fields.insert("_noisy".to_string(), Value::Bool(true));
11402 return Ok(Value::Struct {
11403 name: sname.clone(),
11404 fields: Rc::new(RefCell::new(new_fields)),
11405 });
11406 }
11407 _ => return Ok(value.clone()),
11408 }
11409 }
11410
11411 if name.name == "error_correct" {
11413 match &value {
11414 Value::Struct { name: sname, fields } => {
11415 let mut new_fields = fields.borrow().clone();
11416 new_fields.remove("_noisy");
11417 new_fields.remove("_noise_rate");
11418 new_fields.insert("_corrected".to_string(), Value::Bool(true));
11419 return Ok(Value::Struct {
11420 name: sname.clone(),
11421 fields: Rc::new(RefCell::new(new_fields)),
11422 });
11423 }
11424 _ => return Ok(value.clone()),
11425 }
11426 }
11427
11428 if name.name == "teleport" {
11430 if arg_values.len() >= 2 {
11431 let inner = match &value {
11433 Value::Struct { fields, .. } => {
11434 fields.borrow().get("value").cloned().unwrap_or(value.clone())
11435 }
11436 _ => value.clone(),
11437 };
11438 let mut fields = std::collections::HashMap::new();
11439 fields.insert("value".to_string(), inner);
11440 fields.insert("_teleported".to_string(), Value::Bool(true));
11441 return Ok(Value::Struct {
11442 name: "QHState".to_string(),
11443 fields: Rc::new(RefCell::new(fields)),
11444 });
11445 }
11446 }
11447
11448 if name.name == "qh_compress" {
11450 let size = match &value {
11451 Value::Array(arr) => arr.borrow().len() as i64 / 2,
11452 _ => 1,
11453 };
11454 let mut fields = std::collections::HashMap::new();
11455 fields.insert("data".to_string(), value.clone());
11456 fields.insert("_compressed_size".to_string(), Value::Int(size.max(1)));
11457 return Ok(Value::Struct {
11458 name: "QHCompressed".to_string(),
11459 fields: Rc::new(RefCell::new(fields)),
11460 });
11461 }
11462
11463 if name.name == "quantum_reconstruct" {
11465 match &value {
11466 Value::Struct { fields, .. } => {
11467 let fields_ref = fields.borrow();
11468 if let Some(Value::Array(shards)) = fields_ref.get("shards") {
11469 if let Some(first) = shards.borrow().first() {
11470 if let Value::Struct { fields: shard_fields, .. } = first {
11471 if let Some(data) = shard_fields.borrow().get("data") {
11472 let mut qh_fields = std::collections::HashMap::new();
11473 qh_fields.insert("value".to_string(), data.clone());
11474 qh_fields.insert("_reconstructed".to_string(), Value::Bool(true));
11475 return Ok(Value::Struct {
11476 name: "QHState".to_string(),
11477 fields: Rc::new(RefCell::new(qh_fields)),
11478 });
11479 }
11480 }
11481 }
11482 }
11483 let mut qh_fields = std::collections::HashMap::new();
11485 qh_fields.insert("value".to_string(), Value::Int(42));
11486 qh_fields.insert("_reconstructed".to_string(), Value::Bool(true));
11487 return Ok(Value::Struct {
11488 name: "QHState".to_string(),
11489 fields: Rc::new(RefCell::new(qh_fields)),
11490 });
11491 }
11492 _ => {
11493 let mut qh_fields = std::collections::HashMap::new();
11494 qh_fields.insert("value".to_string(), value.clone());
11495 return Ok(Value::Struct {
11496 name: "QHState".to_string(),
11497 fields: Rc::new(RefCell::new(qh_fields)),
11498 });
11499 }
11500 }
11501 }
11502
11503 if name.name == "partial_trace" {
11505 match &value {
11506 Value::Struct { name: sname, fields } if sname == "Entangled" => {
11507 let fields_ref = fields.borrow();
11508 let a = fields_ref.get("0").cloned().unwrap_or(Value::Null);
11509 let b = fields_ref.get("1").cloned().unwrap_or(Value::Null);
11510 let system = match a {
11512 Value::Struct { name, fields } => {
11513 let mut new_fields = fields.borrow().clone();
11514 new_fields.insert("_is_pure".to_string(), Value::Bool(false));
11515 Value::Struct {
11516 name,
11517 fields: Rc::new(RefCell::new(new_fields)),
11518 }
11519 }
11520 _ => a,
11521 };
11522 return Ok(Value::Tuple(Rc::new(vec![system, b])));
11523 }
11524 _ => return Ok(Value::Tuple(Rc::new(vec![value.clone(), Value::Null]))),
11525 }
11526 }
11527
11528 if name.name == "verify" {
11530 match &value {
11532 Value::Struct { fields, .. } => {
11533 let fields_ref = fields.borrow();
11534 if let Some(v) = fields_ref.get("value") {
11535 return Ok(v.clone());
11536 }
11537 drop(fields_ref);
11538 return Ok(Value::Int(42)); }
11540 _ => return Ok(value.clone()),
11541 }
11542 }
11543
11544 if name.name == "is_pure" {
11546 match &value {
11547 Value::Struct { fields, .. } => {
11548 if let Some(Value::Bool(is_pure)) = fields.borrow().get("_is_pure") {
11549 return Ok(Value::Bool(*is_pure));
11550 }
11551 return Ok(Value::Bool(true)); }
11553 _ => return Ok(Value::Bool(true)),
11554 }
11555 }
11556
11557 if name.name == "size" {
11559 match &value {
11560 Value::Struct { name: sname, fields } if sname == "QHCompressed" => {
11561 if let Some(Value::Int(size)) = fields.borrow().get("_compressed_size") {
11562 return Ok(Value::Int(*size));
11563 }
11564 }
11565 _ => {}
11566 }
11567 return Ok(Value::Int(1));
11568 }
11569
11570 Err(RuntimeError::new(format!(
11571 "Unknown pipe method: {}",
11572 name.name
11573 )))
11574 }
11575 }
11576 }
11577 PipeOp::Await => {
11578 self.await_value(value)
11580 }
11581 PipeOp::First => {
11583 match &value {
11585 Value::Array(arr) => arr
11586 .borrow()
11587 .first()
11588 .cloned()
11589 .ok_or_else(|| RuntimeError::new("first (α) on empty array")),
11590 Value::Tuple(t) => t
11591 .first()
11592 .cloned()
11593 .ok_or_else(|| RuntimeError::new("first (α) on empty tuple")),
11594 _ => Err(RuntimeError::new("first (α) requires array or tuple")),
11595 }
11596 }
11597 PipeOp::Last => {
11598 match &value {
11600 Value::Array(arr) => arr
11601 .borrow()
11602 .last()
11603 .cloned()
11604 .ok_or_else(|| RuntimeError::new("last (ω) on empty array")),
11605 Value::Tuple(t) => t
11606 .last()
11607 .cloned()
11608 .ok_or_else(|| RuntimeError::new("last (ω) on empty tuple")),
11609 _ => Err(RuntimeError::new("last (ω) requires array or tuple")),
11610 }
11611 }
11612 PipeOp::Middle => {
11613 match &value {
11615 Value::Array(arr) => {
11616 let arr = arr.borrow();
11617 if arr.is_empty() {
11618 return Err(RuntimeError::new("middle (μ) on empty array"));
11619 }
11620 let mid = arr.len() / 2;
11621 Ok(arr[mid].clone())
11622 }
11623 Value::Tuple(t) => {
11624 if t.is_empty() {
11625 return Err(RuntimeError::new("middle (μ) on empty tuple"));
11626 }
11627 let mid = t.len() / 2;
11628 Ok(t[mid].clone())
11629 }
11630 _ => Err(RuntimeError::new("middle (μ) requires array or tuple")),
11631 }
11632 }
11633 PipeOp::Choice => {
11634 use std::time::{SystemTime, UNIX_EPOCH};
11636 match &value {
11637 Value::Array(arr) => {
11638 let arr = arr.borrow();
11639 if arr.is_empty() {
11640 return Err(RuntimeError::new("choice (χ) on empty array"));
11641 }
11642 let seed = SystemTime::now()
11643 .duration_since(UNIX_EPOCH)
11644 .unwrap_or(std::time::Duration::ZERO)
11645 .as_nanos() as u64;
11646 let idx = ((seed.wrapping_mul(1103515245).wrapping_add(12345)) >> 16)
11647 as usize
11648 % arr.len();
11649 Ok(arr[idx].clone())
11650 }
11651 Value::Tuple(t) => {
11652 if t.is_empty() {
11653 return Err(RuntimeError::new("choice (χ) on empty tuple"));
11654 }
11655 let seed = SystemTime::now()
11656 .duration_since(UNIX_EPOCH)
11657 .unwrap_or(std::time::Duration::ZERO)
11658 .as_nanos() as u64;
11659 let idx = ((seed.wrapping_mul(1103515245).wrapping_add(12345)) >> 16)
11660 as usize
11661 % t.len();
11662 Ok(t[idx].clone())
11663 }
11664 _ => Err(RuntimeError::new("choice (χ) requires array or tuple")),
11665 }
11666 }
11667 PipeOp::Nth(index_expr) => {
11668 let index = match self.evaluate(index_expr)? {
11670 Value::Int(n) => n,
11671 _ => return Err(RuntimeError::new("nth (ν) index must be integer")),
11672 };
11673 match &value {
11674 Value::Array(arr) => {
11675 let arr = arr.borrow();
11676 if index < 0 || index as usize >= arr.len() {
11677 return Err(RuntimeError::new("nth (ν) index out of bounds"));
11678 }
11679 Ok(arr[index as usize].clone())
11680 }
11681 Value::Tuple(t) => {
11682 if index < 0 || index as usize >= t.len() {
11683 return Err(RuntimeError::new("nth (ν) index out of bounds"));
11684 }
11685 Ok(t[index as usize].clone())
11686 }
11687 _ => Err(RuntimeError::new("nth (ν) requires array or tuple")),
11688 }
11689 }
11690 PipeOp::Next => {
11691 match &value {
11694 Value::Array(arr) => arr
11695 .borrow()
11696 .first()
11697 .cloned()
11698 .ok_or_else(|| RuntimeError::new("next (ξ) on empty array")),
11699 Value::Tuple(t) => t
11700 .first()
11701 .cloned()
11702 .ok_or_else(|| RuntimeError::new("next (ξ) on empty tuple")),
11703 _ => Err(RuntimeError::new("next (ξ) requires array or tuple")),
11704 }
11705 }
11706 PipeOp::Named { prefix, body } => {
11707 let method_name = prefix
11709 .iter()
11710 .map(|i| i.name.as_str())
11711 .collect::<Vec<_>>()
11712 .join("·");
11713 match method_name.as_str() {
11714 "map" => {
11715 if let Some(body) = body {
11716 match value {
11717 Value::Array(arr) => {
11718 let results: Vec<Value> = arr
11719 .borrow()
11720 .iter()
11721 .map(|item| {
11722 self.environment
11723 .borrow_mut()
11724 .define("_".to_string(), item.clone());
11725 self.evaluate(body)
11726 })
11727 .collect::<Result<_, _>>()?;
11728 Ok(Value::Array(Rc::new(RefCell::new(results))))
11729 }
11730 _ => Err(RuntimeError::new("map requires array")),
11731 }
11732 } else {
11733 Ok(value)
11734 }
11735 }
11736 "filter" => {
11737 if let Some(body) = body {
11738 match value {
11739 Value::Array(arr) => {
11740 let results: Vec<Value> = arr
11741 .borrow()
11742 .iter()
11743 .filter_map(|item| {
11744 self.environment
11745 .borrow_mut()
11746 .define("_".to_string(), item.clone());
11747 match self.evaluate(body) {
11748 Ok(v) if self.is_truthy(&v) => {
11749 Some(Ok(item.clone()))
11750 }
11751 Ok(_) => None,
11752 Err(e) => Some(Err(e)),
11753 }
11754 })
11755 .collect::<Result<_, _>>()?;
11756 Ok(Value::Array(Rc::new(RefCell::new(results))))
11757 }
11758 _ => Err(RuntimeError::new("filter requires array")),
11759 }
11760 } else {
11761 Ok(value)
11762 }
11763 }
11764 "all" => {
11765 if let Some(body) = body {
11766 match value {
11767 Value::Array(arr) => {
11768 for item in arr.borrow().iter() {
11769 self.environment
11770 .borrow_mut()
11771 .define("_".to_string(), item.clone());
11772 let result = self.evaluate(body)?;
11773 if !self.is_truthy(&result) {
11774 return Ok(Value::Bool(false));
11775 }
11776 }
11777 Ok(Value::Bool(true))
11778 }
11779 _ => Err(RuntimeError::new("all requires array")),
11780 }
11781 } else {
11782 match value {
11784 Value::Array(arr) => {
11785 for item in arr.borrow().iter() {
11786 if !self.is_truthy(item) {
11787 return Ok(Value::Bool(false));
11788 }
11789 }
11790 Ok(Value::Bool(true))
11791 }
11792 _ => Err(RuntimeError::new("all requires array")),
11793 }
11794 }
11795 }
11796 "any" => {
11797 if let Some(body) = body {
11798 match value {
11799 Value::Array(arr) => {
11800 for item in arr.borrow().iter() {
11801 self.environment
11802 .borrow_mut()
11803 .define("_".to_string(), item.clone());
11804 let result = self.evaluate(body)?;
11805 if self.is_truthy(&result) {
11806 return Ok(Value::Bool(true));
11807 }
11808 }
11809 Ok(Value::Bool(false))
11810 }
11811 _ => Err(RuntimeError::new("any requires array")),
11812 }
11813 } else {
11814 match value {
11816 Value::Array(arr) => {
11817 for item in arr.borrow().iter() {
11818 if self.is_truthy(item) {
11819 return Ok(Value::Bool(true));
11820 }
11821 }
11822 Ok(Value::Bool(false))
11823 }
11824 _ => Err(RuntimeError::new("any requires array")),
11825 }
11826 }
11827 }
11828 _ => Err(RuntimeError::new(format!(
11829 "Unknown named morpheme: {}",
11830 method_name
11831 ))),
11832 }
11833 }
11834 PipeOp::Parallel(inner_op) => {
11835 match value {
11838 Value::Array(arr) => {
11839 use std::sync::{Arc, Mutex};
11840
11841 let arr_ref = arr.borrow();
11842 let len = arr_ref.len();
11843 if len == 0 {
11844 return Ok(Value::Array(Rc::new(RefCell::new(vec![]))));
11845 }
11846
11847 match inner_op.as_ref() {
11849 PipeOp::Transform(body) => {
11850 let num_threads = std::thread::available_parallelism()
11852 .map(|p| p.get())
11853 .unwrap_or(4)
11854 .min(len);
11855
11856 let _chunk_size = (len + num_threads - 1) / num_threads;
11858 let _results = Arc::new(Mutex::new(vec![Value::Null; len]));
11859 let items: Vec<Value> = arr_ref.clone();
11860 drop(arr_ref);
11861
11862 let _body_str = format!("{:?}", body);
11864
11865 let mut result_vec = Vec::with_capacity(len);
11869 for item in items.iter() {
11870 self.environment
11871 .borrow_mut()
11872 .define("_".to_string(), item.clone());
11873 result_vec.push(self.evaluate(body)?);
11874 }
11875 Ok(Value::Array(Rc::new(RefCell::new(result_vec))))
11876 }
11877 PipeOp::Filter(predicate) => {
11878 let items: Vec<Value> = arr_ref.clone();
11880 drop(arr_ref);
11881
11882 let mut result_vec = Vec::new();
11883 for item in items.iter() {
11884 self.environment
11885 .borrow_mut()
11886 .define("_".to_string(), item.clone());
11887 let pred_result = self.evaluate(predicate)?;
11888 if self.is_truthy(&pred_result) {
11889 result_vec.push(item.clone());
11890 }
11891 }
11892 Ok(Value::Array(Rc::new(RefCell::new(result_vec))))
11893 }
11894 _ => {
11895 drop(arr_ref);
11897 self.apply_pipe_op(Value::Array(arr), inner_op)
11898 }
11899 }
11900 }
11901 _ => {
11902 self.apply_pipe_op(value, inner_op)
11904 }
11905 }
11906 }
11907 PipeOp::Gpu(inner_op) => {
11908 match value {
11915 Value::Array(arr) => {
11916 #[cfg(debug_assertions)]
11919 eprintln!(
11920 "[GPU] Would execute {:?} on GPU, falling back to CPU",
11921 inner_op
11922 );
11923
11924 self.apply_pipe_op(Value::Array(arr), inner_op)
11925 }
11926 _ => self.apply_pipe_op(value, inner_op),
11927 }
11928 }
11929
11930 PipeOp::Send(data_expr) => {
11936 let data = self.evaluate(data_expr)?;
11939
11940 let response = self.protocol_send(&value, &data)?;
11943
11944 Ok(self.wrap_reported(response))
11946 }
11947
11948 PipeOp::Recv => {
11949 let response = self.protocol_recv(&value)?;
11954
11955 Ok(self.wrap_reported(response))
11957 }
11958
11959 PipeOp::Stream(handler_expr) => {
11960 let handler = self.evaluate(handler_expr)?;
11962
11963 let stream = self.protocol_stream(&value, &handler)?;
11966 Ok(stream)
11967 }
11968
11969 PipeOp::Connect(config_expr) => {
11970 let config = match config_expr {
11972 Some(expr) => Some(self.evaluate(expr)?),
11973 None => None,
11974 };
11975
11976 let connection = self.protocol_connect(&value, config.as_ref())?;
11978 Ok(connection)
11979 }
11980
11981 PipeOp::Close => {
11982 self.protocol_close(&value)?;
11984 Ok(Value::Null)
11985 }
11986
11987 PipeOp::Header {
11988 name,
11989 value: value_expr,
11990 } => {
11991 let header_name = self.evaluate(name)?;
11993 let header_value = self.evaluate(value_expr)?;
11994
11995 self.protocol_add_header(value, &header_name, &header_value)
11997 }
11998
11999 PipeOp::Body(data_expr) => {
12000 let body_data = self.evaluate(data_expr)?;
12002
12003 self.protocol_set_body(value, &body_data)
12005 }
12006
12007 PipeOp::Timeout(ms_expr) => {
12008 let ms = self.evaluate(ms_expr)?;
12010
12011 self.protocol_set_timeout(value, &ms)
12013 }
12014
12015 PipeOp::Retry { count, strategy } => {
12016 let retry_count = self.evaluate(count)?;
12018 let retry_strategy = match strategy {
12019 Some(s) => Some(self.evaluate(s)?),
12020 None => None,
12021 };
12022
12023 self.protocol_set_retry(value, &retry_count, retry_strategy.as_ref())
12025 }
12026
12027 PipeOp::Validate {
12031 predicate,
12032 target_evidence,
12033 } => {
12034 let predicate_result = match predicate.as_ref() {
12037 Expr::Closure { params, body, .. } => {
12038 if let Some(param) = params.first() {
12039 let param_name = match ¶m.pattern {
12040 Pattern::Ident { name, .. } => name.name.clone(),
12041 _ => "it".to_string(),
12042 };
12043 self.environment
12044 .borrow_mut()
12045 .define(param_name, value.clone());
12046 }
12047 self.evaluate(body)?
12048 }
12049 _ => self.evaluate(predicate)?,
12050 };
12051
12052 match predicate_result {
12054 Value::Bool(true) => {
12055 let target_ev = match target_evidence {
12057 Evidentiality::Known => Evidence::Known,
12058 Evidentiality::Uncertain | Evidentiality::Predicted => {
12059 Evidence::Uncertain
12060 }
12061 Evidentiality::Reported => Evidence::Reported,
12062 Evidentiality::Paradox => Evidence::Paradox,
12063 };
12064 let inner = match value {
12065 Value::Evidential { value: v, .. } => *v,
12066 v => v,
12067 };
12068 Ok(Value::Evidential {
12069 value: Box::new(inner),
12070 evidence: target_ev,
12071 })
12072 }
12073 Value::Bool(false) => Err(RuntimeError::new(
12074 "validation failed: predicate returned false",
12075 )),
12076 _ => Err(RuntimeError::new("validation predicate must return bool")),
12077 }
12078 }
12079
12080 PipeOp::Assume {
12081 reason,
12082 target_evidence,
12083 } => {
12084 let reason_str: Rc<String> = if let Some(r) = reason {
12086 match self.evaluate(r)? {
12087 Value::String(s) => s,
12088 _ => Rc::new("<no reason>".to_string()),
12089 }
12090 } else {
12091 Rc::new("<no reason>".to_string())
12092 };
12093
12094 #[cfg(debug_assertions)]
12096 eprintln!(
12097 "[AUDIT] Evidence assumption: {} - reason: {}",
12098 match target_evidence {
12099 Evidentiality::Known => "!",
12100 Evidentiality::Uncertain | Evidentiality::Predicted => "?",
12101 Evidentiality::Reported => "~",
12102 Evidentiality::Paradox => "‽",
12103 },
12104 reason_str
12105 );
12106
12107 let target_ev = match target_evidence {
12108 Evidentiality::Known => Evidence::Known,
12109 Evidentiality::Uncertain | Evidentiality::Predicted => Evidence::Uncertain,
12110 Evidentiality::Reported => Evidence::Reported,
12111 Evidentiality::Paradox => Evidence::Paradox,
12112 };
12113
12114 let inner = match value {
12115 Value::Evidential { value: v, .. } => *v,
12116 v => v,
12117 };
12118
12119 Ok(Value::Evidential {
12120 value: Box::new(inner),
12121 evidence: target_ev,
12122 })
12123 }
12124
12125 PipeOp::AssertEvidence(expected) => {
12126 let actual_evidence = match &value {
12128 Value::Evidential { evidence, .. } => evidence.clone(),
12129 _ => Evidence::Known,
12130 };
12131
12132 let expected_ev = match expected {
12133 Evidentiality::Known => Evidence::Known,
12134 Evidentiality::Uncertain | Evidentiality::Predicted => Evidence::Uncertain,
12135 Evidentiality::Reported => Evidence::Reported,
12136 Evidentiality::Paradox => Evidence::Paradox,
12137 };
12138
12139 let satisfies = match (&actual_evidence, &expected_ev) {
12141 (Evidence::Known, _) => true,
12142 (
12143 Evidence::Uncertain,
12144 Evidence::Uncertain | Evidence::Reported | Evidence::Paradox,
12145 ) => true,
12146 (Evidence::Reported, Evidence::Reported | Evidence::Paradox) => true,
12147 (Evidence::Paradox, Evidence::Paradox) => true,
12148 _ => false,
12149 };
12150
12151 if satisfies {
12152 Ok(value)
12153 } else {
12154 Err(RuntimeError::new(format!(
12155 "evidence assertion failed: expected {:?}, found {:?}",
12156 expected_ev, actual_evidence
12157 )))
12158 }
12159 }
12160
12161 PipeOp::Also(func) => {
12165 match func.as_ref() {
12168 Expr::Closure { params, body, .. } => {
12169 if let Some(param) = params.first() {
12170 let param_name = match ¶m.pattern {
12171 Pattern::Ident { name, .. } => name.name.clone(),
12172 _ => "it".to_string(),
12173 };
12174 self.environment
12175 .borrow_mut()
12176 .define(param_name, value.clone());
12177 }
12178 let _ = self.evaluate(body);
12180 }
12181 _ => {
12182 let _ = self.evaluate(func);
12184 }
12185 }
12186 Ok(value)
12188 }
12189
12190 PipeOp::Apply(func) => {
12191 match func.as_ref() {
12194 Expr::Closure { params, body, .. } => {
12195 if let Some(param) = params.first() {
12196 let param_name = match ¶m.pattern {
12197 Pattern::Ident { name, .. } => name.name.clone(),
12198 _ => "it".to_string(),
12199 };
12200 self.environment
12201 .borrow_mut()
12202 .define(param_name, value.clone());
12203 }
12204 let _ = self.evaluate(body);
12206 }
12207 _ => {
12208 let _ = self.evaluate(func);
12209 }
12210 }
12211 Ok(value)
12213 }
12214
12215 PipeOp::TakeIf(predicate) => {
12216 let predicate_result = match predicate.as_ref() {
12218 Expr::Closure { params, body, .. } => {
12219 if let Some(param) = params.first() {
12220 let param_name = match ¶m.pattern {
12221 Pattern::Ident { name, .. } => name.name.clone(),
12222 _ => "it".to_string(),
12223 };
12224 self.environment
12225 .borrow_mut()
12226 .define(param_name, value.clone());
12227 }
12228 self.evaluate(body)?
12229 }
12230 _ => self.evaluate(predicate)?,
12231 };
12232
12233 match predicate_result {
12234 Value::Bool(true) => Ok(Value::Variant {
12235 enum_name: "Option".to_string(),
12236 variant_name: "Some".to_string(),
12237 fields: Some(Rc::new(vec![value])),
12238 }),
12239 Value::Bool(false) => Ok(Value::Variant {
12240 enum_name: "Option".to_string(),
12241 variant_name: "None".to_string(),
12242 fields: None,
12243 }),
12244 _ => Err(RuntimeError::new("take_if predicate must return bool")),
12245 }
12246 }
12247
12248 PipeOp::TakeUnless(predicate) => {
12249 let predicate_result = match predicate.as_ref() {
12251 Expr::Closure { params, body, .. } => {
12252 if let Some(param) = params.first() {
12253 let param_name = match ¶m.pattern {
12254 Pattern::Ident { name, .. } => name.name.clone(),
12255 _ => "it".to_string(),
12256 };
12257 self.environment
12258 .borrow_mut()
12259 .define(param_name, value.clone());
12260 }
12261 self.evaluate(body)?
12262 }
12263 _ => self.evaluate(predicate)?,
12264 };
12265
12266 match predicate_result {
12267 Value::Bool(false) => Ok(Value::Variant {
12268 enum_name: "Option".to_string(),
12269 variant_name: "Some".to_string(),
12270 fields: Some(Rc::new(vec![value])),
12271 }),
12272 Value::Bool(true) => Ok(Value::Variant {
12273 enum_name: "Option".to_string(),
12274 variant_name: "None".to_string(),
12275 fields: None,
12276 }),
12277 _ => Err(RuntimeError::new("take_unless predicate must return bool")),
12278 }
12279 }
12280
12281 PipeOp::Let(func) => {
12282 match func.as_ref() {
12284 Expr::Closure { params, body, .. } => {
12285 if let Some(param) = params.first() {
12286 let param_name = match ¶m.pattern {
12287 Pattern::Ident { name, .. } => name.name.clone(),
12288 _ => "it".to_string(),
12289 };
12290 self.environment
12291 .borrow_mut()
12292 .define(param_name, value.clone());
12293 }
12294 self.evaluate(body)
12295 }
12296 _ => self.evaluate(func),
12297 }
12298 }
12299
12300 PipeOp::All(pred) => {
12304 match value {
12306 Value::Array(arr) => {
12307 for elem in arr.borrow().iter() {
12308 self.environment
12309 .borrow_mut()
12310 .define("_".to_string(), elem.clone());
12311 let result = self.evaluate(pred)?;
12312 if !self.is_truthy(&result) {
12313 return Ok(Value::Bool(false));
12314 }
12315 }
12316 Ok(Value::Bool(true))
12317 }
12318 _ => Err(RuntimeError::new("All requires array")),
12319 }
12320 }
12321
12322 PipeOp::Any(pred) => {
12323 match value {
12325 Value::Array(arr) => {
12326 for elem in arr.borrow().iter() {
12327 self.environment
12328 .borrow_mut()
12329 .define("_".to_string(), elem.clone());
12330 let result = self.evaluate(pred)?;
12331 if self.is_truthy(&result) {
12332 return Ok(Value::Bool(true));
12333 }
12334 }
12335 Ok(Value::Bool(false))
12336 }
12337 _ => Err(RuntimeError::new("Any requires array")),
12338 }
12339 }
12340
12341 PipeOp::Compose(f) => {
12342 self.environment.borrow_mut().define("_".to_string(), value);
12344 self.evaluate(f)
12345 }
12346
12347 PipeOp::Zip(other_expr) => {
12348 let other = self.evaluate(other_expr)?;
12350 match (value, other) {
12351 (Value::Array(arr1), Value::Array(arr2)) => {
12352 let zipped: Vec<Value> = arr1
12353 .borrow()
12354 .iter()
12355 .zip(arr2.borrow().iter())
12356 .map(|(a, b)| Value::Tuple(Rc::new(vec![a.clone(), b.clone()])))
12357 .collect();
12358 Ok(Value::Array(Rc::new(RefCell::new(zipped))))
12359 }
12360 _ => Err(RuntimeError::new("Zip requires two arrays")),
12361 }
12362 }
12363
12364 PipeOp::Scan(f) => {
12365 match value {
12367 Value::Array(arr) => {
12368 let arr = arr.borrow();
12369 if arr.is_empty() {
12370 return Ok(Value::Array(Rc::new(RefCell::new(vec![]))));
12371 }
12372 let mut results = vec![arr[0].clone()];
12373 let mut acc = arr[0].clone();
12374 for elem in arr.iter().skip(1) {
12375 self.environment
12376 .borrow_mut()
12377 .define("acc".to_string(), acc.clone());
12378 self.environment
12379 .borrow_mut()
12380 .define("_".to_string(), elem.clone());
12381 acc = self.evaluate(f)?;
12382 results.push(acc.clone());
12383 }
12384 Ok(Value::Array(Rc::new(RefCell::new(results))))
12385 }
12386 _ => Err(RuntimeError::new("Scan requires array")),
12387 }
12388 }
12389
12390 PipeOp::Diff => {
12391 match value {
12393 Value::Array(arr) => {
12394 let arr = arr.borrow();
12395 if arr.len() < 2 {
12396 return Ok(Value::Array(Rc::new(RefCell::new(vec![]))));
12397 }
12398 let mut diffs = Vec::new();
12399 for i in 1..arr.len() {
12400 let diff = self.subtract_values(&arr[i], &arr[i - 1])?;
12401 diffs.push(diff);
12402 }
12403 Ok(Value::Array(Rc::new(RefCell::new(diffs))))
12404 }
12405 _ => Err(RuntimeError::new("Diff requires array")),
12406 }
12407 }
12408
12409 PipeOp::Gradient(var_expr) => {
12410 let _ = var_expr;
12413 Ok(Value::Float(0.0)) }
12415
12416 PipeOp::SortAsc => {
12417 match value {
12419 Value::Array(arr) => {
12420 let mut v = arr.borrow().clone();
12421 v.sort_by(|a, b| self.compare_values(a, b, &None));
12422 Ok(Value::Array(Rc::new(RefCell::new(v))))
12423 }
12424 _ => Err(RuntimeError::new("SortAsc requires array")),
12425 }
12426 }
12427
12428 PipeOp::SortDesc => {
12429 match value {
12431 Value::Array(arr) => {
12432 let mut v = arr.borrow().clone();
12433 v.sort_by(|a, b| self.compare_values(b, a, &None));
12434 Ok(Value::Array(Rc::new(RefCell::new(v))))
12435 }
12436 _ => Err(RuntimeError::new("SortDesc requires array")),
12437 }
12438 }
12439
12440 PipeOp::Reverse => {
12441 match value {
12443 Value::Array(arr) => {
12444 let mut v = arr.borrow().clone();
12445 v.reverse();
12446 Ok(Value::Array(Rc::new(RefCell::new(v))))
12447 }
12448 _ => Err(RuntimeError::new("Reverse requires array")),
12449 }
12450 }
12451
12452 PipeOp::Cycle(n_expr) => {
12453 match value {
12455 Value::Array(arr) => {
12456 let n_val = self.evaluate(n_expr)?;
12457 let n = match n_val {
12458 Value::Int(i) => i as usize,
12459 _ => return Err(RuntimeError::new("Cycle count must be integer")),
12460 };
12461 let arr = arr.borrow();
12462 let cycled: Vec<Value> =
12463 arr.iter().cloned().cycle().take(arr.len() * n).collect();
12464 Ok(Value::Array(Rc::new(RefCell::new(cycled))))
12465 }
12466 _ => Err(RuntimeError::new("Cycle requires array")),
12467 }
12468 }
12469
12470 PipeOp::Windows(n_expr) => {
12471 match value {
12473 Value::Array(arr) => {
12474 let n_val = self.evaluate(n_expr)?;
12475 let n = match n_val {
12476 Value::Int(i) => i as usize,
12477 _ => return Err(RuntimeError::new("Window size must be integer")),
12478 };
12479 let arr = arr.borrow();
12480 let windows: Vec<Value> = arr
12481 .windows(n)
12482 .map(|w| Value::Array(Rc::new(RefCell::new(w.to_vec()))))
12483 .collect();
12484 Ok(Value::Array(Rc::new(RefCell::new(windows))))
12485 }
12486 _ => Err(RuntimeError::new("Windows requires array")),
12487 }
12488 }
12489
12490 PipeOp::Chunks(n_expr) => {
12491 match value {
12493 Value::Array(arr) => {
12494 let n_val = self.evaluate(n_expr)?;
12495 let n = match n_val {
12496 Value::Int(i) => i as usize,
12497 _ => return Err(RuntimeError::new("Chunk size must be integer")),
12498 };
12499 let arr = arr.borrow();
12500 let chunks: Vec<Value> = arr
12501 .chunks(n)
12502 .map(|c| Value::Array(Rc::new(RefCell::new(c.to_vec()))))
12503 .collect();
12504 Ok(Value::Array(Rc::new(RefCell::new(chunks))))
12505 }
12506 _ => Err(RuntimeError::new("Chunks requires array")),
12507 }
12508 }
12509
12510 PipeOp::Flatten => {
12511 match value {
12513 Value::Array(arr) => {
12514 let mut flat = Vec::new();
12515 for elem in arr.borrow().iter() {
12516 match elem {
12517 Value::Array(inner) => {
12518 flat.extend(inner.borrow().iter().cloned());
12519 }
12520 other => flat.push(other.clone()),
12521 }
12522 }
12523 Ok(Value::Array(Rc::new(RefCell::new(flat))))
12524 }
12525 _ => Err(RuntimeError::new("Flatten requires array")),
12526 }
12527 }
12528
12529 PipeOp::Unique => {
12530 match value {
12532 Value::Array(arr) => {
12533 let mut seen = std::collections::HashSet::new();
12534 let mut unique = Vec::new();
12535 for elem in arr.borrow().iter() {
12536 let key = format!("{:?}", elem);
12537 if seen.insert(key) {
12538 unique.push(elem.clone());
12539 }
12540 }
12541 Ok(Value::Array(Rc::new(RefCell::new(unique))))
12542 }
12543 _ => Err(RuntimeError::new("Unique requires array")),
12544 }
12545 }
12546
12547 PipeOp::Enumerate => {
12548 match value {
12550 Value::Array(arr) => {
12551 let enumerated: Vec<Value> = arr
12552 .borrow()
12553 .iter()
12554 .enumerate()
12555 .map(|(i, v)| {
12556 Value::Tuple(Rc::new(vec![Value::Int(i as i64), v.clone()]))
12557 })
12558 .collect();
12559 Ok(Value::Array(Rc::new(RefCell::new(enumerated))))
12560 }
12561 _ => Err(RuntimeError::new("Enumerate requires array")),
12562 }
12563 }
12564
12565 PipeOp::Universal => {
12569 match value {
12572 Value::Struct { name, fields } => {
12574 let fields_ref = fields.borrow();
12575 if name == "Hologram" || name == "EntangledHologram" {
12577 if let Some(v) = fields_ref.get("value") {
12578 return Ok(v.clone());
12579 }
12580 }
12581 if name == "QHState" {
12583 if let Some(v) = fields_ref.get("value") {
12584 return Ok(v.clone());
12585 }
12586 }
12587 if name == "Superposition" {
12589 if let Some(Value::Array(states)) = fields_ref.get("states") {
12590 if let Some(first) = states.borrow().first() {
12591 if let Value::Struct { fields: inner_fields, .. } = first {
12593 if let Some(v) = inner_fields.borrow().get("value") {
12594 return Ok(v.clone());
12595 }
12596 }
12597 return Ok(first.clone());
12598 }
12599 }
12600 }
12601 if let Some(v) = fields_ref.get("value") {
12603 return Ok(v.clone());
12604 }
12605 drop(fields_ref);
12606 return Ok(Value::Struct { name, fields });
12607 }
12608 Value::Array(arr) => {
12609 let arr = arr.borrow();
12610 if arr.is_empty() {
12611 return Ok(Value::Int(0));
12612 }
12613 if let Some(Value::Struct { name, fields }) = arr.first() {
12615 if name == "Shard" {
12616 if let Some(data) = fields.borrow().get("data") {
12618 return Ok(data.clone());
12619 }
12620 }
12621 if name == "Hologram" {
12623 if let Some(value) = fields.borrow().get("value") {
12624 return Ok(value.clone());
12625 }
12626 }
12627 }
12628 let mut sum = 0i64;
12630 let mut has_float = false;
12631 let mut float_sum = 0.0f64;
12632 for elem in arr.iter() {
12633 match elem {
12634 Value::Int(i) => {
12635 sum += i;
12636 float_sum += *i as f64;
12637 }
12638 Value::Float(f) => {
12639 has_float = true;
12640 float_sum += f;
12641 }
12642 Value::Struct { fields, .. } => {
12644 if let Some(Value::Int(i)) = fields.borrow().get("value") {
12645 sum += i;
12646 float_sum += *i as f64;
12647 } else if let Some(Value::Float(f)) = fields.borrow().get("value") {
12648 has_float = true;
12649 float_sum += *f;
12650 } else if let Some(data) = fields.borrow().get("data") {
12651 return Ok(data.clone());
12653 }
12654 }
12655 _ => {} }
12657 }
12658 if has_float {
12659 Ok(Value::Float(float_sum))
12660 } else {
12661 Ok(Value::Int(sum))
12662 }
12663 }
12664 _ => Err(RuntimeError::new("Universal requires array")),
12665 }
12666 }
12667
12668 PipeOp::Possibility => {
12669 match &value {
12673 Value::Array(arr) => {
12674 let arr = arr.borrow();
12675 if arr.is_empty() {
12676 Ok(Value::Null)
12677 } else {
12678 Ok(arr[0].clone())
12679 }
12680 }
12681 Value::Variant {
12683 enum_name,
12684 variant_name,
12685 fields,
12686 } if enum_name == "Option" => {
12687 if variant_name == "Some" {
12688 if let Some(fields) = fields {
12689 if !fields.is_empty() {
12690 Ok(fields[0].clone())
12691 } else {
12692 Ok(Value::Null)
12693 }
12694 } else {
12695 Ok(Value::Null)
12696 }
12697 } else {
12698 Ok(Value::Null)
12700 }
12701 }
12702 _ => Ok(value), }
12704 }
12705
12706 PipeOp::Necessity => {
12707 match &value {
12710 Value::Array(arr) => {
12711 if arr.borrow().is_empty() {
12712 Err(RuntimeError::new("Necessity verification failed: empty array"))
12713 } else {
12714 Ok(Value::Evidential {
12716 value: Box::new(value),
12717 evidence: Evidence::Known,
12718 })
12719 }
12720 }
12721 Value::Variant {
12723 enum_name,
12724 variant_name,
12725 fields,
12726 } if enum_name == "Option" => {
12727 if variant_name == "Some" {
12728 if let Some(fields) = fields {
12729 if !fields.is_empty() {
12730 Ok(Value::Evidential {
12731 value: Box::new(fields[0].clone()),
12732 evidence: Evidence::Known,
12733 })
12734 } else {
12735 Err(RuntimeError::new(
12736 "Necessity verification failed: empty Some",
12737 ))
12738 }
12739 } else {
12740 Err(RuntimeError::new(
12741 "Necessity verification failed: empty Some",
12742 ))
12743 }
12744 } else {
12745 Err(RuntimeError::new(
12746 "Necessity verification failed: None value",
12747 ))
12748 }
12749 }
12750 _ => Ok(Value::Evidential {
12751 value: Box::new(value),
12752 evidence: Evidence::Known,
12753 }),
12754 }
12755 }
12756
12757 PipeOp::PossibilityMethod { name, args } => {
12758 let arg_values: Vec<Value> = args
12761 .iter()
12762 .map(|a| self.evaluate(a))
12763 .collect::<Result<_, _>>()?;
12764
12765 let method_result = self.apply_pipe_op(
12767 value.clone(),
12768 &PipeOp::Method {
12769 name: name.clone(),
12770 type_args: None,
12771 args: args.clone(),
12772 },
12773 )?;
12774
12775 Ok(Value::Evidential {
12777 value: Box::new(method_result),
12778 evidence: Evidence::Predicted,
12779 })
12780 }
12781
12782 PipeOp::NecessityMethod { name, args } => {
12783 let arg_values: Vec<Value> = args
12786 .iter()
12787 .map(|a| self.evaluate(a))
12788 .collect::<Result<_, _>>()?;
12789
12790 let method_result = self.apply_pipe_op(
12792 value.clone(),
12793 &PipeOp::Method {
12794 name: name.clone(),
12795 type_args: None,
12796 args: args.clone(),
12797 },
12798 )?;
12799
12800 Ok(Value::Evidential {
12802 value: Box::new(method_result),
12803 evidence: Evidence::Known,
12804 })
12805 }
12806 }
12807 }
12808
12809 fn wrap_reported(&self, value: Value) -> Value {
12816 Value::Evidential {
12817 value: Box::new(value),
12818 evidence: Evidence::Reported,
12819 }
12820 }
12821
12822 fn protocol_send(&mut self, connection: &Value, data: &Value) -> Result<Value, RuntimeError> {
12824 match connection {
12826 Value::Map(obj) => {
12827 let obj = obj.borrow();
12828 if let Some(Value::String(protocol)) = obj.get("__protocol__") {
12829 match protocol.as_str() {
12830 "http" | "https" => {
12831 #[cfg(debug_assertions)]
12834 eprintln!("[HTTP] Would send request with body: {:?}", data);
12835 Ok(Value::Map(Rc::new(RefCell::new({
12836 let mut response = HashMap::new();
12837 response.insert("status".to_string(), Value::Int(200));
12838 response.insert("body".to_string(), data.clone());
12839 response.insert(
12840 "__protocol__".to_string(),
12841 Value::String(Rc::new("http_response".to_string())),
12842 );
12843 response
12844 }))))
12845 }
12846 "ws" | "wss" => {
12847 #[cfg(debug_assertions)]
12849 eprintln!("[WebSocket] Would send message: {:?}", data);
12850 Ok(Value::Bool(true)) }
12852 "grpc" => {
12853 #[cfg(debug_assertions)]
12855 eprintln!("[gRPC] Would send message: {:?}", data);
12856 Ok(Value::Map(Rc::new(RefCell::new({
12857 let mut response = HashMap::new();
12858 response.insert("status".to_string(), Value::Int(0)); response.insert("message".to_string(), data.clone());
12860 response.insert(
12861 "__protocol__".to_string(),
12862 Value::String(Rc::new("grpc_response".to_string())),
12863 );
12864 response
12865 }))))
12866 }
12867 "kafka" => {
12868 #[cfg(debug_assertions)]
12870 eprintln!("[Kafka] Would produce message: {:?}", data);
12871 Ok(Value::Map(Rc::new(RefCell::new({
12872 let mut result = HashMap::new();
12873 result.insert("partition".to_string(), Value::Int(0));
12874 result.insert("offset".to_string(), Value::Int(42));
12875 result
12876 }))))
12877 }
12878 _ => Err(RuntimeError::new(format!("Unknown protocol: {}", protocol))),
12879 }
12880 } else {
12881 Err(RuntimeError::new(
12882 "Connection object missing __protocol__ field",
12883 ))
12884 }
12885 }
12886 _ => Err(RuntimeError::new("send requires a connection object")),
12887 }
12888 }
12889
12890 fn protocol_recv(&mut self, connection: &Value) -> Result<Value, RuntimeError> {
12892 match connection {
12893 Value::Map(obj) => {
12894 let obj = obj.borrow();
12895 if let Some(Value::String(protocol)) = obj.get("__protocol__") {
12896 match protocol.as_str() {
12897 "ws" | "wss" => {
12898 #[cfg(debug_assertions)]
12900 eprintln!("[WebSocket] Would receive message");
12901 Ok(Value::String(Rc::new("received message".to_string())))
12902 }
12903 "kafka" => {
12904 #[cfg(debug_assertions)]
12906 eprintln!("[Kafka] Would consume message");
12907 Ok(Value::Map(Rc::new(RefCell::new({
12908 let mut msg = HashMap::new();
12909 msg.insert("key".to_string(), Value::Null);
12910 msg.insert(
12911 "value".to_string(),
12912 Value::String(Rc::new("consumed message".to_string())),
12913 );
12914 msg.insert("partition".to_string(), Value::Int(0));
12915 msg.insert("offset".to_string(), Value::Int(100));
12916 msg
12917 }))))
12918 }
12919 "grpc" => {
12920 #[cfg(debug_assertions)]
12922 eprintln!("[gRPC] Would receive stream message");
12923 Ok(Value::Map(Rc::new(RefCell::new({
12924 let mut msg = HashMap::new();
12925 msg.insert(
12926 "data".to_string(),
12927 Value::String(Rc::new("stream data".to_string())),
12928 );
12929 msg
12930 }))))
12931 }
12932 _ => Err(RuntimeError::new(format!(
12933 "recv not supported for protocol: {}",
12934 protocol
12935 ))),
12936 }
12937 } else {
12938 Err(RuntimeError::new(
12939 "Connection object missing __protocol__ field",
12940 ))
12941 }
12942 }
12943 _ => Err(RuntimeError::new("recv requires a connection object")),
12944 }
12945 }
12946
12947 fn protocol_stream(
12949 &mut self,
12950 connection: &Value,
12951 _handler: &Value,
12952 ) -> Result<Value, RuntimeError> {
12953 match connection {
12955 Value::Map(obj) => {
12956 let obj = obj.borrow();
12957 if let Some(Value::String(protocol)) = obj.get("__protocol__") {
12958 #[cfg(debug_assertions)]
12959 eprintln!("[{}] Would create stream", protocol);
12960
12961 Ok(Value::Map(Rc::new(RefCell::new({
12963 let mut stream = HashMap::new();
12964 stream.insert(
12965 "__type__".to_string(),
12966 Value::String(Rc::new("Stream".to_string())),
12967 );
12968 stream.insert("__protocol__".to_string(), Value::String(protocol.clone()));
12969 stream.insert(
12970 "__evidentiality__".to_string(),
12971 Value::String(Rc::new("reported".to_string())),
12972 );
12973 stream
12974 }))))
12975 } else {
12976 Err(RuntimeError::new(
12977 "Connection object missing __protocol__ field",
12978 ))
12979 }
12980 }
12981 _ => Err(RuntimeError::new("stream requires a connection object")),
12982 }
12983 }
12984
12985 fn protocol_connect(
12987 &mut self,
12988 target: &Value,
12989 _config: Option<&Value>,
12990 ) -> Result<Value, RuntimeError> {
12991 match target {
12992 Value::String(url) => {
12993 let protocol = if url.starts_with("wss://") || url.starts_with("ws://") {
12995 if url.starts_with("wss://") {
12996 "wss"
12997 } else {
12998 "ws"
12999 }
13000 } else if url.starts_with("https://") || url.starts_with("http://") {
13001 if url.starts_with("https://") {
13002 "https"
13003 } else {
13004 "http"
13005 }
13006 } else if url.starts_with("grpc://") || url.starts_with("grpcs://") {
13007 "grpc"
13008 } else if url.starts_with("kafka://") {
13009 "kafka"
13010 } else if url.starts_with("amqp://") || url.starts_with("amqps://") {
13011 "amqp"
13012 } else {
13013 "unknown"
13014 };
13015
13016 #[cfg(debug_assertions)]
13017 eprintln!("[{}] Would connect to: {}", protocol, url);
13018
13019 Ok(Value::Map(Rc::new(RefCell::new({
13021 let mut conn = HashMap::new();
13022 conn.insert(
13023 "__protocol__".to_string(),
13024 Value::String(Rc::new(protocol.to_string())),
13025 );
13026 conn.insert("url".to_string(), Value::String(url.clone()));
13027 conn.insert("connected".to_string(), Value::Bool(true));
13028 conn
13029 }))))
13030 }
13031 Value::Map(obj) => {
13032 let mut conn = obj.borrow().clone();
13034 conn.insert("connected".to_string(), Value::Bool(true));
13035 Ok(Value::Map(Rc::new(RefCell::new(conn))))
13036 }
13037 _ => Err(RuntimeError::new(
13038 "connect requires URL string or config object",
13039 )),
13040 }
13041 }
13042
13043 fn protocol_close(&mut self, connection: &Value) -> Result<(), RuntimeError> {
13045 match connection {
13046 Value::Map(obj) => {
13047 let mut obj = obj.borrow_mut();
13048 if let Some(Value::String(protocol)) = obj.get("__protocol__").cloned() {
13049 #[cfg(debug_assertions)]
13050 eprintln!("[{}] Would close connection", protocol);
13051 obj.insert("connected".to_string(), Value::Bool(false));
13052 Ok(())
13053 } else {
13054 Err(RuntimeError::new(
13055 "Connection object missing __protocol__ field",
13056 ))
13057 }
13058 }
13059 _ => Err(RuntimeError::new("close requires a connection object")),
13060 }
13061 }
13062
13063 fn protocol_add_header(
13065 &mut self,
13066 mut request: Value,
13067 name: &Value,
13068 header_value: &Value,
13069 ) -> Result<Value, RuntimeError> {
13070 let name_str = match name {
13071 Value::String(s) => (**s).clone(),
13072 _ => return Err(RuntimeError::new("Header name must be a string")),
13073 };
13074 let value_str = match header_value {
13075 Value::String(s) => (**s).clone(),
13076 Value::Int(i) => i.to_string(),
13077 _ => return Err(RuntimeError::new("Header value must be string or int")),
13078 };
13079
13080 match &mut request {
13081 Value::Map(obj) => {
13082 let mut obj = obj.borrow_mut();
13083
13084 let headers = obj
13086 .entry("headers".to_string())
13087 .or_insert_with(|| Value::Map(Rc::new(RefCell::new(HashMap::new()))));
13088
13089 if let Value::Map(headers_obj) = headers {
13090 headers_obj
13091 .borrow_mut()
13092 .insert(name_str, Value::String(Rc::new(value_str)));
13093 }
13094 drop(obj);
13095 Ok(request)
13096 }
13097 _ => Err(RuntimeError::new("header requires a request object")),
13098 }
13099 }
13100
13101 fn protocol_set_body(
13103 &mut self,
13104 mut request: Value,
13105 body: &Value,
13106 ) -> Result<Value, RuntimeError> {
13107 match &mut request {
13108 Value::Map(obj) => {
13109 obj.borrow_mut().insert("body".to_string(), body.clone());
13110 Ok(request)
13111 }
13112 _ => Err(RuntimeError::new("body requires a request object")),
13113 }
13114 }
13115
13116 fn protocol_set_timeout(
13118 &mut self,
13119 mut request: Value,
13120 ms: &Value,
13121 ) -> Result<Value, RuntimeError> {
13122 let timeout_ms = match ms {
13123 Value::Int(n) => *n,
13124 Value::Float(f) => *f as i64,
13125 _ => return Err(RuntimeError::new("Timeout must be a number (milliseconds)")),
13126 };
13127
13128 match &mut request {
13129 Value::Map(obj) => {
13130 obj.borrow_mut()
13131 .insert("timeout_ms".to_string(), Value::Int(timeout_ms));
13132 Ok(request)
13133 }
13134 _ => Err(RuntimeError::new("timeout requires a request object")),
13135 }
13136 }
13137
13138 fn protocol_set_retry(
13140 &mut self,
13141 mut request: Value,
13142 count: &Value,
13143 strategy: Option<&Value>,
13144 ) -> Result<Value, RuntimeError> {
13145 let retry_count = match count {
13146 Value::Int(n) => *n,
13147 _ => return Err(RuntimeError::new("Retry count must be an integer")),
13148 };
13149
13150 match &mut request {
13151 Value::Map(obj) => {
13152 let mut obj = obj.borrow_mut();
13153 obj.insert("retry_count".to_string(), Value::Int(retry_count));
13154 if let Some(strat) = strategy {
13155 obj.insert("retry_strategy".to_string(), strat.clone());
13156 }
13157 drop(obj);
13158 Ok(request)
13159 }
13160 _ => Err(RuntimeError::new("retry requires a request object")),
13161 }
13162 }
13163
13164 fn backward_propagate(&self, tensor_fields: Rc<RefCell<std::collections::HashMap<String, Value>>>) -> Result<(), RuntimeError> {
13166 let fields_ref = tensor_fields.borrow();
13167
13168 if let Some(Value::Struct { fields: grad_fields, .. }) = fields_ref.get("_grad_left") {
13170 let shape = grad_fields.borrow().get("shape").cloned();
13172 let data_len = match grad_fields.borrow().get("data") {
13173 Some(Value::Array(arr)) => arr.borrow().len(),
13174 _ => 0,
13175 };
13176
13177 let grad_data: Vec<Value> = vec![Value::Float(1.0); data_len];
13179 let mut grad_tensor_fields = std::collections::HashMap::new();
13180 if let Some(s) = shape {
13181 grad_tensor_fields.insert("shape".to_string(), s);
13182 }
13183 grad_tensor_fields.insert("data".to_string(), Value::Array(Rc::new(RefCell::new(grad_data))));
13184 grad_tensor_fields.insert("requires_grad".to_string(), Value::Bool(false));
13185
13186 grad_fields.borrow_mut().insert("grad".to_string(), Value::Variant {
13188 enum_name: "Option".to_string(),
13189 variant_name: "Some".to_string(),
13190 fields: Some(Rc::new(vec![Value::Struct {
13191 name: "Tensor".to_string(),
13192 fields: Rc::new(RefCell::new(grad_tensor_fields)),
13193 }])),
13194 });
13195
13196 self.backward_propagate(grad_fields.clone())?;
13198 }
13199
13200 if let Some(Value::Struct { fields: grad_fields, .. }) = fields_ref.get("_grad_input") {
13201 let shape = grad_fields.borrow().get("shape").cloned();
13203 let data_len = match grad_fields.borrow().get("data") {
13204 Some(Value::Array(arr)) => arr.borrow().len(),
13205 _ => 0,
13206 };
13207
13208 let grad_data: Vec<Value> = vec![Value::Float(1.0); data_len];
13209 let mut grad_tensor_fields = std::collections::HashMap::new();
13210 if let Some(s) = shape {
13211 grad_tensor_fields.insert("shape".to_string(), s);
13212 }
13213 grad_tensor_fields.insert("data".to_string(), Value::Array(Rc::new(RefCell::new(grad_data))));
13214 grad_tensor_fields.insert("requires_grad".to_string(), Value::Bool(false));
13215
13216 grad_fields.borrow_mut().insert("grad".to_string(), Value::Variant {
13218 enum_name: "Option".to_string(),
13219 variant_name: "Some".to_string(),
13220 fields: Some(Rc::new(vec![Value::Struct {
13221 name: "Tensor".to_string(),
13222 fields: Rc::new(RefCell::new(grad_tensor_fields)),
13223 }])),
13224 });
13225
13226 self.backward_propagate(grad_fields.clone())?;
13227 }
13228
13229 Ok(())
13230 }
13231
13232 fn sum_values(&self, value: Value) -> Result<Value, RuntimeError> {
13233 match value {
13234 Value::Array(arr) => {
13235 let arr = arr.borrow();
13236 if arr.is_empty() {
13237 return Ok(Value::Int(0));
13238 }
13239 let mut sum = match &arr[0] {
13240 Value::Int(_) => Value::Int(0),
13241 Value::Float(_) => Value::Float(0.0),
13242 _ => return Err(RuntimeError::new("Cannot sum non-numeric array")),
13243 };
13244 for item in arr.iter() {
13245 sum = match (&sum, item) {
13246 (Value::Int(a), Value::Int(b)) => Value::Int(a + b),
13247 (Value::Float(a), Value::Float(b)) => Value::Float(a + b),
13248 (Value::Int(a), Value::Float(b)) => Value::Float(*a as f64 + b),
13249 (Value::Float(a), Value::Int(b)) => Value::Float(a + *b as f64),
13250 _ => return Err(RuntimeError::new("Cannot sum non-numeric values")),
13251 };
13252 }
13253 Ok(sum)
13254 }
13255 Value::Struct { name, fields } if name == "Tensor" => {
13257 let fields_ref = fields.borrow();
13258 let requires_grad = matches!(fields_ref.get("requires_grad"), Some(Value::Bool(true)));
13259 let grad_left = fields_ref.get("_grad_left").cloned();
13260 let data: Vec<f64> = match fields_ref.get("data") {
13261 Some(Value::Array(arr)) => {
13262 arr.borrow().iter().filter_map(|v| match v {
13263 Value::Float(f) => Some(*f),
13264 Value::Int(n) => Some(*n as f64),
13265 _ => None,
13266 }).collect()
13267 }
13268 _ => vec![],
13269 };
13270 drop(fields_ref);
13271 let sum: f64 = data.iter().sum();
13272
13273 if requires_grad {
13275 let mut result_fields = std::collections::HashMap::new();
13276 result_fields.insert("shape".to_string(), Value::Array(Rc::new(RefCell::new(vec![]))));
13277 result_fields.insert("data".to_string(), Value::Array(Rc::new(RefCell::new(vec![Value::Float(sum)]))));
13278 result_fields.insert("_value".to_string(), Value::Float(sum));
13279 result_fields.insert("requires_grad".to_string(), Value::Bool(true));
13280 result_fields.insert("_op".to_string(), Value::String(Rc::new("sum".to_string())));
13281 if let Some(grad_input) = grad_left {
13283 result_fields.insert("_grad_left".to_string(), grad_input);
13284 } else {
13285 result_fields.insert("_grad_input".to_string(), Value::Struct {
13287 name: "Tensor".to_string(),
13288 fields: fields.clone(),
13289 });
13290 }
13291 Ok(Value::Struct {
13292 name: "Tensor".to_string(),
13293 fields: Rc::new(RefCell::new(result_fields)),
13294 })
13295 } else {
13296 Ok(Value::Float(sum))
13297 }
13298 }
13299 _ => Err(RuntimeError::new("sum requires array")),
13300 }
13301 }
13302
13303 fn product_values(&self, value: Value) -> Result<Value, RuntimeError> {
13304 match value {
13305 Value::Array(arr) => {
13306 let arr = arr.borrow();
13307 if arr.is_empty() {
13308 return Ok(Value::Int(1));
13309 }
13310 let mut prod = match &arr[0] {
13311 Value::Int(_) => Value::Int(1),
13312 Value::Float(_) => Value::Float(1.0),
13313 _ => return Err(RuntimeError::new("Cannot multiply non-numeric array")),
13314 };
13315 for item in arr.iter() {
13316 prod = match (&prod, item) {
13317 (Value::Int(a), Value::Int(b)) => Value::Int(a * b),
13318 (Value::Float(a), Value::Float(b)) => Value::Float(a * b),
13319 (Value::Int(a), Value::Float(b)) => Value::Float(*a as f64 * b),
13320 (Value::Float(a), Value::Int(b)) => Value::Float(a * *b as f64),
13321 _ => return Err(RuntimeError::new("Cannot multiply non-numeric values")),
13322 };
13323 }
13324 Ok(prod)
13325 }
13326 _ => Err(RuntimeError::new("product requires array")),
13327 }
13328 }
13329
13330 fn min_values(&self, value: Value) -> Result<Value, RuntimeError> {
13331 match value {
13332 Value::Array(arr) => {
13333 let arr = arr.borrow();
13334 if arr.is_empty() {
13335 return Err(RuntimeError::new("Cannot find min of empty array"));
13336 }
13337 let mut min = arr[0].clone();
13338 for item in arr.iter().skip(1) {
13339 min = match (&min, item) {
13340 (Value::Int(a), Value::Int(b)) => {
13341 if *b < *a {
13342 Value::Int(*b)
13343 } else {
13344 Value::Int(*a)
13345 }
13346 }
13347 (Value::Float(a), Value::Float(b)) => {
13348 if *b < *a {
13349 Value::Float(*b)
13350 } else {
13351 Value::Float(*a)
13352 }
13353 }
13354 (Value::Int(a), Value::Float(b)) => {
13355 let af = *a as f64;
13356 if *b < af {
13357 Value::Float(*b)
13358 } else {
13359 Value::Float(af)
13360 }
13361 }
13362 (Value::Float(a), Value::Int(b)) => {
13363 let bf = *b as f64;
13364 if bf < *a {
13365 Value::Float(bf)
13366 } else {
13367 Value::Float(*a)
13368 }
13369 }
13370 _ => {
13371 return Err(RuntimeError::new("Cannot find min of non-numeric values"))
13372 }
13373 };
13374 }
13375 Ok(min)
13376 }
13377 _ => Err(RuntimeError::new("min requires array")),
13378 }
13379 }
13380
13381 fn max_values(&self, value: Value) -> Result<Value, RuntimeError> {
13382 match value {
13383 Value::Array(arr) => {
13384 let arr = arr.borrow();
13385 if arr.is_empty() {
13386 return Err(RuntimeError::new("Cannot find max of empty array"));
13387 }
13388 let mut max = arr[0].clone();
13389 for item in arr.iter().skip(1) {
13390 max = match (&max, item) {
13391 (Value::Int(a), Value::Int(b)) => {
13392 if *b > *a {
13393 Value::Int(*b)
13394 } else {
13395 Value::Int(*a)
13396 }
13397 }
13398 (Value::Float(a), Value::Float(b)) => {
13399 if *b > *a {
13400 Value::Float(*b)
13401 } else {
13402 Value::Float(*a)
13403 }
13404 }
13405 (Value::Int(a), Value::Float(b)) => {
13406 let af = *a as f64;
13407 if *b > af {
13408 Value::Float(*b)
13409 } else {
13410 Value::Float(af)
13411 }
13412 }
13413 (Value::Float(a), Value::Int(b)) => {
13414 let bf = *b as f64;
13415 if bf > *a {
13416 Value::Float(bf)
13417 } else {
13418 Value::Float(*a)
13419 }
13420 }
13421 _ => {
13422 return Err(RuntimeError::new("Cannot find max of non-numeric values"))
13423 }
13424 };
13425 }
13426 Ok(max)
13427 }
13428 _ => Err(RuntimeError::new("max requires array")),
13429 }
13430 }
13431
13432 fn concat_values(&self, value: Value) -> Result<Value, RuntimeError> {
13433 match value {
13434 Value::Array(arr) => {
13435 let arr = arr.borrow();
13436 if arr.is_empty() {
13437 return Ok(Value::String(Rc::new(String::new())));
13438 }
13439 match &arr[0] {
13441 Value::String(_) => {
13442 let mut result = String::new();
13443 for item in arr.iter() {
13444 if let Value::String(s) = item {
13445 result.push_str(s);
13446 } else {
13447 return Err(RuntimeError::new(
13448 "concat requires all elements to be strings",
13449 ));
13450 }
13451 }
13452 Ok(Value::String(Rc::new(result)))
13453 }
13454 Value::Array(_) => {
13455 let mut result = Vec::new();
13456 for item in arr.iter() {
13457 if let Value::Array(inner) = item {
13458 result.extend(inner.borrow().iter().cloned());
13459 } else {
13460 return Err(RuntimeError::new(
13461 "concat requires all elements to be arrays",
13462 ));
13463 }
13464 }
13465 Ok(Value::Array(Rc::new(RefCell::new(result))))
13466 }
13467 _ => Err(RuntimeError::new("concat requires strings or arrays")),
13468 }
13469 }
13470 _ => Err(RuntimeError::new("concat requires array")),
13471 }
13472 }
13473
13474 fn all_values(&self, value: Value) -> Result<Value, RuntimeError> {
13475 match value {
13476 Value::Array(arr) => {
13477 let arr = arr.borrow();
13478 for item in arr.iter() {
13479 match item {
13480 Value::Bool(b) => {
13481 if !*b {
13482 return Ok(Value::Bool(false));
13483 }
13484 }
13485 _ => return Err(RuntimeError::new("all requires array of booleans")),
13486 }
13487 }
13488 Ok(Value::Bool(true))
13489 }
13490 _ => Err(RuntimeError::new("all requires array")),
13491 }
13492 }
13493
13494 fn any_values(&self, value: Value) -> Result<Value, RuntimeError> {
13495 match value {
13496 Value::Array(arr) => {
13497 let arr = arr.borrow();
13498 for item in arr.iter() {
13499 match item {
13500 Value::Bool(b) => {
13501 if *b {
13502 return Ok(Value::Bool(true));
13503 }
13504 }
13505 _ => return Err(RuntimeError::new("any requires array of booleans")),
13506 }
13507 }
13508 Ok(Value::Bool(false))
13509 }
13510 _ => Err(RuntimeError::new("any requires array")),
13511 }
13512 }
13513
13514 fn compare_values(&self, a: &Value, b: &Value, _field: &Option<Ident>) -> std::cmp::Ordering {
13515 match (a, b) {
13517 (Value::Int(a), Value::Int(b)) => a.cmp(b),
13518 (Value::Float(a), Value::Float(b)) => {
13519 a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal)
13520 }
13521 (Value::String(a), Value::String(b)) => a.cmp(b),
13522 _ => std::cmp::Ordering::Equal,
13523 }
13524 }
13525
13526 fn subtract_values(&self, a: &Value, b: &Value) -> Result<Value, RuntimeError> {
13528 match (a, b) {
13529 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a - b)),
13530 (Value::Float(a), Value::Float(b)) => Ok(Value::Float(a - b)),
13531 (Value::Int(a), Value::Float(b)) => Ok(Value::Float(*a as f64 - b)),
13532 (Value::Float(a), Value::Int(b)) => Ok(Value::Float(a - *b as f64)),
13533 _ => Err(RuntimeError::new(format!(
13534 "Cannot subtract {:?} from {:?}",
13535 b, a
13536 ))),
13537 }
13538 }
13539
13540 fn eval_closure(
13541 &mut self,
13542 params: &[ClosureParam],
13543 body: &Expr,
13544 ) -> Result<Value, RuntimeError> {
13545 let param_names: Vec<String> = params
13546 .iter()
13547 .map(|p| match &p.pattern {
13548 Pattern::Ident { name, .. } => name.name.clone(),
13549 _ => "_".to_string(),
13550 })
13551 .collect();
13552
13553 Ok(Value::Function(Rc::new(Function {
13554 name: None,
13555 params: param_names,
13556 body: body.clone(),
13557 closure: self.environment.clone(),
13558 })))
13559 }
13560
13561 fn eval_struct_literal(
13562 &mut self,
13563 path: &TypePath,
13564 fields: &[FieldInit],
13565 rest: &Option<Box<Expr>>,
13566 ) -> Result<Value, RuntimeError> {
13567 let raw_name = path
13568 .segments
13569 .iter()
13570 .map(|s| s.ident.name.as_str())
13571 .collect::<Vec<_>>()
13572 .join("·"); let name = if raw_name == "Self" {
13576 if let Some(ref self_type) = self.current_self_type {
13577 self_type.clone()
13578 } else {
13579 raw_name
13581 }
13582 } else {
13583 raw_name.replace("::", "·")
13585 };
13586
13587 let mut field_values = HashMap::new();
13588
13589 if let Some(rest_expr) = rest {
13591 let prev_self_type = self.current_self_type.clone();
13593 self.current_self_type = Some(name.clone());
13594
13595 let rest_value = self.evaluate(rest_expr)?;
13596
13597 self.current_self_type = prev_self_type;
13598
13599 if let Value::Struct {
13601 fields: rest_fields,
13602 ..
13603 } = rest_value
13604 {
13605 for (k, v) in rest_fields.borrow().iter() {
13606 field_values.insert(k.clone(), v.clone());
13607 }
13608 }
13609 }
13610
13611 for field in fields {
13613 let value = match &field.value {
13614 Some(expr) => self.evaluate(expr)?,
13615 None => self
13616 .environment
13617 .borrow()
13618 .get(&field.name.name)
13619 .ok_or_else(|| {
13620 RuntimeError::new(format!("Unknown variable: {}", field.name.name))
13621 })?,
13622 };
13623 field_values.insert(field.name.name.clone(), value);
13624 }
13625
13626 if path.segments.len() >= 2 {
13629 let enum_name_segments: Vec<&str> = path.segments[..path.segments.len() - 1]
13630 .iter()
13631 .map(|s| s.ident.name.as_str())
13632 .collect();
13633 let variant_name = &path.segments.last().unwrap().ident.name;
13634
13635 let enum_name_direct = enum_name_segments.join("::");
13637 let enum_name_qualified = enum_name_segments.join("·");
13638
13639 let enum_def_opt = self
13641 .types
13642 .get(&enum_name_direct)
13643 .or_else(|| self.types.get(&enum_name_qualified));
13644
13645 if let Some(TypeDef::Enum(enum_def)) = enum_def_opt {
13646 for variant in &enum_def.variants {
13648 if &variant.name.name == variant_name {
13649 let inner_struct = Value::Struct {
13652 name: format!("{}::{}", enum_name_direct, variant_name),
13653 fields: Rc::new(RefCell::new(field_values)),
13654 };
13655 return Ok(Value::Variant {
13656 enum_name: enum_name_direct,
13657 variant_name: variant_name.clone(),
13658 fields: Some(Rc::new(vec![inner_struct])),
13659 });
13660 }
13661 }
13662 }
13663 }
13664
13665 if let Some(TypeDef::Struct(struct_def)) = self.types.get(&name) {
13667 if let crate::ast::StructFields::Named(def_fields) = &struct_def.fields {
13668 for def_field in def_fields {
13669 if !field_values.contains_key(&def_field.name.name) {
13670 return Err(RuntimeError::new(format!(
13671 "missing field '{}' in struct '{}'",
13672 def_field.name.name,
13673 name
13674 )));
13675 }
13676 }
13677 }
13678 }
13679
13680 Ok(Value::Struct {
13681 name,
13682 fields: Rc::new(RefCell::new(field_values)),
13683 })
13684 }
13685
13686 fn extract_evidence(value: &Value) -> Option<Evidence> {
13688 match value {
13689 Value::Evidential { evidence, .. } => Some(*evidence),
13690 _ => None,
13691 }
13692 }
13693
13694 fn extract_affect(value: &Value) -> Option<&RuntimeAffect> {
13696 match value {
13697 Value::Affective { affect, .. } => Some(affect),
13698 _ => None,
13699 }
13700 }
13701
13702 fn affect_to_evidence(affect: &RuntimeAffect) -> Option<Evidence> {
13706 if affect.sarcasm {
13708 return Some(Evidence::Uncertain);
13709 }
13710
13711 match affect.confidence {
13713 Some(RuntimeConfidence::High) => Some(Evidence::Known),
13714 Some(RuntimeConfidence::Low) => Some(Evidence::Uncertain),
13715 Some(RuntimeConfidence::Medium) | None => None,
13716 }
13717 }
13718
13719 fn combine_evidence(a: Option<Evidence>, b: Option<Evidence>) -> Option<Evidence> {
13722 match (a, b) {
13723 (None, None) => None,
13724 (Some(e), None) | (None, Some(e)) => Some(e),
13725 (Some(a), Some(b)) => {
13726 let rank = |e: Evidence| match e {
13727 Evidence::Known => 0,
13728 Evidence::Uncertain => 1,
13729 Evidence::Predicted => 2,
13730 Evidence::Reported => 3,
13731 Evidence::Paradox => 4,
13732 };
13733 if rank(a) >= rank(b) {
13734 Some(a)
13735 } else {
13736 Some(b)
13737 }
13738 }
13739 }
13740 }
13741
13742 fn unwrap_evidential(value: &Value) -> &Value {
13744 match value {
13745 Value::Evidential { value: inner, .. } => Self::unwrap_evidential(inner),
13746 _ => value,
13747 }
13748 }
13749
13750 fn unwrap_affective(value: &Value) -> &Value {
13752 match value {
13753 Value::Affective { value: inner, .. } => Self::unwrap_affective(inner),
13754 _ => value,
13755 }
13756 }
13757
13758 fn unwrap_value(value: &Value) -> &Value {
13760 match value {
13761 Value::Evidential { value: inner, .. } => Self::unwrap_value(inner),
13762 Value::Affective { value: inner, .. } => Self::unwrap_value(inner),
13763 _ => value,
13764 }
13765 }
13766
13767 fn unwrap_all(value: &Value) -> Value {
13769 match value {
13770 Value::Evidential { value: inner, .. } => Self::unwrap_all(inner),
13771 Value::Affective { value: inner, .. } => Self::unwrap_all(inner),
13772 Value::Ref(r) => Self::unwrap_all(&r.borrow()),
13773 _ => value.clone(),
13774 }
13775 }
13776
13777 fn eval_evidential(&mut self, expr: &Expr, ev: &Evidentiality) -> Result<Value, RuntimeError> {
13778 let value = self.evaluate(expr)?;
13779
13780 if *ev == Evidentiality::Known {
13785 return match value {
13786 Value::Null => Ok(Value::Null), Value::Evidential { value: inner, .. } => Ok(*inner), other => Ok(other), };
13790 }
13791
13792 let evidence = match ev {
13793 Evidentiality::Known => Evidence::Known, Evidentiality::Uncertain | Evidentiality::Predicted => Evidence::Uncertain,
13795 Evidentiality::Reported => Evidence::Reported,
13796 Evidentiality::Paradox => Evidence::Paradox,
13797 };
13798 Ok(Value::Evidential {
13799 value: Box::new(value),
13800 evidence,
13801 })
13802 }
13803
13804 fn eval_format_macro(&mut self, tokens: &str) -> Result<Value, RuntimeError> {
13806 let tokens = tokens.trim();
13811 if !tokens.starts_with('"') {
13812 return Ok(Value::String(Rc::new(tokens.to_string())));
13814 }
13815
13816 let mut in_escape = false;
13818 let mut format_end = 1;
13819 for (i, c) in tokens[1..].char_indices() {
13820 if in_escape {
13821 in_escape = false;
13822 } else if c == '\\' {
13823 in_escape = true;
13824 } else if c == '"' {
13825 format_end = i + 2; break;
13827 }
13828 }
13829
13830 let format_str = &tokens[1..format_end - 1]; crate::sigil_debug!("DEBUG format_str: '{}'", format_str);
13832 let args_str = if format_end < tokens.len() {
13833 tokens[format_end..].trim_start_matches(',').trim()
13834 } else {
13835 ""
13836 };
13837
13838 let mut arg_values: Vec<String> = Vec::new();
13840 if !args_str.is_empty() {
13841 let mut depth = 0;
13843 let mut current_arg = String::new();
13844 for c in args_str.chars() {
13845 match c {
13846 '(' | '[' | '{' => {
13847 depth += 1;
13848 current_arg.push(c);
13849 }
13850 ')' | ']' | '}' => {
13851 depth -= 1;
13852 current_arg.push(c);
13853 }
13854 ',' if depth == 0 => {
13855 let arg = current_arg.trim().to_string();
13856 if !arg.is_empty() {
13857 let mut parser = crate::parser::Parser::new(&arg);
13859 match parser.parse_expr() {
13860 Ok(expr) => match self.evaluate(&expr) {
13861 Ok(val) => arg_values.push(self.format_value(&val)),
13862 Err(_) => arg_values.push(arg),
13863 },
13864 Err(_) => arg_values.push(arg),
13865 }
13866 }
13867 current_arg.clear();
13868 }
13869 _ => current_arg.push(c),
13870 }
13871 }
13872 let arg = current_arg.trim().to_string();
13874 if !arg.is_empty() {
13875 let mut parser = crate::parser::Parser::new(&arg);
13876 match parser.parse_expr() {
13877 Ok(expr) => match self.evaluate(&expr) {
13878 Ok(val) => arg_values.push(self.format_value(&val)),
13879 Err(_) => arg_values.push(arg),
13880 },
13881 Err(_) => arg_values.push(arg),
13882 }
13883 }
13884 }
13885
13886 let mut result = String::new();
13888 let mut arg_idx = 0;
13889 let mut chars = format_str.chars().peekable();
13890
13891 while let Some(c) = chars.next() {
13892 if c == '{' {
13893 if chars.peek() == Some(&'{') {
13894 chars.next();
13896 result.push('{');
13897 } else {
13898 let mut placeholder = String::new();
13900 while let Some(pc) = chars.next() {
13901 if pc == '}' {
13902 break;
13903 }
13904 placeholder.push(pc);
13905 }
13906 if arg_idx < arg_values.len() {
13908 result.push_str(&arg_values[arg_idx]);
13909 arg_idx += 1;
13910 } else {
13911 result.push_str(&format!("{{{}}}", placeholder));
13912 }
13913 }
13914 } else if c == '}' {
13915 if chars.peek() == Some(&'}') {
13916 chars.next();
13918 result.push('}');
13919 } else {
13920 result.push('}');
13921 }
13922 } else if c == '\\' {
13923 if let Some(next) = chars.next() {
13925 match next {
13926 'n' => result.push('\n'),
13927 't' => result.push('\t'),
13928 'r' => result.push('\r'),
13929 '\\' => result.push('\\'),
13930 '"' => result.push('"'),
13931 _ => {
13932 result.push('\\');
13933 result.push(next);
13934 }
13935 }
13936 }
13937 } else {
13938 result.push(c);
13939 }
13940 }
13941
13942 Ok(Value::String(Rc::new(result)))
13943 }
13944
13945 fn infer_expr_type(&self, expr: &Expr) -> Option<String> {
13948 match expr {
13949 Expr::Literal(lit) => match lit {
13950 Literal::Int { .. } => Some("i32".to_string()),
13951 Literal::Float { .. } => Some("f64".to_string()),
13952 Literal::String(_) | Literal::RawString(_) => Some("String".to_string()),
13953 Literal::Bool(_) => Some("bool".to_string()),
13954 Literal::Char(_) => Some("char".to_string()),
13955 Literal::Null => Some("null".to_string()),
13956 _ => None,
13957 },
13958 Expr::Array(elements) => {
13959 if let Some(first) = elements.first() {
13961 if let Some(elem_type) = self.infer_expr_type(first) {
13962 return Some(format!("[{}]", elem_type));
13963 }
13964 }
13965 Some("[_]".to_string())
13966 },
13967 Expr::Tuple(elements) => {
13968 let types: Vec<String> = elements.iter()
13969 .filter_map(|e| self.infer_expr_type(e))
13970 .collect();
13971 Some(format!("({})", types.join(", ")))
13972 },
13973 Expr::Block(block) => {
13974 if let Some(ref e) = block.expr {
13976 return self.infer_expr_type(e);
13977 }
13978 Some("()".to_string())
13979 },
13980 Expr::If { then_branch, else_branch, .. } => {
13981 if let Some(ref e) = then_branch.expr {
13983 if let Some(t) = self.infer_expr_type(e) {
13984 return Some(t);
13985 }
13986 }
13987 if let Some(e) = else_branch {
13988 return self.infer_expr_type(e);
13989 }
13990 None
13991 },
13992 _ => None, }
13994 }
13995
13996 fn value_type_name(&self, value: &Value) -> String {
13998 match value {
13999 Value::Int(_) => "i32".to_string(),
14000 Value::Float(_) => "f64".to_string(),
14001 Value::String(_) => "String".to_string(),
14002 Value::Bool(_) => "bool".to_string(),
14003 Value::Char(_) => "char".to_string(),
14004 Value::Null => "null".to_string(),
14005 Value::Array(_) => "Array".to_string(),
14006 Value::Tuple(_) => "Tuple".to_string(),
14007 Value::Struct { name, .. } => name.clone(),
14008 Value::Variant { enum_name, .. } => enum_name.clone(),
14009 Value::Function(_) => "Function".to_string(),
14010 Value::BuiltIn(_) => "BuiltIn".to_string(),
14011 Value::Ref(_) => "Ref".to_string(),
14012 _ => "unknown".to_string(),
14013 }
14014 }
14015
14016 fn extract_type_params(&self, type_expr: &crate::ast::TypeExpr) -> Option<(String, Vec<String>)> {
14019 use crate::ast::TypeExpr;
14020
14021 if let TypeExpr::Path(path) = type_expr {
14022 if let Some(segment) = path.segments.first() {
14023 let type_name = segment.ident.name.clone();
14024 if let Some(generics) = &segment.generics {
14025 let mut type_params: Vec<String> = Vec::new();
14026 for generic in generics {
14027 if let TypeExpr::Path(inner_path) = generic {
14028 if let Some(inner_seg) = inner_path.segments.first() {
14029 type_params.push(inner_seg.ident.name.clone());
14030 }
14031 }
14032 }
14033 return Some((type_name, type_params));
14034 }
14035 return Some((type_name, vec![]));
14036 }
14037 }
14038 None
14039 }
14040
14041 fn check_generic_type_match(
14043 &self,
14044 type_name: &str,
14045 type_params: &[String],
14046 value: &Value,
14047 ) -> Result<(), RuntimeError> {
14048 match (type_name, value) {
14049 ("Option", Value::Variant { enum_name, variant_name, fields })
14051 if enum_name == "Option" && variant_name == "Some" => {
14052 if let (Some(expected_type), Some(fields)) = (type_params.first(), fields) {
14053 if let Some(inner_value) = fields.first() {
14054 let actual_type = self.value_type_name(inner_value);
14055 if &actual_type != expected_type {
14056 return Err(RuntimeError::new(format!(
14057 "type mismatch: expected Option<{}>, found Some({})",
14058 expected_type, actual_type
14059 )));
14060 }
14061 }
14062 }
14063 }
14064 ("Result", Value::Variant { enum_name, variant_name, fields })
14066 if enum_name == "Result" && variant_name == "Ok" => {
14067 if let (Some(expected_type), Some(fields)) = (type_params.first(), fields) {
14068 if let Some(inner_value) = fields.first() {
14069 let actual_type = self.value_type_name(inner_value);
14070 if &actual_type != expected_type {
14071 return Err(RuntimeError::new(format!(
14072 "type mismatch: expected Result<{}, _>, found Ok({})",
14073 expected_type, actual_type
14074 )));
14075 }
14076 }
14077 }
14078 }
14079 ("Result", Value::Variant { enum_name, variant_name, fields })
14081 if enum_name == "Result" && variant_name == "Err" => {
14082 if let (Some(expected_type), Some(fields)) = (type_params.get(1), fields) {
14083 if let Some(inner_value) = fields.first() {
14084 let actual_type = self.value_type_name(inner_value);
14085 if &actual_type != expected_type {
14086 return Err(RuntimeError::new(format!(
14087 "type mismatch: expected Result<_, {}>, found Err({})",
14088 expected_type, actual_type
14089 )));
14090 }
14091 }
14092 }
14093 }
14094 _ => {} }
14096 Ok(())
14097 }
14098
14099 fn format_value(&self, value: &Value) -> String {
14101 match value {
14102 Value::String(s) => s.to_string(),
14103 Value::Int(n) => n.to_string(),
14104 Value::Float(f) => f.to_string(),
14105 Value::Bool(b) => b.to_string(),
14106 Value::Char(c) => c.to_string(),
14107 Value::Null => "null".to_string(),
14108 Value::Array(arr) => {
14109 let items: Vec<String> =
14110 arr.borrow().iter().map(|v| self.format_value(v)).collect();
14111 format!("[{}]", items.join(", "))
14112 }
14113 Value::Tuple(items) => {
14114 let formatted: Vec<String> = items.iter().map(|v| self.format_value(v)).collect();
14115 format!("({})", formatted.join(", "))
14116 }
14117 Value::Struct { name, fields } => {
14118 let field_strs: Vec<String> = fields
14119 .borrow()
14120 .iter()
14121 .map(|(k, v)| format!("{}: {}", k, self.format_value(v)))
14122 .collect();
14123 format!("{} {{ {} }}", name, field_strs.join(", "))
14124 }
14125 Value::Variant {
14126 enum_name,
14127 variant_name,
14128 fields,
14129 } => match fields {
14130 Some(f) if !f.is_empty() => {
14131 let formatted: Vec<String> = f.iter().map(|v| self.format_value(v)).collect();
14132 format!("{}::{}({})", enum_name, variant_name, formatted.join(", "))
14133 }
14134 _ => format!("{}::{}", enum_name, variant_name),
14135 },
14136 Value::Evidential {
14137 value: inner,
14138 evidence,
14139 } => {
14140 format!("{:?}{}", evidence, self.format_value(inner))
14141 }
14142 Value::Ref(r) => self.format_value(&r.borrow()),
14143 _ => format!("{:?}", value),
14144 }
14145 }
14146
14147 fn eval_vec_macro(&mut self, tokens: &str) -> Result<Value, RuntimeError> {
14149 let mut elements = Vec::new();
14151 let mut depth = 0;
14152 let mut current = String::new();
14153
14154 for c in tokens.chars() {
14155 match c {
14156 '(' | '[' | '{' => {
14157 depth += 1;
14158 current.push(c);
14159 }
14160 ')' | ']' | '}' => {
14161 depth -= 1;
14162 current.push(c);
14163 }
14164 ',' if depth == 0 => {
14165 let elem = current.trim().to_string();
14166 if !elem.is_empty() {
14167 let mut parser = crate::parser::Parser::new(&elem);
14168 if let Ok(expr) = parser.parse_expr() {
14169 elements.push(self.evaluate(&expr)?);
14170 }
14171 }
14172 current.clear();
14173 }
14174 _ => current.push(c),
14175 }
14176 }
14177
14178 let elem = current.trim().to_string();
14180 if !elem.is_empty() {
14181 let mut parser = crate::parser::Parser::new(&elem);
14182 if let Ok(expr) = parser.parse_expr() {
14183 elements.push(self.evaluate(&expr)?);
14184 }
14185 }
14186
14187 Ok(Value::Array(Rc::new(RefCell::new(elements))))
14188 }
14189
14190 fn eval_range(
14191 &mut self,
14192 start: &Option<Box<Expr>>,
14193 end: &Option<Box<Expr>>,
14194 inclusive: bool,
14195 ) -> Result<Value, RuntimeError> {
14196 let start_val = match start {
14197 Some(e) => match self.evaluate(e)? {
14198 Value::Int(n) => n,
14199 _ => return Err(RuntimeError::new("Range requires integer bounds")),
14200 },
14201 None => 0,
14202 };
14203
14204 let end_val = match end {
14205 Some(e) => match self.evaluate(e)? {
14206 Value::Int(n) => n,
14207 _ => return Err(RuntimeError::new("Range requires integer bounds")),
14208 },
14209 None => {
14210 return Ok(Value::Tuple(Rc::new(vec![
14213 Value::Int(start_val),
14214 Value::Null, ])));
14216 }
14217 };
14218
14219 let values: Vec<Value> = if inclusive {
14220 (start_val..=end_val).map(Value::Int).collect()
14221 } else {
14222 (start_val..end_val).map(Value::Int).collect()
14223 };
14224
14225 Ok(Value::Array(Rc::new(RefCell::new(values))))
14226 }
14227
14228 fn is_truthy(&self, value: &Value) -> bool {
14229 match value {
14230 Value::Null => false,
14231 Value::Bool(b) => *b,
14232 Value::Int(n) => *n != 0,
14233 Value::Float(n) => *n != 0.0,
14234 Value::String(s) => !s.is_empty(),
14235 Value::Array(arr) => !arr.borrow().is_empty(),
14236 Value::Empty => false,
14237 Value::Evidential { value, .. } => self.is_truthy(value),
14238 _ => true,
14239 }
14240 }
14241}
14242
14243impl Default for Interpreter {
14244 fn default() -> Self {
14245 Self::new()
14246 }
14247}
14248
14249#[cfg(test)]
14250mod tests {
14251 use super::*;
14252 use crate::Parser;
14253
14254 fn run(source: &str) -> Result<Value, RuntimeError> {
14255 let mut parser = Parser::new(source);
14256 let file = parser
14257 .parse_file()
14258 .map_err(|e| RuntimeError::new(e.to_string()))?;
14259 let mut interp = Interpreter::new();
14260 interp.execute(&file)
14261 }
14262
14263 #[test]
14264 fn test_arithmetic() {
14265 assert!(matches!(
14266 run("fn main() { return 2 + 3; }"),
14267 Ok(Value::Int(5))
14268 ));
14269 assert!(matches!(
14270 run("fn main() { return 10 - 4; }"),
14271 Ok(Value::Int(6))
14272 ));
14273 assert!(matches!(
14274 run("fn main() { return 3 * 4; }"),
14275 Ok(Value::Int(12))
14276 ));
14277 assert!(matches!(
14278 run("fn main() { return 15 / 3; }"),
14279 Ok(Value::Int(5))
14280 ));
14281 assert!(matches!(
14282 run("fn main() { return 2 ** 10; }"),
14283 Ok(Value::Int(1024))
14284 ));
14285 }
14286
14287 #[test]
14288 fn test_variables() {
14289 assert!(matches!(
14290 run("fn main() { let x = 42; return x; }"),
14291 Ok(Value::Int(42))
14292 ));
14293 }
14294
14295 #[test]
14296 fn test_conditionals() {
14297 assert!(matches!(
14298 run("fn main() { if true { return 1; } else { return 2; } }"),
14299 Ok(Value::Int(1))
14300 ));
14301 assert!(matches!(
14302 run("fn main() { if false { return 1; } else { return 2; } }"),
14303 Ok(Value::Int(2))
14304 ));
14305 }
14306
14307 #[test]
14308 fn test_arrays() {
14309 assert!(matches!(
14310 run("fn main() { return [1, 2, 3][1]; }"),
14311 Ok(Value::Int(2))
14312 ));
14313 }
14314
14315 #[test]
14316 fn test_functions() {
14317 let result = run("
14318 fn double(x: i64) -> i64 { return x * 2; }
14319 fn main() { return double(21); }
14320 ");
14321 assert!(matches!(result, Ok(Value::Int(42))));
14322 }
14323
14324 #[test]
14325 fn test_pipe_transform() {
14326 let result = run("fn main() { return [1, 2, 3]|τ{_ * 2}|sum; }");
14327 assert!(matches!(result, Ok(Value::Int(12))));
14328 }
14329
14330 #[test]
14331 fn test_pipe_filter() {
14332 let result = run("fn main() { return [1, 2, 3, 4, 5]|φ{_ > 2}|sum; }");
14333 assert!(matches!(result, Ok(Value::Int(12)))); }
14335
14336 #[test]
14337 fn test_interpolation_evidentiality_propagation() {
14338 let result = run(r#"
14341 fn main() {
14342 let rep = reported(42);
14343
14344 // Interpolating a reported value should make the string reported
14345 let s = f"Value: {rep}";
14346 return s;
14347 }
14348 "#);
14349
14350 match result {
14351 Ok(Value::Evidential {
14352 evidence: Evidence::Reported,
14353 value,
14354 }) => {
14355 assert!(matches!(*value, Value::String(_)));
14357 }
14358 Ok(other) => panic!("Expected Evidential Reported, got {:?}", other),
14359 Err(e) => panic!("Error: {:?}", e),
14360 }
14361 }
14362
14363 #[test]
14364 fn test_interpolation_worst_evidence_wins() {
14365 let result = run(r#"
14367 fn main() {
14368 let k = known(1); // Known is best
14369 let u = uncertain(2); // Uncertain is worse
14370
14371 // Combining known and uncertain should yield uncertain
14372 let s = f"{k} and {u}";
14373 return s;
14374 }
14375 "#);
14376
14377 match result {
14378 Ok(Value::Evidential {
14379 evidence: Evidence::Uncertain,
14380 ..
14381 }) => (),
14382 Ok(other) => panic!("Expected Evidential Uncertain, got {:?}", other),
14383 Err(e) => panic!("Error: {:?}", e),
14384 }
14385 }
14386
14387 #[test]
14388 fn test_interpolation_no_evidential_plain_string() {
14389 let result = run(r#"
14391 fn main() {
14392 let x = 42;
14393 let s = f"Value: {x}";
14394 return s;
14395 }
14396 "#);
14397
14398 match result {
14399 Ok(Value::String(s)) => {
14400 assert_eq!(*s, "Value: 42");
14401 }
14402 Ok(other) => panic!("Expected plain String, got {:?}", other),
14403 Err(e) => panic!("Error: {:?}", e),
14404 }
14405 }
14406}