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