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 RefCellValue(Rc<RefCellInner>),
93 TraitObject {
95 value: Box<Value>,
97 concrete_type: String,
99 trait_name: String,
101 },
102}
103
104pub struct RefCellInner {
106 pub value: RefCell<Value>,
108 pub borrow_state: RefCell<BorrowState>,
110}
111
112impl Clone for RefCellInner {
113 fn clone(&self) -> Self {
114 RefCellInner {
115 value: RefCell::new(self.value.borrow().clone()),
116 borrow_state: RefCell::new(BorrowState::Unborrowed),
117 }
118 }
119}
120
121#[derive(Clone, Debug)]
123pub enum BorrowState {
124 Unborrowed,
126 Borrowed(usize),
128 BorrowedMut,
130}
131
132#[derive(Clone)]
134pub enum FutureState {
135 Pending,
137 Running,
139 Ready(Box<Value>),
141 Failed(String),
143}
144
145pub struct FutureInner {
147 pub state: FutureState,
149 pub computation: Option<FutureComputation>,
151 pub complete_at: Option<std::time::Instant>,
153}
154
155impl Clone for FutureInner {
156 fn clone(&self) -> Self {
157 FutureInner {
158 state: self.state.clone(),
159 computation: self.computation.clone(),
160 complete_at: self.complete_at,
161 }
162 }
163}
164
165#[derive(Clone)]
167pub enum FutureComputation {
168 Immediate(Box<Value>),
170 Timer(std::time::Duration),
172 Lazy {
174 func: Rc<Function>,
175 args: Vec<Value>,
176 },
177 Join(Vec<Rc<RefCell<FutureInner>>>),
179 Race(Vec<Rc<RefCell<FutureInner>>>),
181}
182
183pub struct ChannelInner {
185 pub sender: Mutex<mpsc::Sender<Value>>,
186 pub receiver: Mutex<mpsc::Receiver<Value>>,
187}
188
189impl Clone for ChannelInner {
190 fn clone(&self) -> Self {
191 panic!("Channels cannot be cloned directly - use channel_clone()")
194 }
195}
196
197pub struct ActorInner {
200 pub name: String,
201 pub message_queue: Mutex<Vec<(String, String)>>, pub message_count: std::sync::atomic::AtomicUsize,
203}
204
205#[derive(Debug, Clone, Copy, PartialEq, Eq)]
207pub enum Evidence {
208 Known, Uncertain, Reported, Paradox, }
213
214#[derive(Debug, Clone, PartialEq)]
216pub struct RuntimeAffect {
217 pub sentiment: Option<RuntimeSentiment>,
218 pub sarcasm: bool, pub intensity: Option<RuntimeIntensity>,
220 pub formality: Option<RuntimeFormality>,
221 pub emotion: Option<RuntimeEmotion>,
222 pub confidence: Option<RuntimeConfidence>,
223}
224
225#[derive(Debug, Clone, Copy, PartialEq, Eq)]
226pub enum RuntimeSentiment {
227 Positive, Negative, Neutral, }
231
232#[derive(Debug, Clone, Copy, PartialEq, Eq)]
233pub enum RuntimeIntensity {
234 Up, Down, Max, }
238
239#[derive(Debug, Clone, Copy, PartialEq, Eq)]
240pub enum RuntimeFormality {
241 Formal, Informal, }
244
245#[derive(Debug, Clone, Copy, PartialEq, Eq)]
246pub enum RuntimeEmotion {
247 Joy, Sadness, Anger, Fear, Surprise, Love, }
254
255#[derive(Debug, Clone, Copy, PartialEq, Eq)]
256pub enum RuntimeConfidence {
257 High, Medium, Low, }
261
262pub struct Function {
264 pub name: Option<String>,
265 pub params: Vec<String>,
266 pub body: Expr,
267 pub closure: Rc<RefCell<Environment>>,
268}
269
270pub struct BuiltInFn {
272 pub name: String,
273 pub arity: Option<usize>, pub func: fn(&mut Interpreter, Vec<Value>) -> Result<Value, RuntimeError>,
275}
276
277impl fmt::Debug for Value {
278 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
279 match self {
280 Value::Null => write!(f, "null"),
281 Value::Bool(b) => write!(f, "{}", b),
282 Value::Int(n) => write!(f, "{}", n),
283 Value::Float(n) => write!(f, "{}", n),
284 Value::String(s) => write!(f, "\"{}\"", s),
285 Value::Char(c) => write!(f, "'{}'", c),
286 Value::Array(arr) => {
287 let arr = arr.borrow();
288 write!(f, "[")?;
289 for (i, v) in arr.iter().enumerate() {
290 if i > 0 {
291 write!(f, ", ")?;
292 }
293 write!(f, "{:?}", v)?;
294 }
295 write!(f, "]")
296 }
297 Value::Tuple(vals) => {
298 write!(f, "(")?;
299 for (i, v) in vals.iter().enumerate() {
300 if i > 0 {
301 write!(f, ", ")?;
302 }
303 write!(f, "{:?}", v)?;
304 }
305 write!(f, ")")
306 }
307 Value::Struct { name, fields } => {
308 write!(f, "{} {{ ", name)?;
309 let fields = fields.borrow();
310 for (i, (k, v)) in fields.iter().enumerate() {
311 if i > 0 {
312 write!(f, ", ")?;
313 }
314 write!(f, "{}: {:?}", k, v)?;
315 }
316 write!(f, " }}")
317 }
318 Value::Variant {
319 enum_name,
320 variant_name,
321 fields,
322 } => {
323 write!(f, "{}::{}", enum_name, variant_name)?;
324 if let Some(fields) = fields {
325 write!(f, "(")?;
326 for (i, v) in fields.iter().enumerate() {
327 if i > 0 {
328 write!(f, ", ")?;
329 }
330 write!(f, "{:?}", v)?;
331 }
332 write!(f, ")")?;
333 }
334 Ok(())
335 }
336 Value::Function(func) => {
337 write!(f, "<fn {}>", func.name.as_deref().unwrap_or("anonymous"))
338 }
339 Value::BuiltIn(b) => write!(f, "<builtin {}>", b.name),
340 Value::Ref(r) => write!(f, "&{:?}", r.borrow()),
341 Value::Infinity => write!(f, "∞"),
342 Value::Empty => write!(f, "∅"),
343 Value::Evidential { value, evidence } => {
344 write!(f, "{:?}", value)?;
345 match evidence {
346 Evidence::Known => write!(f, "!"),
347 Evidence::Uncertain => write!(f, "?"),
348 Evidence::Reported => write!(f, "~"),
349 Evidence::Paradox => write!(f, "‽"),
350 }
351 }
352 Value::Map(map) => {
353 let map = map.borrow();
354 write!(f, "{{")?;
355 for (i, (k, v)) in map.iter().enumerate() {
356 if i > 0 {
357 write!(f, ", ")?;
358 }
359 write!(f, "{:?}: {:?}", k, v)?;
360 }
361 write!(f, "}}")
362 }
363 Value::Set(set) => {
364 let set = set.borrow();
365 write!(f, "Set{{")?;
366 for (i, k) in set.iter().enumerate() {
367 if i > 0 {
368 write!(f, ", ")?;
369 }
370 write!(f, "{:?}", k)?;
371 }
372 write!(f, "}}")
373 }
374 Value::Channel(_) => write!(f, "<channel>"),
375 Value::ThreadHandle(_) => write!(f, "<thread>"),
376 Value::Actor(actor) => write!(f, "<actor {}>", actor.name),
377 Value::Future(fut) => {
378 let fut = fut.borrow();
379 match &fut.state {
380 FutureState::Pending => write!(f, "<future pending>"),
381 FutureState::Running => write!(f, "<future running>"),
382 FutureState::Ready(v) => write!(f, "<future ready: {:?}>", v),
383 FutureState::Failed(e) => write!(f, "<future failed: {}>", e),
384 }
385 }
386 Value::Affective { value, affect } => {
387 write!(f, "{:?}", value)?;
388 if let Some(s) = &affect.sentiment {
389 match s {
390 RuntimeSentiment::Positive => write!(f, "⊕")?,
391 RuntimeSentiment::Negative => write!(f, "⊖")?,
392 RuntimeSentiment::Neutral => write!(f, "⊜")?,
393 }
394 }
395 if affect.sarcasm {
396 write!(f, "⸮")?;
397 }
398 if let Some(i) = &affect.intensity {
399 match i {
400 RuntimeIntensity::Up => write!(f, "↑")?,
401 RuntimeIntensity::Down => write!(f, "↓")?,
402 RuntimeIntensity::Max => write!(f, "⇈")?,
403 }
404 }
405 if let Some(fo) = &affect.formality {
406 match fo {
407 RuntimeFormality::Formal => write!(f, "♔")?,
408 RuntimeFormality::Informal => write!(f, "♟")?,
409 }
410 }
411 if let Some(e) = &affect.emotion {
412 match e {
413 RuntimeEmotion::Joy => write!(f, "☺")?,
414 RuntimeEmotion::Sadness => write!(f, "☹")?,
415 RuntimeEmotion::Anger => write!(f, "⚡")?,
416 RuntimeEmotion::Fear => write!(f, "❄")?,
417 RuntimeEmotion::Surprise => write!(f, "✦")?,
418 RuntimeEmotion::Love => write!(f, "♡")?,
419 }
420 }
421 if let Some(c) = &affect.confidence {
422 match c {
423 RuntimeConfidence::High => write!(f, "◉")?,
424 RuntimeConfidence::Medium => write!(f, "◎")?,
425 RuntimeConfidence::Low => write!(f, "○")?,
426 }
427 }
428 Ok(())
429 }
430 Value::VariantConstructor { enum_name, variant_name } => {
431 write!(f, "<constructor {}::{}>", enum_name, variant_name)
432 }
433 Value::DefaultConstructor { type_name } => {
434 write!(f, "<default {}>", type_name)
435 }
436 Value::Range { start, end, inclusive } => {
437 match (start, end) {
438 (Some(s), Some(e)) => if *inclusive {
439 write!(f, "{}..={}", s, e)
440 } else {
441 write!(f, "{}..{}", s, e)
442 },
443 (Some(s), None) => write!(f, "{}..", s),
444 (None, Some(e)) => if *inclusive {
445 write!(f, "..={}", e)
446 } else {
447 write!(f, "..{}", e)
448 },
449 (None, None) => write!(f, ".."),
450 }
451 }
452 Value::RefCellValue(rc) => {
453 write!(f, "RefCell({:?})", rc.value.borrow())
454 }
455 Value::TraitObject { value, concrete_type, trait_name } => {
456 write!(f, "dyn {}({}: {:?})", trait_name, concrete_type, value)
457 }
458 }
459 }
460}
461
462impl fmt::Display for Value {
463 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
464 match self {
465 Value::Null => write!(f, "null"),
466 Value::Bool(b) => write!(f, "{}", b),
467 Value::Int(n) => write!(f, "{}", n),
468 Value::Float(n) => write!(f, "{}", n),
469 Value::String(s) => write!(f, "{}", s),
470 Value::Char(c) => write!(f, "{}", c),
471 Value::Array(arr) => {
472 let arr = arr.borrow();
473 write!(f, "[")?;
474 for (i, v) in arr.iter().enumerate() {
475 if i > 0 {
476 write!(f, ", ")?;
477 }
478 write!(f, "{}", v)?;
479 }
480 write!(f, "]")
481 }
482 Value::Evidential { value, .. } => write!(f, "{}", value),
483 Value::Affective { value, affect } => {
484 let mut suffix = String::new();
486 if let Some(sent) = &affect.sentiment {
487 suffix.push(match sent {
488 RuntimeSentiment::Positive => '⊕',
489 RuntimeSentiment::Negative => '⊖',
490 RuntimeSentiment::Neutral => '⊜',
491 });
492 }
493 if affect.sarcasm {
494 suffix.push('⸮');
495 }
496 if let Some(int) = &affect.intensity {
497 suffix.push(match int {
498 RuntimeIntensity::Up => '↑',
499 RuntimeIntensity::Down => '↓',
500 RuntimeIntensity::Max => '⇈',
501 });
502 }
503 if let Some(form) = &affect.formality {
504 suffix.push(match form {
505 RuntimeFormality::Formal => '♔',
506 RuntimeFormality::Informal => '♟',
507 });
508 }
509 if let Some(emo) = &affect.emotion {
510 suffix.push(match emo {
511 RuntimeEmotion::Joy => '☺',
512 RuntimeEmotion::Sadness => '☹',
513 RuntimeEmotion::Anger => '⚡',
514 RuntimeEmotion::Fear => '❄',
515 RuntimeEmotion::Surprise => '✦',
516 RuntimeEmotion::Love => '♡',
517 });
518 }
519 if let Some(conf) = &affect.confidence {
520 suffix.push(match conf {
521 RuntimeConfidence::High => '◉',
522 RuntimeConfidence::Medium => '◎',
523 RuntimeConfidence::Low => '○',
524 });
525 }
526 write!(f, "{}{}", value, suffix)
527 }
528 Value::RefCellValue(rc) => {
529 write!(f, "RefCell({})", rc.value.borrow())
530 }
531 Value::TraitObject { value, trait_name, .. } => {
532 write!(f, "dyn {}({})", trait_name, value)
533 }
534 _ => write!(f, "{:?}", self),
535 }
536 }
537}
538
539#[derive(Debug)]
541pub struct RuntimeError {
542 pub message: String,
543 pub span: Option<Span>,
544}
545
546impl RuntimeError {
547 pub fn new(message: impl Into<String>) -> Self {
548 Self {
549 message: message.into(),
550 span: None,
551 }
552 }
553
554 pub fn with_span(message: impl Into<String>, span: Span) -> Self {
555 Self {
556 message: message.into(),
557 span: Some(span),
558 }
559 }
560}
561
562impl fmt::Display for RuntimeError {
563 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
564 write!(f, "Runtime error: {}", self.message)?;
565 if let Some(span) = self.span {
566 write!(f, " at {}", span)?;
567 }
568 Ok(())
569 }
570}
571
572#[derive(Debug, Clone)]
574pub enum ControlFlow {
575 Return(Value),
576 Break(Option<Value>),
577 Continue,
578}
579
580impl From<ControlFlow> for RuntimeError {
581 fn from(cf: ControlFlow) -> Self {
582 match cf {
583 ControlFlow::Return(_) => RuntimeError::new("return outside function"),
584 ControlFlow::Break(_) => RuntimeError::new("break outside loop"),
585 ControlFlow::Continue => RuntimeError::new("continue outside loop"),
586 }
587 }
588}
589
590pub type EvalResult = Result<Value, EvalError>;
592
593#[derive(Debug)]
595pub enum EvalError {
596 Runtime(RuntimeError),
597 Control(ControlFlow),
598}
599
600impl From<RuntimeError> for EvalError {
601 fn from(e: RuntimeError) -> Self {
602 EvalError::Runtime(e)
603 }
604}
605
606impl From<ControlFlow> for EvalError {
607 fn from(cf: ControlFlow) -> Self {
608 EvalError::Control(cf)
609 }
610}
611
612impl fmt::Display for EvalError {
613 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
614 match self {
615 EvalError::Runtime(e) => write!(f, "{}", e),
616 EvalError::Control(cf) => write!(f, "Unexpected control flow: {:?}", cf),
617 }
618 }
619}
620
621#[derive(Clone)]
623pub struct Environment {
624 values: HashMap<String, Value>,
625 parent: Option<Rc<RefCell<Environment>>>,
626}
627
628impl Environment {
629 pub fn new() -> Self {
630 Self {
631 values: HashMap::new(),
632 parent: None,
633 }
634 }
635
636 pub fn with_parent(parent: Rc<RefCell<Environment>>) -> Self {
637 Self {
638 values: HashMap::new(),
639 parent: Some(parent),
640 }
641 }
642
643 pub fn define(&mut self, name: String, value: Value) {
644 self.values.insert(name, value);
645 }
646
647 pub fn get(&self, name: &str) -> Option<Value> {
648 if let Some(value) = self.values.get(name) {
649 Some(value.clone())
650 } else if let Some(ref parent) = self.parent {
651 parent.borrow().get(name)
652 } else {
653 None
654 }
655 }
656
657 pub fn set(&mut self, name: &str, value: Value) -> Result<(), RuntimeError> {
658 if self.values.contains_key(name) {
659 self.values.insert(name.to_string(), value);
660 Ok(())
661 } else if let Some(ref parent) = self.parent {
662 parent.borrow_mut().set(name, value)
663 } else {
664 Err(RuntimeError::new(format!("Undefined variable: {}", name)))
665 }
666 }
667}
668
669impl Default for Environment {
670 fn default() -> Self {
671 Self::new()
672 }
673}
674
675pub struct Interpreter {
677 pub globals: Rc<RefCell<Environment>>,
679 pub environment: Rc<RefCell<Environment>>,
681 pub types: HashMap<String, TypeDef>,
683 pub variant_constructors: HashMap<String, (String, String, usize)>,
685 pub default_structs: HashMap<String, StructDef>,
687 pub output: Vec<String>,
689 return_value: Option<Value>,
691 pub program_args: Option<Vec<String>>,
693 pub current_module: Option<String>,
695 pub current_self_type: Option<String>,
697 pub current_source_dir: Option<String>,
699 pub loaded_crates: HashSet<String>,
701 pub loading_crates: HashSet<String>,
703 pub project_root: Option<PathBuf>,
705 pub workspace_members: HashMap<String, PathBuf>,
707 pub drop_types: HashSet<String>,
709 pub trait_defs: HashMap<String, TraitInfo>,
711 pub trait_impls: HashMap<(String, String), bool>,
713}
714
715#[derive(Clone, Debug)]
717pub struct TraitInfo {
718 pub name: String,
720 pub methods: Vec<String>,
722 pub supertraits: Vec<String>,
724}
725
726#[derive(Clone)]
728pub enum TypeDef {
729 Struct(StructDef),
730 Enum(EnumDef),
731}
732
733impl Interpreter {
734 pub fn new() -> Self {
735 let globals = Rc::new(RefCell::new(Environment::new()));
736 let environment = globals.clone();
737
738 let mut interp = Self {
739 globals: globals.clone(),
740 environment,
741 types: HashMap::new(),
742 variant_constructors: HashMap::new(),
743 default_structs: HashMap::new(),
744 return_value: None,
745 output: Vec::new(),
746 program_args: None,
747 current_module: None,
748 current_self_type: None,
749 current_source_dir: None,
750 loaded_crates: HashSet::new(),
751 loading_crates: HashSet::new(),
752 project_root: None,
753 workspace_members: HashMap::new(),
754 drop_types: HashSet::new(),
755 trait_defs: HashMap::new(),
756 trait_impls: HashMap::new(),
757 };
758
759 interp.register_builtins();
761
762 interp
763 }
764
765 pub fn set_program_args(&mut self, args: Vec<String>) {
767 self.program_args = Some(args);
768 }
769
770 pub fn set_current_module(&mut self, module: Option<String>) {
772 self.current_module = module;
773 }
774
775 pub fn set_current_source_dir(&mut self, dir: Option<String>) {
777 self.current_source_dir = dir;
778 }
779
780 pub fn get_program_args(&self) -> Vec<String> {
782 self.program_args.clone().unwrap_or_else(|| std::env::args().collect())
783 }
784
785 pub fn discover_project(&mut self, source_dir: &str) -> Result<(), RuntimeError> {
788 let mut current = PathBuf::from(source_dir);
789
790 loop {
792 let sigil_toml = current.join("Sigil.toml");
793 if sigil_toml.exists() {
794 if let Ok(result) = self.try_parse_workspace_toml(&sigil_toml) {
795 if result {
796 return Ok(());
797 }
798 }
800 }
801
802 let sigil_toml_lower = current.join("sigil.toml");
804 if sigil_toml_lower.exists() {
805 if let Ok(result) = self.try_parse_workspace_toml(&sigil_toml_lower) {
806 if result {
807 return Ok(());
808 }
809 }
811 }
812
813 if !current.pop() {
814 crate::sigil_debug!("DEBUG discover_project: no workspace Sigil.toml found from {}", source_dir);
816 return Ok(());
817 }
818 }
819 }
820
821 fn try_parse_workspace_toml(&mut self, path: &PathBuf) -> Result<bool, RuntimeError> {
824 let content = std::fs::read_to_string(path)
825 .map_err(|e| RuntimeError::new(format!("Failed to read Sigil.toml: {}", e)))?;
826
827 let toml_value: toml::Value = content.parse()
828 .map_err(|e| RuntimeError::new(format!("Failed to parse Sigil.toml: {}", e)))?;
829
830 if let Some(workspace) = toml_value.get("workspace") {
832 if workspace.get("members").and_then(|m| m.as_array()).is_some() {
833 return self.parse_sigil_toml(path).map(|_| true);
835 }
836 }
837
838 crate::sigil_debug!("DEBUG try_parse_workspace_toml: {:?} is not a workspace config", path);
840 Ok(false)
841 }
842
843 fn parse_sigil_toml(&mut self, path: &PathBuf) -> Result<(), RuntimeError> {
845 let content = std::fs::read_to_string(path)
846 .map_err(|e| RuntimeError::new(format!("Failed to read Sigil.toml: {}", e)))?;
847
848 let toml_value: toml::Value = content.parse()
849 .map_err(|e| RuntimeError::new(format!("Failed to parse Sigil.toml: {}", e)))?;
850
851 self.project_root = path.parent().map(|p| p.to_path_buf());
852
853 if let Some(workspace) = toml_value.get("workspace") {
855 if let Some(members) = workspace.get("members").and_then(|m| m.as_array()) {
856 for member in members {
857 if let Some(member_path) = member.as_str() {
858 let crate_name = std::path::Path::new(member_path)
860 .file_name()
861 .and_then(|n| n.to_str())
862 .map(|n| n.replace("-", "_"))
863 .unwrap_or_default();
864
865 if !crate_name.is_empty() {
866 crate::sigil_debug!("DEBUG parse_sigil_toml: registered workspace member: {} -> {}",
867 &crate_name, member_path);
868 self.workspace_members.insert(crate_name, PathBuf::from(member_path));
869 }
870 }
871 }
872 }
873 }
874
875 crate::sigil_debug!("DEBUG parse_sigil_toml: loaded {} workspace members from {:?}",
876 self.workspace_members.len(), path);
877
878 Ok(())
879 }
880
881 pub fn load_crate(&mut self, crate_name: &str) -> Result<bool, RuntimeError> {
883 if self.loaded_crates.contains(crate_name) {
885 return Ok(true);
886 }
887
888 if self.loading_crates.contains(crate_name) {
890 return Err(RuntimeError::new(format!(
891 "Circular dependency detected: crate '{}' is already being loaded", crate_name
892 )));
893 }
894
895 let crate_path = match self.workspace_members.get(crate_name) {
897 Some(p) => p.clone(),
898 None => {
899 crate::sigil_debug!("DEBUG load_crate: crate '{}' not found in workspace members", crate_name);
900 return Ok(false);
901 }
902 };
903
904 let project_root = match &self.project_root {
905 Some(r) => r.clone(),
906 None => {
907 crate::sigil_debug!("DEBUG load_crate: no project root set");
908 return Ok(false);
909 }
910 };
911
912 let lib_path = project_root.join(&crate_path).join("src").join("lib.sigil");
914
915 if !lib_path.exists() {
916 crate::sigil_debug!("DEBUG load_crate: lib.sigil not found at {:?}", lib_path);
917 return Ok(false);
918 }
919
920 self.loading_crates.insert(crate_name.to_string());
922
923 crate::sigil_debug!("DEBUG load_crate: loading crate '{}' from {:?}", crate_name, lib_path);
924
925 let source = std::fs::read_to_string(&lib_path)
927 .map_err(|e| RuntimeError::new(format!("Failed to read {:?}: {}", lib_path, e)))?;
928
929 let prev_module = self.current_module.clone();
931 let prev_source_dir = self.current_source_dir.clone();
932
933 self.current_module = Some(crate_name.to_string());
935 self.current_source_dir = lib_path.parent().map(|p| p.to_string_lossy().to_string());
936
937 let mut parser = crate::Parser::new(&source);
939
940 match parser.parse_file() {
941 Ok(parsed_file) => {
942 for item in &parsed_file.items {
944 if let Err(e) = self.execute_item(&item.node) {
945 crate::sigil_warn!("Warning: error loading crate '{}': {}", crate_name, e);
946 }
947 }
948 }
949 Err(e) => {
950 crate::sigil_warn!("Warning: failed to parse crate '{}': {:?}", crate_name, e);
951 }
952 }
953
954 self.current_module = prev_module;
956 self.current_source_dir = prev_source_dir;
957
958 self.loading_crates.remove(crate_name);
960 self.loaded_crates.insert(crate_name.to_string());
961
962 crate::sigil_debug!("DEBUG load_crate: successfully loaded crate '{}'", crate_name);
963
964 Ok(true)
965 }
966
967 fn register_builtins(&mut self) {
968 self.globals.borrow_mut().define("PhantomData".to_string(), Value::Null);
970
971 self.define_builtin("print", None, |interp, args| {
973 let output: Vec<String> = args.iter().map(|v| format!("{}", v)).collect();
974 let line = output.join(" ");
975 println!("{}", line);
976 interp.output.push(line);
977 Ok(Value::Null)
978 });
979
980 self.define_builtin("type_of", Some(1), |_, args| {
982 let type_name = match &args[0] {
983 Value::Null => "null",
984 Value::Bool(_) => "bool",
985 Value::Int(_) => "i64",
986 Value::Float(_) => "f64",
987 Value::String(_) => "str",
988 Value::Char(_) => "char",
989 Value::Array(_) => "array",
990 Value::Tuple(_) => "tuple",
991 Value::Struct { name, .. } => name,
992 Value::Variant { enum_name, .. } => enum_name,
993 Value::Function(_) => "fn",
994 Value::BuiltIn(_) => "builtin",
995 Value::Ref(_) => "ref",
996 Value::Infinity => "infinity",
997 Value::Empty => "empty",
998 Value::Evidential { .. } => "evidential",
999 Value::Affective { .. } => "affective",
1000 Value::Map(_) => "map",
1001 Value::Set(_) => "set",
1002 Value::Channel(_) => "channel",
1003 Value::ThreadHandle(_) => "thread",
1004 Value::Actor(_) => "actor",
1005 Value::Future(_) => "future",
1006 Value::VariantConstructor { .. } => "variant_constructor",
1007 Value::DefaultConstructor { .. } => "default_constructor",
1008 Value::Range { .. } => "range",
1009 Value::RefCellValue(_) => "refcell",
1010 Value::TraitObject { trait_name, .. } => {
1011 return Ok(Value::String(Rc::new(format!("dyn {}", trait_name))));
1012 }
1013 };
1014 Ok(Value::String(Rc::new(type_name.to_string())))
1015 });
1016
1017 self.define_builtin("len", Some(1), |_, args| match &args[0] {
1019 Value::Array(arr) => Ok(Value::Int(arr.borrow().len() as i64)),
1020 Value::String(s) => Ok(Value::Int(s.len() as i64)),
1021 Value::Tuple(t) => Ok(Value::Int(t.len() as i64)),
1022 _ => Err(RuntimeError::new("len() requires array, string, or tuple")),
1023 });
1024
1025 self.define_builtin("push", Some(2), |_, args| match &args[0] {
1026 Value::Array(arr) => {
1027 arr.borrow_mut().push(args[1].clone());
1028 Ok(Value::Null)
1029 }
1030 _ => Err(RuntimeError::new("push() requires array")),
1031 });
1032
1033 self.define_builtin("pop", Some(1), |_, args| match &args[0] {
1034 Value::Array(arr) => arr
1035 .borrow_mut()
1036 .pop()
1037 .ok_or_else(|| RuntimeError::new("pop() on empty array")),
1038 _ => Err(RuntimeError::new("pop() requires array")),
1039 });
1040
1041 self.define_builtin("abs", Some(1), |_, args| match &args[0] {
1043 Value::Int(n) => Ok(Value::Int(n.abs())),
1044 Value::Float(n) => Ok(Value::Float(n.abs())),
1045 _ => Err(RuntimeError::new("abs() requires number")),
1046 });
1047
1048 self.define_builtin("sqrt", Some(1), |_, args| match &args[0] {
1049 Value::Int(n) => Ok(Value::Float((*n as f64).sqrt())),
1050 Value::Float(n) => Ok(Value::Float(n.sqrt())),
1051 _ => Err(RuntimeError::new("sqrt() requires number")),
1052 });
1053
1054 self.define_builtin("sin", Some(1), |_, args| match &args[0] {
1055 Value::Int(n) => Ok(Value::Float((*n as f64).sin())),
1056 Value::Float(n) => Ok(Value::Float(n.sin())),
1057 _ => Err(RuntimeError::new("sin() requires number")),
1058 });
1059
1060 self.define_builtin("cos", Some(1), |_, args| match &args[0] {
1061 Value::Int(n) => Ok(Value::Float((*n as f64).cos())),
1062 Value::Float(n) => Ok(Value::Float(n.cos())),
1063 _ => Err(RuntimeError::new("cos() requires number")),
1064 });
1065
1066 self.define_builtin("known", Some(1), |_, args| {
1068 Ok(Value::Evidential {
1069 value: Box::new(args[0].clone()),
1070 evidence: Evidence::Known,
1071 })
1072 });
1073
1074 self.define_builtin("uncertain", Some(1), |_, args| {
1075 Ok(Value::Evidential {
1076 value: Box::new(args[0].clone()),
1077 evidence: Evidence::Uncertain,
1078 })
1079 });
1080
1081 self.define_builtin("reported", Some(1), |_, args| {
1082 Ok(Value::Evidential {
1083 value: Box::new(args[0].clone()),
1084 evidence: Evidence::Reported,
1085 })
1086 });
1087
1088 self.globals.borrow_mut().define(
1090 "Box·new".to_string(),
1091 Value::BuiltIn(Rc::new(BuiltInFn {
1092 name: "Box·new".to_string(),
1093 arity: Some(1),
1094 func: |_, args| Ok(args[0].clone()),
1095 })),
1096 );
1097
1098 self.globals.borrow_mut().define(
1100 "Map·new".to_string(),
1101 Value::BuiltIn(Rc::new(BuiltInFn {
1102 name: "Map·new".to_string(),
1103 arity: Some(0),
1104 func: |_, _| Ok(Value::Map(Rc::new(RefCell::new(HashMap::new())))),
1105 })),
1106 );
1107
1108 self.define_builtin("range", Some(2), |_, args| {
1110 let start = match &args[0] {
1111 Value::Int(n) => *n,
1112 _ => return Err(RuntimeError::new("range() requires integers")),
1113 };
1114 let end = match &args[1] {
1115 Value::Int(n) => *n,
1116 _ => return Err(RuntimeError::new("range() requires integers")),
1117 };
1118 let values: Vec<Value> = (start..end).map(Value::Int).collect();
1119 Ok(Value::Array(Rc::new(RefCell::new(values))))
1120 });
1121
1122 self.globals.borrow_mut().define(
1124 "ExitCode·SUCCESS".to_string(),
1125 Value::Variant {
1126 enum_name: "ExitCode".to_string(),
1127 variant_name: "SUCCESS".to_string(),
1128 fields: Some(Rc::new(vec![Value::Int(0)])),
1129 },
1130 );
1131 self.globals.borrow_mut().define(
1132 "ExitCode·FAILURE".to_string(),
1133 Value::Variant {
1134 enum_name: "ExitCode".to_string(),
1135 variant_name: "FAILURE".to_string(),
1136 fields: Some(Rc::new(vec![Value::Int(1)])),
1137 },
1138 );
1139
1140 self.define_builtin("PathBuf·from", Some(1), |_, args| {
1142 let arg = match &args[0] {
1144 Value::Ref(r) => r.borrow().clone(),
1145 other => other.clone(),
1146 };
1147 let path = match &arg {
1148 Value::String(s2) => s2.as_str().to_string(),
1149 _ => return Err(RuntimeError::new("PathBuf::from expects a string")),
1150 };
1151 let mut fields = HashMap::new();
1153 fields.insert("path".to_string(), Value::String(Rc::new(path)));
1154 Ok(Value::Struct {
1155 name: "PathBuf".to_string(),
1156 fields: Rc::new(RefCell::new(fields)),
1157 })
1158 });
1159
1160 self.define_builtin("Path·new", Some(1), |_, args| {
1162 let arg = match &args[0] {
1164 Value::Ref(r) => r.borrow().clone(),
1165 other => other.clone(),
1166 };
1167 let path = match &arg {
1168 Value::String(s2) => s2.as_str().to_string(),
1169 _ => return Err(RuntimeError::new("Path::new expects a string")),
1170 };
1171 let mut fields = HashMap::new();
1172 fields.insert("path".to_string(), Value::String(Rc::new(path)));
1173 Ok(Value::Struct {
1174 name: "Path".to_string(),
1175 fields: Rc::new(RefCell::new(fields)),
1176 })
1177 });
1178
1179 self.define_builtin("std·fs·read_to_string", Some(1), |interp, args| {
1181 fn unwrap_refs(v: &Value) -> Value {
1183 match v {
1184 Value::Ref(r) => unwrap_refs(&r.borrow()),
1185 other => other.clone(),
1186 }
1187 }
1188 let arg = unwrap_refs(&args[0]);
1189 crate::sigil_debug!("DEBUG read_to_string: arg = {:?}", arg);
1190 crate::sigil_debug!("DEBUG read_to_string: env has path = {:?}", interp.environment.borrow().get("path"));
1192 let path = match &arg {
1193 Value::String(s) => s.to_string(),
1194 Value::Struct { name, fields, .. } => {
1196 crate::sigil_debug!("DEBUG read_to_string: struct name = {}", name);
1197 fields.borrow().get("path")
1198 .and_then(|v| if let Value::String(s) = v { Some(s.to_string()) } else { None })
1199 .ok_or_else(|| RuntimeError::new("Expected path field in struct"))?
1200 }
1201 Value::Variant { enum_name, variant_name, fields } if enum_name == "Option" && variant_name == "Some" => {
1203 if let Some(fields) = fields {
1204 if let Some(Value::String(s)) = fields.first() {
1205 s.to_string()
1206 } else {
1207 return Err(RuntimeError::new("read_to_string: Option::Some does not contain a string"));
1208 }
1209 } else {
1210 return Err(RuntimeError::new("read_to_string: Option::Some has no fields"));
1211 }
1212 }
1213 _ => return Err(RuntimeError::new(&format!("read_to_string expects a path string or PathBuf, got {:?}", arg))),
1214 };
1215 match std::fs::read_to_string(&path) {
1216 Ok(content) => Ok(Value::Variant {
1217 enum_name: "Result".to_string(),
1218 variant_name: "Ok".to_string(),
1219 fields: Some(Rc::new(vec![Value::String(Rc::new(content))])),
1220 }),
1221 Err(e) => Ok(Value::Variant {
1222 enum_name: "Result".to_string(),
1223 variant_name: "Err".to_string(),
1224 fields: Some(Rc::new(vec![Value::String(Rc::new(e.to_string()))])),
1225 }),
1226 }
1227 });
1228
1229 self.define_builtin("fs·read_to_string", Some(1), |_, args| {
1231 let arg = match &args[0] {
1232 Value::Ref(r) => r.borrow().clone(),
1233 other => other.clone(),
1234 };
1235 let path = match &arg {
1236 Value::String(s) => s.to_string(),
1237 Value::Struct { fields, .. } => {
1238 fields.borrow().get("path")
1239 .and_then(|v| if let Value::String(s) = v { Some(s.to_string()) } else { None })
1240 .ok_or_else(|| RuntimeError::new("Expected path field in struct"))?
1241 }
1242 _ => return Err(RuntimeError::new("read_to_string expects a path string or PathBuf")),
1243 };
1244 match std::fs::read_to_string(&path) {
1245 Ok(content) => Ok(Value::Variant {
1246 enum_name: "Result".to_string(),
1247 variant_name: "Ok".to_string(),
1248 fields: Some(Rc::new(vec![Value::String(Rc::new(content))])),
1249 }),
1250 Err(e) => Ok(Value::Variant {
1251 enum_name: "Result".to_string(),
1252 variant_name: "Err".to_string(),
1253 fields: Some(Rc::new(vec![Value::String(Rc::new(e.to_string()))])),
1254 }),
1255 }
1256 });
1257
1258 self.define_builtin("std·fs·read_dir", Some(1), |_, args| {
1260 fn unwrap_refs(v: &Value) -> Value {
1261 match v {
1262 Value::Ref(r) => unwrap_refs(&r.borrow()),
1263 other => other.clone(),
1264 }
1265 }
1266 let arg = unwrap_refs(&args[0]);
1267 let path = match &arg {
1268 Value::String(s) => s.to_string(),
1269 Value::Struct { name, fields, .. } if name == "Path" || name == "PathBuf" => {
1270 fields.borrow().get("path")
1271 .and_then(|v| if let Value::String(s) = v { Some(s.to_string()) } else { None })
1272 .ok_or_else(|| RuntimeError::new("Expected path field in struct"))?
1273 }
1274 _ => return Err(RuntimeError::new(&format!("read_dir expects a path, got {:?}", arg))),
1275 };
1276 match std::fs::read_dir(&path) {
1277 Ok(entries) => {
1278 let entry_values: Vec<Value> = entries
1280 .filter_map(|e| e.ok())
1281 .map(|e| {
1282 let entry_path = e.path().to_string_lossy().to_string();
1283 let mut fields = HashMap::new();
1284 fields.insert("path".to_string(), Value::String(Rc::new(entry_path)));
1285 Value::Variant {
1287 enum_name: "Result".to_string(),
1288 variant_name: "Ok".to_string(),
1289 fields: Some(Rc::new(vec![Value::Struct {
1290 name: "DirEntry".to_string(),
1291 fields: Rc::new(RefCell::new(fields)),
1292 }])),
1293 }
1294 })
1295 .collect();
1296 Ok(Value::Variant {
1298 enum_name: "Result".to_string(),
1299 variant_name: "Ok".to_string(),
1300 fields: Some(Rc::new(vec![Value::Array(Rc::new(RefCell::new(entry_values)))])),
1301 })
1302 }
1303 Err(e) => Ok(Value::Variant {
1304 enum_name: "Result".to_string(),
1305 variant_name: "Err".to_string(),
1306 fields: Some(Rc::new(vec![Value::String(Rc::new(e.to_string()))])),
1307 }),
1308 }
1309 });
1310
1311 self.define_builtin("fs·read_dir", Some(1), |_, args| {
1313 fn unwrap_refs(v: &Value) -> Value {
1314 match v {
1315 Value::Ref(r) => unwrap_refs(&r.borrow()),
1316 other => other.clone(),
1317 }
1318 }
1319 let arg = unwrap_refs(&args[0]);
1320 let path = match &arg {
1321 Value::String(s) => s.to_string(),
1322 Value::Struct { name, fields, .. } if name == "Path" || name == "PathBuf" => {
1323 fields.borrow().get("path")
1324 .and_then(|v| if let Value::String(s) = v { Some(s.to_string()) } else { None })
1325 .ok_or_else(|| RuntimeError::new("Expected path field in struct"))?
1326 }
1327 _ => return Err(RuntimeError::new(&format!("read_dir expects a path, got {:?}", arg))),
1328 };
1329 match std::fs::read_dir(&path) {
1330 Ok(entries) => {
1331 let entry_values: Vec<Value> = entries
1332 .filter_map(|e| e.ok())
1333 .map(|e| {
1334 let entry_path = e.path().to_string_lossy().to_string();
1335 let mut fields = HashMap::new();
1336 fields.insert("path".to_string(), Value::String(Rc::new(entry_path)));
1337 Value::Variant {
1338 enum_name: "Result".to_string(),
1339 variant_name: "Ok".to_string(),
1340 fields: Some(Rc::new(vec![Value::Struct {
1341 name: "DirEntry".to_string(),
1342 fields: Rc::new(RefCell::new(fields)),
1343 }])),
1344 }
1345 })
1346 .collect();
1347 Ok(Value::Variant {
1348 enum_name: "Result".to_string(),
1349 variant_name: "Ok".to_string(),
1350 fields: Some(Rc::new(vec![Value::Array(Rc::new(RefCell::new(entry_values)))])),
1351 })
1352 }
1353 Err(e) => Ok(Value::Variant {
1354 enum_name: "Result".to_string(),
1355 variant_name: "Err".to_string(),
1356 fields: Some(Rc::new(vec![Value::String(Rc::new(e.to_string()))])),
1357 }),
1358 }
1359 });
1360
1361 self.define_builtin("std·env·var", Some(1), |_, args| {
1363 fn unwrap_refs(v: &Value) -> Value {
1364 match v {
1365 Value::Ref(r) => unwrap_refs(&r.borrow()),
1366 other => other.clone(),
1367 }
1368 }
1369 let arg = unwrap_refs(&args[0]);
1370 let var_name = match &arg {
1371 Value::String(s) => s.to_string(),
1372 _ => return Err(RuntimeError::new("env::var expects a string")),
1373 };
1374 match std::env::var(&var_name) {
1375 Ok(value) => Ok(Value::Variant {
1376 enum_name: "Result".to_string(),
1377 variant_name: "Ok".to_string(),
1378 fields: Some(Rc::new(vec![Value::String(Rc::new(value))])),
1379 }),
1380 Err(_) => Ok(Value::Variant {
1381 enum_name: "Result".to_string(),
1382 variant_name: "Err".to_string(),
1383 fields: Some(Rc::new(vec![Value::String(Rc::new("Environment variable not found".to_string()))])),
1384 }),
1385 }
1386 });
1387
1388 self.define_builtin("env·var", Some(1), |_, args| {
1390 fn unwrap_refs(v: &Value) -> Value {
1391 match v {
1392 Value::Ref(r) => unwrap_refs(&r.borrow()),
1393 other => other.clone(),
1394 }
1395 }
1396 let arg = unwrap_refs(&args[0]);
1397 let var_name = match &arg {
1398 Value::String(s) => s.to_string(),
1399 _ => return Err(RuntimeError::new("env::var expects a string")),
1400 };
1401 match std::env::var(&var_name) {
1402 Ok(value) => Ok(Value::Variant {
1403 enum_name: "Result".to_string(),
1404 variant_name: "Ok".to_string(),
1405 fields: Some(Rc::new(vec![Value::String(Rc::new(value))])),
1406 }),
1407 Err(_) => Ok(Value::Variant {
1408 enum_name: "Result".to_string(),
1409 variant_name: "Err".to_string(),
1410 fields: Some(Rc::new(vec![Value::String(Rc::new("Environment variable not found".to_string()))])),
1411 }),
1412 }
1413 });
1414
1415 self.define_builtin("std·env·args", Some(0), |interp, _| {
1418 let args = interp.get_program_args();
1419 let arg_values: Vec<Value> = args.iter()
1420 .map(|s| Value::String(Rc::new(s.clone())))
1421 .collect();
1422 Ok(Value::Array(Rc::new(RefCell::new(arg_values))))
1423 });
1424
1425 self.define_builtin("env·args", Some(0), |interp, _| {
1427 let args = interp.get_program_args();
1428 let arg_values: Vec<Value> = args.iter()
1429 .map(|s| Value::String(Rc::new(s.clone())))
1430 .collect();
1431 Ok(Value::Array(Rc::new(RefCell::new(arg_values))))
1432 });
1433
1434 self.define_builtin("fs_read", Some(1), |_, args| {
1440 let path = match &args[0] {
1441 Value::String(s) => s.to_string(),
1442 _ => return Err(RuntimeError::new("fs_read requires a string path")),
1443 };
1444 match std::fs::read_to_string(&path) {
1445 Ok(content) => Ok(Value::String(Rc::new(content))),
1446 Err(e) => {
1447 crate::sigil_debug!("DEBUG fs_read error for '{}': {}", path, e);
1448 Ok(Value::Null)
1449 }
1450 }
1451 });
1452
1453 self.define_builtin("fs_list", Some(1), |_, args| {
1455 let path = match &args[0] {
1456 Value::String(s) => s.to_string(),
1457 _ => return Err(RuntimeError::new("fs_list requires a string path")),
1458 };
1459 match std::fs::read_dir(&path) {
1460 Ok(entries) => {
1461 let files: Vec<Value> = entries
1462 .filter_map(|e| e.ok())
1463 .map(|e| Value::String(Rc::new(e.file_name().to_string_lossy().to_string())))
1464 .collect();
1465 Ok(Value::Array(Rc::new(RefCell::new(files))))
1466 }
1467 Err(e) => {
1468 crate::sigil_debug!("DEBUG fs_list error for '{}': {}", path, e);
1469 Ok(Value::Array(Rc::new(RefCell::new(Vec::new()))))
1470 }
1471 }
1472 });
1473
1474 self.define_builtin("fs_is_dir", Some(1), |_, args| {
1476 let path = match &args[0] {
1477 Value::String(s) => s.to_string(),
1478 _ => return Err(RuntimeError::new("fs_is_dir requires a string path")),
1479 };
1480 Ok(Value::Bool(std::path::Path::new(&path).is_dir()))
1481 });
1482
1483 self.define_builtin("fs_is_file", Some(1), |_, args| {
1485 let path = match &args[0] {
1486 Value::String(s) => s.to_string(),
1487 _ => return Err(RuntimeError::new("fs_is_file requires a string path")),
1488 };
1489 Ok(Value::Bool(std::path::Path::new(&path).is_file()))
1490 });
1491
1492 self.define_builtin("fs_exists", Some(1), |_, args| {
1494 let path = match &args[0] {
1495 Value::String(s) => s.to_string(),
1496 _ => return Err(RuntimeError::new("fs_exists requires a string path")),
1497 };
1498 Ok(Value::Bool(std::path::Path::new(&path).exists()))
1499 });
1500
1501 self.define_builtin("path_extension", Some(1), |_, args| {
1503 let path = match &args[0] {
1504 Value::String(s) => s.to_string(),
1505 _ => return Err(RuntimeError::new("path_extension requires a string path")),
1506 };
1507 let ext = std::path::Path::new(&path)
1508 .extension()
1509 .and_then(|e| e.to_str())
1510 .map(|s| s.to_string());
1511 match ext {
1512 Some(e) => Ok(Value::String(Rc::new(e))),
1513 None => Ok(Value::Null),
1514 }
1515 });
1516
1517 self.define_builtin("path_join", Some(2), |_, args| {
1519 let base = match &args[0] {
1520 Value::String(s) => s.to_string(),
1521 _ => return Err(RuntimeError::new("path_join requires string paths")),
1522 };
1523 let part = match &args[1] {
1524 Value::String(s) => s.to_string(),
1525 _ => return Err(RuntimeError::new("path_join requires string paths")),
1526 };
1527 let joined = std::path::Path::new(&base).join(&part);
1528 Ok(Value::String(Rc::new(joined.to_string_lossy().to_string())))
1529 });
1530
1531 self.define_builtin("path_parent", Some(1), |_, args| {
1533 let path = match &args[0] {
1534 Value::String(s) => s.to_string(),
1535 _ => return Err(RuntimeError::new("path_parent requires a string path")),
1536 };
1537 match std::path::Path::new(&path).parent() {
1538 Some(p) => Ok(Value::String(Rc::new(p.to_string_lossy().to_string()))),
1539 None => Ok(Value::Null),
1540 }
1541 });
1542
1543 self.define_builtin("path_file_name", Some(1), |_, args| {
1545 let path = match &args[0] {
1546 Value::String(s) => s.to_string(),
1547 _ => return Err(RuntimeError::new("path_file_name requires a string path")),
1548 };
1549 match std::path::Path::new(&path).file_name() {
1550 Some(n) => Ok(Value::String(Rc::new(n.to_string_lossy().to_string()))),
1551 None => Ok(Value::Null),
1552 }
1553 });
1554
1555 self.define_builtin("TreeSitterParser·new", Some(1), |_, args| {
1561 use crate::tree_sitter_support::{TSLanguage, TSParser};
1562
1563 let lang_str = match &args[0] {
1565 Value::String(s) => s.to_string(),
1566 Value::Variant { enum_name, variant_name, .. } => {
1567 format!("{}::{}", enum_name, variant_name)
1569 }
1570 other => format!("{:?}", other),
1571 };
1572
1573 let language = match TSLanguage::from_str(&lang_str) {
1575 Some(lang) => lang,
1576 None => {
1577 return Ok(Value::Variant {
1578 enum_name: "Result".to_string(),
1579 variant_name: "Err".to_string(),
1580 fields: Some(Rc::new(vec![Value::Struct {
1581 name: "ParseError".to_string(),
1582 fields: Rc::new(RefCell::new({
1583 let mut f = HashMap::new();
1584 f.insert("kind".to_string(), Value::String(Rc::new("ParserNotFound".to_string())));
1585 f.insert("message".to_string(), Value::String(Rc::new(format!("Unsupported language: {}", lang_str))));
1586 f
1587 })),
1588 }])),
1589 });
1590 }
1591 };
1592
1593 match TSParser::new(language) {
1595 Ok(_) => {
1596 let mut fields = HashMap::new();
1598 fields.insert("language".to_string(), Value::String(Rc::new(lang_str)));
1599 fields.insert("_ts_language".to_string(), Value::String(Rc::new(format!("{:?}", language))));
1600
1601 Ok(Value::Variant {
1602 enum_name: "Result".to_string(),
1603 variant_name: "Ok".to_string(),
1604 fields: Some(Rc::new(vec![Value::Struct {
1605 name: "TreeSitterParser".to_string(),
1606 fields: Rc::new(RefCell::new(fields)),
1607 }])),
1608 })
1609 }
1610 Err(e) => {
1611 Ok(Value::Variant {
1612 enum_name: "Result".to_string(),
1613 variant_name: "Err".to_string(),
1614 fields: Some(Rc::new(vec![Value::Struct {
1615 name: "ParseError".to_string(),
1616 fields: Rc::new(RefCell::new({
1617 let mut f = HashMap::new();
1618 f.insert("kind".to_string(), Value::String(Rc::new("ParserNotFound".to_string())));
1619 f.insert("message".to_string(), Value::String(Rc::new(e)));
1620 f
1621 })),
1622 }])),
1623 })
1624 }
1625 }
1626 });
1627
1628 self.define_builtin("tree_sitter_parse", Some(2), |_, args| {
1630 use crate::tree_sitter_support::{parse_source, node_to_value};
1631
1632 let lang_str = match &args[0] {
1634 Value::String(s) => s.to_string(),
1635 Value::Variant { enum_name, variant_name, .. } => {
1636 format!("{}::{}", enum_name, variant_name)
1637 }
1638 other => format!("{:?}", other),
1639 };
1640
1641 let source = match &args[1] {
1642 Value::String(s) => s.to_string(),
1643 _ => return Err(RuntimeError::new("tree_sitter_parse expects source code string as second argument")),
1644 };
1645
1646 match parse_source(&lang_str, &source) {
1648 Ok(tree) => {
1649 let root = tree.root_node();
1651 let root_fields = node_to_value(&root);
1652
1653 let mut tree_fields = HashMap::new();
1655 tree_fields.insert("root".to_string(), Value::Struct {
1656 name: "SyntaxNode".to_string(),
1657 fields: Rc::new(RefCell::new(root_fields)),
1658 });
1659 tree_fields.insert("source".to_string(), Value::String(Rc::new(source)));
1660
1661 Ok(Value::Variant {
1662 enum_name: "Result".to_string(),
1663 variant_name: "Ok".to_string(),
1664 fields: Some(Rc::new(vec![Value::Struct {
1665 name: "TSTree".to_string(),
1666 fields: Rc::new(RefCell::new(tree_fields)),
1667 }])),
1668 })
1669 }
1670 Err(e) => {
1671 Ok(Value::Variant {
1672 enum_name: "Result".to_string(),
1673 variant_name: "Err".to_string(),
1674 fields: Some(Rc::new(vec![Value::Struct {
1675 name: "ParseError".to_string(),
1676 fields: Rc::new(RefCell::new({
1677 let mut f = HashMap::new();
1678 f.insert("kind".to_string(), Value::String(Rc::new("SyntaxError".to_string())));
1679 f.insert("message".to_string(), Value::String(Rc::new(e)));
1680 f
1681 })),
1682 }])),
1683 })
1684 }
1685 }
1686 });
1687
1688 self.define_builtin("tree_sitter_supported_languages", Some(0), |_, _| {
1690 use crate::tree_sitter_support::supported_languages;
1691
1692 let languages: Vec<Value> = supported_languages()
1693 .iter()
1694 .map(|s| Value::String(Rc::new(s.to_string())))
1695 .collect();
1696
1697 Ok(Value::Array(Rc::new(RefCell::new(languages))))
1698 });
1699
1700 self.define_builtin("tree_sitter_node_text", Some(2), |_, args| {
1702 let (start_byte, end_byte) = match &args[0] {
1704 Value::Struct { fields, .. } => {
1705 let fields = fields.borrow();
1706 let start = match fields.get("start_byte") {
1707 Some(Value::Int(n)) => *n as usize,
1708 _ => return Err(RuntimeError::new("Node missing start_byte field")),
1709 };
1710 let end = match fields.get("end_byte") {
1711 Some(Value::Int(n)) => *n as usize,
1712 _ => return Err(RuntimeError::new("Node missing end_byte field")),
1713 };
1714 (start, end)
1715 }
1716 _ => return Err(RuntimeError::new("tree_sitter_node_text expects a SyntaxNode struct")),
1717 };
1718
1719 let source = match &args[1] {
1720 Value::String(s) => s.to_string(),
1721 _ => return Err(RuntimeError::new("tree_sitter_node_text expects source string as second argument")),
1722 };
1723
1724 if end_byte <= source.len() && start_byte <= end_byte {
1725 Ok(Value::String(Rc::new(source[start_byte..end_byte].to_string())))
1726 } else {
1727 Err(RuntimeError::new("Byte range out of bounds"))
1728 }
1729 });
1730
1731 let rc_new = Value::BuiltIn(Rc::new(BuiltInFn {
1733 name: "Rc·new".to_string(),
1734 arity: Some(1),
1735 func: |_, args| {
1736 let mut fields = HashMap::new();
1737 fields.insert("_value".to_string(), args[0].clone());
1738 Ok(Value::Struct {
1739 name: "Rc".to_string(),
1740 fields: std::rc::Rc::new(RefCell::new(fields)),
1741 })
1742 },
1743 }));
1744 self.globals.borrow_mut().define("Rc·new".to_string(), rc_new);
1745
1746 let cell_new = Value::BuiltIn(Rc::new(BuiltInFn {
1748 name: "Cell·new".to_string(),
1749 arity: Some(1),
1750 func: |_, args| {
1751 let mut fields = HashMap::new();
1752 fields.insert("_value".to_string(), args[0].clone());
1753 Ok(Value::Struct {
1754 name: "Cell".to_string(),
1755 fields: std::rc::Rc::new(RefCell::new(fields)),
1756 })
1757 },
1758 }));
1759 self.globals.borrow_mut().define("Cell·new".to_string(), cell_new);
1760
1761 let refcell_new = Value::BuiltIn(Rc::new(BuiltInFn {
1763 name: "RefCell·new".to_string(),
1764 arity: Some(1),
1765 func: |_, args| {
1766 Ok(Value::RefCellValue(Rc::new(RefCellInner {
1767 value: RefCell::new(args[0].clone()),
1768 borrow_state: RefCell::new(BorrowState::Unborrowed),
1769 })))
1770 },
1771 }));
1772 self.globals.borrow_mut().define("RefCell·new".to_string(), refcell_new);
1773
1774 let as_dyn_fn = Value::BuiltIn(Rc::new(BuiltInFn {
1778 name: "as_dyn".to_string(),
1779 arity: Some(2),
1780 func: |interp, args| {
1781 let value = args[0].clone();
1782 let trait_name = match &args[1] {
1783 Value::String(s) => (**s).clone(),
1784 _ => return Err(RuntimeError::new("as_dyn: second argument must be trait name string")),
1785 };
1786
1787 let concrete_type = match &value {
1789 Value::Struct { name, .. } => name.clone(),
1790 _ => return Err(RuntimeError::new("as_dyn: first argument must be a struct")),
1791 };
1792
1793 if !interp.trait_impls.contains_key(&(concrete_type.clone(), trait_name.clone())) {
1795 return Err(RuntimeError::new(format!(
1796 "Type '{}' does not implement trait '{}'",
1797 concrete_type, trait_name
1798 )));
1799 }
1800
1801 Ok(Value::TraitObject {
1802 value: Box::new(value),
1803 concrete_type,
1804 trait_name,
1805 })
1806 },
1807 }));
1808 self.globals.borrow_mut().define("as_dyn".to_string(), as_dyn_fn);
1809 }
1810
1811 fn define_builtin(
1812 &mut self,
1813 name: &str,
1814 arity: Option<usize>,
1815 func: fn(&mut Interpreter, Vec<Value>) -> Result<Value, RuntimeError>,
1816 ) {
1817 let builtin = Value::BuiltIn(Rc::new(BuiltInFn {
1818 name: name.to_string(),
1819 arity,
1820 func,
1821 }));
1822 self.globals.borrow_mut().define(name.to_string(), builtin);
1823 }
1824
1825 pub fn execute(&mut self, file: &SourceFile) -> Result<Value, RuntimeError> {
1827 let mut result = Value::Null;
1828
1829 for item in &file.items {
1830 result = self.execute_item(&item.node)?;
1831 }
1832
1833 let main_fn = self.globals.borrow().get("main").and_then(|v| {
1835 if let Value::Function(f) = v {
1836 Some(f.clone())
1837 } else {
1838 None
1839 }
1840 });
1841 if let Some(f) = main_fn {
1842 if f.params.is_empty() {
1845 result = self.call_function(&f, vec![])?;
1846 }
1847 }
1848
1849 Ok(result)
1850 }
1851
1852 pub fn execute_definitions(&mut self, file: &SourceFile) -> Result<Value, RuntimeError> {
1855 let mut result = Value::Null;
1856
1857 for item in &file.items {
1858 result = self.execute_item(&item.node)?;
1859 }
1860
1861 Ok(result)
1862 }
1863
1864 fn execute_item(&mut self, item: &Item) -> Result<Value, RuntimeError> {
1865 match item {
1866 Item::Function(func) => {
1867 let fn_value = self.create_function(func)?;
1868 let fn_name = func.name.name.clone();
1869
1870 self.globals.borrow_mut().define(fn_name.clone(), fn_value.clone());
1872
1873 if let Some(ref module) = self.current_module {
1875 let qualified_name = format!("{}·{}", module, fn_name);
1876 self.globals.borrow_mut().define(qualified_name, fn_value);
1877 }
1878
1879 Ok(Value::Null)
1880 }
1881 Item::Struct(s) => {
1882 self.types
1884 .insert(s.name.name.clone(), TypeDef::Struct(s.clone()));
1885
1886 if let Some(ref module) = self.current_module {
1888 let qualified_name = format!("{}·{}", module, s.name.name);
1889 self.types.insert(qualified_name, TypeDef::Struct(s.clone()));
1890 }
1891
1892 if matches!(&s.fields, crate::ast::StructFields::Unit) {
1894 let unit_value = Value::Struct {
1895 name: s.name.name.clone(),
1896 fields: Rc::new(RefCell::new(HashMap::new())),
1897 };
1898 self.globals.borrow_mut().define(s.name.name.clone(), unit_value.clone());
1899
1900 if let Some(ref module) = self.current_module {
1902 let qualified_name = format!("{}·{}", module, s.name.name);
1903 self.globals.borrow_mut().define(qualified_name, unit_value);
1904 }
1905 }
1906
1907 let has_default = s.attrs.derives.iter().any(|d| matches!(d, DeriveTrait::Default));
1909 if has_default {
1910 self.default_structs.insert(s.name.name.clone(), s.clone());
1911 if let Some(ref module) = self.current_module {
1912 let qualified_name = format!("{}·{}", module, s.name.name);
1913 self.default_structs.insert(qualified_name, s.clone());
1914 }
1915 }
1916
1917 Ok(Value::Null)
1918 }
1919 Item::Enum(e) => {
1920 self.types
1922 .insert(e.name.name.clone(), TypeDef::Enum(e.clone()));
1923
1924 if let Some(ref module) = self.current_module {
1926 let qualified_name = format!("{}·{}", module, e.name.name);
1927 self.types.insert(qualified_name, TypeDef::Enum(e.clone()));
1928 }
1929
1930 let enum_name = e.name.name.clone();
1933 for variant in &e.variants {
1934 let variant_name = variant.name.name.clone();
1935 let qualified_name = format!("{}·{}", enum_name, variant_name);
1936
1937 let arity = match &variant.fields {
1938 crate::ast::StructFields::Unit => 0,
1939 crate::ast::StructFields::Tuple(types) => types.len(),
1940 crate::ast::StructFields::Named(fields) => fields.len(),
1941 };
1942
1943 self.variant_constructors.insert(qualified_name.clone(), (enum_name.clone(), variant_name.clone(), arity));
1945 }
1946 Ok(Value::Null)
1947 }
1948 Item::Const(c) => {
1949 let value = self.evaluate(&c.value)?;
1950 self.globals.borrow_mut().define(c.name.name.clone(), value);
1951 Ok(Value::Null)
1952 }
1953 Item::Static(s) => {
1954 let value = self.evaluate(&s.value)?;
1955 self.globals.borrow_mut().define(s.name.name.clone(), value);
1956 Ok(Value::Null)
1957 }
1958 Item::ExternBlock(extern_block) => {
1959 for item in &extern_block.items {
1961 if let ExternItem::Function(func) = item {
1962 let name = func.name.name.clone();
1963 match name.as_str() {
1965 "sigil_read_file" => {
1966 self.define_builtin("sigil_read_file", Some(2), |_, args| {
1967 let path = match &args[0] {
1969 Value::String(s) => (**s).clone(),
1970 _ => return Err(RuntimeError::new("sigil_read_file expects string path")),
1971 };
1972 match std::fs::read_to_string(&path) {
1973 Ok(content) => {
1974 Ok(Value::String(Rc::new(content)))
1976 }
1977 Err(_) => Ok(Value::Null),
1978 }
1979 });
1980 }
1981 "sigil_file_len" => {
1982 self.define_builtin("sigil_file_len", Some(0), |_, _| {
1983 Ok(Value::Int(0))
1985 });
1986 }
1987 "sigil_write_file" => {
1988 self.define_builtin("sigil_write_file", Some(4), |_, args| {
1989 let path = match &args[0] {
1990 Value::String(s) => (**s).clone(),
1991 _ => return Err(RuntimeError::new("sigil_write_file expects string path")),
1992 };
1993 let content = match &args[2] {
1994 Value::String(s) => (**s).clone(),
1995 _ => return Err(RuntimeError::new("sigil_write_file expects string content")),
1996 };
1997 match std::fs::write(&path, &content) {
1998 Ok(_) => Ok(Value::Bool(true)),
1999 Err(_) => Ok(Value::Bool(false)),
2000 }
2001 });
2002 }
2003 "write" => {
2004 self.define_builtin("write", Some(3), |_, args| {
2005 let fd = match &args[0] {
2007 Value::Int(n) => *n,
2008 _ => 1,
2009 };
2010 let content = match &args[1] {
2011 Value::String(s) => (**s).clone(),
2012 _ => format!("{}", args[1]),
2013 };
2014 if fd == 1 {
2015 print!("{}", content);
2016 } else if fd == 2 {
2017 eprint!("{}", content);
2018 }
2019 Ok(Value::Int(content.len() as i64))
2020 });
2021 }
2022 _ => {
2023 }
2025 }
2026 }
2027 }
2028 Ok(Value::Null)
2029 }
2030 Item::Impl(impl_block) => {
2031 let type_name = match &impl_block.self_ty {
2033 TypeExpr::Path(path) => {
2034 path.segments.iter().map(|s| s.ident.name.as_str()).collect::<Vec<_>>().join("::")
2035 }
2036 _ => return Ok(Value::Null), };
2038
2039 if let Some(trait_path) = &impl_block.trait_ {
2041 let trait_name = trait_path.segments.iter()
2042 .map(|s| s.ident.name.as_str())
2043 .collect::<Vec<_>>()
2044 .join("::");
2045 if trait_name == "Drop" {
2046 self.drop_types.insert(type_name.clone());
2047 }
2048 }
2049
2050 for impl_item in &impl_block.items {
2052 if let ImplItem::Function(func) = impl_item {
2053 let fn_value = self.create_function(func)?;
2054 let qualified_name = format!("{}·{}", type_name, func.name.name);
2055 if type_name == "Lexer" && func.name.name.contains("keyword") {
2057 crate::sigil_debug!("DEBUG registering: {}", qualified_name);
2058 }
2059 self.globals.borrow_mut().define(qualified_name.clone(), fn_value.clone());
2060
2061 if let Some(ref module) = self.current_module {
2063 let fully_qualified = format!("{}·{}", module, qualified_name);
2064 self.globals.borrow_mut().define(fully_qualified, fn_value);
2065 }
2066 }
2067 }
2068
2069 if let Some(trait_path) = &impl_block.trait_ {
2071 let trait_name = trait_path.segments.iter()
2072 .map(|s| s.ident.name.as_str())
2073 .collect::<Vec<_>>()
2074 .join("::");
2075 self.trait_impls.insert((type_name.clone(), trait_name), true);
2076 }
2077
2078 Ok(Value::Null)
2079 }
2080 Item::Trait(trait_def) => {
2081 let trait_name = trait_def.name.name.clone();
2083
2084 let methods: Vec<String> = trait_def.items.iter()
2086 .filter_map(|item| {
2087 if let crate::ast::TraitItem::Function(f) = item {
2088 Some(f.name.name.clone())
2089 } else {
2090 None
2091 }
2092 })
2093 .collect();
2094
2095 let supertraits: Vec<String> = trait_def.supertraits.iter()
2097 .filter_map(|t| {
2098 if let TypeExpr::Path(path) = t {
2099 Some(path.segments.iter()
2100 .map(|s| s.ident.name.as_str())
2101 .collect::<Vec<_>>()
2102 .join("::"))
2103 } else {
2104 None
2105 }
2106 })
2107 .collect();
2108
2109 self.trait_defs.insert(trait_name.clone(), TraitInfo {
2110 name: trait_name,
2111 methods,
2112 supertraits,
2113 });
2114
2115 Ok(Value::Null)
2116 }
2117 Item::Module(module) => {
2118 let module_name = &module.name.name;
2120
2121 if let Some(items) = &module.items {
2122 for item in items {
2125 match &item.node {
2126 Item::Const(c) => {
2127 let value = self.evaluate(&c.value)?;
2128 let qualified_name = format!("{}·{}", module_name, c.name.name);
2129 self.globals.borrow_mut().define(qualified_name, value);
2130 }
2131 Item::Static(s) => {
2132 let value = self.evaluate(&s.value)?;
2133 let qualified_name = format!("{}·{}", module_name, s.name.name);
2134 self.globals.borrow_mut().define(qualified_name, value);
2135 }
2136 Item::Function(func) => {
2137 let fn_value = self.create_function(func)?;
2138 let qualified_name = format!("{}·{}", module_name, func.name.name);
2139 self.globals.borrow_mut().define(qualified_name, fn_value);
2140 }
2141 Item::Struct(s) => {
2142 let qualified_name = format!("{}·{}", module_name, s.name.name);
2143 self.types.insert(qualified_name, TypeDef::Struct(s.clone()));
2144 }
2145 Item::Enum(e) => {
2146 let qualified_name = format!("{}·{}", module_name, e.name.name);
2147 self.types.insert(qualified_name, TypeDef::Enum(e.clone()));
2148 }
2149 _ => {} }
2151 }
2152 } else {
2153 if let Some(ref source_dir) = self.current_source_dir {
2155 let module_path = std::path::Path::new(source_dir)
2156 .join(format!("{}.sigil", module_name));
2157
2158 if module_path.exists() {
2159 crate::sigil_debug!("DEBUG Loading external module: {}", module_path.display());
2160
2161 match std::fs::read_to_string(&module_path) {
2162 Ok(source) => {
2163 let mut parser = crate::Parser::new(&source);
2165 match parser.parse_file() {
2166 Ok(parsed_file) => {
2167 let prev_module = self.current_module.clone();
2169
2170 self.current_module = Some(module_name.clone());
2172
2173 for item in &parsed_file.items {
2175 if let Err(e) = self.execute_item(&item.node) {
2176 crate::sigil_warn!("Warning: error in module {}: {}", module_name, e);
2177 }
2178 }
2179
2180 self.current_module = prev_module;
2182 }
2183 Err(e) => {
2184 crate::sigil_warn!("Warning: failed to parse module {}: {:?}", module_name, e);
2185 }
2186 }
2187 }
2188 Err(e) => {
2189 crate::sigil_warn!("Warning: failed to read module file {}: {}", module_path.display(), e);
2190 }
2191 }
2192 } else {
2193 crate::sigil_debug!("DEBUG Module file not found: {} (source_dir={})", module_path.display(), source_dir);
2194 }
2195 } else {
2196 crate::sigil_debug!("DEBUG No source_dir set, cannot load external module: {}", module_name);
2197 }
2198 }
2199 Ok(Value::Null)
2200 }
2201 Item::Use(use_decl) => {
2202 self.process_use_tree(&use_decl.tree, &[])?;
2204 Ok(Value::Null)
2205 }
2206 _ => Ok(Value::Null), }
2208 }
2209
2210 fn process_use_tree(&mut self, tree: &crate::ast::UseTree, prefix: &[String]) -> Result<(), RuntimeError> {
2212 use crate::ast::UseTree;
2213 match tree {
2214 UseTree::Path { prefix: path_prefix, suffix } => {
2215 let mut new_prefix = prefix.to_vec();
2217 new_prefix.push(path_prefix.name.clone());
2218 self.process_use_tree(suffix, &new_prefix)
2219 }
2220 UseTree::Name(name) => {
2221 let mut path = prefix.to_vec();
2223 path.push(name.name.clone());
2224 let qualified = path.join("·");
2225 let simple_name = name.name.clone();
2226
2227 if !prefix.is_empty() {
2230 let crate_name = &prefix[0];
2231 if !self.types.contains_key(&qualified)
2232 && self.globals.borrow().get(&qualified).is_none()
2233 && !self.loaded_crates.contains(crate_name)
2234 {
2235 if let Err(e) = self.load_crate(crate_name) {
2237 crate::sigil_debug!("DEBUG process_use_tree: failed to load crate '{}': {}", crate_name, e);
2238 }
2239 }
2240 }
2241
2242 if let Some(type_def) = self.types.get(&qualified).cloned() {
2245 self.types.insert(simple_name.clone(), type_def);
2246 }
2247 let func = self.globals.borrow().get(&qualified).map(|v| v.clone());
2249 if let Some(val) = func {
2250 self.globals.borrow_mut().define(simple_name.clone(), val);
2251 }
2252
2253 let method_prefix = format!("{}·", qualified);
2257 let matching_methods: Vec<(String, Value)> = {
2258 let globals = self.globals.borrow();
2259 globals.values.iter()
2260 .filter(|(k, _)| k.starts_with(&method_prefix))
2261 .map(|(k, v)| {
2262 let method_suffix = k.strip_prefix(&method_prefix).unwrap();
2264 let new_name = format!("{}·{}", simple_name, method_suffix);
2265 (new_name, v.clone())
2266 })
2267 .collect()
2268 };
2269 for (name, val) in matching_methods {
2270 self.globals.borrow_mut().define(name, val);
2271 }
2272 Ok(())
2273 }
2274 UseTree::Rename { name, alias } => {
2275 let mut path = prefix.to_vec();
2277 path.push(name.name.clone());
2278 let qualified = path.join("·");
2279 let alias_name = alias.name.clone();
2280
2281 if let Some(type_def) = self.types.get(&qualified).cloned() {
2282 self.types.insert(alias_name.clone(), type_def);
2283 }
2284 let func = self.globals.borrow().get(&qualified).map(|v| v.clone());
2285 if let Some(val) = func {
2286 self.globals.borrow_mut().define(alias_name, val);
2287 }
2288 Ok(())
2289 }
2290 UseTree::Glob => {
2291 let path_prefix = prefix.join("·");
2293 let matching_types: Vec<(String, TypeDef)> = self.types.iter()
2295 .filter(|(k, _)| k.starts_with(&path_prefix) && k.len() > path_prefix.len())
2296 .map(|(k, v)| {
2297 let suffix = k.strip_prefix(&path_prefix).unwrap().trim_start_matches('·');
2298 (suffix.to_string(), v.clone())
2299 })
2300 .filter(|(k, _)| !k.contains('·')) .collect();
2302 for (name, def) in matching_types {
2303 self.types.insert(name, def);
2304 }
2305 let matching_funcs: Vec<(String, Value)> = {
2307 let globals = self.globals.borrow();
2308 globals.values.iter()
2309 .filter(|(k, _)| k.starts_with(&path_prefix) && k.len() > path_prefix.len())
2310 .map(|(k, v)| {
2311 let suffix = k.strip_prefix(&path_prefix).unwrap().trim_start_matches('·');
2312 (suffix.to_string(), v.clone())
2313 })
2314 .filter(|(k, _)| !k.contains('·'))
2315 .collect()
2316 };
2317 for (name, val) in matching_funcs {
2318 self.globals.borrow_mut().define(name, val);
2319 }
2320 Ok(())
2321 }
2322 UseTree::Group(trees) => {
2323 for tree in trees {
2325 self.process_use_tree(tree, prefix)?;
2326 }
2327 Ok(())
2328 }
2329 }
2330 }
2331
2332 fn create_function(&self, func: &crate::ast::Function) -> Result<Value, RuntimeError> {
2333 let params: Vec<String> = func
2334 .params
2335 .iter()
2336 .map(|p| Self::extract_param_name(&p.pattern))
2337 .collect();
2338
2339 let body = func
2340 .body
2341 .as_ref()
2342 .map(|b| Expr::Block(b.clone()))
2343 .unwrap_or(Expr::Literal(Literal::Bool(false)));
2344
2345 Ok(Value::Function(Rc::new(Function {
2346 name: Some(func.name.name.clone()),
2347 params,
2348 body,
2349 closure: self.environment.clone(),
2350 })))
2351 }
2352
2353 fn extract_param_name(pattern: &Pattern) -> String {
2355 match pattern {
2356 Pattern::Ident { name, .. } => name.name.clone(),
2357 Pattern::Ref { pattern: inner, .. } => Self::extract_param_name(inner),
2359 Pattern::RefBinding { name, .. } => name.name.clone(),
2361 _ => "_".to_string(),
2362 }
2363 }
2364
2365 pub fn evaluate(&mut self, expr: &Expr) -> Result<Value, RuntimeError> {
2367 match expr {
2368 Expr::Literal(lit) => self.eval_literal(lit),
2369 Expr::Path(path) => self.eval_path(path),
2370 Expr::Binary { left, op, right } => self.eval_binary(left, op, right),
2371 Expr::Unary { op, expr } => self.eval_unary(op, expr),
2372 Expr::Call { func, args } => self.eval_call(func, args),
2373 Expr::Array(elements) => self.eval_array(elements),
2374 Expr::Tuple(elements) => self.eval_tuple(elements),
2375 Expr::Block(block) => self.eval_block(block),
2376 Expr::If {
2377 condition,
2378 then_branch,
2379 else_branch,
2380 } => self.eval_if(condition, then_branch, else_branch),
2381 Expr::Match { expr, arms } => self.eval_match(expr, arms),
2382 Expr::For {
2383 pattern,
2384 iter,
2385 body,
2386 ..
2387 } => self.eval_for(pattern, iter, body),
2388 Expr::While { condition, body, .. } => self.eval_while(condition, body),
2389 Expr::Loop { body, .. } => self.eval_loop(body),
2390 Expr::Return(value) => self.eval_return(value),
2391 Expr::Break { value, .. } => self.eval_break(value),
2392 Expr::Continue { .. } => Err(RuntimeError::new("continue")),
2393 Expr::Index { expr, index } => self.eval_index(expr, index),
2394 Expr::Field { expr, field } => self.eval_field(expr, field),
2395 Expr::MethodCall {
2396 receiver,
2397 method,
2398 args,
2399 ..
2400 } => self.eval_method_call(receiver, method, args),
2401 Expr::Incorporation { segments } => self.eval_incorporation(segments),
2404 Expr::Pipe { expr, operations } => self.eval_pipe(expr, operations),
2405 Expr::Closure { params, body, .. } => self.eval_closure(params, body),
2406 Expr::Struct { path, fields, rest } => self.eval_struct_literal(path, fields, rest),
2407 Expr::Evidential {
2408 expr,
2409 evidentiality,
2410 } => self.eval_evidential(expr, evidentiality),
2411 Expr::Range {
2412 start,
2413 end,
2414 inclusive,
2415 } => {
2416 crate::sigil_debug!("DEBUG evaluate: Expr::Range being evaluated standalone");
2417 self.eval_range(start, end, *inclusive)
2418 }
2419 Expr::Assign { target, value } => self.eval_assign(target, value),
2420 Expr::Let { pattern, value } => {
2421 let val = self.evaluate(value)?;
2424 if self.pattern_matches(pattern, &val)? {
2426 self.bind_pattern(pattern, val)?;
2428 Ok(Value::Bool(true))
2429 } else {
2430 Ok(Value::Bool(false))
2432 }
2433 }
2434 Expr::Await {
2435 expr: inner,
2436 evidentiality,
2437 } => {
2438 let value = self.evaluate(inner)?;
2439 let awaited = self.await_value(value)?;
2440 match evidentiality {
2442 Some(Evidentiality::Uncertain) => {
2443 self.unwrap_result_or_option(awaited, true, false)
2445 }
2446 Some(Evidentiality::Known) => {
2447 self.unwrap_result_or_option(awaited, true, true)
2449 }
2450 Some(Evidentiality::Reported) | Some(Evidentiality::Paradox) | Some(Evidentiality::Predicted) => {
2451 self.unwrap_result_or_option(awaited, false, false)
2453 }
2454 None => Ok(awaited),
2455 }
2456 }
2457 Expr::Macro { path, tokens } => {
2459 let macro_name = path.segments.last()
2460 .map(|s| s.ident.name.as_str())
2461 .unwrap_or("");
2462 crate::sigil_debug!("DEBUG Expr::Macro: name='{}', tokens='{}'", macro_name, tokens);
2463
2464 match macro_name {
2465 "format" => self.eval_format_macro(tokens),
2466 "println" => {
2467 let formatted = self.eval_format_macro(tokens)?;
2468 if let Value::String(s) = formatted {
2469 println!("{}", s);
2470 }
2471 Ok(Value::Null)
2472 }
2473 "eprintln" => {
2474 let formatted = self.eval_format_macro(tokens)?;
2475 if let Value::String(s) = formatted {
2476 eprintln!("{}", s);
2477 }
2478 Ok(Value::Null)
2479 }
2480 "print" => {
2481 let formatted = self.eval_format_macro(tokens)?;
2482 if let Value::String(s) = formatted {
2483 print!("{}", s);
2484 }
2485 Ok(Value::Null)
2486 }
2487 "eprint" => {
2488 let formatted = self.eval_format_macro(tokens)?;
2489 if let Value::String(s) = formatted {
2490 eprint!("{}", s);
2491 }
2492 Ok(Value::Null)
2493 }
2494 "vec" => {
2495 self.eval_vec_macro(tokens)
2497 }
2498 "panic" => {
2499 let formatted = self.eval_format_macro(tokens)?;
2500 let msg = if let Value::String(s) = formatted {
2501 s.to_string()
2502 } else {
2503 "panic!".to_string()
2504 };
2505 Err(RuntimeError::new(format!("panic: {}", msg)))
2506 }
2507 "assert" => {
2508 let condition = self.eval_format_macro(tokens)?;
2510 if self.is_truthy(&condition) {
2511 Ok(Value::Null)
2512 } else {
2513 Err(RuntimeError::new("assertion failed"))
2514 }
2515 }
2516 _ => {
2517 Ok(Value::String(Rc::new(tokens.clone())))
2519 }
2520 }
2521 }
2522 Expr::Unsafe(block) => self.eval_block(block),
2524 Expr::Async { block, .. } => self.eval_block(block),
2526 Expr::Try(inner) => {
2528 let value = self.evaluate(inner)?;
2529 match &value {
2532 Value::Variant { enum_name, variant_name, fields } => {
2533 match (enum_name.as_str(), variant_name.as_str()) {
2534 ("Result", "Ok") => {
2535 if let Some(f) = fields {
2536 Ok(f.first().cloned().unwrap_or(Value::Null))
2537 } else {
2538 Ok(Value::Null)
2539 }
2540 }
2541 ("Result", "Err") => {
2542 crate::sigil_debug!("DEBUG Try propagating Result::Err with fields: {:?}", fields);
2543 let err_msg = if let Some(f) = fields {
2544 let first = f.first().cloned().unwrap_or(Value::Null);
2545 crate::sigil_debug!("DEBUG Try error first value: {}", first);
2546 match &first {
2548 Value::Struct { name, fields: sf } => {
2549 let field_str = sf.borrow().iter()
2550 .map(|(k, v)| format!("{}: {}", k, v))
2551 .collect::<Vec<_>>()
2552 .join(", ");
2553 format!("{} {{ {} }}", name, field_str)
2554 }
2555 Value::Variant { enum_name: en, variant_name: vn, fields: vf } => {
2556 let vf_str = vf.as_ref().map(|vs|
2557 vs.iter().map(|v| format!("{}", v)).collect::<Vec<_>>().join(", ")
2558 ).unwrap_or_default();
2559 format!("{}::{} {{ {} }}", en, vn, vf_str)
2560 }
2561 _ => format!("{}", first)
2562 }
2563 } else {
2564 "error".to_string()
2565 };
2566 Err(RuntimeError::new(format!("try failed: {}", err_msg)))
2567 }
2568 ("Option", "Some") => {
2569 if let Some(f) = fields {
2570 Ok(f.first().cloned().unwrap_or(Value::Null))
2571 } else {
2572 Ok(Value::Null)
2573 }
2574 }
2575 ("Option", "None") => {
2576 Err(RuntimeError::new("try failed: None"))
2577 }
2578 _ => Ok(value), }
2580 }
2581 _ => Ok(value), }
2583 }
2584 Expr::Cast { expr, ty } => {
2586 let value = self.evaluate(expr)?;
2587 let type_name = match ty {
2589 TypeExpr::Path(path) => {
2590 if !path.segments.is_empty() {
2591 path.segments.last().map(|s| s.ident.name.as_str()).unwrap_or("")
2592 } else {
2593 ""
2594 }
2595 }
2596 _ => "",
2597 };
2598 match (value, type_name) {
2599 (Value::Char(c), "u8") => Ok(Value::Int(c as i64)),
2601 (Value::Char(c), "u16") => Ok(Value::Int(c as i64)),
2602 (Value::Char(c), "u32") => Ok(Value::Int(c as i64)),
2603 (Value::Char(c), "u64") => Ok(Value::Int(c as i64)),
2604 (Value::Char(c), "i8") => Ok(Value::Int(c as i64)),
2605 (Value::Char(c), "i16") => Ok(Value::Int(c as i64)),
2606 (Value::Char(c), "i32") => Ok(Value::Int(c as i64)),
2607 (Value::Char(c), "i64") => Ok(Value::Int(c as i64)),
2608 (Value::Char(c), "usize") => Ok(Value::Int(c as i64)),
2609 (Value::Char(c), "isize") => Ok(Value::Int(c as i64)),
2610 (Value::Int(i), "u8") => Ok(Value::Int(i)),
2612 (Value::Int(i), "u16") => Ok(Value::Int(i)),
2613 (Value::Int(i), "u32") => Ok(Value::Int(i)),
2614 (Value::Int(i), "u64") => Ok(Value::Int(i)),
2615 (Value::Int(i), "i8") => Ok(Value::Int(i)),
2616 (Value::Int(i), "i16") => Ok(Value::Int(i)),
2617 (Value::Int(i), "i32") => Ok(Value::Int(i)),
2618 (Value::Int(i), "i64") => Ok(Value::Int(i)),
2619 (Value::Int(i), "usize") => Ok(Value::Int(i)),
2620 (Value::Int(i), "isize") => Ok(Value::Int(i)),
2621 (Value::Float(f), "i32") => Ok(Value::Int(f as i64)),
2623 (Value::Float(f), "i64") => Ok(Value::Int(f as i64)),
2624 (Value::Float(f), "u32") => Ok(Value::Int(f as i64)),
2625 (Value::Float(f), "u64") => Ok(Value::Int(f as i64)),
2626 (Value::Int(i), "f32") => Ok(Value::Float(i as f64)),
2628 (Value::Int(i), "f64") => Ok(Value::Float(i as f64)),
2629 (Value::Int(i), "char") => {
2631 if let Some(c) = char::from_u32(i as u32) {
2632 Ok(Value::Char(c))
2633 } else {
2634 Err(RuntimeError::new(format!("invalid char code: {}", i)))
2635 }
2636 }
2637 (v, _) => Ok(v),
2639 }
2640 }
2641 _ => Err(RuntimeError::new(format!(
2642 "Unsupported expression: {:?}",
2643 expr
2644 ))),
2645 }
2646 }
2647
2648 fn eval_assign(&mut self, target: &Expr, value: &Expr) -> Result<Value, RuntimeError> {
2649 let val = self.evaluate(value)?;
2650
2651 match target {
2652 Expr::Path(path) if path.segments.len() == 1 => {
2653 let name = &path.segments[0].ident.name;
2654 self.environment.borrow_mut().set(name, val.clone())?;
2655 Ok(val)
2656 }
2657 Expr::Index { expr, index } => {
2658 let idx = self.evaluate(index)?;
2660 let idx = match idx {
2661 Value::Int(i) => i as usize,
2662 _ => return Err(RuntimeError::new("Index must be an integer")),
2663 };
2664
2665 if let Expr::Path(path) = expr.as_ref() {
2667 if path.segments.len() == 1 {
2668 let name = &path.segments[0].ident.name;
2669 let current = self.environment.borrow().get(name).ok_or_else(|| {
2670 RuntimeError::new(format!("Undefined variable: {}", name))
2671 })?;
2672
2673 if let Value::Array(arr) = current {
2674 let borrowed = arr.borrow();
2675 let mut new_arr = borrowed.clone();
2676 drop(borrowed);
2677 if idx < new_arr.len() {
2678 new_arr[idx] = val.clone();
2679 self.environment
2680 .borrow_mut()
2681 .set(name, Value::Array(Rc::new(RefCell::new(new_arr))))?;
2682 return Ok(val);
2683 }
2684 }
2685 }
2686 }
2687 Err(RuntimeError::new("Invalid index assignment target"))
2688 }
2689 Expr::Field { expr, field } => {
2690 match expr.as_ref() {
2693 Expr::Path(path) if path.segments.len() == 1 => {
2694 let var_name = &path.segments[0].ident.name;
2695 let current = self.environment.borrow().get(var_name).ok_or_else(|| {
2696 RuntimeError::new(format!("Undefined variable: {}", var_name))
2697 })?;
2698
2699 match current {
2700 Value::Struct { fields, .. } => {
2701 fields.borrow_mut().insert(field.name.clone(), val.clone());
2702 Ok(val)
2703 }
2704 Value::Ref(r) => {
2705 let mut borrowed = r.borrow_mut();
2706 if let Value::Struct { fields, .. } = &mut *borrowed {
2707 fields.borrow_mut().insert(field.name.clone(), val.clone());
2708 Ok(val)
2709 } else {
2710 Err(RuntimeError::new("Cannot assign field on non-struct ref"))
2711 }
2712 }
2713 _ => Err(RuntimeError::new("Cannot assign field on non-struct")),
2714 }
2715 }
2716 _ => {
2717 let struct_val = self.evaluate(expr)?;
2719 match struct_val {
2720 Value::Struct { fields, .. } => {
2721 fields.borrow_mut().insert(field.name.clone(), val.clone());
2722 Ok(val)
2723 }
2724 Value::Ref(r) => {
2725 let mut borrowed = r.borrow_mut();
2726 if let Value::Struct { fields, .. } = &mut *borrowed {
2727 fields.borrow_mut().insert(field.name.clone(), val.clone());
2728 Ok(val)
2729 } else {
2730 Err(RuntimeError::new("Cannot assign field on non-struct"))
2731 }
2732 }
2733 _ => Err(RuntimeError::new("Cannot assign field on non-struct")),
2734 }
2735 }
2736 }
2737 }
2738 Expr::Unary { op: UnaryOp::Deref, expr: inner } => {
2739 let ptr_val = self.evaluate(inner)?;
2742 match ptr_val {
2743 Value::Ref(r) => {
2744 *r.borrow_mut() = val.clone();
2745 Ok(val)
2746 }
2747 _ => Err(RuntimeError::new("Cannot dereference assign to non-reference")),
2748 }
2749 }
2750 Expr::Deref(inner) => {
2751 let ptr_val = self.evaluate(inner)?;
2754 match ptr_val {
2755 Value::Ref(r) => {
2756 *r.borrow_mut() = val.clone();
2757 Ok(val)
2758 }
2759 _ => Err(RuntimeError::new("Cannot dereference assign to non-reference")),
2760 }
2761 }
2762 _ => Err(RuntimeError::new("Invalid assignment target")),
2763 }
2764 }
2765
2766 fn eval_literal(&mut self, lit: &Literal) -> Result<Value, RuntimeError> {
2767 match lit {
2768 Literal::Int { value, base, .. } => {
2769 let n = self.parse_int(value, base)?;
2770 Ok(Value::Int(n))
2771 }
2772 Literal::Float { value, .. } => {
2773 let n: f64 = value
2774 .parse()
2775 .map_err(|_| RuntimeError::new(format!("Invalid float: {}", value)))?;
2776 Ok(Value::Float(n))
2777 }
2778 Literal::String(s) => Ok(Value::String(Rc::new(s.clone()))),
2779 Literal::MultiLineString(s) => Ok(Value::String(Rc::new(s.clone()))),
2780 Literal::RawString(s) => Ok(Value::String(Rc::new(s.clone()))),
2781 Literal::ByteString(bytes) => {
2782 let arr: Vec<Value> = bytes.iter().map(|&b| Value::Int(b as i64)).collect();
2784 Ok(Value::Array(Rc::new(RefCell::new(arr))))
2785 }
2786 Literal::InterpolatedString { parts } => {
2787 let mut result = String::new();
2789 let mut combined_evidence: Option<Evidence> = None;
2790
2791 for part in parts {
2792 match part {
2793 InterpolationPart::Text(s) => result.push_str(s),
2794 InterpolationPart::Expr(expr) => {
2795 let value = self.evaluate(expr)?;
2796
2797 combined_evidence = Self::combine_evidence(
2799 combined_evidence,
2800 Self::extract_evidence(&value),
2801 );
2802
2803 if let Some(affect) = Self::extract_affect(&value) {
2805 combined_evidence = Self::combine_evidence(
2806 combined_evidence,
2807 Self::affect_to_evidence(affect),
2808 );
2809 }
2810
2811 let display_value = Self::unwrap_value(&value);
2813 result.push_str(&format!("{}", display_value));
2814 }
2815 }
2816 }
2817
2818 let string_value = Value::String(Rc::new(result));
2820 match combined_evidence {
2821 Some(evidence) => Ok(Value::Evidential {
2822 value: Box::new(string_value),
2823 evidence,
2824 }),
2825 None => Ok(string_value),
2826 }
2827 }
2828 Literal::SigilStringSql(s) => {
2829 Ok(Value::String(Rc::new(s.clone())))
2832 }
2833 Literal::SigilStringRoute(s) => {
2834 Ok(Value::String(Rc::new(s.clone())))
2837 }
2838 Literal::Char(c) => Ok(Value::Char(*c)),
2839 Literal::ByteChar(b) => Ok(Value::Int(*b as i64)),
2840 Literal::Bool(b) => Ok(Value::Bool(*b)),
2841 Literal::Null => Ok(Value::Null),
2842 Literal::Empty => Ok(Value::Empty),
2843 Literal::Infinity => Ok(Value::Infinity),
2844 Literal::Circle => Ok(Value::Int(0)), }
2846 }
2847
2848 fn parse_int(&self, value: &str, base: &NumBase) -> Result<i64, RuntimeError> {
2849 let (radix, prefix_len) = match base {
2850 NumBase::Binary => (2, 2), NumBase::Octal => (8, 2), NumBase::Decimal => (10, 0),
2853 NumBase::Hex => (16, 2), NumBase::Vigesimal => (20, 2), NumBase::Sexagesimal => (60, 2), NumBase::Duodecimal => (12, 2), NumBase::Explicit(b) => (*b as u32, 0),
2858 };
2859
2860 let clean = value[prefix_len..].replace('_', "");
2861 i64::from_str_radix(&clean, radix)
2862 .map_err(|_| RuntimeError::new(format!("Invalid integer: {}", value)))
2863 }
2864
2865 fn eval_path(&self, path: &TypePath) -> Result<Value, RuntimeError> {
2866 if path.segments.len() == 1 {
2867 let name = &path.segments[0].ident.name;
2868 if let Some(val) = self.environment.borrow().get(name) {
2872 return Ok(val);
2873 }
2874 if name == "_" {
2876 return Ok(Value::Null);
2877 }
2878 if name == "Self" {
2880 if let Some(ref self_type) = self.current_self_type {
2881 if let Some(TypeDef::Struct(struct_def)) = self.types.get(self_type) {
2883 if matches!(struct_def.fields, crate::ast::StructFields::Unit) {
2884 return Ok(Value::Struct {
2885 name: self_type.clone(),
2886 fields: Rc::new(RefCell::new(HashMap::new())),
2887 });
2888 }
2889 }
2890 return Ok(Value::Struct {
2892 name: self_type.clone(),
2893 fields: Rc::new(RefCell::new(HashMap::new())),
2894 });
2895 }
2896 }
2897 if name.len() <= 2 {
2898 crate::sigil_debug!("DEBUG Undefined variable '{}' (len={})", name, name.len());
2899 }
2900 Err(RuntimeError::new(format!("Undefined variable: {}", name)))
2901 } else {
2902 let full_name = path
2905 .segments
2906 .iter()
2907 .map(|s| s.ident.name.as_str())
2908 .collect::<Vec<_>>()
2909 .join("·");
2910
2911 if let Some(val) = self.environment.borrow().get(&full_name) {
2912 return Ok(val);
2913 }
2914
2915 if let Some(val) = self.globals.borrow().get(&full_name) {
2917 return Ok(val);
2918 }
2919
2920 if let Some(ref current_mod) = self.current_module {
2923 let crate_name = current_mod.split('·').next().unwrap_or(current_mod);
2925 let crate_qualified = format!("{}·{}", crate_name, full_name);
2926 if full_name.contains("execute") {
2927 crate::sigil_debug!("DEBUG eval_path: Looking for '{}' with crate_qualified='{}'", full_name, crate_qualified);
2928 }
2929 if let Some(val) = self.globals.borrow().get(&crate_qualified) {
2930 crate::sigil_debug!("DEBUG eval_path: FOUND '{}' via crate_qualified", crate_qualified);
2931 return Ok(val);
2932 }
2933 } else if full_name.contains("execute") {
2934 crate::sigil_debug!("DEBUG eval_path: current_module is None, can't resolve '{}'", full_name);
2935 }
2936
2937 if full_name.ends_with("·new") {
2939 crate::sigil_debug!("DEBUG eval_path: Looking for '{}' - NOT FOUND in globals", full_name);
2940 }
2941
2942 if path.segments.len() == 2 {
2946 let type_name = &path.segments[0].ident.name;
2947 let variant_name = &path.segments[1].ident.name;
2948
2949 if let Some(TypeDef::Enum(enum_def)) = self.types.get(type_name) {
2951 for variant in &enum_def.variants {
2952 if &variant.name.name == variant_name {
2953 if matches!(variant.fields, crate::ast::StructFields::Unit) {
2955 return Ok(Value::Variant {
2956 enum_name: type_name.clone(),
2957 variant_name: variant_name.clone(),
2958 fields: None,
2959 });
2960 }
2961 }
2962 }
2963 }
2964
2965 for (actual_type_name, type_def) in &self.types {
2967 if let TypeDef::Enum(enum_def) = type_def {
2968 for variant in &enum_def.variants {
2969 if &variant.name.name == variant_name {
2970 if matches!(variant.fields, crate::ast::StructFields::Unit) {
2971 return Ok(Value::Variant {
2972 enum_name: actual_type_name.clone(),
2973 variant_name: variant_name.clone(),
2974 fields: None,
2975 });
2976 }
2977 }
2978 }
2979 }
2980 }
2981 }
2982
2983 let last_name = &path.segments.last().unwrap().ident.name;
2985 if let Some(val) = self.environment.borrow().get(last_name) {
2986 if last_name == "new" {
2988 crate::sigil_debug!("DEBUG eval_path: FALLBACK from '{}' to '{}' - found in env", full_name, last_name);
2989 }
2990 return Ok(val);
2991 }
2992
2993 if path.segments.len() == 2 && path.segments[0].ident.name == "Self" {
2995 if let Some(ref self_type) = self.current_self_type {
2996 let qualified = format!("{}·{}", self_type, last_name);
2998 if let Some(val) = self.globals.borrow().get(&qualified) {
2999 return Ok(val);
3000 }
3001 }
3002 }
3003
3004 if let Some((enum_name, variant_name, arity)) = self.variant_constructors.get(&full_name).cloned() {
3006 if arity == 0 {
3009 return Ok(Value::Variant {
3010 enum_name,
3011 variant_name,
3012 fields: None,
3013 });
3014 }
3015 }
3019
3020 if path.segments.len() == 2 {
3022 let type_name = &path.segments[0].ident.name;
3023 let method_name = &path.segments[1].ident.name;
3024
3025 let is_method = method_name.chars().next().map_or(false, |c| c.is_lowercase())
3027 || method_name == "new"
3028 || method_name == "default"
3029 || method_name == "from"
3030 || method_name == "try_from"
3031 || method_name == "into"
3032 || method_name == "with_capacity"
3033 || method_name == "from_str";
3034
3035 if is_method {
3036 return Ok(Value::Struct {
3039 name: format!("__constructor__{}", type_name),
3040 fields: Rc::new(RefCell::new(HashMap::new())),
3041 });
3042 } else {
3043 return Ok(Value::Variant {
3045 enum_name: type_name.clone(),
3046 variant_name: method_name.clone(),
3047 fields: None,
3048 });
3049 }
3050 }
3051
3052 Err(RuntimeError::new(format!(
3053 "Undefined: {} (tried {} and {})",
3054 full_name, full_name, last_name
3055 )))
3056 }
3057 }
3058
3059 fn eval_binary(
3060 &mut self,
3061 left: &Expr,
3062 op: &BinOp,
3063 right: &Expr,
3064 ) -> Result<Value, RuntimeError> {
3065 let lhs = self.evaluate(left)?;
3066
3067 match op {
3069 BinOp::And => {
3070 if !self.is_truthy(&lhs) {
3071 return Ok(Value::Bool(false));
3072 }
3073 let rhs = self.evaluate(right)?;
3074 return Ok(Value::Bool(self.is_truthy(&rhs)));
3075 }
3076 BinOp::Or => {
3077 if self.is_truthy(&lhs) {
3078 return Ok(Value::Bool(true));
3079 }
3080 let rhs = self.evaluate(right)?;
3081 return Ok(Value::Bool(self.is_truthy(&rhs)));
3082 }
3083 _ => {}
3084 }
3085
3086 let rhs = self.evaluate(right)?;
3087
3088 let lhs = Self::unwrap_all(&lhs);
3090 let rhs = Self::unwrap_all(&rhs);
3091
3092 if matches!(op, BinOp::Mul) && (matches!(lhs, Value::Null) || matches!(rhs, Value::Null) || matches!(lhs, Value::Struct { .. }) || matches!(rhs, Value::Struct { .. })) {
3094 crate::sigil_debug!("DEBUG eval_binary Mul: left={:?}, right={:?}", left, right);
3095 crate::sigil_debug!("DEBUG eval_binary Mul: lhs={}, rhs={}", self.format_value(&lhs), self.format_value(&rhs));
3096 }
3097
3098 match (lhs, rhs) {
3099 (Value::Int(a), Value::Int(b)) => self.int_binary_op(a, b, op),
3100 (Value::Float(a), Value::Float(b)) => self.float_binary_op(a, b, op),
3101 (Value::Int(a), Value::Float(b)) => self.float_binary_op(a as f64, b, op),
3102 (Value::Float(a), Value::Int(b)) => self.float_binary_op(a, b as f64, op),
3103 (Value::String(a), Value::String(b)) => match op {
3104 BinOp::Add | BinOp::Concat => Ok(Value::String(Rc::new(format!("{}{}", a, b)))),
3105 BinOp::Eq => Ok(Value::Bool(*a == *b)),
3106 BinOp::Ne => Ok(Value::Bool(*a != *b)),
3107 _ => Err(RuntimeError::new("Invalid string operation")),
3108 },
3109 (Value::Bool(a), Value::Bool(b)) => match op {
3110 BinOp::Eq => Ok(Value::Bool(a == b)),
3111 BinOp::Ne => Ok(Value::Bool(a != b)),
3112 _ => Err(RuntimeError::new("Invalid boolean operation")),
3113 },
3114 (Value::Array(a), Value::Array(b)) => match op {
3115 BinOp::Concat => {
3116 let mut result = a.borrow().clone();
3117 result.extend(b.borrow().iter().cloned());
3118 Ok(Value::Array(Rc::new(RefCell::new(result))))
3119 }
3120 BinOp::Eq => Ok(Value::Bool(Rc::ptr_eq(&a, &b))),
3121 BinOp::Ne => Ok(Value::Bool(!Rc::ptr_eq(&a, &b))),
3122 _ => Err(RuntimeError::new("Invalid array operation")),
3123 },
3124 (Value::Null, Value::Null) => match op {
3126 BinOp::Eq => Ok(Value::Bool(true)),
3127 BinOp::Ne => Ok(Value::Bool(false)),
3128 _ => {
3129 crate::sigil_debug!("DEBUG: null op {:?} on (Null, Null)", op);
3130 Err(RuntimeError::new(format!("Invalid null operation: {:?} on (Null, Null)", op)))
3131 }
3132 },
3133 (Value::Null, other) | (other, Value::Null) => match op {
3134 BinOp::Eq => Ok(Value::Bool(false)),
3135 BinOp::Ne => Ok(Value::Bool(true)),
3136 _ => {
3137 crate::sigil_debug!("DEBUG: null op {:?} with other={}", op, self.format_value(&other));
3138 Err(RuntimeError::new(format!("Invalid null operation: {:?}", op)))
3139 }
3140 },
3141 (Value::Char(a), Value::Char(b)) => match op {
3143 BinOp::Eq => Ok(Value::Bool(a == b)),
3144 BinOp::Ne => Ok(Value::Bool(a != b)),
3145 BinOp::Lt => Ok(Value::Bool(a < b)),
3146 BinOp::Le => Ok(Value::Bool(a <= b)),
3147 BinOp::Gt => Ok(Value::Bool(a > b)),
3148 BinOp::Ge => Ok(Value::Bool(a >= b)),
3149 _ => Err(RuntimeError::new("Invalid char operation")),
3150 },
3151 (Value::String(a), Value::Char(b)) => match op {
3153 BinOp::Add | BinOp::Concat => Ok(Value::String(Rc::new(format!("{}{}", a, b)))),
3154 _ => Err(RuntimeError::new("Invalid string/char operation")),
3155 },
3156 (Value::Char(a), Value::String(b)) => match op {
3157 BinOp::Add | BinOp::Concat => Ok(Value::String(Rc::new(format!("{}{}", a, b)))),
3158 _ => Err(RuntimeError::new("Invalid char/string operation")),
3159 },
3160 (Value::Variant { enum_name: e1, variant_name: v1, fields: f1 },
3162 Value::Variant { enum_name: e2, variant_name: v2, fields: f2 }) => match op {
3163 BinOp::Eq => {
3164 let eq = e1 == e2 && v1 == v2 && match (f1, f2) {
3165 (None, None) => true,
3166 (Some(a), Some(b)) => Rc::ptr_eq(&a, &b),
3167 _ => false,
3168 };
3169 Ok(Value::Bool(eq))
3170 }
3171 BinOp::Ne => {
3172 let eq = e1 == e2 && v1 == v2 && match (f1, f2) {
3173 (None, None) => true,
3174 (Some(a), Some(b)) => Rc::ptr_eq(&a, &b),
3175 _ => false,
3176 };
3177 Ok(Value::Bool(!eq))
3178 }
3179 _ => Err(RuntimeError::new("Invalid variant operation")),
3180 },
3181 (Value::Struct { name: n1, fields: f1 }, Value::Struct { name: n2, fields: f2 }) => match op {
3183 BinOp::Eq => Ok(Value::Bool(n1 == n2 && Rc::ptr_eq(&f1, &f2))),
3184 BinOp::Ne => Ok(Value::Bool(n1 != n2 || !Rc::ptr_eq(&f1, &f2))),
3185 _ => Err(RuntimeError::new("Invalid struct operation")),
3186 },
3187 (l, r) => Err(RuntimeError::new(format!(
3188 "Type mismatch in binary operation: {:?} {:?} {:?}",
3189 l, op, r
3190 ))),
3191 }
3192 }
3193
3194 fn int_binary_op(&self, a: i64, b: i64, op: &BinOp) -> Result<Value, RuntimeError> {
3195 Ok(match op {
3196 BinOp::Add => Value::Int(a + b),
3197 BinOp::Sub => Value::Int(a - b),
3198 BinOp::Mul => Value::Int(a * b),
3199 BinOp::Div => {
3200 if b == 0 {
3201 return Err(RuntimeError::new("Division by zero"));
3202 }
3203 Value::Int(a / b)
3204 }
3205 BinOp::Rem => {
3206 if b == 0 {
3207 return Err(RuntimeError::new("Division by zero"));
3208 }
3209 Value::Int(a % b)
3210 }
3211 BinOp::Pow => Value::Int(a.pow(b as u32)),
3212 BinOp::Eq => Value::Bool(a == b),
3213 BinOp::Ne => Value::Bool(a != b),
3214 BinOp::Lt => Value::Bool(a < b),
3215 BinOp::Le => Value::Bool(a <= b),
3216 BinOp::Gt => Value::Bool(a > b),
3217 BinOp::Ge => Value::Bool(a >= b),
3218 BinOp::BitAnd => Value::Int(a & b),
3219 BinOp::BitOr => Value::Int(a | b),
3220 BinOp::BitXor => Value::Int(a ^ b),
3221 BinOp::Shl => Value::Int(a << b),
3222 BinOp::Shr => Value::Int(a >> b),
3223 _ => return Err(RuntimeError::new("Invalid integer operation")),
3224 })
3225 }
3226
3227 fn float_binary_op(&self, a: f64, b: f64, op: &BinOp) -> Result<Value, RuntimeError> {
3228 Ok(match op {
3229 BinOp::Add => Value::Float(a + b),
3230 BinOp::Sub => Value::Float(a - b),
3231 BinOp::Mul => Value::Float(a * b),
3232 BinOp::Div => Value::Float(a / b),
3233 BinOp::Rem => Value::Float(a % b),
3234 BinOp::Pow => Value::Float(a.powf(b)),
3235 BinOp::Eq => Value::Bool((a - b).abs() < f64::EPSILON),
3236 BinOp::Ne => Value::Bool((a - b).abs() >= f64::EPSILON),
3237 BinOp::Lt => Value::Bool(a < b),
3238 BinOp::Le => Value::Bool(a <= b),
3239 BinOp::Gt => Value::Bool(a > b),
3240 BinOp::Ge => Value::Bool(a >= b),
3241 _ => return Err(RuntimeError::new("Invalid float operation")),
3242 })
3243 }
3244
3245 fn eval_unary(&mut self, op: &UnaryOp, expr: &Expr) -> Result<Value, RuntimeError> {
3246 let val = self.evaluate(expr)?;
3247 match (op, &val) {
3248 (UnaryOp::Neg, Value::Int(n)) => Ok(Value::Int(-n)),
3249 (UnaryOp::Neg, Value::Float(n)) => Ok(Value::Float(-n)),
3250 (UnaryOp::Not, Value::Bool(b)) => Ok(Value::Bool(!b)),
3251 (UnaryOp::Not, Value::Int(n)) => Ok(Value::Int(!n)),
3252 (UnaryOp::Not, Value::Evidential { value, evidence }) => {
3254 match value.as_ref() {
3256 Value::Bool(b) => Ok(Value::Evidential {
3257 value: Box::new(Value::Bool(!b)),
3258 evidence: evidence.clone(),
3259 }),
3260 other => {
3261 let truthy = self.is_truthy(other);
3262 Ok(Value::Evidential {
3263 value: Box::new(Value::Bool(!truthy)),
3264 evidence: evidence.clone(),
3265 })
3266 }
3267 }
3268 }
3269 (UnaryOp::Not, Value::String(s)) => Ok(Value::Bool(s.is_empty())),
3271 (UnaryOp::Not, Value::Array(arr)) => Ok(Value::Bool(arr.borrow().is_empty())),
3273 (UnaryOp::Not, Value::Null) => Ok(Value::Bool(true)),
3275 (UnaryOp::Ref, _) => Ok(Value::Ref(Rc::new(RefCell::new(val)))),
3276 (UnaryOp::RefMut, _) => Ok(Value::Ref(Rc::new(RefCell::new(val)))),
3277 (UnaryOp::Deref, Value::Ref(r)) => Ok(r.borrow().clone()),
3278 (UnaryOp::Deref, Value::Struct { name, fields }) if name == "Rc" => {
3279 let borrowed = fields.borrow();
3281 if let Some(value) = borrowed.get("_value") {
3282 Ok(value.clone())
3283 } else {
3284 Err(RuntimeError::new("Rc has no value"))
3285 }
3286 }
3287 (UnaryOp::Deref, other) => {
3288 let unwrapped = Self::unwrap_all(&val);
3290 if let Value::Ref(r) = &unwrapped {
3291 return Ok(r.borrow().clone());
3292 }
3293 Ok(unwrapped)
3296 }
3297 _ => Err(RuntimeError::new(format!("Invalid unary {:?} on {:?}", op, std::mem::discriminant(&val)))),
3298 }
3299 }
3300
3301 fn eval_call(&mut self, func_expr: &Expr, args: &[Expr]) -> Result<Value, RuntimeError> {
3302 if let Expr::Path(path) = func_expr {
3304 let qualified_name = path.segments.iter()
3305 .map(|s| s.ident.name.as_str())
3306 .collect::<Vec<_>>()
3307 .join("·");
3308
3309 if qualified_name == "Self" {
3311 if let Some(ref self_type) = self.current_self_type {
3312 let tuple_arity = if let Some(TypeDef::Struct(struct_def)) = self.types.get(self_type) {
3314 if let crate::ast::StructFields::Tuple(field_types) = &struct_def.fields {
3315 Some((self_type.clone(), field_types.len()))
3316 } else {
3317 None
3318 }
3319 } else {
3320 None
3321 };
3322
3323 if let Some((type_name, expected_arity)) = tuple_arity {
3324 let arg_values: Vec<Value> = args
3326 .iter()
3327 .map(|a| self.evaluate(a))
3328 .collect::<Result<_, _>>()?;
3329
3330 if arg_values.len() != expected_arity {
3331 return Err(RuntimeError::new(format!(
3332 "Tuple struct {} expects {} fields, got {}",
3333 type_name, expected_arity, arg_values.len()
3334 )));
3335 }
3336
3337 let mut fields = HashMap::new();
3339 for (i, value) in arg_values.into_iter().enumerate() {
3340 fields.insert(i.to_string(), value);
3341 }
3342 return Ok(Value::Struct {
3343 name: type_name,
3344 fields: Rc::new(RefCell::new(fields)),
3345 });
3346 }
3347 }
3348 }
3349
3350 if path.segments.len() == 1 {
3352 let type_name = &path.segments[0].ident.name;
3353 let tuple_arity = if let Some(TypeDef::Struct(struct_def)) = self.types.get(type_name) {
3355 if let crate::ast::StructFields::Tuple(field_types) = &struct_def.fields {
3356 Some((type_name.clone(), field_types.len()))
3357 } else {
3358 None
3359 }
3360 } else {
3361 None
3362 };
3363
3364 if let Some((struct_name, expected_arity)) = tuple_arity {
3365 let arg_values: Vec<Value> = args
3366 .iter()
3367 .map(|a| self.evaluate(a))
3368 .collect::<Result<_, _>>()?;
3369
3370 if arg_values.len() != expected_arity {
3371 return Err(RuntimeError::new(format!(
3372 "Tuple struct {} expects {} fields, got {}",
3373 struct_name, expected_arity, arg_values.len()
3374 )));
3375 }
3376
3377 let mut fields = HashMap::new();
3378 for (i, value) in arg_values.into_iter().enumerate() {
3379 fields.insert(i.to_string(), value);
3380 }
3381 return Ok(Value::Struct {
3382 name: struct_name,
3383 fields: Rc::new(RefCell::new(fields)),
3384 });
3385 }
3386 }
3387
3388 if qualified_name == "Default·default" && args.is_empty() {
3391 if let Some(type_name) = self.current_self_type.clone() {
3392 let default_fn_name = format!("{}·default", type_name);
3394 crate::sigil_debug!("DEBUG Default::default() looking for '{}', self_type='{}'", default_fn_name, type_name);
3395 let func_clone = self.globals.borrow().get(&default_fn_name).map(|v| v.clone());
3396 if let Some(Value::Function(f)) = func_clone {
3397 crate::sigil_debug!("DEBUG Found function '{}', calling it", default_fn_name);
3398 crate::sigil_debug!("DEBUG current_self_type before call: {:?}", self.current_self_type);
3399 let result = self.call_function(&f, vec![]);
3401 crate::sigil_debug!("DEBUG Default call result: {:?}", result.as_ref().map(|v| self.format_value(v)).unwrap_or_else(|e| format!("ERR: {:?}", e)));
3402 return result;
3403 }
3404 if let Some(struct_def) = self.default_structs.get(&type_name).cloned() {
3406 let mut fields = HashMap::new();
3407 if let StructFields::Named(field_defs) = &struct_def.fields {
3408 for field in field_defs {
3409 let default_val = if let Some(default_expr) = &field.default {
3410 self.evaluate(default_expr)?
3411 } else {
3412 Value::Null
3413 };
3414 fields.insert(field.name.name.clone(), default_val);
3415 }
3416 }
3417 return Ok(Value::Struct {
3418 name: type_name,
3419 fields: Rc::new(RefCell::new(fields)),
3420 });
3421 }
3422 }
3423 }
3424
3425 if qualified_name.ends_with("·default") && args.is_empty() {
3427 let type_name = qualified_name.strip_suffix("·default").unwrap();
3428 let default_fn_name = format!("{}·default", type_name);
3430 let func_clone = self.globals.borrow().get(&default_fn_name).map(|v| v.clone());
3431 if let Some(Value::Function(f)) = func_clone {
3432 return self.call_function(&f, vec![]);
3434 }
3435 if let Some(struct_def) = self.default_structs.get(type_name).cloned() {
3437 let mut fields = HashMap::new();
3438 if let StructFields::Named(field_defs) = &struct_def.fields {
3439 for field in field_defs {
3440 let default_val = if let Some(default_expr) = &field.default {
3441 self.evaluate(default_expr)?
3442 } else {
3443 Value::Null
3445 };
3446 fields.insert(field.name.name.clone(), default_val);
3447 }
3448 }
3449 return Ok(Value::Struct {
3450 name: type_name.to_string(),
3451 fields: Rc::new(RefCell::new(fields)),
3452 });
3453 }
3454 }
3455
3456 if let Some((enum_name, variant_name, arity)) = self.variant_constructors.get(&qualified_name).cloned() {
3458 let arg_values: Vec<Value> = args
3459 .iter()
3460 .map(|a| self.evaluate(a))
3461 .collect::<Result<_, _>>()?;
3462
3463 if arg_values.len() != arity {
3464 return Err(RuntimeError::new(format!(
3465 "{} expects {} arguments, got {}",
3466 qualified_name, arity, arg_values.len()
3467 )));
3468 }
3469
3470 if arity == 0 {
3471 return Ok(Value::Variant {
3472 enum_name,
3473 variant_name,
3474 fields: None,
3475 });
3476 } else {
3477 if enum_name == "Item" {
3478 crate::sigil_debug!("DEBUG creating Item::{} variant with {} fields", variant_name, arg_values.len());
3479 }
3480 return Ok(Value::Variant {
3481 enum_name,
3482 variant_name,
3483 fields: Some(Rc::new(arg_values)),
3484 });
3485 }
3486 }
3487
3488 let segments: Vec<&str> = path.segments.iter().map(|s| s.ident.name.as_str()).collect();
3490 match segments.as_slice() {
3491 ["Map", "new"] | ["HashMap", "new"] => {
3492 return Ok(Value::Struct {
3494 name: "Map".to_string(),
3495 fields: Rc::new(RefCell::new(HashMap::new())),
3496 });
3497 }
3498 ["String", "new"] => {
3499 return Ok(Value::String(Rc::new(String::new())));
3500 }
3501 ["Vec", "new"] | ["Array", "new"] => {
3502 return Ok(Value::Array(Rc::new(RefCell::new(Vec::new()))));
3503 }
3504 ["Box", "new"] => {
3505 if args.len() == 1 {
3507 return self.evaluate(&args[0]);
3508 }
3509 return Err(RuntimeError::new("Box::new expects 1 argument"));
3510 }
3511 ["char", "from_u32"] => {
3512 if args.len() == 1 {
3514 let arg = self.evaluate(&args[0])?;
3515 let code = match arg {
3516 Value::Int(i) => i as u32,
3517 _ => return Err(RuntimeError::new("char::from_u32 expects u32")),
3518 };
3519 if let Some(c) = char::from_u32(code) {
3520 return Ok(Value::Variant {
3522 enum_name: "Option".to_string(),
3523 variant_name: "Some".to_string(),
3524 fields: Some(Rc::new(vec![Value::Char(c)])),
3525 });
3526 } else {
3527 return Ok(Value::Variant {
3529 enum_name: "Option".to_string(),
3530 variant_name: "None".to_string(),
3531 fields: None,
3532 });
3533 }
3534 }
3535 return Err(RuntimeError::new("char::from_u32 expects 1 argument"));
3536 }
3537 ["parking_lot", "Mutex", "new"] | ["std", "sync", "Mutex", "new"] | ["Mutex", "new"] => {
3539 if args.len() == 1 {
3540 let inner = self.evaluate(&args[0])?;
3541 return Ok(Value::Struct {
3542 name: "Mutex".to_string(),
3543 fields: Rc::new(RefCell::new(HashMap::from([
3544 ("__inner__".to_string(), inner),
3545 ]))),
3546 });
3547 }
3548 return Err(RuntimeError::new("Mutex::new expects 1 argument"));
3549 }
3550 ["parking_lot", "RwLock", "new"] | ["std", "sync", "RwLock", "new"] | ["RwLock", "new"] => {
3552 if args.len() == 1 {
3553 let inner = self.evaluate(&args[0])?;
3554 return Ok(Value::Struct {
3555 name: "RwLock".to_string(),
3556 fields: Rc::new(RefCell::new(HashMap::from([
3557 ("__inner__".to_string(), inner),
3558 ]))),
3559 });
3560 }
3561 return Err(RuntimeError::new("RwLock::new expects 1 argument"));
3562 }
3563 ["std", "sync", "Arc", "new"] | ["Arc", "new"] => {
3565 if args.len() == 1 {
3566 let inner = self.evaluate(&args[0])?;
3567 return Ok(Value::Ref(Rc::new(RefCell::new(inner))));
3568 }
3569 return Err(RuntimeError::new("Arc::new expects 1 argument"));
3570 }
3571 ["std", "sync", "atomic", "AtomicU64", "new"] | ["AtomicU64", "new"] => {
3573 if args.len() == 1 {
3574 let inner = self.evaluate(&args[0])?;
3575 return Ok(Value::Struct {
3576 name: "AtomicU64".to_string(),
3577 fields: Rc::new(RefCell::new(HashMap::from([
3578 ("__value__".to_string(), inner),
3579 ]))),
3580 });
3581 }
3582 return Err(RuntimeError::new("AtomicU64::new expects 1 argument"));
3583 }
3584 ["std", "sync", "atomic", "AtomicUsize", "new"] | ["AtomicUsize", "new"] => {
3585 if args.len() == 1 {
3586 let inner = self.evaluate(&args[0])?;
3587 return Ok(Value::Struct {
3588 name: "AtomicUsize".to_string(),
3589 fields: Rc::new(RefCell::new(HashMap::from([
3590 ("__value__".to_string(), inner),
3591 ]))),
3592 });
3593 }
3594 return Err(RuntimeError::new("AtomicUsize::new expects 1 argument"));
3595 }
3596 ["std", "sync", "atomic", "AtomicBool", "new"] | ["AtomicBool", "new"] => {
3597 if args.len() == 1 {
3598 let inner = self.evaluate(&args[0])?;
3599 return Ok(Value::Struct {
3600 name: "AtomicBool".to_string(),
3601 fields: Rc::new(RefCell::new(HashMap::from([
3602 ("__value__".to_string(), inner),
3603 ]))),
3604 });
3605 }
3606 return Err(RuntimeError::new("AtomicBool::new expects 1 argument"));
3607 }
3608 _ => {}
3609 }
3610 }
3611
3612 let type_name_for_self = if let Expr::Path(path) = func_expr {
3614 if path.segments.len() >= 2 {
3615 let first = &path.segments[0].ident.name;
3617 if self.types.contains_key(first) {
3619 Some(first.clone())
3620 } else {
3621 None
3622 }
3623 } else {
3624 None
3625 }
3626 } else {
3627 None
3628 };
3629
3630 let func = self.evaluate(func_expr)?;
3631
3632 let mut mut_ref_sync: Vec<(String, Rc<RefCell<Value>>)> = Vec::new();
3635
3636 let mut arg_values: Vec<Value> = Vec::new();
3637 for arg in args.iter() {
3638 let val = self.evaluate(arg)?;
3639
3640 if let Expr::Unary { op: crate::ast::UnaryOp::RefMut, expr } = arg {
3642 if let Expr::Path(path) = expr.as_ref() {
3643 if path.segments.len() == 1 {
3644 let var_name = path.segments[0].ident.name.clone();
3645 if let Value::Ref(r) = &val {
3646 mut_ref_sync.push((var_name, r.clone()));
3647 }
3648 }
3649 }
3650 }
3651
3652 arg_values.push(val);
3653 }
3654
3655 let old_self_type = self.current_self_type.clone();
3658 if let Some(type_name) = type_name_for_self {
3659 self.current_self_type = Some(type_name);
3660 }
3661
3662 let result = match func {
3663 Value::Function(f) => self.call_function(&f, arg_values),
3664 Value::BuiltIn(b) => self.call_builtin(&b, arg_values),
3665 Value::Struct { ref name, .. } if name.starts_with("__constructor__") => {
3667 let actual_type = name.strip_prefix("__constructor__").unwrap();
3668 Ok(Value::Struct {
3670 name: actual_type.to_string(),
3671 fields: Rc::new(RefCell::new(HashMap::new())),
3672 })
3673 }
3674 _ => {
3675 crate::sigil_debug!("DEBUG Cannot call non-function: {:?}, expr: {:?}", func, func_expr);
3676 Err(RuntimeError::new("Cannot call non-function"))
3677 }
3678 };
3679
3680 for (var_name, ref_val) in mut_ref_sync {
3683 let current_value = ref_val.borrow().clone();
3684 let _ = self.environment.borrow_mut().set(&var_name, current_value);
3685 }
3686
3687 self.current_self_type = old_self_type;
3689
3690 result
3691 }
3692
3693 pub fn call_function(
3694 &mut self,
3695 func: &Function,
3696 args: Vec<Value>,
3697 ) -> Result<Value, RuntimeError> {
3698 if func.name.as_ref().map_or(false, |n| n.contains("read_source") || n.contains("parse_file") || n.contains("load_from_file") || n.contains("read_to_string")) {
3700 crate::sigil_debug!("DEBUG call_function: name={:?}, params={:?}", func.name, func.params);
3701 for (i, arg) in args.iter().enumerate() {
3702 crate::sigil_debug!(" arg[{}] = {:?}", i, arg);
3703 }
3704 }
3705 if args.len() != func.params.len() {
3706 return Err(RuntimeError::new(format!(
3707 "Expected {} arguments, got {} (func={:?}, params={:?})",
3708 func.params.len(),
3709 args.len(),
3710 func.name,
3711 func.params
3712 )));
3713 }
3714
3715 if func.params.iter().any(|p| p == "name") {
3717 for arg in &args {
3718 let unwrapped = Self::unwrap_all(arg);
3719 if let Value::String(s) = &unwrapped {
3720 if s.len() <= 10 {
3721 crate::sigil_debug!("DEBUG call_function(name='{}')", s);
3722 }
3723 }
3724 }
3725 }
3726
3727 let env = Rc::new(RefCell::new(Environment::with_parent(func.closure.clone())));
3729
3730 for (param, value) in func.params.iter().zip(args) {
3732 if param == "path" {
3734 crate::sigil_debug!("DEBUG call_function func={:?} binding param 'path' = {:?}", func.name, value);
3735 }
3736 env.borrow_mut().define(param.clone(), value);
3737 }
3738
3739 let prev_env = self.environment.clone();
3741 self.environment = env;
3742
3743 let result = match self.evaluate(&func.body) {
3744 Ok(val) => Ok(val),
3745 Err(e) if e.message == "return" => {
3746 Ok(self.return_value.take().unwrap_or(Value::Null))
3748 }
3749 Err(e) => Err(e),
3750 };
3751
3752 self.environment = prev_env;
3753 result
3754 }
3755
3756 fn call_builtin(
3757 &mut self,
3758 builtin: &BuiltInFn,
3759 args: Vec<Value>,
3760 ) -> Result<Value, RuntimeError> {
3761 if let Some(arity) = builtin.arity {
3762 if args.len() != arity {
3763 return Err(RuntimeError::new(format!(
3764 "{}() expects {} arguments, got {}",
3765 builtin.name,
3766 arity,
3767 args.len()
3768 )));
3769 }
3770 }
3771 (builtin.func)(self, args)
3772 }
3773
3774 pub fn await_value(&mut self, value: Value) -> Result<Value, RuntimeError> {
3776 match value {
3777 Value::Future(fut) => {
3778 let mut fut_inner = fut.borrow_mut();
3779 self.poll_future(&mut fut_inner)
3780 }
3781 other => Ok(other),
3783 }
3784 }
3785
3786 fn unwrap_result_or_option(
3790 &self,
3791 value: Value,
3792 propagate_errors: bool,
3793 panic_on_error: bool,
3794 ) -> Result<Value, RuntimeError> {
3795 let (is_ok_or_some, is_err, is_none, inner_val) = match &value {
3797 Value::Struct { name, fields } if name == "Ok" || name == "Some" => {
3798 let borrowed = fields.borrow();
3799 let inner = borrowed.get("0").or(borrowed.get("value")).cloned();
3800 (true, false, false, inner)
3801 }
3802 Value::Struct { name, fields } if name == "Err" => {
3803 let borrowed = fields.borrow();
3804 let inner = borrowed.get("0").or(borrowed.get("value")).cloned();
3805 (false, true, false, inner)
3806 }
3807 Value::Struct { name, .. } if name == "None" => (false, false, true, None),
3808 _ => return Ok(value),
3809 };
3810
3811 if is_ok_or_some {
3812 Ok(inner_val.unwrap_or(value))
3813 } else if is_err {
3814 let msg = format!("Error: {:?}", inner_val);
3815 if panic_on_error {
3816 panic!("{}", msg);
3817 } else if propagate_errors {
3818 Err(RuntimeError::new(msg))
3819 } else {
3820 Ok(inner_val.unwrap_or(value))
3821 }
3822 } else if is_none {
3823 if panic_on_error {
3824 panic!("Unwrapped None");
3825 } else if propagate_errors {
3826 Err(RuntimeError::new("Unwrapped None".to_string()))
3827 } else {
3828 Ok(value)
3829 }
3830 } else {
3831 Ok(value)
3832 }
3833 }
3834
3835 fn poll_future(&mut self, fut: &mut FutureInner) -> Result<Value, RuntimeError> {
3837 match &fut.state {
3839 FutureState::Ready(v) => return Ok((**v).clone()),
3840 FutureState::Failed(e) => return Err(RuntimeError::new(e.clone())),
3841 _ => {}
3842 }
3843
3844 if let Some(complete_at) = fut.complete_at {
3846 if std::time::Instant::now() >= complete_at {
3847 fut.state = FutureState::Ready(Box::new(Value::Null));
3848 return Ok(Value::Null);
3849 } else {
3850 let remaining = complete_at - std::time::Instant::now();
3852 std::thread::sleep(remaining);
3853 fut.state = FutureState::Ready(Box::new(Value::Null));
3854 return Ok(Value::Null);
3855 }
3856 }
3857
3858 if let Some(computation) = fut.computation.take() {
3860 fut.state = FutureState::Running;
3861
3862 match computation {
3863 FutureComputation::Immediate(v) => {
3864 fut.state = FutureState::Ready(v.clone());
3865 Ok((*v).clone())
3866 }
3867 FutureComputation::Timer(duration) => {
3868 std::thread::sleep(duration);
3870 fut.state = FutureState::Ready(Box::new(Value::Null));
3871 Ok(Value::Null)
3872 }
3873 FutureComputation::Lazy { func, args } => {
3874 match self.call_function(&func, args) {
3876 Ok(result) => {
3877 fut.state = FutureState::Ready(Box::new(result.clone()));
3878 Ok(result)
3879 }
3880 Err(e) => {
3881 fut.state = FutureState::Failed(e.message.clone());
3882 Err(e)
3883 }
3884 }
3885 }
3886 FutureComputation::Join(futures) => {
3887 let mut results = Vec::new();
3889 for f in futures {
3890 let mut f_inner = f.borrow_mut();
3891 results.push(self.poll_future(&mut f_inner)?);
3892 }
3893 let result = Value::Array(Rc::new(RefCell::new(results)));
3894 fut.state = FutureState::Ready(Box::new(result.clone()));
3895 Ok(result)
3896 }
3897 FutureComputation::Race(futures) => {
3898 for f in futures {
3901 let f_inner = f.borrow_mut();
3902 if matches!(f_inner.state, FutureState::Ready(_)) {
3903 if let FutureState::Ready(v) = &f_inner.state {
3904 fut.state = FutureState::Ready(v.clone());
3905 return Ok((**v).clone());
3906 }
3907 }
3908 }
3909 Err(RuntimeError::new("No futures ready in race"))
3911 }
3912 }
3913 } else {
3914 match &fut.state {
3916 FutureState::Ready(v) => Ok((**v).clone()),
3917 FutureState::Failed(e) => Err(RuntimeError::new(e.clone())),
3918 _ => Err(RuntimeError::new("Future has no computation")),
3919 }
3920 }
3921 }
3922
3923 pub fn make_future_immediate(&self, value: Value) -> Value {
3925 Value::Future(Rc::new(RefCell::new(FutureInner {
3926 state: FutureState::Ready(Box::new(value)),
3927 computation: None,
3928 complete_at: None,
3929 })))
3930 }
3931
3932 pub fn make_future_lazy(&self, func: Rc<Function>, args: Vec<Value>) -> Value {
3934 Value::Future(Rc::new(RefCell::new(FutureInner {
3935 state: FutureState::Pending,
3936 computation: Some(FutureComputation::Lazy { func, args }),
3937 complete_at: None,
3938 })))
3939 }
3940
3941 pub fn make_future_timer(&self, duration: std::time::Duration) -> Value {
3943 Value::Future(Rc::new(RefCell::new(FutureInner {
3944 state: FutureState::Pending,
3945 computation: Some(FutureComputation::Timer(duration)),
3946 complete_at: Some(std::time::Instant::now() + duration),
3947 })))
3948 }
3949
3950 fn eval_array(&mut self, elements: &[Expr]) -> Result<Value, RuntimeError> {
3951 let values: Vec<Value> = elements
3952 .iter()
3953 .map(|e| self.evaluate(e))
3954 .collect::<Result<_, _>>()?;
3955 Ok(Value::Array(Rc::new(RefCell::new(values))))
3956 }
3957
3958 fn eval_tuple(&mut self, elements: &[Expr]) -> Result<Value, RuntimeError> {
3959 let values: Vec<Value> = elements
3960 .iter()
3961 .map(|e| self.evaluate(e))
3962 .collect::<Result<_, _>>()?;
3963 Ok(Value::Tuple(Rc::new(values)))
3964 }
3965
3966 fn eval_block(&mut self, block: &Block) -> Result<Value, RuntimeError> {
3967 let env = Rc::new(RefCell::new(Environment::with_parent(
3968 self.environment.clone(),
3969 )));
3970 let prev_env = self.environment.clone();
3971 self.environment = env;
3972
3973 let mut result = Value::Null;
3974
3975 for stmt in &block.stmts {
3976 match stmt {
3977 Stmt::Let { pattern, init, .. } => {
3978 let value = match init {
3979 Some(expr) => self.evaluate(expr)?,
3980 None => Value::Null,
3981 };
3982 self.bind_pattern(pattern, value)?;
3983 }
3984 Stmt::LetElse { pattern, init, else_branch, .. } => {
3985 let value = self.evaluate(init)?;
3986 if self.bind_pattern(pattern, value.clone()).is_err() {
3988 return self.evaluate(else_branch);
3989 }
3990 }
3991 Stmt::Expr(expr) => {
3992 result = self.evaluate(expr)?;
3993 }
3994 Stmt::Semi(expr) => {
3995 self.evaluate(expr)?;
3996 result = Value::Null;
3997 }
3998 Stmt::Item(item) => {
3999 self.execute_item(item)?;
4000 }
4001 }
4002 }
4003
4004 if let Some(expr) = &block.expr {
4005 result = self.evaluate(expr)?;
4006 }
4007
4008 let values_to_drop: Vec<(String, Value)> = self.environment
4011 .borrow()
4012 .values
4013 .iter()
4014 .filter_map(|(name, value)| {
4015 if let Value::Struct { name: struct_name, .. } = value {
4016 if self.drop_types.contains(struct_name) {
4017 return Some((name.clone(), value.clone()));
4018 }
4019 }
4020 None
4021 })
4022 .collect();
4023
4024 for (_var_name, value) in values_to_drop {
4026 if let Value::Struct { name: struct_name, .. } = &value {
4027 let drop_fn_name = format!("{}·drop", struct_name);
4028 let drop_fn = self.globals.borrow().get(&drop_fn_name).map(|v| v.clone());
4030 if let Some(Value::Function(f)) = drop_fn {
4031 let _ = self.call_function(&f, vec![value.clone()]);
4033 }
4034 }
4035 }
4036
4037 self.environment = prev_env;
4038 Ok(result)
4039 }
4040
4041 fn bind_pattern(&mut self, pattern: &Pattern, value: Value) -> Result<(), RuntimeError> {
4042 match pattern {
4043 Pattern::Ident { name, .. } => {
4044 if name.name != "_" {
4046 if name.name == "path" {
4048 crate::sigil_debug!("DEBUG bind_pattern: binding 'path' = {:?}", value);
4049 }
4050 self.environment
4051 .borrow_mut()
4052 .define(name.name.clone(), value);
4053 }
4054 Ok(())
4055 }
4056 Pattern::Tuple(patterns) => {
4057 let unwrapped = Self::unwrap_all(&value);
4059 crate::sigil_debug!("DEBUG bind_pattern Tuple: patterns.len()={}, value type={:?}",
4060 patterns.len(), std::mem::discriminant(&unwrapped));
4061 match unwrapped {
4062 Value::Tuple(values) => {
4063 if patterns.len() != values.len() {
4064 return Err(RuntimeError::new("Tuple pattern size mismatch"));
4065 }
4066 for (i, (p, v)) in patterns.iter().zip(values.iter()).enumerate() {
4067 crate::sigil_debug!("DEBUG binding tuple element {}: {:?} = {}", i, p, self.format_value(v));
4068 self.bind_pattern(p, v.clone())?;
4069 }
4070 Ok(())
4071 }
4072 Value::Null => {
4073 Ok(())
4075 }
4076 Value::Array(arr) if arr.borrow().len() == patterns.len() => {
4077 let vals = arr.borrow();
4079 for (p, v) in patterns.iter().zip(vals.iter()) {
4080 self.bind_pattern(p, v.clone())?;
4081 }
4082 Ok(())
4083 }
4084 _ => Err(RuntimeError::new("Expected tuple"))
4085 }
4086 }
4087 Pattern::Wildcard => Ok(()),
4088 Pattern::Struct { path, fields, .. } => {
4089 let unwrapped = Self::unwrap_all(&value);
4091 match &unwrapped {
4093 Value::Struct { fields: struct_fields, .. } => {
4094 for field_pat in fields {
4095 let field_name = &field_pat.name.name;
4096 let field_val = struct_fields.borrow().get(field_name).cloned().unwrap_or(Value::Null);
4098 if let Some(pat) = &field_pat.pattern {
4099 self.bind_pattern(pat, field_val)?;
4100 } else {
4101 self.environment.borrow_mut().define(field_name.clone(), field_val);
4103 }
4104 }
4105 Ok(())
4106 }
4107 Value::Variant { enum_name, variant_name, fields: variant_fields } => {
4108 let pattern_variant = path.segments.last().map(|s| s.ident.name.as_str()).unwrap_or("");
4110 if pattern_variant == variant_name || path.segments.iter().any(|s| s.ident.name == *variant_name) {
4111 if let Some(inner_fields) = variant_fields {
4114 if inner_fields.len() == 1 {
4115 if let Value::Struct { fields: inner_struct, .. } = &inner_fields[0] {
4117 for field_pat in fields {
4118 let field_name = &field_pat.name.name;
4119 let field_val = inner_struct.borrow().get(field_name).cloned().unwrap_or(Value::Null);
4121 if let Some(pat) = &field_pat.pattern {
4122 self.bind_pattern(pat, field_val)?;
4123 } else {
4124 self.environment.borrow_mut().define(field_name.clone(), field_val);
4125 }
4126 }
4127 return Ok(());
4128 }
4129 }
4130 for field_pat in fields {
4133 let field_name = &field_pat.name.name;
4134 let field_val = inner_fields.iter().find_map(|f| {
4138 if let Value::Struct { fields: fs, .. } = f {
4139 fs.borrow().get(field_name).cloned()
4140 } else {
4141 None
4142 }
4143 });
4144 if let Some(val) = field_val {
4145 if let Some(pat) = &field_pat.pattern {
4146 self.bind_pattern(pat, val)?;
4147 } else {
4148 self.environment.borrow_mut().define(field_name.clone(), val);
4149 }
4150 }
4151 }
4152 }
4153 Ok(())
4154 } else {
4155 crate::sigil_debug!("DEBUG variant name mismatch: pattern={}, actual={}", pattern_variant, variant_name);
4156 Err(RuntimeError::new(format!(
4157 "Variant name mismatch: expected {} but got {}::{}",
4158 pattern_variant, enum_name, variant_name
4159 )))
4160 }
4161 }
4162 _ => {
4163 crate::sigil_debug!("DEBUG struct pattern bind: expected struct/variant but got {:?}", std::mem::discriminant(&unwrapped));
4164 Err(RuntimeError::new("Expected struct or variant value for struct pattern"))
4165 }
4166 }
4167 }
4168 Pattern::Path(_path) => {
4169 Ok(())
4172 }
4173 Pattern::TupleStruct { path, fields } => {
4174 let unwrapped = Self::unwrap_all(&value);
4177 let path_str = path.segments.iter().map(|s| s.ident.name.as_str()).collect::<Vec<_>>().join("::");
4178 crate::sigil_debug!("DEBUG bind_pattern TupleStruct: path={}, value type={:?}",
4179 path_str,
4180 std::mem::discriminant(&unwrapped));
4181 if let Value::Variant { variant_name, fields: variant_fields, enum_name } = &unwrapped {
4182 crate::sigil_debug!("DEBUG Variant {}::{}, fields={}", enum_name, variant_name,
4183 if variant_fields.is_some() { format!("Some(len={})", variant_fields.as_ref().unwrap().len()) } else { "None".to_string() });
4184 let pattern_variant = path.segments.last().map(|s| s.ident.name.as_str()).unwrap_or("");
4185 if pattern_variant == variant_name {
4186 if let Some(inner_fields) = variant_fields {
4188 if fields.len() == 1 && inner_fields.len() == 1 {
4189 self.bind_pattern(&fields[0], inner_fields[0].clone())?;
4190 } else {
4191 for (pat, val) in fields.iter().zip(inner_fields.iter()) {
4192 self.bind_pattern(pat, val.clone())?;
4193 }
4194 }
4195 } else if !fields.is_empty() {
4196 crate::sigil_debug!("DEBUG TupleStruct: pattern expects {} fields but variant has none", fields.len());
4198 }
4199 }
4200 Ok(())
4201 } else {
4202 if let Value::Tuple(tuple_vals) = &value {
4204 for (pat, val) in fields.iter().zip(tuple_vals.iter()) {
4205 self.bind_pattern(pat, val.clone())?;
4206 }
4207 Ok(())
4208 } else {
4209 Err(RuntimeError::new("Expected variant or tuple for tuple struct pattern"))
4210 }
4211 }
4212 }
4213 Pattern::Literal(_) => {
4214 Ok(())
4216 }
4217 Pattern::Rest => {
4218 Ok(())
4220 }
4221 Pattern::Range { .. } => {
4222 Ok(())
4224 }
4225 Pattern::Or(patterns) => {
4226 for p in patterns {
4228 if self.pattern_matches(p, &value)? {
4229 return self.bind_pattern(p, value.clone());
4230 }
4231 }
4232 Err(RuntimeError::new("Or pattern didn't match any alternative"))
4234 }
4235 _ => Err(RuntimeError::new(format!("Unsupported pattern: {:?}", pattern))),
4236 }
4237 }
4238
4239 fn eval_if(
4240 &mut self,
4241 condition: &Expr,
4242 then_branch: &Block,
4243 else_branch: &Option<Box<Expr>>,
4244 ) -> Result<Value, RuntimeError> {
4245 let cond = self.evaluate(condition)?;
4246 if self.is_truthy(&cond) {
4247 self.eval_block(then_branch)
4248 } else if let Some(else_expr) = else_branch {
4249 self.evaluate(else_expr)
4250 } else {
4251 Ok(Value::Null)
4252 }
4253 }
4254
4255 fn eval_match(&mut self, expr: &Expr, arms: &[MatchArm]) -> Result<Value, RuntimeError> {
4256 let value = self.evaluate(expr)?;
4257
4258 let unwrapped = Self::unwrap_all(&value);
4260 if let Value::String(s) = &unwrapped {
4261 if s.len() <= 10 {
4262 crate::sigil_debug!("DEBUG eval_match: string='{}', arms={}", s, arms.len());
4263 }
4264 }
4265
4266 for arm in arms {
4267 if self.pattern_matches(&arm.pattern, &value)? {
4268 let env = Rc::new(RefCell::new(Environment::with_parent(
4270 self.environment.clone(),
4271 )));
4272 let prev_env = self.environment.clone();
4273 self.environment = env;
4274
4275 if let Err(e) = self.bind_pattern(&arm.pattern, value.clone()) {
4278 self.environment = prev_env;
4279 return Err(e);
4280 }
4281
4282 if let Some(guard) = &arm.guard {
4284 let guard_val = self.evaluate(guard)?;
4285 if !self.is_truthy(&guard_val) {
4286 self.environment = prev_env;
4288 continue;
4289 }
4290 }
4291
4292 let result = self.evaluate(&arm.body);
4294
4295 self.environment = prev_env;
4296 return result;
4297 }
4298 }
4299
4300 crate::sigil_debug!("DEBUG No matching pattern for value: {} (discriminant: {:?})",
4302 self.format_value(&value), std::mem::discriminant(&value));
4303 for (i, arm) in arms.iter().enumerate() {
4305 crate::sigil_debug!("DEBUG arm {}: {:?}", i, arm.pattern);
4306 }
4307 Err(RuntimeError::new(format!("No matching pattern for {}", self.format_value(&value))))
4308 }
4309
4310 fn pattern_matches(&mut self, pattern: &Pattern, value: &Value) -> Result<bool, RuntimeError> {
4311 let value = Self::unwrap_all(value);
4313
4314 if let Value::String(s) = &value {
4316 if **s == "fn" {
4317 crate::sigil_debug!("DEBUG pattern_matches: value='fn', pattern={:?}", pattern);
4318 }
4319 }
4320
4321 match (pattern, &value) {
4322 (Pattern::Wildcard, _) => Ok(true),
4323 (Pattern::Ident { evidentiality: Some(Evidentiality::Uncertain), name, .. }, val) => {
4325 let matches = match val {
4327 Value::Null => false,
4328 Value::Variant { variant_name, .. } if variant_name == "None" => false,
4329 _ => true,
4330 };
4331 crate::sigil_debug!("DEBUG pattern_matches ?{}: value={} => {}", name.name, self.format_value(val), matches);
4332 Ok(matches)
4333 }
4334 (Pattern::Ident { .. }, _) => Ok(true),
4335 (Pattern::Literal(lit), val) => {
4336 let lit_val = self.eval_literal(lit)?;
4337 let result = self.values_equal(&lit_val, val);
4338 if matches!(lit, Literal::Null) || matches!(val, Value::Null) {
4340 crate::sigil_debug!("DEBUG literal pattern: lit={:?}, lit_val={}, val={}, result={}",
4341 lit, self.format_value(&lit_val), self.format_value(val), result);
4342 }
4343 Ok(result)
4344 }
4345 (Pattern::Tuple(patterns), Value::Tuple(values)) => {
4346 if patterns.len() != values.len() {
4347 return Ok(false);
4348 }
4349 for (p, v) in patterns.iter().zip(values.iter()) {
4350 if !self.pattern_matches(p, v)? {
4351 return Ok(false);
4352 }
4353 }
4354 Ok(true)
4355 }
4356 (Pattern::Path(path), Value::Variant { variant_name, fields, .. }) => {
4358 let pattern_variant = path.segments.last().map(|s| s.ident.name.as_str()).unwrap_or("");
4359 Ok(pattern_variant == variant_name && fields.is_none())
4361 }
4362 (Pattern::TupleStruct { path, fields: pat_fields }, Value::Variant { variant_name, fields, .. }) => {
4364 let pattern_variant = path.segments.last().map(|s| s.ident.name.as_str()).unwrap_or("");
4365 if pattern_variant != variant_name {
4366 return Ok(false);
4367 }
4368 if let Some(variant_fields) = fields {
4370 if pat_fields.len() != variant_fields.len() {
4371 return Ok(false);
4372 }
4373 for (p, v) in pat_fields.iter().zip(variant_fields.iter()) {
4374 if !self.pattern_matches(p, v)? {
4375 return Ok(false);
4376 }
4377 }
4378 Ok(true)
4379 } else {
4380 Ok(pat_fields.is_empty())
4382 }
4383 }
4384 (Pattern::Struct { path, fields: pat_fields, rest }, Value::Struct { name: struct_name, fields: struct_fields }) => {
4386 let pattern_name = path.segments.iter().map(|s| s.ident.name.as_str()).collect::<Vec<_>>().join("::");
4387 if pattern_name != *struct_name {
4388 return Ok(false);
4389 }
4390 let borrowed = struct_fields.borrow();
4392 for field_pat in pat_fields {
4393 let field_name = &field_pat.name.name;
4394 if let Some(field_val) = borrowed.get(field_name) {
4395 if let Some(sub_pat) = &field_pat.pattern {
4396 if !self.pattern_matches(sub_pat, field_val)? {
4397 return Ok(false);
4398 }
4399 }
4400 } else if !rest {
4402 return Ok(false);
4404 }
4405 }
4406 Ok(true)
4407 }
4408 (Pattern::Struct { path, fields: pat_fields, rest }, Value::Variant { variant_name, fields: variant_fields, .. }) => {
4410 let pattern_variant = path.segments.last().map(|s| s.ident.name.as_str()).unwrap_or("");
4411 if pattern_variant != variant_name {
4412 return Ok(false);
4413 }
4414 if let Some(inner_fields) = variant_fields {
4416 if inner_fields.len() == 1 {
4417 if let Value::Struct { fields: inner_struct, .. } = &inner_fields[0] {
4418 let borrowed = inner_struct.borrow();
4419 for field_pat in pat_fields {
4420 let field_name = &field_pat.name.name;
4421 if let Some(field_val) = borrowed.get(field_name) {
4422 if let Some(sub_pat) = &field_pat.pattern {
4423 if !self.pattern_matches(sub_pat, field_val)? {
4424 return Ok(false);
4425 }
4426 }
4427 } else if !rest {
4428 return Ok(false);
4429 }
4430 }
4431 return Ok(true);
4432 }
4433 }
4434 }
4435 Ok(pat_fields.is_empty() || *rest)
4437 }
4438 (Pattern::Or(patterns), val) => {
4440 for p in patterns {
4441 if self.pattern_matches(p, val)? {
4442 return Ok(true);
4443 }
4444 }
4445 Ok(false)
4446 }
4447 (Pattern::Rest, _) => Ok(true),
4449 (Pattern::Range { start, end, inclusive }, val) => {
4451 let extract_char = |pat: &Option<Box<Pattern>>| -> Option<char> {
4453 match pat {
4454 Some(p) => match p.as_ref() {
4455 Pattern::Literal(Literal::Char(c)) => Some(*c),
4456 _ => None,
4457 },
4458 None => None,
4459 }
4460 };
4461 let extract_int = |pat: &Option<Box<Pattern>>| -> Option<i64> {
4463 match pat {
4464 Some(p) => match p.as_ref() {
4465 Pattern::Literal(Literal::Int { value, .. }) => value.parse().ok(),
4466 _ => None,
4467 },
4468 None => None,
4469 }
4470 };
4471
4472 match val {
4473 Value::Char(c) => {
4474 let start_val = extract_char(start);
4475 let end_val = extract_char(end);
4476 let in_range = match (start_val, end_val, *inclusive) {
4477 (Some(s), Some(e), true) => *c >= s && *c <= e,
4478 (Some(s), Some(e), false) => *c >= s && *c < e,
4479 (Some(s), None, _) => *c >= s,
4480 (None, Some(e), true) => *c <= e,
4481 (None, Some(e), false) => *c < e,
4482 (None, None, _) => true,
4483 };
4484 Ok(in_range)
4485 }
4486 Value::Int(i) => {
4487 let start_val = extract_int(start);
4488 let end_val = extract_int(end);
4489 let in_range = match (start_val, end_val, *inclusive) {
4490 (Some(s), Some(e), true) => *i >= s && *i <= e,
4491 (Some(s), Some(e), false) => *i >= s && *i < e,
4492 (Some(s), None, _) => *i >= s,
4493 (None, Some(e), true) => *i <= e,
4494 (None, Some(e), false) => *i < e,
4495 (None, None, _) => true,
4496 };
4497 Ok(in_range)
4498 }
4499 _ => Ok(false),
4500 }
4501 }
4502 (Pattern::Literal(Literal::String(s)), Value::String(vs)) => {
4504 Ok(s == vs.as_str())
4505 }
4506 (Pattern::Literal(Literal::Char(c)), Value::Char(vc)) => {
4507 Ok(c == vc)
4508 }
4509 _ => Ok(false),
4510 }
4511 }
4512
4513 fn values_equal(&self, a: &Value, b: &Value) -> bool {
4514 let a_unwrapped = match a {
4516 Value::Ref(r) => r.borrow().clone(),
4517 _ => a.clone(),
4518 };
4519 let b_unwrapped = match b {
4520 Value::Ref(r) => r.borrow().clone(),
4521 _ => b.clone(),
4522 };
4523 match (&a_unwrapped, &b_unwrapped) {
4524 (Value::Null, Value::Null) => true,
4525 (Value::Bool(a), Value::Bool(b)) => a == b,
4526 (Value::Int(a), Value::Int(b)) => a == b,
4527 (Value::Float(a), Value::Float(b)) => (a - b).abs() < f64::EPSILON,
4528 (Value::String(a), Value::String(b)) => {
4529 let result = **a == **b;
4530 if a.len() <= 5 && b.len() <= 5 {
4532 crate::sigil_debug!("DEBUG values_equal: '{}' == '{}' -> {}", a, b, result);
4533 }
4534 result
4535 }
4536 (Value::Char(a), Value::Char(b)) => a == b,
4537 _ => false,
4538 }
4539 }
4540
4541 fn eval_for(
4542 &mut self,
4543 pattern: &Pattern,
4544 iter: &Expr,
4545 body: &Block,
4546 ) -> Result<Value, RuntimeError> {
4547 let iterable_raw = self.evaluate(iter)?;
4548 let iterable = Self::unwrap_all(&iterable_raw);
4549 let items = match iterable {
4550 Value::Array(arr) => arr.borrow().clone(),
4551 Value::Tuple(t) => (*t).clone(),
4552 Value::String(s) => s.chars().map(Value::Char).collect(),
4553 Value::Map(m) => {
4554 m.borrow()
4556 .iter()
4557 .map(|(k, v)| {
4558 Value::Tuple(Rc::new(vec![
4559 Value::String(Rc::new(k.clone())),
4560 v.clone(),
4561 ]))
4562 })
4563 .collect()
4564 }
4565 Value::Variant { fields: Some(f), .. } => (*f).clone(),
4566 _ => return Err(RuntimeError::new(format!("Cannot iterate over non-iterable: {:?}", iterable_raw))),
4567 };
4568
4569 let mut result = Value::Null;
4570 for item in items {
4571 let env = Rc::new(RefCell::new(Environment::with_parent(
4572 self.environment.clone(),
4573 )));
4574 let prev_env = self.environment.clone();
4575 self.environment = env;
4576
4577 self.bind_pattern(pattern, item)?;
4578
4579 match self.eval_block(body) {
4580 Ok(val) => result = val,
4581 Err(e) if e.message == "break" => {
4582 self.environment = prev_env;
4583 break;
4584 }
4585 Err(e) if e.message == "continue" => {
4586 self.environment = prev_env;
4587 continue;
4588 }
4589 Err(e) => {
4590 self.environment = prev_env;
4591 return Err(e);
4592 }
4593 }
4594
4595 self.environment = prev_env;
4596 }
4597
4598 Ok(result)
4599 }
4600
4601 fn eval_while(&mut self, condition: &Expr, body: &Block) -> Result<Value, RuntimeError> {
4602 let mut result = Value::Null;
4603 loop {
4604 let cond = self.evaluate(condition)?;
4605 if !self.is_truthy(&cond) {
4606 break;
4607 }
4608
4609 match self.eval_block(body) {
4610 Ok(val) => result = val,
4611 Err(e) if e.message == "break" => break,
4612 Err(e) if e.message == "continue" => continue,
4613 Err(e) => return Err(e),
4614 }
4615 }
4616 Ok(result)
4617 }
4618
4619 fn eval_loop(&mut self, body: &Block) -> Result<Value, RuntimeError> {
4620 loop {
4621 match self.eval_block(body) {
4622 Ok(_) => {}
4623 Err(e) if e.message == "break" => break,
4624 Err(e) if e.message == "continue" => continue,
4625 Err(e) => return Err(e),
4626 }
4627 }
4628 Ok(Value::Null)
4629 }
4630
4631 fn eval_return(&mut self, value: &Option<Box<Expr>>) -> Result<Value, RuntimeError> {
4632 let val = match value {
4633 Some(expr) => self.evaluate(expr)?,
4634 None => Value::Null,
4635 };
4636 self.return_value = Some(val);
4638 Err(RuntimeError::new("return"))
4639 }
4640
4641 fn eval_break(&mut self, _value: &Option<Box<Expr>>) -> Result<Value, RuntimeError> {
4642 Err(RuntimeError::new("break"))
4644 }
4645
4646 fn eval_index(&mut self, expr: &Expr, index: &Expr) -> Result<Value, RuntimeError> {
4647 let collection = self.evaluate(expr)?;
4648
4649 let collection = match collection {
4651 Value::Ref(r) => r.borrow().clone(),
4652 other => other,
4653 };
4654
4655 if let Expr::Range { start, end, inclusive } = index {
4657 let start_val = match start {
4658 Some(e) => match self.evaluate(e)? {
4659 Value::Int(n) => n as usize,
4660 _ => return Err(RuntimeError::new("Slice start must be an integer")),
4661 },
4662 None => 0,
4663 };
4664
4665 return match &collection {
4666 Value::Array(arr) => {
4667 let arr = arr.borrow();
4668 let len = arr.len();
4669 let end_val = match end {
4670 Some(e) => match self.evaluate(e)? {
4671 Value::Int(n) => {
4672 let n = n as usize;
4673 if *inclusive { n + 1 } else { n }
4674 },
4675 _ => return Err(RuntimeError::new("Slice end must be an integer")),
4676 },
4677 None => len, };
4679 let end_val = end_val.min(len);
4680 let start_val = start_val.min(len);
4681 let sliced: Vec<Value> = arr[start_val..end_val].to_vec();
4682 Ok(Value::Array(Rc::new(RefCell::new(sliced))))
4683 }
4684 Value::String(s) => {
4685 let len = s.len();
4686 let end_val = match end {
4687 Some(e) => match self.evaluate(e)? {
4688 Value::Int(n) => {
4689 let n = n as usize;
4690 if *inclusive { n + 1 } else { n }
4691 },
4692 _ => return Err(RuntimeError::new("Slice end must be an integer")),
4693 },
4694 None => len, };
4696 let end_val = end_val.min(len);
4697 let start_val = start_val.min(len);
4698 let sliced = &s[start_val..end_val];
4700 Ok(Value::String(Rc::new(sliced.to_string())))
4701 }
4702 _ => Err(RuntimeError::new("Cannot slice this type")),
4703 };
4704 }
4705
4706 let idx = self.evaluate(index)?;
4707
4708 match (collection, idx) {
4709 (Value::Array(arr), Value::Int(i)) => {
4710 let arr = arr.borrow();
4711 let i = if i < 0 { arr.len() as i64 + i } else { i } as usize;
4712 let result = arr.get(i)
4713 .cloned()
4714 .ok_or_else(|| RuntimeError::new("Index out of bounds"));
4715 if let Ok(ref v) = result {
4716 crate::sigil_debug!("DEBUG eval_index: arr[{}] = {:?}", i, std::mem::discriminant(v));
4717 }
4718 result
4719 }
4720 (Value::Tuple(t), Value::Int(i)) => {
4721 let i = if i < 0 { t.len() as i64 + i } else { i } as usize;
4722 t.get(i)
4723 .cloned()
4724 .ok_or_else(|| RuntimeError::new("Index out of bounds"))
4725 }
4726 (Value::String(s), Value::Int(i)) => {
4727 let i = if i < 0 { s.len() as i64 + i } else { i } as usize;
4728 s.chars()
4729 .nth(i)
4730 .map(Value::Char)
4731 .ok_or_else(|| RuntimeError::new("Index out of bounds"))
4732 }
4733 (Value::Array(arr), Value::Tuple(range_tuple)) if range_tuple.len() == 2 => {
4735 let arr = arr.borrow();
4736 let start = match &range_tuple[0] {
4737 Value::Int(n) => *n as usize,
4738 _ => return Err(RuntimeError::new("Range start must be integer")),
4739 };
4740 let end = match &range_tuple[1] {
4741 Value::Null => arr.len(), Value::Int(n) => *n as usize,
4743 _ => return Err(RuntimeError::new("Range end must be integer or None")),
4744 };
4745 let start = start.min(arr.len());
4746 let end = end.min(arr.len());
4747 let sliced: Vec<Value> = arr[start..end].to_vec();
4748 Ok(Value::Array(Rc::new(RefCell::new(sliced))))
4749 }
4750 (Value::String(s), Value::Tuple(range_tuple)) if range_tuple.len() == 2 => {
4751 let start = match &range_tuple[0] {
4752 Value::Int(n) => *n as usize,
4753 _ => return Err(RuntimeError::new("Range start must be integer")),
4754 };
4755 let end = match &range_tuple[1] {
4756 Value::Null => s.len(), Value::Int(n) => *n as usize,
4758 _ => return Err(RuntimeError::new("Range end must be integer or None")),
4759 };
4760 let start = start.min(s.len());
4761 let end = end.min(s.len());
4762 let sliced = &s[start..end];
4763 Ok(Value::String(Rc::new(sliced.to_string())))
4764 }
4765 (coll, idx) => {
4766 crate::sigil_debug!("DEBUG Cannot index: collection={:?}, index={:?}",
4767 std::mem::discriminant(&coll), std::mem::discriminant(&idx));
4768 Err(RuntimeError::new("Cannot index"))
4769 }
4770 }
4771 }
4772
4773 fn eval_field(&mut self, expr: &Expr, field: &Ident) -> Result<Value, RuntimeError> {
4774 if field.name == "items" {
4775 crate::sigil_debug!("DEBUG eval_field: accessing .items on expr={:?}", expr);
4776 }
4777 if field.name == "evidence" {
4779 crate::sigil_debug!("DEBUG eval_field: accessing .evidence");
4780 }
4781 let value = self.evaluate(expr)?;
4782 if field.name == "items" {
4783 crate::sigil_debug!("DEBUG eval_field: .items receiver value={:?}", std::mem::discriminant(&value));
4784 }
4785 if field.name == "evidence" {
4786 crate::sigil_debug!("DEBUG eval_field: .evidence receiver value type={:?}", std::mem::discriminant(&value));
4787 }
4788 fn get_field(val: &Value, field_name: &str) -> Result<Value, RuntimeError> {
4790 if field_name == "evidence" {
4792 crate::sigil_debug!("DEBUG get_field 'evidence' on value type: {:?}", std::mem::discriminant(val));
4793 }
4794 match val {
4795 Value::Struct { name, fields } => {
4796 let field_val = fields.borrow().get(field_name).cloned();
4797 if field_val.is_none() && field_name == "path" {
4798 crate::sigil_debug!("DEBUG Unknown field 'path': struct={}, available={:?}", name, fields.borrow().keys().collect::<Vec<_>>());
4799 }
4800 if field_name == "evidence" || name.contains("IrPattern") {
4802 crate::sigil_debug!("DEBUG get_field on Struct: name={}, field={}, available={:?}, found={}",
4803 name, field_name, fields.borrow().keys().collect::<Vec<_>>(), field_val.is_some());
4804 }
4805 match field_val {
4807 Some(v) => Ok(v),
4808 None => {
4809 crate::sigil_warn!("WARN: Unknown field '{}' on '{}' - returning null", field_name, name);
4810 Ok(Value::Null)
4811 }
4812 }
4813 }
4814 Value::Tuple(t) => {
4815 let idx: usize = field_name
4817 .parse()
4818 .map_err(|_| RuntimeError::new("Invalid tuple index"))?;
4819 t.get(idx)
4820 .cloned()
4821 .ok_or_else(|| RuntimeError::new("Tuple index out of bounds"))
4822 }
4823 Value::Ref(r) => {
4824 get_field(&r.borrow(), field_name)
4826 }
4827 Value::Evidential { value, .. } => {
4828 get_field(value, field_name)
4830 }
4831 Value::Affective { value, .. } => {
4832 get_field(value, field_name)
4834 }
4835 Value::Variant { fields: variant_fields, .. } => {
4836 if let Some(inner_fields) = variant_fields {
4839 for f in inner_fields.iter() {
4841 if let Value::Struct { fields: struct_fields, .. } = f {
4842 if let Some(field_val) = struct_fields.borrow().get(field_name).cloned() {
4843 return Ok(field_val);
4844 }
4845 }
4846 }
4847 Ok(Value::Null)
4849 } else {
4850 Ok(Value::Null)
4852 }
4853 }
4854 other => {
4855 crate::sigil_warn!("WARN: Cannot access field '{}' on non-struct - returning null", field_name);
4857 Ok(Value::Null)
4858 }
4859 }
4860 }
4861 get_field(&value, &field.name)
4862 }
4863
4864 fn extract_root_var(expr: &Expr) -> Option<String> {
4866 match expr {
4867 Expr::Path(path) if path.segments.len() == 1 => {
4868 Some(path.segments[0].ident.name.clone())
4869 }
4870 Expr::MethodCall { receiver, .. } => {
4871 Self::extract_root_var(receiver)
4872 }
4873 _ => None,
4874 }
4875 }
4876
4877 fn eval_method_call(
4878 &mut self,
4879 receiver: &Expr,
4880 method: &Ident,
4881 args: &[Expr],
4882 ) -> Result<Value, RuntimeError> {
4883 if (method.name == "push" || method.name == "push_str") && args.len() == 1 {
4885 let recv_val = self.evaluate(receiver)?;
4886 let recv_unwrapped = Self::unwrap_all(&recv_val);
4887 if let Value::String(s) = &recv_unwrapped {
4888 let arg = self.evaluate(&args[0])?;
4889 let arg_unwrapped = Self::unwrap_all(&arg);
4890 let new_s = match arg_unwrapped {
4891 Value::Char(c) => {
4892 let mut new_str = (**s).clone();
4893 new_str.push(c);
4894 new_str
4895 }
4896 Value::String(ref add_s) => {
4897 let mut new_str = (**s).clone();
4898 new_str.push_str(add_s);
4899 new_str
4900 }
4901 _ => return Err(RuntimeError::new("push expects char or string argument")),
4902 };
4903 let new_val = Value::String(Rc::new(new_s));
4904
4905 if let Some(root_var) = Self::extract_root_var(receiver) {
4907 self.environment.borrow_mut().set(&root_var, new_val.clone())?;
4908 return Ok(new_val);
4910 }
4911
4912 if let Expr::Field { expr: base_expr, field: field_ident } = receiver {
4914 let base = self.evaluate(base_expr)?;
4915 if let Value::Struct { fields, .. } = base {
4916 fields.borrow_mut().insert(field_ident.name.clone(), new_val.clone());
4917 return Ok(new_val);
4919 }
4920 }
4921 return Ok(new_val);
4923 }
4924 }
4925
4926 let recv_raw = self.evaluate(receiver)?;
4927 let recv = Self::unwrap_value(&recv_raw).clone();
4929
4930 static METHOD_COUNT: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0);
4932 let count = METHOD_COUNT.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
4933 if count < 500 {
4934 let recv_type = match &recv {
4935 Value::Struct { name, .. } => format!("Struct({})", name),
4936 Value::String(s) => format!("String('{}')", if s.len() <= 20 { s.as_str() } else { "<long>" }),
4937 Value::Ref(r) => format!("Ref({:?})", std::mem::discriminant(&*r.borrow())),
4938 other => format!("{:?}", std::mem::discriminant(other)),
4939 };
4940 if recv_type.contains("Lexer") || method.name.contains("keyword") || method.name.contains("lex") {
4941 crate::sigil_debug!("DEBUG method #{}: {}.{}()", count, recv_type, method.name);
4942 }
4943 }
4944 let arg_values: Vec<Value> = args
4945 .iter()
4946 .map(|a| self.evaluate(a))
4947 .collect::<Result<_, _>>()?;
4948
4949 if method.name == "cloned" || method.name == "clone" {
4951 let recv_type = match &recv {
4952 Value::Struct { name, .. } => format!("Struct({})", name),
4953 Value::Variant { enum_name, variant_name, .. } => format!("Variant({}::{})", enum_name, variant_name),
4954 Value::String(_) => "String".to_string(),
4955 Value::Ref(r) => format!("Ref({:?})", std::mem::discriminant(&*r.borrow())),
4956 Value::Null => "Null".to_string(),
4957 other => format!("{:?}", std::mem::discriminant(other)),
4958 };
4959 crate::sigil_debug!("DEBUG {}: recv_type={}", method.name, recv_type);
4960 }
4961
4962 if method.name == "as_str" {
4964 let recv_unwrapped = Self::unwrap_all(&recv);
4965 if let Value::String(s) = &recv_unwrapped {
4966 crate::sigil_debug!("DEBUG as_str CALL: recv='{}' len={}", s, s.len());
4967 } else {
4968 crate::sigil_debug!("DEBUG as_str CALL: recv={:?} (not string)", recv_unwrapped);
4969 }
4970 }
4971
4972 if method.name == "keyword_or_ident" {
4974 let recv_type = match &recv {
4975 Value::Struct { name, .. } => format!("Struct({})", name),
4976 Value::String(_) => "String".to_string(),
4977 Value::Ref(r) => format!("Ref({})", match &*r.borrow() {
4978 Value::Struct { name, .. } => format!("Struct({})", name),
4979 other => format!("{:?}", std::mem::discriminant(other)),
4980 }),
4981 other => format!("{:?}", std::mem::discriminant(other)),
4982 };
4983 crate::sigil_debug!("DEBUG keyword_or_ident: recv_type={}", recv_type);
4984 }
4985
4986 for arg in &arg_values {
4988 let unwrapped = Self::unwrap_all(arg);
4989 if let Value::String(s) = &unwrapped {
4990 if **s == "fn" {
4991 let recv_type = match &recv {
4992 Value::Struct { name, .. } => format!("Struct({})", name),
4993 Value::String(_) => "String".to_string(),
4994 Value::Ref(_) => "Ref".to_string(),
4995 other => format!("{:?}", std::mem::discriminant(other)),
4996 };
4997 crate::sigil_debug!("DEBUG method call with 'fn': method={}, recv_type={}", method.name, recv_type);
4998 }
4999 }
5000 }
5001
5002 match (&recv, method.name.as_str()) {
5004 (Value::Array(arr), "len") => Ok(Value::Int(arr.borrow().len() as i64)),
5005 (Value::Array(arr), "push") => {
5006 if arg_values.len() != 1 {
5007 return Err(RuntimeError::new("push expects 1 argument"));
5008 }
5009 arr.borrow_mut().push(arg_values[0].clone());
5010 Ok(Value::Null)
5011 }
5012 (Value::Array(arr), "pop") => arr
5013 .borrow_mut()
5014 .pop()
5015 .ok_or_else(|| RuntimeError::new("pop on empty array")),
5016 (Value::Array(arr), "extend") => {
5017 if arg_values.len() != 1 {
5018 return Err(RuntimeError::new("extend expects 1 argument"));
5019 }
5020 match &arg_values[0] {
5021 Value::Array(other) => {
5022 arr.borrow_mut().extend(other.borrow().iter().cloned());
5023 Ok(Value::Null)
5024 }
5025 _ => Err(RuntimeError::new("extend expects array argument")),
5026 }
5027 }
5028 (Value::Array(arr), "reverse") => {
5029 let mut v = arr.borrow().clone();
5030 v.reverse();
5031 Ok(Value::Array(Rc::new(RefCell::new(v))))
5032 }
5033 (Value::Array(arr), "skip") => {
5034 let n = match arg_values.first() {
5035 Some(Value::Int(i)) => *i as usize,
5036 _ => 1,
5037 };
5038 let v: Vec<Value> = arr.borrow().iter().skip(n).cloned().collect();
5039 Ok(Value::Array(Rc::new(RefCell::new(v))))
5040 }
5041 (Value::Array(arr), "take") => {
5042 let n = match arg_values.first() {
5043 Some(Value::Int(i)) => *i as usize,
5044 _ => 1,
5045 };
5046 let v: Vec<Value> = arr.borrow().iter().take(n).cloned().collect();
5047 Ok(Value::Array(Rc::new(RefCell::new(v))))
5048 }
5049 (Value::Array(arr), "step_by") => {
5050 let n = match arg_values.first() {
5051 Some(Value::Int(i)) if *i > 0 => *i as usize,
5052 _ => 1,
5053 };
5054 let v: Vec<Value> = arr.borrow().iter().step_by(n).cloned().collect();
5055 Ok(Value::Array(Rc::new(RefCell::new(v))))
5056 }
5057 (Value::Array(arr), "contains") => {
5058 if arg_values.len() != 1 {
5059 return Err(RuntimeError::new("contains expects 1 argument"));
5060 }
5061 let target = &arg_values[0];
5062 let found = arr.borrow().iter().any(|v| self.values_equal(v, target));
5063 Ok(Value::Bool(found))
5064 }
5065 (Value::Tuple(t), "to_string") | (Value::Tuple(t), "string") => {
5067 let s: Vec<String> = t.iter().map(|v| format!("{}", v)).collect();
5068 Ok(Value::String(Rc::new(format!("({})", s.join(", ")))))
5069 }
5070 (Value::Tuple(t), "len") => Ok(Value::Int(t.len() as i64)),
5071 (Value::Tuple(t), "first") => t.first().cloned().ok_or_else(|| RuntimeError::new("empty tuple")),
5072 (Value::Tuple(t), "last") => t.last().cloned().ok_or_else(|| RuntimeError::new("empty tuple")),
5073 (Value::Tuple(t), "get") => {
5074 let idx = match arg_values.first() {
5075 Some(Value::Int(i)) => *i as usize,
5076 _ => return Err(RuntimeError::new("get expects integer index")),
5077 };
5078 t.get(idx).cloned().ok_or_else(|| RuntimeError::new("tuple index out of bounds"))
5079 }
5080 (Value::Array(arr), "first") | (Value::Array(arr), "next") => Ok(arr
5081 .borrow()
5082 .first()
5083 .cloned()
5084 .unwrap_or(Value::Null)),
5085 (Value::Array(arr), "last") => arr
5086 .borrow()
5087 .last()
5088 .cloned()
5089 .ok_or_else(|| RuntimeError::new("empty array")),
5090 (Value::Array(arr), "iter") | (Value::Array(arr), "into_iter") => {
5091 Ok(Value::Array(arr.clone()))
5093 }
5094 (Value::Array(arr), "map") => {
5095 if arg_values.len() != 1 {
5097 return Err(RuntimeError::new("map expects 1 argument (closure)"));
5098 }
5099 match &arg_values[0] {
5100 Value::Function(f) => {
5101 let mut results = Vec::new();
5102 for val in arr.borrow().iter() {
5103 let result = self.call_function(f, vec![val.clone()])?;
5104 results.push(result);
5105 }
5106 Ok(Value::Array(Rc::new(RefCell::new(results))))
5107 }
5108 _ => Err(RuntimeError::new("map expects closure argument")),
5109 }
5110 }
5111 (Value::Array(arr), "filter") => {
5112 if arg_values.len() != 1 {
5114 return Err(RuntimeError::new("filter expects 1 argument (closure)"));
5115 }
5116 match &arg_values[0] {
5117 Value::Function(f) => {
5118 let mut results = Vec::new();
5119 for val in arr.borrow().iter() {
5120 let keep = self.call_function(f, vec![val.clone()])?;
5121 if matches!(keep, Value::Bool(true)) {
5122 results.push(val.clone());
5123 }
5124 }
5125 Ok(Value::Array(Rc::new(RefCell::new(results))))
5126 }
5127 _ => Err(RuntimeError::new("filter expects closure argument")),
5128 }
5129 }
5130 (Value::Array(arr), "any") => {
5131 if arg_values.len() != 1 {
5133 return Err(RuntimeError::new("any expects 1 argument (closure)"));
5134 }
5135 match &arg_values[0] {
5136 Value::Function(f) => {
5137 for val in arr.borrow().iter() {
5138 let result = self.call_function(f, vec![val.clone()])?;
5139 if matches!(result, Value::Bool(true)) {
5140 return Ok(Value::Bool(true));
5141 }
5142 }
5143 Ok(Value::Bool(false))
5144 }
5145 _ => Err(RuntimeError::new("any expects closure argument")),
5146 }
5147 }
5148 (Value::Array(arr), "all") => {
5149 if arg_values.len() != 1 {
5151 return Err(RuntimeError::new("all expects 1 argument (closure)"));
5152 }
5153 match &arg_values[0] {
5154 Value::Function(f) => {
5155 for val in arr.borrow().iter() {
5156 let result = self.call_function(f, vec![val.clone()])?;
5157 if !matches!(result, Value::Bool(true)) {
5158 return Ok(Value::Bool(false));
5159 }
5160 }
5161 Ok(Value::Bool(true))
5162 }
5163 _ => Err(RuntimeError::new("all expects closure argument")),
5164 }
5165 }
5166 (Value::Array(arr), "find") => {
5167 if arg_values.len() != 1 {
5169 return Err(RuntimeError::new("find expects 1 argument (closure)"));
5170 }
5171 match &arg_values[0] {
5172 Value::Function(f) => {
5173 for val in arr.borrow().iter() {
5174 let result = self.call_function(f, vec![val.clone()])?;
5175 if matches!(result, Value::Bool(true)) {
5176 return Ok(Value::Variant {
5177 enum_name: "Option".to_string(),
5178 variant_name: "Some".to_string(),
5179 fields: Some(Rc::new(vec![val.clone()])),
5180 });
5181 }
5182 }
5183 Ok(Value::Variant {
5184 enum_name: "Option".to_string(),
5185 variant_name: "None".to_string(),
5186 fields: None,
5187 })
5188 }
5189 _ => Err(RuntimeError::new("find expects closure argument")),
5190 }
5191 }
5192 (Value::Array(arr), "enumerate") => {
5193 let enumerated: Vec<Value> = arr
5195 .borrow()
5196 .iter()
5197 .enumerate()
5198 .map(|(i, v)| Value::Tuple(Rc::new(vec![Value::Int(i as i64), v.clone()])))
5199 .collect();
5200 Ok(Value::Array(Rc::new(RefCell::new(enumerated))))
5201 }
5202 (Value::Array(arr), "zip") => {
5203 if arg_values.len() != 1 {
5205 return Err(RuntimeError::new("zip expects 1 argument"));
5206 }
5207 match &arg_values[0] {
5208 Value::Array(other) => {
5209 let a = arr.borrow();
5210 let b = other.borrow();
5211 let zipped: Vec<Value> = a.iter()
5212 .zip(b.iter())
5213 .map(|(x, y)| Value::Tuple(Rc::new(vec![x.clone(), y.clone()])))
5214 .collect();
5215 Ok(Value::Array(Rc::new(RefCell::new(zipped))))
5216 }
5217 _ => Err(RuntimeError::new("zip expects array argument")),
5218 }
5219 }
5220 (Value::String(s), "len") => Ok(Value::Int(s.len() as i64)),
5221 (Value::String(s), "chars") => {
5222 let chars: Vec<Value> = s.chars().map(Value::Char).collect();
5223 Ok(Value::Array(Rc::new(RefCell::new(chars))))
5224 }
5225 (Value::String(s), "contains") => {
5226 if arg_values.len() != 1 {
5227 return Err(RuntimeError::new("contains expects 1 argument"));
5228 }
5229 match &arg_values[0] {
5230 Value::String(sub) => Ok(Value::Bool(s.contains(sub.as_str()))),
5231 Value::Char(c) => Ok(Value::Bool(s.contains(*c))),
5232 Value::Ref(inner) => {
5233 if let Value::String(sub) = &*inner.borrow() {
5234 Ok(Value::Bool(s.contains(sub.as_str())))
5235 } else {
5236 Err(RuntimeError::new("contains expects string or char"))
5237 }
5238 }
5239 _ => Err(RuntimeError::new("contains expects string or char")),
5240 }
5241 }
5242 (Value::String(s), "as_str") => {
5243 if s.len() <= 10 { crate::sigil_debug!("DEBUG as_str: '{}'", s); }
5244 Ok(Value::String(s.clone()))
5245 }
5246 (Value::String(s), "to_string") => Ok(Value::String(s.clone())),
5247 (Value::String(s), "into") => Ok(Value::String(s.clone())), (Value::String(s), "starts_with") => {
5249 if arg_values.len() != 1 {
5250 return Err(RuntimeError::new("starts_with expects 1 argument"));
5251 }
5252 match &arg_values[0] {
5253 Value::String(prefix) => Ok(Value::Bool(s.starts_with(prefix.as_str()))),
5254 _ => Err(RuntimeError::new("starts_with expects string")),
5255 }
5256 }
5257 (Value::String(s), "ends_with") => {
5258 if arg_values.len() != 1 {
5259 return Err(RuntimeError::new("ends_with expects 1 argument"));
5260 }
5261 match &arg_values[0] {
5262 Value::String(suffix) => Ok(Value::Bool(s.ends_with(suffix.as_str()))),
5263 _ => Err(RuntimeError::new("ends_with expects string")),
5264 }
5265 }
5266 (Value::String(s), "strip_prefix") => {
5267 if arg_values.len() != 1 {
5268 return Err(RuntimeError::new("strip_prefix expects 1 argument"));
5269 }
5270 match &arg_values[0] {
5271 Value::String(prefix) => {
5272 match s.strip_prefix(prefix.as_str()) {
5273 Some(stripped) => Ok(Value::String(Rc::new(stripped.to_string()))),
5274 None => Ok(Value::Null),
5275 }
5276 }
5277 _ => Err(RuntimeError::new("strip_prefix expects string")),
5278 }
5279 }
5280 (Value::String(s), "strip_suffix") => {
5281 if arg_values.len() != 1 {
5282 return Err(RuntimeError::new("strip_suffix expects 1 argument"));
5283 }
5284 match &arg_values[0] {
5285 Value::String(suffix) => {
5286 match s.strip_suffix(suffix.as_str()) {
5287 Some(stripped) => Ok(Value::String(Rc::new(stripped.to_string()))),
5288 None => Ok(Value::Null),
5289 }
5290 }
5291 _ => Err(RuntimeError::new("strip_suffix expects string")),
5292 }
5293 }
5294 (Value::String(s), "is_empty") => Ok(Value::Bool(s.is_empty())),
5295 (Value::String(s), "find") => {
5296 if arg_values.len() != 1 {
5297 return Err(RuntimeError::new("find expects 1 argument"));
5298 }
5299 match &arg_values[0] {
5300 Value::Char(c) => {
5301 match s.find(*c) {
5302 Some(idx) => Ok(Value::Variant {
5303 enum_name: "Option".to_string(),
5304 variant_name: "Some".to_string(),
5305 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
5306 }),
5307 None => Ok(Value::Variant {
5308 enum_name: "Option".to_string(),
5309 variant_name: "None".to_string(),
5310 fields: None,
5311 }),
5312 }
5313 }
5314 Value::String(pattern) => {
5315 match s.find(pattern.as_str()) {
5316 Some(idx) => Ok(Value::Variant {
5317 enum_name: "Option".to_string(),
5318 variant_name: "Some".to_string(),
5319 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
5320 }),
5321 None => Ok(Value::Variant {
5322 enum_name: "Option".to_string(),
5323 variant_name: "None".to_string(),
5324 fields: None,
5325 }),
5326 }
5327 }
5328 Value::Function(f) => {
5329 for (idx, c) in s.chars().enumerate() {
5330 let result = self.call_function(f, vec![Value::Char(c)])?;
5331 if let Value::Bool(true) = result {
5332 return Ok(Value::Variant {
5333 enum_name: "Option".to_string(),
5334 variant_name: "Some".to_string(),
5335 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
5336 });
5337 }
5338 }
5339 Ok(Value::Variant {
5340 enum_name: "Option".to_string(),
5341 variant_name: "None".to_string(),
5342 fields: None,
5343 })
5344 }
5345 _ => Err(RuntimeError::new("find expects a char, string, or closure")),
5346 }
5347 }
5348 (Value::String(s), "clone") => Ok(Value::String(Rc::new((**s).clone()))),
5349 (Value::String(s), "concat") => {
5350 if arg_values.len() != 1 {
5351 return Err(RuntimeError::new("concat expects 1 argument"));
5352 }
5353 match &arg_values[0] {
5354 Value::String(other) => {
5355 let mut result = (**s).clone();
5356 result.push_str(other);
5357 Ok(Value::String(Rc::new(result)))
5358 }
5359 _ => Err(RuntimeError::new("concat expects string argument")),
5360 }
5361 }
5362 (Value::String(s), "as_ptr") => {
5363 Ok(Value::String(s.clone()))
5365 }
5366 (Value::String(_), "is_null") => Ok(Value::Bool(false)),
5367 (Value::Null, "is_null") => Ok(Value::Bool(true)),
5368 (Value::String(s), "char_at") => {
5369 if arg_values.len() != 1 {
5370 return Err(RuntimeError::new("char_at expects 1 argument"));
5371 }
5372 let idx = match &arg_values[0] {
5373 Value::Int(i) => *i as usize,
5374 _ => return Err(RuntimeError::new("char_at expects integer index")),
5375 };
5376 if idx < s.len() {
5379 let remaining = &s[idx..];
5381 match remaining.chars().next() {
5382 Some(c) => Ok(Value::Char(c)),
5383 None => Ok(Value::Null),
5384 }
5385 } else {
5386 Ok(Value::Null) }
5388 }
5389 (Value::String(s), "chars") => {
5390 let chars: Vec<Value> = s.chars().map(Value::Char).collect();
5391 Ok(Value::Array(Rc::new(RefCell::new(chars))))
5392 }
5393 (Value::String(s), "bytes") => {
5394 let bytes: Vec<Value> = s.bytes().map(|b| Value::Int(b as i64)).collect();
5395 Ok(Value::Array(Rc::new(RefCell::new(bytes))))
5396 }
5397 (Value::String(s), "split") => {
5398 if arg_values.len() != 1 {
5399 return Err(RuntimeError::new("split expects 1 argument"));
5400 }
5401 match &arg_values[0] {
5402 Value::String(sep) => {
5403 let parts: Vec<Value> = s.split(sep.as_str())
5404 .map(|p| Value::String(Rc::new(p.to_string())))
5405 .collect();
5406 Ok(Value::Array(Rc::new(RefCell::new(parts))))
5407 }
5408 Value::Char(sep) => {
5409 let parts: Vec<Value> = s.split(*sep)
5410 .map(|p| Value::String(Rc::new(p.to_string())))
5411 .collect();
5412 Ok(Value::Array(Rc::new(RefCell::new(parts))))
5413 }
5414 _ => Err(RuntimeError::new("split expects string or char separator")),
5415 }
5416 }
5417 (Value::Char(c), "len_utf8") => Ok(Value::Int(c.len_utf8() as i64)),
5419 (Value::Char(c), "is_alphabetic") => Ok(Value::Bool(c.is_alphabetic())),
5420 (Value::Char(c), "is_alphanumeric") => Ok(Value::Bool(c.is_alphanumeric())),
5421 (Value::Char(c), "is_ascii_alphanumeric") => Ok(Value::Bool(c.is_ascii_alphanumeric())),
5422 (Value::Char(c), "is_ascii_alphabetic") => Ok(Value::Bool(c.is_ascii_alphabetic())),
5423 (Value::Char(c), "is_ascii_digit") => Ok(Value::Bool(c.is_ascii_digit())),
5424 (Value::Char(c), "is_ascii_hexdigit") => Ok(Value::Bool(c.is_ascii_hexdigit())),
5425 (Value::Char(c), "is_ascii") => Ok(Value::Bool(c.is_ascii())),
5426 (Value::Char(c), "is_digit") => {
5427 let radix = if arg_values.is_empty() { 10 } else {
5428 match &arg_values[0] {
5429 Value::Int(n) => *n as u32,
5430 _ => 10,
5431 }
5432 };
5433 Ok(Value::Bool(c.is_digit(radix)))
5434 }
5435 (Value::Char(c), "is_numeric") => Ok(Value::Bool(c.is_numeric())),
5436 (Value::Char(c), "is_whitespace") => Ok(Value::Bool(c.is_whitespace())),
5437 (Value::Char(c), "is_uppercase") => Ok(Value::Bool(c.is_uppercase())),
5438 (Value::Char(c), "is_lowercase") => Ok(Value::Bool(c.is_lowercase())),
5439 (Value::Char(c), "to_uppercase") => {
5440 let upper: String = c.to_uppercase().collect();
5441 Ok(Value::String(Rc::new(upper)))
5442 }
5443 (Value::Char(c), "to_lowercase") => {
5444 let lower: String = c.to_lowercase().collect();
5445 Ok(Value::String(Rc::new(lower)))
5446 }
5447 (Value::Char(c), "to_string") => Ok(Value::String(Rc::new(c.to_string()))),
5448 (Value::Char(c), "to_digit") => {
5449 let radix = if arg_values.is_empty() { 10 } else {
5450 match &arg_values[0] {
5451 Value::Int(n) => *n as u32,
5452 _ => 10,
5453 }
5454 };
5455 match c.to_digit(radix) {
5456 Some(d) => Ok(Value::Int(d as i64)),
5457 None => Ok(Value::Null),
5458 }
5459 }
5460 (Value::Char(c), "to_ascii_uppercase") => Ok(Value::Char(c.to_ascii_uppercase())),
5461 (Value::Char(c), "to_ascii_lowercase") => Ok(Value::Char(c.to_ascii_lowercase())),
5462 (Value::Char(c), "clone") => Ok(Value::Char(*c)),
5463 (Value::String(s), "upper") | (Value::String(s), "uppercase") | (Value::String(s), "to_uppercase") => {
5464 Ok(Value::String(Rc::new(s.to_uppercase())))
5465 }
5466 (Value::String(s), "lower") | (Value::String(s), "lowercase") | (Value::String(s), "to_lowercase") => {
5467 Ok(Value::String(Rc::new(s.to_lowercase())))
5468 }
5469 (Value::String(s), "trim") => Ok(Value::String(Rc::new(s.trim().to_string()))),
5470 (Value::String(s), "len") => Ok(Value::Int(s.len() as i64)),
5471 (Value::String(s), "is_empty") => Ok(Value::Bool(s.is_empty())),
5472 (Value::String(s), "exists") => Ok(Value::Bool(std::path::Path::new(s.as_str()).exists())),
5474 (Value::String(s), "is_dir") => Ok(Value::Bool(std::path::Path::new(s.as_str()).is_dir())),
5475 (Value::String(s), "is_file") => Ok(Value::Bool(std::path::Path::new(s.as_str()).is_file())),
5476 (Value::String(s), "join") => {
5477 if arg_values.len() != 1 {
5479 return Err(RuntimeError::new(&format!("join expects 1 argument, got {}", arg_values.len())));
5480 }
5481 let other = match &arg_values[0] {
5482 Value::String(s2) => s2.as_str().to_string(),
5483 other => return Err(RuntimeError::new(&format!("join expects String argument, got {:?}", other))),
5484 };
5485 let path = std::path::Path::new(s.as_str()).join(&other);
5486 Ok(Value::String(Rc::new(path.to_string_lossy().to_string())))
5487 }
5488 (Value::String(s), "parent") => {
5489 let path = std::path::Path::new(s.as_str());
5491 match path.parent() {
5492 Some(p) => Ok(Value::String(Rc::new(p.to_string_lossy().to_string()))),
5493 None => Ok(Value::Null),
5494 }
5495 }
5496 (Value::String(s), "file_name") => {
5497 let path = std::path::Path::new(s.as_str());
5499 match path.file_name() {
5500 Some(n) => Ok(Value::String(Rc::new(n.to_string_lossy().to_string()))),
5501 None => Ok(Value::Null),
5502 }
5503 }
5504 (Value::String(s), "extension") => {
5505 let path = std::path::Path::new(s.as_str());
5507 match path.extension() {
5508 Some(e) => Ok(Value::String(Rc::new(e.to_string_lossy().to_string()))),
5509 None => Ok(Value::Null),
5510 }
5511 }
5512 (Value::String(_), "and_then") | (Value::String(_), "or_else") => {
5514 Ok(recv.clone())
5516 }
5517 (Value::String(s), "first") => s
5518 .chars()
5519 .next()
5520 .map(Value::Char)
5521 .ok_or_else(|| RuntimeError::new("empty string")),
5522 (Value::String(s), "last") => s
5523 .chars()
5524 .last()
5525 .map(Value::Char)
5526 .ok_or_else(|| RuntimeError::new("empty string")),
5527 (Value::Array(arr), "is_empty") => Ok(Value::Bool(arr.borrow().is_empty())),
5528 (Value::Array(arr), "clone") => Ok(Value::Array(Rc::new(RefCell::new(arr.borrow().clone())))),
5529 (Value::Array(arr), "collect") => {
5530 Ok(Value::Array(arr.clone()))
5533 }
5534 (Value::Array(arr), "join") => {
5535 let separator = if arg_values.is_empty() {
5536 String::new()
5537 } else {
5538 match &arg_values[0] {
5539 Value::String(s) => (**s).clone(),
5540 _ => return Err(RuntimeError::new("join separator must be string")),
5541 }
5542 };
5543 let parts: Vec<String> = arr.borrow().iter()
5544 .map(|v| self.format_value(v))
5545 .collect();
5546 Ok(Value::String(Rc::new(parts.join(&separator))))
5547 }
5548 (Value::Map(m), "insert") => {
5550 if arg_values.len() != 2 {
5551 return Err(RuntimeError::new("insert expects 2 arguments"));
5552 }
5553 let key = match &arg_values[0] {
5554 Value::String(s) => (**s).clone(),
5555 _ => format!("{}", arg_values[0]),
5556 };
5557 m.borrow_mut().insert(key, arg_values[1].clone());
5558 Ok(Value::Null)
5559 }
5560 (Value::Map(m), "get") => {
5561 if arg_values.len() != 1 {
5562 return Err(RuntimeError::new("get expects 1 argument"));
5563 }
5564 let key = match &arg_values[0] {
5565 Value::String(s) => (**s).clone(),
5566 _ => format!("{}", arg_values[0]),
5567 };
5568 Ok(m.borrow().get(&key).cloned().unwrap_or(Value::Null))
5569 }
5570 (Value::Map(m), "contains_key") => {
5571 if arg_values.len() != 1 {
5572 return Err(RuntimeError::new("contains_key expects 1 argument"));
5573 }
5574 let key = match &arg_values[0] {
5575 Value::String(s) => (**s).clone(),
5576 _ => format!("{}", arg_values[0]),
5577 };
5578 Ok(Value::Bool(m.borrow().contains_key(&key)))
5579 }
5580 (Value::Map(m), "len") => Ok(Value::Int(m.borrow().len() as i64)),
5581 (Value::Map(m), "is_empty") => Ok(Value::Bool(m.borrow().is_empty())),
5582 (Value::Map(m), "keys") => {
5583 let keys: Vec<Value> = m.borrow().keys()
5584 .map(|k| Value::String(Rc::new(k.clone())))
5585 .collect();
5586 Ok(Value::Array(Rc::new(RefCell::new(keys))))
5587 }
5588 (Value::Map(m), "values") => {
5589 let values: Vec<Value> = m.borrow().values().cloned().collect();
5590 Ok(Value::Array(Rc::new(RefCell::new(values))))
5591 }
5592 (Value::RefCellValue(rc), "borrow") => {
5594 let state = rc.borrow_state.borrow().clone();
5596 match state {
5597 BorrowState::BorrowedMut => {
5598 Err(RuntimeError::new("RefCell already mutably borrowed"))
5599 }
5600 BorrowState::Borrowed(count) => {
5601 *rc.borrow_state.borrow_mut() = BorrowState::Borrowed(count + 1);
5602 Ok(rc.value.borrow().clone())
5603 }
5604 BorrowState::Unborrowed => {
5605 *rc.borrow_state.borrow_mut() = BorrowState::Borrowed(1);
5606 Ok(rc.value.borrow().clone())
5607 }
5608 }
5609 }
5610 (Value::RefCellValue(rc), "borrow_mut") => {
5611 let state = rc.borrow_state.borrow().clone();
5613 match state {
5614 BorrowState::BorrowedMut => {
5615 Err(RuntimeError::new("RefCell already mutably borrowed"))
5616 }
5617 BorrowState::Borrowed(_) => {
5618 Err(RuntimeError::new("RefCell already borrowed"))
5619 }
5620 BorrowState::Unborrowed => {
5621 *rc.borrow_state.borrow_mut() = BorrowState::BorrowedMut;
5622 Ok(Value::Ref(Rc::new(RefCell::new(rc.value.borrow().clone()))))
5624 }
5625 }
5626 }
5627 (Value::RefCellValue(rc), "get") => {
5628 Ok(rc.value.borrow().clone())
5630 }
5631 (Value::RefCellValue(rc), "set") => {
5632 if arg_values.len() != 1 {
5634 return Err(RuntimeError::new("set expects 1 argument"));
5635 }
5636 let state = rc.borrow_state.borrow().clone();
5637 match state {
5638 BorrowState::BorrowedMut => {
5639 Err(RuntimeError::new("RefCell is mutably borrowed, cannot set"))
5640 }
5641 BorrowState::Borrowed(_) => {
5642 Err(RuntimeError::new("RefCell is borrowed, cannot set"))
5643 }
5644 BorrowState::Unborrowed => {
5645 *rc.value.borrow_mut() = arg_values[0].clone();
5646 Ok(Value::Null)
5647 }
5648 }
5649 }
5650 (Value::RefCellValue(rc), "into_inner") => {
5651 Ok(rc.value.borrow().clone())
5653 }
5654 (Value::RefCellValue(rc), "replace") => {
5655 if arg_values.len() != 1 {
5657 return Err(RuntimeError::new("replace expects 1 argument"));
5658 }
5659 let state = rc.borrow_state.borrow().clone();
5660 match state {
5661 BorrowState::BorrowedMut | BorrowState::Borrowed(_) => {
5662 Err(RuntimeError::new("RefCell is borrowed, cannot replace"))
5663 }
5664 BorrowState::Unborrowed => {
5665 let old = rc.value.borrow().clone();
5666 *rc.value.borrow_mut() = arg_values[0].clone();
5667 Ok(old)
5668 }
5669 }
5670 }
5671 (Value::TraitObject { value, concrete_type, trait_name }, _) => {
5673 let qualified_name = format!("{}·{}", concrete_type, method.name);
5675 let func = self.globals.borrow().get(&qualified_name).map(|v| v.clone());
5676
5677 if let Some(func) = func {
5678 if let Value::Function(f) = func {
5679 let old_self_type = self.current_self_type.take();
5681 self.current_self_type = Some(concrete_type.clone());
5682
5683 let mut all_args = vec![(**value).clone()];
5685 all_args.extend(arg_values.clone());
5686 let result = self.call_function(&f, all_args);
5687
5688 self.current_self_type = old_self_type;
5690 return result;
5691 } else if let Value::BuiltIn(b) = func {
5692 let mut all_args = vec![(**value).clone()];
5693 all_args.extend(arg_values.clone());
5694 return (b.func)(self, all_args);
5695 }
5696 }
5697
5698 Err(RuntimeError::new(format!(
5700 "Method '{}' not found for trait object '{}' with concrete type '{}'",
5701 method.name, trait_name, concrete_type
5702 )))
5703 }
5704 (Value::Ref(r), "cloned") => {
5706 Ok(r.borrow().clone())
5708 }
5709 (Value::Ref(r), "borrow") => {
5710 Ok(recv.clone())
5712 }
5713 (Value::Ref(r), "borrow_mut") => {
5714 Ok(recv.clone())
5716 }
5717 (Value::Ref(r), _) => {
5719 let inner = r.borrow().clone();
5721 if let Value::Struct { name, fields } = &inner {
5722 let qualified_name = format!("{}·{}", name, method.name);
5724 let func = self.globals.borrow().get(&qualified_name).map(|v| v.clone());
5725 if let Some(func) = func {
5726 if let Value::Function(f) = func {
5727 let old_self_type = self.current_self_type.take();
5729 self.current_self_type = Some(name.clone());
5730
5731 let mut all_args = vec![recv.clone()];
5733 all_args.extend(arg_values.clone());
5734 let result = self.call_function(&f, all_args);
5735
5736 self.current_self_type = old_self_type;
5738 return result;
5739 } else if let Value::BuiltIn(b) = func {
5740 let mut all_args = vec![recv.clone()];
5741 all_args.extend(arg_values.clone());
5742 return (b.func)(self, all_args);
5743 }
5744 }
5745
5746 if name == "Self" {
5748 let field_names: Vec<String> = fields.borrow().keys().cloned().collect();
5749
5750 for (type_name, type_def) in &self.types {
5752 if let TypeDef::Struct(struct_def) = type_def {
5753 let def_fields: Vec<String> = match &struct_def.fields {
5754 crate::ast::StructFields::Named(fs) => fs.iter().map(|f| f.name.name.clone()).collect(),
5755 _ => continue,
5756 };
5757
5758 let matches = field_names.iter().all(|f| def_fields.contains(f));
5760 if matches {
5761 let qualified_name = format!("{}·{}", type_name, method.name);
5762 let func = self.globals.borrow().get(&qualified_name).map(|v| v.clone());
5763 if let Some(func) = func {
5764 if let Value::Function(f) = func {
5765 let old_self_type = self.current_self_type.take();
5767 self.current_self_type = Some(type_name.clone());
5768
5769 let mut all_args = vec![recv.clone()];
5770 all_args.extend(arg_values.clone());
5771 let result = self.call_function(&f, all_args);
5772
5773 self.current_self_type = old_self_type;
5775 return result;
5776 } else if let Value::BuiltIn(b) = func {
5777 let mut all_args = vec![recv.clone()];
5778 all_args.extend(arg_values.clone());
5779 return (b.func)(self, all_args);
5780 }
5781 }
5782 }
5783 }
5784 }
5785 }
5786
5787 if name == "PathBuf" || name == "Path" {
5789 if let Some(Value::String(path)) = fields.borrow().get("path").cloned() {
5790 match method.name.as_str() {
5791 "exists" => return Ok(Value::Bool(std::path::Path::new(path.as_str()).exists())),
5792 "is_dir" => return Ok(Value::Bool(std::path::Path::new(path.as_str()).is_dir())),
5793 "is_file" => return Ok(Value::Bool(std::path::Path::new(path.as_str()).is_file())),
5794 "join" => {
5795 if let Some(Value::String(other)) = arg_values.first() {
5796 let new_path = std::path::Path::new(path.as_str()).join(other.as_str());
5797 let mut new_fields = std::collections::HashMap::new();
5798 new_fields.insert("path".to_string(), Value::String(Rc::new(new_path.to_string_lossy().to_string())));
5799 return Ok(Value::Struct {
5800 name: "PathBuf".to_string(),
5801 fields: Rc::new(RefCell::new(new_fields)),
5802 });
5803 }
5804 return Err(RuntimeError::new("join requires string argument"));
5805 }
5806 "parent" => {
5807 let p = std::path::Path::new(path.as_str());
5808 return match p.parent() {
5809 Some(par) => {
5810 let mut new_fields = std::collections::HashMap::new();
5811 new_fields.insert("path".to_string(), Value::String(Rc::new(par.to_string_lossy().to_string())));
5812 Ok(Value::Struct {
5813 name: "PathBuf".to_string(),
5814 fields: Rc::new(RefCell::new(new_fields)),
5815 })
5816 }
5817 None => Ok(Value::Null),
5818 };
5819 }
5820 "file_name" => {
5821 let p = std::path::Path::new(path.as_str());
5822 return match p.file_name() {
5823 Some(n) => Ok(Value::String(Rc::new(n.to_string_lossy().to_string()))),
5824 None => Ok(Value::Null),
5825 };
5826 }
5827 "extension" => {
5828 let p = std::path::Path::new(path.as_str());
5829 return match p.extension() {
5830 Some(e) => Ok(Value::String(Rc::new(e.to_string_lossy().to_string()))),
5831 None => Ok(Value::Null),
5832 };
5833 }
5834 "to_string" | "display" | "to_str" => {
5835 return Ok(Value::String(path.clone()));
5836 }
5837 _ => {}
5838 }
5839 }
5840 }
5841
5842 crate::sigil_warn!("WARN: Unknown method '{}' on '&{}' - returning null", method.name, name);
5844 return Ok(Value::Null);
5845 }
5846 if let Value::String(s) = &inner {
5849 match method.name.as_str() {
5850 "to_string" => return Ok(Value::String(s.clone())),
5851 "len" => return Ok(Value::Int(s.len() as i64)),
5852 "is_empty" => return Ok(Value::Bool(s.is_empty())),
5853 "as_str" => return Ok(Value::String(s.clone())),
5854 "starts_with" => {
5855 let prefix = match arg_values.first() {
5856 Some(Value::String(p)) => p.as_str(),
5857 Some(Value::Char(c)) => return Ok(Value::Bool(s.starts_with(*c))),
5858 _ => return Err(RuntimeError::new("starts_with expects string or char")),
5859 };
5860 return Ok(Value::Bool(s.starts_with(prefix)));
5861 }
5862 "ends_with" => {
5863 let suffix = match arg_values.first() {
5864 Some(Value::String(p)) => p.as_str(),
5865 Some(Value::Char(c)) => return Ok(Value::Bool(s.ends_with(*c))),
5866 _ => return Err(RuntimeError::new("ends_with expects string or char")),
5867 };
5868 return Ok(Value::Bool(s.ends_with(suffix)));
5869 }
5870 "contains" => {
5871 let substr = match arg_values.first() {
5872 Some(Value::String(p)) => p.as_str(),
5873 Some(Value::Char(c)) => return Ok(Value::Bool(s.contains(*c))),
5874 _ => return Err(RuntimeError::new("contains expects string or char")),
5875 };
5876 return Ok(Value::Bool(s.contains(substr)));
5877 }
5878 "trim" => return Ok(Value::String(Rc::new(s.trim().to_string()))),
5879 "to_lowercase" => return Ok(Value::String(Rc::new(s.to_lowercase()))),
5880 "to_uppercase" => return Ok(Value::String(Rc::new(s.to_uppercase()))),
5881 "chars" => {
5882 let chars: Vec<Value> = s.chars().map(Value::Char).collect();
5883 return Ok(Value::Array(Rc::new(RefCell::new(chars))));
5884 }
5885 "split" => {
5886 let delim = match arg_values.first() {
5887 Some(Value::String(d)) => d.as_str().to_string(),
5888 Some(Value::Char(c)) => c.to_string(),
5889 _ => " ".to_string(),
5890 };
5891 let parts: Vec<Value> = s.split(&delim)
5892 .map(|p| Value::String(Rc::new(p.to_string())))
5893 .collect();
5894 return Ok(Value::Array(Rc::new(RefCell::new(parts))));
5895 }
5896 "replace" => {
5897 if arg_values.len() != 2 {
5898 return Err(RuntimeError::new("replace expects 2 arguments"));
5899 }
5900 let from = match &arg_values[0] {
5901 Value::String(f) => f.as_str().to_string(),
5902 Value::Char(c) => c.to_string(),
5903 _ => return Err(RuntimeError::new("replace expects strings")),
5904 };
5905 let to = match &arg_values[1] {
5906 Value::String(t) => t.as_str().to_string(),
5907 Value::Char(c) => c.to_string(),
5908 _ => return Err(RuntimeError::new("replace expects strings")),
5909 };
5910 return Ok(Value::String(Rc::new(s.replace(&from, &to))));
5911 }
5912 _ => {}
5913 }
5914 }
5915 if let Value::Array(arr) = &inner {
5917 match method.name.as_str() {
5918 "len" => return Ok(Value::Int(arr.borrow().len() as i64)),
5919 "is_empty" => return Ok(Value::Bool(arr.borrow().is_empty())),
5920 "push" => {
5921 if arg_values.len() != 1 {
5922 return Err(RuntimeError::new("push expects 1 argument"));
5923 }
5924 arr.borrow_mut().push(arg_values[0].clone());
5925 return Ok(Value::Null);
5926 }
5927 "pop" => {
5928 return arr.borrow_mut().pop()
5929 .ok_or_else(|| RuntimeError::new("pop on empty array"));
5930 }
5931 "contains" => {
5932 if arg_values.len() != 1 {
5933 return Err(RuntimeError::new("contains expects 1 argument"));
5934 }
5935 let target = &arg_values[0];
5936 let found = arr.borrow().iter().any(|v| self.values_equal(v, target));
5937 return Ok(Value::Bool(found));
5938 }
5939 "first" | "next" => {
5940 return Ok(arr.borrow().first().cloned().unwrap_or(Value::Null));
5941 }
5942 "last" => {
5943 return arr.borrow().last().cloned()
5944 .ok_or_else(|| RuntimeError::new("empty array"));
5945 }
5946 "iter" | "into_iter" => {
5947 return Ok(Value::Array(arr.clone()));
5948 }
5949 "reverse" => {
5950 let mut v = arr.borrow().clone();
5951 v.reverse();
5952 return Ok(Value::Array(Rc::new(RefCell::new(v))));
5953 }
5954 "skip" => {
5955 let n = match arg_values.first() {
5956 Some(Value::Int(i)) => *i as usize,
5957 _ => 1,
5958 };
5959 let v: Vec<Value> = arr.borrow().iter().skip(n).cloned().collect();
5960 return Ok(Value::Array(Rc::new(RefCell::new(v))));
5961 }
5962 "take" => {
5963 let n = match arg_values.first() {
5964 Some(Value::Int(i)) => *i as usize,
5965 _ => 1,
5966 };
5967 let v: Vec<Value> = arr.borrow().iter().take(n).cloned().collect();
5968 return Ok(Value::Array(Rc::new(RefCell::new(v))));
5969 }
5970 "get" => {
5971 let idx = match arg_values.first() {
5972 Some(Value::Int(i)) => *i as usize,
5973 _ => return Err(RuntimeError::new("get expects integer index")),
5974 };
5975 return Ok(arr.borrow().get(idx).cloned().unwrap_or(Value::Null));
5976 }
5977 _ => {}
5978 }
5979 }
5980 if method.name == "clone" {
5982 crate::sigil_debug!("DEBUG clone: recv_type=Ref({:?})", std::mem::discriminant(&inner));
5983 return Ok(inner.clone());
5984 }
5985 if method.name == "into" {
5987 return Ok(inner.clone());
5988 }
5989 if method.name == "to_string" {
5991 return Ok(Value::String(Rc::new(format!("{}", inner))));
5992 }
5993 if let Value::Struct { name, fields, .. } = &inner {
5995 if name == "PathBuf" || name == "Path" {
5996 let borrowed = fields.borrow();
5997 if let Some(Value::String(path)) = borrowed.get("path") {
5998 match method.name.as_str() {
5999 "exists" => return Ok(Value::Bool(std::path::Path::new(path.as_str()).exists())),
6000 "is_dir" => return Ok(Value::Bool(std::path::Path::new(path.as_str()).is_dir())),
6001 "is_file" => return Ok(Value::Bool(std::path::Path::new(path.as_str()).is_file())),
6002 "join" => {
6003 if let Some(Value::String(other)) = arg_values.first() {
6004 let new_path = std::path::Path::new(path.as_str()).join(other.as_str());
6005 let mut new_fields = std::collections::HashMap::new();
6006 new_fields.insert("path".to_string(), Value::String(Rc::new(new_path.to_string_lossy().to_string())));
6007 return Ok(Value::Struct {
6008 name: "PathBuf".to_string(),
6009 fields: Rc::new(RefCell::new(new_fields)),
6010 });
6011 }
6012 return Err(RuntimeError::new("join requires string argument"));
6013 }
6014 "parent" => {
6015 let p = std::path::Path::new(path.as_str());
6016 return match p.parent() {
6017 Some(par) => {
6018 let mut new_fields = std::collections::HashMap::new();
6019 new_fields.insert("path".to_string(), Value::String(Rc::new(par.to_string_lossy().to_string())));
6020 Ok(Value::Struct {
6021 name: "PathBuf".to_string(),
6022 fields: Rc::new(RefCell::new(new_fields)),
6023 })
6024 }
6025 None => Ok(Value::Null),
6026 };
6027 }
6028 "file_name" => {
6029 let p = std::path::Path::new(path.as_str());
6030 return match p.file_name() {
6031 Some(n) => Ok(Value::String(Rc::new(n.to_string_lossy().to_string()))),
6032 None => Ok(Value::Null),
6033 };
6034 }
6035 "extension" => {
6036 let p = std::path::Path::new(path.as_str());
6037 return match p.extension() {
6038 Some(e) => Ok(Value::String(Rc::new(e.to_string_lossy().to_string()))),
6039 None => Ok(Value::Null),
6040 };
6041 }
6042 "to_string" | "display" => {
6043 return Ok(Value::String(path.clone()));
6044 }
6045 _ => {}
6046 }
6047 }
6048 }
6049 }
6050 if let Value::String(s) = &inner {
6052 match method.name.as_str() {
6053 "exists" => return Ok(Value::Bool(std::path::Path::new(s.as_str()).exists())),
6054 "is_dir" => return Ok(Value::Bool(std::path::Path::new(s.as_str()).is_dir())),
6055 "is_file" => return Ok(Value::Bool(std::path::Path::new(s.as_str()).is_file())),
6056 "join" => {
6057 if let Some(Value::String(other)) = arg_values.first() {
6058 let path = std::path::Path::new(s.as_str()).join(other.as_str());
6059 return Ok(Value::String(Rc::new(path.to_string_lossy().to_string())));
6060 }
6061 return Err(RuntimeError::new("join requires string argument"));
6062 }
6063 "parent" => {
6064 let path = std::path::Path::new(s.as_str());
6065 return match path.parent() {
6066 Some(p) => Ok(Value::String(Rc::new(p.to_string_lossy().to_string()))),
6067 None => Ok(Value::Null),
6068 };
6069 }
6070 "file_name" => {
6071 let path = std::path::Path::new(s.as_str());
6072 return match path.file_name() {
6073 Some(n) => Ok(Value::String(Rc::new(n.to_string_lossy().to_string()))),
6074 None => Ok(Value::Null),
6075 };
6076 }
6077 "extension" => {
6078 let path = std::path::Path::new(s.as_str());
6079 return match path.extension() {
6080 Some(e) => Ok(Value::String(Rc::new(e.to_string_lossy().to_string()))),
6081 None => Ok(Value::Null),
6082 };
6083 }
6084 _ => {}
6085 }
6086 }
6087 if let Value::String(_) = inner {
6090 let recv_unwrapped = inner.clone();
6093 match (&recv_unwrapped, method.name.as_str()) {
6094 (Value::String(s), "find") => {
6095 if arg_values.len() != 1 {
6096 return Err(RuntimeError::new("find expects 1 argument"));
6097 }
6098 match &arg_values[0] {
6099 Value::Char(c) => {
6100 return match s.find(*c) {
6101 Some(idx) => Ok(Value::Variant {
6102 enum_name: "Option".to_string(),
6103 variant_name: "Some".to_string(),
6104 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
6105 }),
6106 None => Ok(Value::Variant {
6107 enum_name: "Option".to_string(),
6108 variant_name: "None".to_string(),
6109 fields: None,
6110 }),
6111 }
6112 }
6113 Value::String(pattern) => {
6114 return match s.find(pattern.as_str()) {
6115 Some(idx) => Ok(Value::Variant {
6116 enum_name: "Option".to_string(),
6117 variant_name: "Some".to_string(),
6118 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
6119 }),
6120 None => Ok(Value::Variant {
6121 enum_name: "Option".to_string(),
6122 variant_name: "None".to_string(),
6123 fields: None,
6124 }),
6125 }
6126 }
6127 Value::Function(f) => {
6128 for (idx, c) in s.chars().enumerate() {
6129 let result = self.call_function(f, vec![Value::Char(c)])?;
6130 if let Value::Bool(true) = result {
6131 return Ok(Value::Variant {
6132 enum_name: "Option".to_string(),
6133 variant_name: "Some".to_string(),
6134 fields: Some(Rc::new(vec![Value::Int(idx as i64)])),
6135 });
6136 }
6137 }
6138 return Ok(Value::Variant {
6139 enum_name: "Option".to_string(),
6140 variant_name: "None".to_string(),
6141 fields: None,
6142 })
6143 }
6144 _ => return Err(RuntimeError::new("find expects a char, string, or closure")),
6145 }
6146 }
6147 (Value::String(s), "trim") => return Ok(Value::String(Rc::new(s.trim().to_string()))),
6148 (Value::String(s), "is_empty") => return Ok(Value::Bool(s.is_empty())),
6149 (Value::String(s), "len") => return Ok(Value::Int(s.len() as i64)),
6150 (Value::String(s), "to_string") => return Ok(Value::String(s.clone())),
6151 (Value::String(s), "chars") => {
6152 let chars: Vec<Value> = s.chars().map(Value::Char).collect();
6153 return Ok(Value::Array(Rc::new(RefCell::new(chars))))
6154 }
6155 (Value::String(s), "starts_with") => {
6156 if let Some(Value::String(prefix)) = arg_values.first() {
6157 return Ok(Value::Bool(s.starts_with(prefix.as_str())));
6158 }
6159 return Err(RuntimeError::new("starts_with expects string argument"));
6160 }
6161 _ => {}
6162 }
6163 }
6164 Err(RuntimeError::new(format!(
6165 "Cannot call method {} on Ref to non-struct",
6166 method.name
6167 )))
6168 }
6169 (Value::Struct { name, fields }, _) => {
6171 if method.name == "clone" {
6173 return Ok(recv.clone());
6175 }
6176 if name == "PathBuf" || name == "Path" {
6178 let borrowed = fields.borrow();
6179 if let Some(Value::String(path)) = borrowed.get("path") {
6180 match method.name.as_str() {
6181 "exists" => return Ok(Value::Bool(std::path::Path::new(path.as_str()).exists())),
6182 "is_dir" => return Ok(Value::Bool(std::path::Path::new(path.as_str()).is_dir())),
6183 "is_file" => return Ok(Value::Bool(std::path::Path::new(path.as_str()).is_file())),
6184 "join" => {
6185 if let Some(Value::String(other)) = arg_values.first() {
6186 let new_path = std::path::Path::new(path.as_str()).join(other.as_str());
6187 let mut new_fields = std::collections::HashMap::new();
6188 new_fields.insert("path".to_string(), Value::String(Rc::new(new_path.to_string_lossy().to_string())));
6189 return Ok(Value::Struct {
6190 name: "PathBuf".to_string(),
6191 fields: Rc::new(RefCell::new(new_fields)),
6192 });
6193 }
6194 return Err(RuntimeError::new("join requires string argument"));
6195 }
6196 "parent" => {
6197 let p = std::path::Path::new(path.as_str());
6198 return match p.parent() {
6199 Some(par) => {
6200 let mut new_fields = std::collections::HashMap::new();
6201 new_fields.insert("path".to_string(), Value::String(Rc::new(par.to_string_lossy().to_string())));
6202 Ok(Value::Struct {
6203 name: "PathBuf".to_string(),
6204 fields: Rc::new(RefCell::new(new_fields)),
6205 })
6206 }
6207 None => Ok(Value::Null),
6208 };
6209 }
6210 "file_name" => {
6211 let p = std::path::Path::new(path.as_str());
6212 return match p.file_name() {
6213 Some(n) => Ok(Value::String(Rc::new(n.to_string_lossy().to_string()))),
6214 None => Ok(Value::Null),
6215 };
6216 }
6217 "extension" => {
6218 let p = std::path::Path::new(path.as_str());
6219 return match p.extension() {
6220 Some(e) => Ok(Value::String(Rc::new(e.to_string_lossy().to_string()))),
6221 None => Ok(Value::Null),
6222 };
6223 }
6224 "to_string" | "display" => {
6225 return Ok(Value::String(path.clone()));
6226 }
6227 _ => {}
6228 }
6229 }
6230 }
6231 if name == "Rc" {
6233 let borrowed = fields.borrow();
6234 if let Some(value) = borrowed.get("_value") {
6235 match method.name.as_str() {
6236 "clone" => {
6237 let mut new_fields = HashMap::new();
6239 new_fields.insert("_value".to_string(), value.clone());
6240 return Ok(Value::Struct {
6241 name: "Rc".to_string(),
6242 fields: Rc::new(RefCell::new(new_fields)),
6243 });
6244 }
6245 _ => {}
6246 }
6247 }
6248 }
6249 if name == "Cell" {
6251 match method.name.as_str() {
6252 "get" => {
6253 let borrowed = fields.borrow();
6254 if let Some(value) = borrowed.get("_value") {
6255 return Ok(value.clone());
6256 }
6257 return Err(RuntimeError::new("Cell has no value"));
6258 }
6259 "set" => {
6260 if arg_values.len() != 1 {
6261 return Err(RuntimeError::new("set expects 1 argument"));
6262 }
6263 fields.borrow_mut().insert("_value".to_string(), arg_values[0].clone());
6264 return Ok(Value::Null);
6265 }
6266 _ => {}
6267 }
6268 }
6269 if name == "Duration" {
6271 let borrowed = fields.borrow();
6272 let secs = match borrowed.get("secs") {
6273 Some(Value::Int(s)) => *s,
6274 _ => 0,
6275 };
6276 let nanos = match borrowed.get("nanos") {
6277 Some(Value::Int(n)) => *n,
6278 _ => 0,
6279 };
6280 match method.name.as_str() {
6281 "as_secs" => return Ok(Value::Int(secs)),
6282 "as_millis" => return Ok(Value::Int(secs * 1000 + nanos / 1_000_000)),
6283 "as_micros" => return Ok(Value::Int(secs * 1_000_000 + nanos / 1000)),
6284 "as_nanos" => return Ok(Value::Int(secs * 1_000_000_000 + nanos)),
6285 "subsec_nanos" => return Ok(Value::Int(nanos)),
6286 "subsec_millis" => return Ok(Value::Int(nanos / 1_000_000)),
6287 "is_zero" => return Ok(Value::Bool(secs == 0 && nanos == 0)),
6288 _ => {}
6289 }
6290 }
6291 if name == "Mutex" {
6293 match method.name.as_str() {
6294 "lock" => {
6295 let borrowed = fields.borrow();
6298 if let Some(inner) = borrowed.get("__inner__") {
6299 return Ok(Value::Ref(Rc::new(RefCell::new(inner.clone()))));
6301 }
6302 return Err(RuntimeError::new("Mutex has no inner value"));
6303 }
6304 "try_lock" => {
6305 let borrowed = fields.borrow();
6307 if let Some(inner) = borrowed.get("__inner__") {
6308 let guard = Value::Ref(Rc::new(RefCell::new(inner.clone())));
6309 return Ok(Value::Variant {
6310 enum_name: "Option".to_string(),
6311 variant_name: "Some".to_string(),
6312 fields: Some(Rc::new(vec![guard])),
6313 });
6314 }
6315 return Ok(Value::Variant {
6316 enum_name: "Option".to_string(),
6317 variant_name: "None".to_string(),
6318 fields: None,
6319 });
6320 }
6321 "into_inner" => {
6322 let borrowed = fields.borrow();
6324 if let Some(inner) = borrowed.get("__inner__") {
6325 return Ok(inner.clone());
6326 }
6327 return Err(RuntimeError::new("Mutex has no inner value"));
6328 }
6329 "get_mut" => {
6330 let borrowed = fields.borrow();
6332 if let Some(inner) = borrowed.get("__inner__") {
6333 return Ok(Value::Ref(Rc::new(RefCell::new(inner.clone()))));
6334 }
6335 return Err(RuntimeError::new("Mutex has no inner value"));
6336 }
6337 _ => {}
6338 }
6339 }
6340 if name == "RwLock" {
6342 match method.name.as_str() {
6343 "read" => {
6344 let borrowed = fields.borrow();
6346 if let Some(inner) = borrowed.get("__inner__") {
6347 return Ok(Value::Ref(Rc::new(RefCell::new(inner.clone()))));
6348 }
6349 return Err(RuntimeError::new("RwLock has no inner value"));
6350 }
6351 "write" => {
6352 let borrowed = fields.borrow();
6354 if let Some(inner) = borrowed.get("__inner__") {
6355 return Ok(Value::Ref(Rc::new(RefCell::new(inner.clone()))));
6356 }
6357 return Err(RuntimeError::new("RwLock has no inner value"));
6358 }
6359 "try_read" => {
6360 let borrowed = fields.borrow();
6361 if let Some(inner) = borrowed.get("__inner__") {
6362 let guard = Value::Ref(Rc::new(RefCell::new(inner.clone())));
6363 return Ok(Value::Variant {
6364 enum_name: "Option".to_string(),
6365 variant_name: "Some".to_string(),
6366 fields: Some(Rc::new(vec![guard])),
6367 });
6368 }
6369 return Ok(Value::Variant {
6370 enum_name: "Option".to_string(),
6371 variant_name: "None".to_string(),
6372 fields: None,
6373 });
6374 }
6375 "try_write" => {
6376 let borrowed = fields.borrow();
6377 if let Some(inner) = borrowed.get("__inner__") {
6378 let guard = Value::Ref(Rc::new(RefCell::new(inner.clone())));
6379 return Ok(Value::Variant {
6380 enum_name: "Option".to_string(),
6381 variant_name: "Some".to_string(),
6382 fields: Some(Rc::new(vec![guard])),
6383 });
6384 }
6385 return Ok(Value::Variant {
6386 enum_name: "Option".to_string(),
6387 variant_name: "None".to_string(),
6388 fields: None,
6389 });
6390 }
6391 "into_inner" => {
6392 let borrowed = fields.borrow();
6393 if let Some(inner) = borrowed.get("__inner__") {
6394 return Ok(inner.clone());
6395 }
6396 return Err(RuntimeError::new("RwLock has no inner value"));
6397 }
6398 _ => {}
6399 }
6400 }
6401 if name == "AtomicU64" || name == "AtomicUsize" || name == "AtomicI64" || name == "AtomicIsize" {
6403 match method.name.as_str() {
6404 "load" => {
6405 let borrowed = fields.borrow();
6407 if let Some(val) = borrowed.get("__value__") {
6408 return Ok(val.clone());
6409 }
6410 return Ok(Value::Int(0));
6411 }
6412 "store" => {
6413 if let Some(new_val) = arg_values.first() {
6415 fields.borrow_mut().insert("__value__".to_string(), new_val.clone());
6416 return Ok(Value::Null);
6417 }
6418 return Err(RuntimeError::new("store requires a value"));
6419 }
6420 "fetch_add" => {
6421 if let Some(Value::Int(n)) = arg_values.first() {
6423 let mut borrowed = fields.borrow_mut();
6424 let old = match borrowed.get("__value__") {
6425 Some(Value::Int(v)) => *v,
6426 _ => 0,
6427 };
6428 borrowed.insert("__value__".to_string(), Value::Int(old + n));
6429 return Ok(Value::Int(old));
6430 }
6431 return Err(RuntimeError::new("fetch_add requires integer"));
6432 }
6433 "fetch_sub" => {
6434 if let Some(Value::Int(n)) = arg_values.first() {
6435 let mut borrowed = fields.borrow_mut();
6436 let old = match borrowed.get("__value__") {
6437 Some(Value::Int(v)) => *v,
6438 _ => 0,
6439 };
6440 borrowed.insert("__value__".to_string(), Value::Int(old - n));
6441 return Ok(Value::Int(old));
6442 }
6443 return Err(RuntimeError::new("fetch_sub requires integer"));
6444 }
6445 "swap" => {
6446 if let Some(new_val) = arg_values.first() {
6447 let mut borrowed = fields.borrow_mut();
6448 let old = borrowed.get("__value__").cloned().unwrap_or(Value::Int(0));
6449 borrowed.insert("__value__".to_string(), new_val.clone());
6450 return Ok(old);
6451 }
6452 return Err(RuntimeError::new("swap requires a value"));
6453 }
6454 "compare_exchange" | "compare_and_swap" => {
6455 if arg_values.len() >= 2 {
6457 let current = &arg_values[0];
6458 let new_val = &arg_values[1];
6459 let mut borrowed = fields.borrow_mut();
6460 let actual = borrowed.get("__value__").cloned().unwrap_or(Value::Int(0));
6461 if self.values_equal(&actual, current) {
6462 borrowed.insert("__value__".to_string(), new_val.clone());
6463 return Ok(Value::Variant {
6464 enum_name: "Result".to_string(),
6465 variant_name: "Ok".to_string(),
6466 fields: Some(Rc::new(vec![actual])),
6467 });
6468 } else {
6469 return Ok(Value::Variant {
6470 enum_name: "Result".to_string(),
6471 variant_name: "Err".to_string(),
6472 fields: Some(Rc::new(vec![actual])),
6473 });
6474 }
6475 }
6476 return Err(RuntimeError::new("compare_exchange requires two arguments"));
6477 }
6478 _ => {}
6479 }
6480 }
6481 if name == "AtomicBool" {
6483 match method.name.as_str() {
6484 "load" => {
6485 let borrowed = fields.borrow();
6486 if let Some(val) = borrowed.get("__value__") {
6487 return Ok(val.clone());
6488 }
6489 return Ok(Value::Bool(false));
6490 }
6491 "store" => {
6492 if let Some(new_val) = arg_values.first() {
6493 fields.borrow_mut().insert("__value__".to_string(), new_val.clone());
6494 return Ok(Value::Null);
6495 }
6496 return Err(RuntimeError::new("store requires a value"));
6497 }
6498 "swap" => {
6499 if let Some(new_val) = arg_values.first() {
6500 let mut borrowed = fields.borrow_mut();
6501 let old = borrowed.get("__value__").cloned().unwrap_or(Value::Bool(false));
6502 borrowed.insert("__value__".to_string(), new_val.clone());
6503 return Ok(old);
6504 }
6505 return Err(RuntimeError::new("swap requires a value"));
6506 }
6507 "fetch_and" => {
6508 if let Some(Value::Bool(b)) = arg_values.first() {
6509 let mut borrowed = fields.borrow_mut();
6510 let old = match borrowed.get("__value__") {
6511 Some(Value::Bool(v)) => *v,
6512 _ => false,
6513 };
6514 borrowed.insert("__value__".to_string(), Value::Bool(old && *b));
6515 return Ok(Value::Bool(old));
6516 }
6517 return Err(RuntimeError::new("fetch_and requires boolean"));
6518 }
6519 "fetch_or" => {
6520 if let Some(Value::Bool(b)) = arg_values.first() {
6521 let mut borrowed = fields.borrow_mut();
6522 let old = match borrowed.get("__value__") {
6523 Some(Value::Bool(v)) => *v,
6524 _ => false,
6525 };
6526 borrowed.insert("__value__".to_string(), Value::Bool(old || *b));
6527 return Ok(Value::Bool(old));
6528 }
6529 return Err(RuntimeError::new("fetch_or requires boolean"));
6530 }
6531 _ => {}
6532 }
6533 }
6534 if method.name == "to_string" {
6535 let field_str = fields.borrow().iter()
6537 .map(|(k, v)| format!("{}: {}", k, v))
6538 .collect::<Vec<_>>()
6539 .join(", ");
6540 return Ok(Value::String(Rc::new(format!("{} {{ {} }}", name, field_str))));
6541 }
6542
6543 if name.starts_with("Pattern::") {
6545 match method.name.as_str() {
6546 "evidentiality" => {
6547 if let Some(ev) = fields.borrow().get("evidentiality") {
6549 return Ok(ev.clone());
6550 }
6551 return Ok(Value::Null);
6552 }
6553 "name" | "binding_name" => {
6554 if let Some(n) = fields.borrow().get("name") {
6556 let result = match &n {
6559 Value::Struct { fields: inner_fields, .. } => {
6560 if let Some(inner_name) = inner_fields.borrow().get("name") {
6561 crate::sigil_debug!("DEBUG binding_name: returning inner name {} from {}", inner_name, name);
6562 inner_name.clone()
6563 } else {
6564 crate::sigil_debug!("DEBUG binding_name: returning struct {} from {}", n, name);
6565 n.clone()
6566 }
6567 }
6568 _ => {
6569 crate::sigil_debug!("DEBUG binding_name: returning {} from {}", n, name);
6570 n.clone()
6571 }
6572 };
6573 return Ok(result);
6574 }
6575 crate::sigil_debug!("DEBUG binding_name: 'name' field not found in {}, fields: {:?}", name, fields.borrow().keys().collect::<Vec<_>>());
6576 return Ok(Value::Null);
6578 }
6579 "mutable" => {
6580 if let Some(m) = fields.borrow().get("mutable") {
6582 return Ok(m.clone());
6583 }
6584 return Ok(Value::Bool(false));
6585 }
6586 "is_ident" => {
6587 return Ok(Value::Bool(name == "Pattern::Ident"));
6588 }
6589 "is_wildcard" => {
6590 return Ok(Value::Bool(name == "Pattern::Wildcard"));
6591 }
6592 "clone" => {
6593 return Ok(recv.clone());
6594 }
6595 _ => {}
6596 }
6597 }
6598
6599 if name == "PathBuf" || name == "Path" {
6601 match method.name.as_str() {
6602 "exists" => {
6603 let path = match fields.borrow().get("path") {
6605 Some(Value::String(s)) => s.to_string(),
6606 _ => return Err(RuntimeError::new("PathBuf has no path field")),
6607 };
6608 return Ok(Value::Bool(std::path::Path::new(&path).exists()));
6609 }
6610 "is_dir" => {
6611 let path = match fields.borrow().get("path") {
6612 Some(Value::String(s)) => s.to_string(),
6613 _ => return Err(RuntimeError::new("PathBuf has no path field")),
6614 };
6615 return Ok(Value::Bool(std::path::Path::new(&path).is_dir()));
6616 }
6617 "is_file" => {
6618 let path = match fields.borrow().get("path") {
6619 Some(Value::String(s)) => s.to_string(),
6620 _ => return Err(RuntimeError::new("PathBuf has no path field")),
6621 };
6622 return Ok(Value::Bool(std::path::Path::new(&path).is_file()));
6623 }
6624 "extension" => {
6625 let path = match fields.borrow().get("path") {
6626 Some(Value::String(s)) => s.to_string(),
6627 _ => return Err(RuntimeError::new("PathBuf has no path field")),
6628 };
6629 match std::path::Path::new(&path).extension() {
6630 Some(ext) => {
6631 let ext_str = ext.to_string_lossy().to_string();
6633 let mut ext_fields = HashMap::new();
6634 ext_fields.insert("value".to_string(), Value::String(Rc::new(ext_str)));
6635 return Ok(Value::Variant {
6636 enum_name: "Option".to_string(),
6637 variant_name: "Some".to_string(),
6638 fields: Some(Rc::new(vec![Value::Struct {
6639 name: "OsStr".to_string(),
6640 fields: Rc::new(RefCell::new(ext_fields)),
6641 }])),
6642 });
6643 }
6644 None => {
6645 return Ok(Value::Variant {
6646 enum_name: "Option".to_string(),
6647 variant_name: "None".to_string(),
6648 fields: None,
6649 });
6650 }
6651 }
6652 }
6653 "file_name" => {
6654 let path = match fields.borrow().get("path") {
6655 Some(Value::String(s)) => s.to_string(),
6656 _ => return Err(RuntimeError::new("PathBuf has no path field")),
6657 };
6658 match std::path::Path::new(&path).file_name() {
6659 Some(fname) => {
6660 let fname_str = fname.to_string_lossy().to_string();
6661 let mut fname_fields = HashMap::new();
6662 fname_fields.insert("value".to_string(), Value::String(Rc::new(fname_str)));
6663 return Ok(Value::Variant {
6664 enum_name: "Option".to_string(),
6665 variant_name: "Some".to_string(),
6666 fields: Some(Rc::new(vec![Value::Struct {
6667 name: "OsStr".to_string(),
6668 fields: Rc::new(RefCell::new(fname_fields)),
6669 }])),
6670 });
6671 }
6672 None => {
6673 return Ok(Value::Variant {
6674 enum_name: "Option".to_string(),
6675 variant_name: "None".to_string(),
6676 fields: None,
6677 });
6678 }
6679 }
6680 }
6681 "parent" => {
6682 let path = match fields.borrow().get("path") {
6683 Some(Value::String(s)) => s.to_string(),
6684 _ => return Err(RuntimeError::new("PathBuf has no path field")),
6685 };
6686 match std::path::Path::new(&path).parent() {
6687 Some(parent) => {
6688 let mut parent_fields = HashMap::new();
6689 parent_fields.insert("path".to_string(), Value::String(Rc::new(parent.to_string_lossy().to_string())));
6690 return Ok(Value::Variant {
6691 enum_name: "Option".to_string(),
6692 variant_name: "Some".to_string(),
6693 fields: Some(Rc::new(vec![Value::Struct {
6694 name: "Path".to_string(),
6695 fields: Rc::new(RefCell::new(parent_fields)),
6696 }])),
6697 });
6698 }
6699 None => {
6700 return Ok(Value::Variant {
6701 enum_name: "Option".to_string(),
6702 variant_name: "None".to_string(),
6703 fields: None,
6704 });
6705 }
6706 }
6707 }
6708 "to_str" => {
6709 let path = match fields.borrow().get("path") {
6711 Some(Value::String(s)) => s.clone(),
6712 _ => return Err(RuntimeError::new("PathBuf has no path field")),
6713 };
6714 return Ok(Value::Variant {
6716 enum_name: "Option".to_string(),
6717 variant_name: "Some".to_string(),
6718 fields: Some(Rc::new(vec![Value::String(path)])),
6719 });
6720 }
6721 "to_string_lossy" => {
6722 let path = match fields.borrow().get("path") {
6723 Some(Value::String(s)) => s.clone(),
6724 _ => return Err(RuntimeError::new("PathBuf has no path field")),
6725 };
6726 return Ok(Value::String(path));
6727 }
6728 "join" => {
6729 if arg_values.is_empty() {
6731 return Err(RuntimeError::new("join expects 1 argument"));
6732 }
6733 let base = match fields.borrow().get("path") {
6734 Some(Value::String(s)) => s.to_string(),
6735 _ => return Err(RuntimeError::new("PathBuf has no path field")),
6736 };
6737 let component = match &arg_values[0] {
6738 Value::String(s) => s.to_string(),
6739 Value::Struct { name: n, fields: f } if n == "PathBuf" || n == "Path" => {
6740 match f.borrow().get("path") {
6741 Some(Value::String(s)) => s.to_string(),
6742 _ => return Err(RuntimeError::new("PathBuf has no path field")),
6743 }
6744 }
6745 _ => return Err(RuntimeError::new("join expects string or PathBuf")),
6746 };
6747 let joined = std::path::Path::new(&base).join(&component);
6748 let mut new_fields = HashMap::new();
6749 new_fields.insert("path".to_string(), Value::String(Rc::new(joined.to_string_lossy().to_string())));
6750 return Ok(Value::Struct {
6751 name: "PathBuf".to_string(),
6752 fields: Rc::new(RefCell::new(new_fields)),
6753 });
6754 }
6755 "display" => {
6756 let path = match fields.borrow().get("path") {
6757 Some(Value::String(s)) => s.clone(),
6758 _ => return Err(RuntimeError::new("PathBuf has no path field")),
6759 };
6760 return Ok(Value::String(path));
6761 }
6762 "to_path_buf" => {
6763 return Ok(recv.clone());
6765 }
6766 _ => {}
6767 }
6768 }
6769
6770 if name == "OsStr" {
6772 match method.name.as_str() {
6773 "to_str" => {
6774 let val = match fields.borrow().get("value") {
6775 Some(Value::String(s)) => s.clone(),
6776 _ => return Err(RuntimeError::new("OsStr has no value field")),
6777 };
6778 return Ok(Value::Variant {
6779 enum_name: "Option".to_string(),
6780 variant_name: "Some".to_string(),
6781 fields: Some(Rc::new(vec![Value::String(val)])),
6782 });
6783 }
6784 "to_string_lossy" => {
6785 let val = match fields.borrow().get("value") {
6786 Some(Value::String(s)) => s.clone(),
6787 _ => return Err(RuntimeError::new("OsStr has no value field")),
6788 };
6789 return Ok(Value::String(val));
6790 }
6791 "to_lowercase" => {
6792 let val = match fields.borrow().get("value") {
6793 Some(Value::String(s)) => s.to_lowercase(),
6794 _ => return Err(RuntimeError::new("OsStr has no value field")),
6795 };
6796 return Ok(Value::String(Rc::new(val)));
6797 }
6798 "as_str" => {
6799 let val = match fields.borrow().get("value") {
6800 Some(Value::String(s)) => s.clone(),
6801 _ => return Err(RuntimeError::new("OsStr has no value field")),
6802 };
6803 return Ok(Value::String(val));
6804 }
6805 _ => {}
6806 }
6807 }
6808
6809 if name == "DirEntry" {
6811 match method.name.as_str() {
6812 "path" => {
6813 let path = match fields.borrow().get("path") {
6814 Some(Value::String(s)) => s.clone(),
6815 _ => return Err(RuntimeError::new("DirEntry has no path field")),
6816 };
6817 let mut path_fields = HashMap::new();
6818 path_fields.insert("path".to_string(), Value::String(path));
6819 return Ok(Value::Struct {
6820 name: "PathBuf".to_string(),
6821 fields: Rc::new(RefCell::new(path_fields)),
6822 });
6823 }
6824 "file_name" => {
6825 let path = match fields.borrow().get("path") {
6826 Some(Value::String(s)) => s.to_string(),
6827 _ => return Err(RuntimeError::new("DirEntry has no path field")),
6828 };
6829 let fname = std::path::Path::new(&path)
6830 .file_name()
6831 .map(|f| f.to_string_lossy().to_string())
6832 .unwrap_or_default();
6833 let mut fname_fields = HashMap::new();
6834 fname_fields.insert("value".to_string(), Value::String(Rc::new(fname)));
6835 return Ok(Value::Struct {
6836 name: "OsStr".to_string(),
6837 fields: Rc::new(RefCell::new(fname_fields)),
6838 });
6839 }
6840 _ => {}
6841 }
6842 }
6843
6844 if name == "Map" {
6846 match method.name.as_str() {
6847 "get" => {
6848 if arg_values.len() != 1 {
6850 return Err(RuntimeError::new("Map.get expects 1 argument"));
6851 }
6852 let key = match &arg_values[0] {
6853 Value::String(s) => s.to_string(),
6854 Value::Int(n) => n.to_string(),
6855 other => format!("{:?}", other),
6856 };
6857 if let Some(val) = fields.borrow().get(&key) {
6858 return Ok(val.clone());
6859 }
6860 return Ok(Value::Null);
6861 }
6862 "insert" => {
6863 if arg_values.len() != 2 {
6865 return Err(RuntimeError::new("Map.insert expects 2 arguments"));
6866 }
6867 let key = match &arg_values[0] {
6868 Value::String(s) => s.to_string(),
6869 Value::Int(n) => n.to_string(),
6870 other => format!("{:?}", other),
6871 };
6872 crate::sigil_debug!("DEBUG Map.insert: key='{}', value={}", key, arg_values[1]);
6873 fields.borrow_mut().insert(key, arg_values[1].clone());
6874 return Ok(Value::Null);
6875 }
6876 "contains_key" => {
6877 if arg_values.len() != 1 {
6878 return Err(RuntimeError::new("Map.contains_key expects 1 argument"));
6879 }
6880 let key = match &arg_values[0] {
6881 Value::String(s) => s.to_string(),
6882 Value::Int(n) => n.to_string(),
6883 other => format!("{:?}", other),
6884 };
6885 return Ok(Value::Bool(fields.borrow().contains_key(&key)));
6886 }
6887 "len" => {
6888 return Ok(Value::Int(fields.borrow().len() as i64));
6889 }
6890 "is_empty" => {
6891 return Ok(Value::Bool(fields.borrow().is_empty()));
6892 }
6893 "keys" => {
6894 let keys: Vec<Value> = fields.borrow()
6895 .keys()
6896 .map(|k| Value::String(Rc::new(k.clone())))
6897 .collect();
6898 return Ok(Value::Array(Rc::new(RefCell::new(keys))));
6899 }
6900 "values" => {
6901 let vals: Vec<Value> = fields.borrow()
6902 .values()
6903 .cloned()
6904 .collect();
6905 return Ok(Value::Array(Rc::new(RefCell::new(vals))));
6906 }
6907 "clone" => {
6908 return Ok(recv.clone());
6909 }
6910 _ => {}
6911 }
6912 }
6913
6914 let qualified_name = format!("{}·{}", name, method.name);
6915
6916 if name == "Parser" && (method.name == "parse_file" || method.name == "read_source") {
6918 crate::sigil_debug!("DEBUG Parser method call: {}", qualified_name);
6919 for (i, arg) in arg_values.iter().enumerate() {
6920 crate::sigil_debug!(" arg_value[{}] = {:?}", i, arg);
6921 }
6922 }
6923
6924 if name == "Lexer" {
6926 if method.name == "lex_ident_or_keyword" {
6928 for (i, arg) in arg_values.iter().enumerate() {
6929 let unwrapped = Self::unwrap_all(arg);
6930 if let Value::Char(c) = &unwrapped {
6931 crate::sigil_debug!("DEBUG Lexer·lex_ident_or_keyword arg[{}]='{}'", i, c);
6932 }
6933 }
6934 }
6935 crate::sigil_debug!("DEBUG Lexer method call: {}", qualified_name);
6936 }
6937 for arg in &arg_values {
6939 let unwrapped = Self::unwrap_all(arg);
6940 if let Value::String(s) = &unwrapped {
6941 if **s == "fn" {
6942 crate::sigil_debug!("DEBUG struct method with 'fn': {} recv_name={}", method.name, name);
6943 }
6944 }
6945 }
6946
6947 let func = self.globals.borrow().get(&qualified_name).map(|v| v.clone());
6948 if let Some(func) = func {
6949 if let Value::Function(f) = func {
6950 let old_self_type = self.current_self_type.take();
6952 self.current_self_type = Some(name.clone());
6953
6954 let mut all_args = vec![recv.clone()];
6956 all_args.extend(arg_values.clone());
6957 let result = self.call_function(&f, all_args);
6958
6959 self.current_self_type = old_self_type;
6961 return result;
6962 } else if let Value::BuiltIn(b) = func {
6963 let mut all_args = vec![recv.clone()];
6964 all_args.extend(arg_values.clone());
6965 return (b.func)(self, all_args);
6966 }
6967 }
6968
6969 if name == "Self" {
6971 let field_names: Vec<String> = fields.borrow().keys().cloned().collect();
6973
6974 for (type_name, type_def) in &self.types {
6976 if let TypeDef::Struct(struct_def) = type_def {
6977 let def_fields: Vec<String> = match &struct_def.fields {
6979 crate::ast::StructFields::Named(fs) => fs.iter().map(|f| f.name.name.clone()).collect(),
6980 _ => continue,
6981 };
6982
6983 let matches = field_names.iter().all(|f| def_fields.contains(f));
6985 if matches {
6986 let qualified_name = format!("{}·{}", type_name, method.name);
6987 let func = self.globals.borrow().get(&qualified_name).map(|v| v.clone());
6988 if let Some(func) = func {
6989 if let Value::Function(f) = func {
6990 let old_self_type = self.current_self_type.take();
6992 self.current_self_type = Some(type_name.clone());
6993
6994 let mut all_args = vec![recv.clone()];
6995 all_args.extend(arg_values.clone());
6996 let result = self.call_function(&f, all_args);
6997
6998 self.current_self_type = old_self_type;
7000 return result;
7001 } else if let Value::BuiltIn(b) = func {
7002 let mut all_args = vec![recv.clone()];
7003 all_args.extend(arg_values.clone());
7004 return (b.func)(self, all_args);
7005 }
7006 }
7007 }
7008 }
7009 }
7010 }
7011
7012 crate::sigil_warn!("WARN: Unknown method '{}' on '{}' - returning null", method.name, name);
7015 Ok(Value::Null)
7016 }
7017 (Value::Variant { enum_name, variant_name, fields }, _) => {
7019 if enum_name == "Option" {
7021 match method.name.as_str() {
7022 "cloned" => {
7023 return Ok(recv.clone());
7026 }
7027 "is_some" => {
7028 return Ok(Value::Bool(variant_name == "Some"));
7029 }
7030 "is_none" => {
7031 return Ok(Value::Bool(variant_name == "None"));
7032 }
7033 "unwrap" => {
7034 crate::sigil_debug!("DEBUG Option.unwrap: variant={}, fields={:?}", variant_name, fields);
7035 if variant_name == "Some" {
7036 if let Some(f) = fields {
7037 let result = f.first().cloned().unwrap_or(Value::Null);
7038 crate::sigil_debug!("DEBUG Option.unwrap: returning {:?}", result);
7039 return Ok(result);
7040 }
7041 }
7042 return Err(RuntimeError::new("unwrap on None"));
7043 }
7044 "unwrap_or" => {
7045 if variant_name == "Some" {
7046 if let Some(f) = fields {
7047 return Ok(f.first().cloned().unwrap_or(Value::Null));
7048 }
7049 }
7050 return Ok(arg_values.first().cloned().unwrap_or(Value::Null));
7051 }
7052 "map" => {
7053 if variant_name == "Some" {
7055 if let Some(f) = fields {
7056 if let Some(inner) = f.first() {
7057 if let Some(Value::Function(func)) = arg_values.first() {
7058 let result = self.call_function(func, vec![inner.clone()])?;
7059 return Ok(Value::Variant {
7060 enum_name: "Option".to_string(),
7061 variant_name: "Some".to_string(),
7062 fields: Some(Rc::new(vec![result])),
7063 });
7064 }
7065 }
7066 }
7067 }
7068 return Ok(Value::Variant {
7069 enum_name: "Option".to_string(),
7070 variant_name: "None".to_string(),
7071 fields: None,
7072 });
7073 }
7074 "and_then" => {
7075 crate::sigil_debug!("DEBUG and_then: variant={}, has_fields={}, arg_count={}", variant_name, fields.is_some(), arg_values.len());
7077 if let Some(arg) = arg_values.first() {
7078 crate::sigil_debug!("DEBUG and_then: arg type = {:?}", std::mem::discriminant(arg));
7079 }
7080 if variant_name == "Some" {
7081 if let Some(f) = fields {
7082 if let Some(inner) = f.first() {
7083 crate::sigil_debug!("DEBUG and_then: inner = {:?}", inner);
7084 if let Some(Value::Function(func)) = arg_values.first() {
7085 let result = self.call_function(func, vec![inner.clone()])?;
7086 crate::sigil_debug!("DEBUG and_then: result = {:?}", result);
7087 return Ok(result);
7089 } else {
7090 crate::sigil_debug!("DEBUG and_then: arg is not a Function!");
7091 }
7092 }
7093 }
7094 }
7095 return Ok(Value::Variant {
7097 enum_name: "Option".to_string(),
7098 variant_name: "None".to_string(),
7099 fields: None,
7100 });
7101 }
7102 "or_else" => {
7103 if variant_name == "Some" {
7105 return Ok(recv.clone());
7107 }
7108 if let Some(Value::Function(func)) = arg_values.first() {
7110 return self.call_function(func, vec![]);
7111 }
7112 return Ok(recv.clone());
7113 }
7114 "ok_or" | "ok_or_else" => {
7115 if variant_name == "Some" {
7117 if let Some(f) = fields {
7118 if let Some(inner) = f.first() {
7119 return Ok(Value::Variant {
7120 enum_name: "Result".to_string(),
7121 variant_name: "Ok".to_string(),
7122 fields: Some(Rc::new(vec![inner.clone()])),
7123 });
7124 }
7125 }
7126 }
7127 let err_val = arg_values.first().cloned().unwrap_or(Value::String(Rc::new("None".to_string())));
7129 return Ok(Value::Variant {
7130 enum_name: "Result".to_string(),
7131 variant_name: "Err".to_string(),
7132 fields: Some(Rc::new(vec![err_val])),
7133 });
7134 }
7135 _ => {}
7136 }
7137 }
7138 if enum_name == "Result" {
7140 match method.name.as_str() {
7141 "is_ok" => {
7142 return Ok(Value::Bool(variant_name == "Ok"));
7143 }
7144 "is_err" => {
7145 return Ok(Value::Bool(variant_name == "Err"));
7146 }
7147 "ok" => {
7148 if variant_name == "Ok" {
7151 let inner = fields.as_ref()
7152 .and_then(|f| f.first().cloned())
7153 .unwrap_or(Value::Null);
7154 return Ok(Value::Variant {
7155 enum_name: "Option".to_string(),
7156 variant_name: "Some".to_string(),
7157 fields: Some(Rc::new(vec![inner])),
7158 });
7159 }
7160 return Ok(Value::Variant {
7161 enum_name: "Option".to_string(),
7162 variant_name: "None".to_string(),
7163 fields: None,
7164 });
7165 }
7166 "err" => {
7167 if variant_name == "Err" {
7170 let inner = fields.as_ref()
7171 .and_then(|f| f.first().cloned())
7172 .unwrap_or(Value::Null);
7173 return Ok(Value::Variant {
7174 enum_name: "Option".to_string(),
7175 variant_name: "Some".to_string(),
7176 fields: Some(Rc::new(vec![inner])),
7177 });
7178 }
7179 return Ok(Value::Variant {
7180 enum_name: "Option".to_string(),
7181 variant_name: "None".to_string(),
7182 fields: None,
7183 });
7184 }
7185 "unwrap" => {
7186 if variant_name == "Ok" {
7187 if let Some(f) = fields {
7188 return Ok(f.first().cloned().unwrap_or(Value::Null));
7189 }
7190 }
7191 return Err(RuntimeError::new("unwrap on Err"));
7192 }
7193 "unwrap_or" => {
7194 if variant_name == "Ok" {
7195 if let Some(f) = fields {
7196 return Ok(f.first().cloned().unwrap_or(Value::Null));
7197 }
7198 }
7199 return Ok(arg_values.first().cloned().unwrap_or(Value::Null));
7200 }
7201 "map" => {
7202 if variant_name == "Ok" {
7204 if let Some(Value::Function(f)) = arg_values.first() {
7205 let inner = fields.as_ref()
7206 .and_then(|f| f.first().cloned())
7207 .unwrap_or(Value::Null);
7208 let result = self.call_function(f, vec![inner])?;
7209 return Ok(Value::Variant {
7210 enum_name: "Result".to_string(),
7211 variant_name: "Ok".to_string(),
7212 fields: Some(Rc::new(vec![result])),
7213 });
7214 }
7215 }
7216 return Ok(recv.clone());
7218 }
7219 "map_err" => {
7220 if variant_name == "Err" {
7222 if let Some(Value::Function(f)) = arg_values.first() {
7223 let inner = fields.as_ref()
7224 .and_then(|f| f.first().cloned())
7225 .unwrap_or(Value::Null);
7226 let result = self.call_function(f, vec![inner])?;
7227 return Ok(Value::Variant {
7228 enum_name: "Result".to_string(),
7229 variant_name: "Err".to_string(),
7230 fields: Some(Rc::new(vec![result])),
7231 });
7232 }
7233 }
7234 return Ok(recv.clone());
7236 }
7237 "and_then" => {
7238 if variant_name == "Ok" {
7240 if let Some(Value::Function(f)) = arg_values.first() {
7241 let inner = fields.as_ref()
7242 .and_then(|f| f.first().cloned())
7243 .unwrap_or(Value::Null);
7244 return self.call_function(f, vec![inner]);
7245 }
7246 }
7247 return Ok(recv.clone());
7249 }
7250 _ => {}
7251 }
7252 }
7253 crate::sigil_debug!("DEBUG variant method call: enum_name={}, variant_name={}, method={}", enum_name, variant_name, method.name);
7255
7256 if enum_name == "Type" {
7258 match method.name.as_str() {
7259 "is_never" => {
7260 return Ok(Value::Bool(variant_name == "Never"));
7262 }
7263 "to_string" => {
7264 let type_str = match variant_name.as_str() {
7266 "Bool" => "bool".to_string(),
7267 "Int" => "i64".to_string(),
7268 "Float" => "f64".to_string(),
7269 "Str" => "str".to_string(),
7270 "Char" => "char".to_string(),
7271 "Unit" => "()".to_string(),
7272 "Never" => "!".to_string(),
7273 "Error" => "<error>".to_string(),
7274 other => format!("Type::{}", other),
7275 };
7276 return Ok(Value::String(Rc::new(type_str)));
7277 }
7278 _ => {}
7279 }
7280 }
7281
7282 if enum_name == "Pattern" {
7283 match method.name.as_str() {
7284 "evidentiality" => {
7285 if variant_name == "Ident" {
7287 if let Some(f) = fields {
7288 for field_val in f.iter() {
7291 if let Value::Struct { fields: inner, .. } = field_val {
7292 if let Some(ev) = inner.borrow().get("evidentiality") {
7293 return Ok(ev.clone());
7294 }
7295 }
7296 }
7297 if f.len() > 2 {
7299 return Ok(f[2].clone());
7300 }
7301 }
7302 }
7303 return Ok(Value::Null);
7305 }
7306 "name" => {
7307 if variant_name == "Ident" {
7309 if let Some(f) = fields {
7310 for field_val in f.iter() {
7311 if let Value::Struct { fields: inner, .. } = field_val {
7312 if let Some(n) = inner.borrow().get("name") {
7313 return Ok(n.clone());
7314 }
7315 }
7316 }
7317 if let Some(n) = f.first() {
7319 return Ok(n.clone());
7320 }
7321 }
7322 }
7323 return Ok(Value::Null);
7324 }
7325 "mutable" => {
7326 if variant_name == "Ident" {
7328 if let Some(f) = fields {
7329 for field_val in f.iter() {
7330 if let Value::Struct { fields: inner, .. } = field_val {
7331 if let Some(m) = inner.borrow().get("mutable") {
7332 return Ok(m.clone());
7333 }
7334 }
7335 }
7336 if f.len() > 1 {
7338 return Ok(f[1].clone());
7339 }
7340 }
7341 }
7342 return Ok(Value::Bool(false));
7343 }
7344 _ => {}
7345 }
7346 }
7347 if method.name == "clone" {
7349 return Ok(recv.clone());
7350 }
7351
7352 let qualified_name = format!("{}·{}", enum_name, method.name);
7353 let func = self.globals.borrow().get(&qualified_name).map(|v| v.clone());
7354 if let Some(func) = func {
7355 if let Value::Function(f) = func {
7356 let mut all_args = vec![recv.clone()];
7357 all_args.extend(arg_values.clone());
7358 return self.call_function(&f, all_args);
7359 } else if let Value::BuiltIn(b) = func {
7360 let mut all_args = vec![recv.clone()];
7361 all_args.extend(arg_values.clone());
7362 return (b.func)(self, all_args);
7363 }
7364 }
7365 crate::sigil_warn!("WARN: Unknown method '{}' on enum '{}' - returning null", method.name, enum_name);
7367 Ok(Value::Null)
7368 }
7369 (Value::Null, "len_utf8") => Ok(Value::Int(0)),
7371 (Value::Null, "is_ascii") => Ok(Value::Bool(false)),
7372 (Value::Null, "is_alphabetic") => Ok(Value::Bool(false)),
7373 (Value::Null, "is_alphanumeric") => Ok(Value::Bool(false)),
7374 (Value::Null, "is_numeric") | (Value::Null, "is_digit") => Ok(Value::Bool(false)),
7375 (Value::Null, "is_whitespace") => Ok(Value::Bool(false)),
7376 (Value::Null, "is_uppercase") => Ok(Value::Bool(false)),
7377 (Value::Null, "is_lowercase") => Ok(Value::Bool(false)),
7378 (Value::Null, "len") => Ok(Value::Int(0)),
7379 (Value::Null, "is_empty") => Ok(Value::Bool(true)),
7380 (Value::Null, "to_string") => Ok(Value::String(Rc::new("".to_string()))),
7381 (Value::Null, "clone") => Ok(Value::Null),
7382 (Value::Null, "is_some") => Ok(Value::Bool(false)),
7383 (Value::Null, "is_none") => Ok(Value::Bool(true)),
7384 (Value::Null, "unwrap_or") => {
7385 if arg_values.is_empty() {
7386 Ok(Value::Null)
7387 } else {
7388 Ok(arg_values[0].clone())
7389 }
7390 }
7391 (Value::Char(c), "unwrap_or") => Ok(Value::Char(*c)),
7393 (Value::Int(n), "unwrap_or") => Ok(Value::Int(*n)),
7394 (Value::Float(n), "unwrap_or") => Ok(Value::Float(*n)),
7395 (Value::String(s), "unwrap_or") => Ok(Value::String(s.clone())),
7396 (Value::Bool(b), "unwrap_or") => Ok(Value::Bool(*b)),
7397 (Value::Int(n), "to_string") | (Value::Int(n), "string") => {
7399 Ok(Value::String(Rc::new(n.to_string())))
7400 }
7401 (Value::Int(n), "abs") => Ok(Value::Int(n.abs())),
7402 (Value::Int(n), "to_float") | (Value::Int(n), "float") => Ok(Value::Float(*n as f64)),
7403 (Value::Int(n), "duration_since") => {
7404 let other_ns = match arg_values.first() {
7407 Some(Value::Int(i)) => *i,
7408 Some(Value::Struct { fields, .. }) => {
7409 let borrowed = fields.borrow();
7410 let secs = match borrowed.get("secs") {
7411 Some(Value::Int(s)) => *s,
7412 _ => 0,
7413 };
7414 let nanos = match borrowed.get("nanos") {
7415 Some(Value::Int(n)) => *n,
7416 _ => 0,
7417 };
7418 secs * 1_000_000_000 + nanos
7419 }
7420 _ => 0,
7421 };
7422 let diff_ns = n - other_ns;
7423 let mut fields = std::collections::HashMap::new();
7424 fields.insert("secs".to_string(), Value::Int(diff_ns / 1_000_000_000));
7425 fields.insert("nanos".to_string(), Value::Int(diff_ns % 1_000_000_000));
7426 Ok(Value::Variant {
7427 enum_name: "Result".to_string(),
7428 variant_name: "Ok".to_string(),
7429 fields: Some(Rc::new(vec![Value::Struct {
7430 name: "Duration".to_string(),
7431 fields: Rc::new(RefCell::new(fields)),
7432 }])),
7433 })
7434 }
7435 (Value::Float(n), "to_string") | (Value::Float(n), "string") => {
7437 Ok(Value::String(Rc::new(n.to_string())))
7438 }
7439 (Value::Float(n), "abs") => Ok(Value::Float(n.abs())),
7440 (Value::Float(n), "to_int") | (Value::Float(n), "int") => Ok(Value::Int(*n as i64)),
7441 (Value::Bool(b), "to_string") | (Value::Bool(b), "string") => {
7443 Ok(Value::String(Rc::new(b.to_string())))
7444 }
7445 (Value::Char(c), "to_string") | (Value::Char(c), "string") => {
7447 Ok(Value::String(Rc::new(c.to_string())))
7448 }
7449 _ => {
7450 let recv_type = match &recv {
7452 Value::String(s) => format!("String(len={})", s.len()),
7453 Value::Array(arr) => format!("Array(len={})", arr.borrow().len()),
7454 Value::Struct { name, .. } => format!("Struct({})", name),
7455 Value::Variant { enum_name, variant_name, .. } => format!("Variant({}::{})", enum_name, variant_name),
7456 Value::Ref(r) => format!("Ref({:?})", std::mem::discriminant(&*r.borrow())),
7457 Value::Null => "Null".to_string(),
7458 other => format!("{:?}", std::mem::discriminant(other)),
7459 };
7460 crate::sigil_warn!("WARN: Unknown method '{}' on recv_type={} - returning null", method.name, recv_type);
7461 Ok(Value::Null)
7463 }
7464 }
7465 }
7466
7467 fn eval_incorporation(
7470 &mut self,
7471 segments: &[IncorporationSegment],
7472 ) -> Result<Value, RuntimeError> {
7473 if segments.is_empty() {
7474 return Err(RuntimeError::new("empty incorporation chain"));
7475 }
7476
7477 let first = &segments[0];
7479 let mut value = if let Some(args) = &first.args {
7480 let arg_values: Vec<Value> = args
7482 .iter()
7483 .map(|a| self.evaluate(a))
7484 .collect::<Result<_, _>>()?;
7485 self.call_function_by_name(&first.name.name, arg_values)?
7486 } else {
7487 self.environment
7489 .borrow()
7490 .get(&first.name.name)
7491 .ok_or_else(|| RuntimeError::new(format!("undefined: {}", first.name.name)))?
7492 };
7493
7494 for segment in segments.iter().skip(1) {
7496 let arg_values: Vec<Value> = segment
7497 .args
7498 .as_ref()
7499 .map(|args| {
7500 args.iter()
7501 .map(|a| self.evaluate(a))
7502 .collect::<Result<Vec<_>, _>>()
7503 })
7504 .transpose()?
7505 .unwrap_or_default();
7506
7507 value = self.call_incorporation_method(&value, &segment.name.name, arg_values)?;
7509 }
7510
7511 Ok(value)
7512 }
7513
7514 fn call_incorporation_method(
7517 &mut self,
7518 receiver: &Value,
7519 method_name: &str,
7520 args: Vec<Value>,
7521 ) -> Result<Value, RuntimeError> {
7522 match (receiver, method_name) {
7524 (Value::String(s), "len") => Ok(Value::Int(s.len() as i64)),
7526 (Value::String(s), "upper") | (Value::String(s), "uppercase") | (Value::String(s), "to_uppercase") => {
7527 Ok(Value::String(Rc::new(s.to_uppercase())))
7528 }
7529 (Value::String(s), "lower") | (Value::String(s), "lowercase") | (Value::String(s), "to_lowercase") => {
7530 Ok(Value::String(Rc::new(s.to_lowercase())))
7531 }
7532 (Value::String(s), "trim") => Ok(Value::String(Rc::new(s.trim().to_string()))),
7533 (Value::String(s), "chars") => {
7534 let chars: Vec<Value> = s
7535 .chars()
7536 .map(|c| Value::String(Rc::new(c.to_string())))
7537 .collect();
7538 Ok(Value::Array(Rc::new(RefCell::new(chars))))
7539 }
7540 (Value::String(s), "lines") => {
7541 let lines: Vec<Value> = s
7542 .lines()
7543 .map(|l| Value::String(Rc::new(l.to_string())))
7544 .collect();
7545 Ok(Value::Array(Rc::new(RefCell::new(lines))))
7546 }
7547 (Value::String(s), "bytes") => {
7548 let bytes: Vec<Value> = s.bytes().map(|b| Value::Int(b as i64)).collect();
7549 Ok(Value::Array(Rc::new(RefCell::new(bytes))))
7550 }
7551 (Value::String(s), "parse_int") | (Value::String(s), "to_int") => s
7552 .parse::<i64>()
7553 .map(Value::Int)
7554 .map_err(|_| RuntimeError::new(format!("cannot parse '{}' as int", s))),
7555 (Value::String(s), "parse_float") | (Value::String(s), "to_float") => s
7556 .parse::<f64>()
7557 .map(Value::Float)
7558 .map_err(|_| RuntimeError::new(format!("cannot parse '{}' as float", s))),
7559 (Value::String(s), "as_str") => {
7560 if s.len() <= 10 { crate::sigil_debug!("DEBUG as_str: '{}'", s); }
7561 Ok(Value::String(s.clone()))
7562 }
7563 (Value::String(s), "to_string") => Ok(Value::String(s.clone())),
7564 (Value::String(s), "starts_with") => {
7565 if args.len() != 1 {
7566 return Err(RuntimeError::new("starts_with expects 1 argument"));
7567 }
7568 match &args[0] {
7569 Value::String(prefix) => Ok(Value::Bool(s.starts_with(prefix.as_str()))),
7570 _ => Err(RuntimeError::new("starts_with expects string")),
7571 }
7572 }
7573 (Value::String(s), "ends_with") => {
7574 if args.len() != 1 {
7575 return Err(RuntimeError::new("ends_with expects 1 argument"));
7576 }
7577 match &args[0] {
7578 Value::String(suffix) => Ok(Value::Bool(s.ends_with(suffix.as_str()))),
7579 _ => Err(RuntimeError::new("ends_with expects string")),
7580 }
7581 }
7582 (Value::String(s), "is_empty") => Ok(Value::Bool(s.is_empty())),
7583 (Value::String(s), "clone") => Ok(Value::String(Rc::new((**s).clone()))),
7584 (Value::String(s), "first") => s
7585 .chars()
7586 .next()
7587 .map(Value::Char)
7588 .ok_or_else(|| RuntimeError::new("empty string")),
7589 (Value::String(s), "last") => s
7590 .chars()
7591 .last()
7592 .map(Value::Char)
7593 .ok_or_else(|| RuntimeError::new("empty string")),
7594
7595 (Value::Array(arr), "len") => Ok(Value::Int(arr.borrow().len() as i64)),
7597 (Value::Array(arr), "first") | (Value::Array(arr), "next") => Ok(arr
7598 .borrow()
7599 .first()
7600 .cloned()
7601 .unwrap_or(Value::Null)),
7602 (Value::Array(arr), "last") => arr
7603 .borrow()
7604 .last()
7605 .cloned()
7606 .ok_or_else(|| RuntimeError::new("empty array")),
7607 (Value::Array(arr), "reverse") | (Value::Array(arr), "rev") => {
7608 let mut v = arr.borrow().clone();
7609 v.reverse();
7610 Ok(Value::Array(Rc::new(RefCell::new(v))))
7611 }
7612 (Value::Array(arr), "join") => {
7613 let sep = args
7614 .first()
7615 .map(|v| match v {
7616 Value::String(s) => s.to_string(),
7617 _ => "".to_string(),
7618 })
7619 .unwrap_or_default();
7620 let joined = arr
7621 .borrow()
7622 .iter()
7623 .map(|v| format!("{}", v))
7624 .collect::<Vec<_>>()
7625 .join(&sep);
7626 Ok(Value::String(Rc::new(joined)))
7627 }
7628 (Value::Array(arr), "sum") => {
7629 let mut sum = 0i64;
7630 for v in arr.borrow().iter() {
7631 match v {
7632 Value::Int(i) => sum += i,
7633 Value::Float(f) => return Ok(Value::Float(sum as f64 + f)),
7634 _ => {}
7635 }
7636 }
7637 Ok(Value::Int(sum))
7638 }
7639 (Value::Array(arr), "skip") => {
7640 let n = match args.first() {
7641 Some(Value::Int(i)) => *i as usize,
7642 _ => 1,
7643 };
7644 let v: Vec<Value> = arr.borrow().iter().skip(n).cloned().collect();
7645 Ok(Value::Array(Rc::new(RefCell::new(v))))
7646 }
7647 (Value::Array(arr), "take") => {
7648 let n = match args.first() {
7649 Some(Value::Int(i)) => *i as usize,
7650 _ => 1,
7651 };
7652 let v: Vec<Value> = arr.borrow().iter().take(n).cloned().collect();
7653 Ok(Value::Array(Rc::new(RefCell::new(v))))
7654 }
7655 (Value::Array(arr), "step_by") => {
7656 let n = match args.first() {
7657 Some(Value::Int(i)) if *i > 0 => *i as usize,
7658 _ => 1,
7659 };
7660 let v: Vec<Value> = arr.borrow().iter().step_by(n).cloned().collect();
7661 Ok(Value::Array(Rc::new(RefCell::new(v))))
7662 }
7663
7664 (Value::Int(n), "abs") => Ok(Value::Int(n.abs())),
7666 (Value::Float(n), "abs") => Ok(Value::Float(n.abs())),
7667 (Value::Int(n), "to_string") | (Value::Int(n), "string") => {
7668 Ok(Value::String(Rc::new(n.to_string())))
7669 }
7670 (Value::Float(n), "to_string") | (Value::Float(n), "string") => {
7671 Ok(Value::String(Rc::new(n.to_string())))
7672 }
7673 (Value::Int(n), "to_float") | (Value::Int(n), "float") => Ok(Value::Float(*n as f64)),
7674 (Value::Float(n), "to_int") | (Value::Float(n), "int") => Ok(Value::Int(*n as i64)),
7675
7676 (Value::Map(map), field) => map
7678 .borrow()
7679 .get(field)
7680 .cloned()
7681 .ok_or_else(|| RuntimeError::new(format!("no field '{}' in map", field))),
7682 (Value::Struct { fields, .. }, field) => fields
7683 .borrow()
7684 .get(field)
7685 .cloned()
7686 .ok_or_else(|| RuntimeError::new(format!("no field '{}' in struct", field))),
7687
7688 _ => {
7690 let mut all_args = vec![receiver.clone()];
7691 all_args.extend(args);
7692 self.call_function_by_name(method_name, all_args)
7693 }
7694 }
7695 }
7696
7697 pub fn call_function_by_name(
7699 &mut self,
7700 name: &str,
7701 args: Vec<Value>,
7702 ) -> Result<Value, RuntimeError> {
7703 let func_value = self.environment.borrow().get(name);
7705
7706 match func_value {
7707 Some(Value::Function(f)) => self.call_function(&f, args),
7708 Some(Value::BuiltIn(b)) => self.call_builtin(&b, args),
7709 Some(_) => Err(RuntimeError::new(format!("{} is not a function", name))),
7710 None => {
7711 if let Some((enum_name, variant_name, arity)) = self.variant_constructors.get(name).cloned() {
7713 if arity == 0 && args.is_empty() {
7714 return Ok(Value::Variant {
7715 enum_name,
7716 variant_name,
7717 fields: None,
7718 });
7719 } else if args.len() == arity {
7720 return Ok(Value::Variant {
7721 enum_name,
7722 variant_name,
7723 fields: Some(Rc::new(args)),
7724 });
7725 } else {
7726 return Err(RuntimeError::new(format!(
7727 "{} expects {} arguments, got {}",
7728 name, arity, args.len()
7729 )));
7730 }
7731 }
7732 Err(RuntimeError::new(format!("undefined function: {}", name)))
7733 }
7734 }
7735 }
7736
7737 fn eval_pipe(&mut self, expr: &Expr, operations: &[PipeOp]) -> Result<Value, RuntimeError> {
7738 let mut value = self.evaluate(expr)?;
7739
7740 for op in operations {
7741 value = self.apply_pipe_op(value, op)?;
7742 }
7743
7744 Ok(value)
7745 }
7746
7747 fn apply_pipe_op(&mut self, value: Value, op: &PipeOp) -> Result<Value, RuntimeError> {
7748 let value = Self::unwrap_all(&value);
7750
7751 match op {
7752 PipeOp::Transform(body) => {
7753 let (param_pattern, inner_body) = match body.as_ref() {
7756 Expr::Closure { params, body, .. } => {
7757 let pattern = params.first().map(|p| p.pattern.clone());
7758 (pattern, body.as_ref())
7759 }
7760 _ => (None, body.as_ref()),
7761 };
7762
7763 match value {
7764 Value::Array(arr) => {
7765 let results: Vec<Value> = arr
7766 .borrow()
7767 .iter()
7768 .map(|item| {
7769 if let Some(ref pattern) = param_pattern {
7771 self.bind_pattern(pattern, item.clone())?;
7772 } else {
7773 self.environment
7774 .borrow_mut()
7775 .define("_".to_string(), item.clone());
7776 }
7777 self.evaluate(inner_body)
7778 })
7779 .collect::<Result<_, _>>()?;
7780 Ok(Value::Array(Rc::new(RefCell::new(results))))
7781 }
7782 single => {
7783 if let Some(ref pattern) = param_pattern {
7784 self.bind_pattern(pattern, single)?;
7785 } else {
7786 self.environment
7787 .borrow_mut()
7788 .define("_".to_string(), single);
7789 }
7790 self.evaluate(inner_body)
7791 }
7792 }
7793 }
7794 PipeOp::Filter(predicate) => {
7795 let (param_pattern, inner_pred) = match predicate.as_ref() {
7798 Expr::Closure { params, body, .. } => {
7799 let pattern = params.first().map(|p| p.pattern.clone());
7800 (pattern, body.as_ref())
7801 }
7802 _ => (None, predicate.as_ref()),
7803 };
7804
7805 match value {
7806 Value::Array(arr) => {
7807 let results: Vec<Value> = arr
7808 .borrow()
7809 .iter()
7810 .filter_map(|item| {
7811 if let Some(ref pattern) = param_pattern {
7813 if let Err(e) = self.bind_pattern(pattern, item.clone()) {
7814 return Some(Err(e));
7815 }
7816 } else {
7817 self.environment
7818 .borrow_mut()
7819 .define("_".to_string(), item.clone());
7820 }
7821 match self.evaluate(inner_pred) {
7822 Ok(v) if self.is_truthy(&v) => Some(Ok(item.clone())),
7823 Ok(_) => None,
7824 Err(e) => Some(Err(e)),
7825 }
7826 })
7827 .collect::<Result<_, _>>()?;
7828 Ok(Value::Array(Rc::new(RefCell::new(results))))
7829 }
7830 _ => Err(RuntimeError::new("Filter requires array")),
7831 }
7832 }
7833 PipeOp::Sort(field) => {
7834 match value {
7836 Value::Array(arr) => {
7837 let mut v = arr.borrow().clone();
7838 v.sort_by(|a, b| self.compare_values(a, b, field));
7839 Ok(Value::Array(Rc::new(RefCell::new(v))))
7840 }
7841 _ => Err(RuntimeError::new("Sort requires array")),
7842 }
7843 }
7844 PipeOp::Reduce(body) => {
7845 match value {
7847 Value::Array(arr) => {
7848 let arr = arr.borrow();
7849 if arr.is_empty() {
7850 return Err(RuntimeError::new("Cannot reduce empty array"));
7851 }
7852 let mut acc = arr[0].clone();
7853 for item in arr.iter().skip(1) {
7854 self.environment.borrow_mut().define("acc".to_string(), acc);
7855 self.environment
7856 .borrow_mut()
7857 .define("_".to_string(), item.clone());
7858 acc = self.evaluate(body)?;
7859 }
7860 Ok(acc)
7861 }
7862 _ => Err(RuntimeError::new("Reduce requires array")),
7863 }
7864 }
7865 PipeOp::ReduceSum => {
7866 self.sum_values(value)
7868 }
7869 PipeOp::ReduceProd => {
7870 self.product_values(value)
7872 }
7873 PipeOp::ReduceMin => {
7874 self.min_values(value)
7876 }
7877 PipeOp::ReduceMax => {
7878 self.max_values(value)
7880 }
7881 PipeOp::ReduceConcat => {
7882 self.concat_values(value)
7884 }
7885 PipeOp::ReduceAll => {
7886 self.all_values(value)
7888 }
7889 PipeOp::ReduceAny => {
7890 self.any_values(value)
7892 }
7893 PipeOp::Match(arms) => {
7894 for arm in arms {
7896 if self.pattern_matches(&arm.pattern, &value)? {
7897 let prev_env = self.environment.clone();
7899 self.environment =
7900 Rc::new(RefCell::new(Environment::with_parent(prev_env.clone())));
7901
7902 self.bind_pattern(&arm.pattern, value.clone())?;
7904
7905 self.environment
7907 .borrow_mut()
7908 .define("_".to_string(), value.clone());
7909
7910 let guard_passes = if let Some(guard) = &arm.guard {
7912 matches!(self.evaluate(guard)?, Value::Bool(true))
7913 } else {
7914 true
7915 };
7916
7917 if guard_passes {
7918 let result = self.evaluate(&arm.body)?;
7919 self.environment = prev_env;
7920 return Ok(result);
7921 }
7922
7923 self.environment = prev_env;
7925 }
7926 }
7927 Err(RuntimeError::new("No pattern matched in pipe match"))
7928 }
7929 PipeOp::TryMap(mapper) => {
7930 match &value {
7932 Value::Struct { name, fields } if name == "Ok" || name.ends_with("::Ok") => {
7934 let fields = fields.borrow();
7936 fields
7937 .get("0")
7938 .or_else(|| fields.get("value"))
7939 .cloned()
7940 .ok_or_else(|| RuntimeError::new("Ok variant has no value"))
7941 }
7942 Value::Struct { name, fields } if name == "Err" || name.ends_with("::Err") => {
7943 let fields = fields.borrow();
7945 let err_val = fields
7946 .get("0")
7947 .or_else(|| fields.get("error"))
7948 .cloned()
7949 .unwrap_or(Value::Null);
7950 if let Some(mapper_expr) = mapper {
7951 let prev_env = self.environment.clone();
7953 self.environment =
7954 Rc::new(RefCell::new(Environment::with_parent(prev_env.clone())));
7955 self.environment
7956 .borrow_mut()
7957 .define("_".to_string(), err_val);
7958 let mapped = self.evaluate(mapper_expr)?;
7959 self.environment = prev_env;
7960 Err(RuntimeError::new(format!("Error: {:?}", mapped)))
7961 } else {
7962 Err(RuntimeError::new(format!("Error: {:?}", err_val)))
7963 }
7964 }
7965 Value::Struct { name, fields }
7967 if name == "Some" || name.ends_with("::Some") =>
7968 {
7969 let fields = fields.borrow();
7970 fields
7971 .get("0")
7972 .or_else(|| fields.get("value"))
7973 .cloned()
7974 .ok_or_else(|| RuntimeError::new("Some variant has no value"))
7975 }
7976 Value::Struct { name, .. } if name == "None" || name.ends_with("::None") => {
7977 Err(RuntimeError::new("Unwrapped None value"))
7978 }
7979 Value::Null => Err(RuntimeError::new("Unwrapped null value")),
7980 _ => Ok(value),
7982 }
7983 }
7984 PipeOp::Call(callee) => {
7985 let callee_val = self.evaluate(callee)?;
7987 match callee_val {
7988 Value::Function(f) => {
7989 self.call_function(&f, vec![value])
7991 }
7992 Value::BuiltIn(b) => {
7993 self.call_builtin(&b, vec![value])
7995 }
7996 Value::Struct { .. } => {
7997 Ok(value)
8000 }
8001 _ => Err(RuntimeError::new(format!(
8002 "Cannot call non-function value in pipe: {:?}",
8003 callee_val
8004 ))),
8005 }
8006 }
8007 PipeOp::Method { name, type_args: _, args } => {
8008 let arg_values: Vec<Value> = args
8009 .iter()
8010 .map(|a| self.evaluate(a))
8011 .collect::<Result<_, _>>()?;
8012
8013 match name.name.as_str() {
8015 "collect" => Ok(value), "sum" | "Σ" => self.sum_values(value),
8017 "product" | "Π" => self.product_values(value),
8018 "len" => match &value {
8019 Value::Array(arr) => Ok(Value::Int(arr.borrow().len() as i64)),
8020 Value::String(s) => Ok(Value::Int(s.len() as i64)),
8021 _ => Err(RuntimeError::new("len requires array or string")),
8022 },
8023 "reverse" => match value {
8024 Value::Array(arr) => {
8025 let mut v = arr.borrow().clone();
8026 v.reverse();
8027 Ok(Value::Array(Rc::new(RefCell::new(v))))
8028 }
8029 _ => Err(RuntimeError::new("reverse requires array")),
8030 },
8031 "iter" | "into_iter" => {
8032 Ok(value)
8034 },
8035 "enumerate" => {
8036 match &value {
8038 Value::Array(arr) => {
8039 let enumerated: Vec<Value> = arr
8040 .borrow()
8041 .iter()
8042 .enumerate()
8043 .map(|(i, v)| {
8044 Value::Tuple(Rc::new(vec![Value::Int(i as i64), v.clone()]))
8045 })
8046 .collect();
8047 Ok(Value::Array(Rc::new(RefCell::new(enumerated))))
8048 }
8049 _ => Err(RuntimeError::new("enumerate requires array")),
8050 }
8051 },
8052 "first" => match &value {
8053 Value::Array(arr) => arr
8054 .borrow()
8055 .first()
8056 .cloned()
8057 .ok_or_else(|| RuntimeError::new("first on empty array")),
8058 _ => Err(RuntimeError::new("first requires array")),
8059 },
8060 "last" => match &value {
8061 Value::Array(arr) => arr
8062 .borrow()
8063 .last()
8064 .cloned()
8065 .ok_or_else(|| RuntimeError::new("last on empty array")),
8066 _ => Err(RuntimeError::new("last requires array")),
8067 },
8068 "take" => {
8069 if arg_values.len() != 1 {
8070 return Err(RuntimeError::new("take requires 1 argument"));
8071 }
8072 let n = match &arg_values[0] {
8073 Value::Int(n) => *n as usize,
8074 _ => return Err(RuntimeError::new("take requires integer")),
8075 };
8076 match value {
8077 Value::Array(arr) => {
8078 let v: Vec<Value> = arr.borrow().iter().take(n).cloned().collect();
8079 Ok(Value::Array(Rc::new(RefCell::new(v))))
8080 }
8081 _ => Err(RuntimeError::new("take requires array")),
8082 }
8083 }
8084 "skip" => {
8085 if arg_values.len() != 1 {
8086 return Err(RuntimeError::new("skip requires 1 argument"));
8087 }
8088 let n = match &arg_values[0] {
8089 Value::Int(n) => *n as usize,
8090 _ => return Err(RuntimeError::new("skip requires integer")),
8091 };
8092 match value {
8093 Value::Array(arr) => {
8094 let v: Vec<Value> = arr.borrow().iter().skip(n).cloned().collect();
8095 Ok(Value::Array(Rc::new(RefCell::new(v))))
8096 }
8097 _ => Err(RuntimeError::new("skip requires array")),
8098 }
8099 }
8100 "join" => {
8101 let separator = if arg_values.is_empty() {
8103 String::new()
8104 } else {
8105 match &arg_values[0] {
8106 Value::String(s) => (**s).clone(),
8107 _ => return Err(RuntimeError::new("join separator must be string")),
8108 }
8109 };
8110 match value {
8111 Value::Array(arr) => {
8112 let parts: Vec<String> = arr.borrow().iter()
8113 .map(|v| format!("{}", Self::unwrap_all(v)))
8114 .collect();
8115 Ok(Value::String(Rc::new(parts.join(&separator))))
8116 }
8117 _ => Err(RuntimeError::new("join requires array")),
8118 }
8119 }
8120 "all" => {
8121 match value {
8123 Value::Array(arr) => {
8124 for item in arr.borrow().iter() {
8125 if !self.is_truthy(item) {
8126 return Ok(Value::Bool(false));
8127 }
8128 }
8129 Ok(Value::Bool(true))
8130 }
8131 _ => Err(RuntimeError::new("all requires array")),
8132 }
8133 }
8134 "any" => {
8135 match value {
8137 Value::Array(arr) => {
8138 for item in arr.borrow().iter() {
8139 if self.is_truthy(item) {
8140 return Ok(Value::Bool(true));
8141 }
8142 }
8143 Ok(Value::Bool(false))
8144 }
8145 _ => Err(RuntimeError::new("any requires array")),
8146 }
8147 }
8148 "map" => {
8149 if arg_values.len() != 1 {
8151 return Err(RuntimeError::new("map expects 1 argument (closure)"));
8152 }
8153 match (&value, &arg_values[0]) {
8154 (Value::Array(arr), Value::Function(f)) => {
8155 let mut results = Vec::new();
8156 for val in arr.borrow().iter() {
8157 let result = self.call_function(f, vec![val.clone()])?;
8158 results.push(result);
8159 }
8160 Ok(Value::Array(Rc::new(RefCell::new(results))))
8161 }
8162 (Value::Array(_), _) => Err(RuntimeError::new("map expects closure argument")),
8163 _ => Err(RuntimeError::new("map requires array")),
8164 }
8165 }
8166 "filter" => {
8167 if arg_values.len() != 1 {
8169 return Err(RuntimeError::new("filter expects 1 argument (closure)"));
8170 }
8171 match (&value, &arg_values[0]) {
8172 (Value::Array(arr), Value::Function(f)) => {
8173 let mut results = Vec::new();
8174 for val in arr.borrow().iter() {
8175 let keep = self.call_function(f, vec![val.clone()])?;
8176 if matches!(keep, Value::Bool(true)) {
8177 results.push(val.clone());
8178 }
8179 }
8180 Ok(Value::Array(Rc::new(RefCell::new(results))))
8181 }
8182 (Value::Array(_), _) => Err(RuntimeError::new("filter expects closure argument")),
8183 _ => Err(RuntimeError::new("filter requires array")),
8184 }
8185 }
8186 "fold" => {
8187 if arg_values.len() != 2 {
8189 return Err(RuntimeError::new("fold expects 2 arguments (init, closure)"));
8190 }
8191 match (&value, &arg_values[1]) {
8192 (Value::Array(arr), Value::Function(f)) => {
8193 let mut acc = arg_values[0].clone();
8194 for val in arr.borrow().iter() {
8195 acc = self.call_function(f, vec![acc, val.clone()])?;
8196 }
8197 Ok(acc)
8198 }
8199 (Value::Array(_), _) => Err(RuntimeError::new("fold expects closure as second argument")),
8200 _ => Err(RuntimeError::new("fold requires array")),
8201 }
8202 }
8203 _ => Err(RuntimeError::new(format!(
8204 "Unknown pipe method: {}",
8205 name.name
8206 ))),
8207 }
8208 }
8209 PipeOp::Await => {
8210 self.await_value(value)
8212 }
8213 PipeOp::First => {
8215 match &value {
8217 Value::Array(arr) => arr
8218 .borrow()
8219 .first()
8220 .cloned()
8221 .ok_or_else(|| RuntimeError::new("first (α) on empty array")),
8222 Value::Tuple(t) => t
8223 .first()
8224 .cloned()
8225 .ok_or_else(|| RuntimeError::new("first (α) on empty tuple")),
8226 _ => Err(RuntimeError::new("first (α) requires array or tuple")),
8227 }
8228 }
8229 PipeOp::Last => {
8230 match &value {
8232 Value::Array(arr) => arr
8233 .borrow()
8234 .last()
8235 .cloned()
8236 .ok_or_else(|| RuntimeError::new("last (ω) on empty array")),
8237 Value::Tuple(t) => t
8238 .last()
8239 .cloned()
8240 .ok_or_else(|| RuntimeError::new("last (ω) on empty tuple")),
8241 _ => Err(RuntimeError::new("last (ω) requires array or tuple")),
8242 }
8243 }
8244 PipeOp::Middle => {
8245 match &value {
8247 Value::Array(arr) => {
8248 let arr = arr.borrow();
8249 if arr.is_empty() {
8250 return Err(RuntimeError::new("middle (μ) on empty array"));
8251 }
8252 let mid = arr.len() / 2;
8253 Ok(arr[mid].clone())
8254 }
8255 Value::Tuple(t) => {
8256 if t.is_empty() {
8257 return Err(RuntimeError::new("middle (μ) on empty tuple"));
8258 }
8259 let mid = t.len() / 2;
8260 Ok(t[mid].clone())
8261 }
8262 _ => Err(RuntimeError::new("middle (μ) requires array or tuple")),
8263 }
8264 }
8265 PipeOp::Choice => {
8266 use std::time::{SystemTime, UNIX_EPOCH};
8268 match &value {
8269 Value::Array(arr) => {
8270 let arr = arr.borrow();
8271 if arr.is_empty() {
8272 return Err(RuntimeError::new("choice (χ) on empty array"));
8273 }
8274 let seed = SystemTime::now()
8275 .duration_since(UNIX_EPOCH)
8276 .unwrap_or(std::time::Duration::ZERO)
8277 .as_nanos() as u64;
8278 let idx = ((seed.wrapping_mul(1103515245).wrapping_add(12345)) >> 16)
8279 as usize
8280 % arr.len();
8281 Ok(arr[idx].clone())
8282 }
8283 Value::Tuple(t) => {
8284 if t.is_empty() {
8285 return Err(RuntimeError::new("choice (χ) on empty tuple"));
8286 }
8287 let seed = SystemTime::now()
8288 .duration_since(UNIX_EPOCH)
8289 .unwrap_or(std::time::Duration::ZERO)
8290 .as_nanos() as u64;
8291 let idx = ((seed.wrapping_mul(1103515245).wrapping_add(12345)) >> 16)
8292 as usize
8293 % t.len();
8294 Ok(t[idx].clone())
8295 }
8296 _ => Err(RuntimeError::new("choice (χ) requires array or tuple")),
8297 }
8298 }
8299 PipeOp::Nth(index_expr) => {
8300 let index = match self.evaluate(index_expr)? {
8302 Value::Int(n) => n,
8303 _ => return Err(RuntimeError::new("nth (ν) index must be integer")),
8304 };
8305 match &value {
8306 Value::Array(arr) => {
8307 let arr = arr.borrow();
8308 if index < 0 || index as usize >= arr.len() {
8309 return Err(RuntimeError::new("nth (ν) index out of bounds"));
8310 }
8311 Ok(arr[index as usize].clone())
8312 }
8313 Value::Tuple(t) => {
8314 if index < 0 || index as usize >= t.len() {
8315 return Err(RuntimeError::new("nth (ν) index out of bounds"));
8316 }
8317 Ok(t[index as usize].clone())
8318 }
8319 _ => Err(RuntimeError::new("nth (ν) requires array or tuple")),
8320 }
8321 }
8322 PipeOp::Next => {
8323 match &value {
8326 Value::Array(arr) => arr
8327 .borrow()
8328 .first()
8329 .cloned()
8330 .ok_or_else(|| RuntimeError::new("next (ξ) on empty array")),
8331 Value::Tuple(t) => t
8332 .first()
8333 .cloned()
8334 .ok_or_else(|| RuntimeError::new("next (ξ) on empty tuple")),
8335 _ => Err(RuntimeError::new("next (ξ) requires array or tuple")),
8336 }
8337 }
8338 PipeOp::Named { prefix, body } => {
8339 let method_name = prefix
8341 .iter()
8342 .map(|i| i.name.as_str())
8343 .collect::<Vec<_>>()
8344 .join("·");
8345 match method_name.as_str() {
8346 "map" => {
8347 if let Some(body) = body {
8348 match value {
8349 Value::Array(arr) => {
8350 let results: Vec<Value> = arr
8351 .borrow()
8352 .iter()
8353 .map(|item| {
8354 self.environment
8355 .borrow_mut()
8356 .define("_".to_string(), item.clone());
8357 self.evaluate(body)
8358 })
8359 .collect::<Result<_, _>>()?;
8360 Ok(Value::Array(Rc::new(RefCell::new(results))))
8361 }
8362 _ => Err(RuntimeError::new("map requires array")),
8363 }
8364 } else {
8365 Ok(value)
8366 }
8367 }
8368 "filter" => {
8369 if let Some(body) = body {
8370 match value {
8371 Value::Array(arr) => {
8372 let results: Vec<Value> = arr
8373 .borrow()
8374 .iter()
8375 .filter_map(|item| {
8376 self.environment
8377 .borrow_mut()
8378 .define("_".to_string(), item.clone());
8379 match self.evaluate(body) {
8380 Ok(v) if self.is_truthy(&v) => {
8381 Some(Ok(item.clone()))
8382 }
8383 Ok(_) => None,
8384 Err(e) => Some(Err(e)),
8385 }
8386 })
8387 .collect::<Result<_, _>>()?;
8388 Ok(Value::Array(Rc::new(RefCell::new(results))))
8389 }
8390 _ => Err(RuntimeError::new("filter requires array")),
8391 }
8392 } else {
8393 Ok(value)
8394 }
8395 }
8396 "all" => {
8397 if let Some(body) = body {
8398 match value {
8399 Value::Array(arr) => {
8400 for item in arr.borrow().iter() {
8401 self.environment
8402 .borrow_mut()
8403 .define("_".to_string(), item.clone());
8404 let result = self.evaluate(body)?;
8405 if !self.is_truthy(&result) {
8406 return Ok(Value::Bool(false));
8407 }
8408 }
8409 Ok(Value::Bool(true))
8410 }
8411 _ => Err(RuntimeError::new("all requires array")),
8412 }
8413 } else {
8414 match value {
8416 Value::Array(arr) => {
8417 for item in arr.borrow().iter() {
8418 if !self.is_truthy(item) {
8419 return Ok(Value::Bool(false));
8420 }
8421 }
8422 Ok(Value::Bool(true))
8423 }
8424 _ => Err(RuntimeError::new("all requires array")),
8425 }
8426 }
8427 }
8428 "any" => {
8429 if let Some(body) = body {
8430 match value {
8431 Value::Array(arr) => {
8432 for item in arr.borrow().iter() {
8433 self.environment
8434 .borrow_mut()
8435 .define("_".to_string(), item.clone());
8436 let result = self.evaluate(body)?;
8437 if self.is_truthy(&result) {
8438 return Ok(Value::Bool(true));
8439 }
8440 }
8441 Ok(Value::Bool(false))
8442 }
8443 _ => Err(RuntimeError::new("any requires array")),
8444 }
8445 } else {
8446 match value {
8448 Value::Array(arr) => {
8449 for item in arr.borrow().iter() {
8450 if self.is_truthy(item) {
8451 return Ok(Value::Bool(true));
8452 }
8453 }
8454 Ok(Value::Bool(false))
8455 }
8456 _ => Err(RuntimeError::new("any requires array")),
8457 }
8458 }
8459 }
8460 _ => Err(RuntimeError::new(format!(
8461 "Unknown named morpheme: {}",
8462 method_name
8463 ))),
8464 }
8465 }
8466 PipeOp::Parallel(inner_op) => {
8467 match value {
8470 Value::Array(arr) => {
8471 use std::sync::{Arc, Mutex};
8472
8473 let arr_ref = arr.borrow();
8474 let len = arr_ref.len();
8475 if len == 0 {
8476 return Ok(Value::Array(Rc::new(RefCell::new(vec![]))));
8477 }
8478
8479 match inner_op.as_ref() {
8481 PipeOp::Transform(body) => {
8482 let num_threads = std::thread::available_parallelism()
8484 .map(|p| p.get())
8485 .unwrap_or(4)
8486 .min(len);
8487
8488 let _chunk_size = (len + num_threads - 1) / num_threads;
8490 let _results = Arc::new(Mutex::new(vec![Value::Null; len]));
8491 let items: Vec<Value> = arr_ref.clone();
8492 drop(arr_ref);
8493
8494 let _body_str = format!("{:?}", body);
8496
8497 let mut result_vec = Vec::with_capacity(len);
8501 for item in items.iter() {
8502 self.environment
8503 .borrow_mut()
8504 .define("_".to_string(), item.clone());
8505 result_vec.push(self.evaluate(body)?);
8506 }
8507 Ok(Value::Array(Rc::new(RefCell::new(result_vec))))
8508 }
8509 PipeOp::Filter(predicate) => {
8510 let items: Vec<Value> = arr_ref.clone();
8512 drop(arr_ref);
8513
8514 let mut result_vec = Vec::new();
8515 for item in items.iter() {
8516 self.environment
8517 .borrow_mut()
8518 .define("_".to_string(), item.clone());
8519 let pred_result = self.evaluate(predicate)?;
8520 if self.is_truthy(&pred_result) {
8521 result_vec.push(item.clone());
8522 }
8523 }
8524 Ok(Value::Array(Rc::new(RefCell::new(result_vec))))
8525 }
8526 _ => {
8527 drop(arr_ref);
8529 self.apply_pipe_op(Value::Array(arr), inner_op)
8530 }
8531 }
8532 }
8533 _ => {
8534 self.apply_pipe_op(value, inner_op)
8536 }
8537 }
8538 }
8539 PipeOp::Gpu(inner_op) => {
8540 match value {
8547 Value::Array(arr) => {
8548 #[cfg(debug_assertions)]
8551 eprintln!(
8552 "[GPU] Would execute {:?} on GPU, falling back to CPU",
8553 inner_op
8554 );
8555
8556 self.apply_pipe_op(Value::Array(arr), inner_op)
8557 }
8558 _ => self.apply_pipe_op(value, inner_op),
8559 }
8560 }
8561
8562 PipeOp::Send(data_expr) => {
8568 let data = self.evaluate(data_expr)?;
8571
8572 let response = self.protocol_send(&value, &data)?;
8575
8576 Ok(self.wrap_reported(response))
8578 }
8579
8580 PipeOp::Recv => {
8581 let response = self.protocol_recv(&value)?;
8586
8587 Ok(self.wrap_reported(response))
8589 }
8590
8591 PipeOp::Stream(handler_expr) => {
8592 let handler = self.evaluate(handler_expr)?;
8594
8595 let stream = self.protocol_stream(&value, &handler)?;
8598 Ok(stream)
8599 }
8600
8601 PipeOp::Connect(config_expr) => {
8602 let config = match config_expr {
8604 Some(expr) => Some(self.evaluate(expr)?),
8605 None => None,
8606 };
8607
8608 let connection = self.protocol_connect(&value, config.as_ref())?;
8610 Ok(connection)
8611 }
8612
8613 PipeOp::Close => {
8614 self.protocol_close(&value)?;
8616 Ok(Value::Null)
8617 }
8618
8619 PipeOp::Header {
8620 name,
8621 value: value_expr,
8622 } => {
8623 let header_name = self.evaluate(name)?;
8625 let header_value = self.evaluate(value_expr)?;
8626
8627 self.protocol_add_header(value, &header_name, &header_value)
8629 }
8630
8631 PipeOp::Body(data_expr) => {
8632 let body_data = self.evaluate(data_expr)?;
8634
8635 self.protocol_set_body(value, &body_data)
8637 }
8638
8639 PipeOp::Timeout(ms_expr) => {
8640 let ms = self.evaluate(ms_expr)?;
8642
8643 self.protocol_set_timeout(value, &ms)
8645 }
8646
8647 PipeOp::Retry { count, strategy } => {
8648 let retry_count = self.evaluate(count)?;
8650 let retry_strategy = match strategy {
8651 Some(s) => Some(self.evaluate(s)?),
8652 None => None,
8653 };
8654
8655 self.protocol_set_retry(value, &retry_count, retry_strategy.as_ref())
8657 }
8658
8659 PipeOp::Validate {
8663 predicate,
8664 target_evidence,
8665 } => {
8666 let predicate_result = match predicate.as_ref() {
8669 Expr::Closure { params, body, .. } => {
8670 if let Some(param) = params.first() {
8671 let param_name = match ¶m.pattern {
8672 Pattern::Ident { name, .. } => name.name.clone(),
8673 _ => "it".to_string(),
8674 };
8675 self.environment
8676 .borrow_mut()
8677 .define(param_name, value.clone());
8678 }
8679 self.evaluate(body)?
8680 }
8681 _ => self.evaluate(predicate)?,
8682 };
8683
8684 match predicate_result {
8686 Value::Bool(true) => {
8687 let target_ev = match target_evidence {
8689 Evidentiality::Known => Evidence::Known,
8690 Evidentiality::Uncertain | Evidentiality::Predicted => Evidence::Uncertain,
8691 Evidentiality::Reported => Evidence::Reported,
8692 Evidentiality::Paradox => Evidence::Paradox,
8693 };
8694 let inner = match value {
8695 Value::Evidential { value: v, .. } => *v,
8696 v => v,
8697 };
8698 Ok(Value::Evidential {
8699 value: Box::new(inner),
8700 evidence: target_ev,
8701 })
8702 }
8703 Value::Bool(false) => Err(RuntimeError::new(
8704 "validation failed: predicate returned false",
8705 )),
8706 _ => Err(RuntimeError::new("validation predicate must return bool")),
8707 }
8708 }
8709
8710 PipeOp::Assume {
8711 reason,
8712 target_evidence,
8713 } => {
8714 let reason_str: Rc<String> = if let Some(r) = reason {
8716 match self.evaluate(r)? {
8717 Value::String(s) => s,
8718 _ => Rc::new("<no reason>".to_string()),
8719 }
8720 } else {
8721 Rc::new("<no reason>".to_string())
8722 };
8723
8724 #[cfg(debug_assertions)]
8726 eprintln!(
8727 "[AUDIT] Evidence assumption: {} - reason: {}",
8728 match target_evidence {
8729 Evidentiality::Known => "!",
8730 Evidentiality::Uncertain | Evidentiality::Predicted => "?",
8731 Evidentiality::Reported => "~",
8732 Evidentiality::Paradox => "‽",
8733 },
8734 reason_str
8735 );
8736
8737 let target_ev = match target_evidence {
8738 Evidentiality::Known => Evidence::Known,
8739 Evidentiality::Uncertain | Evidentiality::Predicted => Evidence::Uncertain,
8740 Evidentiality::Reported => Evidence::Reported,
8741 Evidentiality::Paradox => Evidence::Paradox,
8742 };
8743
8744 let inner = match value {
8745 Value::Evidential { value: v, .. } => *v,
8746 v => v,
8747 };
8748
8749 Ok(Value::Evidential {
8750 value: Box::new(inner),
8751 evidence: target_ev,
8752 })
8753 }
8754
8755 PipeOp::AssertEvidence(expected) => {
8756 let actual_evidence = match &value {
8758 Value::Evidential { evidence, .. } => evidence.clone(),
8759 _ => Evidence::Known,
8760 };
8761
8762 let expected_ev = match expected {
8763 Evidentiality::Known => Evidence::Known,
8764 Evidentiality::Uncertain | Evidentiality::Predicted => Evidence::Uncertain,
8765 Evidentiality::Reported => Evidence::Reported,
8766 Evidentiality::Paradox => Evidence::Paradox,
8767 };
8768
8769 let satisfies = match (&actual_evidence, &expected_ev) {
8771 (Evidence::Known, _) => true,
8772 (
8773 Evidence::Uncertain,
8774 Evidence::Uncertain | Evidence::Reported | Evidence::Paradox,
8775 ) => true,
8776 (Evidence::Reported, Evidence::Reported | Evidence::Paradox) => true,
8777 (Evidence::Paradox, Evidence::Paradox) => true,
8778 _ => false,
8779 };
8780
8781 if satisfies {
8782 Ok(value)
8783 } else {
8784 Err(RuntimeError::new(format!(
8785 "evidence assertion failed: expected {:?}, found {:?}",
8786 expected_ev, actual_evidence
8787 )))
8788 }
8789 }
8790
8791 PipeOp::Also(func) => {
8795 match func.as_ref() {
8798 Expr::Closure { params, body, .. } => {
8799 if let Some(param) = params.first() {
8800 let param_name = match ¶m.pattern {
8801 Pattern::Ident { name, .. } => name.name.clone(),
8802 _ => "it".to_string(),
8803 };
8804 self.environment
8805 .borrow_mut()
8806 .define(param_name, value.clone());
8807 }
8808 let _ = self.evaluate(body);
8810 }
8811 _ => {
8812 let _ = self.evaluate(func);
8814 }
8815 }
8816 Ok(value)
8818 }
8819
8820 PipeOp::Apply(func) => {
8821 match func.as_ref() {
8824 Expr::Closure { params, body, .. } => {
8825 if let Some(param) = params.first() {
8826 let param_name = match ¶m.pattern {
8827 Pattern::Ident { name, .. } => name.name.clone(),
8828 _ => "it".to_string(),
8829 };
8830 self.environment
8831 .borrow_mut()
8832 .define(param_name, value.clone());
8833 }
8834 let _ = self.evaluate(body);
8836 }
8837 _ => {
8838 let _ = self.evaluate(func);
8839 }
8840 }
8841 Ok(value)
8843 }
8844
8845 PipeOp::TakeIf(predicate) => {
8846 let predicate_result = match predicate.as_ref() {
8848 Expr::Closure { params, body, .. } => {
8849 if let Some(param) = params.first() {
8850 let param_name = match ¶m.pattern {
8851 Pattern::Ident { name, .. } => name.name.clone(),
8852 _ => "it".to_string(),
8853 };
8854 self.environment
8855 .borrow_mut()
8856 .define(param_name, value.clone());
8857 }
8858 self.evaluate(body)?
8859 }
8860 _ => self.evaluate(predicate)?,
8861 };
8862
8863 match predicate_result {
8864 Value::Bool(true) => Ok(Value::Variant {
8865 enum_name: "Option".to_string(),
8866 variant_name: "Some".to_string(),
8867 fields: Some(Rc::new(vec![value])),
8868 }),
8869 Value::Bool(false) => Ok(Value::Variant {
8870 enum_name: "Option".to_string(),
8871 variant_name: "None".to_string(),
8872 fields: None,
8873 }),
8874 _ => Err(RuntimeError::new("take_if predicate must return bool")),
8875 }
8876 }
8877
8878 PipeOp::TakeUnless(predicate) => {
8879 let predicate_result = match predicate.as_ref() {
8881 Expr::Closure { params, body, .. } => {
8882 if let Some(param) = params.first() {
8883 let param_name = match ¶m.pattern {
8884 Pattern::Ident { name, .. } => name.name.clone(),
8885 _ => "it".to_string(),
8886 };
8887 self.environment
8888 .borrow_mut()
8889 .define(param_name, value.clone());
8890 }
8891 self.evaluate(body)?
8892 }
8893 _ => self.evaluate(predicate)?,
8894 };
8895
8896 match predicate_result {
8897 Value::Bool(false) => Ok(Value::Variant {
8898 enum_name: "Option".to_string(),
8899 variant_name: "Some".to_string(),
8900 fields: Some(Rc::new(vec![value])),
8901 }),
8902 Value::Bool(true) => Ok(Value::Variant {
8903 enum_name: "Option".to_string(),
8904 variant_name: "None".to_string(),
8905 fields: None,
8906 }),
8907 _ => Err(RuntimeError::new("take_unless predicate must return bool")),
8908 }
8909 }
8910
8911 PipeOp::Let(func) => {
8912 match func.as_ref() {
8914 Expr::Closure { params, body, .. } => {
8915 if let Some(param) = params.first() {
8916 let param_name = match ¶m.pattern {
8917 Pattern::Ident { name, .. } => name.name.clone(),
8918 _ => "it".to_string(),
8919 };
8920 self.environment
8921 .borrow_mut()
8922 .define(param_name, value.clone());
8923 }
8924 self.evaluate(body)
8925 }
8926 _ => self.evaluate(func),
8927 }
8928 }
8929
8930 PipeOp::All(pred) => {
8934 match value {
8936 Value::Array(arr) => {
8937 for elem in arr.borrow().iter() {
8938 self.environment
8939 .borrow_mut()
8940 .define("_".to_string(), elem.clone());
8941 let result = self.evaluate(pred)?;
8942 if !self.is_truthy(&result) {
8943 return Ok(Value::Bool(false));
8944 }
8945 }
8946 Ok(Value::Bool(true))
8947 }
8948 _ => Err(RuntimeError::new("All requires array")),
8949 }
8950 }
8951
8952 PipeOp::Any(pred) => {
8953 match value {
8955 Value::Array(arr) => {
8956 for elem in arr.borrow().iter() {
8957 self.environment
8958 .borrow_mut()
8959 .define("_".to_string(), elem.clone());
8960 let result = self.evaluate(pred)?;
8961 if self.is_truthy(&result) {
8962 return Ok(Value::Bool(true));
8963 }
8964 }
8965 Ok(Value::Bool(false))
8966 }
8967 _ => Err(RuntimeError::new("Any requires array")),
8968 }
8969 }
8970
8971 PipeOp::Compose(f) => {
8972 self.environment.borrow_mut().define("_".to_string(), value);
8974 self.evaluate(f)
8975 }
8976
8977 PipeOp::Zip(other_expr) => {
8978 let other = self.evaluate(other_expr)?;
8980 match (value, other) {
8981 (Value::Array(arr1), Value::Array(arr2)) => {
8982 let zipped: Vec<Value> = arr1
8983 .borrow()
8984 .iter()
8985 .zip(arr2.borrow().iter())
8986 .map(|(a, b)| Value::Tuple(Rc::new(vec![a.clone(), b.clone()])))
8987 .collect();
8988 Ok(Value::Array(Rc::new(RefCell::new(zipped))))
8989 }
8990 _ => Err(RuntimeError::new("Zip requires two arrays")),
8991 }
8992 }
8993
8994 PipeOp::Scan(f) => {
8995 match value {
8997 Value::Array(arr) => {
8998 let arr = arr.borrow();
8999 if arr.is_empty() {
9000 return Ok(Value::Array(Rc::new(RefCell::new(vec![]))));
9001 }
9002 let mut results = vec![arr[0].clone()];
9003 let mut acc = arr[0].clone();
9004 for elem in arr.iter().skip(1) {
9005 self.environment
9006 .borrow_mut()
9007 .define("acc".to_string(), acc.clone());
9008 self.environment
9009 .borrow_mut()
9010 .define("_".to_string(), elem.clone());
9011 acc = self.evaluate(f)?;
9012 results.push(acc.clone());
9013 }
9014 Ok(Value::Array(Rc::new(RefCell::new(results))))
9015 }
9016 _ => Err(RuntimeError::new("Scan requires array")),
9017 }
9018 }
9019
9020 PipeOp::Diff => {
9021 match value {
9023 Value::Array(arr) => {
9024 let arr = arr.borrow();
9025 if arr.len() < 2 {
9026 return Ok(Value::Array(Rc::new(RefCell::new(vec![]))));
9027 }
9028 let mut diffs = Vec::new();
9029 for i in 1..arr.len() {
9030 let diff = self.subtract_values(&arr[i], &arr[i - 1])?;
9031 diffs.push(diff);
9032 }
9033 Ok(Value::Array(Rc::new(RefCell::new(diffs))))
9034 }
9035 _ => Err(RuntimeError::new("Diff requires array")),
9036 }
9037 }
9038
9039 PipeOp::Gradient(var_expr) => {
9040 let _ = var_expr;
9043 Ok(Value::Float(0.0)) }
9045
9046 PipeOp::SortAsc => {
9047 match value {
9049 Value::Array(arr) => {
9050 let mut v = arr.borrow().clone();
9051 v.sort_by(|a, b| self.compare_values(a, b, &None));
9052 Ok(Value::Array(Rc::new(RefCell::new(v))))
9053 }
9054 _ => Err(RuntimeError::new("SortAsc requires array")),
9055 }
9056 }
9057
9058 PipeOp::SortDesc => {
9059 match value {
9061 Value::Array(arr) => {
9062 let mut v = arr.borrow().clone();
9063 v.sort_by(|a, b| self.compare_values(b, a, &None));
9064 Ok(Value::Array(Rc::new(RefCell::new(v))))
9065 }
9066 _ => Err(RuntimeError::new("SortDesc requires array")),
9067 }
9068 }
9069
9070 PipeOp::Reverse => {
9071 match value {
9073 Value::Array(arr) => {
9074 let mut v = arr.borrow().clone();
9075 v.reverse();
9076 Ok(Value::Array(Rc::new(RefCell::new(v))))
9077 }
9078 _ => Err(RuntimeError::new("Reverse requires array")),
9079 }
9080 }
9081
9082 PipeOp::Cycle(n_expr) => {
9083 match value {
9085 Value::Array(arr) => {
9086 let n_val = self.evaluate(n_expr)?;
9087 let n = match n_val {
9088 Value::Int(i) => i as usize,
9089 _ => return Err(RuntimeError::new("Cycle count must be integer")),
9090 };
9091 let arr = arr.borrow();
9092 let cycled: Vec<Value> =
9093 arr.iter().cloned().cycle().take(arr.len() * n).collect();
9094 Ok(Value::Array(Rc::new(RefCell::new(cycled))))
9095 }
9096 _ => Err(RuntimeError::new("Cycle requires array")),
9097 }
9098 }
9099
9100 PipeOp::Windows(n_expr) => {
9101 match value {
9103 Value::Array(arr) => {
9104 let n_val = self.evaluate(n_expr)?;
9105 let n = match n_val {
9106 Value::Int(i) => i as usize,
9107 _ => return Err(RuntimeError::new("Window size must be integer")),
9108 };
9109 let arr = arr.borrow();
9110 let windows: Vec<Value> = arr
9111 .windows(n)
9112 .map(|w| Value::Array(Rc::new(RefCell::new(w.to_vec()))))
9113 .collect();
9114 Ok(Value::Array(Rc::new(RefCell::new(windows))))
9115 }
9116 _ => Err(RuntimeError::new("Windows requires array")),
9117 }
9118 }
9119
9120 PipeOp::Chunks(n_expr) => {
9121 match value {
9123 Value::Array(arr) => {
9124 let n_val = self.evaluate(n_expr)?;
9125 let n = match n_val {
9126 Value::Int(i) => i as usize,
9127 _ => return Err(RuntimeError::new("Chunk size must be integer")),
9128 };
9129 let arr = arr.borrow();
9130 let chunks: Vec<Value> = arr
9131 .chunks(n)
9132 .map(|c| Value::Array(Rc::new(RefCell::new(c.to_vec()))))
9133 .collect();
9134 Ok(Value::Array(Rc::new(RefCell::new(chunks))))
9135 }
9136 _ => Err(RuntimeError::new("Chunks requires array")),
9137 }
9138 }
9139
9140 PipeOp::Flatten => {
9141 match value {
9143 Value::Array(arr) => {
9144 let mut flat = Vec::new();
9145 for elem in arr.borrow().iter() {
9146 match elem {
9147 Value::Array(inner) => {
9148 flat.extend(inner.borrow().iter().cloned());
9149 }
9150 other => flat.push(other.clone()),
9151 }
9152 }
9153 Ok(Value::Array(Rc::new(RefCell::new(flat))))
9154 }
9155 _ => Err(RuntimeError::new("Flatten requires array")),
9156 }
9157 }
9158
9159 PipeOp::Unique => {
9160 match value {
9162 Value::Array(arr) => {
9163 let mut seen = std::collections::HashSet::new();
9164 let mut unique = Vec::new();
9165 for elem in arr.borrow().iter() {
9166 let key = format!("{:?}", elem);
9167 if seen.insert(key) {
9168 unique.push(elem.clone());
9169 }
9170 }
9171 Ok(Value::Array(Rc::new(RefCell::new(unique))))
9172 }
9173 _ => Err(RuntimeError::new("Unique requires array")),
9174 }
9175 }
9176
9177 PipeOp::Enumerate => {
9178 match value {
9180 Value::Array(arr) => {
9181 let enumerated: Vec<Value> = arr
9182 .borrow()
9183 .iter()
9184 .enumerate()
9185 .map(|(i, v)| {
9186 Value::Tuple(Rc::new(vec![Value::Int(i as i64), v.clone()]))
9187 })
9188 .collect();
9189 Ok(Value::Array(Rc::new(RefCell::new(enumerated))))
9190 }
9191 _ => Err(RuntimeError::new("Enumerate requires array")),
9192 }
9193 }
9194 }
9195 }
9196
9197 fn wrap_reported(&self, value: Value) -> Value {
9204 Value::Evidential {
9205 value: Box::new(value),
9206 evidence: Evidence::Reported,
9207 }
9208 }
9209
9210 fn protocol_send(&mut self, connection: &Value, data: &Value) -> Result<Value, RuntimeError> {
9212 match connection {
9214 Value::Map(obj) => {
9215 let obj = obj.borrow();
9216 if let Some(Value::String(protocol)) = obj.get("__protocol__") {
9217 match protocol.as_str() {
9218 "http" | "https" => {
9219 #[cfg(debug_assertions)]
9222 eprintln!("[HTTP] Would send request with body: {:?}", data);
9223 Ok(Value::Map(Rc::new(RefCell::new({
9224 let mut response = HashMap::new();
9225 response.insert("status".to_string(), Value::Int(200));
9226 response.insert("body".to_string(), data.clone());
9227 response.insert(
9228 "__protocol__".to_string(),
9229 Value::String(Rc::new("http_response".to_string())),
9230 );
9231 response
9232 }))))
9233 }
9234 "ws" | "wss" => {
9235 #[cfg(debug_assertions)]
9237 eprintln!("[WebSocket] Would send message: {:?}", data);
9238 Ok(Value::Bool(true)) }
9240 "grpc" => {
9241 #[cfg(debug_assertions)]
9243 eprintln!("[gRPC] Would send message: {:?}", data);
9244 Ok(Value::Map(Rc::new(RefCell::new({
9245 let mut response = HashMap::new();
9246 response.insert("status".to_string(), Value::Int(0)); response.insert("message".to_string(), data.clone());
9248 response.insert(
9249 "__protocol__".to_string(),
9250 Value::String(Rc::new("grpc_response".to_string())),
9251 );
9252 response
9253 }))))
9254 }
9255 "kafka" => {
9256 #[cfg(debug_assertions)]
9258 eprintln!("[Kafka] Would produce message: {:?}", data);
9259 Ok(Value::Map(Rc::new(RefCell::new({
9260 let mut result = HashMap::new();
9261 result.insert("partition".to_string(), Value::Int(0));
9262 result.insert("offset".to_string(), Value::Int(42));
9263 result
9264 }))))
9265 }
9266 _ => Err(RuntimeError::new(format!("Unknown protocol: {}", protocol))),
9267 }
9268 } else {
9269 Err(RuntimeError::new(
9270 "Connection object missing __protocol__ field",
9271 ))
9272 }
9273 }
9274 _ => Err(RuntimeError::new("send requires a connection object")),
9275 }
9276 }
9277
9278 fn protocol_recv(&mut self, connection: &Value) -> Result<Value, RuntimeError> {
9280 match connection {
9281 Value::Map(obj) => {
9282 let obj = obj.borrow();
9283 if let Some(Value::String(protocol)) = obj.get("__protocol__") {
9284 match protocol.as_str() {
9285 "ws" | "wss" => {
9286 #[cfg(debug_assertions)]
9288 eprintln!("[WebSocket] Would receive message");
9289 Ok(Value::String(Rc::new("received message".to_string())))
9290 }
9291 "kafka" => {
9292 #[cfg(debug_assertions)]
9294 eprintln!("[Kafka] Would consume message");
9295 Ok(Value::Map(Rc::new(RefCell::new({
9296 let mut msg = HashMap::new();
9297 msg.insert("key".to_string(), Value::Null);
9298 msg.insert(
9299 "value".to_string(),
9300 Value::String(Rc::new("consumed message".to_string())),
9301 );
9302 msg.insert("partition".to_string(), Value::Int(0));
9303 msg.insert("offset".to_string(), Value::Int(100));
9304 msg
9305 }))))
9306 }
9307 "grpc" => {
9308 #[cfg(debug_assertions)]
9310 eprintln!("[gRPC] Would receive stream message");
9311 Ok(Value::Map(Rc::new(RefCell::new({
9312 let mut msg = HashMap::new();
9313 msg.insert(
9314 "data".to_string(),
9315 Value::String(Rc::new("stream data".to_string())),
9316 );
9317 msg
9318 }))))
9319 }
9320 _ => Err(RuntimeError::new(format!(
9321 "recv not supported for protocol: {}",
9322 protocol
9323 ))),
9324 }
9325 } else {
9326 Err(RuntimeError::new(
9327 "Connection object missing __protocol__ field",
9328 ))
9329 }
9330 }
9331 _ => Err(RuntimeError::new("recv requires a connection object")),
9332 }
9333 }
9334
9335 fn protocol_stream(
9337 &mut self,
9338 connection: &Value,
9339 _handler: &Value,
9340 ) -> Result<Value, RuntimeError> {
9341 match connection {
9343 Value::Map(obj) => {
9344 let obj = obj.borrow();
9345 if let Some(Value::String(protocol)) = obj.get("__protocol__") {
9346 #[cfg(debug_assertions)]
9347 eprintln!("[{}] Would create stream", protocol);
9348
9349 Ok(Value::Map(Rc::new(RefCell::new({
9351 let mut stream = HashMap::new();
9352 stream.insert(
9353 "__type__".to_string(),
9354 Value::String(Rc::new("Stream".to_string())),
9355 );
9356 stream.insert("__protocol__".to_string(), Value::String(protocol.clone()));
9357 stream.insert(
9358 "__evidentiality__".to_string(),
9359 Value::String(Rc::new("reported".to_string())),
9360 );
9361 stream
9362 }))))
9363 } else {
9364 Err(RuntimeError::new(
9365 "Connection object missing __protocol__ field",
9366 ))
9367 }
9368 }
9369 _ => Err(RuntimeError::new("stream requires a connection object")),
9370 }
9371 }
9372
9373 fn protocol_connect(
9375 &mut self,
9376 target: &Value,
9377 _config: Option<&Value>,
9378 ) -> Result<Value, RuntimeError> {
9379 match target {
9380 Value::String(url) => {
9381 let protocol = if url.starts_with("wss://") || url.starts_with("ws://") {
9383 if url.starts_with("wss://") {
9384 "wss"
9385 } else {
9386 "ws"
9387 }
9388 } else if url.starts_with("https://") || url.starts_with("http://") {
9389 if url.starts_with("https://") {
9390 "https"
9391 } else {
9392 "http"
9393 }
9394 } else if url.starts_with("grpc://") || url.starts_with("grpcs://") {
9395 "grpc"
9396 } else if url.starts_with("kafka://") {
9397 "kafka"
9398 } else if url.starts_with("amqp://") || url.starts_with("amqps://") {
9399 "amqp"
9400 } else {
9401 "unknown"
9402 };
9403
9404 #[cfg(debug_assertions)]
9405 eprintln!("[{}] Would connect to: {}", protocol, url);
9406
9407 Ok(Value::Map(Rc::new(RefCell::new({
9409 let mut conn = HashMap::new();
9410 conn.insert(
9411 "__protocol__".to_string(),
9412 Value::String(Rc::new(protocol.to_string())),
9413 );
9414 conn.insert("url".to_string(), Value::String(url.clone()));
9415 conn.insert("connected".to_string(), Value::Bool(true));
9416 conn
9417 }))))
9418 }
9419 Value::Map(obj) => {
9420 let mut conn = obj.borrow().clone();
9422 conn.insert("connected".to_string(), Value::Bool(true));
9423 Ok(Value::Map(Rc::new(RefCell::new(conn))))
9424 }
9425 _ => Err(RuntimeError::new(
9426 "connect requires URL string or config object",
9427 )),
9428 }
9429 }
9430
9431 fn protocol_close(&mut self, connection: &Value) -> Result<(), RuntimeError> {
9433 match connection {
9434 Value::Map(obj) => {
9435 let mut obj = obj.borrow_mut();
9436 if let Some(Value::String(protocol)) = obj.get("__protocol__").cloned() {
9437 #[cfg(debug_assertions)]
9438 eprintln!("[{}] Would close connection", protocol);
9439 obj.insert("connected".to_string(), Value::Bool(false));
9440 Ok(())
9441 } else {
9442 Err(RuntimeError::new(
9443 "Connection object missing __protocol__ field",
9444 ))
9445 }
9446 }
9447 _ => Err(RuntimeError::new("close requires a connection object")),
9448 }
9449 }
9450
9451 fn protocol_add_header(
9453 &mut self,
9454 mut request: Value,
9455 name: &Value,
9456 header_value: &Value,
9457 ) -> Result<Value, RuntimeError> {
9458 let name_str = match name {
9459 Value::String(s) => (**s).clone(),
9460 _ => return Err(RuntimeError::new("Header name must be a string")),
9461 };
9462 let value_str = match header_value {
9463 Value::String(s) => (**s).clone(),
9464 Value::Int(i) => i.to_string(),
9465 _ => return Err(RuntimeError::new("Header value must be string or int")),
9466 };
9467
9468 match &mut request {
9469 Value::Map(obj) => {
9470 let mut obj = obj.borrow_mut();
9471
9472 let headers = obj
9474 .entry("headers".to_string())
9475 .or_insert_with(|| Value::Map(Rc::new(RefCell::new(HashMap::new()))));
9476
9477 if let Value::Map(headers_obj) = headers {
9478 headers_obj
9479 .borrow_mut()
9480 .insert(name_str, Value::String(Rc::new(value_str)));
9481 }
9482 drop(obj);
9483 Ok(request)
9484 }
9485 _ => Err(RuntimeError::new("header requires a request object")),
9486 }
9487 }
9488
9489 fn protocol_set_body(
9491 &mut self,
9492 mut request: Value,
9493 body: &Value,
9494 ) -> Result<Value, RuntimeError> {
9495 match &mut request {
9496 Value::Map(obj) => {
9497 obj.borrow_mut().insert("body".to_string(), body.clone());
9498 Ok(request)
9499 }
9500 _ => Err(RuntimeError::new("body requires a request object")),
9501 }
9502 }
9503
9504 fn protocol_set_timeout(
9506 &mut self,
9507 mut request: Value,
9508 ms: &Value,
9509 ) -> Result<Value, RuntimeError> {
9510 let timeout_ms = match ms {
9511 Value::Int(n) => *n,
9512 Value::Float(f) => *f as i64,
9513 _ => return Err(RuntimeError::new("Timeout must be a number (milliseconds)")),
9514 };
9515
9516 match &mut request {
9517 Value::Map(obj) => {
9518 obj.borrow_mut()
9519 .insert("timeout_ms".to_string(), Value::Int(timeout_ms));
9520 Ok(request)
9521 }
9522 _ => Err(RuntimeError::new("timeout requires a request object")),
9523 }
9524 }
9525
9526 fn protocol_set_retry(
9528 &mut self,
9529 mut request: Value,
9530 count: &Value,
9531 strategy: Option<&Value>,
9532 ) -> Result<Value, RuntimeError> {
9533 let retry_count = match count {
9534 Value::Int(n) => *n,
9535 _ => return Err(RuntimeError::new("Retry count must be an integer")),
9536 };
9537
9538 match &mut request {
9539 Value::Map(obj) => {
9540 let mut obj = obj.borrow_mut();
9541 obj.insert("retry_count".to_string(), Value::Int(retry_count));
9542 if let Some(strat) = strategy {
9543 obj.insert("retry_strategy".to_string(), strat.clone());
9544 }
9545 drop(obj);
9546 Ok(request)
9547 }
9548 _ => Err(RuntimeError::new("retry requires a request object")),
9549 }
9550 }
9551
9552 fn sum_values(&self, value: Value) -> Result<Value, RuntimeError> {
9553 match value {
9554 Value::Array(arr) => {
9555 let arr = arr.borrow();
9556 if arr.is_empty() {
9557 return Ok(Value::Int(0));
9558 }
9559 let mut sum = match &arr[0] {
9560 Value::Int(_) => Value::Int(0),
9561 Value::Float(_) => Value::Float(0.0),
9562 _ => return Err(RuntimeError::new("Cannot sum non-numeric array")),
9563 };
9564 for item in arr.iter() {
9565 sum = match (&sum, item) {
9566 (Value::Int(a), Value::Int(b)) => Value::Int(a + b),
9567 (Value::Float(a), Value::Float(b)) => Value::Float(a + b),
9568 (Value::Int(a), Value::Float(b)) => Value::Float(*a as f64 + b),
9569 (Value::Float(a), Value::Int(b)) => Value::Float(a + *b as f64),
9570 _ => return Err(RuntimeError::new("Cannot sum non-numeric values")),
9571 };
9572 }
9573 Ok(sum)
9574 }
9575 _ => Err(RuntimeError::new("sum requires array")),
9576 }
9577 }
9578
9579 fn product_values(&self, value: Value) -> Result<Value, RuntimeError> {
9580 match value {
9581 Value::Array(arr) => {
9582 let arr = arr.borrow();
9583 if arr.is_empty() {
9584 return Ok(Value::Int(1));
9585 }
9586 let mut prod = match &arr[0] {
9587 Value::Int(_) => Value::Int(1),
9588 Value::Float(_) => Value::Float(1.0),
9589 _ => return Err(RuntimeError::new("Cannot multiply non-numeric array")),
9590 };
9591 for item in arr.iter() {
9592 prod = match (&prod, item) {
9593 (Value::Int(a), Value::Int(b)) => Value::Int(a * b),
9594 (Value::Float(a), Value::Float(b)) => Value::Float(a * b),
9595 (Value::Int(a), Value::Float(b)) => Value::Float(*a as f64 * b),
9596 (Value::Float(a), Value::Int(b)) => Value::Float(a * *b as f64),
9597 _ => return Err(RuntimeError::new("Cannot multiply non-numeric values")),
9598 };
9599 }
9600 Ok(prod)
9601 }
9602 _ => Err(RuntimeError::new("product requires array")),
9603 }
9604 }
9605
9606 fn min_values(&self, value: Value) -> Result<Value, RuntimeError> {
9607 match value {
9608 Value::Array(arr) => {
9609 let arr = arr.borrow();
9610 if arr.is_empty() {
9611 return Err(RuntimeError::new("Cannot find min of empty array"));
9612 }
9613 let mut min = arr[0].clone();
9614 for item in arr.iter().skip(1) {
9615 min = match (&min, item) {
9616 (Value::Int(a), Value::Int(b)) => {
9617 if *b < *a {
9618 Value::Int(*b)
9619 } else {
9620 Value::Int(*a)
9621 }
9622 }
9623 (Value::Float(a), Value::Float(b)) => {
9624 if *b < *a {
9625 Value::Float(*b)
9626 } else {
9627 Value::Float(*a)
9628 }
9629 }
9630 (Value::Int(a), Value::Float(b)) => {
9631 let af = *a as f64;
9632 if *b < af {
9633 Value::Float(*b)
9634 } else {
9635 Value::Float(af)
9636 }
9637 }
9638 (Value::Float(a), Value::Int(b)) => {
9639 let bf = *b as f64;
9640 if bf < *a {
9641 Value::Float(bf)
9642 } else {
9643 Value::Float(*a)
9644 }
9645 }
9646 _ => {
9647 return Err(RuntimeError::new("Cannot find min of non-numeric values"))
9648 }
9649 };
9650 }
9651 Ok(min)
9652 }
9653 _ => Err(RuntimeError::new("min requires array")),
9654 }
9655 }
9656
9657 fn max_values(&self, value: Value) -> Result<Value, RuntimeError> {
9658 match value {
9659 Value::Array(arr) => {
9660 let arr = arr.borrow();
9661 if arr.is_empty() {
9662 return Err(RuntimeError::new("Cannot find max of empty array"));
9663 }
9664 let mut max = arr[0].clone();
9665 for item in arr.iter().skip(1) {
9666 max = match (&max, item) {
9667 (Value::Int(a), Value::Int(b)) => {
9668 if *b > *a {
9669 Value::Int(*b)
9670 } else {
9671 Value::Int(*a)
9672 }
9673 }
9674 (Value::Float(a), Value::Float(b)) => {
9675 if *b > *a {
9676 Value::Float(*b)
9677 } else {
9678 Value::Float(*a)
9679 }
9680 }
9681 (Value::Int(a), Value::Float(b)) => {
9682 let af = *a as f64;
9683 if *b > af {
9684 Value::Float(*b)
9685 } else {
9686 Value::Float(af)
9687 }
9688 }
9689 (Value::Float(a), Value::Int(b)) => {
9690 let bf = *b as f64;
9691 if bf > *a {
9692 Value::Float(bf)
9693 } else {
9694 Value::Float(*a)
9695 }
9696 }
9697 _ => {
9698 return Err(RuntimeError::new("Cannot find max of non-numeric values"))
9699 }
9700 };
9701 }
9702 Ok(max)
9703 }
9704 _ => Err(RuntimeError::new("max requires array")),
9705 }
9706 }
9707
9708 fn concat_values(&self, value: Value) -> Result<Value, RuntimeError> {
9709 match value {
9710 Value::Array(arr) => {
9711 let arr = arr.borrow();
9712 if arr.is_empty() {
9713 return Ok(Value::String(Rc::new(String::new())));
9714 }
9715 match &arr[0] {
9717 Value::String(_) => {
9718 let mut result = String::new();
9719 for item in arr.iter() {
9720 if let Value::String(s) = item {
9721 result.push_str(s);
9722 } else {
9723 return Err(RuntimeError::new(
9724 "concat requires all elements to be strings",
9725 ));
9726 }
9727 }
9728 Ok(Value::String(Rc::new(result)))
9729 }
9730 Value::Array(_) => {
9731 let mut result = Vec::new();
9732 for item in arr.iter() {
9733 if let Value::Array(inner) = item {
9734 result.extend(inner.borrow().iter().cloned());
9735 } else {
9736 return Err(RuntimeError::new(
9737 "concat requires all elements to be arrays",
9738 ));
9739 }
9740 }
9741 Ok(Value::Array(Rc::new(RefCell::new(result))))
9742 }
9743 _ => Err(RuntimeError::new("concat requires strings or arrays")),
9744 }
9745 }
9746 _ => Err(RuntimeError::new("concat requires array")),
9747 }
9748 }
9749
9750 fn all_values(&self, value: Value) -> Result<Value, RuntimeError> {
9751 match value {
9752 Value::Array(arr) => {
9753 let arr = arr.borrow();
9754 for item in arr.iter() {
9755 match item {
9756 Value::Bool(b) => {
9757 if !*b {
9758 return Ok(Value::Bool(false));
9759 }
9760 }
9761 _ => return Err(RuntimeError::new("all requires array of booleans")),
9762 }
9763 }
9764 Ok(Value::Bool(true))
9765 }
9766 _ => Err(RuntimeError::new("all requires array")),
9767 }
9768 }
9769
9770 fn any_values(&self, value: Value) -> Result<Value, RuntimeError> {
9771 match value {
9772 Value::Array(arr) => {
9773 let arr = arr.borrow();
9774 for item in arr.iter() {
9775 match item {
9776 Value::Bool(b) => {
9777 if *b {
9778 return Ok(Value::Bool(true));
9779 }
9780 }
9781 _ => return Err(RuntimeError::new("any requires array of booleans")),
9782 }
9783 }
9784 Ok(Value::Bool(false))
9785 }
9786 _ => Err(RuntimeError::new("any requires array")),
9787 }
9788 }
9789
9790 fn compare_values(&self, a: &Value, b: &Value, _field: &Option<Ident>) -> std::cmp::Ordering {
9791 match (a, b) {
9793 (Value::Int(a), Value::Int(b)) => a.cmp(b),
9794 (Value::Float(a), Value::Float(b)) => {
9795 a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal)
9796 }
9797 (Value::String(a), Value::String(b)) => a.cmp(b),
9798 _ => std::cmp::Ordering::Equal,
9799 }
9800 }
9801
9802 fn subtract_values(&self, a: &Value, b: &Value) -> Result<Value, RuntimeError> {
9804 match (a, b) {
9805 (Value::Int(a), Value::Int(b)) => Ok(Value::Int(a - b)),
9806 (Value::Float(a), Value::Float(b)) => Ok(Value::Float(a - b)),
9807 (Value::Int(a), Value::Float(b)) => Ok(Value::Float(*a as f64 - b)),
9808 (Value::Float(a), Value::Int(b)) => Ok(Value::Float(a - *b as f64)),
9809 _ => Err(RuntimeError::new(format!(
9810 "Cannot subtract {:?} from {:?}",
9811 b, a
9812 ))),
9813 }
9814 }
9815
9816 fn eval_closure(
9817 &mut self,
9818 params: &[ClosureParam],
9819 body: &Expr,
9820 ) -> Result<Value, RuntimeError> {
9821 let param_names: Vec<String> = params
9822 .iter()
9823 .map(|p| match &p.pattern {
9824 Pattern::Ident { name, .. } => name.name.clone(),
9825 _ => "_".to_string(),
9826 })
9827 .collect();
9828
9829 Ok(Value::Function(Rc::new(Function {
9830 name: None,
9831 params: param_names,
9832 body: body.clone(),
9833 closure: self.environment.clone(),
9834 })))
9835 }
9836
9837 fn eval_struct_literal(
9838 &mut self,
9839 path: &TypePath,
9840 fields: &[FieldInit],
9841 rest: &Option<Box<Expr>>,
9842 ) -> Result<Value, RuntimeError> {
9843 let raw_name = path
9844 .segments
9845 .iter()
9846 .map(|s| s.ident.name.as_str())
9847 .collect::<Vec<_>>()
9848 .join("::");
9849
9850 let name = if raw_name == "Self" {
9852 if let Some(ref self_type) = self.current_self_type {
9853 self_type.clone()
9854 } else {
9855 raw_name
9857 }
9858 } else {
9859 raw_name
9860 };
9861
9862 let mut field_values = HashMap::new();
9863
9864 if let Some(rest_expr) = rest {
9866 let prev_self_type = self.current_self_type.clone();
9868 self.current_self_type = Some(name.clone());
9869
9870 let rest_value = self.evaluate(rest_expr)?;
9871
9872 self.current_self_type = prev_self_type;
9873
9874 if let Value::Struct { fields: rest_fields, .. } = rest_value {
9876 for (k, v) in rest_fields.borrow().iter() {
9877 field_values.insert(k.clone(), v.clone());
9878 }
9879 }
9880 }
9881
9882 for field in fields {
9884 let value = match &field.value {
9885 Some(expr) => self.evaluate(expr)?,
9886 None => self
9887 .environment
9888 .borrow()
9889 .get(&field.name.name)
9890 .ok_or_else(|| {
9891 RuntimeError::new(format!("Unknown variable: {}", field.name.name))
9892 })?,
9893 };
9894 field_values.insert(field.name.name.clone(), value);
9895 }
9896
9897 Ok(Value::Struct {
9898 name,
9899 fields: Rc::new(RefCell::new(field_values)),
9900 })
9901 }
9902
9903 fn extract_evidence(value: &Value) -> Option<Evidence> {
9905 match value {
9906 Value::Evidential { evidence, .. } => Some(*evidence),
9907 _ => None,
9908 }
9909 }
9910
9911 fn extract_affect(value: &Value) -> Option<&RuntimeAffect> {
9913 match value {
9914 Value::Affective { affect, .. } => Some(affect),
9915 _ => None,
9916 }
9917 }
9918
9919 fn affect_to_evidence(affect: &RuntimeAffect) -> Option<Evidence> {
9923 if affect.sarcasm {
9925 return Some(Evidence::Uncertain);
9926 }
9927
9928 match affect.confidence {
9930 Some(RuntimeConfidence::High) => Some(Evidence::Known),
9931 Some(RuntimeConfidence::Low) => Some(Evidence::Uncertain),
9932 Some(RuntimeConfidence::Medium) | None => None,
9933 }
9934 }
9935
9936 fn combine_evidence(a: Option<Evidence>, b: Option<Evidence>) -> Option<Evidence> {
9939 match (a, b) {
9940 (None, None) => None,
9941 (Some(e), None) | (None, Some(e)) => Some(e),
9942 (Some(a), Some(b)) => {
9943 let rank = |e: Evidence| match e {
9944 Evidence::Known => 0,
9945 Evidence::Uncertain => 1,
9946 Evidence::Reported => 2,
9947 Evidence::Paradox => 3,
9948 };
9949 if rank(a) >= rank(b) {
9950 Some(a)
9951 } else {
9952 Some(b)
9953 }
9954 }
9955 }
9956 }
9957
9958 fn unwrap_evidential(value: &Value) -> &Value {
9960 match value {
9961 Value::Evidential { value: inner, .. } => Self::unwrap_evidential(inner),
9962 _ => value,
9963 }
9964 }
9965
9966 fn unwrap_affective(value: &Value) -> &Value {
9968 match value {
9969 Value::Affective { value: inner, .. } => Self::unwrap_affective(inner),
9970 _ => value,
9971 }
9972 }
9973
9974 fn unwrap_value(value: &Value) -> &Value {
9976 match value {
9977 Value::Evidential { value: inner, .. } => Self::unwrap_value(inner),
9978 Value::Affective { value: inner, .. } => Self::unwrap_value(inner),
9979 _ => value,
9980 }
9981 }
9982
9983 fn unwrap_all(value: &Value) -> Value {
9985 match value {
9986 Value::Evidential { value: inner, .. } => Self::unwrap_all(inner),
9987 Value::Affective { value: inner, .. } => Self::unwrap_all(inner),
9988 Value::Ref(r) => Self::unwrap_all(&r.borrow()),
9989 _ => value.clone(),
9990 }
9991 }
9992
9993 fn eval_evidential(&mut self, expr: &Expr, ev: &Evidentiality) -> Result<Value, RuntimeError> {
9994 let value = self.evaluate(expr)?;
9995
9996 if *ev == Evidentiality::Known {
10001 return match value {
10002 Value::Null => Ok(Value::Null), Value::Evidential { value: inner, .. } => Ok(*inner), other => Ok(other), };
10006 }
10007
10008 let evidence = match ev {
10009 Evidentiality::Known => Evidence::Known, Evidentiality::Uncertain | Evidentiality::Predicted => Evidence::Uncertain,
10011 Evidentiality::Reported => Evidence::Reported,
10012 Evidentiality::Paradox => Evidence::Paradox,
10013 };
10014 Ok(Value::Evidential {
10015 value: Box::new(value),
10016 evidence,
10017 })
10018 }
10019
10020 fn eval_format_macro(&mut self, tokens: &str) -> Result<Value, RuntimeError> {
10022 let tokens = tokens.trim();
10027 if !tokens.starts_with('"') {
10028 return Ok(Value::String(Rc::new(tokens.to_string())));
10030 }
10031
10032 let mut in_escape = false;
10034 let mut format_end = 1;
10035 for (i, c) in tokens[1..].char_indices() {
10036 if in_escape {
10037 in_escape = false;
10038 } else if c == '\\' {
10039 in_escape = true;
10040 } else if c == '"' {
10041 format_end = i + 2; break;
10043 }
10044 }
10045
10046 let format_str = &tokens[1..format_end-1]; crate::sigil_debug!("DEBUG format_str: '{}'", format_str);
10048 let args_str = if format_end < tokens.len() {
10049 tokens[format_end..].trim_start_matches(',').trim()
10050 } else {
10051 ""
10052 };
10053
10054 let mut arg_values: Vec<String> = Vec::new();
10056 if !args_str.is_empty() {
10057 let mut depth = 0;
10059 let mut current_arg = String::new();
10060 for c in args_str.chars() {
10061 match c {
10062 '(' | '[' | '{' => {
10063 depth += 1;
10064 current_arg.push(c);
10065 }
10066 ')' | ']' | '}' => {
10067 depth -= 1;
10068 current_arg.push(c);
10069 }
10070 ',' if depth == 0 => {
10071 let arg = current_arg.trim().to_string();
10072 if !arg.is_empty() {
10073 let mut parser = crate::parser::Parser::new(&arg);
10075 match parser.parse_expr() {
10076 Ok(expr) => {
10077 match self.evaluate(&expr) {
10078 Ok(val) => arg_values.push(self.format_value(&val)),
10079 Err(_) => arg_values.push(arg),
10080 }
10081 }
10082 Err(_) => arg_values.push(arg),
10083 }
10084 }
10085 current_arg.clear();
10086 }
10087 _ => current_arg.push(c),
10088 }
10089 }
10090 let arg = current_arg.trim().to_string();
10092 if !arg.is_empty() {
10093 let mut parser = crate::parser::Parser::new(&arg);
10094 match parser.parse_expr() {
10095 Ok(expr) => {
10096 match self.evaluate(&expr) {
10097 Ok(val) => arg_values.push(self.format_value(&val)),
10098 Err(_) => arg_values.push(arg),
10099 }
10100 }
10101 Err(_) => arg_values.push(arg),
10102 }
10103 }
10104 }
10105
10106 let mut result = String::new();
10108 let mut arg_idx = 0;
10109 let mut chars = format_str.chars().peekable();
10110
10111 while let Some(c) = chars.next() {
10112 if c == '{' {
10113 if chars.peek() == Some(&'{') {
10114 chars.next();
10116 result.push('{');
10117 } else {
10118 let mut placeholder = String::new();
10120 while let Some(pc) = chars.next() {
10121 if pc == '}' {
10122 break;
10123 }
10124 placeholder.push(pc);
10125 }
10126 if arg_idx < arg_values.len() {
10128 result.push_str(&arg_values[arg_idx]);
10129 arg_idx += 1;
10130 } else {
10131 result.push_str(&format!("{{{}}}", placeholder));
10132 }
10133 }
10134 } else if c == '}' {
10135 if chars.peek() == Some(&'}') {
10136 chars.next();
10138 result.push('}');
10139 } else {
10140 result.push('}');
10141 }
10142 } else if c == '\\' {
10143 if let Some(next) = chars.next() {
10145 match next {
10146 'n' => result.push('\n'),
10147 't' => result.push('\t'),
10148 'r' => result.push('\r'),
10149 '\\' => result.push('\\'),
10150 '"' => result.push('"'),
10151 _ => {
10152 result.push('\\');
10153 result.push(next);
10154 }
10155 }
10156 }
10157 } else {
10158 result.push(c);
10159 }
10160 }
10161
10162 Ok(Value::String(Rc::new(result)))
10163 }
10164
10165 fn format_value(&self, value: &Value) -> String {
10167 match value {
10168 Value::String(s) => s.to_string(),
10169 Value::Int(n) => n.to_string(),
10170 Value::Float(f) => f.to_string(),
10171 Value::Bool(b) => b.to_string(),
10172 Value::Char(c) => c.to_string(),
10173 Value::Null => "null".to_string(),
10174 Value::Array(arr) => {
10175 let items: Vec<String> = arr.borrow().iter().map(|v| self.format_value(v)).collect();
10176 format!("[{}]", items.join(", "))
10177 }
10178 Value::Tuple(items) => {
10179 let formatted: Vec<String> = items.iter().map(|v| self.format_value(v)).collect();
10180 format!("({})", formatted.join(", "))
10181 }
10182 Value::Struct { name, fields } => {
10183 let field_strs: Vec<String> = fields.borrow().iter()
10184 .map(|(k, v)| format!("{}: {}", k, self.format_value(v)))
10185 .collect();
10186 format!("{} {{ {} }}", name, field_strs.join(", "))
10187 }
10188 Value::Variant { enum_name, variant_name, fields } => {
10189 match fields {
10190 Some(f) if !f.is_empty() => {
10191 let formatted: Vec<String> = f.iter().map(|v| self.format_value(v)).collect();
10192 format!("{}::{}({})", enum_name, variant_name, formatted.join(", "))
10193 }
10194 _ => format!("{}::{}", enum_name, variant_name),
10195 }
10196 }
10197 Value::Evidential { value: inner, evidence } => {
10198 format!("{:?}{}", evidence, self.format_value(inner))
10199 }
10200 Value::Ref(r) => self.format_value(&r.borrow()),
10201 _ => format!("{:?}", value),
10202 }
10203 }
10204
10205 fn eval_vec_macro(&mut self, tokens: &str) -> Result<Value, RuntimeError> {
10207 let mut elements = Vec::new();
10209 let mut depth = 0;
10210 let mut current = String::new();
10211
10212 for c in tokens.chars() {
10213 match c {
10214 '(' | '[' | '{' => {
10215 depth += 1;
10216 current.push(c);
10217 }
10218 ')' | ']' | '}' => {
10219 depth -= 1;
10220 current.push(c);
10221 }
10222 ',' if depth == 0 => {
10223 let elem = current.trim().to_string();
10224 if !elem.is_empty() {
10225 let mut parser = crate::parser::Parser::new(&elem);
10226 if let Ok(expr) = parser.parse_expr() {
10227 elements.push(self.evaluate(&expr)?);
10228 }
10229 }
10230 current.clear();
10231 }
10232 _ => current.push(c),
10233 }
10234 }
10235
10236 let elem = current.trim().to_string();
10238 if !elem.is_empty() {
10239 let mut parser = crate::parser::Parser::new(&elem);
10240 if let Ok(expr) = parser.parse_expr() {
10241 elements.push(self.evaluate(&expr)?);
10242 }
10243 }
10244
10245 Ok(Value::Array(Rc::new(RefCell::new(elements))))
10246 }
10247
10248 fn eval_range(
10249 &mut self,
10250 start: &Option<Box<Expr>>,
10251 end: &Option<Box<Expr>>,
10252 inclusive: bool,
10253 ) -> Result<Value, RuntimeError> {
10254 let start_val = match start {
10255 Some(e) => match self.evaluate(e)? {
10256 Value::Int(n) => n,
10257 _ => return Err(RuntimeError::new("Range requires integer bounds")),
10258 },
10259 None => 0,
10260 };
10261
10262 let end_val = match end {
10263 Some(e) => match self.evaluate(e)? {
10264 Value::Int(n) => n,
10265 _ => return Err(RuntimeError::new("Range requires integer bounds")),
10266 },
10267 None => {
10268 return Ok(Value::Tuple(Rc::new(vec![
10271 Value::Int(start_val),
10272 Value::Null, ])));
10274 }
10275 };
10276
10277 let values: Vec<Value> = if inclusive {
10278 (start_val..=end_val).map(Value::Int).collect()
10279 } else {
10280 (start_val..end_val).map(Value::Int).collect()
10281 };
10282
10283 Ok(Value::Array(Rc::new(RefCell::new(values))))
10284 }
10285
10286 fn is_truthy(&self, value: &Value) -> bool {
10287 match value {
10288 Value::Null => false,
10289 Value::Bool(b) => *b,
10290 Value::Int(n) => *n != 0,
10291 Value::Float(n) => *n != 0.0,
10292 Value::String(s) => !s.is_empty(),
10293 Value::Array(arr) => !arr.borrow().is_empty(),
10294 Value::Empty => false,
10295 Value::Evidential { value, .. } => self.is_truthy(value),
10296 _ => true,
10297 }
10298 }
10299}
10300
10301impl Default for Interpreter {
10302 fn default() -> Self {
10303 Self::new()
10304 }
10305}
10306
10307#[cfg(test)]
10308mod tests {
10309 use super::*;
10310 use crate::Parser;
10311
10312 fn run(source: &str) -> Result<Value, RuntimeError> {
10313 let mut parser = Parser::new(source);
10314 let file = parser
10315 .parse_file()
10316 .map_err(|e| RuntimeError::new(e.to_string()))?;
10317 let mut interp = Interpreter::new();
10318 interp.execute(&file)
10319 }
10320
10321 #[test]
10322 fn test_arithmetic() {
10323 assert!(matches!(
10324 run("fn main() { return 2 + 3; }"),
10325 Ok(Value::Int(5))
10326 ));
10327 assert!(matches!(
10328 run("fn main() { return 10 - 4; }"),
10329 Ok(Value::Int(6))
10330 ));
10331 assert!(matches!(
10332 run("fn main() { return 3 * 4; }"),
10333 Ok(Value::Int(12))
10334 ));
10335 assert!(matches!(
10336 run("fn main() { return 15 / 3; }"),
10337 Ok(Value::Int(5))
10338 ));
10339 assert!(matches!(
10340 run("fn main() { return 2 ** 10; }"),
10341 Ok(Value::Int(1024))
10342 ));
10343 }
10344
10345 #[test]
10346 fn test_variables() {
10347 assert!(matches!(
10348 run("fn main() { let x = 42; return x; }"),
10349 Ok(Value::Int(42))
10350 ));
10351 }
10352
10353 #[test]
10354 fn test_conditionals() {
10355 assert!(matches!(
10356 run("fn main() { if true { return 1; } else { return 2; } }"),
10357 Ok(Value::Int(1))
10358 ));
10359 assert!(matches!(
10360 run("fn main() { if false { return 1; } else { return 2; } }"),
10361 Ok(Value::Int(2))
10362 ));
10363 }
10364
10365 #[test]
10366 fn test_arrays() {
10367 assert!(matches!(
10368 run("fn main() { return [1, 2, 3][1]; }"),
10369 Ok(Value::Int(2))
10370 ));
10371 }
10372
10373 #[test]
10374 fn test_functions() {
10375 let result = run("
10376 fn double(x: i64) -> i64 { return x * 2; }
10377 fn main() { return double(21); }
10378 ");
10379 assert!(matches!(result, Ok(Value::Int(42))));
10380 }
10381
10382 #[test]
10383 fn test_pipe_transform() {
10384 let result = run("fn main() { return [1, 2, 3]|τ{_ * 2}|sum; }");
10385 assert!(matches!(result, Ok(Value::Int(12))));
10386 }
10387
10388 #[test]
10389 fn test_pipe_filter() {
10390 let result = run("fn main() { return [1, 2, 3, 4, 5]|φ{_ > 2}|sum; }");
10391 assert!(matches!(result, Ok(Value::Int(12)))); }
10393
10394 #[test]
10395 fn test_interpolation_evidentiality_propagation() {
10396 let result = run(r#"
10399 fn main() {
10400 let rep = reported(42);
10401
10402 // Interpolating a reported value should make the string reported
10403 let s = f"Value: {rep}";
10404 return s;
10405 }
10406 "#);
10407
10408 match result {
10409 Ok(Value::Evidential {
10410 evidence: Evidence::Reported,
10411 value,
10412 }) => {
10413 assert!(matches!(*value, Value::String(_)));
10415 }
10416 Ok(other) => panic!("Expected Evidential Reported, got {:?}", other),
10417 Err(e) => panic!("Error: {:?}", e),
10418 }
10419 }
10420
10421 #[test]
10422 fn test_interpolation_worst_evidence_wins() {
10423 let result = run(r#"
10425 fn main() {
10426 let k = known(1); // Known is best
10427 let u = uncertain(2); // Uncertain is worse
10428
10429 // Combining known and uncertain should yield uncertain
10430 let s = f"{k} and {u}";
10431 return s;
10432 }
10433 "#);
10434
10435 match result {
10436 Ok(Value::Evidential {
10437 evidence: Evidence::Uncertain,
10438 ..
10439 }) => (),
10440 Ok(other) => panic!("Expected Evidential Uncertain, got {:?}", other),
10441 Err(e) => panic!("Error: {:?}", e),
10442 }
10443 }
10444
10445 #[test]
10446 fn test_interpolation_no_evidential_plain_string() {
10447 let result = run(r#"
10449 fn main() {
10450 let x = 42;
10451 let s = f"Value: {x}";
10452 return s;
10453 }
10454 "#);
10455
10456 match result {
10457 Ok(Value::String(s)) => {
10458 assert_eq!(*s, "Value: 42");
10459 }
10460 Ok(other) => panic!("Expected plain String, got {:?}", other),
10461 Err(e) => panic!("Error: {:?}", e),
10462 }
10463 }
10464}