## Coverage Report

#### Created: 2025-09-08 21:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /home/noah/src/ruchy/src/runtime/repl.rs

    Line
    Count
    Source
    1
    //! REPL implementation for interactive Ruchy development
    2
    //!
    3
    //! Production-grade REPL with resource bounds, error recovery, and grammar coverage
    4
    #![allow(clippy::cast_sign_loss)]
    5
    //!
    6
    //! # Examples
    7
    //!
    8
    //! ```
    9
    //! use ruchy::runtime::Repl;
    10
    //!
    11
    //! let mut repl = Repl::new().unwrap();
    12
    //!
    13
    //! // Evaluate arithmetic
    14
    //! let result = repl.eval("2 + 2").unwrap();
    15
    //! assert_eq!(result, "4");
    16
    //!
    17
    //! // Define variables
    18
    //! repl.eval("let x = 10").unwrap();
    19
    //! let result = repl.eval("x * 2").unwrap();
    20
    //! assert_eq!(result, "20");
    21
    //! ```
    22
    //!
    23
    //! # One-liner evaluation
    24
    //!
    25
    //! ```
    26
    //! use ruchy::runtime::Repl;
    27
    //! use std::time::{Duration, Instant};
    28
    //!
    29
    //! let mut repl = Repl::new().unwrap();
    30
    //! let deadline = Some(Instant::now() + Duration::from_millis(100));
    31
    //!
    32
    //! let value = repl.evaluate_expr_str("5 + 3", deadline).unwrap();
    33
    //! assert_eq!(value.to_string(), "8");
    34
    //! ```
    35
    36
    #![allow(clippy::print_stdout)] // REPL needs to print to stdout
    37
    #![allow(clippy::print_stderr)] // REPL needs to print errors
    38
    #![allow(clippy::expect_used)] // REPL can panic on initialization failure
    39
    40
    use crate::frontend::ast::{
    41
        BinaryOp, Expr, ExprKind, ImportItem, Literal, MatchArm, Pattern, PipelineStage, Span, StructPatternField, UnaryOp,
    42
    };
    43
    use crate::runtime::completion::RuchyCompleter;
    44
    use crate::runtime::magic::{MagicRegistry, UnicodeExpander};
    45
    use crate::runtime::transaction::TransactionalState;
    46
    use crate::{Parser, Transpiler};
    47
    use anyhow::{bail, Context, Result};
    48
    use colored::Colorize;
    49
    50
    // mod display;
    51
    // mod inspect;
    52
    use rustyline::error::ReadlineError;
    53
    use rustyline::history::DefaultHistory;
    54
    use rustyline::{CompletionType, Config, EditMode};
    55
    use std::collections::{HashMap, HashSet};
    56
    use std::fmt;
    57
    #[allow(unused_imports)]
    58
    use std::fmt::Write;
    59
    use std::fs;
    60
    use std::path::{Path, PathBuf};
    61
    use std::process::Command;
    62
    use std::time::{Duration, Instant, SystemTime};
    63
    64
    /// Runtime value for evaluation
    65
    #[derive(Debug, Clone, PartialEq)]
    66
    pub enum Value {
    67
        Int(i64),
    68
        Float(f64),
    69
        String(String),
    70
        Bool(bool),
    71
        Char(char),
    72
        List(Vec<Value>),
    73
        Tuple(Vec<Value>),
    74
        Function {
    75
            name: String,
    76
            params: Vec<String>,
    77
            body: Box<Expr>,
    78
        },
    79
        Lambda {
    80
            params: Vec<String>,
    81
            body: Box<Expr>,
    82
        },
    83
        DataFrame {
    84
            columns: Vec<DataFrameColumn>,
    85
        },
    86
        Object(HashMap<String, Value>),
    87
        HashMap(HashMap<Value, Value>),
    88
        HashSet(HashSet<Value>),
    89
        Range {
    90
            start: i64,
    91
            end: i64,
    92
            inclusive: bool,
    93
        },
    94
        EnumVariant {
    95
            enum_name: String,
    96
            variant_name: String,
    97
            data: Option<Vec<Value>>,
    98
        },
    99
        Unit,
    100
        Nil,
    101
    }
    102
    103
    /// `DataFrame` column representation for pretty printing
    104
    #[derive(Debug, Clone, PartialEq)]
    105
    pub struct DataFrameColumn {
    106
        pub name: String,
    107
        pub values: Vec<Value>,
    108
    }
    109
    110
    // Manual Eq implementation for Value
    111
    impl Eq for Value {}
    112
    113
    // Manual Hash implementation for Value
    114
    impl std::hash::Hash for Value {
    115
    0
        fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
    116
    0
            std::mem::discriminant(self).hash(state);
    117
    0
            match self {
    118
    0
                Value::Int(n) => n.hash(state),
    119
    0
                Value::Float(f) => {
    120
    0
                    // Hash floats by their bit representation to handle NaN properly
    121
    0
                    f.to_bits().hash(state);
    122
    0
                },
    123
    0
                Value::String(s) => s.hash(state),
    124
    0
                Value::Bool(b) => b.hash(state),
    125
    0
                Value::Char(c) => c.hash(state),
    126
    0
                Value::List(items) => {
    127
    0
                    for item in items {
    128
    0
                        item.hash(state);
    129
    0
                    }
    130
                },
    131
    0
                Value::Tuple(items) => {
    132
    0
                    for item in items {
    133
    0
                        item.hash(state);
    134
    0
                    }
    135
                },
    136
                // Functions, DataFrames, Objects, HashMaps, and HashSets are not hashable
    137
                // We'll just hash their discriminant
    138
    0
                Value::Function { name, .. } => name.hash(state),
    139
    0
                Value::Lambda { .. } => "lambda".hash(state),
    140
    0
                Value::DataFrame { .. } => "dataframe".hash(state),
    141
    0
                Value::Object(_) => "object".hash(state),
    142
    0
                Value::HashMap(_) => "hashmap".hash(state),
    143
    0
                Value::HashSet(_) => "hashset".hash(state),
    144
    0
                Value::Range { start, end, inclusive } => {
    145
    0
                    start.hash(state);
    146
    0
                    end.hash(state);
    147
    0
                    inclusive.hash(state);
    148
    0
                },
    149
    0
                Value::EnumVariant { enum_name, variant_name, data } => {
    150
    0
                    enum_name.hash(state);
    151
    0
                    variant_name.hash(state);
    152
    0
                    if let Some(d) = data {
    153
    0
                        for item in d {
    154
    0
                            item.hash(state);
    155
    0
                        }
    156
    0
                    }
    157
                },
    158
    0
                Value::Unit => "unit".hash(state),
    159
    0
                Value::Nil => "nil".hash(state),
    160
            }
    161
    0
        }
    162
    }
    163
    164
    // Display implementations moved to repl_display.rs
    165
    166
    impl fmt::Display for Value {
    167
    0
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    168
    0
            match self {
    169
    0
                Value::Int(n) => write!(f, "{n}"),
    170
    0
                Value::Float(x) => write!(f, "{x}"),
    171
    0
                Value::String(s) => write!(f, "\"{s}\""),
    172
    0
                Value::Bool(b) => write!(f, "{b}"),
    173
    0
                Value::Char(c) => write!(f, "'{c}'"),
    174
    0
                Value::List(items) => {
    175
    0
                    write!(f, "[")?;
    176
    0
                    for (i, item) in items.iter().enumerate() {
    177
    0
                        if i > 0 { write!(f, ", ")?; }
    178
    0
                        write!(f, "{item}")?;
    179
                    }
    180
    0
                    write!(f, "]")
    181
                }
    182
    0
                Value::Tuple(items) => {
    183
    0
                    write!(f, "(")?;
    184
    0
                    for (i, item) in items.iter().enumerate() {
    185
    0
                        if i > 0 { write!(f, ", ")?; }
    186
    0
                        write!(f, "{item}")?;
    187
                    }
    188
    0
                    write!(f, ")")
    189
                }
    190
    0
                Value::Function { name, params, .. } => {
    191
    0
                    write!(f, "fn {}({})", name, params.join(", "))
    192
                }
    193
    0
                Value::Lambda { params, .. } => {
    194
    0
                    write!(f, "|{}| <closure>", params.join(", "))
    195
                }
    196
    0
                Value::DataFrame { columns } => {
    197
    0
                    writeln!(f, "DataFrame with {} columns:", columns.len())?;
    198
    0
                    for col in columns {
    199
    0
                        writeln!(f, "  {}: {} rows", col.name, col.values.len())?;
    200
                    }
    201
    0
                    Ok(())
    202
                }
    203
    0
                Value::Object(map) => {
    204
    0
                    write!(f, "{{")?;
    205
    0
                    for (i, (k, v)) in map.iter().enumerate() {
    206
    0
                        if i > 0 { write!(f, ", ")?; }
    207
    0
                        write!(f, "{k}: {v}")?;
    208
                    }
    209
    0
                    write!(f, "}}")
    210
                }
    211
    0
                Value::HashMap(map) => {
    212
    0
                    write!(f, "HashMap{{")?;
    213
    0
                    for (i, (k, v)) in map.iter().enumerate() {
    214
    0
                        if i > 0 { write!(f, ", ")?; }
    215
    0
                        write!(f, "{k}: {v}")?;
    216
                    }
    217
    0
                    write!(f, "}}")
    218
                }
    219
    0
                Value::HashSet(set) => {
    220
    0
                    write!(f, "HashSet{{")?;
    221
    0
                    for (i, v) in set.iter().enumerate() {
    222
    0
                        if i > 0 { write!(f, ", ")?; }
    223
    0
                        write!(f, "{v}")?;
    224
                    }
    225
    0
                    write!(f, "}}")
    226
                }
    227
                Value::Range {
    228
    0
                    start,
    229
    0
                    end,
    230
    0
                    inclusive,
    231
                } => {
    232
    0
                    if *inclusive {
    233
    0
                        write!(f, "{start}..={end}")
    234
                    } else {
    235
    0
                        write!(f, "{start}..{end}")
    236
                    }
    237
                }
    238
                Value::EnumVariant {
    239
    0
                    enum_name,
    240
    0
                    variant_name,
    241
    0
                    data,
    242
                } => {
    243
    0
                    write!(f, "{enum_name}::{variant_name}")?;
    244
    0
                    if let Some(data) = data {
    245
    0
                        write!(f, "(")?;
    246
    0
                        for (i, val) in data.iter().enumerate() {
    247
    0
                            if i > 0 { write!(f, ", ")?; }
    248
    0
                            write!(f, "{val}")?;
    249
                        }
    250
    0
                        write!(f, ")")?;
    251
    0
                    }
    252
    0
                    Ok(())
    253
                }
    254
    0
                Value::Unit => write!(f, "()"),
    255
    0
                Value::Nil => write!(f, "null"),
    256
            }
    257
    0
        }
    258
    }
    259
    260
    impl Value {
    261
        /// Check if the value is considered truthy in boolean contexts
    262
    0
        fn is_truthy(&self) -> bool {
    263
    0
            match self {
    264
    0
                Value::Bool(b) => *b,
    265
    0
                Value::Nil => false,
    266
    0
                Value::Unit => false,
    267
    0
                Value::Int(0) => false,
    268
    0
                Value::Float(f) => *f != 0.0 && !f.is_nan(),
    269
    0
                Value::String(s) => !s.is_empty(),
    270
    0
                Value::List(items) => !items.is_empty(),
    271
    0
                _ => true,
    272
            }
    273
    0
        }
    274
    }
    275
    276
    /// REPL mode determines how input is processed
    277
    #[derive(Debug, Clone, Copy, PartialEq)]
    278
    pub enum ReplMode {
    279
        Normal,  // Standard Ruchy evaluation
    280
        Shell,   // Execute everything as shell commands
    281
        Pkg,     // Package management mode
    282
        Help,    // Help documentation mode
    283
        Sql,     // SQL query mode
    284
        Math,    // Mathematical expression mode
    285
        Debug,   // Debug mode with extra info and trace timing
    286
        Time,    // Time mode showing execution timing
    287
        Test,    // Test mode with assertions and table tests
    288
    }
    289
    290
    impl ReplMode {
    291
    0
        fn prompt(&self) -> String {
    292
    0
            match self {
    293
    0
                ReplMode::Normal => "ruchy> ".to_string(),
    294
    0
                ReplMode::Shell => "shell> ".to_string(),
    295
    0
                ReplMode::Pkg => "pkg> ".to_string(),
    296
    0
                ReplMode::Help => "help> ".to_string(),
    297
    0
                ReplMode::Sql => "sql> ".to_string(),
    298
    0
                ReplMode::Math => "math> ".to_string(),
    299
    0
                ReplMode::Debug => "debug> ".to_string(),
    300
    0
                ReplMode::Time => "time> ".to_string(),
    301
    0
                ReplMode::Test => "test> ".to_string(),
    302
            }
    303
    0
        }
    304
    }
    305
    306
    /// Debug information for post-mortem analysis
    307
    #[derive(Debug, Clone)]
    308
    pub struct DebugInfo {
    309
        /// The expression that caused the error
    310
        pub expression: String,
    311
        /// The error message
    312
        pub error_message: String,
    313
        /// Stack trace at time of error
    314
        pub stack_trace: Vec<String>,
    315
        /// Variable bindings at time of error
    316
        pub bindings_snapshot: HashMap<String, Value>,
    317
        /// Timestamp when error occurred
    318
        pub timestamp: std::time::SystemTime,
    319
    }
    320
    321
    // === Error Recovery UI System ===
    322
    323
    /// Interactive error recovery options
    324
    #[derive(Debug, Clone)]
    325
    pub enum RecoveryOption {
    326
        /// Continue with a default or empty value
    327
        ContinueWithDefault(String),
    328
        /// Retry with a corrected expression
    329
        RetryWith(String),
    330
        /// Show completion suggestions
    331
        ShowCompletions,
    332
        /// Discard the failed expression
    333
        Abort,
    334
        /// Restore from previous checkpoint
    335
        RestoreCheckpoint,
    336
        /// Use a specific value from history
    337
        UseHistoryValue(usize),
    338
    }
    339
    340
    /// Error recovery context with available options
    341
    #[derive(Debug, Clone)]
    342
    pub struct ErrorRecovery {
    343
        /// The original failed expression
    344
        pub failed_expression: String,
    345
        /// The error that occurred
    346
        pub error_message: String,
    347
        /// Line and column where error occurred
    348
        pub position: Option<(usize, usize)>,
    349
        /// Available recovery options for this error type
    350
        pub options: Vec<RecoveryOption>,
    351
        /// Suggested completions if applicable
    352
        pub completions: Vec<String>,
    353
        /// Checkpoint at time of error for recovery
    354
        pub error_checkpoint: Checkpoint,
    355
    }
    356
    357
    /// Recovery result after user chooses an option
    358
    #[derive(Debug)]
    359
    pub enum RecoveryResult {
    360
        /// Successfully recovered with new expression
    361
        Recovered(String),
    362
        /// User chose to abort the operation
    363
        Aborted,
    364
        /// Restored from checkpoint
    365
        Restored,
    366
        /// Show completions to user
    367
        ShowCompletions(Vec<String>),
    368
    }
    369
    370
    // === Transactional State Machine ===
    371
    372
    /// Checkpoint for O(1) state recovery using persistent data structures
    373
    #[derive(Debug, Clone)]
    374
    pub struct Checkpoint {
    375
        /// Persistent bindings snapshot
    376
        bindings: im::HashMap<String, Value>,
    377
        /// Persistent mutability tracking
    378
        mutability: im::HashMap<String, bool>,
    379
        /// Result history snapshot
    380
        result_history: im::Vector<Value>,
    381
        /// Enum definitions snapshot
    382
        enum_definitions: im::HashMap<String, im::Vector<String>>,
    383
        /// Timestamp of checkpoint creation
    384
        timestamp: SystemTime,
    385
        /// Program counter for recovery context
    386
        _pc: usize,
    387
    }
    388
    389
    /// REPL transaction state for reliable evaluation
    390
    #[derive(Clone, Default)]
    391
    pub enum ReplState {
    392
        /// Ready to accept input
    393
        #[default]
    394
        Ready,
    395
        /// Currently evaluating (with checkpoint for rollback)
    396
        Evaluating(Checkpoint),
    397
        /// Failed state (with checkpoint for recovery)
    398
        Failed(Checkpoint),
    399
    }
    400
    401
    impl Checkpoint {
    402
        /// Create new checkpoint from current REPL state
    403
    0
        fn from_repl(repl: &Repl) -> Self {
    404
    0
            let bindings = repl.bindings.iter()
    405
    0
                .map(|(k, v)| (k.clone(), v.clone()))
    406
    0
                .collect();
    407
    408
    0
            let mutability = repl.binding_mutability.iter()
    409
    0
                .map(|(k, v)| (k.clone(), *v))
    410
    0
                .collect();
    411
    412
    0
            let result_history = repl.result_history.iter().cloned().collect();
    413
    414
    0
            let enum_definitions = repl.enum_definitions.iter()
    415
    0
                .map(|(k, v)| (k.clone(), v.iter().cloned().collect()))
    416
    0
                .collect();
    417
    418
    0
            Self {
    419
    0
                bindings,
    420
    0
                mutability,
    421
    0
                result_history,
    422
    0
                enum_definitions,
    423
    0
                timestamp: SystemTime::now(),
    424
    0
                _pc: repl.history.len(),
    425
    0
            }
    426
    0
        }
    427
    428
        /// Restore REPL state from checkpoint (O(1) with persistent structures)
    429
    0
        fn restore_to(&self, repl: &mut Repl) {
    430
            // Convert from persistent structures back to std collections
    431
    0
            repl.bindings = self.bindings.iter()
    432
    0
                .map(|(k, v)| (k.clone(), v.clone()))
    433
    0
                .collect();
    434
    435
    0
            repl.binding_mutability = self.mutability.iter()
    436
    0
                .map(|(k, v)| (k.clone(), *v))
    437
    0
                .collect();
    438
    439
    0
            repl.result_history = self.result_history.iter().cloned().collect();
    440
    441
    0
            repl.enum_definitions = self.enum_definitions.iter()
    442
    0
                .map(|(k, v)| (k.clone(), v.iter().cloned().collect()))
    443
    0
                .collect();
    444
    445
            // Update history variables (_1, _2, etc.) after restoration
    446
    0
            repl.update_history_variables();
    447
    0
        }
    448
    449
        /// Get checkpoint age
    450
    0
        pub fn age(&self) -> Duration {
    451
    0
            SystemTime::now().duration_since(self.timestamp)
    452
    0
                .unwrap_or(Duration::ZERO)
    453
    0
        }
    454
    }
    455
    456
    457
    impl ReplState {
    458
        /// Transition state machine for evaluation
    459
    0
        pub fn eval(self, repl: &mut Repl, input: &str) -> (ReplState, Result<String>) {
    460
    0
            match self {
    461
                ReplState::Ready => {
    462
                    // Create checkpoint before evaluation
    463
    0
                    let checkpoint = Checkpoint::from_repl(repl);
    464
    465
                    // Attempt evaluation
    466
    0
                    match repl.eval_internal(input) {
    467
    0
                        Ok(result) => (ReplState::Ready, Ok(result)),
    468
    0
                        Err(e) => (ReplState::Failed(checkpoint), Err(e)),
    469
                    }
    470
                }
    471
    0
                ReplState::Evaluating(checkpoint) => {
    472
                    // Should not happen - evaluating state is transient
    473
    0
                    (ReplState::Failed(checkpoint), Err(anyhow::anyhow!("Invalid state transition")))
    474
                }
    475
    0
                ReplState::Failed(checkpoint) => {
    476
                    // Restore from checkpoint and retry
    477
    0
                    checkpoint.restore_to(repl);
    478
    0
                    (ReplState::Ready, Err(anyhow::anyhow!("Recovered from previous failure")))
    479
                }
    480
            }
    481
    0
        }
    482
    }
    483
    484
    /// REPL configuration
    485
    #[derive(Clone)]
    486
    pub struct ReplConfig {
    487
        /// Maximum memory for evaluation (default: 10MB)
    488
        pub max_memory: usize,
    489
        /// Timeout for evaluation (default: 100ms)
    490
        pub timeout: Duration,
    491
        /// Maximum stack depth (default: 1000)
    492
        pub max_depth: usize,
    493
        /// Enable debug mode
    494
        pub debug: bool,
    495
    }
    496
    497
    impl Default for ReplConfig {
    498
    0
        fn default() -> Self {
    499
    0
            Self {
    500
    0
                max_memory: 10 * 1024 * 1024, // 10MB arena allocation limit
    501
    0
                timeout: Duration::from_millis(100), // 100ms hard limit per spec
    502
    0
                max_depth: 1000, // 1000 frame maximum per spec
    503
    0
                debug: false,
    504
    0
            }
    505
    0
        }
    506
    }
    507
    508
    // RuchyCompleter is now imported from crate::runtime::completion
    509
    510
    // Old RuchyCompleter implementation removed - now using advanced completion from runtime::completion module
    511
    512
    // Keep only the trait implementations that rustyline needs
    513
    // The Completer trait is already implemented in the completion module
    514
    515
    // rustyline trait implementations moved to completion.rs module
    516
    517
    /// Memory tracker for bounded allocation
    518
    /// Arena-style memory tracker for bounded evaluation
    519
    /// Provides fixed memory allocation with reset capability
    520
    struct MemoryTracker {
    521
        max_size: usize,
    522
        current: usize,
    523
        peak_usage: usize,
    524
        allocation_count: usize,
    525
    }
    526
    527
    impl MemoryTracker {
    528
    0
        fn new(max_size: usize) -> Self {
    529
    0
            Self {
    530
    0
                max_size,
    531
    0
                current: 0,
    532
    0
                peak_usage: 0,
    533
    0
                allocation_count: 0,
    534
    0
            }
    535
    0
        }
    536
    537
        /// Reset arena for new evaluation (O(1) operation)
    538
    0
        fn reset(&mut self) {
    539
    0
            self.current = 0;
    540
    0
            self.allocation_count = 0;
    541
    0
        }
    542
    543
        /// Track memory usage during evaluation
    544
    0
        fn try_alloc(&mut self, size: usize) -> Result<()> {
    545
    0
            if self.current + size > self.max_size {
    546
    0
                bail!(
    547
    0
                    "Memory limit exceeded: {} + {} > {} (peak: {}, allocs: {})",
    548
                    self.current,
    549
                    size,
    550
                    self.max_size,
    551
                    self.peak_usage,
    552
                    self.allocation_count
    553
                );
    554
    0
            }
    555
    0
            self.current += size;
    556
    0
            self.allocation_count += 1;
    557
    558
            // Track peak usage
    559
    0
            if self.current > self.peak_usage {
    560
    0
                self.peak_usage = self.current;
    561
    0
            }
    562
    563
    0
            Ok(())
    564
    0
        }
    565
    566
        /// Get current memory usage
    567
    0
        fn memory_used(&self) -> usize {
    568
    0
            self.current
    569
    0
        }
    570
    571
        /// Get peak memory usage since last reset
    572
    0
        fn peak_memory(&self) -> usize {
    573
    0
            self.peak_usage
    574
    0
        }
    575
    576
        /// Get allocation count since last reset
    577
        #[allow(dead_code)]
    578
    0
        fn allocation_count(&self) -> usize {
    579
    0
            self.allocation_count
    580
    0
        }
    581
    582
        /// Check if we're approaching memory limit
    583
    0
        fn memory_pressure(&self) -> f64 {
    584
    0
            self.current as f64 / self.max_size as f64
    585
    0
        }
    586
    }
    587
    588
    /// REPL state management with resource bounds
    589
    pub struct Repl {
    590
        /// History of successfully parsed expressions
    591
        history: Vec<String>,
    592
        /// History of evaluation results (for _ and _n variables)
    593
        result_history: Vec<Value>,
    594
        /// Accumulated definitions for the session
    595
        definitions: Vec<String>,
    596
        /// Bindings and their types/values
    597
        bindings: HashMap<String, Value>,
    598
        /// Mutability tracking for bindings
    599
        binding_mutability: HashMap<String, bool>,
    600
        /// Impl methods: `Type::method` -> (params, body)
    601
        impl_methods: HashMap<String, (Vec<String>, Box<Expr>)>,
    602
        /// Enum definitions: `EnumName` -> list of variant names
    603
        enum_definitions: HashMap<String, Vec<String>>,
    604
        /// Transpiler instance
    605
        transpiler: Transpiler,
    606
        /// Working directory for compilation
    607
        temp_dir: PathBuf,
    608
        /// Session counter for unique naming
    609
        session_counter: usize,
    610
        /// Configuration
    611
        config: ReplConfig,
    612
        /// Memory tracker
    613
        memory: MemoryTracker,
    614
        /// O(1) in-memory module cache: path -> parsed functions
    615
        /// Guarantees O(1) performance regardless of storage backend (EFS, NFS, etc)
    616
        module_cache: HashMap<String, HashMap<String, Value>>,
    617
        /// Current REPL mode
    618
        mode: ReplMode,
    619
        /// Debug information from last error
    620
        last_error_debug: Option<DebugInfo>,
    621
        /// Error recovery context for interactive recovery
    622
        error_recovery: Option<ErrorRecovery>,
    623
        /// Transactional state machine for reliable evaluation
    624
        state: ReplState,
    625
        /// Magic command registry
    626
        magic_registry: MagicRegistry,
    627
        /// Unicode expander for LaTeX-style input
    628
        unicode_expander: UnicodeExpander,
    629
        /// Transactional state for safe evaluation
    630
        tx_state: TransactionalState,
    631
    }
    632
    633
    impl Repl {
    634
        /// Create a new REPL instance with default config
    635
        ///
    636
        /// # Errors
    637
        ///
    638
        /// Returns an error if the working directory cannot be created
    639
        ///
    640
        /// # Examples
    641
        ///
    642
        /// ```
    643
        /// use ruchy::runtime::Repl;
    644
        ///
    645
        /// let repl = Repl::new();
    646
        /// assert!(repl.is_ok());
    647
        /// ```
    648
    0
        pub fn new() -> Result<Self> {
    649
    0
            Self::with_config(ReplConfig::default())
    650
    0
        }
    651
    652
        /// Create a new REPL instance with custom config
    653
        ///
    654
        /// # Errors
    655
        ///
    656
        /// Returns an error if the working directory cannot be created
    657
    0
        pub fn with_config(config: ReplConfig) -> Result<Self> {
    658
    0
            let temp_dir = std::env::temp_dir().join("ruchy_repl");
    659
    0
            fs::create_dir_all(&temp_dir)?;
    660
    661
    0
            let memory = MemoryTracker::new(config.max_memory);
    662
    663
    0
            let mut repl = Self {
    664
    0
                history: Vec::new(),
    665
    0
                result_history: Vec::new(),
    666
    0
                definitions: Vec::new(),
    667
    0
                bindings: HashMap::new(),
    668
    0
                binding_mutability: HashMap::new(),
    669
    0
                impl_methods: HashMap::new(),
    670
    0
                enum_definitions: HashMap::new(),
    671
    0
                transpiler: Transpiler::new(),
    672
    0
                temp_dir,
    673
    0
                session_counter: 0,
    674
    0
                memory,
    675
    0
                module_cache: HashMap::new(),
    676
    0
                mode: ReplMode::Normal,
    677
    0
                last_error_debug: None,
    678
    0
                error_recovery: None,
    679
    0
                state: ReplState::Ready,
    680
    0
                magic_registry: MagicRegistry::new(),
    681
    0
                unicode_expander: UnicodeExpander::new(),
    682
    0
                tx_state: TransactionalState::new(config.max_memory),
    683
    0
                config,
    684
    0
            };
    685
    686
            // Initialize built-in types
    687
    0
            repl.init_builtins();
    688
    689
    0
            Ok(repl)
    690
    0
        }
    691
    692
        /// Initialize built-in enum types (Option, Result)
    693
    0
        fn init_builtins(&mut self) {
    694
            // Register Option enum
    695
    0
            self.enum_definitions.insert(
    696
    0
                "Option".to_string(),
    697
    0
                vec!["None".to_string(), "Some".to_string()],
    698
            );
    699
    700
            // Register Result enum
    701
    0
            self.enum_definitions.insert(
    702
    0
                "Result".to_string(),
    703
    0
                vec!["Ok".to_string(), "Err".to_string()],
    704
            );
    705
    706
            // Add Option and Result to definitions for transpiler
    707
    0
            self.definitions
    708
    0
                .push("enum Option<T> { None, Some(T) }".to_string());
    709
    0
            self.definitions
    710
    0
                .push("enum Result<T, E> { Ok(T), Err(E) }".to_string());
    711
    0
        }
    712
    713
        // === Helper Functions for Common Value Creation ===
    714
    715
        /// Create an `Option::None` value
    716
    0
        fn create_option_none() -> Value {
    717
    0
            Value::EnumVariant {
    718
    0
                enum_name: "Option".to_string(),
    719
    0
                variant_name: "None".to_string(),
    720
    0
                data: None,
    721
    0
            }
    722
    0
        }
    723
    724
        /// Create an `Option::Some(value)` value
    725
    0
        fn create_option_some(value: Value) -> Value {
    726
    0
            Value::EnumVariant {
    727
    0
                enum_name: "Option".to_string(),
    728
    0
                variant_name: "Some".to_string(),
    729
    0
                data: Some(vec![value]),
    730
    0
            }
    731
    0
        }
    732
    733
        /// Create a `Result::Ok(value)` value
    734
    0
        fn create_result_ok(value: Value) -> Value {
    735
    0
            Value::EnumVariant {
    736
    0
                enum_name: "Result".to_string(),
    737
    0
                variant_name: "Ok".to_string(),
    738
    0
                data: Some(vec![value]),
    739
    0
            }
    740
    0
        }
    741
    742
        /// Create a `Result::Err(value)` value
    743
    0
        fn create_result_err(value: Value) -> Value {
    744
    0
            Value::EnumVariant {
    745
    0
                enum_name: "Result".to_string(),
    746
    0
                variant_name: "Err".to_string(),
    747
    0
                data: Some(vec![value]),
    748
    0
            }
    749
    0
        }
    750
    751
        /// Evaluate a unary math function
    752
    0
        fn evaluate_unary_math_function(
    753
    0
            &mut self,
    754
    0
            args: &[Expr],
    755
    0
            deadline: Instant,
    756
    0
            depth: usize,
    757
    0
            func_name: &str,
    758
    0
            operation: fn(f64) -> f64,
    759
    0
        ) -> Result<Value> {
    760
    0
            self.validate_arg_count(func_name, args, 1)?;
    761
    762
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    763
    0
            match value {
    764
    0
                Value::Float(f) => Self::ok_float(operation(f)),
    765
    0
                Value::Int(n) => Self::ok_float(operation(n as f64)),
    766
    0
                _ => bail!("{}", Self::numeric_arg_error(func_name)),
    767
            }
    768
    0
        }
    769
    770
        /// Evaluate a unary math function with validation
    771
    0
        fn evaluate_unary_math_function_validated(
    772
    0
            &mut self,
    773
    0
            args: &[Expr],
    774
    0
            deadline: Instant,
    775
    0
            depth: usize,
    776
    0
            func_name: &str,
    777
    0
            operation: fn(f64) -> f64,
    778
    0
            validator: fn(f64) -> Result<()>,
    779
    0
        ) -> Result<Value> {
    780
    0
            self.validate_arg_count(func_name, args, 1)?;
    781
    782
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    783
    0
            match value {
    784
    0
                Value::Float(f) => {
    785
    0
                    validator(f)?;
    786
    0
                    Self::ok_float(operation(f))
    787
                }
    788
    0
                Value::Int(n) => {
    789
    0
                    let f = n as f64;
    790
    0
                    validator(f)?;
    791
    0
                    Self::ok_float(operation(f))
    792
                }
    793
    0
                _ => bail!("{}", Self::numeric_arg_error(func_name)),
    794
            }
    795
    0
        }
    796
    797
        // === Resource-Bounded Evaluation API ===
    798
    799
        /// Create a sandboxed REPL instance for testing/fuzzing
    800
        /// Uses minimal resource limits for safety
    801
    0
        pub fn sandboxed() -> Result<Self> {
    802
    0
            let config = ReplConfig {
    803
    0
                max_memory: 1024 * 1024, // 1MB limit for sandbox
    804
    0
                timeout: Duration::from_millis(10), // Very short timeout
    805
    0
                max_depth: 100, // Limited recursion
    806
    0
                debug: false,
    807
    0
            };
    808
    0
            Self::with_config(config)
    809
    0
        }
    810
    811
        /// Get current memory usage in bytes
    812
    0
        pub fn memory_used(&self) -> usize {
    813
    0
            self.memory.memory_used()
    814
    0
        }
    815
    816
        /// Get peak memory usage since last evaluation
    817
    0
        pub fn peak_memory(&self) -> usize {
    818
    0
            self.memory.peak_memory()
    819
    0
        }
    820
    821
        /// Get memory pressure (0.0 to 1.0)
    822
    0
        pub fn memory_pressure(&self) -> f64 {
    823
    0
            self.memory.memory_pressure()
    824
    0
        }
    825
    826
        /// Check if REPL can accept new input (not at resource limits)
    827
    0
        pub fn can_accept_input(&self) -> bool {
    828
    0
            self.memory_pressure() < 0.95 // Less than 95% memory usage
    829
    0
        }
    830
    831
        /// Validate that all bindings are still valid (no corruption)
    832
    0
        pub fn bindings_valid(&self) -> bool {
    833
            // Check that mutability tracking doesn't have orphaned entries
    834
            // (bindings without mutability entries are allowed - they default to immutable)
    835
    0
            for name in self.binding_mutability.keys() {
    836
    0
                if !self.bindings.contains_key(name) {
    837
    0
                    return false;
    838
    0
                }
    839
            }
    840
    0
            true
    841
    0
        }
    842
    843
        /// Evaluate with explicit resource bounds (for testing)
    844
    0
        pub fn eval_bounded(&mut self, input: &str, max_memory: usize, timeout: Duration) -> Result<String> {
    845
            // Save current config
    846
    0
            let old_config = self.config.clone();
    847
    848
            // Apply working bounds
    849
    0
            self.config.max_memory = max_memory;
    850
    0
            self.config.timeout = timeout;
    851
    852
            // Update memory tracker limit
    853
    0
            self.memory.max_size = max_memory;
    854
    855
            // Evaluate
    856
    0
            let result = self.eval(input);
    857
    858
            // Restore original config
    859
    0
            self.config = old_config;
    860
    0
            self.memory.max_size = self.config.max_memory;
    861
    862
    0
            result
    863
    0
        }
    864
    865
        /// Evaluate an expression string and return the Value
    866
        ///
    867
        /// This is used for one-liner evaluation from CLI
    868
        ///
    869
        /// # Errors
    870
        ///
    871
        /// Returns an error if parsing or evaluation fails
    872
    0
        pub fn evaluate_expr_str(&mut self, input: &str, deadline: Option<Instant>) -> Result<Value> {
    873
            // Reset memory tracker for fresh evaluation
    874
    0
            self.memory.reset();
    875
    876
            // Track input memory
    877
    0
            self.memory.try_alloc(input.len())?;
    878
    879
            // Use provided deadline or default timeout
    880
    0
            let deadline = deadline.unwrap_or_else(|| Instant::now() + self.config.timeout);
    881
    882
            // Preprocess macro syntax: convert println! -> println, etc.
    883
    0
            let preprocessed_input = Self::preprocess_macro_syntax(input);
    884
    885
            // Parse the input
    886
    0
            let mut parser = Parser::new(&preprocessed_input);
    887
    0
            let ast = parser.parse().context("Failed to parse input")?;
    888
    889
            // Check memory for AST
    890
    0
            self.memory.try_alloc(std::mem::size_of_val(&ast))?;
    891
    892
            // Evaluate the expression
    893
    0
            let value = self.evaluate_expr(&ast, deadline, 0)?;
    894
    895
            // Handle let bindings specially (for backward compatibility)
    896
    0
            if let ExprKind::Let { name, type_annotation: _, is_mutable, .. } = &ast.kind {
    897
    0
                self.create_binding(name.clone(), value.clone(), *is_mutable);
    898
    0
            }
    899
    900
    0
            Ok(value)
    901
    0
        }
    902
    903
        // === Transactional Evaluation API ===
    904
    905
        /// Evaluate with transactional state machine
    906
    0
        pub fn eval_transactional(&mut self, input: &str) -> Result<String> {
    907
    0
            let (new_state, result) = std::mem::take(&mut self.state).eval(self, input);
    908
    0
            self.state = new_state;
    909
    0
            result
    910
    0
        }
    911
    912
        /// Create checkpoint of current state
    913
        ///
    914
        /// # Example
    915
        /// ```
    916
        /// use ruchy::runtime::Repl;
    917
        ///
    918
        /// let mut repl = Repl::new().unwrap();
    919
        /// repl.eval("let x = 42").unwrap();
    920
        /// let checkpoint = repl.checkpoint();
    921
        /// repl.eval("let x = 100").unwrap();
    922
        /// repl.restore_checkpoint(&checkpoint);
    923
        /// assert_eq!(repl.eval("x").unwrap(), "42");
    924
        /// ```
    925
    0
        pub fn checkpoint(&self) -> Checkpoint {
    926
    0
            Checkpoint::from_repl(self)
    927
    0
        }
    928
    929
        /// Restore from checkpoint
    930
        ///
    931
        /// # Example
    932
        /// ```
    933
        /// use ruchy::runtime::Repl;
    934
        ///
    935
        /// let mut repl = Repl::new().unwrap();
    936
        /// let checkpoint = repl.checkpoint();
    937
        /// repl.eval("let y = 100").unwrap();
    938
        /// repl.restore_checkpoint(&checkpoint);
    939
        /// // y is no longer defined after restore
    940
        /// ```
    941
    0
        pub fn restore_checkpoint(&mut self, checkpoint: &Checkpoint) {
    942
    0
            checkpoint.restore_to(self);
    943
    0
            self.state = ReplState::Ready;
    944
    0
        }
    945
    946
        /// Get current state
    947
    0
        pub fn get_state(&self) -> &ReplState {
    948
    0
            &self.state
    949
    0
        }
    950
    951
        /// Set state (for testing purposes only - do not use in production)
    952
    0
        pub fn set_state_for_testing(&mut self, state: ReplState) {
    953
    0
            self.state = state;
    954
    0
        }
    955
    956
        /// Get result history length (for debugging)
    957
    0
        pub fn result_history_len(&self) -> usize {
    958
    0
            self.result_history.len()
    959
    0
        }
    960
    961
        /// Get bindings (for replay testing)
    962
    0
        pub fn get_bindings(&self) -> &HashMap<String, Value> {
    963
    0
            &self.bindings
    964
    0
        }
    965
    966
        /// Get mutable bindings (for replay testing)
    967
    0
        pub fn get_bindings_mut(&mut self) -> &mut HashMap<String, Value> {
    968
    0
            &mut self.bindings
    969
    0
        }
    970
    971
        /// Clear bindings (for replay testing)
    972
    0
        pub fn clear_bindings(&mut self) {
    973
    0
            self.bindings.clear();
    974
    0
            self.binding_mutability.clear();
    975
    0
        }
    976
    977
        /// Get last error (for magic commands)
    978
    0
        pub fn get_last_error(&self) -> Option<&DebugInfo> {
    979
    0
            self.last_error_debug.as_ref()
    980
    0
        }
    981
    982
        /// Check if REPL is in failed state
    983
    0
        pub fn is_failed(&self) -> bool {
    984
    0
            matches!(self.state, ReplState::Failed(_))
    985
    0
        }
    986
    987
        /// Recover from failed state (if applicable)
    988
    0
        pub fn recover(&mut self) -> Result<String> {
    989
    0
            match std::mem::take(&mut self.state) {
    990
    0
                ReplState::Failed(checkpoint) => {
    991
    0
                    checkpoint.restore_to(self);
    992
    0
                    self.state = ReplState::Ready;
    993
    0
                    Ok("Recovered from previous failure".to_string())
    994
                }
    995
    0
                state => {
    996
                    // Restore original state if not failed
    997
    0
                    self.state = state;
    998
    0
                    Err(anyhow::anyhow!("REPL is not in failed state"))
    999
                }
    1000
            }
    1001
    0
        }
    1002
    1003
        // === Interactive Error Recovery System ===
    1004
    1005
        /// Create error recovery context when evaluation fails
    1006
    0
        pub fn create_error_recovery(&mut self, failed_expr: &str, error_msg: &str) -> ErrorRecovery {
    1007
    0
            let checkpoint = self.checkpoint();
    1008
    1009
            // Parse error message to determine position if possible
    1010
    0
            let position = self.parse_error_position(error_msg);
    1011
    1012
            // Determine appropriate recovery options based on error type
    1013
    0
            let options = self.suggest_recovery_options(failed_expr, error_msg);
    1014
    1015
            // Generate completions if appropriate
    1016
    0
            let completions = if failed_expr.trim().is_empty() || error_msg.contains("expected expression") {
    1017
    0
                self.generate_completions_for_error(failed_expr)
    1018
            } else {
    1019
    0
                Vec::new()
    1020
            };
    1021
    1022
    0
            let recovery = ErrorRecovery {
    1023
    0
                failed_expression: failed_expr.to_string(),
    1024
    0
                error_message: error_msg.to_string(),
    1025
    0
                position,
    1026
    0
                options,
    1027
    0
                completions,
    1028
    0
                error_checkpoint: checkpoint,
    1029
    0
            };
    1030
    1031
    0
            self.error_recovery = Some(recovery.clone());
    1032
    0
            recovery
    1033
    0
        }
    1034
    1035
        /// Parse error position from error message
    1036
    0
        fn parse_error_position(&self, error_msg: &str) -> Option<(usize, usize)> {
    1037
            // Try to extract line:column from common error formats
    1038
    0
            if let Some(caps) = regex::Regex::new(r"line (\d+):(\d+)")
    1039
    0
                .ok()
    1040
    0
                .and_then(|re| re.captures(error_msg))
    1041
            {
    1042
    0
                if let (Ok(line), Ok(col)) = (
    1043
    0
                    caps.get(1)?.as_str().parse::<usize>(),
    1044
    0
                    caps.get(2)?.as_str().parse::<usize>()
    1045
                ) {
    1046
    0
                    return Some((line, col));
    1047
    0
                }
    1048
    0
            }
    1049
    0
            None
    1050
    0
        }
    1051
    1052
        /// Suggest appropriate recovery options based on error type
    1053
    0
        fn suggest_recovery_options(&self, failed_expr: &str, error_msg: &str) -> Vec<RecoveryOption> {
    1054
    0
            let mut options = Vec::new();
    1055
    1056
            // Common recovery options based on error patterns
    1057
    0
            if error_msg.contains("Unexpected EOF") || error_msg.contains("expected expression") ||
    1058
    0
               error_msg.contains("Unexpected end of input") || error_msg.contains("end of input") {
    1059
    0
                if failed_expr.starts_with("let ") && failed_expr.ends_with(" = ") {
    1060
    0
                    if let Some(without_let) = failed_expr.strip_prefix("let ") {
    1061
    0
                        if let Some(var_name) = without_let.strip_suffix(" = ") {
    1062
    0
                            options.push(RecoveryOption::ContinueWithDefault(
    1063
    0
                                format!("let {var_name} = ()")
    1064
    0
                            ));
    1065
    0
                            options.push(RecoveryOption::RetryWith(
    1066
    0
                                format!("let {var_name} = 0")
    1067
    0
                            ));
    1068
    0
                        }
    1069
    0
                    }
    1070
    0
                }
    1071
    0
                options.push(RecoveryOption::ShowCompletions);
    1072
    0
            }
    1073
    1074
    0
            if error_msg.to_lowercase().contains("undefined variable") || error_msg.contains("not found") {
    1075
                // Suggest similar variable names
    1076
    0
                if let Some(undefined_var) = self.extract_undefined_variable(error_msg) {
    1077
    0
                    let similar_vars = self.find_similar_variables(&undefined_var);
    1078
    0
                    for similar_var in &similar_vars {
    1079
    0
                        options.push(RecoveryOption::RetryWith(
    1080
    0
                            failed_expr.replace(&undefined_var, similar_var)
    1081
    0
                        ));
    1082
    0
                    }
    1083
    1084
                    // If no similar variables found, provide a default fallback
    1085
    0
                    if similar_vars.is_empty() {
    1086
    0
                        options.push(RecoveryOption::ContinueWithDefault(format!("let {undefined_var} = ()")));
    1087
    0
                        options.push(RecoveryOption::RetryWith("0".to_string())); // Simple default value
    1088
    0
                    }
    1089
    0
                }
    1090
    0
            }
    1091
    1092
    0
            if error_msg.contains("type mismatch") || error_msg.contains("cannot convert") {
    1093
    0
                // Suggest type conversions
    1094
    0
                options.push(RecoveryOption::RetryWith(
    1095
    0
                    format!("{}.to_string()", failed_expr.trim())
    1096
    0
                ));
    1097
    0
            }
    1098
    1099
            // Always provide these standard options
    1100
    0
            options.push(RecoveryOption::Abort);
    1101
    0
            options.push(RecoveryOption::RestoreCheckpoint);
    1102
    1103
            // Suggest using recent history values
    1104
    0
            if !self.result_history.is_empty() {
    1105
    0
                for (i, _) in self.result_history.iter().enumerate().take(3) {
    1106
    0
                    options.push(RecoveryOption::UseHistoryValue(i + 1));
    1107
    0
                }
    1108
    0
            }
    1109
    1110
    0
            options
    1111
    0
        }
    1112
    1113
        /// Extract undefined variable name from error message
    1114
    0
        pub fn extract_undefined_variable(&self, error_msg: &str) -> Option<String> {
    1115
            // Try to find variable name in various error message formats
    1116
            // Pattern for "Undefined variable: name"
    1117
    0
            if let Some(caps) = regex::Regex::new(r"Undefined variable: ([a-zA-Z_][a-zA-Z0-9_]*)")
    1118
    0
                .ok()
    1119
    0
                .and_then(|re| re.captures(error_msg))
    1120
            {
    1121
    0
                return Some(caps.get(1)?.as_str().to_string());
    1122
    0
            }
    1123
    1124
            // Pattern for "undefined variable name" or "undefined variable 'name'"
    1125
    0
            if let Some(caps) = regex::Regex::new(r#"undefined variable[: ]+['"]?([a-zA-Z_][a-zA-Z0-9_]*)['"]?"#)
    1126
    0
                .ok()
    1127
    0
                .and_then(|re| re.captures(error_msg))
    1128
            {
    1129
    0
                return Some(caps.get(1)?.as_str().to_string());
    1130
    0
            }
    1131
    1132
            // Pattern for "variable name not found"
    1133
    0
            if let Some(caps) = regex::Regex::new(r#"variable[: ]+['"]?([a-zA-Z_][a-zA-Z0-9_]*)['"]? not found"#)
    1134
    0
                .ok()
    1135
    0
                .and_then(|re| re.captures(error_msg))
    1136
            {
    1137
    0
                return Some(caps.get(1)?.as_str().to_string());
    1138
    0
            }
    1139
    1140
    0
            None
    1141
    0
        }
    1142
    1143
        /// Find variables similar to the undefined one (for typo correction)
    1144
    0
        pub fn find_similar_variables(&self, target: &str) -> Vec<String> {
    1145
    0
            let mut similar = Vec::new();
    1146
    1147
    0
            for var_name in self.bindings.keys() {
    1148
    0
                let distance = self.edit_distance(target, var_name);
    1149
                // Suggest variables with edit distance <= 2
    1150
    0
                if distance <= 2 && distance > 0 {
    1151
    0
                    similar.push(var_name.clone());
    1152
    0
                }
    1153
            }
    1154
    1155
            // Sort by similarity (lower distance first)
    1156
    0
            similar.sort_by_key(|var| self.edit_distance(target, var));
    1157
    0
            similar.truncate(5); // Limit to top 5 suggestions
    1158
    0
            similar
    1159
    0
        }
    1160
    1161
        /// Calculate edit distance between two strings (Levenshtein distance)
    1162
    0
        pub fn edit_distance(&self, a: &str, b: &str) -> usize {
    1163
    0
            let a_chars: Vec<char> = a.chars().collect();
    1164
    0
            let b_chars: Vec<char> = b.chars().collect();
    1165
    0
            let mut matrix = vec![vec![0; b_chars.len() + 1]; a_chars.len() + 1];
    1166
    1167
            // Initialize first row and column
    1168
    0
            for (i, row) in matrix.iter_mut().enumerate().take(a_chars.len() + 1) {
    1169
    0
                row[0] = i;
    1170
    0
            }
    1171
    0
            for j in 0..=b_chars.len() {
    1172
    0
                matrix[0][j] = j;
    1173
    0
            }
    1174
    1175
            // Fill the matrix
    1176
    0
            for i in 1..=a_chars.len() {
    1177
    0
                for j in 1..=b_chars.len() {
    1178
    0
                    let cost = usize::from(a_chars[i-1] != b_chars[j-1]);
    1179
    0
                    matrix[i][j] = std::cmp::min(
    1180
    0
                        std::cmp::min(
    1181
    0
                            matrix[i-1][j] + 1,      // deletion
    1182
    0
                            matrix[i][j-1] + 1       // insertion
    1183
    0
                        ),
    1184
    0
                        matrix[i-1][j-1] + cost      // substitution
    1185
    0
                    );
    1186
    0
                }
    1187
            }
    1188
    1189
    0
            matrix[a_chars.len()][b_chars.len()]
    1190
    0
        }
    1191
    1192
        /// Generate completions for incomplete expressions
    1193
    0
        pub fn generate_completions_for_error(&self, partial_expr: &str) -> Vec<String> {
    1194
    0
            let mut completions = Vec::new();
    1195
    1196
    0
            if partial_expr.trim().is_empty() {
    1197
                // Suggest common starting patterns
    1198
    0
                completions.extend(vec![
    1199
    0
                    "let ".to_string(),
    1200
    0
                    "if ".to_string(),
    1201
    0
                    "match ".to_string(),
    1202
    0
                    "for ".to_string(),
    1203
    0
                    "while ".to_string(),
    1204
    0
                    "fun ".to_string(),
    1205
                ]);
    1206
    1207
                // Add some variable names
    1208
    0
                for var_name in self.bindings.keys().take(10) {
    1209
    0
                    completions.push(var_name.clone());
    1210
    0
                }
    1211
    0
            } else if partial_expr.starts_with("let ") && partial_expr.contains(" = ") {
    1212
    0
                // Suggest values for let bindings
    1213
    0
                completions.extend(vec![
    1214
    0
                    "0".to_string(),
    1215
    0
                    "true".to_string(),
    1216
    0
                    "false".to_string(),
    1217
    0
                    "[]".to_string(),
    1218
    0
                    "{}".to_string(),
    1219
    0
                    "\"\"".to_string(),
    1220
    0
                ]);
    1221
    0
            } else {
    1222
                // Context-sensitive completions based on available variables
    1223
    0
                let prefix = partial_expr.trim();
    1224
    0
                for var_name in self.bindings.keys() {
    1225
    0
                    if var_name.starts_with(prefix) {
    1226
    0
                        completions.push(var_name.clone());
    1227
    0
                    }
    1228
                }
    1229
            }
    1230
    1231
    0
            completions.sort();
    1232
    0
            completions.dedup();
    1233
    0
            completions.truncate(10); // Limit suggestions
    1234
    0
            completions
    1235
    0
        }
    1236
    1237
        /// Apply a recovery option and return the result
    1238
    0
        pub fn apply_recovery(&mut self, option: RecoveryOption) -> Result<RecoveryResult> {
    1239
    0
            match option {
    1240
    0
                RecoveryOption::ContinueWithDefault(expr) => {
    1241
    0
                    self.error_recovery = None;
    1242
    0
                    Ok(RecoveryResult::Recovered(expr))
    1243
                }
    1244
    0
                RecoveryOption::RetryWith(expr) => {
    1245
    0
                    self.error_recovery = None;
    1246
    0
                    Ok(RecoveryResult::Recovered(expr))
    1247
                }
    1248
                RecoveryOption::ShowCompletions => {
    1249
    0
                    if let Some(recovery) = &self.error_recovery {
    1250
    0
                        Ok(RecoveryResult::ShowCompletions(recovery.completions.clone()))
    1251
                    } else {
    1252
    0
                        Ok(RecoveryResult::ShowCompletions(Vec::new()))
    1253
                    }
    1254
                }
    1255
                RecoveryOption::Abort => {
    1256
    0
                    self.error_recovery = None;
    1257
    0
                    Ok(RecoveryResult::Aborted)
    1258
                }
    1259
                RecoveryOption::RestoreCheckpoint => {
    1260
    0
                    if let Some(recovery) = self.error_recovery.take() {
    1261
    0
                        recovery.error_checkpoint.restore_to(self);
    1262
    0
                        Ok(RecoveryResult::Restored)
    1263
                    } else {
    1264
    0
                        Err(anyhow::anyhow!("No error recovery context available"))
    1265
                    }
    1266
                }
    1267
    0
                RecoveryOption::UseHistoryValue(index) => {
    1268
    0
                    if index > 0 && index <= self.result_history.len() {
    1269
                        // Check that history value exists
    1270
    0
                        let expr = format!("_{index}");
    1271
    0
                        self.error_recovery = None;
    1272
    0
                        Ok(RecoveryResult::Recovered(expr))
    1273
                    } else {
    1274
    0
                        Err(anyhow::anyhow!("History index {} not available", index))
    1275
                    }
    1276
                }
    1277
            }
    1278
    0
        }
    1279
    1280
        /// Get current error recovery context
    1281
    0
        pub fn get_error_recovery(&self) -> Option<&ErrorRecovery> {
    1282
    0
            self.error_recovery.as_ref()
    1283
    0
        }
    1284
    1285
        /// Clear error recovery context
    1286
    0
        pub fn clear_error_recovery(&mut self) {
    1287
    0
            self.error_recovery = None;
    1288
    0
        }
    1289
    1290
        /// Format error recovery options for display
    1291
    0
        pub fn format_error_recovery(&self, recovery: &ErrorRecovery) -> String {
    1292
    0
            let mut output = String::new();
    1293
    1294
    0
            output.push_str(&format!("Error: {}\n", recovery.error_message));
    1295
    1296
    0
            if let Some((line, col)) = recovery.position {
    1297
    0
                output.push_str(&format!("     │ {} \n", recovery.failed_expression));
    1298
    0
                output.push_str(&format!("     │ {}↑ at line {}:{}\n",
    1299
    0
                    " ".repeat(col.saturating_sub(1)), line, col));
    1300
    0
            }
    1301
    1302
    0
            output.push_str("\nRecovery Options:\n");
    1303
    1304
    0
            for (i, option) in recovery.options.iter().enumerate() {
    1305
    0
                match option {
    1306
    0
                    RecoveryOption::ContinueWithDefault(expr) => {
    1307
    0
                        output.push_str(&format!("  {}. Continue with: {}\n", i + 1, expr));
    1308
    0
                    }
    1309
    0
                    RecoveryOption::RetryWith(expr) => {
    1310
    0
                        output.push_str(&format!("  {}. Retry with: {}\n", i + 1, expr));
    1311
    0
                    }
    1312
    0
                    RecoveryOption::ShowCompletions => {
    1313
    0
                        output.push_str(&format!("  {}. Show completions\n", i + 1));
    1314
    0
                    }
    1315
    0
                    RecoveryOption::Abort => {
    1316
    0
                        output.push_str(&format!("  {}. Abort operation\n", i + 1));
    1317
    0
                    }
    1318
    0
                    RecoveryOption::RestoreCheckpoint => {
    1319
    0
                        output.push_str(&format!("  {}. Restore from checkpoint\n", i + 1));
    1320
    0
                    }
    1321
    0
                    RecoveryOption::UseHistoryValue(index) => {
    1322
    0
                        output.push_str(&format!("  {}. Use history value _{}\n", i + 1, index));
    1323
    0
                    }
    1324
                }
    1325
            }
    1326
    1327
    0
            if !recovery.completions.is_empty() {
    1328
    0
                output.push_str("\nSuggestions: ");
    1329
    0
                output.push_str(&recovery.completions.join(", "));
    1330
    0
                output.push('\n');
    1331
    0
            }
    1332
    1333
    0
            output.push_str("\nEnter option number, or press Ctrl+C to abort.");
    1334
    0
            output
    1335
    0
        }
    1336
    1337
        /// Check if error recovery is available
    1338
    0
        pub fn has_error_recovery(&self) -> bool {
    1339
    0
            self.error_recovery.is_some()
    1340
    0
        }
    1341
    1342
        /// Get a formatted error recovery prompt if available
    1343
    0
        pub fn get_error_recovery_prompt(&self) -> Option<String> {
    1344
    0
            self.error_recovery.as_ref().map(|recovery| self.format_error_recovery(recovery))
    1345
    0
        }
    1346
    1347
        /// Internal evaluation method (called by state machine)
    1348
    0
        fn eval_internal(&mut self, input: &str) -> Result<String> {
    1349
            // This will be the core evaluation logic without state machine overhead
    1350
            // For now, use a simplified approach that bypasses the state machine
    1351
    1352
            // Reset memory tracker for fresh evaluation
    1353
    0
            self.memory.reset();
    1354
    1355
            // Track input memory
    1356
    0
            self.memory.try_alloc(input.len())?;
    1357
    1358
            // Check for magic commands
    1359
    0
            let trimmed = input.trim();
    1360
    1361
    0
            if trimmed.starts_with('%') {
    1362
    0
                return self.handle_magic_command(trimmed);
    1363
    0
            }
    1364
    1365
            // Check for REPL commands
    1366
    0
            if trimmed.starts_with(':') {
    1367
    0
                let (should_quit, output) = self.handle_command_with_output(trimmed)?;
    1368
    0
                if should_quit {
    1369
    0
                    return Ok("Exiting REPL...".to_string());
    1370
    0
                }
    1371
    0
                return Ok(output);
    1372
    0
            }
    1373
    1374
            // Set evaluation deadline
    1375
    0
            let deadline = Instant::now() + self.config.timeout;
    1376
    1377
            // Preprocess macro syntax: convert println! -> println, etc.
    1378
    0
            let preprocessed = trimmed
    1379
    0
                .replace("println!", "println")
    1380
    0
                .replace("print!", "print")
    1381
    0
                .replace("assert!", "assert")
    1382
    0
                .replace("assert_eq!", "assert_eq")
    1383
    0
                .replace("panic!", "panic")
    1384
    0
                .replace("vec!", "vec")
    1385
    0
                .replace("format!", "format");
    1386
    1387
            // Try to parse the input as an expression
    1388
    0
            let mut parser = Parser::new(&preprocessed);
    1389
    0
            let ast = parser.parse().context("Failed to parse input")?;
    1390
    1391
            // Track AST memory
    1392
    0
            self.memory.try_alloc(std::mem::size_of_val(&ast))?;
    1393
    1394
            // Evaluate the expression
    1395
    0
            let value = self.evaluate_expr(&ast, deadline, 0)?;
    1396
    1397
            // Add to history and update variables
    1398
    0
            self.history.push(input.to_string());
    1399
    0
            self.result_history.push(value.clone());
    1400
    0
            self.update_history_variables();
    1401
    1402
            // Return string representation (suppress Unit values from loops/statements)
    1403
    0
            match value {
    1404
    0
                Value::Unit => Ok(String::new()),
    1405
    0
                _ => Ok(value.to_string())
    1406
            }
    1407
    0
        }
    1408
    1409
        /// Evaluate an expression with resource bounds
    1410
        ///
    1411
        /// # Errors
    1412
        ///
    1413
        /// Returns an error if:
    1414
        /// - Memory limit is exceeded
    1415
        /// - Timeout is reached
    1416
        /// - Stack depth limit is exceeded
    1417
        /// - Parse or evaluation fails
    1418
        ///
    1419
        /// # Example
    1420
        /// ```
    1421
        /// use ruchy::runtime::Repl;
    1422
        ///
    1423
        /// let mut repl = Repl::new().unwrap();
    1424
        /// let result = repl.eval("1 + 1");
    1425
        /// assert_eq!(result.unwrap(), "2");
    1426
        /// ```
    1427
        /// Handle mode-specific evaluation (complexity: 9)
    1428
    0
        fn handle_mode_evaluation(&mut self, trimmed: &str) -> Option<Result<String>> {
    1429
    0
            if trimmed.starts_with(':') {
    1430
    0
                return None; // Colon commands are handled normally
    1431
    0
            }
    1432
    1433
    0
            match self.mode {
    1434
    0
                ReplMode::Shell => Some(self.execute_shell_command(trimmed)),
    1435
    0
                ReplMode::Pkg => Some(self.handle_pkg_command(trimmed)),
    1436
    0
                ReplMode::Help => Some(self.handle_help_command(trimmed)),
    1437
    0
                ReplMode::Sql => Some(Ok(format!("SQL mode not yet implemented: {trimmed}"))),
    1438
    0
                ReplMode::Math => Some(self.handle_math_command(trimmed)),
    1439
    0
                ReplMode::Debug => Some(self.handle_debug_evaluation(trimmed)),
    1440
    0
                ReplMode::Time => Some(self.handle_timed_evaluation(trimmed)),
    1441
    0
                ReplMode::Test => Some(self.handle_test_evaluation(trimmed)),
    1442
    0
                ReplMode::Normal => None,
    1443
            }
    1444
    0
        }
    1445
    1446
        /// Check if input is a shell command (complexity: 5)
    1447
    0
        fn is_shell_command(&self, trimmed: &str) -> bool {
    1448
    0
            if let Some(stripped) = trimmed.strip_prefix('!') {
    1449
                // Not a shell command if it's a unary expression
    1450
    0
                !(stripped.starts_with("true") ||
    1451
    0
                  stripped.starts_with("false") ||
    1452
    0
                  stripped.starts_with('(') ||
    1453
    0
                  (stripped.chars().next().is_some_and(char::is_lowercase) &&
    1454
    0
                   stripped.chars().all(|c| c.is_alphanumeric() || c == '_')))
    1455
            } else {
    1456
    0
                false
    1457
            }
    1458
    0
        }
    1459
    1460
        /// Handle shell substitution in let bindings (complexity: 6)
    1461
    0
        fn handle_shell_substitution(&mut self, input: &str, trimmed: &str) -> Option<Result<String>> {
    1462
    0
            if !trimmed.starts_with("let ") {
    1463
    0
                return None;
    1464
    0
            }
    1465
    1466
    0
            if let Some(bang_pos) = trimmed.find(" = !") {
    1467
    0
                let var_part = &trimmed[4..bang_pos];
    1468
    0
                let command_part = &trimmed[bang_pos + 4..];
    1469
    1470
                // Execute the shell command
    1471
    0
                let result = match self.execute_shell_command(command_part) {
    1472
    0
                    Ok(r) => r,
    1473
    0
                    Err(e) => return Some(Err(e)),
    1474
                };
    1475
    1476
                // Create a let binding with the result
    1477
    0
                let modified_input = format!("let {} = \"{}\"", var_part, result.replace('"', "\\\""));
    1478
    1479
                // Parse and evaluate the modified input
    1480
    0
                let deadline = Instant::now() + self.config.timeout;
    1481
    0
                let mut parser = Parser::new(&modified_input);
    1482
    0
                let ast = match parser.parse() {
    1483
    0
                    Ok(a) => a,
    1484
    0
                    Err(e) => return Some(Err(e.context("Failed to parse shell substitution"))),
    1485
                };
    1486
    1487
    0
                if let Err(e) = self.memory.try_alloc(std::mem::size_of_val(&ast)) {
    1488
    0
                    return Some(Err(e));
    1489
    0
                }
    1490
    1491
    0
                match self.evaluate_expr(&ast, deadline, 0) {
    1492
    0
                    Ok(value) => {
    1493
    0
                        self.history.push(input.to_string());
    1494
    0
                        self.result_history.push(value);
    1495
    0
                        self.update_history_variables();
    1496
    0
                        Some(Ok(String::new()))
    1497
                    }
    1498
    0
                    Err(e) => Some(Err(e)),
    1499
                }
    1500
            } else {
    1501
    0
                None
    1502
            }
    1503
    0
        }
    1504
    1505
        /// Main eval function with reduced complexity (complexity: 10)
    1506
    0
        pub fn eval(&mut self, input: &str) -> Result<String> {
    1507
            // Reset memory tracker for fresh evaluation
    1508
    0
            self.memory.reset();
    1509
    0
            self.memory.try_alloc(input.len())?;
    1510
    1511
    0
            let trimmed = input.trim();
    1512
    1513
            // Handle progressive mode activation via attributes
    1514
    0
            if let Some(activated_mode) = self.detect_mode_activation(trimmed) {
    1515
    0
                self.mode = activated_mode;
    1516
    0
                return Ok(format!("Activated {} mode", self.get_mode()));
    1517
    0
            }
    1518
    1519
            // Handle mode-specific evaluation
    1520
    0
            if let Some(result) = self.handle_mode_evaluation(trimmed) {
    1521
    0
                return result;
    1522
    0
            }
    1523
            // Handle magic commands
    1524
    0
            if trimmed.starts_with('%') {
    1525
    0
                return self.handle_magic_command(trimmed);
    1526
    0
            }
    1527
    1528
            // Check for REPL commands
    1529
    0
            if trimmed.starts_with(':') {
    1530
    0
                let (should_quit, output) = self.handle_command_with_output(trimmed)?;
    1531
    0
                if should_quit {
    1532
    0
                    return Ok("Exiting REPL...".to_string());
    1533
    0
                }
    1534
    0
                return Ok(output);
    1535
    0
            }
    1536
    1537
            // Check for shell commands
    1538
    0
            if self.is_shell_command(trimmed) {
    1539
    0
                if let Some(stripped) = trimmed.strip_prefix('!') {
    1540
    0
                    return self.execute_shell_command(stripped);
    1541
    0
                }
    1542
    0
            }
    1543
    1544
            // Check for introspection commands
    1545
    0
            if let Some(stripped) = trimmed.strip_prefix("??") {
    1546
    0
                return self.detailed_introspection(stripped.trim());
    1547
    0
            } else if trimmed.starts_with('?') && !trimmed.starts_with("?:") {
    1548
    0
                return self.basic_introspection(trimmed[1..].trim());
    1549
    0
            }
    1550
    1551
            // Handle shell substitution in let bindings
    1552
    0
            if let Some(result) = self.handle_shell_substitution(input, trimmed) {
    1553
    0
                return result;
    1554
    0
            }
    1555
    1556
            // Set evaluation deadline
    1557
    0
            let deadline = Instant::now() + self.config.timeout;
    1558
    1559
            // Preprocess macro syntax: convert println! -> println, etc.
    1560
    0
            let preprocessed_input = Self::preprocess_macro_syntax(input);
    1561
    1562
            // Parse the input
    1563
    0
            let mut parser = Parser::new(&preprocessed_input);
    1564
    0
            let ast = match parser.parse() {
    1565
    0
                Ok(ast) => ast,
    1566
    0
                Err(e) => {
    1567
                    // Create error recovery context for parse errors using original error message
    1568
    0
                    let _recovery = self.create_error_recovery(input, &e.to_string());
    1569
    0
                    let parse_error = e.context("Failed to parse input");
    1570
    0
                    return Err(parse_error);
    1571
                }
    1572
            };
    1573
    1574
            // Check memory for AST
    1575
    0
            self.memory.try_alloc(std::mem::size_of_val(&ast))?;
    1576
    1577
            // Evaluate the expression with debug capture
    1578
    0
            let value = match self.evaluate_expr(&ast, deadline, 0) {
    1579
    0
                Ok(value) => {
    1580
                    // Clear debug info on successful evaluation
    1581
    0
                    self.last_error_debug = None;
    1582
    0
                    value
    1583
                }
    1584
    0
                Err(e) => {
    1585
                    // Capture debug information
    1586
    0
                    self.last_error_debug = Some(DebugInfo {
    1587
    0
                        expression: input.to_string(),
    1588
    0
                        error_message: e.to_string(),
    1589
    0
                        stack_trace: self.generate_stack_trace(&e),
    1590
    0
                        bindings_snapshot: self.bindings.clone(),
    1591
    0
                        timestamp: std::time::SystemTime::now(),
    1592
    0
                    });
    1593
    1594
                    // Create error recovery context for interactive recovery
    1595
    0
                    let _recovery = self.create_error_recovery(input, &e.to_string());
    1596
    1597
    0
                    return Err(e);
    1598
                }
    1599
            };
    1600
    1601
            // Store successful evaluation
    1602
    0
            self.history.push(input.to_string());
    1603
    0
            self.result_history.push(value.clone());
    1604
    1605
            // Update history variables
    1606
    0
            self.update_history_variables();
    1607
    1608
            // Let bindings are handled in evaluate_expr, no need to duplicate here
    1609
    1610
            // Return string representation (suppress Unit values from loops/statements)
    1611
    0
            match value {
    1612
    0
                Value::Unit => Ok(String::new()),
    1613
    0
                _ => Ok(value.to_string())
    1614
            }
    1615
    0
        }
    1616
    1617
        /// Get tab completions for the given input at the cursor position
    1618
    0
        pub fn complete(&self, input: &str) -> Vec<String> {
    1619
    0
            let pos = input.len();
    1620
    0
            let mut completer = RuchyCompleter::new();
    1621
    0
            completer.get_completions(input, pos, &self.bindings)
    1622
    0
        }
    1623
    1624
        /// Get the current REPL mode
    1625
    0
        pub fn get_mode(&self) -> &str {
    1626
    0
            match self.mode {
    1627
    0
                ReplMode::Normal => "normal",
    1628
    0
                ReplMode::Shell => "shell",
    1629
    0
                ReplMode::Pkg => "pkg",
    1630
    0
                ReplMode::Help => "help",
    1631
    0
                ReplMode::Sql => "sql",
    1632
    0
                ReplMode::Math => "math",
    1633
    0
                ReplMode::Debug => "debug",
    1634
    0
                ReplMode::Time => "time",
    1635
    0
                ReplMode::Test => "test",
    1636
            }
    1637
    0
        }
    1638
    1639
        /// Get the current prompt
    1640
    0
        pub fn get_prompt(&self) -> String {
    1641
    0
            self.mode.prompt()
    1642
    0
        }
    1643
    1644
        /// Create a new binding (for let/var) - handles shadowing
    1645
    0
        fn create_binding(&mut self, name: String, value: Value, is_mutable: bool) {
    1646
    0
            self.bindings.insert(name.clone(), value);
    1647
    0
            self.binding_mutability.insert(name, is_mutable);
    1648
    0
        }
    1649
    1650
        /// Try to update an existing binding (for assignment)
    1651
    0
        fn update_binding(&mut self, name: &str, value: Value) -> Result<()> {
    1652
    0
            if !self.bindings.contains_key(name) {
    1653
    0
                bail!("Cannot assign to undefined variable '{}'. \n  Hint: Declare it first with 'let {} = value' or 'var {} = value'", name, name, name)
    1654
    0
            }
    1655
    1656
    0
            let is_mutable = self.binding_mutability.get(name).copied().unwrap_or(false);
    1657
    0
            if !is_mutable {
    1658
    0
                bail!("Cannot assign to immutable binding '{}'. \n  Hint: Use 'var {} = value' for mutable bindings or shadow with 'let {} = new_value'", name, name, name)
    1659
    0
            }
    1660
    1661
    0
            self.bindings.insert(name.to_string(), value);
    1662
    0
            Ok(())
    1663
    0
        }
    1664
    1665
        /// Get the value of a binding
    1666
    0
        fn get_binding(&self, name: &str) -> Option<Value> {
    1667
    0
            self.bindings.get(name).cloned()
    1668
    0
        }
    1669
    1670
        /// Check if a binding exists
    1671
        #[allow(dead_code)]
    1672
    0
        fn has_binding(&self, name: &str) -> bool {
    1673
    0
            self.bindings.contains_key(name)
    1674
    0
        }
    1675
    1676
        /// Evaluate an expression to a value
    1677
        #[allow(clippy::too_many_lines)]
    1678
        #[allow(clippy::cognitive_complexity)]
    1679
    0
        fn evaluate_expr(&mut self, expr: &Expr, deadline: Instant, depth: usize) -> Result<Value> {
    1680
            // Check resource bounds
    1681
    0
            self.check_resource_limits(deadline, depth)?;
    1682
    1683
            // COMPLEXITY REDUCTION: Dispatcher pattern by expression category
    1684
    0
            match &expr.kind {
    1685
                // Basic expressions (literals, identifiers, binaries, unaries)
    1686
                ExprKind::Literal(_) | ExprKind::Binary { .. } | ExprKind::Unary { .. }
    1687
                | ExprKind::Identifier(_) | ExprKind::QualifiedName { .. } => {
    1688
    0
                    self.evaluate_basic_expr(expr, deadline, depth)
    1689
                }
    1690
    1691
                // Control flow expressions
    1692
                ExprKind::If { .. } | ExprKind::Match { .. } | ExprKind::For { .. }
    1693
                | ExprKind::While { .. } | ExprKind::IfLet { .. } | ExprKind::WhileLet { .. }
    1694
                | ExprKind::Loop { .. } | ExprKind::Break { .. } | ExprKind::Continue { .. }
    1695
                | ExprKind::TryCatch { .. } => {
    1696
    0
                    self.evaluate_control_flow_expr(expr, deadline, depth)
    1697
                }
    1698
    1699
                // Data structure expressions
    1700
                ExprKind::List(_) | ExprKind::Tuple(_) | ExprKind::ObjectLiteral { .. }
    1701
                | ExprKind::Range { .. } | ExprKind::FieldAccess { .. } | ExprKind::OptionalFieldAccess { .. }
    1702
                | ExprKind::IndexAccess { .. } | ExprKind::Slice { .. } => {
    1703
    0
                    self.evaluate_data_structure_expr(expr, deadline, depth)
    1704
                }
    1705
    1706
                // Function and call expressions
    1707
                ExprKind::Function { .. } | ExprKind::Lambda { .. } | ExprKind::Call { .. }
    1708
                | ExprKind::MethodCall { .. } | ExprKind::OptionalMethodCall { .. } => {
    1709
    0
                    self.evaluate_function_expr(expr, deadline, depth)
    1710
                }
    1711
    1712
                // Advanced language features
    1713
    0
                _ => self.evaluate_advanced_expr(expr, deadline, depth)
    1714
            }
    1715
    0
        }
    1716
    1717
        // COMPLEXITY REDUCTION: Basic expressions dispatcher
    1718
    0
        fn evaluate_basic_expr(&mut self, expr: &Expr, deadline: Instant, depth: usize) -> Result<Value> {
    1719
    0
            match &expr.kind {
    1720
    0
                ExprKind::Literal(lit) => self.evaluate_literal(lit),
    1721
    0
                ExprKind::Binary { left, op, right } => {
    1722
    0
                    self.evaluate_binary_expr(left, *op, right, deadline, depth)
    1723
                }
    1724
    0
                ExprKind::Unary { op, operand } => {
    1725
    0
                    self.evaluate_unary_expr(*op, operand, deadline, depth)
    1726
                }
    1727
    0
                ExprKind::Identifier(name) => self.evaluate_identifier(name),
    1728
    0
                ExprKind::QualifiedName { module, name } => {
    1729
    0
                    Ok(Self::evaluate_qualified_name(module, name))
    1730
                }
    1731
    0
                _ => bail!("Non-basic expression in basic dispatcher"),
    1732
            }
    1733
    0
        }
    1734
    1735
        // COMPLEXITY REDUCTION: Control flow expressions dispatcher
    1736
    0
        fn evaluate_control_flow_expr(&mut self, expr: &Expr, deadline: Instant, depth: usize) -> Result<Value> {
    1737
    0
            match &expr.kind {
    1738
    0
                ExprKind::If { condition, then_branch, else_branch } => {
    1739
    0
                    self.evaluate_if(condition, then_branch, else_branch.as_deref(), deadline, depth)
    1740
                }
    1741
    0
                ExprKind::Match { expr: match_expr, arms } => {
    1742
    0
                    self.evaluate_match(match_expr, arms, deadline, depth)
    1743
                }
    1744
    0
                ExprKind::For { var, pattern, iter, body } => {
    1745
    0
                    self.evaluate_for_loop(var, pattern.as_ref(), iter, body, deadline, depth)
    1746
                }
    1747
    0
                ExprKind::While { condition, body } => {
    1748
    0
                    self.evaluate_while_loop(condition, body, deadline, depth)
    1749
                }
    1750
    0
                ExprKind::IfLet { pattern, expr, then_branch, else_branch } => {
    1751
    0
                    self.evaluate_if_let(pattern, expr, then_branch, else_branch.as_deref(), deadline, depth)
    1752
                }
    1753
    0
                ExprKind::WhileLet { pattern, expr, body } => {
    1754
    0
                    self.evaluate_while_let(pattern, expr, body, deadline, depth)
    1755
                }
    1756
    0
                ExprKind::Loop { body } => self.evaluate_loop(body, deadline, depth),
    1757
    0
                ExprKind::Break { .. } => Err(anyhow::anyhow!("break")),
    1758
    0
                ExprKind::Continue { .. } => Err(anyhow::anyhow!("continue")),
    1759
    0
                ExprKind::TryCatch { try_block, catch_clauses, finally_block } => {
    1760
    0
                    self.evaluate_try_catch_block(try_block, catch_clauses, finally_block.as_deref(), deadline, depth)
    1761
                }
    1762
    0
                _ => bail!("Non-control-flow expression in control flow dispatcher"),
    1763
            }
    1764
    0
        }
    1765
    1766
        // COMPLEXITY REDUCTION: Data structure expressions dispatcher
    1767
    0
        fn evaluate_data_structure_expr(&mut self, expr: &Expr, deadline: Instant, depth: usize) -> Result<Value> {
    1768
    0
            match &expr.kind {
    1769
    0
                ExprKind::List(elements) => self.evaluate_list_literal(elements, deadline, depth),
    1770
    0
                ExprKind::Tuple(elements) => self.evaluate_tuple_literal(elements, deadline, depth),
    1771
    0
                ExprKind::ObjectLiteral { fields } => self.evaluate_object_literal(fields, deadline, depth),
    1772
    0
                ExprKind::Range { start, end, inclusive } => {
    1773
    0
                    self.evaluate_range_literal(start, end, *inclusive, deadline, depth)
    1774
                }
    1775
    0
                ExprKind::FieldAccess { object, field } => {
    1776
    0
                    self.evaluate_field_access(object, field, deadline, depth)
    1777
                }
    1778
    0
                ExprKind::OptionalFieldAccess { object, field } => {
    1779
    0
                    self.evaluate_optional_field_access(object, field, deadline, depth)
    1780
                }
    1781
    0
                ExprKind::IndexAccess { object, index } => {
    1782
    0
                    self.evaluate_index_access(object, index, deadline, depth)
    1783
                }
    1784
    0
                ExprKind::Slice { object, start, end } => {
    1785
    0
                    self.evaluate_slice(object, start.as_deref(), end.as_deref(), deadline, depth)
    1786
                }
    1787
    0
                _ => bail!("Non-data-structure expression in data structure dispatcher"),
    1788
            }
    1789
    0
        }
    1790
    1791
        // COMPLEXITY REDUCTION: Function expressions dispatcher
    1792
    0
        fn evaluate_function_expr(&mut self, expr: &Expr, deadline: Instant, depth: usize) -> Result<Value> {
    1793
    0
            match &expr.kind {
    1794
    0
                ExprKind::Function { name, params, body, .. } => {
    1795
    0
                    Ok(self.evaluate_function_definition(name, params, body))
    1796
                }
    1797
    0
                ExprKind::Lambda { params, body } => Ok(Self::evaluate_lambda_expression(params, body)),
    1798
    0
                ExprKind::Call { func, args } => self.evaluate_call(func, args, deadline, depth),
    1799
    0
                ExprKind::MethodCall { receiver, method, args } => {
    1800
    0
                    let receiver_val = self.evaluate_expr(receiver, deadline, depth + 1)?;
    1801
    0
                    match receiver_val {
    1802
    0
                        Value::List(items) => {
    1803
    0
                            self.evaluate_list_methods(items, method, args, deadline, depth)
    1804
                        }
    1805
    0
                        Value::String(s) => {
    1806
                            // Special case for Array constructor
    1807
    0
                            if s == "Array constructor" && method == "new" {
    1808
    0
                                self.validate_arg_count("Array.new", args, 2)?;
    1809
                                // Evaluate arguments
    1810
    0
                                let size_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    1811
    0
                                let default_val = self.evaluate_arg(args, 1, deadline, depth)?;
    1812
    1813
                                // Return a stub Array representation
    1814
    0
                                return Self::ok_string(format!("Array(size: {size_val}, default: {default_val})"));
    1815
    0
                            }
    1816
    0
                            Self::evaluate_string_methods(&s, method, args, deadline, depth)
    1817
                        }
    1818
    0
                        Value::Int(_) | Value::Float(_) => self.evaluate_numeric_methods(&receiver_val, method),
    1819
    0
                        Value::Char(c) => Self::evaluate_char_methods(c, method),
    1820
    0
                        Value::Object(obj) => {
    1821
    0
                            Self::evaluate_object_methods(obj, method, args, deadline, depth)
    1822
                        }
    1823
    0
                        Value::HashMap(map) => {
    1824
    0
                            self.evaluate_hashmap_methods(map, method, args, deadline, depth)
    1825
                        }
    1826
    0
                        Value::HashSet(set) => {
    1827
    0
                            self.evaluate_hashset_methods(set, method, args, deadline, depth)
    1828
                        }
    1829
                        Value::EnumVariant { .. } => {
    1830
    0
                            self.evaluate_enum_methods(receiver_val, method, args, deadline, depth)
    1831
                        }
    1832
    0
                        Value::DataFrame { columns } => {
    1833
    0
                            self.evaluate_dataframe_methods(columns, method, args, deadline, depth)
    1834
                        }
    1835
    0
                        _ => Err(Self::method_not_supported(method, "this type"))?,
    1836
                    }
    1837
                }
    1838
    0
                ExprKind::OptionalMethodCall { receiver, method, args } => {
    1839
    0
                    self.evaluate_optional_method_call(receiver, method, args, deadline, depth)
    1840
                }
    1841
    0
                _ => bail!("Non-function expression in function dispatcher"),
    1842
            }
    1843
    0
        }
    1844
    1845
        // COMPLEXITY REDUCTION: Advanced expressions dispatcher
    1846
        /// Dispatch binding and assignment expressions (complexity: 6)
    1847
    0
        fn dispatch_binding_exprs(&mut self, expr: &Expr, deadline: Instant, depth: usize) -> Option<Result<Value>> {
    1848
    0
            match &expr.kind {
    1849
    0
                ExprKind::Let { name, type_annotation: _, value, body, is_mutable } => {
    1850
    0
                    Some(self.evaluate_let_binding(name, value, body, *is_mutable, deadline, depth))
    1851
                }
    1852
    0
                ExprKind::LetPattern { pattern, type_annotation: _, value, body, is_mutable } => {
    1853
    0
                    Some(self.evaluate_let_pattern(pattern, value, body, *is_mutable, deadline, depth))
    1854
                }
    1855
    0
                ExprKind::Assign { target, value } => {
    1856
    0
                    Some(self.evaluate_assignment(target, value, deadline, depth))
    1857
                }
    1858
    0
                ExprKind::Block(exprs) => Some(self.evaluate_block(exprs, deadline, depth)),
    1859
    0
                ExprKind::Module { name: _name, body } => {
    1860
    0
                    Some(self.evaluate_expr(body, deadline, depth + 1))
    1861
                }
    1862
    0
                _ => None,
    1863
            }
    1864
    0
        }
    1865
    1866
        /// Dispatch data structure expressions (complexity: 5)
    1867
    0
        fn dispatch_data_exprs(&mut self, expr: &Expr, deadline: Instant, depth: usize) -> Option<Result<Value>> {
    1868
    0
            match &expr.kind {
    1869
    0
                ExprKind::DataFrame { columns } => {
    1870
    0
                    Some(self.evaluate_dataframe_literal(columns, deadline, depth))
    1871
                }
    1872
    0
                ExprKind::DataFrameOperation { .. } => Some(Self::evaluate_dataframe_operation()),
    1873
    0
                ExprKind::StructLiteral { name: _, fields } => {
    1874
    0
                    Some(self.evaluate_struct_literal(fields, deadline, depth))
    1875
                }
    1876
    0
                ExprKind::Pipeline { expr, stages } => {
    1877
    0
                    Some(self.evaluate_pipeline(expr, stages, deadline, depth))
    1878
                }
    1879
    0
                ExprKind::StringInterpolation { parts } => {
    1880
    0
                    Some(self.evaluate_string_interpolation(parts, deadline, depth))
    1881
                }
    1882
    0
                _ => None,
    1883
            }
    1884
    0
        }
    1885
    1886
        /// Dispatch type definition expressions (complexity: 5)
    1887
    0
        fn dispatch_type_definitions(&mut self, expr: &Expr) -> Option<Result<Value>> {
    1888
    0
            match &expr.kind {
    1889
    0
                ExprKind::Enum { name, variants, .. } => {
    1890
    0
                    Some(Ok(self.evaluate_enum_definition(name, variants)))
    1891
                }
    1892
    0
                ExprKind::Struct { name, fields, .. } => {
    1893
    0
                    Some(Ok(Self::evaluate_struct_definition(name, fields)))
    1894
                }
    1895
    0
                ExprKind::Trait { name, methods, .. } => {
    1896
    0
                    Some(Ok(Self::evaluate_trait_definition(name, methods)))
    1897
                }
    1898
    0
                ExprKind::Impl { for_type, methods, .. } => {
    1899
    0
                    Some(Ok(self.evaluate_impl_block(for_type, methods)))
    1900
                }
    1901
    0
                _ => None,
    1902
            }
    1903
    0
        }
    1904
    1905
        /// Dispatch Result/Option expressions (complexity: 5)
    1906
    0
        fn dispatch_result_option_exprs(&mut self, expr: &Expr, deadline: Instant, depth: usize) -> Option<Result<Value>> {
    1907
    0
            match &expr.kind {
    1908
    0
                ExprKind::Ok { value } => Some(self.evaluate_result_ok(value, deadline, depth)),
    1909
    0
                ExprKind::Err { error } => Some(self.evaluate_result_err(error, deadline, depth)),
    1910
    0
                ExprKind::Some { value } => Some(self.evaluate_option_some(value, deadline, depth)),
    1911
    0
                ExprKind::None => Some(Ok(Self::evaluate_option_none())),
    1912
    0
                ExprKind::Try { expr } => Some(self.evaluate_try_operator(expr, deadline, depth)),
    1913
    0
                _ => None,
    1914
            }
    1915
    0
        }
    1916
    1917
        /// Dispatch control flow expressions (complexity: 4)
    1918
    0
        fn dispatch_control_flow_exprs(&mut self, expr: &Expr, deadline: Instant, depth: usize) -> Option<Result<Value>> {
    1919
    0
            match &expr.kind {
    1920
    0
                ExprKind::Return { value } => {
    1921
    0
                    if let Some(val) = value {
    1922
    0
                        let result = self.evaluate_expr(val, deadline, depth + 1);
    1923
    0
                        Some(result.and_then(|v| Err(anyhow::anyhow!("return:{}", v))))
    1924
                    } else {
    1925
    0
                        Some(Err(anyhow::anyhow!("return:()")))
    1926
                    }
    1927
                }
    1928
    0
                ExprKind::Await { expr } => Some(self.evaluate_await_expr(expr, deadline, depth)),
    1929
    0
                ExprKind::AsyncBlock { body } => Some(self.evaluate_async_block(body, deadline, depth)),
    1930
    0
                _ => None,
    1931
            }
    1932
    0
        }
    1933
    1934
        /// Main advanced expression dispatcher (complexity: 8)
    1935
    0
        fn evaluate_advanced_expr(&mut self, expr: &Expr, deadline: Instant, depth: usize) -> Result<Value> {
    1936
            // Try binding and assignment expressions
    1937
    0
            if let Some(result) = self.dispatch_binding_exprs(expr, deadline, depth) {
    1938
    0
                return result;
    1939
    0
            }
    1940
    1941
            // Try data structure expressions
    1942
    0
            if let Some(result) = self.dispatch_data_exprs(expr, deadline, depth) {
    1943
    0
                return result;
    1944
    0
            }
    1945
    1946
            // Try type definitions
    1947
    0
            if let Some(result) = self.dispatch_type_definitions(expr) {
    1948
    0
                return result;
    1949
    0
            }
    1950
    1951
            // Try Result/Option expressions
    1952
    0
            if let Some(result) = self.dispatch_result_option_exprs(expr, deadline, depth) {
    1953
    0
                return result;
    1954
    0
            }
    1955
    1956
            // Try control flow expressions
    1957
    0
            if let Some(result) = self.dispatch_control_flow_exprs(expr, deadline, depth) {
    1958
    0
                return result;
    1959
    0
            }
    1960
    1961
            // Handle remaining cases
    1962
    0
            match &expr.kind {
    1963
    0
                ExprKind::Command { program, args, env: _, working_dir: _ } => {
    1964
    0
                    Self::evaluate_command(program, args, deadline, depth)
    1965
                }
    1966
    0
                ExprKind::Macro { name, args } => {
    1967
    0
                    self.evaluate_macro(name, args, deadline, depth)
    1968
                }
    1969
    0
                ExprKind::Import { path, items } => {
    1970
    0
                    self.evaluate_import(path, items)
    1971
                }
    1972
    0
                ExprKind::Export { items } => {
    1973
    0
                    self.evaluate_export(items)
    1974
                }
    1975
    0
                ExprKind::TypeCast { expr, target_type } => {
    1976
    0
                    self.evaluate_type_cast(expr, target_type, deadline, depth)
    1977
                }
    1978
                ExprKind::Spread { .. } => {
    1979
    0
                    bail!("Spread operator (...) can only be used inside array literals")
    1980
                }
    1981
    0
                _ => bail!("Expression type not yet implemented: {:?}", expr.kind),
    1982
            }
    1983
    0
        }
    1984
    1985
        // ========================================================================
    1986
        // Helper methods extracted to reduce evaluate_expr complexity
    1987
        // Following Toyota Way: Each function has single responsibility
    1988
        // Target: All functions < 50 cyclomatic complexity
    1989
        // ========================================================================
    1990
    1991
        /// Handle method calls on list values (complexity < 20)
    1992
    0
        fn evaluate_list_methods(
    1993
    0
            &mut self,
    1994
    0
            items: Vec<Value>,
    1995
    0
            method: &str,
    1996
    0
            args: &[Expr],
    1997
    0
            deadline: Instant,
    1998
    0
            depth: usize,
    1999
    0
        ) -> Result<Value> {
    2000
    0
            match method {
    2001
    0
                "map" => self.evaluate_list_map(items, args, deadline, depth),
    2002
    0
                "filter" => self.evaluate_list_filter(items, args, deadline, depth),
    2003
    0
                "reduce" => self.evaluate_list_reduce(items, args, deadline, depth),
    2004
    0
                "len" | "length" => {
    2005
    0
                    self.validate_arg_count(method, args, 0)?;
    2006
    0
                    Self::evaluate_list_length(&items)
    2007
                }
    2008
    0
                "head" | "first" => {
    2009
    0
                    self.validate_arg_count(method, args, 0)?;
    2010
    0
                    Self::evaluate_list_head(&items)
    2011
                }
    2012
    0
                "last" => {
    2013
    0
                    self.validate_arg_count("last", args, 0)?;
    2014
    0
                    Self::evaluate_list_last(&items)
    2015
                }
    2016
    0
                "tail" | "rest" => {
    2017
    0
                    self.validate_arg_count(method, args, 0)?;
    2018
    0
                    Self::evaluate_list_tail(items)
    2019
                }
    2020
    0
                "reverse" => {
    2021
    0
                    self.validate_arg_count("reverse", args, 0)?;
    2022
    0
                    Self::evaluate_list_reverse(items)
    2023
                }
    2024
    0
                "sum" => {
    2025
    0
                    self.validate_arg_count("sum", args, 0)?;
    2026
    0
                    Self::evaluate_list_sum(&items)
    2027
                }
    2028
    0
                "push" => self.evaluate_list_push(items, args, deadline, depth),
    2029
    0
                "pop" => Self::evaluate_list_pop(items, args),
    2030
    0
                "append" => self.evaluate_list_append(items, args, deadline, depth),
    2031
    0
                "insert" => self.evaluate_list_insert(items, args, deadline, depth),
    2032
    0
                "remove" => self.evaluate_list_remove(items, args, deadline, depth),
    2033
    0
                "slice" => self.evaluate_list_slice(items, args, deadline, depth),
    2034
    0
                "concat" => self.evaluate_list_concat(items, args, deadline, depth),
    2035
    0
                "flatten" => Self::evaluate_list_flatten(items, args),
    2036
    0
                "unique" => Self::evaluate_list_unique(items, args),
    2037
    0
                "join" => self.evaluate_list_join(items, args, deadline, depth),
    2038
    0
                "find" => self.evaluate_list_find(items, args, deadline, depth),
    2039
    0
                "any" => self.evaluate_list_any(items, args, deadline, depth),
    2040
    0
                "all" => self.evaluate_list_all(items, args, deadline, depth),
    2041
    0
                "product" => Self::evaluate_list_product(&items),
    2042
    0
                "min" => Self::evaluate_list_min(&items),
    2043
    0
                "max" => Self::evaluate_list_max(&items),
    2044
    0
                "take" => self.evaluate_list_take(items, args, deadline, depth),
    2045
    0
                "drop" => self.evaluate_list_drop(items, args, deadline, depth),
    2046
    0
                _ => self.unknown_method_error("list", method),
    2047
            }
    2048
    0
        }
    2049
    2050
        /// Evaluate `list.map()` operation (complexity: 8)
    2051
    0
        fn evaluate_list_map(
    2052
    0
            &mut self,
    2053
    0
            items: Vec<Value>,
    2054
    0
            args: &[Expr],
    2055
    0
            deadline: Instant,
    2056
    0
            depth: usize,
    2057
    0
        ) -> Result<Value> {
    2058
    0
            self.validate_arg_count("map", args, 1)?;
    2059
    2060
    0
            if let ExprKind::Lambda { params, body } = &args[0].kind {
    2061
    0
                if params.len() != 1 {
    2062
    0
                    bail!("map lambda must take exactly 1 parameter");
    2063
    0
                }
    2064
    2065
    0
                self.with_saved_bindings(|repl| {
    2066
    0
                    let mut results = Vec::new();
    2067
    0
                    for item in items {
    2068
    0
                        repl.bindings.insert(params[0].name(), item);
    2069
    0
                        let result = repl.evaluate_expr(body, deadline, depth + 1)?;
    2070
    0
                        results.push(result);
    2071
                    }
    2072
    0
                    Self::ok_list(results)
    2073
    0
                })
    2074
            } else {
    2075
    0
                bail!("map currently only supports lambda expressions");
    2076
            }
    2077
    0
        }
    2078
    2079
        /// Evaluate `list.filter()` operation (complexity: 9)
    2080
    0
        fn evaluate_list_filter(
    2081
    0
            &mut self,
    2082
    0
            items: Vec<Value>,
    2083
    0
            args: &[Expr],
    2084
    0
            deadline: Instant,
    2085
    0
            depth: usize,
    2086
    0
        ) -> Result<Value> {
    2087
    0
            self.validate_arg_count("filter", args, 1)?;
    2088
    2089
    0
            if let ExprKind::Lambda { params, body } = &args[0].kind {
    2090
    0
                if params.len() != 1 {
    2091
    0
                    bail!("filter lambda must take exactly 1 parameter");
    2092
    0
                }
    2093
    2094
    0
                self.with_saved_bindings(|repl| {
    2095
    0
                    let mut results = Vec::new();
    2096
    0
                    for item in items {
    2097
    0
                        repl.bindings.insert(params[0].name(), item.clone());
    2098
    0
                        let predicate_result = repl.evaluate_expr(body, deadline, depth + 1)?;
    2099
    2100
    0
                        if let Value::Bool(true) = predicate_result {
    2101
    0
                            results.push(item);
    2102
    0
                        }
    2103
                    }
    2104
    0
                    Self::ok_list(results)
    2105
    0
                })
    2106
            } else {
    2107
    0
                bail!("filter currently only supports lambda expressions");
    2108
            }
    2109
    0
        }
    2110
    2111
        /// Evaluate `list.reduce()` operation (complexity: 10)
    2112
    0
        fn evaluate_list_reduce(
    2113
    0
            &mut self,
    2114
    0
            items: Vec<Value>,
    2115
    0
            args: &[Expr],
    2116
    0
            deadline: Instant,
    2117
    0
            depth: usize,
    2118
    0
        ) -> Result<Value> {
    2119
    0
            if args.len() != 2 {
    2120
    0
                bail!("reduce expects 2 arguments: lambda and initial value");
    2121
    0
            }
    2122
    2123
            // Args are now: [lambda, initial_value] to match JS/Ruby style
    2124
    0
            let mut accumulator = self.evaluate_arg(args, 1, deadline, depth)?;
    2125
    2126
            // Debug: Check what type of expression args[0] is
    2127
    0
            match &args[0].kind {
    2128
    0
                ExprKind::Lambda { params, body } => {
    2129
    0
                    if params.len() != 2 {
    2130
    0
                        bail!("reduce lambda must take exactly 2 parameters");
    2131
    0
                    }
    2132
    2133
    0
                    self.with_saved_bindings(|repl| {
    2134
    0
                        for item in items {
    2135
    0
                            repl.bindings.insert(params[0].name(), accumulator);
    2136
    0
                            repl.bindings.insert(params[1].name(), item);
    2137
    0
                            accumulator = repl.evaluate_expr(body, deadline, depth + 1)?;
    2138
                        }
    2139
    0
                        Ok(accumulator)
    2140
    0
                    })
    2141
                }
    2142
    0
                other => {
    2143
                    // Debug: Check the actual expression kind
    2144
    0
                    match other {
    2145
    0
                        ExprKind::Call { .. } => bail!("reduce first argument is a function call, not a lambda"),
    2146
    0
                        ExprKind::Identifier(..) => bail!("reduce first argument is an identifier, not a lambda"),
    2147
    0
                        ExprKind::Literal(..) => bail!("reduce first argument is a literal, not a lambda"),
    2148
    0
                        ExprKind::Binary { .. } => bail!("reduce first argument is a binary expression, not a lambda"),
    2149
    0
                        ExprKind::Unary { .. } => bail!("reduce first argument is a unary expression, not a lambda"),
    2150
    0
                        _ => bail!("reduce first argument is not a lambda expression (some other type)"),
    2151
                    }
    2152
                }
    2153
            }
    2154
    0
        }
    2155
    2156
        /// Evaluate `list.len()` and `list.length()` operations (complexity: 3)
    2157
    0
        fn evaluate_list_length(items: &[Value]) -> Result<Value> {
    2158
    0
            let len = items.len();
    2159
    0
            i64::try_from(len)
    2160
    0
                .map(Value::Int)
    2161
    0
                .map_err(|_| anyhow::anyhow!("List length too large to represent as i64"))
    2162
    0
        }
    2163
    2164
        /// Evaluate `list.head()` and `list.first()` operations (complexity: 2)
    2165
    0
        fn evaluate_list_head(items: &[Value]) -> Result<Value> {
    2166
    0
            items
    2167
    0
                .first()
    2168
    0
                .cloned()
    2169
    0
                .ok_or_else(|| anyhow::anyhow!("Empty list"))
    2170
    0
        }
    2171
    2172
        /// Evaluate `list.last()` operation (complexity: 2)
    2173
    0
        fn evaluate_list_last(items: &[Value]) -> Result<Value> {
    2174
    0
            items
    2175
    0
                .last()
    2176
    0
                .cloned()
    2177
    0
                .ok_or_else(|| anyhow::anyhow!("Empty list"))
    2178
    0
        }
    2179
    2180
        /// Evaluate `list.tail()` and `list.rest()` operations (complexity: 2)
    2181
    0
        fn evaluate_list_tail(items: Vec<Value>) -> Result<Value> {
    2182
    0
            if items.is_empty() {
    2183
    0
                Self::ok_list(Vec::new())
    2184
            } else {
    2185
    0
                Self::ok_list(items[1..].to_vec())
    2186
            }
    2187
    0
        }
    2188
    2189
        /// Evaluate `list.reverse()` operation (complexity: 2)
    2190
    0
        fn evaluate_list_reverse(mut items: Vec<Value>) -> Result<Value> {
    2191
    0
            items.reverse();
    2192
    0
            Self::ok_list(items)
    2193
    0
        }
    2194
    2195
        /// Evaluate `list.sum()` operation (complexity: 4)
    2196
    0
        fn evaluate_list_sum(items: &[Value]) -> Result<Value> {
    2197
    0
            if items.is_empty() {
    2198
    0
                return Self::ok_int(0);
    2199
    0
            }
    2200
    2201
            // Check if we have any floats
    2202
    0
            let has_float = items.iter().any(|v| matches!(v, Value::Float(_)));
    2203
    2204
    0
            if has_float {
    2205
    0
                let mut sum = 0.0;
    2206
    0
                for item in items {
    2207
    0
                    match item {
    2208
    0
                        Value::Int(n) => sum += *n as f64,
    2209
    0
                        Value::Float(f) => sum += f,
    2210
    0
                        _ => bail!("sum can only be applied to numbers"),
    2211
                    }
    2212
                }
    2213
    0
                Self::ok_float(sum)
    2214
            } else {
    2215
    0
                let mut sum = 0i64;
    2216
    0
                for item in items {
    2217
    0
                    if let Value::Int(n) = item {
    2218
    0
                        sum += n;
    2219
    0
                    } else {
    2220
    0
                        bail!("sum can only be applied to numbers");
    2221
                    }
    2222
                }
    2223
    0
                Self::ok_int(sum)
    2224
            }
    2225
    0
        }
    2226
    2227
        /// Evaluate `list.push()` operation (complexity: 4)
    2228
    0
        fn evaluate_list_push(
    2229
    0
            &mut self,
    2230
    0
            mut items: Vec<Value>,
    2231
    0
            args: &[Expr],
    2232
    0
            deadline: Instant,
    2233
    0
            depth: usize,
    2234
    0
        ) -> Result<Value> {
    2235
    0
            Self::validate_exact_args("push", 1, args.len())?;
    2236
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    2237
    0
            items.push(value);
    2238
    0
            Self::ok_list(items)
    2239
    0
        }
    2240
    2241
        /// Evaluate `list.pop()` operation (complexity: 3)
    2242
    0
        fn evaluate_list_pop(mut items: Vec<Value>, args: &[Expr]) -> Result<Value> {
    2243
    0
            if !args.is_empty() {
    2244
    0
                bail!("pop requires no arguments");
    2245
    0
            }
    2246
    0
            if let Some(popped) = items.pop() {
    2247
    0
                Ok(popped)
    2248
            } else {
    2249
    0
                bail!("Cannot pop from empty list")
    2250
            }
    2251
    0
        }
    2252
    2253
        /// Evaluate `list.append()` operation (complexity: 5)
    2254
    0
        fn evaluate_list_append(
    2255
    0
            &mut self,
    2256
    0
            mut items: Vec<Value>,
    2257
    0
            args: &[Expr],
    2258
    0
            deadline: Instant,
    2259
    0
            depth: usize,
    2260
    0
        ) -> Result<Value> {
    2261
    0
            Self::validate_exact_args("append", 1, args.len())?;
    2262
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    2263
    0
            if let Value::List(other_items) = value {
    2264
    0
                items.extend(other_items);
    2265
    0
                Self::ok_list(items)
    2266
            } else {
    2267
    0
                bail!("append requires a list argument");
    2268
            }
    2269
    0
        }
    2270
    2271
        /// Evaluate `list.insert()` operation (complexity: 6)
    2272
    0
        fn evaluate_list_insert(
    2273
    0
            &mut self,
    2274
    0
            mut items: Vec<Value>,
    2275
    0
            args: &[Expr],
    2276
    0
            deadline: Instant,
    2277
    0
            depth: usize,
    2278
    0
        ) -> Result<Value> {
    2279
    0
            if args.len() != 2 {
    2280
    0
                bail!("insert requires exactly 2 arguments (index, value)");
    2281
    0
            }
    2282
    0
            let index = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    2283
    0
            let value = self.evaluate_arg(args, 1, deadline, depth)?;
    2284
    0
            if let Value::Int(idx) = index {
    2285
    0
                if idx < 0 || idx as usize > items.len() {
    2286
    0
                    bail!("Insert index out of bounds");
    2287
    0
                }
    2288
    0
                items.insert(idx as usize, value);
    2289
    0
                Self::ok_list(items)
    2290
            } else {
    2291
    0
                bail!("Insert index must be an integer");
    2292
            }
    2293
    0
        }
    2294
    2295
        /// Evaluate `list.remove()` operation (complexity: 6)
    2296
    0
        fn evaluate_list_remove(
    2297
    0
            &mut self,
    2298
    0
            mut items: Vec<Value>,
    2299
    0
            args: &[Expr],
    2300
    0
            deadline: Instant,
    2301
    0
            depth: usize,
    2302
    0
        ) -> Result<Value> {
    2303
    0
            if args.len() != 1 {
    2304
    0
                bail!("remove requires exactly 1 argument (index)");
    2305
    0
            }
    2306
    0
            let index = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    2307
    0
            if let Value::Int(idx) = index {
    2308
    0
                if idx < 0 || idx as usize >= items.len() {
    2309
    0
                    bail!("Remove index out of bounds");
    2310
    0
                }
    2311
    0
                let removed = items.remove(idx as usize);
    2312
    0
                Ok(removed)
    2313
            } else {
    2314
    0
                bail!("Remove index must be an integer");
    2315
            }
    2316
    0
        }
    2317
    2318
        /// Evaluate `list.slice()` operation (complexity: 7)
    2319
    0
        fn evaluate_list_slice(
    2320
    0
            &mut self,
    2321
    0
            items: Vec<Value>,
    2322
    0
            args: &[Expr],
    2323
    0
            deadline: Instant,
    2324
    0
            depth: usize,
    2325
    0
        ) -> Result<Value> {
    2326
    0
            if args.len() != 2 {
    2327
    0
                bail!("slice requires exactly 2 arguments (start, end)");
    2328
    0
            }
    2329
    0
            let start_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    2330
    0
            let end_val = self.evaluate_arg(args, 1, deadline, depth)?;
    2331
    2332
    0
            if let (Value::Int(start), Value::Int(end)) = (start_val, end_val) {
    2333
    0
                let start = start as usize;
    2334
    0
                let end = end as usize;
    2335
    2336
    0
                if start > items.len() || end > items.len() || start > end {
    2337
    0
                    Self::ok_list(Vec::new()) // Return empty for out of bounds
    2338
                } else {
    2339
    0
                    Self::ok_list(items[start..end].to_vec())
    2340
                }
    2341
            } else {
    2342
    0
                bail!("slice arguments must be integers");
    2343
            }
    2344
    0
        }
    2345
    2346
        /// Evaluate `list.concat()` operation (complexity: 5)
    2347
    0
        fn evaluate_list_concat(
    2348
    0
            &mut self,
    2349
    0
            mut items: Vec<Value>,
    2350
    0
            args: &[Expr],
    2351
    0
            deadline: Instant,
    2352
    0
            depth: usize,
    2353
    0
        ) -> Result<Value> {
    2354
    0
            if args.len() != 1 {
    2355
    0
                bail!("concat requires exactly 1 argument");
    2356
    0
            }
    2357
    0
            let other_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    2358
    2359
    0
            if let Value::List(other_items) = other_val {
    2360
    0
                items.extend(other_items);
    2361
    0
                Self::ok_list(items)
    2362
            } else {
    2363
    0
                bail!("concat argument must be a list");
    2364
            }
    2365
    0
        }
    2366
    2367
        /// Evaluate `list.flatten()` operation (complexity: 4)
    2368
    0
        fn evaluate_list_flatten(items: Vec<Value>, args: &[Expr]) -> Result<Value> {
    2369
    0
            if !args.is_empty() {
    2370
    0
                bail!("flatten requires no arguments");
    2371
    0
            }
    2372
    0
            let mut result = Vec::new();
    2373
    0
            for item in items {
    2374
    0
                if let Value::List(inner_items) = item {
    2375
    0
                    result.extend(inner_items);
    2376
    0
                } else {
    2377
    0
                    result.push(item);
    2378
    0
                }
    2379
            }
    2380
    0
            Self::ok_list(result)
    2381
    0
        }
    2382
    2383
        /// Evaluate `list.unique()` operation (complexity: 5)
    2384
    0
        fn evaluate_list_unique(items: Vec<Value>, args: &[Expr]) -> Result<Value> {
    2385
            use std::collections::HashSet;
    2386
    0
            if !args.is_empty() {
    2387
    0
                bail!("unique requires no arguments");
    2388
    0
            }
    2389
    0
            let mut seen = HashSet::new();
    2390
    0
            let mut result = Vec::new();
    2391
    2392
    0
            for item in items {
    2393
                // Use string representation for hashing since Value doesn't implement Hash
    2394
    0
                let key = format!("{item:?}");
    2395
    0
                if seen.insert(key) {
    2396
    0
                    result.push(item);
    2397
    0
                }
    2398
            }
    2399
    0
            Self::ok_list(result)
    2400
    0
        }
    2401
    2402
        /// Evaluate `list.join()` operation (complexity: 7)
    2403
    0
        fn evaluate_list_join(
    2404
    0
            &mut self,
    2405
    0
            items: Vec<Value>,
    2406
    0
            args: &[Expr],
    2407
    0
            deadline: Instant,
    2408
    0
            depth: usize,
    2409
    0
        ) -> Result<Value> {
    2410
    0
            if args.len() != 1 {
    2411
    0
                bail!("join requires exactly 1 argument (separator)");
    2412
    0
            }
    2413
    0
            let sep_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    2414
    2415
    0
            if let Value::String(separator) = sep_val {
    2416
    0
                let strings: Result<Vec<String>, _> = items.iter().map(|item| {
    2417
    0
                    if let Value::String(s) = item {
    2418
    0
                        Ok(s.clone())
    2419
                    } else {
    2420
    0
                        bail!("join requires a list of strings");
    2421
                    }
    2422
    0
                }).collect();
    2423
    2424
    0
                match strings {
    2425
    0
                    Ok(string_vec) => Self::ok_string(string_vec.join(&separator)),
    2426
    0
                    Err(e) => Err(e),
    2427
                }
    2428
            } else {
    2429
    0
                bail!("join separator must be a string");
    2430
            }
    2431
    0
        }
    2432
    2433
        /// Evaluate `list.find()` operation - find first element matching predicate
    2434
    0
        fn evaluate_list_find(
    2435
    0
            &mut self,
    2436
    0
            items: Vec<Value>,
    2437
    0
            args: &[Expr],
    2438
    0
            deadline: Instant,
    2439
    0
            depth: usize,
    2440
    0
        ) -> Result<Value> {
    2441
    0
            if args.len() != 1 {
    2442
    0
                bail!("find expects exactly one argument (predicate function)");
    2443
    0
            }
    2444
    2445
            // Handle lambda expression
    2446
    0
            if let ExprKind::Lambda { params, body } = &args[0].kind {
    2447
    0
                if params.len() != 1 {
    2448
    0
                    bail!("find lambda must take exactly 1 parameter");
    2449
    0
                }
    2450
    2451
    0
                let saved_bindings = self.bindings.clone();
    2452
    2453
    0
                for item in items {
    2454
    0
                    self.bindings.insert(params[0].name(), item.clone());
    2455
    0
                    let result = self.evaluate_expr(body, deadline, depth + 1)?;
    2456
    0
                    self.bindings = saved_bindings.clone();
    2457
    2458
    0
                    if let Value::Bool(true) = result {
    2459
    0
                        return Ok(Self::create_option_some(item));
    2460
    0
                    }
    2461
                }
    2462
    2463
    0
                self.bindings = saved_bindings;
    2464
            } else {
    2465
    0
                bail!("find currently only supports lambda expressions");
    2466
            }
    2467
    2468
    0
            Ok(Self::create_option_none())
    2469
    0
        }
    2470
    2471
        /// Evaluate `list.any()` operation - check if any element matches predicate
    2472
    0
        fn evaluate_list_any(
    2473
    0
            &mut self,
    2474
    0
            items: Vec<Value>,
    2475
    0
            args: &[Expr],
    2476
    0
            deadline: Instant,
    2477
    0
            depth: usize,
    2478
    0
        ) -> Result<Value> {
    2479
    0
            if args.len() != 1 {
    2480
    0
                bail!("any expects exactly one argument (predicate function)");
    2481
    0
            }
    2482
    2483
    0
            if let ExprKind::Lambda { params, body } = &args[0].kind {
    2484
    0
                if params.len() != 1 {
    2485
    0
                    bail!("any lambda must take exactly 1 parameter");
    2486
    0
                }
    2487
    2488
    0
                let saved_bindings = self.bindings.clone();
    2489
    2490
    0
                for item in items {
    2491
    0
                    self.bindings.insert(params[0].name(), item);
    2492
    0
                    let result = self.evaluate_expr(body, deadline, depth + 1)?;
    2493
    2494
    0
                    if let Value::Bool(true) = result {
    2495
    0
                        self.bindings = saved_bindings;
    2496
    0
                        return Self::ok_bool(true);
    2497
    0
                    }
    2498
                }
    2499
    2500
    0
                self.bindings = saved_bindings;
    2501
    0
                Self::ok_bool(false)
    2502
            } else {
    2503
    0
                bail!("any currently only supports lambda expressions");
    2504
            }
    2505
    0
        }
    2506
    2507
        /// Evaluate `list.all()` operation - check if all elements match predicate
    2508
    0
        fn evaluate_list_all(
    2509
    0
            &mut self,
    2510
    0
            items: Vec<Value>,
    2511
    0
            args: &[Expr],
    2512
    0
            deadline: Instant,
    2513
    0
            depth: usize,
    2514
    0
        ) -> Result<Value> {
    2515
    0
            if args.len() != 1 {
    2516
    0
                bail!("all expects exactly one argument (predicate function)");
    2517
    0
            }
    2518
    2519
    0
            if let ExprKind::Lambda { params, body } = &args[0].kind {
    2520
    0
                if params.len() != 1 {
    2521
    0
                    bail!("all lambda must take exactly 1 parameter");
    2522
    0
                }
    2523
    2524
    0
                let saved_bindings = self.bindings.clone();
    2525
    2526
    0
                for item in items {
    2527
    0
                    self.bindings.insert(params[0].name(), item);
    2528
    0
                    let result = self.evaluate_expr(body, deadline, depth + 1)?;
    2529
    2530
    0
                    match result {
    2531
                        Value::Bool(false) => {
    2532
    0
                            self.bindings = saved_bindings;
    2533
    0
                            return Self::ok_bool(false);
    2534
                        }
    2535
    0
                        Value::Bool(true) => {}
    2536
                        _ => {
    2537
    0
                            self.bindings = saved_bindings;
    2538
    0
                            bail!("Predicate must return boolean");
    2539
                        }
    2540
                    }
    2541
                }
    2542
    2543
    0
                self.bindings = saved_bindings;
    2544
    0
                Self::ok_bool(true)
    2545
            } else {
    2546
    0
                bail!("all currently only supports lambda expressions");
    2547
            }
    2548
    0
        }
    2549
    2550
        /// Evaluate `list.product()` operation - multiply all elements
    2551
    0
        fn evaluate_list_product(items: &[Value]) -> Result<Value> {
    2552
    0
            if items.is_empty() {
    2553
    0
                return Self::ok_int(1);
    2554
    0
            }
    2555
    2556
    0
            let mut product = Value::Int(1);
    2557
    0
            for item in items {
    2558
    0
                match (&product, item) {
    2559
    0
                    (Value::Int(a), Value::Int(b)) => {
    2560
    0
                        product = Value::Int(a * b);
    2561
    0
                    }
    2562
    0
                    (Value::Float(a), Value::Int(b)) => {
    2563
    0
                        product = Value::Float(a * (*b as f64));
    2564
    0
                    }
    2565
    0
                    (Value::Int(a), Value::Float(b)) => {
    2566
    0
                        product = Value::Float((*a as f64) * b);
    2567
    0
                    }
    2568
    0
                    (Value::Float(a), Value::Float(b)) => {
    2569
    0
                        product = Value::Float(a * b);
    2570
    0
                    }
    2571
    0
                    _ => bail!("Product can only be applied to numbers"),
    2572
                }
    2573
            }
    2574
    2575
    0
            Ok(product)
    2576
    0
        }
    2577
    2578
        /// Evaluate `list.min()` operation - find minimum element
    2579
    0
        fn evaluate_list_min(items: &[Value]) -> Result<Value> {
    2580
    0
            if items.is_empty() {
    2581
    0
                return Ok(Self::create_option_none());
    2582
    0
            }
    2583
    2584
    0
            let mut min = items[0].clone();
    2585
    0
            for item in &items[1..] {
    2586
    0
                match (&min, item) {
    2587
    0
                    (Value::Int(a), Value::Int(b)) if b < a => min = item.clone(),
    2588
    0
                    (Value::Float(a), Value::Float(b)) if b < a => min = item.clone(),
    2589
    0
                    (Value::Int(a), Value::Float(b)) if b < &(*a as f64) => min = item.clone(),
    2590
    0
                    (Value::Float(a), Value::Int(b)) if (*b as f64) < *a => min = item.clone(),
    2591
    0
                    _ => {}
    2592
                }
    2593
            }
    2594
    2595
    0
            Ok(Self::create_option_some(min))
    2596
    0
        }
    2597
    2598
        /// Evaluate `list.max()` operation - find maximum element
    2599
    0
        fn evaluate_list_max(items: &[Value]) -> Result<Value> {
    2600
    0
            if items.is_empty() {
    2601
    0
                return Ok(Self::create_option_none());
    2602
    0
            }
    2603
    2604
    0
            let mut max = items[0].clone();
    2605
    0
            for item in &items[1..] {
    2606
    0
                match (&max, item) {
    2607
    0
                    (Value::Int(a), Value::Int(b)) if b > a => max = item.clone(),
    2608
    0
                    (Value::Float(a), Value::Float(b)) if b > a => max = item.clone(),
    2609
    0
                    (Value::Int(a), Value::Float(b)) if b > &(*a as f64) => max = item.clone(),
    2610
    0
                    (Value::Float(a), Value::Int(b)) if (*b as f64) > *a => max = item.clone(),
    2611
    0
                    _ => {}
    2612
                }
    2613
            }
    2614
    2615
    0
            Ok(Self::create_option_some(max))
    2616
    0
        }
    2617
    2618
        /// Evaluate `list.take()` operation - take first n elements
    2619
    0
        fn evaluate_list_take(
    2620
    0
            &mut self,
    2621
    0
            items: Vec<Value>,
    2622
    0
            args: &[Expr],
    2623
    0
            deadline: Instant,
    2624
    0
            depth: usize,
    2625
    0
        ) -> Result<Value> {
    2626
    0
            if args.len() != 1 {
    2627
    0
                bail!("take expects exactly one argument (count)");
    2628
    0
            }
    2629
    2630
    0
            let count_val = self.evaluate_expr(&args[0], deadline, depth)?;
    2631
    0
            if let Value::Int(n) = count_val {
    2632
    0
                let n = n.max(0) as usize;
    2633
    0
                let taken: Vec<Value> = items.into_iter().take(n).collect();
    2634
    0
                Self::ok_list(taken)
    2635
            } else {
    2636
    0
                bail!("take count must be an integer");
    2637
            }
    2638
    0
        }
    2639
    2640
        /// Evaluate `list.drop()` operation - drop first n elements
    2641
    0
        fn evaluate_list_drop(
    2642
    0
            &mut self,
    2643
    0
            items: Vec<Value>,
    2644
    0
            args: &[Expr],
    2645
    0
            deadline: Instant,
    2646
    0
            depth: usize,
    2647
    0
        ) -> Result<Value> {
    2648
    0
            if args.len() != 1 {
    2649
    0
                bail!("drop expects exactly one argument (count)");
    2650
    0
            }
    2651
    2652
    0
            let count_val = self.evaluate_expr(&args[0], deadline, depth)?;
    2653
    0
            if let Value::Int(n) = count_val {
    2654
    0
                let n = n.max(0) as usize;
    2655
    0
                let dropped: Vec<Value> = items.into_iter().skip(n).collect();
    2656
    0
                Self::ok_list(dropped)
    2657
            } else {
    2658
    0
                bail!("drop count must be an integer");
    2659
            }
    2660
    0
        }
    2661
    2662
        /// Handle method calls on string values (complexity < 10)
    2663
        /// Handle simple string transformation methods (complexity: 5)
    2664
    0
        fn handle_string_transforms(s: &str, method: &str) -> Option<Result<Value>> {
    2665
    0
            match method {
    2666
    0
                "len" | "length" => {
    2667
    0
                    let len = s.len();
    2668
    0
                    Some(i64::try_from(len)
    2669
    0
                        .map(Value::Int)
    2670
    0
                        .map_err(|_| anyhow::anyhow!("String length too large to represent as i64")))
    2671
                }
    2672
    0
                "upper" | "to_upper" | "to_uppercase" => Some(Self::ok_string(s.to_uppercase())),
    2673
    0
                "lower" | "to_lower" | "to_lowercase" => Some(Self::ok_string(s.to_lowercase())),
    2674
    0
                "trim" => Some(Self::ok_string(s.trim().to_string())),
    2675
    0
                "chars" => {
    2676
    0
                    let chars: Vec<Value> = s.chars()
    2677
    0
                        .map(|c| Value::String(c.to_string()))
    2678
    0
                        .collect();
    2679
    0
                    Some(Self::ok_list(chars))
    2680
                }
    2681
    0
                "reverse" => {
    2682
    0
                    let reversed: String = s.chars().rev().collect();
    2683
    0
                    Some(Self::ok_string(reversed))
    2684
                }
    2685
    0
                "to_int" => {
    2686
    0
                    match s.parse::<i64>() {
    2687
    0
                        Ok(n) => Some(Self::ok_int(n)),
    2688
    0
                        Err(_) => Some(Err(anyhow::anyhow!("Cannot parse '{}' as integer", s))),
    2689
                    }
    2690
                }
    2691
    0
                "to_float" => {
    2692
    0
                    match s.parse::<f64>() {
    2693
    0
                        Ok(f) => Some(Self::ok_float(f)),
    2694
    0
                        Err(_) => Some(Err(anyhow::anyhow!("Cannot parse '{}' as float", s))),
    2695
                    }
    2696
                }
    2697
    0
                "parse" => {
    2698
                    // Try to parse as int first, then float
    2699
    0
                    if let Ok(n) = s.parse::<i64>() {
    2700
    0
                        Some(Self::ok_int(n))
    2701
    0
                    } else if let Ok(f) = s.parse::<f64>() {
    2702
    0
                        Some(Self::ok_float(f))
    2703
                    } else {
    2704
    0
                        Some(Err(anyhow::anyhow!("Cannot parse '{}' as number", s)))
    2705
                    }
    2706
                }
    2707
    0
                "bytes" => {
    2708
    0
                    let bytes: Vec<Value> = s.bytes()
    2709
    0
                        .map(|b| Value::Int(i64::from(b)))
    2710
    0
                        .collect();
    2711
    0
                    Some(Self::ok_list(bytes))
    2712
                }
    2713
    0
                "is_numeric" => {
    2714
    0
                    let is_num = s.parse::<f64>().is_ok();
    2715
    0
                    Some(Self::ok_bool(is_num))
    2716
                }
    2717
    0
                "is_alpha" => {
    2718
    0
                    let is_alpha = !s.is_empty() && s.chars().all(char::is_alphabetic);
    2719
    0
                    Some(Self::ok_bool(is_alpha))
    2720
                }
    2721
    0
                "is_alphanumeric" => {
    2722
    0
                    let is_alnum = !s.is_empty() && s.chars().all(char::is_alphanumeric);
    2723
    0
                    Some(Self::ok_bool(is_alnum))
    2724
                }
    2725
    0
                _ => None,
    2726
            }
    2727
    0
        }
    2728
    2729
        /// Handle string search methods (complexity: 6)
    2730
    0
        fn handle_string_search(s: &str, method: &str, args: &[Expr]) -> Option<Result<Value>> {
    2731
    0
            match method {
    2732
    0
                "contains" => {
    2733
    0
                    if args.len() != 1 {
    2734
    0
                        return Some(Err(anyhow::anyhow!("contains expects 1 argument")));
    2735
    0
                    }
    2736
    0
                    if let ExprKind::Literal(Literal::String(needle)) = &args[0].kind {
    2737
    0
                        Some(Self::ok_bool(s.contains(needle)))
    2738
                    } else {
    2739
    0
                        Some(Err(anyhow::anyhow!("contains argument must be a string literal")))
    2740
                    }
    2741
                }
    2742
    0
                "starts_with" => {
    2743
    0
                    if args.len() != 1 {
    2744
    0
                        return Some(Err(anyhow::anyhow!("starts_with expects 1 argument")));
    2745
    0
                    }
    2746
    0
                    if let ExprKind::Literal(Literal::String(prefix)) = &args[0].kind {
    2747
    0
                        Some(Self::ok_bool(s.starts_with(prefix)))
    2748
                    } else {
    2749
    0
                        Some(Err(anyhow::anyhow!("starts_with argument must be a string literal")))
    2750
                    }
    2751
                }
    2752
    0
                "ends_with" => {
    2753
    0
                    if args.len() != 1 {
    2754
    0
                        return Some(Err(anyhow::anyhow!("ends_with expects 1 argument")));
    2755
    0
                    }
    2756
    0
                    if let ExprKind::Literal(Literal::String(suffix)) = &args[0].kind {
    2757
    0
                        Some(Self::ok_bool(s.ends_with(suffix)))
    2758
                    } else {
    2759
    0
                        Some(Err(anyhow::anyhow!("ends_with argument must be a string literal")))
    2760
                    }
    2761
                }
    2762
    0
                _ => None,
    2763
            }
    2764
    0
        }
    2765
    2766
        /// Handle string manipulation methods (complexity: 8)
    2767
    0
        fn handle_string_manipulation(s: &str, method: &str, args: &[Expr]) -> Option<Result<Value>> {
    2768
    0
            match method {
    2769
    0
                "split" => {
    2770
    0
                    if args.len() != 1 {
    2771
    0
                        return Some(Err(anyhow::anyhow!("split expects 1 argument")));
    2772
    0
                    }
    2773
    0
                    if let ExprKind::Literal(Literal::String(sep)) = &args[0].kind {
    2774
    0
                        let parts: Vec<Value> = s.split(sep)
    2775
    0
                            .map(|p| Value::String(p.to_string()))
    2776
    0
                            .collect();
    2777
    0
                        Some(Self::ok_list(parts))
    2778
                    } else {
    2779
    0
                        Some(Err(anyhow::anyhow!("split separator must be a string literal")))
    2780
                    }
    2781
                }
    2782
    0
                "replace" => {
    2783
    0
                    if args.len() != 2 {
    2784
    0
                        return Some(Err(anyhow::anyhow!("replace expects 2 arguments (from, to)")));
    2785
    0
                    }
    2786
    0
                    if let (ExprKind::Literal(Literal::String(from)), ExprKind::Literal(Literal::String(to))) =
    2787
    0
                        (&args[0].kind, &args[1].kind) {
    2788
    0
                        Some(Self::ok_string(s.replace(from, to)))
    2789
                    } else {
    2790
    0
                        Some(Err(anyhow::anyhow!("replace arguments must be string literals")))
    2791
                    }
    2792
                }
    2793
    0
                "repeat" => {
    2794
    0
                    if args.len() != 1 {
    2795
    0
                        return Some(Err(anyhow::anyhow!("repeat expects 1 argument")));
    2796
    0
                    }
    2797
    0
                    if let ExprKind::Literal(Literal::Integer(count)) = &args[0].kind {
    2798
    0
                        if *count < 0 {
    2799
    0
                            Some(Err(anyhow::anyhow!("repeat count cannot be negative")))
    2800
                        } else {
    2801
    0
                            Some(Self::ok_string(s.repeat(*count as usize)))
    2802
                        }
    2803
                    } else {
    2804
    0
                        Some(Err(anyhow::anyhow!("repeat argument must be an integer")))
    2805
                    }
    2806
                }
    2807
    0
                "pad_left" => {
    2808
    0
                    if args.len() != 2 {
    2809
    0
                        return Some(Err(anyhow::anyhow!("pad_left expects 2 arguments (width, fill)")));
    2810
    0
                    }
    2811
    0
                    if let (ExprKind::Literal(Literal::Integer(width)), ExprKind::Literal(Literal::String(fill))) =
    2812
    0
                        (&args[0].kind, &args[1].kind) {
    2813
    0
                        let width = *width as usize;
    2814
    0
                        if s.len() >= width {
    2815
    0
                            Some(Self::ok_string(s.to_string()))
    2816
                        } else {
    2817
    0
                            let padding_needed = width - s.len();
    2818
    0
                            let fill_char = fill.chars().next().unwrap_or(' ');
    2819
    0
                            let padding = fill_char.to_string().repeat(padding_needed);
    2820
    0
                            Some(Self::ok_string(format!("{padding}{s}")))
    2821
                        }
    2822
                    } else {
    2823
    0
                        Some(Err(anyhow::anyhow!("pad_left arguments must be (integer, string)")))
    2824
                    }
    2825
                }
    2826
    0
                "pad_right" => {
    2827
    0
                    if args.len() != 2 {
    2828
    0
                        return Some(Err(anyhow::anyhow!("pad_right expects 2 arguments (width, fill)")));
    2829
    0
                    }
    2830
    0
                    if let (ExprKind::Literal(Literal::Integer(width)), ExprKind::Literal(Literal::String(fill))) =
    2831
    0
                        (&args[0].kind, &args[1].kind) {
    2832
    0
                        let width = *width as usize;
    2833
    0
                        if s.len() >= width {
    2834
    0
                            Some(Self::ok_string(s.to_string()))
    2835
                        } else {
    2836
    0
                            let padding_needed = width - s.len();
    2837
    0
                            let fill_char = fill.chars().next().unwrap_or(' ');
    2838
    0
                            let padding = fill_char.to_string().repeat(padding_needed);
    2839
    0
                            Some(Self::ok_string(format!("{s}{padding}")))
    2840
                        }
    2841
                    } else {
    2842
    0
                        Some(Err(anyhow::anyhow!("pad_right arguments must be (integer, string)")))
    2843
                    }
    2844
                }
    2845
    0
                _ => None,
    2846
            }
    2847
    0
        }
    2848
    2849
        /// Handle substring extraction (complexity: 7)
    2850
    0
        fn handle_substring(s: &str, args: &[Expr]) -> Result<Value> {
    2851
    0
            if args.len() == 2 {
    2852
                // substring(start, end)
    2853
    0
                if let (ExprKind::Literal(Literal::Integer(start)), ExprKind::Literal(Literal::Integer(end))) =
    2854
    0
                    (&args[0].kind, &args[1].kind) {
    2855
    0
                    let start_idx = (*start as usize).min(s.len());
    2856
    0
                    let end_idx = (*end as usize).min(s.len());
    2857
    0
                    if start_idx <= end_idx {
    2858
    0
                        Self::ok_string(s[start_idx..end_idx].to_string())
    2859
                    } else {
    2860
    0
                        Self::ok_string(String::new())
    2861
                    }
    2862
                } else {
    2863
    0
                    bail!("substring arguments must be integers");
    2864
                }
    2865
    0
            } else if args.len() == 1 {
    2866
                // substring(start) - to end of string
    2867
    0
                if let ExprKind::Literal(Literal::Integer(start)) = &args[0].kind {
    2868
    0
                    let start_idx = (*start as usize).min(s.len());
    2869
    0
                    Self::ok_string(s[start_idx..].to_string())
    2870
                } else {
    2871
    0
                    bail!("substring argument must be an integer");
    2872
                }
    2873
            } else {
    2874
    0
                bail!("substring expects 1 or 2 arguments");
    2875
            }
    2876
    0
        }
    2877
    2878
        /// Main string methods dispatcher (complexity: 6)
    2879
    0
        fn evaluate_string_methods(
    2880
    0
            s: &str,
    2881
    0
            method: &str,
    2882
    0
            args: &[Expr],
    2883
    0
            _deadline: Instant,
    2884
    0
            _depth: usize,
    2885
    0
        ) -> Result<Value> {
    2886
            // Try simple transforms first - these methods take no arguments
    2887
    0
            if let Some(result) = Self::handle_string_transforms(s, method) {
    2888
                // Check that no arguments were provided for no-arg methods
    2889
    0
                if !args.is_empty() {
    2890
    0
                    bail!("{} requires no arguments", method);
    2891
    0
                }
    2892
    0
                return result;
    2893
    0
            }
    2894
    2895
            // Try search methods
    2896
    0
            if let Some(result) = Self::handle_string_search(s, method, args) {
    2897
    0
                return result;
    2898
    0
            }
    2899
    2900
            // Try manipulation methods
    2901
    0
            if let Some(result) = Self::handle_string_manipulation(s, method, args) {
    2902
    0
                return result;
    2903
    0
            }
    2904
    2905
            // Handle substring specially
    2906
    0
            if method == "substring" || method == "substr" {
    2907
    0
                return Self::handle_substring(s, args);
    2908
    0
            }
    2909
    2910
    0
            bail!("Unknown string method: {}", method)
    2911
    0
        }
    2912
    2913
        /// Handle method calls on char values (complexity < 10)
    2914
    0
        fn evaluate_char_methods(c: char, method: &str) -> Result<Value> {
    2915
    0
            match method {
    2916
    0
                "to_int" => Self::ok_int(c as i64),
    2917
    0
                "to_string" => Self::ok_string(c.to_string()),
    2918
    0
                "is_alphabetic" => Self::ok_bool(c.is_alphabetic()),
    2919
    0
                "is_numeric" => Self::ok_bool(c.is_numeric()),
    2920
    0
                "is_alphanumeric" => Self::ok_bool(c.is_alphanumeric()),
    2921
    0
                "is_whitespace" => Self::ok_bool(c.is_whitespace()),
    2922
    0
                "to_uppercase" => Self::ok_string(c.to_uppercase().to_string()),
    2923
    0
                "to_lowercase" => Self::ok_string(c.to_lowercase().to_string()),
    2924
    0
                _ => bail!("Unknown char method: {}", method),
    2925
            }
    2926
    0
        }
    2927
    2928
        /// Handle method calls on numeric values (complexity < 10)
    2929
    0
        fn evaluate_numeric_methods(&self, value: &Value, method: &str) -> Result<Value> {
    2930
    0
            match (value, method) {
    2931
                // Integer-specific methods
    2932
    0
                (Value::Int(n), "abs") => Self::ok_int(n.abs()),
    2933
    0
                (Value::Int(n), "to_string") => Self::ok_string(n.to_string()),
    2934
    2935
                // Float-specific methods
    2936
    0
                (Value::Float(f), "abs") => Self::ok_float(f.abs()),
    2937
    0
                (Value::Float(f), "floor") => Self::ok_float(f.floor()),
    2938
    0
                (Value::Float(f), "ceil") => Self::ok_float(f.ceil()),
    2939
    0
                (Value::Float(f), "round") => Self::ok_float(f.round()),
    2940
    2941
                // Math operations that work on both (convert int to float)
    2942
    0
                (Value::Int(n), op @ ("sqrt" | "sin" | "cos" | "tan" | "log" | "log10" | "exp")) => {
    2943
                    #[allow(clippy::cast_precision_loss)]
    2944
    0
                    let f = *n as f64;
    2945
    0
                    self.evaluate_float_math(f, op)
    2946
                }
    2947
    0
                (Value::Float(f), op @ ("sqrt" | "sin" | "cos" | "tan" | "log" | "log10" | "exp")) => {
    2948
    0
                    self.evaluate_float_math(*f, op)
    2949
                }
    2950
    2951
    0
                (Value::Int(_), _) => self.unknown_method_error("integer", method),
    2952
    0
                (Value::Float(_), _) => self.unknown_method_error("float", method),
    2953
    0
                _ => Err(Self::method_not_supported(method, &format!("{value:?}")))?,
    2954
            }
    2955
    0
        }
    2956
    2957
        /// Helper for float math operations (complexity: 8)
    2958
    0
        fn evaluate_float_math(&self, f: f64, op: &str) -> Result<Value> {
    2959
    0
            let result = match op {
    2960
    0
                "sqrt" => f.sqrt(),
    2961
    0
                "sin" => f.sin(),
    2962
    0
                "cos" => f.cos(),
    2963
    0
                "tan" => f.tan(),
    2964
    0
                "log" => f.ln(),
    2965
    0
                "log10" => f.log10(),
    2966
    0
                "exp" => f.exp(),
    2967
    0
                _ => bail!("Unknown math operation: {}", op),
    2968
            };
    2969
    0
            Self::ok_float(result)
    2970
    0
        }
    2971
    2972
        /// Handle method calls on object values (complexity < 10)
    2973
    0
        fn evaluate_object_methods(
    2974
    0
            obj: HashMap<String, Value>,
    2975
    0
            method: &str,
    2976
    0
            _args: &[Expr],
    2977
    0
            _deadline: Instant,
    2978
    0
            _depth: usize,
    2979
    0
        ) -> Result<Value> {
    2980
    0
            match method {
    2981
    0
                "items" => {
    2982
                    // Return list of (key, value) tuples
    2983
    0
                    let mut items = Vec::new();
    2984
    0
                    for (key, value) in obj {
    2985
    0
                        let tuple = Value::Tuple(vec![Value::String(key), value]);
    2986
    0
                        items.push(tuple);
    2987
    0
                    }
    2988
    0
                    Self::ok_list(items)
    2989
                }
    2990
    0
                "keys" => {
    2991
                    // Return list of keys
    2992
    0
                    let keys: Vec<Value> = obj.keys().map(|k| Value::String(k.clone())).collect();
    2993
    0
                    Self::ok_list(keys)
    2994
                }
    2995
    0
                "values" => {
    2996
                    // Return list of values
    2997
    0
                    let values: Vec<Value> = obj.values().cloned().collect();
    2998
    0
                    Self::ok_list(values)
    2999
                }
    3000
    0
                "len" => {
    3001
                    // Return length of object
    3002
    0
                    Self::ok_int(obj.len() as i64)
    3003
                }
    3004
    0
                "has_key" => {
    3005
                    // This would need args handling - simplified for now
    3006
    0
                    bail!("has_key method requires arguments")
    3007
                }
    3008
    0
                _ => bail!("Unknown object method: {}", method),
    3009
            }
    3010
    0
        }
    3011
    3012
        /// Handle method calls on `HashMap` values (complexity < 10)
    3013
    0
        fn evaluate_hashmap_methods(
    3014
    0
            &mut self,
    3015
    0
            mut map: HashMap<Value, Value>,
    3016
    0
            method: &str,
    3017
    0
            args: &[Expr],
    3018
    0
            deadline: Instant,
    3019
    0
            depth: usize,
    3020
    0
        ) -> Result<Value> {
    3021
    0
            match method {
    3022
    0
                "insert" => {
    3023
    0
                    if args.len() != 2 {
    3024
    0
                        bail!("insert requires exactly 2 arguments (key, value)");
    3025
    0
                    }
    3026
    0
                    let key = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    3027
    0
                    let value = self.evaluate_arg(args, 1, deadline, depth)?;
    3028
    0
                    map.insert(key, value);
    3029
    0
                    Self::ok_hashmap(map)
    3030
                }
    3031
    0
                "get" => {
    3032
    0
                    if args.len() != 1 {
    3033
    0
                        bail!("get requires exactly 1 argument (key)");
    3034
    0
                    }
    3035
    0
                    let key = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    3036
    0
                    match map.get(&key) {
    3037
    0
                        Some(value) => Ok(value.clone()),
    3038
    0
                        None => Self::ok_unit(), // Could return Option::None in future
    3039
                    }
    3040
                }
    3041
    0
                "contains_key" => {
    3042
    0
                    if args.len() != 1 {
    3043
    0
                        bail!("contains_key requires exactly 1 argument (key)");
    3044
    0
                    }
    3045
    0
                    let key = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    3046
    0
                    Self::ok_bool(map.contains_key(&key))
    3047
                }
    3048
    0
                "remove" => {
    3049
    0
                    if args.len() != 1 {
    3050
    0
                        bail!("remove requires exactly 1 argument (key)");
    3051
    0
                    }
    3052
    0
                    let key = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    3053
    0
                    let removed_value = map.remove(&key);
    3054
    0
                    match removed_value {
    3055
    0
                        Some(value) => Self::ok_tuple(vec![Value::HashMap(map), value]),
    3056
    0
                        None => Self::ok_tuple(vec![Value::HashMap(map), Value::Unit]),
    3057
                    }
    3058
                }
    3059
    0
                "len" => Self::ok_int(map.len() as i64),
    3060
    0
                "is_empty" => Self::ok_bool(map.is_empty()),
    3061
    0
                "clear" => {
    3062
    0
                    map.clear();
    3063
    0
                    Self::ok_hashmap(map)
    3064
                }
    3065
    0
                _ => bail!("Unknown HashMap method: {}", method),
    3066
            }
    3067
    0
        }
    3068
    3069
        /// Handle basic `HashSet` methods (complexity: 6)
    3070
    0
        fn handle_basic_hashset_methods(
    3071
    0
            &mut self,
    3072
    0
            mut set: HashSet<Value>,
    3073
    0
            method: &str,
    3074
    0
            args: &[Expr],
    3075
    0
            deadline: Instant,
    3076
    0
            depth: usize,
    3077
    0
        ) -> Option<Result<Value>> {
    3078
    0
            match method {
    3079
    0
                "insert" => {
    3080
    0
                    if args.len() != 1 {
    3081
    0
                        return Some(Err(anyhow::anyhow!("insert requires exactly 1 argument (value)")));
    3082
    0
                    }
    3083
    0
                    let value = match self.evaluate_expr(&args[0], deadline, depth + 1) {
    3084
    0
                        Ok(v) => v,
    3085
    0
                        Err(e) => return Some(Err(e)),
    3086
                    };
    3087
    0
                    let was_new = set.insert(value);
    3088
    0
                    Some(Self::ok_tuple(vec![Value::HashSet(set), Self::bool_value(was_new)]))
    3089
                }
    3090
    0
                "contains" => {
    3091
    0
                    if args.len() != 1 {
    3092
    0
                        return Some(Err(anyhow::anyhow!("contains requires exactly 1 argument (value)")));
    3093
    0
                    }
    3094
    0
                    let value = match self.evaluate_expr(&args[0], deadline, depth + 1) {
    3095
    0
                        Ok(v) => v,
    3096
    0
                        Err(e) => return Some(Err(e)),
    3097
                    };
    3098
    0
                    Some(Self::ok_bool(set.contains(&value)))
    3099
                }
    3100
    0
                "remove" => {
    3101
    0
                    if args.len() != 1 {
    3102
    0
                        return Some(Err(anyhow::anyhow!("remove requires exactly 1 argument (value)")));
    3103
    0
                    }
    3104
    0
                    let value = match self.evaluate_expr(&args[0], deadline, depth + 1) {
    3105
    0
                        Ok(v) => v,
    3106
    0
                        Err(e) => return Some(Err(e)),
    3107
                    };
    3108
    0
                    let was_present = set.remove(&value);
    3109
    0
                    Some(Self::ok_tuple(vec![Value::HashSet(set), Self::bool_value(was_present)]))
    3110
                }
    3111
    0
                "len" => Some(Self::ok_int(set.len() as i64)),
    3112
    0
                "is_empty" => Some(Self::ok_bool(set.is_empty())),
    3113
    0
                "clear" => {
    3114
    0
                    set.clear();
    3115
    0
                    Some(Self::ok_hashset(set))
    3116
                }
    3117
    0
                _ => None,
    3118
            }
    3119
    0
        }
    3120
    3121
        /// Handle set operation methods (complexity: 8)
    3122
    0
        fn handle_set_operation_methods(
    3123
    0
            &mut self,
    3124
    0
            set: HashSet<Value>,
    3125
    0
            method: &str,
    3126
    0
            args: &[Expr],
    3127
    0
            deadline: Instant,
    3128
    0
            depth: usize,
    3129
    0
        ) -> Option<Result<Value>> {
    3130
    0
            if args.len() != 1 {
    3131
    0
                return Some(Err(anyhow::anyhow!("{} requires exactly 1 argument (other set)", method)));
    3132
    0
            }
    3133
    3134
    0
            let other_val = match self.evaluate_expr(&args[0], deadline, depth + 1) {
    3135
    0
                Ok(v) => v,
    3136
    0
                Err(e) => return Some(Err(e)),
    3137
            };
    3138
    3139
    0
            if let Value::HashSet(other_set) = other_val {
    3140
    0
                match method {
    3141
    0
                    "union" => {
    3142
    0
                        let union_set = set.union(&other_set).cloned().collect();
    3143
    0
                        Some(Self::ok_hashset(union_set))
    3144
                    }
    3145
    0
                    "intersection" => {
    3146
    0
                        let intersection_set = set.intersection(&other_set).cloned().collect();
    3147
    0
                        Some(Self::ok_hashset(intersection_set))
    3148
                    }
    3149
    0
                    "difference" => {
    3150
    0
                        let difference_set = set.difference(&other_set).cloned().collect();
    3151
    0
                        Some(Self::ok_hashset(difference_set))
    3152
                    }
    3153
    0
                    _ => None,
    3154
                }
    3155
            } else {
    3156
    0
                Some(Err(anyhow::anyhow!("{} argument must be a HashSet", method)))
    3157
            }
    3158
    0
        }
    3159
    3160
        /// Handle method calls on `HashSet` values (complexity: 5)
    3161
    0
        fn evaluate_hashset_methods(
    3162
    0
            &mut self,
    3163
    0
            set: HashSet<Value>,
    3164
    0
            method: &str,
    3165
    0
            args: &[Expr],
    3166
    0
            deadline: Instant,
    3167
    0
            depth: usize,
    3168
    0
        ) -> Result<Value> {
    3169
            // Try basic methods first
    3170
    0
            if let Some(result) = self.handle_basic_hashset_methods(set.clone(), method, args, deadline, depth) {
    3171
    0
                return result;
    3172
    0
            }
    3173
    3174
            // Try set operation methods
    3175
    0
            if let Some(result) = self.handle_set_operation_methods(set, method, args, deadline, depth) {
    3176
    0
                return result;
    3177
    0
            }
    3178
    3179
            // Unknown method
    3180
    0
            bail!("Unknown HashSet method: {}", method)
    3181
    0
        }
    3182
    3183
        // ========================================================================
    3184
        // Additional helper methods to further reduce evaluate_expr complexity
    3185
        // Phase 2: Control flow extraction (Target: < 50 total complexity)
    3186
        // ========================================================================
    3187
    3188
        /// Evaluate for loop (complexity: 10)
    3189
    0
        fn evaluate_for_loop(
    3190
    0
            &mut self,
    3191
    0
            var: &str,
    3192
    0
            pattern: Option<&Pattern>,
    3193
    0
            iter: &Expr,
    3194
    0
            body: &Expr,
    3195
    0
            deadline: Instant,
    3196
    0
            depth: usize,
    3197
    0
        ) -> Result<Value> {
    3198
            // Evaluate the iterable
    3199
    0
            let iterable = self.evaluate_expr(iter, deadline, depth + 1)?;
    3200
    3201
            // Save the previous value of the loop variable (if any)
    3202
    0
            let saved_loop_var = self.bindings.get(var).cloned();
    3203
    3204
            // If we have a pattern, save all variables it will bind
    3205
    0
            let saved_pattern_vars = if let Some(pat) = pattern {
    3206
    0
                self.save_pattern_variables(pat)
    3207
            } else {
    3208
    0
                HashMap::new()
    3209
            };
    3210
    3211
            // Execute the loop based on iterable type
    3212
    0
            let result = match iterable {
    3213
    0
                Value::List(items) => {
    3214
    0
                    if let Some(pat) = pattern {
    3215
    0
                        self.iterate_list_with_pattern(pat, items, body, deadline, depth)
    3216
                    } else {
    3217
    0
                        self.iterate_list(var, items, body, deadline, depth)
    3218
                    }
    3219
                },
    3220
                Value::Range {
    3221
    0
                    start,
    3222
    0
                    end,
    3223
    0
                    inclusive,
    3224
    0
                } => self.iterate_range(var, start, end, inclusive, body, deadline, depth),
    3225
    0
                Value::String(s) => self.iterate_string(var, &s, body, deadline, depth),
    3226
    0
                _ => bail!(
    3227
    0
                    "For loops only support lists, ranges, and strings, got: {:?}",
    3228
                    iterable
    3229
                ),
    3230
            };
    3231
    3232
            // Restore the loop variable
    3233
    0
            if let Some(prev_value) = saved_loop_var {
    3234
    0
                self.bindings.insert(var.to_string(), prev_value);
    3235
    0
            } else {
    3236
    0
                self.bindings.remove(var);
    3237
    0
            }
    3238
    3239
            // Restore pattern variables
    3240
    0
            for (name, value) in saved_pattern_vars {
    3241
    0
                if let Some(val) = value {
    3242
    0
                    self.bindings.insert(name, val);
    3243
    0
                } else {
    3244
    0
                    self.bindings.remove(&name);
    3245
    0
                }
    3246
            }
    3247
    3248
    0
            result
    3249
    0
        }
    3250
    3251
        /// Helper: Iterate over a list (complexity: 4)
    3252
    0
        fn iterate_list(
    3253
    0
            &mut self,
    3254
    0
            var: &str,
    3255
    0
            items: Vec<Value>,
    3256
    0
            body: &Expr,
    3257
    0
            deadline: Instant,
    3258
    0
            depth: usize,
    3259
    0
        ) -> Result<Value> {
    3260
    0
            let mut result = Value::Unit;
    3261
    0
            for item in items {
    3262
    0
                self.bindings.insert(var.to_string(), item);
    3263
    0
                match self.evaluate_expr(body, deadline, depth + 1) {
    3264
    0
                    Ok(value) => result = value,
    3265
    0
                    Err(e) if e.to_string() == "break" => break,
    3266
    0
                    Err(e) if e.to_string() == "continue" => {},
    3267
    0
                    Err(e) => return Err(e),
    3268
                }
    3269
            }
    3270
    0
            Ok(result)
    3271
    0
        }
    3272
    3273
        /// Helper: Iterate over a range (complexity: 5)
    3274
        #[allow(clippy::too_many_arguments)]
    3275
    0
        fn iterate_range(
    3276
    0
            &mut self,
    3277
    0
            var: &str,
    3278
    0
            start: i64,
    3279
    0
            end: i64,
    3280
    0
            inclusive: bool,
    3281
    0
            body: &Expr,
    3282
    0
            deadline: Instant,
    3283
    0
            depth: usize,
    3284
    0
        ) -> Result<Value> {
    3285
    0
            let mut result = Value::Unit;
    3286
    0
            let actual_end = if inclusive { end + 1 } else { end };
    3287
    0
            for i in start..actual_end {
    3288
    0
                self.bindings.insert(var.to_string(), Value::Int(i));
    3289
    0
                match self.evaluate_expr(body, deadline, depth + 1) {
    3290
    0
                    Ok(value) => result = value,
    3291
    0
                    Err(e) if e.to_string() == "break" => break,
    3292
    0
                    Err(e) if e.to_string() == "continue" => {},
    3293
    0
                    Err(e) => return Err(e),
    3294
                }
    3295
            }
    3296
    0
            Ok(result)
    3297
    0
        }
    3298
    3299
        /// Helper: Iterate over a string (as characters)
    3300
    0
        fn iterate_string(
    3301
    0
            &mut self,
    3302
    0
            var: &str,
    3303
    0
            s: &str,
    3304
    0
            body: &Expr,
    3305
    0
            deadline: Instant,
    3306
    0
            depth: usize,
    3307
    0
        ) -> Result<Value> {
    3308
    0
            let mut result = Value::Unit;
    3309
    0
            for ch in s.chars() {
    3310
    0
                self.bindings.insert(var.to_string(), Value::String(ch.to_string()));
    3311
    0
                match self.evaluate_expr(body, deadline, depth + 1) {
    3312
    0
                    Ok(value) => result = value,
    3313
    0
                    Err(e) if e.to_string() == "break" => break,
    3314
    0
                    Err(e) if e.to_string() == "continue" => {},
    3315
    0
                    Err(e) => return Err(e),
    3316
                }
    3317
            }
    3318
    0
            Ok(result)
    3319
    0
        }
    3320
    3321
        /// Helper: Save pattern variables for restoration
    3322
    0
        fn save_pattern_variables(&self, pattern: &Pattern) -> HashMap<String, Option<Value>> {
    3323
    0
            let mut saved = HashMap::new();
    3324
    0
            self.collect_pattern_vars(pattern, &mut saved);
    3325
    0
            saved
    3326
    0
        }
    3327
    3328
        /// Helper: Collect all variables from a pattern
    3329
    0
        fn collect_pattern_vars(&self, pattern: &Pattern, saved: &mut HashMap<String, Option<Value>>) {
    3330
    0
            match pattern {
    3331
    0
                Pattern::Identifier(name) => {
    3332
    0
                    saved.insert(name.clone(), self.bindings.get(name).cloned());
    3333
    0
                }
    3334
    0
                Pattern::Tuple(patterns) => {
    3335
    0
                    for p in patterns {
    3336
    0
                        self.collect_pattern_vars(p, saved);
    3337
    0
                    }
    3338
                }
    3339
    0
                _ => {} // Other patterns don't bind variables
    3340
            }
    3341
    0
        }
    3342
    3343
        /// Helper: Iterate over a list with pattern destructuring
    3344
    0
        fn iterate_list_with_pattern(
    3345
    0
            &mut self,
    3346
    0
            pattern: &Pattern,
    3347
    0
            items: Vec<Value>,
    3348
    0
            body: &Expr,
    3349
    0
            deadline: Instant,
    3350
    0
            depth: usize,
    3351
    0
        ) -> Result<Value> {
    3352
    0
            let mut result = Value::Unit;
    3353
    0
            for item in items {
    3354
                // Bind the pattern variables
    3355
    0
                self.bind_pattern(pattern, &item)?;
    3356
    3357
    0
                match self.evaluate_expr(body, deadline, depth + 1) {
    3358
    0
                    Ok(value) => result = value,
    3359
    0
                    Err(e) if e.to_string() == "break" => break,
    3360
    0
                    Err(e) if e.to_string() == "continue" => {},
    3361
    0
                    Err(e) => return Err(e),
    3362
                }
    3363
            }
    3364
    0
            Ok(result)
    3365
    0
        }
    3366
    3367
        /// Helper: Bind pattern variables from a value
    3368
    0
        fn bind_pattern(&mut self, pattern: &Pattern, value: &Value) -> Result<()> {
    3369
    0
            match (pattern, value) {
    3370
    0
                (Pattern::Identifier(name), val) => {
    3371
    0
                    self.bindings.insert(name.clone(), val.clone());
    3372
    0
                    Ok(())
    3373
                }
    3374
    0
                (Pattern::Tuple(patterns), Value::Tuple(values)) => {
    3375
    0
                    if patterns.len() != values.len() {
    3376
    0
                        bail!("Pattern tuple has {} elements but value has {}", patterns.len(), values.len());
    3377
    0
                    }
    3378
    0
                    for (p, v) in patterns.iter().zip(values.iter()) {
    3379
    0
                        self.bind_pattern(p, v)?;
    3380
                    }
    3381
    0
                    Ok(())
    3382
                }
    3383
    0
                _ => bail!("Pattern does not match value")
    3384
            }
    3385
    0
        }
    3386
    3387
        /// Evaluate while loop (complexity: 7)
    3388
        ///
    3389
        /// While loops always return Unit, regardless of body expression.
    3390
        ///
    3391
        /// # Example
    3392
        /// ```
    3393
        /// use ruchy::runtime::Repl;
    3394
        /// let mut repl = Repl::new().unwrap();
    3395
        ///
    3396
        /// // While loops return Unit, not the last body value
    3397
        /// let result = repl.eval("let i = 0; while i < 3 { i = i + 1 }; i").unwrap();
    3398
        /// assert_eq!(result.to_string(), "3"); // i is 3 after loop
    3399
        ///
    3400
        /// // While loop doesn't return body value
    3401
        /// let result = repl.eval("let i = 0; while i < 1 { i = i + 1; 42 }").unwrap();
    3402
        /// assert_eq!(result.to_string(), "()"); // Returns Unit, not 42
    3403
        /// ```
    3404
    0
        fn evaluate_while_loop(
    3405
    0
            &mut self,
    3406
    0
            condition: &Expr,
    3407
    0
            body: &Expr,
    3408
    0
            deadline: Instant,
    3409
    0
            depth: usize,
    3410
    0
        ) -> Result<Value> {
    3411
    0
            let max_iterations = 1000; // Prevent infinite loops in REPL
    3412
    0
            let mut iterations = 0;
    3413
    3414
            loop {
    3415
    0
                if iterations >= max_iterations {
    3416
    0
                    bail!(
    3417
    0
                        "While loop exceeded maximum iterations ({})",
    3418
                        max_iterations
    3419
                    );
    3420
    0
                }
    3421
    3422
                // Evaluate condition
    3423
    0
                let cond_val = self.evaluate_expr(condition, deadline, depth + 1)?;
    3424
    0
                match cond_val {
    3425
                    Value::Bool(true) => {
    3426
                        // Execute body but don't save result - while loops return Unit
    3427
    0
                        self.evaluate_expr(body, deadline, depth + 1)?;
    3428
    0
                        iterations += 1;
    3429
                    }
    3430
    0
                    Value::Bool(false) => break,
    3431
    0
                    _ => bail!("While condition must be boolean, got: {:?}", cond_val),
    3432
                }
    3433
            }
    3434
            // While loops always return Unit
    3435
    0
            Self::ok_unit()
    3436
    0
        }
    3437
    3438
        /// Evaluate loop expression (complexity: 6)
    3439
    0
        fn evaluate_loop(&mut self, body: &Expr, deadline: Instant, depth: usize) -> Result<Value> {
    3440
    0
            let mut result = Value::Unit;
    3441
    0
            let max_iterations = 1000; // Prevent infinite loops in REPL
    3442
    0
            let mut iterations = 0;
    3443
    3444
            loop {
    3445
    0
                if iterations >= max_iterations {
    3446
    0
                    bail!("Loop exceeded maximum iterations ({})", max_iterations);
    3447
    0
                }
    3448
    3449
                // Evaluate body, catching break
    3450
    0
                match self.evaluate_expr(body, deadline, depth + 1) {
    3451
    0
                    Ok(val) => {
    3452
    0
                        result = val;
    3453
    0
                        iterations += 1;
    3454
    0
                    }
    3455
    0
                    Err(e) if e.to_string() == "break" => {
    3456
    0
                        break;
    3457
                    }
    3458
    0
                    Err(e) if e.to_string() == "continue" => {
    3459
    0
                        iterations += 1;
    3460
    0
                    }
    3461
    0
                    Err(e) => return Err(e),
    3462
                }
    3463
            }
    3464
    3465
    0
            Ok(result)
    3466
    0
        }
    3467
    3468
        /// Evaluate block expression (complexity: 4)
    3469
    0
        fn evaluate_block(&mut self, exprs: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    3470
    0
            if exprs.is_empty() {
    3471
    0
                return Self::ok_unit();
    3472
    0
            }
    3473
    3474
    0
            let mut result = Value::Unit;
    3475
    0
            for expr in exprs {
    3476
    0
                result = self.evaluate_expr(expr, deadline, depth + 1)?;
    3477
            }
    3478
    0
            Ok(result)
    3479
    0
        }
    3480
    3481
        /// Evaluate list literal (complexity: 4)
    3482
    0
        fn evaluate_list_literal(
    3483
    0
            &mut self,
    3484
    0
            elements: &[Expr],
    3485
    0
            deadline: Instant,
    3486
    0
            depth: usize,
    3487
    0
        ) -> Result<Value> {
    3488
    0
            let mut results = Vec::new();
    3489
    0
            for elem in elements {
    3490
    0
                if let ExprKind::Spread { expr } = &elem.kind {
    3491
                    // Evaluate the spread expression and expand it into the array
    3492
    0
                    let val = self.evaluate_expr(expr, deadline, depth + 1)?;
    3493
    0
                    match val {
    3494
    0
                        Value::List(items) => {
    3495
    0
                            // Spread the items into the result
    3496
    0
                            results.extend(items);
    3497
    0
                        }
    3498
    0
                        Value::Tuple(items) => {
    3499
    0
                            // Also allow spreading tuples
    3500
    0
                            results.extend(items);
    3501
    0
                        }
    3502
    0
                        Value::Range { start, end, inclusive } => {
    3503
                            // Spread range values into individual integers
    3504
    0
                            let range_values = self.expand_range_to_values(start, end, inclusive)?;
    3505
    0
                            results.extend(range_values);
    3506
                        }
    3507
                        _ => {
    3508
    0
                            bail!("Cannot spread non-iterable value: {}", self.get_value_type_name(&val));
    3509
                        }
    3510
                    }
    3511
                } else {
    3512
                    // Regular element
    3513
    0
                    let val = self.evaluate_expr(elem, deadline, depth + 1)?;
    3514
    0
                    results.push(val);
    3515
                }
    3516
            }
    3517
    0
            Ok(Value::List(results))
    3518
    0
        }
    3519
    3520
        /// Expand a range into individual `Value::Int` items for spreading
    3521
    0
        fn expand_range_to_values(&self, start: i64, end: i64, inclusive: bool) -> Result<Vec<Value>> {
    3522
    0
            let actual_end = if inclusive { end } else { end - 1 };
    3523
    3524
    0
            if start > actual_end {
    3525
    0
                return Ok(Vec::new()); // Empty range
    3526
    0
            }
    3527
    3528
            // Prevent excessive memory allocation for very large ranges
    3529
    0
            let range_size = (actual_end - start + 1) as usize;
    3530
    0
            if range_size > 10000 {
    3531
    0
                bail!("Range too large to expand: {} elements (limit: 10000)", range_size);
    3532
    0
            }
    3533
    3534
    0
            let mut values = Vec::with_capacity(range_size);
    3535
    0
            for i in start..=actual_end {
    3536
    0
                values.push(Value::Int(i));
    3537
    0
            }
    3538
    3539
    0
            Ok(values)
    3540
    0
        }
    3541
    3542
        /// Evaluate tuple literal (complexity: 4)
    3543
    0
        fn evaluate_tuple_literal(
    3544
    0
            &mut self,
    3545
    0
            elements: &[Expr],
    3546
    0
            deadline: Instant,
    3547
    0
            depth: usize,
    3548
    0
        ) -> Result<Value> {
    3549
    0
            let mut results = Vec::new();
    3550
    0
            for elem in elements {
    3551
    0
                let val = self.evaluate_expr(elem, deadline, depth + 1)?;
    3552
    0
                results.push(val);
    3553
            }
    3554
    0
            Self::ok_tuple(results)
    3555
    0
        }
    3556
    3557
        /// Evaluate range literal (complexity: 5)
    3558
    0
        fn evaluate_range_literal(
    3559
    0
            &mut self,
    3560
    0
            start: &Expr,
    3561
    0
            end: &Expr,
    3562
    0
            inclusive: bool,
    3563
    0
            deadline: Instant,
    3564
    0
            depth: usize,
    3565
    0
        ) -> Result<Value> {
    3566
    0
            let start_val = self.evaluate_expr(start, deadline, depth + 1)?;
    3567
    0
            let end_val = self.evaluate_expr(end, deadline, depth + 1)?;
    3568
    3569
    0
            match (start_val, end_val) {
    3570
    0
                (Value::Int(s), Value::Int(e)) => Self::ok_range(s, e, inclusive),
    3571
    0
                _ => bail!("Range endpoints must be integers"),
    3572
            }
    3573
    0
        }
    3574
    3575
        /// Evaluate assignment expression (complexity: 5)
    3576
    0
        fn evaluate_assignment(
    3577
    0
            &mut self,
    3578
    0
            target: &Expr,
    3579
    0
            value: &Expr,
    3580
    0
            deadline: Instant,
    3581
    0
            depth: usize,
    3582
    0
        ) -> Result<Value> {
    3583
    0
            let val = self.evaluate_expr(value, deadline, depth + 1)?;
    3584
    3585
            // For now, only support simple variable assignment
    3586
    0
            if let ExprKind::Identifier(name) = &target.kind {
    3587
                // Use update_binding which checks mutability
    3588
    0
                self.update_binding(name, val.clone())?;
    3589
    0
                Ok(val)
    3590
            } else {
    3591
    0
                bail!(
    3592
    0
                    "Only simple variable assignment is supported, got: {:?}",
    3593
                    target.kind
    3594
                );
    3595
            }
    3596
    0
        }
    3597
    3598
        /// Evaluate let binding (complexity: 5)
    3599
    0
        fn evaluate_let_binding(
    3600
    0
            &mut self,
    3601
    0
            name: &str,
    3602
    0
            value: &Expr,
    3603
    0
            body: &Expr,
    3604
    0
            is_mutable: bool,
    3605
    0
            deadline: Instant,
    3606
    0
            depth: usize,
    3607
    0
        ) -> Result<Value> {
    3608
    0
            let val = self.evaluate_expr(value, deadline, depth + 1)?;
    3609
    0
            self.create_binding(name.to_string(), val.clone(), is_mutable);
    3610
    3611
            // If there's a body, evaluate it; otherwise return the value
    3612
    0
            match &body.kind {
    3613
    0
                ExprKind::Literal(Literal::Unit) => Ok(val),
    3614
    0
                _ => self.evaluate_expr(body, deadline, depth + 1),
    3615
            }
    3616
    0
        }
    3617
    3618
        /// Evaluate let pattern binding (destructuring assignment)
    3619
    0
        fn evaluate_let_pattern(
    3620
    0
            &mut self,
    3621
    0
            pattern: &crate::frontend::ast::Pattern,
    3622
    0
            value: &Expr,
    3623
    0
            body: &Expr,
    3624
    0
            is_mutable: bool,
    3625
    0
            deadline: Instant,
    3626
    0
            depth: usize,
    3627
    0
        ) -> Result<Value> {
    3628
    0
            let val = self.evaluate_expr(value, deadline, depth + 1)?;
    3629
    3630
            // Use existing pattern matching logic
    3631
    0
            if let Some(bindings) = Self::pattern_matches(&val, pattern)? {
    3632
    0
                let _saved_bindings = self.bindings.clone();
    3633
    3634
                // Apply all pattern bindings
    3635
    0
                for (name, binding_val) in bindings {
    3636
    0
                    self.create_binding(name, binding_val, is_mutable);
    3637
    0
                }
    3638
    3639
                // Evaluate the body expression
    3640
    3641
    3642
                // Pattern matching succeeded, keep the new bindings
    3643
    0
                match &body.kind {
    3644
    0
                    ExprKind::Literal(Literal::Unit) => Ok(val),
    3645
    0
                    _ => self.evaluate_expr(body, deadline, depth + 1),
    3646
                }
    3647
            } else {
    3648
    0
                bail!("Pattern does not match value in let binding");
    3649
            }
    3650
    0
        }
    3651
    3652
        /// Evaluate string interpolation (complexity: 7)
    3653
    0
        fn evaluate_string_interpolation(
    3654
    0
            &mut self,
    3655
    0
            parts: &[crate::frontend::ast::StringPart],
    3656
    0
            deadline: Instant,
    3657
    0
            depth: usize,
    3658
    0
        ) -> Result<Value> {
    3659
            use crate::frontend::ast::StringPart;
    3660
    3661
    0
            let mut result = String::new();
    3662
    0
            for part in parts {
    3663
    0
                match part {
    3664
    0
                    StringPart::Text(text) => result.push_str(text),
    3665
    0
                    StringPart::Expr(expr) => {
    3666
    0
                        let value = self.evaluate_expr(expr, deadline, depth + 1)?;
    3667
                        // Format the value for interpolation (without quotes for strings)
    3668
    0
                        match value {
    3669
    0
                            Value::String(s) => result.push_str(&s),
    3670
    0
                            Value::Char(c) => result.push(c),
    3671
    0
                            other => result.push_str(&other.to_string()),
    3672
                        }
    3673
                    }
    3674
    0
                    StringPart::ExprWithFormat { expr, format_spec } => {
    3675
    0
                        let value = self.evaluate_expr(expr, deadline, depth + 1)?;
    3676
                        // Apply format specifier for REPL
    3677
    0
                        let formatted = Self::format_value_with_spec(&value, format_spec);
    3678
    0
                        result.push_str(&formatted);
    3679
                    }
    3680
                }
    3681
            }
    3682
    0
            Self::ok_string(result)
    3683
    0
        }
    3684
    3685
        /// Format a value with a format specifier like :.2 for floats
    3686
    0
        fn format_value_with_spec(value: &Value, spec: &str) -> String {
    3687
            // Parse format specifier (e.g., ":.2" -> precision 2)
    3688
    0
            if let Some(stripped) = spec.strip_prefix(":.") {
    3689
    0
                if let Ok(precision) = stripped.parse::<usize>() {
    3690
    0
                    match value {
    3691
    0
                        Value::Float(f) => return format!("{f:.precision$}"),
    3692
    0
                        Value::Int(i) => return format!("{:.precision$}", *i as f64, precision = precision),
    3693
    0
                        _ => {}
    3694
                    }
    3695
    0
                }
    3696
    0
            }
    3697
            // Default formatting if spec doesn't match or isn't supported
    3698
    0
            value.to_string()
    3699
    0
        }
    3700
    3701
        /// Evaluate function definition (complexity: 5)
    3702
    0
        fn evaluate_function_definition(
    3703
    0
            &mut self,
    3704
    0
            name: &str,
    3705
    0
            params: &[crate::frontend::ast::Param],
    3706
    0
            body: &Expr,
    3707
    0
        ) -> Value {
    3708
    0
            let param_names: Vec<String> = params
    3709
    0
                .iter()
    3710
    0
                .map(crate::frontend::ast::Param::name)
    3711
    0
                .collect();
    3712
    0
            let func_value = Value::Function {
    3713
    0
                name: name.to_string(),
    3714
    0
                params: param_names,
    3715
    0
                body: Box::new(body.clone()),
    3716
    0
            };
    3717
    3718
            // Store the function in bindings
    3719
    0
            self.bindings.insert(name.to_string(), func_value.clone());
    3720
    0
            func_value
    3721
    0
        }
    3722
    3723
        /// Evaluate lambda expression (complexity: 3)
    3724
    0
        fn evaluate_lambda_expression(params: &[crate::frontend::ast::Param], body: &Expr) -> Value {
    3725
    0
            let param_names: Vec<String> = params
    3726
    0
                .iter()
    3727
    0
                .map(crate::frontend::ast::Param::name)
    3728
    0
                .collect();
    3729
    0
            Value::Lambda {
    3730
    0
                params: param_names,
    3731
    0
                body: Box::new(body.clone()),
    3732
    0
            }
    3733
    0
        }
    3734
    3735
        /// Evaluate `DataFrame` literal (complexity: 6)
    3736
    0
        fn evaluate_dataframe_literal(
    3737
    0
            &mut self,
    3738
    0
            columns: &[crate::frontend::ast::DataFrameColumn],
    3739
    0
            deadline: Instant,
    3740
    0
            depth: usize,
    3741
    0
        ) -> Result<Value> {
    3742
    0
            let mut df_columns = Vec::new();
    3743
    0
            for col in columns {
    3744
    0
                let mut values = Vec::new();
    3745
    0
                for val_expr in &col.values {
    3746
    0
                    let val = self.evaluate_expr(val_expr, deadline, depth + 1)?;
    3747
    0
                    values.push(val);
    3748
                }
    3749
    0
                df_columns.push(DataFrameColumn {
    3750
    0
                    name: col.name.clone(),
    3751
    0
                    values,
    3752
    0
                });
    3753
            }
    3754
    0
            Self::ok_dataframe(df_columns)
    3755
    0
        }
    3756
    3757
    3758
        /// Evaluate `Result::Ok` constructor (complexity: 3)
    3759
    0
        fn evaluate_result_ok(
    3760
    0
            &mut self,
    3761
    0
            value: &Expr,
    3762
    0
            deadline: Instant,
    3763
    0
            depth: usize,
    3764
    0
        ) -> Result<Value> {
    3765
    0
            let val = self.evaluate_expr(value, deadline, depth + 1)?;
    3766
    0
            Self::ok_enum_variant("Result".to_string(), "Ok".to_string(), Some(vec![val]))
    3767
    0
        }
    3768
    3769
        /// Evaluate `Result::Err` constructor (complexity: 3)
    3770
    0
        fn evaluate_result_err(
    3771
    0
            &mut self,
    3772
    0
            error: &Expr,
    3773
    0
            deadline: Instant,
    3774
    0
            depth: usize,
    3775
    0
        ) -> Result<Value> {
    3776
    0
            let err = self.evaluate_expr(error, deadline, depth + 1)?;
    3777
    0
            Self::ok_enum_variant("Result".to_string(), "Err".to_string(), Some(vec![err]))
    3778
    0
        }
    3779
    3780
        /// Evaluate `Option::Some` constructor (complexity: 3)
    3781
    0
        fn evaluate_option_some(
    3782
    0
            &mut self,
    3783
    0
            value: &Expr,
    3784
    0
            deadline: Instant,
    3785
    0
            depth: usize,
    3786
    0
        ) -> Result<Value> {
    3787
    0
            let val = self.evaluate_expr(value, deadline, depth + 1)?;
    3788
    0
            Self::ok_enum_variant("Option".to_string(), "Some".to_string(), Some(vec![val]))
    3789
    0
        }
    3790
    3791
        /// Evaluate `Option::None` constructor (complexity: 1)
    3792
    0
        fn evaluate_option_none() -> Value {
    3793
    0
            Value::EnumVariant {
    3794
    0
                enum_name: "Option".to_string(),
    3795
    0
                variant_name: "None".to_string(),
    3796
    0
                data: None,
    3797
    0
            }
    3798
    0
        }
    3799
    3800
        /// Evaluate try operator (?) - early return on Err or None
    3801
    0
        fn evaluate_try_operator(
    3802
    0
            &mut self,
    3803
    0
            expr: &Expr,
    3804
    0
            deadline: Instant,
    3805
    0
            depth: usize,
    3806
    0
        ) -> Result<Value> {
    3807
    0
            let val = self.evaluate_expr(expr, deadline, depth + 1)?;
    3808
    3809
            // Check if it's a Result::Err or Option::None and propagate
    3810
    0
            if let Value::EnumVariant { enum_name, variant_name, data } = &val {
    3811
    0
                if enum_name == "Result" && variant_name == "Err" {
    3812
                    // For Result::Err, propagate the error
    3813
    0
                    return Ok(val.clone());
    3814
    0
                } else if enum_name == "Option" && variant_name == "None" {
    3815
                    // For Option::None, propagate None
    3816
    0
                    return Ok(val.clone());
    3817
    0
                } else if enum_name == "Result" && variant_name == "Ok" {
    3818
                    // For Result::Ok, unwrap the value
    3819
    0
                    if let Some(values) = data {
    3820
    0
                        if !values.is_empty() {
    3821
    0
                            return Ok(values[0].clone());
    3822
    0
                        }
    3823
    0
                    }
    3824
    0
                } else if enum_name == "Option" && variant_name == "Some" {
    3825
                    // For Option::Some, unwrap the value
    3826
    0
                    if let Some(values) = data {
    3827
    0
                        if !values.is_empty() {
    3828
    0
                            return Ok(values[0].clone());
    3829
    0
                        }
    3830
    0
                    }
    3831
    0
                }
    3832
    0
            }
    3833
    3834
            // If not a Result or Option, return as-is (this might be an error case)
    3835
    0
            Ok(val)
    3836
    0
        }
    3837
    3838
        /// Evaluate methods on enum variants (Result/Option types)
    3839
        #[allow(clippy::too_many_lines)]
    3840
        /// Evaluate enum methods with complexity <10
    3841
        ///
    3842
        /// Delegates to specialized handlers for each enum type
    3843
        ///
    3844
        /// Example Usage:
    3845
        ///
    3846
        /// Handles methods on Result and Option enums:
    3847
        /// - `Result::unwrap()` - Returns Ok value or panics on Err
    3848
        /// - `Result::unwrap_or(default)` - Returns Ok value or default
    3849
        /// - `Option::unwrap()` - Returns Some value or panics on None
    3850
        /// - `Option::unwrap_or(default)` - Returns Some value or default
    3851
    0
        fn evaluate_enum_methods(
    3852
    0
            &mut self,
    3853
    0
            receiver: Value,
    3854
    0
            method: &str,
    3855
    0
            args: &[Expr],
    3856
    0
            deadline: Instant,
    3857
    0
            depth: usize,
    3858
    0
        ) -> Result<Value> {
    3859
    0
            if let Value::EnumVariant { enum_name, variant_name, data } = receiver {
    3860
    0
                match enum_name.as_str() {
    3861
    0
                    "Result" => self.evaluate_result_methods(&variant_name, method, data.as_ref(), args, deadline, depth),
    3862
    0
                    "Option" => self.evaluate_option_methods(&variant_name, method, data.as_ref(), args, deadline, depth),
    3863
    0
                    "Vec" => self.evaluate_vec_methods(&variant_name, method, data.as_ref(), args, deadline, depth),
    3864
    0
                    _ => Err(Self::method_not_supported(method, &enum_name))?,
    3865
                }
    3866
            } else {
    3867
    0
                bail!("evaluate_enum_methods called on non-enum variant")
    3868
            }
    3869
    0
        }
    3870
    3871
        /// Handle Result enum methods (unwrap, expect, map, `and_then`)
    3872
        ///
    3873
        /// # Example Usage
    3874
        /// Evaluates methods on enum variants like `Some(x).unwrap()` or `Ok(v).is_ok()`.
    3875
        ///
    3876
        /// use `ruchy::runtime::{Repl`, Value};
    3877
        /// use `std::time::{Duration`, Instant};
    3878
        ///
    3879
        /// let mut repl = `Repl::new().unwrap()`;
    3880
        /// let deadline = `Instant::now()` + `Duration::from_secs(1)`;
    3881
        /// let data = Some(vec![`Value::Int(42)`]);
    3882
        ///
    3883
        /// // Test Ok unwrap
    3884
        /// let result = `repl.evaluate_result_methods("Ok`", "unwrap", &data, &[], deadline, `0).unwrap()`;
    3885
        /// `assert_eq!(result`, `Value::Int(42)`);
    3886
        /// ```
    3887
    0
        fn evaluate_result_methods(
    3888
    0
            &mut self,
    3889
    0
            variant_name: &str,
    3890
    0
            method: &str,
    3891
    0
            data: Option<&Vec<Value>>,
    3892
    0
            args: &[Expr],
    3893
    0
            deadline: Instant,
    3894
    0
            depth: usize,
    3895
    0
        ) -> Result<Value> {
    3896
    0
            match (variant_name, method) {
    3897
    0
                ("Ok", "unwrap" | "expect") if args.is_empty() || args.len() == 1 => {
    3898
    0
                    self.extract_value_or_unit(data)
    3899
                }
    3900
    0
                ("Err", "unwrap") if args.is_empty() => {
    3901
    0
                    let error_msg = self.format_error_message("Result::unwrap()", "Err", data);
    3902
    0
                    bail!(error_msg)
    3903
                }
    3904
    0
                ("Err", "expect") if args.len() == 1 => {
    3905
    0
                    let custom_msg = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    3906
    0
                    let msg = self.value_to_string(custom_msg);
    3907
    0
                    bail!(msg)
    3908
                }
    3909
    0
                ("Ok", "map") if args.len() == 1 => {
    3910
    0
                    self.apply_function_to_value("Result", "Ok", data, &args[0], deadline, depth)
    3911
                }
    3912
    0
                ("Err", "map") if args.len() == 1 => {
    3913
                    // Err values are not transformed by map
    3914
    0
                    if let Some(err_val) = data.and_then(|d| d.first()) {
    3915
    0
                        Ok(Self::create_result_err(err_val.clone()))
    3916
                    } else {
    3917
    0
                        Ok(Self::create_result_err(Value::Unit))
    3918
                    }
    3919
                }
    3920
    0
                ("Ok", "and_then") if args.len() == 1 => {
    3921
    0
                    self.apply_function_and_flatten(data, &args[0], deadline, depth)
    3922
                }
    3923
    0
                ("Err", "and_then") if args.len() == 1 => {
    3924
    0
                    Ok(Value::EnumVariant {
    3925
    0
                        enum_name: "Result".to_string(),
    3926
    0
                        variant_name: variant_name.to_string(),
    3927
    0
                        data: data.cloned(),
    3928
    0
                    })
    3929
                }
    3930
                // ok converts Result to Option
    3931
    0
                ("Ok", "ok") if args.is_empty() => {
    3932
                    // Result::Ok(x).ok() -> Option::Some(x)
    3933
    0
                    let value = self.extract_value_or_unit(data)?;
    3934
    0
                    Ok(Self::create_option_some(value))
    3935
                }
    3936
    0
                ("Err", "ok") if args.is_empty() => {
    3937
                    // Result::Err(e).ok() -> Option::None
    3938
    0
                    Ok(Self::create_option_none())
    3939
                }
    3940
    0
                _ => Err(Self::method_not_supported(method, &format!("Result::{variant_name}")))?,
    3941
            }
    3942
    0
        }
    3943
    3944
        /// Handle Option enum methods (unwrap, expect, map, `and_then`)
    3945
    0
        fn evaluate_option_methods(
    3946
    0
            &mut self,
    3947
    0
            variant_name: &str,
    3948
    0
            method: &str,
    3949
    0
            data: Option<&Vec<Value>>,
    3950
    0
            args: &[Expr],
    3951
    0
            deadline: Instant,
    3952
    0
            depth: usize,
    3953
    0
        ) -> Result<Value> {
    3954
    0
            match (variant_name, method) {
    3955
    0
                ("Some", "unwrap" | "expect") if args.is_empty() || args.len() == 1 => {
    3956
    0
                    self.extract_value_or_unit(data)
    3957
                }
    3958
    0
                ("None", "unwrap") if args.is_empty() => {
    3959
    0
                    bail!("called `Option::unwrap()` on a `None` value")
    3960
                }
    3961
    0
                ("None", "expect") if args.len() == 1 => {
    3962
    0
                    let custom_msg = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    3963
    0
                    let msg = self.value_to_string(custom_msg);
    3964
    0
                    bail!(msg)
    3965
                }
    3966
    0
                ("Some", "map") if args.len() == 1 => {
    3967
    0
                    self.apply_function_to_value("Option", "Some", data, &args[0], deadline, depth)
    3968
                }
    3969
    0
                ("None", "map" | "and_then") if args.len() == 1 => {
    3970
    0
                    Ok(Value::EnumVariant {
    3971
    0
                        enum_name: "Option".to_string(),
    3972
    0
                        variant_name: variant_name.to_string(),
    3973
    0
                        data: data.cloned(),
    3974
    0
                    })
    3975
                }
    3976
                // ok_or converts Option to Result
    3977
    0
                ("Some", "ok_or") if args.len() == 1 => {
    3978
                    // Option::Some(x).ok_or(err) -> Result::Ok(x)
    3979
    0
                    let value = self.extract_value_or_unit(data)?;
    3980
    0
                    Ok(Self::create_result_ok(value))
    3981
                }
    3982
    0
                ("None", "ok_or") if args.len() == 1 => {
    3983
                    // Option::None.ok_or(err) -> Result::Err(err)
    3984
    0
                    let err_value = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    3985
    0
                    Ok(Self::create_result_err(err_value))
    3986
                }
    3987
    0
                ("Some", "and_then") if args.len() == 1 => {
    3988
    0
                    self.apply_function_and_flatten(data, &args[0], deadline, depth)
    3989
                }
    3990
    0
                _ => Err(Self::method_not_supported(method, &format!("Option::{variant_name}")))?,
    3991
            }
    3992
    0
        }
    3993
    3994
        /// Handle Vec enum methods (placeholder for future Vec methods)
    3995
    0
        fn evaluate_vec_methods(
    3996
    0
            &mut self,
    3997
    0
            variant_name: &str,
    3998
    0
            method: &str,
    3999
    0
            data: Option<&Vec<Value>>,
    4000
    0
            args: &[Expr],
    4001
    0
            deadline: Instant,
    4002
    0
            depth: usize,
    4003
    0
        ) -> Result<Value> {
    4004
    0
            match method {
    4005
    0
                "len" => Ok(Value::Int(data.as_ref().map_or(0, |v| v.len() as i64))),
    4006
    0
                "push" if args.len() == 1 => {
    4007
    0
                    let new_elem = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    4008
    0
                    let mut vec_data = data.cloned().unwrap_or_default();
    4009
    0
                    vec_data.push(new_elem);
    4010
    0
                    Ok(Value::EnumVariant {
    4011
    0
                        enum_name: "Vec".to_string(),
    4012
    0
                        variant_name: variant_name.to_string(),
    4013
    0
                        data: Some(vec_data),
    4014
    0
                    })
    4015
                }
    4016
    0
                _ => Err(Self::method_not_supported(method, "Vec"))?,
    4017
            }
    4018
    0
        }
    4019
    4020
        /// Extract value from enum data or return Unit
    4021
    0
        fn extract_value_or_unit(&self, data: Option<&Vec<Value>>) -> Result<Value> {
    4022
    0
            if let Some(values) = data {
    4023
    0
                if !values.is_empty() {
    4024
    0
                    return Ok(values[0].clone());
    4025
    0
                }
    4026
    0
            }
    4027
    0
            Self::ok_unit()
    4028
    0
        }
    4029
    4030
        /// Format error message for unwrap operations
    4031
    0
        fn format_error_message(&self, method: &str, variant: &str, data: Option<&Vec<Value>>) -> String {
    4032
    0
            if let Some(values) = data {
    4033
    0
                if values.is_empty() {
    4034
    0
                    format!("called `{method}` on an `{variant}` value")
    4035
                } else {
    4036
    0
                    format!("called `{}` on an `{}` value: {}", method, variant, values[0])
    4037
                }
    4038
            } else {
    4039
    0
                format!("called `{method}` on an `{variant}` value")
    4040
            }
    4041
    0
        }
    4042
    4043
        /// Convert Value to string representation
    4044
    0
        fn value_to_string(&self, value: Value) -> String {
    4045
    0
            match value {
    4046
    0
                Value::String(s) => s,
    4047
    0
                other => format!("{other}"),
    4048
            }
    4049
    0
        }
    4050
    4051
        /// Evaluate `DataFrame` methods (builder pattern and queries)
    4052
    0
        fn evaluate_dataframe_methods(
    4053
    0
            &mut self,
    4054
    0
            mut columns: Vec<DataFrameColumn>,
    4055
    0
            method: &str,
    4056
    0
            args: &[Expr],
    4057
    0
            deadline: Instant,
    4058
    0
            depth: usize,
    4059
    0
        ) -> Result<Value> {
    4060
    0
            match method {
    4061
    0
                "column" => {
    4062
                    // Builder pattern: add a column
    4063
    0
                    if args.len() != 2 {
    4064
    0
                        bail!("DataFrame.column() requires exactly 2 arguments (name, values)");
    4065
    0
                    }
    4066
    4067
                    // Evaluate column name
    4068
    0
                    let name_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    4069
    0
                    let column_name = match name_val {
    4070
    0
                        Value::String(s) => s,
    4071
    0
                        _ => bail!("Column name must be a string"),
    4072
                    };
    4073
    4074
                    // Evaluate column values (should be a list)
    4075
    0
                    let values_val = self.evaluate_expr(&args[1], deadline, depth + 1)?;
    4076
    0
                    let column_values = match values_val {
    4077
    0
                        Value::List(items) => items,
    4078
    0
                        _ => bail!("Column values must be a list"),
    4079
                    };
    4080
    4081
                    // Add the column to the DataFrame
    4082
    0
                    columns.push(DataFrameColumn {
    4083
    0
                        name: column_name,
    4084
    0
                        values: column_values,
    4085
    0
                    });
    4086
    4087
    0
                    Ok(Value::DataFrame { columns })
    4088
                }
    4089
    0
                "build" => {
    4090
                    // Finalize the DataFrame builder
    4091
    0
                    if !args.is_empty() {
    4092
    0
                        bail!("DataFrame.build() takes no arguments");
    4093
    0
                    }
    4094
    0
                    Ok(Value::DataFrame { columns })
    4095
                }
    4096
    0
                "rows" => {
    4097
                    // Return number of rows
    4098
    0
                    if !args.is_empty() {
    4099
    0
                        bail!("DataFrame.rows() takes no arguments");
    4100
    0
                    }
    4101
    0
                    let num_rows = columns.first().map_or(0, |col| col.values.len());
    4102
    0
                    Ok(Value::Int(num_rows as i64))
    4103
                }
    4104
    0
                "columns" => {
    4105
                    // Return number of columns
    4106
    0
                    if !args.is_empty() {
    4107
    0
                        bail!("DataFrame.columns() takes no arguments");
    4108
    0
                    }
    4109
    0
                    Ok(Value::Int(columns.len() as i64))
    4110
                }
    4111
    0
                "get" => {
    4112
                    // Get a value at (column_name, row_index)
    4113
    0
                    if args.len() != 2 {
    4114
    0
                        bail!("DataFrame.get() requires exactly 2 arguments (column_name, row_index)");
    4115
    0
                    }
    4116
    4117
                    // Evaluate column name
    4118
    0
                    let name_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    4119
    0
                    let column_name = match name_val {
    4120
    0
                        Value::String(s) => s,
    4121
    0
                        _ => bail!("Column name must be a string"),
    4122
                    };
    4123
    4124
                    // Evaluate row index
    4125
    0
                    let index_val = self.evaluate_expr(&args[1], deadline, depth + 1)?;
    4126
    0
                    let row_index = match index_val {
    4127
    0
                        Value::Int(i) => i as usize,
    4128
    0
                        _ => bail!("Row index must be an integer"),
    4129
                    };
    4130
    4131
                    // Find the column
    4132
    0
                    for col in &columns {
    4133
    0
                        if col.name == column_name {
    4134
    0
                            if row_index < col.values.len() {
    4135
    0
                                return Ok(col.values[row_index].clone());
    4136
    0
                            }
    4137
    0
                            bail!("Row index {} out of bounds for column '{}'", row_index, column_name);
    4138
    0
                        }
    4139
                    }
    4140
    0
                    bail!("Column '{}' not found in DataFrame", column_name);
    4141
                }
    4142
    0
                _ => bail!("Unknown DataFrame method: {}", method),
    4143
            }
    4144
    0
        }
    4145
    4146
        /// Apply function to enum value (for map operations)
    4147
    0
        fn apply_function_to_value(
    4148
    0
            &mut self,
    4149
    0
            enum_name: &str,
    4150
    0
            variant_name: &str,
    4151
    0
            data: Option<&Vec<Value>>,
    4152
    0
            func_arg: &Expr,
    4153
    0
            deadline: Instant,
    4154
    0
            depth: usize,
    4155
    0
        ) -> Result<Value> {
    4156
    0
            if let Some(values) = data {
    4157
    0
                if !values.is_empty() {
    4158
    0
                    let call_expr = self.create_function_call(func_arg, &values[0]);
    4159
    0
                    let mapped_value = self.evaluate_expr(&call_expr, deadline, depth + 1)?;
    4160
    0
                    return Ok(Value::EnumVariant {
    4161
    0
                        enum_name: enum_name.to_string(),
    4162
    0
                        variant_name: variant_name.to_string(),
    4163
    0
                        data: Some(vec![mapped_value]),
    4164
    0
                    });
    4165
    0
                }
    4166
    0
            }
    4167
    0
            Ok(Value::EnumVariant {
    4168
    0
                enum_name: enum_name.to_string(),
    4169
    0
                variant_name: variant_name.to_string(),
    4170
    0
                data: Some(vec![Value::Unit]),
    4171
    0
            })
    4172
    0
        }
    4173
    4174
        /// Apply function and flatten result (for `and_then` operations)
    4175
    0
        fn apply_function_and_flatten(
    4176
    0
            &mut self,
    4177
    0
            data: Option<&Vec<Value>>,
    4178
    0
            func_arg: &Expr,
    4179
    0
            deadline: Instant,
    4180
    0
            depth: usize,
    4181
    0
        ) -> Result<Value> {
    4182
    0
            if let Some(values) = data {
    4183
    0
                if !values.is_empty() {
    4184
    0
                    let call_expr = self.create_function_call(func_arg, &values[0]);
    4185
    0
                    return self.evaluate_expr(&call_expr, deadline, depth + 1);
    4186
    0
                }
    4187
    0
            }
    4188
    0
            Ok(Value::EnumVariant {
    4189
    0
                enum_name: "Result".to_string(),
    4190
    0
                variant_name: "Ok".to_string(),
    4191
    0
                data: Some(vec![Value::Unit]),
    4192
    0
            })
    4193
    0
        }
    4194
    4195
        /// Create function call expression for enum combinators
    4196
    0
        fn create_function_call(&self, func_arg: &Expr, value: &Value) -> Expr {
    4197
    0
            Expr::new(
    4198
    0
                ExprKind::Call {
    4199
    0
                    func: Box::new(func_arg.clone()),
    4200
    0
                    args: vec![Expr::new(
    4201
    0
                        ExprKind::Literal(crate::frontend::ast::Literal::from_value(value)),
    4202
    0
                        Span { start: 0, end: 0 },
    4203
    0
                    )],
    4204
    0
                },
    4205
    0
                Span { start: 0, end: 0 },
    4206
            )
    4207
    0
        }
    4208
    4209
        /// Evaluate object literal (complexity: 10)
    4210
    0
        fn evaluate_object_literal(
    4211
    0
            &mut self,
    4212
    0
            fields: &[crate::frontend::ast::ObjectField],
    4213
    0
            deadline: Instant,
    4214
    0
            depth: usize,
    4215
    0
        ) -> Result<Value> {
    4216
            use crate::frontend::ast::ObjectField;
    4217
    0
            let mut map = HashMap::new();
    4218
    4219
    0
            for field in fields {
    4220
    0
                match field {
    4221
    0
                    ObjectField::KeyValue { key, value } => {
    4222
    0
                        let val = self.evaluate_expr(value, deadline, depth + 1)?;
    4223
    0
                        map.insert(key.clone(), val);
    4224
                    }
    4225
    0
                    ObjectField::Spread { expr } => {
    4226
    0
                        let spread_val = self.evaluate_expr(expr, deadline, depth + 1)?;
    4227
    0
                        if let Value::Object(spread_map) = spread_val {
    4228
    0
                            map.extend(spread_map);
    4229
    0
                        } else {
    4230
    0
                            bail!("Spread operator can only be used with objects");
    4231
                        }
    4232
                    }
    4233
                }
    4234
            }
    4235
    4236
    0
            Self::ok_object(map)
    4237
    0
        }
    4238
    4239
        /// Evaluate enum definition (complexity: 4)
    4240
    0
        fn evaluate_enum_definition(
    4241
    0
            &mut self,
    4242
    0
            name: &str,
    4243
    0
            variants: &[crate::frontend::ast::EnumVariant],
    4244
    0
        ) -> Value {
    4245
    0
            let variant_names: Vec<String> = variants.iter().map(|v| v.name.clone()).collect();
    4246
    0
            self.enum_definitions
    4247
    0
                .insert(name.to_string(), variant_names);
    4248
    0
            println!("Defined enum {} with {} variants", name, variants.len());
    4249
    0
            Value::Unit
    4250
    0
        }
    4251
    4252
        /// Evaluate struct definition (complexity: 3)
    4253
    0
        fn evaluate_struct_definition(
    4254
    0
            name: &str,
    4255
    0
            fields: &[crate::frontend::ast::StructField],
    4256
    0
        ) -> Value {
    4257
    0
            println!("Defined struct {} with {} fields", name, fields.len());
    4258
    0
            Value::Unit
    4259
    0
        }
    4260
    4261
        /// Evaluate struct literal (complexity: 5)
    4262
    0
        fn evaluate_struct_literal(
    4263
    0
            &mut self,
    4264
    0
            fields: &[(String, Expr)],
    4265
    0
            deadline: Instant,
    4266
    0
            depth: usize,
    4267
    0
        ) -> Result<Value> {
    4268
    0
            let mut map = HashMap::new();
    4269
    0
            for (field_name, field_expr) in fields {
    4270
    0
                let field_value = self.evaluate_expr(field_expr, deadline, depth + 1)?;
    4271
    0
                map.insert(field_name.clone(), field_value);
    4272
            }
    4273
    0
            Self::ok_object(map)
    4274
    0
        }
    4275
    4276
        /// Evaluate field access (complexity: 4)
    4277
    0
        fn evaluate_field_access(
    4278
    0
            &mut self,
    4279
    0
            object: &Expr,
    4280
    0
            field: &str,
    4281
    0
            deadline: Instant,
    4282
    0
            depth: usize,
    4283
    0
        ) -> Result<Value> {
    4284
    0
            let obj_val = self.evaluate_expr(object, deadline, depth + 1)?;
    4285
    0
            match obj_val {
    4286
    0
                Value::Object(map) => map
    4287
    0
                    .get(field)
    4288
    0
                    .cloned()
    4289
    0
                    .ok_or_else(|| anyhow::anyhow!("Field '{}' not found", field)),
    4290
    0
                Value::Tuple(values) => {
    4291
                    // Handle tuple access like t.0, t.1, etc.
    4292
    0
                    if let Ok(index) = field.parse::<usize>() {
    4293
    0
                        values.get(index)
    4294
    0
                            .cloned()
    4295
    0
                            .ok_or_else(|| anyhow::anyhow!("Tuple index {} out of bounds (length: {})", index, values.len()))
    4296
                    } else {
    4297
    0
                        bail!("Invalid tuple index: '{}'", field)
    4298
                    }
    4299
                }
    4300
    0
                _ => bail!("Field access on non-object value"),
    4301
            }
    4302
    0
        }
    4303
    4304
        /// Evaluate optional field access (complexity: 5)
    4305
    0
        fn evaluate_optional_field_access(
    4306
    0
            &mut self,
    4307
    0
            object: &Expr,
    4308
    0
            field: &str,
    4309
    0
            deadline: Instant,
    4310
    0
            depth: usize,
    4311
    0
        ) -> Result<Value> {
    4312
    0
            let obj_val = self.evaluate_expr(object, deadline, depth + 1)?;
    4313
    4314
            // If the object is null, return null (short-circuit evaluation)
    4315
    0
            if matches!(obj_val, Value::Nil) {
    4316
    0
                return Self::ok_nil();
    4317
    0
            }
    4318
    4319
    0
            match obj_val {
    4320
    0
                Value::Object(map) => Ok(map.get(field).cloned().unwrap_or(Value::Nil)),
    4321
    0
                Value::Tuple(values) => {
    4322
                    // Handle optional tuple access like t?.0, t?.1, etc.
    4323
    0
                    if let Ok(index) = field.parse::<usize>() {
    4324
    0
                        Ok(values.get(index).cloned().unwrap_or(Value::Nil))
    4325
                    } else {
    4326
    0
                        Self::ok_nil() // Invalid tuple index returns nil instead of error
    4327
                    }
    4328
                }
    4329
    0
                _ => Self::ok_nil(), // Non-object/tuple values return nil instead of error
    4330
            }
    4331
    0
        }
    4332
    4333
        /// Evaluate optional method call with null-safe chaining (complexity: 10)
    4334
    0
        fn evaluate_optional_method_call(
    4335
    0
            &mut self,
    4336
    0
            receiver: &Expr,
    4337
    0
            method: &str,
    4338
    0
            args: &[Expr],
    4339
    0
            deadline: Instant,
    4340
    0
            depth: usize,
    4341
    0
        ) -> Result<Value> {
    4342
    0
            let receiver_val = self.evaluate_expr(receiver, deadline, depth + 1)?;
    4343
    4344
            // If the receiver is null, return null (short-circuit evaluation)
    4345
    0
            if matches!(receiver_val, Value::Nil) {
    4346
    0
                return Self::ok_nil();
    4347
    0
            }
    4348
    4349
            // Try to call the method, but return nil if it fails instead of erroring
    4350
    0
            let result = match receiver_val {
    4351
    0
                Value::List(items) => {
    4352
    0
                    self.evaluate_list_methods(items, method, args, deadline, depth).unwrap_or(Value::Nil)
    4353
                }
    4354
    0
                Value::String(s) => {
    4355
    0
                    Self::evaluate_string_methods(&s, method, args, deadline, depth).unwrap_or(Value::Nil)
    4356
                }
    4357
                Value::Int(_) | Value::Float(_) => {
    4358
    0
                    self.evaluate_numeric_methods(&receiver_val, method).unwrap_or(Value::Nil)
    4359
                }
    4360
    0
                Value::Object(obj) => {
    4361
    0
                    Self::evaluate_object_methods(obj, method, args, deadline, depth).unwrap_or(Value::Nil)
    4362
                }
    4363
    0
                Value::HashMap(map) => {
    4364
    0
                    self.evaluate_hashmap_methods(map, method, args, deadline, depth).unwrap_or(Value::Nil)
    4365
                }
    4366
    0
                Value::HashSet(set) => {
    4367
    0
                    self.evaluate_hashset_methods(set, method, args, deadline, depth).unwrap_or(Value::Nil)
    4368
                }
    4369
                Value::EnumVariant { .. } => {
    4370
    0
                    self.evaluate_enum_methods(receiver_val, method, args, deadline, depth).unwrap_or(Value::Nil)
    4371
                }
    4372
    0
                _ => Value::Nil, // Unsupported types return nil
    4373
            };
    4374
    4375
    0
            Ok(result)
    4376
    0
        }
    4377
    4378
        /// Evaluate index access (complexity: 5)
    4379
    0
        fn evaluate_index_access(
    4380
    0
            &mut self,
    4381
    0
            object: &Expr,
    4382
    0
            index: &Expr,
    4383
    0
            deadline: Instant,
    4384
    0
            depth: usize,
    4385
    0
        ) -> Result<Value> {
    4386
    0
            let obj_val = self.evaluate_expr(object, deadline, depth + 1)?;
    4387
    0
            let index_val = self.evaluate_expr(index, deadline, depth + 1)?;
    4388
    4389
            // Check for range indexing first
    4390
    0
            if let Value::Range { start, end, inclusive } = index_val {
    4391
    0
                return self.handle_range_indexing(obj_val, start, end, inclusive);
    4392
    0
            }
    4393
    4394
            // Handle single index access
    4395
    0
            self.handle_single_index_access(obj_val, index_val)
    4396
    0
        }
    4397
    4398
        /// Handle range-based indexing for lists and strings
    4399
        ///
    4400
        /// Example Usage:
    4401
        ///
    4402
        /// Handles range indexing for lists and strings:
    4403
        /// - list[0..2] returns a sublist with elements at indices 0 and 1
    4404
        /// - string[1..3] returns substring from index 1 to 2
    4405
        /// - list[0..=2] returns elements at indices 0, 1, and 2 (inclusive)
    4406
    0
        fn handle_range_indexing(&self, obj_val: Value, start: i64, end: i64, inclusive: bool) -> Result<Value> {
    4407
    0
            match obj_val {
    4408
    0
                Value::List(list) => {
    4409
    0
                    let (start_idx, end_idx) = self.calculate_slice_bounds(start, end, inclusive, list.len())?;
    4410
    0
                    Self::ok_list(list[start_idx..end_idx].to_vec())
    4411
                }
    4412
    0
                Value::String(s) => {
    4413
    0
                    let chars: Vec<char> = s.chars().collect();
    4414
    0
                    let (start_idx, end_idx) = self.calculate_slice_bounds(start, end, inclusive, chars.len())?;
    4415
    0
                    Self::ok_string(chars[start_idx..end_idx].iter().collect::<String>())
    4416
                }
    4417
    0
                _ => bail!("Cannot slice into {:?}", obj_val),
    4418
            }
    4419
    0
        }
    4420
    4421
        /// Handle single index access for various data types
    4422
        ///
    4423
        /// # Example Usage
    4424
        /// Handles range-based indexing for strings and arrays like arr[0..3] or str[1..].
    4425
        /// # use `ruchy::runtime::repl::Repl`;
    4426
        /// # use `ruchy::runtime::repl::Value`;
    4427
        /// let mut repl = `Repl::new().unwrap()`;
    4428
        /// let list = `Value::List(vec`![`Value::Int(42)`]);
    4429
        /// let result = `repl.handle_single_index_access(list`, `Value::Int(0)).unwrap()`;
    4430
        /// `assert_eq!(result`, `Value::Int(42)`);
    4431
        /// ```
    4432
    0
        fn handle_single_index_access(&self, obj_val: Value, index_val: Value) -> Result<Value> {
    4433
    0
            match (obj_val, index_val) {
    4434
    0
                (Value::List(list), Value::Int(idx)) => {
    4435
    0
                    let idx = self.validate_array_index(idx, list.len())?;
    4436
    0
                    Ok(list[idx].clone())
    4437
                }
    4438
    0
                (Value::String(s), Value::Int(idx)) => {
    4439
    0
                    let chars: Vec<char> = s.chars().collect();
    4440
    0
                    let idx = self.validate_array_index(idx, chars.len())?;
    4441
    0
                    Ok(Value::String(chars[idx].to_string()))
    4442
                }
    4443
    0
                (Value::Object(obj), Value::String(key)) => {
    4444
    0
                    obj.get(&key)
    4445
    0
                        .cloned()
    4446
    0
                        .ok_or_else(|| anyhow::anyhow!("Key '{}' not found in object", key))
    4447
                }
    4448
    0
                (obj_val, index_val) => bail!("Cannot index into {:?} with index {:?}", obj_val, index_val),
    4449
            }
    4450
    0
        }
    4451
    4452
        /// Calculate slice bounds and validate them
    4453
        ///
    4454
        /// # Example Usage
    4455
        /// Calculates and validates slice bounds for array indexing operations.
    4456
        /// Converts indices to valid array bounds and handles inclusive/exclusive ranges.
    4457
    0
        fn calculate_slice_bounds(&self, start: i64, end: i64, inclusive: bool, len: usize) -> Result<(usize, usize)> {
    4458
    0
            let start_idx = usize::try_from(start)
    4459
    0
                .map_err(|_| anyhow::anyhow!("Invalid start index: {}", start))?;
    4460
    4461
    0
            let end_idx = if inclusive {
    4462
    0
                usize::try_from(end + 1)
    4463
    0
                    .map_err(|_| anyhow::anyhow!("Invalid end index: {}", end + 1))?
    4464
            } else {
    4465
    0
                usize::try_from(end)
    4466
    0
                    .map_err(|_| anyhow::anyhow!("Invalid end index: {}", end))?
    4467
            };
    4468
    4469
    0
            if start_idx > len || end_idx > len {
    4470
    0
                bail!("Slice indices out of bounds");
    4471
    0
            }
    4472
    0
            if start_idx > end_idx {
    4473
    0
                bail!("Invalid slice range: start > end");
    4474
    0
            }
    4475
    4476
    0
            Ok((start_idx, end_idx))
    4477
    0
        }
    4478
    4479
        /// Validate array index and convert to usize
    4480
        ///
    4481
        /// # Example Usage
    4482
        /// Calculates and validates slice bounds for array indexing operations.
    4483
        /// # use `ruchy::runtime::repl::Repl`;
    4484
        /// let repl = `Repl::new().unwrap()`;
    4485
        /// let idx = `repl.validate_array_index(2`, `5).unwrap()`;
    4486
        /// `assert_eq!(idx`, 2);
    4487
        /// ```
    4488
    0
        fn validate_array_index(&self, idx: i64, len: usize) -> Result<usize> {
    4489
    0
            let idx = usize::try_from(idx)
    4490
    0
                .map_err(|_| anyhow::anyhow!("Invalid index: {}", idx))?;
    4491
    4492
    0
            if idx >= len {
    4493
    0
                bail!("Index {} out of bounds for length {}", idx, len);
    4494
    0
            }
    4495
    4496
    0
            Ok(idx)
    4497
    0
        }
    4498
    4499
        /// Evaluate slice index expression (complexity: 4)
    4500
    0
        fn evaluate_slice_index(&mut self, expr: Option<&Expr>, deadline: Instant, depth: usize) -> Result<Option<usize>> {
    4501
    0
            if let Some(index_expr) = expr {
    4502
    0
                match self.evaluate_expr(index_expr, deadline, depth + 1)? {
    4503
    0
                    Value::Int(idx) => {
    4504
    0
                        Ok(Some(usize::try_from(idx)
    4505
    0
                            .map_err(|_| anyhow::anyhow!("Invalid slice index: {}", idx))?))
    4506
                    }
    4507
    0
                    _ => Err(anyhow::anyhow!("Slice indices must be integers"))
    4508
                }
    4509
            } else {
    4510
    0
                Ok(None)
    4511
            }
    4512
    0
        }
    4513
    4514
        /// Validate slice bounds (complexity: 3)
    4515
    0
        fn validate_slice_bounds(start: usize, end: usize, len: usize) -> Result<()> {
    4516
    0
            if start > len || end > len {
    4517
    0
                return Err(anyhow::anyhow!("Slice indices out of bounds"));
    4518
    0
            }
    4519
    0
            if start > end {
    4520
    0
                return Err(anyhow::anyhow!("Invalid slice range: start > end"));
    4521
    0
            }
    4522
    0
            Ok(())
    4523
    0
        }
    4524
    4525
        /// Slice a list value (complexity: 4)
    4526
    0
        fn slice_list(list: Vec<Value>, start_idx: Option<usize>, end_idx: Option<usize>) -> Result<Value> {
    4527
    0
            let start = start_idx.unwrap_or(0);
    4528
    0
            let end = end_idx.unwrap_or(list.len());
    4529
    4530
    0
            Self::validate_slice_bounds(start, end, list.len())?;
    4531
    0
            Self::ok_list(list[start..end].to_vec())
    4532
    0
        }
    4533
    4534
        /// Slice a string value (complexity: 5)
    4535
    0
        fn slice_string(s: String, start_idx: Option<usize>, end_idx: Option<usize>) -> Result<Value> {
    4536
    0
            let chars: Vec<char> = s.chars().collect();
    4537
    0
            let start = start_idx.unwrap_or(0);
    4538
    0
            let end = end_idx.unwrap_or(chars.len());
    4539
    4540
    0
            Self::validate_slice_bounds(start, end, chars.len())?;
    4541
    0
            let sliced: String = chars[start..end].iter().collect();
    4542
    0
            Ok(Value::String(sliced))
    4543
    0
        }
    4544
    4545
        /// Main slice evaluation function (complexity: 6)
    4546
    0
        fn evaluate_slice(
    4547
    0
            &mut self,
    4548
    0
            object: &Expr,
    4549
    0
            start: Option<&Expr>,
    4550
    0
            end: Option<&Expr>,
    4551
    0
            deadline: Instant,
    4552
    0
            depth: usize,
    4553
    0
        ) -> Result<Value> {
    4554
    0
            let obj_val = self.evaluate_expr(object, deadline, depth + 1)?;
    4555
    4556
            // Evaluate start and end indices
    4557
    0
            let start_idx = self.evaluate_slice_index(start, deadline, depth)?;
    4558
    0
            let end_idx = self.evaluate_slice_index(end, deadline, depth)?;
    4559
    4560
            // Perform slicing based on value type
    4561
    0
            match obj_val {
    4562
    0
                Value::List(list) => Self::slice_list(list, start_idx, end_idx),
    4563
    0
                Value::String(s) => Self::slice_string(s, start_idx, end_idx),
    4564
    0
                _ => Err(anyhow::anyhow!("Cannot slice value of type {:?}", obj_val)),
    4565
            }
    4566
    0
        }
    4567
    4568
        /// Evaluate trait definition (complexity: 3)
    4569
    0
        fn evaluate_trait_definition(
    4570
    0
            name: &str,
    4571
    0
            methods: &[crate::frontend::ast::TraitMethod],
    4572
    0
        ) -> Value {
    4573
    0
            println!("Defined trait {} with {} methods", name, methods.len());
    4574
    0
            Value::Unit
    4575
    0
        }
    4576
    4577
        /// Evaluate impl block (complexity: 12)
    4578
    0
        fn evaluate_impl_block(
    4579
    0
            &mut self,
    4580
    0
            for_type: &str,
    4581
    0
            methods: &[crate::frontend::ast::ImplMethod],
    4582
    0
        ) -> Value {
    4583
    0
            for method in methods {
    4584
    0
                let qualified_name = format!("{}::{}", for_type, method.name);
    4585
    4586
    0
                let param_names: Vec<String> = method
    4587
    0
                    .params
    4588
    0
                    .iter()
    4589
    0
                    .filter_map(|p| {
    4590
    0
                        let name = p.name();
    4591
    0
                        if name != "self" && name != "&self" {
    4592
    0
                            Some(name)
    4593
                        } else {
    4594
    0
                            None
    4595
                        }
    4596
    0
                    })
    4597
    0
                    .collect();
    4598
    4599
    0
                self.impl_methods
    4600
    0
                    .insert(qualified_name, (param_names, method.body.clone()));
    4601
            }
    4602
    4603
    0
            println!(
    4604
    0
                "Defined impl for {} with {} methods",
    4605
                for_type,
    4606
    0
                methods.len()
    4607
            );
    4608
    0
            Value::Unit
    4609
    0
        }
    4610
    4611
        /// Evaluate binary expression (complexity: 3)
    4612
    0
        fn evaluate_binary_expr(
    4613
    0
            &mut self,
    4614
    0
            left: &Expr,
    4615
    0
            op: BinaryOp,
    4616
    0
            right: &Expr,
    4617
    0
            deadline: Instant,
    4618
    0
            depth: usize,
    4619
    0
        ) -> Result<Value> {
    4620
            // Handle short-circuit operators
    4621
    0
            match op {
    4622
                BinaryOp::NullCoalesce => {
    4623
    0
                    let lhs = self.evaluate_expr(left, deadline, depth + 1)?;
    4624
    0
                    if matches!(lhs, Value::Nil) {
    4625
    0
                        self.evaluate_expr(right, deadline, depth + 1)
    4626
                    } else {
    4627
    0
                        Ok(lhs)
    4628
                    }
    4629
                }
    4630
                BinaryOp::And => {
    4631
    0
                    let lhs = self.evaluate_expr(left, deadline, depth + 1)?;
    4632
    0
                    if lhs.is_truthy() {
    4633
    0
                        self.evaluate_expr(right, deadline, depth + 1)
    4634
                    } else {
    4635
    0
                        Ok(lhs)
    4636
                    }
    4637
                }
    4638
                BinaryOp::Or => {
    4639
    0
                    let lhs = self.evaluate_expr(left, deadline, depth + 1)?;
    4640
    0
                    if lhs.is_truthy() {
    4641
    0
                        Ok(lhs)
    4642
                    } else {
    4643
    0
                        self.evaluate_expr(right, deadline, depth + 1)
    4644
                    }
    4645
                }
    4646
                _ => {
    4647
    0
                    let lhs = self.evaluate_expr(left, deadline, depth + 1)?;
    4648
    0
                    let rhs = self.evaluate_expr(right, deadline, depth + 1)?;
    4649
    0
                    Self::evaluate_binary(&lhs, op, &rhs)
    4650
                }
    4651
            }
    4652
    0
        }
    4653
    4654
        /// Evaluate unary expression (complexity: 2)
    4655
    0
        fn evaluate_unary_expr(
    4656
    0
            &mut self,
    4657
    0
            op: UnaryOp,
    4658
    0
            operand: &Expr,
    4659
    0
            deadline: Instant,
    4660
    0
            depth: usize,
    4661
    0
        ) -> Result<Value> {
    4662
    0
            let val = self.evaluate_expr(operand, deadline, depth + 1)?;
    4663
    0
            Self::evaluate_unary(op, &val)
    4664
    0
        }
    4665
    4666
        /// Evaluate identifier (complexity: 2)
    4667
    0
        fn evaluate_identifier(&self, name: &str) -> Result<Value> {
    4668
            // Check if it's a qualified enum variant like "Option::None"
    4669
    0
            if let Some(pos) = name.find("::") {
    4670
    0
                let (module, variant) = name.split_at(pos);
    4671
    0
                let variant = &variant[2..]; // Skip the "::"
    4672
    4673
                // Handle known enum variants
    4674
    0
                if module == "Option" && variant == "None" {
    4675
    0
                    return Ok(Self::create_option_none());
    4676
    0
                } else if module == "Result" {
    4677
                    // Result variants without data are not valid, but we create them for consistency
    4678
    0
                    return Ok(Value::EnumVariant {
    4679
    0
                        enum_name: module.to_string(),
    4680
    0
                        variant_name: variant.to_string(),
    4681
    0
                        data: None,
    4682
    0
                    });
    4683
    0
                }
    4684
    4685
                // For other qualified names, create an enum variant
    4686
    0
                return Ok(Value::EnumVariant {
    4687
    0
                    enum_name: module.to_string(),
    4688
    0
                    variant_name: variant.to_string(),
    4689
    0
                    data: None,
    4690
    0
                });
    4691
    0
            }
    4692
    4693
    0
            self.get_binding(name)
    4694
    0
                .ok_or_else(|| anyhow::anyhow!("Undefined variable: '{}'\n  Hint: Did you mean to declare it with 'let {} = value'?", name, name))
    4695
    0
        }
    4696
    4697
        /// Evaluate qualified name (complexity: 2)
    4698
    0
        fn evaluate_qualified_name(module: &str, name: &str) -> Value {
    4699
    0
            Value::EnumVariant {
    4700
    0
                enum_name: module.to_string(),
    4701
    0
                variant_name: name.to_string(),
    4702
    0
                data: None,
    4703
    0
            }
    4704
    0
        }
    4705
    4706
        /// Evaluate await expression (complexity: 1)
    4707
    0
        fn evaluate_await_expr(
    4708
    0
            &mut self,
    4709
    0
            expr: &Expr,
    4710
    0
            deadline: Instant,
    4711
    0
            depth: usize,
    4712
    0
        ) -> Result<Value> {
    4713
            // For now, await just evaluates the expression
    4714
            // In a full async implementation, this would handle Future resolution
    4715
    0
            self.evaluate_expr(expr, deadline, depth + 1)
    4716
    0
        }
    4717
    4718
        /// Evaluate async block (complexity: 1)
    4719
    0
        fn evaluate_async_block(
    4720
    0
            &mut self,
    4721
    0
            body: &Expr,
    4722
    0
            deadline: Instant,
    4723
    0
            depth: usize,
    4724
    0
        ) -> Result<Value> {
    4725
            // For REPL purposes, evaluate the async block body synchronously
    4726
            // In a full async implementation, this would return a Future
    4727
    0
            self.evaluate_expr(body, deadline, depth + 1)
    4728
    0
        }
    4729
    4730
        /// Evaluate try operator (?) (complexity: 1)
    4731
        /// Evaluate `DataFrame` operation (complexity: 1)
    4732
    0
        fn evaluate_dataframe_operation() -> Result<Value> {
    4733
            // DataFrame operations not yet implemented in REPL
    4734
    0
            bail!("DataFrame operations not yet implemented in REPL")
    4735
    0
        }
    4736
    4737
        /// Check if a pattern matches a value and return bindings
    4738
        ///
    4739
        /// Returns Some(bindings) if pattern matches, None if it doesn't
    4740
    0
        fn pattern_matches(value: &Value, pattern: &Pattern) -> Result<Option<HashMap<String, Value>>> {
    4741
    0
            let mut bindings = HashMap::new();
    4742
    4743
    0
            if Self::pattern_matches_recursive(value, pattern, &mut bindings)? {
    4744
    0
                Ok(Some(bindings))
    4745
            } else {
    4746
    0
                Ok(None)
    4747
            }
    4748
    0
        }
    4749
    4750
        /// Recursive pattern matching helper
    4751
        /// Match literal patterns (complexity: 4)
    4752
    0
        fn match_literal_pattern(value: &Value, literal: &Literal) -> bool {
    4753
    0
            match (value, literal) {
    4754
    0
                (Value::Unit, Literal::Unit) => true,
    4755
    0
                (Value::Int(v), Literal::Integer(p)) => v == p,
    4756
    0
                (Value::Float(v), Literal::Float(p)) => (v - p).abs() < f64::EPSILON,
    4757
    0
                (Value::String(v), Literal::String(p)) => v == p,
    4758
    0
                (Value::Bool(v), Literal::Bool(p)) => v == p,
    4759
    0
                _ => false,
    4760
            }
    4761
    0
        }
    4762
    4763
        /// Match sequence patterns (list or tuple) (complexity: 4)
    4764
    0
        fn match_sequence_pattern(
    4765
    0
            values: &[Value],
    4766
    0
            patterns: &[Pattern],
    4767
    0
            bindings: &mut HashMap<String, Value>,
    4768
    0
        ) -> Result<bool> {
    4769
    0
            if values.len() != patterns.len() {
    4770
    0
                return Ok(false);
    4771
    0
            }
    4772
    4773
    0
            for (value, pattern) in values.iter().zip(patterns.iter()) {
    4774
    0
                if !Self::pattern_matches_recursive(value, pattern, bindings)? {
    4775
    0
                    return Ok(false);
    4776
    0
                }
    4777
            }
    4778
    0
            Ok(true)
    4779
    0
        }
    4780
    4781
        /// Match OR patterns (complexity: 5)
    4782
    0
        fn match_or_pattern(
    4783
    0
            value: &Value,
    4784
    0
            patterns: &[Pattern],
    4785
    0
            bindings: &mut HashMap<String, Value>,
    4786
    0
        ) -> Result<bool> {
    4787
    0
            for pattern in patterns {
    4788
    0
                let mut temp_bindings = HashMap::new();
    4789
    0
                if Self::pattern_matches_recursive(value, pattern, &mut temp_bindings)? {
    4790
                    // Merge bindings
    4791
    0
                    for (name, val) in temp_bindings {
    4792
    0
                        bindings.insert(name, val);
    4793
    0
                    }
    4794
    0
                    return Ok(true);
    4795
    0
                }
    4796
            }
    4797
    0
            Ok(false)
    4798
    0
        }
    4799
    4800
        /// Match range patterns (complexity: 5)
    4801
    0
        fn match_range_pattern(
    4802
    0
            value: i64,
    4803
    0
            start: &Pattern,
    4804
    0
            end: &Pattern,
    4805
    0
            inclusive: bool,
    4806
    0
        ) -> Result<bool> {
    4807
            // For simplicity, only handle integer literal patterns in ranges
    4808
            if let (
    4809
    0
                Pattern::Literal(Literal::Integer(start_val)),
    4810
    0
                Pattern::Literal(Literal::Integer(end_val)),
    4811
    0
            ) = (start, end)
    4812
            {
    4813
    0
                if inclusive {
    4814
    0
                    Ok(*start_val <= value && value <= *end_val)
    4815
                } else {
    4816
    0
                    Ok(*start_val <= value && value < *end_val)
    4817
                }
    4818
            } else {
    4819
    0
                bail!("Complex range patterns not yet supported");
    4820
            }
    4821
    0
        }
    4822
    4823
        /// Match struct patterns (complexity: 7)
    4824
    0
        fn match_struct_pattern(
    4825
    0
            obj_fields: &HashMap<String, Value>,
    4826
    0
            pattern_fields: &[StructPatternField],
    4827
    0
            bindings: &mut HashMap<String, Value>,
    4828
    0
        ) -> Result<bool> {
    4829
    0
            for pattern_field in pattern_fields {
    4830
    0
                let field_name = &pattern_field.name;
    4831
    4832
                // Find the corresponding field in the object
    4833
    0
                if let Some(field_value) = obj_fields.get(field_name) {
    4834
                    // Check if pattern matches (if specified)
    4835
    0
                    if let Some(pattern) = &pattern_field.pattern {
    4836
    0
                        if !Self::pattern_matches_recursive(field_value, pattern, bindings)? {
    4837
    0
                            return Ok(false);
    4838
    0
                        }
    4839
    0
                    } else {
    4840
    0
                        // Shorthand pattern ({ x } instead of { x: x })
    4841
    0
                        // This creates a binding: x => field_value
    4842
    0
                        bindings.insert(field_name.clone(), field_value.clone());
    4843
    0
                    }
    4844
                } else {
    4845
                    // Required field not found in struct
    4846
    0
                    return Ok(false);
    4847
                }
    4848
            }
    4849
    0
            Ok(true)
    4850
    0
        }
    4851
    4852
        /// Match qualified name patterns (complexity: 4)
    4853
    0
        fn match_qualified_name_pattern(
    4854
    0
            value: &Value,
    4855
    0
            path: &[String],
    4856
    0
        ) -> bool {
    4857
    0
            if let Value::EnumVariant { enum_name, variant_name, data: _ } = value {
    4858
                // Match if qualified name matches enum variant
    4859
    0
                if path.len() >= 2 {
    4860
    0
                    let pattern_enum = &path[path.len() - 2];
    4861
    0
                    let pattern_variant = &path[path.len() - 1];
    4862
    0
                    enum_name == pattern_enum && variant_name == pattern_variant
    4863
                } else {
    4864
    0
                    false
    4865
                }
    4866
            } else {
    4867
                // Convert value to string and compare with pattern path
    4868
    0
                let value_str = format!("{value}");
    4869
    0
                let pattern_str = path.join("::");
    4870
    0
                value_str == pattern_str
    4871
            }
    4872
    0
        }
    4873
    4874
        /// Match simple patterns (complexity: 4)
    4875
    0
        fn match_simple_patterns(
    4876
    0
            value: &Value,
    4877
    0
            pattern: &Pattern,
    4878
    0
            bindings: &mut HashMap<String, Value>,
    4879
    0
        ) -> Option<Result<bool>> {
    4880
    0
            match pattern {
    4881
    0
                Pattern::Wildcard => Some(Ok(true)),
    4882
    0
                Pattern::Literal(literal) => Some(Ok(Self::match_literal_pattern(value, literal))),
    4883
    0
                Pattern::Identifier(name) => {
    4884
    0
                    bindings.insert(name.clone(), value.clone());
    4885
    0
                    Some(Ok(true))
    4886
                }
    4887
    0
                _ => None,
    4888
            }
    4889
    0
        }
    4890
    4891
        /// Match collection patterns (complexity: 5)
    4892
    0
        fn match_collection_patterns(
    4893
    0
            value: &Value,
    4894
    0
            pattern: &Pattern,
    4895
    0
            bindings: &mut HashMap<String, Value>,
    4896
    0
        ) -> Option<Result<bool>> {
    4897
    0
            match pattern {
    4898
    0
                Pattern::List(patterns) => match value {
    4899
    0
                    Value::List(values) => Some(Self::match_sequence_pattern(values, patterns, bindings)),
    4900
    0
                    _ => Some(Ok(false)),
    4901
                },
    4902
    0
                Pattern::Tuple(patterns) => match value {
    4903
    0
                    Value::Tuple(values) => Some(Self::match_sequence_pattern(values, patterns, bindings)),
    4904
    0
                    Value::List(values) => Some(Self::match_sequence_pattern(values, patterns, bindings)),
    4905
    0
                    _ => Some(Ok(false)),
    4906
                },
    4907
    0
                Pattern::Or(patterns) => Some(Self::match_or_pattern(value, patterns, bindings)),
    4908
    0
                _ => None,
    4909
            }
    4910
    0
        }
    4911
    4912
        /// Match Result/Option patterns (complexity: 6)
    4913
    0
        fn match_result_option_patterns(
    4914
    0
            value: &Value,
    4915
    0
            pattern: &Pattern,
    4916
    0
            bindings: &mut HashMap<String, Value>,
    4917
    0
        ) -> Option<Result<bool>> {
    4918
    0
            match pattern {
    4919
    0
                Pattern::Ok(inner_pattern) => {
    4920
    0
                    if let Some(ok_value) = Self::extract_result_ok(value) {
    4921
    0
                        Some(Self::pattern_matches_recursive(&ok_value, inner_pattern, bindings))
    4922
                    } else {
    4923
    0
                        Some(Ok(false))
    4924
                    }
    4925
                }
    4926
    0
                Pattern::Err(inner_pattern) => {
    4927
    0
                    if let Some(err_value) = Self::extract_result_err(value) {
    4928
    0
                        Some(Self::pattern_matches_recursive(&err_value, inner_pattern, bindings))
    4929
                    } else {
    4930
    0
                        Some(Ok(false))
    4931
                    }
    4932
                }
    4933
    0
                Pattern::Some(inner_pattern) => {
    4934
    0
                    if let Some(some_value) = Self::extract_option_some(value) {
    4935
    0
                        Some(Self::pattern_matches_recursive(&some_value, inner_pattern, bindings))
    4936
                    } else {
    4937
    0
                        Some(Ok(false))
    4938
                    }
    4939
                }
    4940
    0
                Pattern::None => Some(Ok(Self::is_option_none(value))),
    4941
    0
                _ => None,
    4942
            }
    4943
    0
        }
    4944
    4945
        /// Match complex patterns (complexity: 5)
    4946
    0
        fn match_complex_patterns(
    4947
    0
            value: &Value,
    4948
    0
            pattern: &Pattern,
    4949
    0
            bindings: &mut HashMap<String, Value>,
    4950
    0
        ) -> Option<Result<bool>> {
    4951
    0
            match pattern {
    4952
    0
                Pattern::Range { start, end, inclusive } => match value {
    4953
    0
                    Value::Int(v) => Some(Self::match_range_pattern(*v, start, end, *inclusive)),
    4954
    0
                    _ => Some(Ok(false)),
    4955
                },
    4956
    0
                Pattern::Struct { name: _struct_name, fields: pattern_fields, has_rest: _ } => {
    4957
    0
                    match value {
    4958
    0
                        Value::Object(obj_fields) => {
    4959
    0
                            Some(Self::match_struct_pattern(obj_fields, pattern_fields, bindings))
    4960
                        }
    4961
    0
                        _ => Some(Ok(false)),
    4962
                    }
    4963
                }
    4964
    0
                Pattern::QualifiedName(path) => {
    4965
    0
                    Some(Ok(Self::match_qualified_name_pattern(value, path)))
    4966
                }
    4967
                Pattern::Rest | Pattern::RestNamed(_) => {
    4968
    0
                    Some(Err(anyhow::anyhow!("Rest patterns are only valid inside struct or tuple patterns")))
    4969
                }
    4970
    0
                _ => None,
    4971
            }
    4972
    0
        }
    4973
    4974
        /// Main pattern matching function (complexity: 6)
    4975
    0
        fn pattern_matches_recursive(
    4976
    0
            value: &Value,
    4977
    0
            pattern: &Pattern,
    4978
    0
            bindings: &mut HashMap<String, Value>,
    4979
    0
        ) -> Result<bool> {
    4980
            // Try simple patterns first
    4981
    0
            if let Some(result) = Self::match_simple_patterns(value, pattern, bindings) {
    4982
    0
                return result;
    4983
    0
            }
    4984
    4985
            // Try collection patterns
    4986
    0
            if let Some(result) = Self::match_collection_patterns(value, pattern, bindings) {
    4987
    0
                return result;
    4988
    0
            }
    4989
    4990
            // Try Result/Option patterns
    4991
    0
            if let Some(result) = Self::match_result_option_patterns(value, pattern, bindings) {
    4992
    0
                return result;
    4993
    0
            }
    4994
    4995
            // Try complex patterns
    4996
    0
            if let Some(result) = Self::match_complex_patterns(value, pattern, bindings) {
    4997
    0
                return result;
    4998
    0
            }
    4999
    5000
            // Should never reach here as all pattern types are covered
    5001
    0
            bail!("Unhandled pattern type: {:?}", pattern)
    5002
    0
        }
    5003
    5004
        /// Extract value from `Result::Ok` variant (complexity: 4)
    5005
    0
        fn extract_result_ok(value: &Value) -> Option<Value> {
    5006
    0
            match value {
    5007
    0
                Value::EnumVariant { enum_name, variant_name, data } => {
    5008
    0
                    if enum_name == "Result" && variant_name == "Ok" {
    5009
    0
                        data.as_ref()?.first().cloned()
    5010
                    } else {
    5011
    0
                        None
    5012
                    }
    5013
                }
    5014
    0
                _ => None,
    5015
            }
    5016
    0
        }
    5017
    5018
        /// Extract value from `Result::Err` variant (complexity: 4)
    5019
    0
        fn extract_result_err(value: &Value) -> Option<Value> {
    5020
    0
            match value {
    5021
    0
                Value::EnumVariant { enum_name, variant_name, data } => {
    5022
    0
                    if enum_name == "Result" && variant_name == "Err" {
    5023
    0
                        data.as_ref()?.first().cloned()
    5024
                    } else {
    5025
    0
                        None
    5026
                    }
    5027
                }
    5028
    0
                _ => None,
    5029
            }
    5030
    0
        }
    5031
    5032
        /// Extract value from `Option::Some` variant (complexity: 4)
    5033
    0
        fn extract_option_some(value: &Value) -> Option<Value> {
    5034
    0
            match value {
    5035
    0
                Value::EnumVariant { enum_name, variant_name, data } => {
    5036
    0
                    if enum_name == "Option" && variant_name == "Some" {
    5037
    0
                        data.as_ref()?.first().cloned()
    5038
                    } else {
    5039
    0
                        None
    5040
                    }
    5041
                }
    5042
    0
                _ => None,
    5043
            }
    5044
    0
        }
    5045
    5046
        /// Check if value is `Option::None` variant (complexity: 3)
    5047
    0
        fn is_option_none(value: &Value) -> bool {
    5048
    0
            match value {
    5049
    0
                Value::EnumVariant { enum_name, variant_name, data: _ } => {
    5050
    0
                    enum_name == "Option" && variant_name == "None"
    5051
                }
    5052
    0
                _ => false,
    5053
            }
    5054
    0
        }
    5055
    5056
        /// Evaluate binary operations
    5057
        /// Evaluate integer arithmetic operations (complexity: 7)
    5058
    0
        fn evaluate_integer_arithmetic(a: i64, op: BinaryOp, b: i64) -> Result<Value> {
    5059
    0
            match op {
    5060
    0
                BinaryOp::Add => a
    5061
    0
                    .checked_add(b)
    5062
    0
                    .map(Value::Int)
    5063
    0
                    .ok_or_else(|| anyhow::anyhow!("Integer overflow in addition: {} + {}", a, b)),
    5064
    0
                BinaryOp::Subtract => a
    5065
    0
                    .checked_sub(b)
    5066
    0
                    .map(Value::Int)
    5067
    0
                    .ok_or_else(|| anyhow::anyhow!("Integer overflow in subtraction: {} - {}", a, b)),
    5068
    0
                BinaryOp::Multiply => a
    5069
    0
                    .checked_mul(b)
    5070
    0
                    .map(Value::Int)
    5071
    0
                    .ok_or_else(|| anyhow::anyhow!("Integer overflow in multiplication: {} * {}", a, b)),
    5072
                BinaryOp::Divide => {
    5073
    0
                    if b == 0 {
    5074
    0
                        bail!("Division by zero");
    5075
    0
                    }
    5076
                    // Division always produces a float
    5077
    0
                    Ok(Value::Float(a as f64 / b as f64))
    5078
                }
    5079
                BinaryOp::Modulo => {
    5080
    0
                    if b == 0 {
    5081
    0
                        bail!("Modulo by zero");
    5082
    0
                    }
    5083
    0
                    Ok(Value::Int(a % b))
    5084
                }
    5085
                BinaryOp::Power => {
    5086
    0
                    if b < 0 {
    5087
    0
                        bail!("Negative integer powers not supported in integer context");
    5088
    0
                    }
    5089
    0
                    let exp = u32::try_from(b).map_err(|_| anyhow::anyhow!("Power exponent too large"))?;
    5090
    0
                    a.checked_pow(exp)
    5091
    0
                        .map(Value::Int)
    5092
    0
                        .ok_or_else(|| anyhow::anyhow!("Integer overflow in power: {} ^ {}", a, b))
    5093
                }
    5094
    0
                _ => bail!("Invalid integer arithmetic operation: {:?}", op),
    5095
            }
    5096
    0
        }
    5097
    5098
        /// Evaluate float arithmetic operations (complexity: 5)
    5099
    0
        fn evaluate_float_arithmetic(a: f64, op: BinaryOp, b: f64) -> Result<Value> {
    5100
    0
            match op {
    5101
    0
                BinaryOp::Add => Ok(Value::Float(a + b)),
    5102
    0
                BinaryOp::Subtract => Ok(Value::Float(a - b)),
    5103
    0
                BinaryOp::Multiply => Ok(Value::Float(a * b)),
    5104
                BinaryOp::Divide => {
    5105
    0
                    if b == 0.0 {
    5106
    0
                        bail!("Division by zero");
    5107
    0
                    }
    5108
    0
                    Ok(Value::Float(a / b))
    5109
                }
    5110
    0
                BinaryOp::Power => Ok(Value::Float(a.powf(b))),
    5111
    0
                _ => bail!("Invalid float arithmetic operation: {:?}", op),
    5112
            }
    5113
    0
        }
    5114
    5115
        /// Evaluate comparison operations (complexity: 6)
    5116
    0
        fn evaluate_comparison(lhs: &Value, op: BinaryOp, rhs: &Value) -> Result<Value> {
    5117
    0
            match (lhs, rhs) {
    5118
    0
                (Value::Int(a), Value::Int(b)) => match op {
    5119
    0
                    BinaryOp::Less => Ok(Value::Bool(a < b)),
    5120
    0
                    BinaryOp::LessEqual => Ok(Value::Bool(a <= b)),
    5121
    0
                    BinaryOp::Greater => Ok(Value::Bool(a > b)),
    5122
    0
                    BinaryOp::GreaterEqual => Ok(Value::Bool(a >= b)),
    5123
    0
                    BinaryOp::Equal => Ok(Value::Bool(a == b)),
    5124
    0
                    BinaryOp::NotEqual => Ok(Value::Bool(a != b)),
    5125
    0
                    _ => bail!("Invalid integer comparison: {:?}", op),
    5126
                },
    5127
    0
                (Value::String(a), Value::String(b)) => match op {
    5128
    0
                    BinaryOp::Equal => Ok(Value::Bool(a == b)),
    5129
    0
                    BinaryOp::NotEqual => Ok(Value::Bool(a != b)),
    5130
    0
                    _ => bail!("Invalid string comparison: {:?}", op),
    5131
                },
    5132
    0
                (Value::Bool(a), Value::Bool(b)) => match op {
    5133
    0
                    BinaryOp::Equal => Ok(Value::Bool(a == b)),
    5134
    0
                    BinaryOp::NotEqual => Ok(Value::Bool(a != b)),
    5135
    0
                    _ => bail!("Invalid boolean comparison: {:?}", op),
    5136
                },
    5137
                // Float comparisons
    5138
    0
                (Value::Float(a), Value::Float(b)) => match op {
    5139
    0
                    BinaryOp::Less => Ok(Value::Bool(a < b)),
    5140
    0
                    BinaryOp::LessEqual => Ok(Value::Bool(a <= b)),
    5141
    0
                    BinaryOp::Greater => Ok(Value::Bool(a > b)),
    5142
    0
                    BinaryOp::GreaterEqual => Ok(Value::Bool(a >= b)),
    5143
    0
                    BinaryOp::Equal => Ok(Value::Bool((a - b).abs() < f64::EPSILON)),
    5144
    0
                    BinaryOp::NotEqual => Ok(Value::Bool((a - b).abs() >= f64::EPSILON)),
    5145
    0
                    _ => bail!("Invalid float comparison: {:?}", op),
    5146
                },
    5147
                // Mixed Int/Float comparisons - coerce to Float
    5148
    0
                (Value::Int(a), Value::Float(b)) => match op {
    5149
    0
                    BinaryOp::Less => Ok(Value::Bool((*a as f64) < *b)),
    5150
    0
                    BinaryOp::LessEqual => Ok(Value::Bool((*a as f64) <= *b)),
    5151
    0
                    BinaryOp::Greater => Ok(Value::Bool((*a as f64) > *b)),
    5152
    0
                    BinaryOp::GreaterEqual => Ok(Value::Bool((*a as f64) >= *b)),
    5153
    0
                    BinaryOp::Equal => Ok(Value::Bool(((*a as f64) - *b).abs() < f64::EPSILON)),
    5154
    0
                    BinaryOp::NotEqual => Ok(Value::Bool(((*a as f64) - *b).abs() >= f64::EPSILON)),
    5155
    0
                    _ => bail!("Invalid mixed int/float comparison: {:?}", op),
    5156
                },
    5157
                // Mixed Float/Int comparisons - coerce to Float
    5158
    0
                (Value::Float(a), Value::Int(b)) => match op {
    5159
    0
                    BinaryOp::Less => Ok(Value::Bool(*a < (*b as f64))),
    5160
    0
                    BinaryOp::LessEqual => Ok(Value::Bool(*a <= (*b as f64))),
    5161
    0
                    BinaryOp::Greater => Ok(Value::Bool(*a > (*b as f64))),
    5162
    0
                    BinaryOp::GreaterEqual => Ok(Value::Bool(*a >= (*b as f64))),
    5163
    0
                    BinaryOp::Equal => Ok(Value::Bool((*a - (*b as f64)).abs() < f64::EPSILON)),
    5164
    0
                    BinaryOp::NotEqual => Ok(Value::Bool((*a - (*b as f64)).abs() >= f64::EPSILON)),
    5165
    0
                    _ => bail!("Invalid mixed float/int comparison: {:?}", op),
    5166
                },
    5167
    0
                _ => bail!("Type mismatch in comparison: {:?} vs {:?}", lhs, rhs),
    5168
            }
    5169
    0
        }
    5170
    5171
        /// Evaluate bitwise operations (complexity: 4)
    5172
    0
        fn evaluate_bitwise(a: i64, op: BinaryOp, b: i64) -> Result<Value> {
    5173
    0
            match op {
    5174
    0
                BinaryOp::BitwiseAnd => Ok(Value::Int(a & b)),
    5175
    0
                BinaryOp::BitwiseOr => Ok(Value::Int(a | b)),
    5176
    0
                BinaryOp::BitwiseXor => Ok(Value::Int(a ^ b)),
    5177
    0
                BinaryOp::LeftShift => Ok(Value::Int(a << b)),
    5178
    0
                _ => bail!("Invalid bitwise operation: {:?}", op),
    5179
            }
    5180
    0
        }
    5181
    5182
    0
        fn evaluate_binary(lhs: &Value, op: BinaryOp, rhs: &Value) -> Result<Value> {
    5183
    0
            match (lhs, op, rhs) {
    5184
                // Integer arithmetic
    5185
    0
                (Value::Int(a), op, Value::Int(b)) if matches!(op,
    5186
                    BinaryOp::Add | BinaryOp::Subtract | BinaryOp::Multiply |
    5187
                    BinaryOp::Divide | BinaryOp::Modulo | BinaryOp::Power) => {
    5188
    0
                    Self::evaluate_integer_arithmetic(*a, op, *b)
    5189
                }
    5190
    5191
                // Float arithmetic
    5192
    0
                (Value::Float(a), op, Value::Float(b)) if matches!(op,
    5193
                    BinaryOp::Add | BinaryOp::Subtract | BinaryOp::Multiply |
    5194
                    BinaryOp::Divide | BinaryOp::Power) => {
    5195
    0
                    Self::evaluate_float_arithmetic(*a, op, *b)
    5196
                }
    5197
    5198
                // Mixed Int/Float arithmetic - coerce to Float
    5199
    0
                (Value::Int(a), op, Value::Float(b)) if matches!(op,
    5200
                    BinaryOp::Add | BinaryOp::Subtract | BinaryOp::Multiply |
    5201
                    BinaryOp::Divide | BinaryOp::Power) => {
    5202
    0
                    Self::evaluate_float_arithmetic(*a as f64, op, *b)
    5203
                }
    5204
    5205
                // Mixed Float/Int arithmetic - coerce to Float
    5206
    0
                (Value::Float(a), op, Value::Int(b)) if matches!(op,
    5207
                    BinaryOp::Add | BinaryOp::Subtract | BinaryOp::Multiply |
    5208
                    BinaryOp::Divide | BinaryOp::Power) => {
    5209
    0
                    Self::evaluate_float_arithmetic(*a, op, *b as f64)
    5210
                }
    5211
    5212
                // String concatenation - optimized with pre-allocation
    5213
    0
                (Value::String(a), BinaryOp::Add, Value::String(b)) => {
    5214
    0
                    let mut result = String::with_capacity(a.len() + b.len());
    5215
    0
                    result.push_str(a);
    5216
    0
                    result.push_str(b);
    5217
    0
                    Self::ok_string(result)
    5218
                }
    5219
    5220
                // Comparisons
    5221
    0
                (lhs, op, rhs) if matches!(op,
    5222
                    BinaryOp::Less | BinaryOp::LessEqual | BinaryOp::Greater |
    5223
                    BinaryOp::GreaterEqual | BinaryOp::Equal | BinaryOp::NotEqual) => {
    5224
    0
                    Self::evaluate_comparison(lhs, op, rhs)
    5225
                }
    5226
    5227
                // Boolean logic
    5228
    0
                (Value::Bool(a), BinaryOp::And, Value::Bool(b)) => Ok(Value::Bool(*a && *b)),
    5229
    0
                (Value::Bool(a), BinaryOp::Or, Value::Bool(b)) => Ok(Value::Bool(*a || *b)),
    5230
    5231
                // Null coalescing
    5232
    0
                (Value::Nil, BinaryOp::NullCoalesce, rhs) => Ok(rhs.clone()),
    5233
    0
                (lhs, BinaryOp::NullCoalesce, _) => Ok(lhs.clone()),
    5234
    5235
                // Bitwise operations
    5236
    0
                (Value::Int(a), op, Value::Int(b)) if matches!(op,
    5237
                    BinaryOp::BitwiseAnd | BinaryOp::BitwiseOr |
    5238
                    BinaryOp::BitwiseXor | BinaryOp::LeftShift) => {
    5239
    0
                    Self::evaluate_bitwise(*a, op, *b)
    5240
                }
    5241
    5242
    0
                _ => bail!(
    5243
    0
                    "Type mismatch in binary operation: {:?} {:?} {:?}",
    5244
                    lhs,
    5245
                    op,
    5246
                    rhs
    5247
                ),
    5248
            }
    5249
    0
        }
    5250
    5251
        /// Evaluate unary operations
    5252
    0
        fn evaluate_unary(op: UnaryOp, val: &Value) -> Result<Value> {
    5253
            use Value::{Bool, Float, Int};
    5254
    5255
    0
            match (op, val) {
    5256
    0
                (UnaryOp::Negate, Int(n)) => Ok(Int(-n)),
    5257
    0
                (UnaryOp::Negate, Float(f)) => Ok(Float(-f)),
    5258
    0
                (UnaryOp::Not, Bool(b)) => Ok(Bool(!b)),
    5259
    0
                (UnaryOp::BitwiseNot, Int(n)) => Ok(Int(!n)),
    5260
    0
                (UnaryOp::Reference, v) => {
    5261
                    // References in the REPL context just return the value
    5262
                    // In a real implementation, this would create a reference/pointer
    5263
                    // For now, we'll just return the value as references are primarily
    5264
                    // useful for the transpiled code, not the interpreted REPL
    5265
    0
                    Ok(v.clone())
    5266
                }
    5267
    0
                _ => bail!("Type mismatch in unary operation: {:?} {:?}", op, val),
    5268
            }
    5269
    0
        }
    5270
    5271
        /// Run the interactive REPL
    5272
        ///
    5273
        /// # Errors
    5274
        ///
    5275
        /// Returns an error if:
    5276
        /// - Readline initialization fails
    5277
        /// - User input cannot be read
    5278
        /// - Commands fail to execute
    5279
    0
        pub fn run(&mut self) -> Result<()> {
    5280
    0
            println!();
    5281
    5282
    0
            let mut rl = self.setup_readline_editor()?;
    5283
    0
            let mut multiline_state = MultilineState::new();
    5284
    5285
            loop {
    5286
    0
                let prompt = self.format_prompt(multiline_state.in_multiline);
    5287
    0
                let readline = rl.readline(&prompt);
    5288
    5289
    0
                match readline {
    5290
    0
                    Ok(line) => {
    5291
    0
                        if self.process_input_line(&line, &mut rl, &mut multiline_state)? {
    5292
    0
                            break; // :quit was executed
    5293
    0
                        }
    5294
                    }
    5295
    0
                    Err(ReadlineError::Interrupted) => {
    5296
    0
                        println!("\nUse :quit to exit");
    5297
    0
                    }
    5298
                    Err(ReadlineError::Eof) => {
    5299
    0
                        println!("\nGoodbye!");
    5300
    0
                        break;
    5301
                    }
    5302
    0
                    Err(err) => {
    5303
    0
                        eprintln!("Error: {err:?}");
    5304
    0
                        break;
    5305
                    }
    5306
                }
    5307
            }
    5308
    5309
            // Save history
    5310
    0
            let history_path = self.temp_dir.join("history.txt");
    5311
    0
            let _ = rl.save_history(&history_path);
    5312
    0
            Ok(())
    5313
    0
        }
    5314
    5315
        /// Handle REPL commands and return output as string (for testing)
    5316
        // Helper functions for command handling (complexity < 10 each)
    5317
        // ========================================================================
    5318
    5319
        /// Handle :quit command (complexity: 3)
    5320
    0
        fn handle_quit_command(&mut self) -> (bool, String) {
    5321
    0
            if self.mode == ReplMode::Normal {
    5322
                // In normal mode, :quit exits REPL
    5323
    0
                (true, String::new())
    5324
            } else {
    5325
                // In a special mode, :quit returns to normal
    5326
    0
                self.mode = ReplMode::Normal;
    5327
    0
                (false, "Returned to normal mode".to_string())
    5328
            }
    5329
    0
        }
    5330
    5331
        /// Handle :history command (complexity: 3)
    5332
    0
        fn handle_history_command(&self) -> String {
    5333
    0
            if self.history.is_empty() {
    5334
    0
                "No history".to_string()
    5335
            } else {
    5336
    0
                let mut output = String::new();
    5337
    0
                for (i, item) in self.history.iter().enumerate() {
    5338
    0
                    output.push_str(&format!("{}: {}\n", i + 1, item));
    5339
    0
                }
    5340
    0
                output
    5341
            }
    5342
    0
        }
    5343
    5344
        /// Handle :clear command (complexity: 2)
    5345
    0
        fn handle_clear_command(&mut self) -> String {
    5346
    0
            self.history.clear();
    5347
    0
            self.definitions.clear();
    5348
    0
            self.bindings.clear();
    5349
    0
            self.result_history.clear();
    5350
    0
            "Session cleared".to_string()
    5351
    0
        }
    5352
    5353
        /// Handle :bindings/:env command (complexity: 3)
    5354
    0
        fn handle_bindings_command(&self) -> String {
    5355
    0
            if self.bindings.is_empty() {
    5356
    0
                "No bindings".to_string()
    5357
            } else {
    5358
    0
                let mut output = String::new();
    5359
    0
                for (name, value) in &self.bindings {
    5360
    0
                    output.push_str(&format!("{name}: {value}\n"));
    5361
    0
                }
    5362
    0
                output
    5363
            }
    5364
    0
        }
    5365
    5366
        /// Handle :compile command (complexity: 2)
    5367
    0
        fn handle_compile_command(&mut self) -> String {
    5368
    0
            match self.compile_session() {
    5369
    0
                Ok(()) => "Session compiled successfully".to_string(),
    5370
    0
                Err(e) => format!("Compilation failed: {e}"),
    5371
            }
    5372
    0
        }
    5373
    5374
        /// Handle :load command (complexity: 3)
    5375
    0
        fn handle_load_command(&mut self, parts: &[&str]) -> String {
    5376
    0
            if parts.len() == 2 {
    5377
    0
                match self.load_file(parts[1]) {
    5378
    0
                    Ok(()) => format!("Loaded file: {}", parts[1]),
    5379
    0
                    Err(e) => format!("Failed to load file: {e}"),
    5380
                }
    5381
            } else {
    5382
    0
                "Usage: :load <filename>".to_string()
    5383
            }
    5384
    0
        }
    5385
    5386
        /// Handle :save command (complexity: 3)
    5387
    0
        fn handle_save_command(&mut self, command: &str) -> String {
    5388
    0
            let filename = command.strip_prefix(":save").unwrap_or("").trim();
    5389
    0
            if filename.is_empty() {
    5390
    0
                "Usage: :save <filename>".to_string()
    5391
            } else {
    5392
    0
                match self.save_session(filename) {
    5393
    0
                    Ok(()) => format!("Session saved to {filename}"),
    5394
    0
                    Err(e) => format!("Failed to save session: {e}"),
    5395
                }
    5396
            }
    5397
    0
        }
    5398
    5399
        /// Handle :export command (complexity: 3)
    5400
    0
        fn handle_export_command(&mut self, command: &str) -> String {
    5401
    0
            let filename = command.strip_prefix(":export").unwrap_or("").trim();
    5402
    0
            if filename.is_empty() {
    5403
    0
                "Usage: :export <filename>".to_string()
    5404
            } else {
    5405
    0
                match self.export_session(filename) {
    5406
    0
                    Ok(()) => format!("Session exported to clean script: {filename}"),
    5407
    0
                    Err(e) => format!("Failed to export session: {e}"),
    5408
                }
    5409
            }
    5410
    0
        }
    5411
    5412
        /// Handle :type command (complexity: 3)
    5413
    0
        fn handle_type_command(&mut self, command: &str) -> String {
    5414
    0
            let expr = command.strip_prefix(":type").unwrap_or("").trim();
    5415
    0
            if expr.is_empty() {
    5416
    0
                "Usage: :type <expression>".to_string()
    5417
            } else {
    5418
    0
                self.get_type_info_with_bindings(expr)
    5419
            }
    5420
    0
        }
    5421
    5422
        /// Handle :ast command (complexity: 3)
    5423
    0
        fn handle_ast_command(command: &str) -> String {
    5424
    0
            let expr = command.strip_prefix(":ast").unwrap_or("").trim();
    5425
    0
            if expr.is_empty() {
    5426
    0
                "Usage: :ast <expression>".to_string()
    5427
            } else {
    5428
    0
                Self::get_ast_info(expr)
    5429
            }
    5430
    0
        }
    5431
    5432
        /// Handle :inspect command (complexity: 3)
    5433
    0
        fn handle_inspect_command(&self, command: &str) -> String {
    5434
    0
            let var_name = command.strip_prefix(":inspect").unwrap_or("").trim();
    5435
    0
            if var_name.is_empty() {
    5436
    0
                "Usage: :inspect <variable>".to_string()
    5437
            } else {
    5438
    0
                self.inspect_value(var_name)
    5439
            }
    5440
    0
        }
    5441
    5442
        /// Handle :reset command (complexity: 2)
    5443
    0
        fn handle_reset_command(&mut self) -> String {
    5444
    0
            self.history.clear();
    5445
    0
            self.definitions.clear();
    5446
    0
            self.bindings.clear();
    5447
    0
            self.result_history.clear();
    5448
    0
            self.memory.reset();
    5449
    0
            "REPL reset to initial state".to_string()
    5450
    0
        }
    5451
    5452
        /// Handle :search command (complexity: 3)
    5453
    0
        fn handle_search_command(&self, command: &str) -> String {
    5454
    0
            let query = command.strip_prefix(":search").unwrap_or("").trim();
    5455
    0
            if query.is_empty() {
    5456
    0
                "Usage: :search <query>\nSearch through command history with fuzzy matching".to_string()
    5457
            } else {
    5458
    0
                self.get_search_results(query)
    5459
            }
    5460
    0
        }
    5461
    5462
        /// Handle mode commands (complexity: 2)
    5463
    0
        fn handle_mode_command(&mut self, mode: ReplMode) -> String {
    5464
    0
            self.mode = mode;
    5465
    0
            format!("Switched to {} mode", mode.prompt())
    5466
    0
        }
    5467
    5468
        /// Dispatch basic REPL commands (complexity: 8)
    5469
    0
        fn dispatch_basic_commands(&mut self, cmd: &str, parts: &[&str]) -> Option<Result<(bool, String)>> {
    5470
    0
            match cmd {
    5471
    0
                ":quit" | ":q" => Some(Ok(self.handle_quit_command())),
    5472
    0
                ":history" => Some(Ok((false, self.handle_history_command()))),
    5473
    0
                ":clear" => Some(Ok((false, self.handle_clear_command()))),
    5474
    0
                ":bindings" | ":env" => Some(Ok((false, self.handle_bindings_command()))),
    5475
    0
                ":compile" => Some(Ok((false, self.handle_compile_command()))),
    5476
    0
                ":load" => Some(Ok((false, self.handle_load_command(parts)))),
    5477
    0
                ":reset" => Some(Ok((false, self.handle_reset_command()))),
    5478
    0
                _ => None,
    5479
            }
    5480
    0
        }
    5481
    5482
        /// Dispatch analysis commands (complexity: 6)
    5483
    0
        fn dispatch_analysis_commands(&mut self, cmd: &str, command: &str) -> Option<Result<(bool, String)>> {
    5484
    0
            if cmd.starts_with(":save") {
    5485
    0
                Some(Ok((false, self.handle_save_command(command))))
    5486
    0
            } else if cmd.starts_with(":export") {
    5487
    0
                Some(Ok((false, self.handle_export_command(command))))
    5488
    0
            } else if cmd.starts_with(":type") {
    5489
    0
                Some(Ok((false, self.handle_type_command(command))))
    5490
    0
            } else if cmd.starts_with(":ast") {
    5491
    0
                Some(Ok((false, Self::handle_ast_command(command))))
    5492
    0
            } else if cmd.starts_with(":inspect") {
    5493
    0
                Some(Ok((false, self.handle_inspect_command(command))))
    5494
    0
            } else if cmd.starts_with(":search") {
    5495
    0
                Some(Ok((false, self.handle_search_command(command))))
    5496
            } else {
    5497
    0
                None
    5498
            }
    5499
    0
        }
    5500
    5501
        /// Dispatch mode switching commands (complexity: 8)
    5502
    0
        fn dispatch_mode_commands(&mut self, cmd: &str, parts: &[&str]) -> Option<Result<(bool, String)>> {
    5503
    0
            match cmd {
    5504
    0
                ":normal" => Some(Ok((false, self.handle_mode_command(ReplMode::Normal)))),
    5505
    0
                ":shell" => Some(Ok((false, self.handle_mode_command(ReplMode::Shell)))),
    5506
    0
                ":pkg" => Some(Ok((false, self.handle_mode_command(ReplMode::Pkg)))),
    5507
    0
                ":sql" => Some(Ok((false, self.handle_mode_command(ReplMode::Sql)))),
    5508
    0
                ":math" => Some(Ok((false, self.handle_mode_command(ReplMode::Math)))),
    5509
    0
                ":debug" => Some(Ok((false, self.handle_mode_command(ReplMode::Debug)))),
    5510
    0
                ":time" => Some(Ok((false, self.handle_mode_command(ReplMode::Time)))),
    5511
    0
                ":test" => Some(Ok((false, self.handle_mode_command(ReplMode::Test)))),
    5512
    0
                ":exit" => Some(Ok((false, self.handle_mode_command(ReplMode::Normal)))),
    5513
    0
                ":help" | ":h" if parts.len() == 1 => {
    5514
    0
                    self.mode = ReplMode::Help;
    5515
    0
                    Some(self.show_help_menu().map(|output| (false, output)))
    5516
                },
    5517
    0
                ":help" if parts.len() > 1 => {
    5518
    0
                    let topic = parts[1];
    5519
    0
                    Some(self.handle_help_command(topic).map(|output| (false, output)))
    5520
                },
    5521
    0
                ":modes" => {
    5522
    0
                    let output = Self::get_modes_list();
    5523
    0
                    Some(Ok((false, output)))
    5524
                },
    5525
    0
                _ => None,
    5526
            }
    5527
    0
        }
    5528
    5529
        /// Get list of available modes (complexity: 1)
    5530
    0
        fn get_modes_list() -> String {
    5531
    0
            let mut output = "Available modes:\n".to_string();
    5532
    0
            output.push_str("  normal - Standard Ruchy evaluation\n");
    5533
    0
            output.push_str("  shell  - Execute shell commands\n");
    5534
    0
            output.push_str("  pkg    - Package management\n");
    5535
    0
            output.push_str("  help   - Interactive help\n");
    5536
    0
            output.push_str("  sql    - SQL queries\n");
    5537
    0
            output.push_str("  math   - Mathematical expressions\n");
    5538
    0
            output.push_str("  debug  - Debug information with traces\n");
    5539
    0
            output.push_str("  time   - Execution timing\n");
    5540
    0
            output.push_str("  test   - Assertions and table tests\n");
    5541
    0
            output.push_str("\nUse :mode_name to switch modes, :normal or :exit to return");
    5542
    0
            output
    5543
    0
        }
    5544
    5545
        /// Main command handler with output (complexity: 6)
    5546
    0
        fn handle_command_with_output(&mut self, command: &str) -> Result<(bool, String)> {
    5547
    0
            let parts: Vec<&str> = command.split_whitespace().collect();
    5548
    0
            let first_cmd = parts.first().copied().unwrap_or("");
    5549
    5550
            // Try basic commands
    5551
    0
            if let Some(result) = self.dispatch_basic_commands(first_cmd, &parts) {
    5552
    0
                return result;
    5553
    0
            }
    5554
    5555
            // Try analysis commands
    5556
    0
            if let Some(result) = self.dispatch_analysis_commands(first_cmd, command) {
    5557
    0
                return result;
    5558
    0
            }
    5559
    5560
            // Try mode commands
    5561
    0
            if let Some(result) = self.dispatch_mode_commands(first_cmd, &parts) {
    5562
    0
                return result;
    5563
    0
            }
    5564
    5565
            // Unknown command
    5566
    0
            Ok((false, format!("Unknown command: {command}\nType :help for available commands")))
    5567
    0
        }
    5568
    5569
        /// Handle session management commands (complexity: 5)
    5570
    0
        fn handle_session_commands(&mut self, cmd: &str) -> Option<Result<bool>> {
    5571
    0
            match cmd {
    5572
    0
                ":history" => {
    5573
    0
                    for (i, item) in self.history.iter().enumerate() {
    5574
    0
                        println!("{}: {}", i + 1, item);
    5575
    0
                    }
    5576
    0
                    Some(Ok(false))
    5577
                }
    5578
    0
                ":clear" => {
    5579
    0
                    self.history.clear();
    5580
    0
                    self.definitions.clear();
    5581
    0
                    self.bindings.clear();
    5582
    0
                    println!("Session cleared");
    5583
    0
                    Some(Ok(false))
    5584
                }
    5585
    0
                ":reset" => {
    5586
    0
                    self.history.clear();
    5587
    0
                    self.definitions.clear();
    5588
    0
                    self.bindings.clear();
    5589
    0
                    self.memory.reset();
    5590
    0
                    println!("REPL reset to initial state");
    5591
    0
                    Some(Ok(false))
    5592
                }
    5593
    0
                ":compile" => Some(self.compile_session().map(|()| false)),
    5594
    0
                _ => None,
    5595
            }
    5596
    0
        }
    5597
    5598
        /// Handle inspection commands (complexity: 4)
    5599
    0
        fn handle_inspection_commands(&mut self, command: &str) -> Option<Result<bool>> {
    5600
    0
            if command.starts_with(":type") {
    5601
    0
                let expr = command.strip_prefix(":type").unwrap_or("").trim();
    5602
    0
                if expr.is_empty() {
    5603
    0
                    println!("Usage: :type <expression>");
    5604
    0
                } else {
    5605
    0
                    Self::show_type(expr);
    5606
    0
                }
    5607
    0
                Some(Ok(false))
    5608
    0
            } else if command.starts_with(":ast") {
    5609
    0
                let expr = command.strip_prefix(":ast").unwrap_or("").trim();
    5610
    0
                if expr.is_empty() {
    5611
    0
                    println!("Usage: :ast <expression>");
    5612
    0
                } else {
    5613
    0
                    Self::show_ast(expr);
    5614
    0
                }
    5615
    0
                Some(Ok(false))
    5616
    0
            } else if command.starts_with(":inspect") {
    5617
    0
                let var_name = command.strip_prefix(":inspect").unwrap_or("").trim();
    5618
    0
                if var_name.is_empty() {
    5619
    0
                    println!("Usage: :inspect <variable>");
    5620
    0
                } else {
    5621
    0
                    println!("{}", self.inspect_value(var_name));
    5622
    0
                }
    5623
    0
                Some(Ok(false))
    5624
    0
            } else if command == ":bindings" || command == ":env" {
    5625
    0
                if self.bindings.is_empty() {
    5626
    0
                    println!("No bindings");
    5627
    0
                } else {
    5628
    0
                    for (name, value) in &self.bindings {
    5629
    0
                        println!("{name}: {value}");
    5630
    0
                    }
    5631
                }
    5632
    0
                Some(Ok(false))
    5633
            } else {
    5634
    0
                None
    5635
            }
    5636
    0
        }
    5637
    5638
        /// Handle file operations (complexity: 4)
    5639
    0
        fn handle_file_operations(&mut self, command: &str, parts: &[&str]) -> Option<Result<bool>> {
    5640
    0
            if command.starts_with(":load") && parts.len() == 2 {
    5641
    0
                Some(self.load_file(parts[1]).map(|()| false))
    5642
    0
            } else if command.starts_with(":save") {
    5643
    0
                let filename = command.strip_prefix(":save").unwrap_or("").trim();
    5644
    0
                if filename.is_empty() {
    5645
    0
                    println!("Usage: :save <filename>");
    5646
    0
                    println!("Save current session to a file");
    5647
    0
                } else {
    5648
    0
                    match self.save_session(filename) {
    5649
    0
                        Ok(()) => println!("Session saved to {}", filename.bright_green()),
    5650
    0
                        Err(e) => eprintln!("Failed to save session: {e}"),
    5651
                    }
    5652
                }
    5653
    0
                Some(Ok(false))
    5654
    0
            } else if command.starts_with(":search") {
    5655
    0
                let query = command.strip_prefix(":search").unwrap_or("").trim();
    5656
    0
                if query.is_empty() {
    5657
    0
                    println!("Usage: :search <query>");
    5658
    0
                    println!("Search through command history with fuzzy matching");
    5659
    0
                } else {
    5660
    0
                    self.search_history(query);
    5661
    0
                }
    5662
    0
                Some(Ok(false))
    5663
            } else {
    5664
    0
                None
    5665
            }
    5666
    0
        }
    5667
    5668
        /// Handle REPL commands (public for testing) (complexity: 7)
    5669
        ///
    5670
        /// # Errors
    5671
        ///
    5672
        /// Returns an error if command execution fails
    5673
    0
        pub fn handle_command(&mut self, command: &str) -> Result<bool> {
    5674
    0
            let parts: Vec<&str> = command.split_whitespace().collect();
    5675
    0
            let first_cmd = parts.first().copied().unwrap_or("");
    5676
    5677
            // Check for quit command
    5678
    0
            if first_cmd == ":quit" || first_cmd == ":q" {
    5679
    0
                return Ok(true);
    5680
    0
            }
    5681
    5682
            // Check for help command
    5683
    0
            if first_cmd == ":help" || first_cmd == ":h" {
    5684
    0
                Self::print_help();
    5685
    0
                return Ok(false);
    5686
    0
            }
    5687
    5688
            // Try session management commands
    5689
    0
            if let Some(result) = self.handle_session_commands(first_cmd) {
    5690
    0
                return result;
    5691
    0
            }
    5692
    5693
            // Try inspection commands
    5694
    0
            if let Some(result) = self.handle_inspection_commands(command) {
    5695
    0
                return result;
    5696
    0
            }
    5697
    5698
            // Try file operations
    5699
    0
            if let Some(result) = self.handle_file_operations(command, &parts) {
    5700
    0
                return result;
    5701
    0
            }
    5702
    5703
            // Unknown command
    5704
    0
            eprintln!("Unknown command: {command}");
    5705
    0
            Self::print_help();
    5706
    0
            Ok(false)
    5707
    0
        }
    5708
    5709
        /// Get help text as string
    5710
    0
        fn get_help_text() -> String {
    5711
    0
            let mut help = String::new();
    5712
    0
            help.push_str("Available commands:\n");
    5713
    0
            help.push_str("  :help, :h       - Show this help message\n");
    5714
    0
            help.push_str("  :quit, :q       - Exit the REPL\n");
    5715
    0
            help.push_str("  :history        - Show evaluation history\n");
    5716
    0
            help.push_str("  :search <query> - Search history with fuzzy matching\n");
    5717
    0
            help.push_str("  :clear          - Clear definitions and history\n");
    5718
    0
            help.push_str("  :reset          - Full reset to initial state\n");
    5719
    0
            help.push_str("  :bindings, :env - Show current variable bindings\n");
    5720
    0
            help.push_str("  :type <expr>    - Show type of expression\n");
    5721
    0
            help.push_str("  :ast <expr>     - Show AST of expression\n");
    5722
    0
            help.push_str("  :inspect <var>  - Inspect a variable in detail\n");
    5723
    0
            help.push_str("  :compile        - Compile and run the session\n");
    5724
    0
            help.push_str("  :load <file>    - Load and evaluate a file\n");
    5725
    0
            help.push_str("  :save <file>    - Save session to file\n");
    5726
    0
            help.push_str("  :export <file>  - Export session to clean script\n");
    5727
    0
            help
    5728
    0
        }
    5729
    5730
        /// Print help message
    5731
    0
        fn print_help() {
    5732
    0
            println!("{}", Self::get_help_text());
    5733
    0
        }
    5734
    5735
        /// Get type information as string
    5736
    0
        fn get_type_info(expr: &str) -> String {
    5737
    0
            match Parser::new(expr).parse() {
    5738
    0
                Ok(ast) => {
    5739
                    // Create an inference context for type checking
    5740
    0
                    let mut ctx = crate::middleend::InferenceContext::new();
    5741
    5742
                    // Infer the type
    5743
    0
                    match ctx.infer(&ast) {
    5744
    0
                        Ok(ty) => format!("Type: {ty}"),
    5745
    0
                        Err(e) => format!("Type inference error: {e}"),
    5746
                    }
    5747
                }
    5748
    0
                Err(e) => format!("Parse error: {e}"),
    5749
            }
    5750
    0
        }
    5751
    5752
        /// Get type information with REPL bindings context
    5753
    0
        fn get_type_info_with_bindings(&self, expr: &str) -> String {
    5754
            // If the expression is a simple identifier, check bindings first
    5755
    0
            if let Ok(_) = Parser::new(expr).parse() {
    5756
    0
                if let Some(value) = self.bindings.get(expr) {
    5757
                    // Infer type from the value
    5758
    0
                    let type_name = match value {
    5759
    0
                        Value::Int(_) => "Integer",
    5760
    0
                        Value::Float(_) => "Float",
    5761
    0
                        Value::String(_) => "String",
    5762
    0
                        Value::Bool(_) => "Bool",
    5763
    0
                        Value::List(_) => "List",
    5764
    0
                        Value::Function { .. } => "Function",
    5765
    0
                        Value::Lambda { .. } => "Lambda",
    5766
    0
                        Value::Object(_) => "Object",
    5767
    0
                        Value::Tuple(_) => "Tuple",
    5768
    0
                        Value::Char(_) => "Char",
    5769
    0
                        Value::DataFrame { .. } => "DataFrame",
    5770
    0
                        Value::HashMap(_) => "HashMap",
    5771
    0
                        Value::HashSet(_) => "HashSet",
    5772
    0
                        Value::Range { .. } => "Range",
    5773
    0
                        Value::EnumVariant { enum_name, variant_name, .. } => {
    5774
    0
                            &format!("{enum_name}::{variant_name}")
    5775
                        }
    5776
    0
                        Value::Unit => "Unit",
    5777
    0
                        Value::Nil => "Nil"
    5778
                    };
    5779
    0
                    return format!("Type: {type_name}");
    5780
    0
                }
    5781
    0
            }
    5782
    5783
            // Fall back to regular type inference
    5784
    0
            Self::get_type_info(expr)
    5785
    0
        }
    5786
    5787
        /// Get AST information as string
    5788
    0
        fn get_ast_info(expr: &str) -> String {
    5789
    0
            match Parser::new(expr).parse() {
    5790
    0
                Ok(ast) => format!("{ast:#?}"),
    5791
    0
                Err(e) => format!("Parse error: {e}"),
    5792
            }
    5793
    0
        }
    5794
    5795
        /// Get search results as string
    5796
    0
        fn get_search_results(&self, query: &str) -> String {
    5797
    0
            let mut results = Vec::new();
    5798
    0
            let query_lower = query.to_lowercase();
    5799
    5800
    0
            for (i, item) in self.history.iter().enumerate() {
    5801
    0
                if item.to_lowercase().contains(&query_lower) {
    5802
    0
                    results.push(format!("{}: {}", i + 1, item));
    5803
    0
                }
    5804
            }
    5805
    5806
    0
            if results.is_empty() {
    5807
    0
                format!("No matches found for '{query}'")
    5808
            } else {
    5809
    0
                results.join("\n")
    5810
            }
    5811
    0
        }
    5812
    5813
        /// Execute a shell command and return its output
    5814
    0
        fn execute_shell_command(&self, command: &str) -> Result<String> {
    5815
            use std::process::Command;
    5816
    5817
            // Execute command through shell
    5818
    0
            let output = Command::new("sh")
    5819
    0
                .arg("-c")
    5820
    0
                .arg(command)
    5821
    0
                .output()
    5822
    0
                .context(format!("Failed to execute shell command: {command}"))?;
    5823
    5824
            // Combine stdout and stderr
    5825
    0
            let stdout = String::from_utf8_lossy(&output.stdout);
    5826
    0
            let stderr = String::from_utf8_lossy(&output.stderr);
    5827
    5828
    0
            if !output.status.success() {
    5829
                // If command failed, return error with stderr
    5830
    0
                if !stderr.is_empty() {
    5831
    0
                    bail!("Shell command failed: {}", stderr);
    5832
    0
                }
    5833
    0
                bail!("Shell command failed with exit code: {:?}", output.status.code());
    5834
    0
            }
    5835
    5836
            // Return stdout (stderr is usually empty for successful commands)
    5837
    0
            Ok(stdout.trim_end().to_string())
    5838
    0
        }
    5839
    5840
        /// Basic introspection with single ?
    5841
    0
        fn basic_introspection(&self, target: &str) -> Result<String> {
    5842
            // Check if target exists in bindings
    5843
    0
            if let Some(value) = self.bindings.get(target) {
    5844
    0
                let type_name = self.get_value_type_name(value);
    5845
    0
                let value_str = self.format_value_brief(value);
    5846
    0
                return Ok(format!("Type: {type_name}\nValue: {value_str}"));
    5847
    0
            }
    5848
    5849
            // Check if it's a builtin function
    5850
    0
            if self.is_builtin_function(target) {
    5851
    0
                return Ok(format!("Type: Builtin Function\nName: {target}"));
    5852
    0
            }
    5853
    5854
            // Try to evaluate the expression and introspect result
    5855
    0
            if let Ok(ast) = Parser::new(target).parse() {
    5856
                // Try to get type information
    5857
    0
                let mut ctx = crate::middleend::InferenceContext::new();
    5858
    0
                if let Ok(ty) = ctx.infer(&ast) {
    5859
    0
                    return Ok(format!("Type: {ty}"));
    5860
    0
                }
    5861
    0
            }
    5862
    5863
    0
            bail!("'{}' is not defined or cannot be introspected", target)
    5864
    0
        }
    5865
    5866
        /// Detailed introspection with double ??
    5867
    0
        fn detailed_introspection(&self, target: &str) -> Result<String> {
    5868
            // Check if target exists in bindings
    5869
    0
            if let Some(value) = self.bindings.get(target) {
    5870
    0
                return Ok(self.format_detailed_introspection(target, value));
    5871
    0
            }
    5872
    5873
            // Check if it's a builtin function
    5874
    0
            if self.is_builtin_function(target) {
    5875
    0
                return Ok(self.format_builtin_help(target));
    5876
    0
            }
    5877
    5878
    0
            bail!("'{}' is not defined or cannot be introspected", target)
    5879
    0
        }
    5880
    5881
        /// Check if a name is a builtin function
    5882
    0
        fn is_builtin_function(&self, name: &str) -> bool {
    5883
    0
            matches!(name, "println" | "print" | "len" | "push" | "pop" | "insert" |
    5884
    0
                           "remove" | "clear" | "contains" | "index_of" | "slice" |
    5885
    0
                           "split" | "join" | "trim" | "to_upper" | "to_lower" |
    5886
    0
                           "replace" | "starts_with" | "ends_with" | "parse" |
    5887
    0
                           "type" | "str" | "int" | "float" | "bool" |
    5888
    0
                           "sqrt" | "pow" | "abs" | "min" | "max" | "floor" | "ceil" | "round")
    5889
    0
        }
    5890
    5891
        /// Get type name for a value
    5892
    0
        fn get_value_type_name(&self, value: &Value) -> &str {
    5893
    0
            match value {
    5894
    0
                Value::Int(_) => "Integer",
    5895
    0
                Value::Float(_) => "Float",
    5896
    0
                Value::String(_) => "String",
    5897
    0
                Value::Bool(_) => "Bool",
    5898
    0
                Value::Char(_) => "Char",
    5899
    0
                Value::List(_) => "List",
    5900
    0
                Value::Tuple(_) => "Tuple",
    5901
    0
                Value::Function { .. } => "Function",
    5902
    0
                Value::Lambda { .. } => "Lambda",
    5903
    0
                Value::Object(_) => "Object",
    5904
    0
                Value::HashMap(_) => "HashMap",
    5905
    0
                Value::HashSet(_) => "HashSet",
    5906
    0
                Value::Range { .. } => "Range",
    5907
    0
                Value::DataFrame { .. } => "DataFrame",
    5908
    0
                Value::EnumVariant { enum_name, variant_name, .. } => {
    5909
                    // Return a static str by leaking - safe for REPL lifetime
    5910
    0
                    Box::leak(format!("{enum_name}::{variant_name}").into_boxed_str())
    5911
                }
    5912
    0
                Value::Unit => "Unit",
    5913
    0
                Value::Nil => "Nil",
    5914
            }
    5915
    0
        }
    5916
    5917
        /// Format value briefly for introspection
    5918
    0
        fn format_value_brief(&self, value: &Value) -> String {
    5919
    0
            match value {
    5920
    0
                Value::List(items) => format!("[{} items]", items.len()),
    5921
    0
                Value::Object(fields) => {
    5922
    0
                    let field_names: Vec<_> = fields.keys().cloned().collect();
    5923
    0
                    format!("{{{}}}",field_names.join(", "))
    5924
                }
    5925
    0
                Value::Function { name, params, .. } => {
    5926
    0
                    format!("fn {}({})", name, params.join(", "))
    5927
                }
    5928
    0
                Value::Lambda { params, .. } => {
    5929
    0
                    format!("|{}| -> ...", params.join(", "))
    5930
                }
    5931
    0
                _ => value.to_string(),
    5932
            }
    5933
    0
        }
    5934
    5935
        /// Format detailed introspection output
    5936
    0
        fn format_detailed_introspection(&self, name: &str, value: &Value) -> String {
    5937
    0
            let mut output = String::new();
    5938
    0
            output.push_str(&format!("Name: {name}\n"));
    5939
    0
            output.push_str(&format!("Type: {}\n", self.get_value_type_name(value)));
    5940
    5941
    0
            match value {
    5942
    0
                Value::Function { name: fn_name, params, body } => {
    5943
    0
                    output.push_str(&format!("Source: fn {}({}) {{\n", fn_name, params.join(", ")));
    5944
    0
                    output.push_str(&format!("  {}\n", self.format_expr_source(body)));
    5945
    0
                    output.push_str("}\n");
    5946
    0
                    output.push_str(&format!("Parameters: {}\n", params.join(", ")));
    5947
    0
                }
    5948
    0
                Value::Lambda { params, body } => {
    5949
    0
                    output.push_str(&format!("Source: |{}| {{\n", params.join(", ")));
    5950
    0
                    output.push_str(&format!("  {}\n", self.format_expr_source(body)));
    5951
    0
                    output.push_str("}\n");
    5952
    0
                    output.push_str(&format!("Parameters: {}\n", params.join(", ")));
    5953
    0
                }
    5954
    0
                Value::Object(fields) => {
    5955
    0
                    output.push_str("Fields:\n");
    5956
    0
                    for (key, val) in fields {
    5957
    0
                        output.push_str(&format!("  {}: {}\n", key, self.get_value_type_name(val)));
    5958
    0
                    }
    5959
                }
    5960
    0
                Value::List(items) => {
    5961
    0
                    output.push_str(&format!("Length: {}\n", items.len()));
    5962
    0
                    if !items.is_empty() {
    5963
    0
                        output.push_str(&format!("First: {}\n", items[0]));
    5964
    0
                        if items.len() > 1 {
    5965
    0
                            output.push_str(&format!("Last: {}\n", items[items.len() - 1]));
    5966
    0
                        }
    5967
    0
                    }
    5968
                }
    5969
    0
                _ => {
    5970
    0
                    output.push_str(&format!("Value: {value}\n"));
    5971
    0
                }
    5972
            }
    5973
    5974
    0
            output
    5975
    0
        }
    5976
    5977
        /// Format expression source code
    5978
    0
        fn format_expr_source(&self, expr: &Expr) -> String {
    5979
            // Format the expression in a more readable way
    5980
    0
            self.expr_to_source_string(expr, 0)
    5981
    0
        }
    5982
    5983
        /// Convert expression to source string
    5984
    0
        fn expr_to_source_string(&self, expr: &Expr, indent: usize) -> String {
    5985
            use crate::frontend::ast::ExprKind;
    5986
    0
            let indent_str = "  ".repeat(indent);
    5987
    5988
    0
            match &expr.kind {
    5989
    0
                ExprKind::Binary { left, op, right } => {
    5990
    0
                    format!("{} {} {}",
    5991
    0
                        self.expr_to_source_string(left, 0),
    5992
                        op,
    5993
    0
                        self.expr_to_source_string(right, 0))
    5994
                }
    5995
    0
                ExprKind::If { condition, then_branch, else_branch } => {
    5996
    0
                    let mut s = format!("if {} {{\n{}{}\n{}}}",
    5997
    0
                        self.expr_to_source_string(condition, 0),
    5998
    0
                        "  ".repeat(indent + 1),
    5999
    0
                        self.expr_to_source_string(then_branch, indent + 1),
    6000
                        indent_str);
    6001
    0
                    if let Some(else_b) = else_branch {
    6002
    0
                        s.push_str(&format!(" else {{\n{}{}\n{}}}",
    6003
    0
                            "  ".repeat(indent + 1),
    6004
    0
                            self.expr_to_source_string(else_b, indent + 1),
    6005
    0
                            indent_str));
    6006
    0
                    }
    6007
    0
                    s
    6008
                }
    6009
    0
                ExprKind::Call { func, args } => {
    6010
    0
                    if let ExprKind::Identifier(name) = &func.kind {
    6011
    0
                        format!("{}({})", name,
    6012
    0
                            args.iter()
    6013
    0
                                .map(|a| self.expr_to_source_string(a, 0))
    6014
    0
                                .collect::<Vec<_>>()
    6015
    0
                                .join(", "))
    6016
                    } else {
    6017
    0
                        "(call ...)".to_string()
    6018
                    }
    6019
                }
    6020
    0
                ExprKind::Identifier(name) => name.clone(),
    6021
    0
                ExprKind::Literal(lit) => format!("{lit:?}"),
    6022
    0
                ExprKind::Block(exprs) => {
    6023
    0
                    if exprs.len() == 1 {
    6024
    0
                        self.expr_to_source_string(&exprs[0], indent)
    6025
                    } else {
    6026
    0
                        exprs.iter()
    6027
    0
                            .map(|e| self.expr_to_source_string(e, indent))
    6028
    0
                            .collect::<Vec<_>>()
    6029
    0
                            .join("; ")
    6030
                    }
    6031
                }
    6032
    0
                _ => format!("{:?}", expr.kind).chars().take(50).collect()
    6033
            }
    6034
    0
        }
    6035
    6036
        /// Format help for builtin functions
    6037
    0
        fn format_builtin_help(&self, name: &str) -> String {
    6038
    0
            match name {
    6039
    0
                "println" => "println(value)\n  Prints a value to stdout with newline\n  Parameters: value - Any value to print".to_string(),
    6040
    0
                "print" => "print(value)\n  Prints a value to stdout without newline\n  Parameters: value - Any value to print".to_string(),
    6041
    0
                "len" => "len(collection)\n  Returns the length of a collection\n  Parameters: collection - List, String, or other collection".to_string(),
    6042
    0
                "type" => "type(value)\n  Returns the type of a value\n  Parameters: value - Any value".to_string(),
    6043
    0
                "str" => "str(value)\n  Converts a value to string\n  Parameters: value - Any value to convert".to_string(),
    6044
    0
                _ => format!("{name}\n  Builtin function\n  (documentation not available)"),
    6045
            }
    6046
    0
        }
    6047
    6048
        /// Evaluate `type()` function
    6049
    0
        fn evaluate_type_function(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    6050
    0
            Self::validate_exact_args("type()", 1, args.len())?;
    6051
    6052
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    6053
    0
            let type_name = self.get_value_type_name(&value);
    6054
    0
            Ok(Value::String(type_name.to_string()))
    6055
    0
        }
    6056
    6057
        /// Evaluate `summary()` function
    6058
    0
        fn evaluate_summary_function(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    6059
    0
            Self::validate_exact_args("summary()", 1, args.len())?;
    6060
    6061
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    6062
    0
            let summary = match &value {
    6063
    0
                Value::List(items) => format!("List with {} items", items.len()),
    6064
    0
                Value::Object(fields) => format!("Object with {} fields", fields.len()),
    6065
    0
                Value::String(s) => format!("String of length {}", s.len()),
    6066
    0
                Value::DataFrame { columns } => format!("DataFrame with {} columns", columns.len()),
    6067
    0
                _ => format!("{} value", self.get_value_type_name(&value)),
    6068
            };
    6069
    0
            Ok(Value::String(summary))
    6070
    0
        }
    6071
    6072
        /// Evaluate `dir()` function
    6073
    0
        fn evaluate_dir_function(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    6074
    0
            Self::validate_exact_args("dir()", 1, args.len())?;
    6075
    6076
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    6077
    0
            let members = match value {
    6078
    0
                Value::Object(fields) => {
    6079
    0
                    fields.keys().cloned().collect::<Vec<_>>()
    6080
                }
    6081
    0
                _ => vec![],
    6082
            };
    6083
    6084
    0
            Ok(Value::String(members.join(", ")))
    6085
    0
        }
    6086
    6087
        /// Evaluate `help()` function
    6088
    0
        fn evaluate_help_function(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    6089
    0
            if args.len() != 1 {
    6090
    0
                bail!("help() expects 1 argument, got {}", args.len());
    6091
    0
            }
    6092
    6093
            // Check if it's a builtin function first
    6094
    0
            if let ExprKind::Identifier(name) = &args[0].kind {
    6095
    0
                if self.is_builtin_function(name) {
    6096
    0
                    return Ok(Value::String(self.format_builtin_help(name)));
    6097
    0
                }
    6098
    0
            }
    6099
    6100
            // Try to evaluate the argument and get its type
    6101
    0
            match self.evaluate_expr(&args[0], deadline, depth + 1) {
    6102
    0
                Ok(value) => {
    6103
    0
                    let help_text = match value {
    6104
    0
                        Value::Function { name, params, .. } => {
    6105
    0
                            format!("Function: {}\nParameters: {}", name, params.join(", "))
    6106
                        }
    6107
    0
                        Value::Lambda { params, .. } => {
    6108
    0
                            format!("Lambda function\nParameters: {}", params.join(", "))
    6109
                        }
    6110
                        _ => {
    6111
    0
                            format!("Type: {}", self.get_value_type_name(&value))
    6112
                        }
    6113
                    };
    6114
    0
                    Ok(Value::String(help_text))
    6115
                }
    6116
                Err(_) => {
    6117
                    // If evaluation fails, just return a generic message
    6118
    0
                    Ok(Value::String("No help available for this value".to_string()))
    6119
                }
    6120
            }
    6121
    0
        }
    6122
    6123
        /// Evaluate `whos()` function - lists all variables with types
    6124
    0
        fn evaluate_whos_function(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    6125
    0
            let filter = if args.len() == 1 {
    6126
                // Get type filter
    6127
    0
                let val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    6128
    0
                if let Value::String(s) = val {
    6129
    0
                    Some(s)
    6130
                } else {
    6131
    0
                    None
    6132
                }
    6133
            } else {
    6134
    0
                None
    6135
            };
    6136
    6137
    0
            let mut output = Vec::new();
    6138
    0
            for (name, value) in &self.bindings {
    6139
    0
                let type_name = self.get_value_type_name(value);
    6140
    0
                if let Some(ref filter_type) = filter {
    6141
    0
                    if type_name != filter_type {
    6142
    0
                        continue;
    6143
    0
                    }
    6144
    0
                }
    6145
    0
                output.push(format!("{name}: {type_name}"));
    6146
            }
    6147
    6148
    0
            Ok(Value::String(output.join("\n")))
    6149
    0
        }
    6150
    6151
        /// Evaluate `who()` function - simple list of variable names
    6152
    0
        fn evaluate_who_function(&mut self, _args: &[Expr], _deadline: Instant, _depth: usize) -> Result<Value> {
    6153
    0
            let names: Vec<_> = self.bindings.keys().cloned().collect();
    6154
    0
            Ok(Value::String(names.join(", ")))
    6155
    0
        }
    6156
    6157
        /// Evaluate clear!() function - clears workspace
    6158
    0
        fn evaluate_clear_bang_function(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    6159
    0
            if args.is_empty() {
    6160
                // Clear all bindings
    6161
    0
                let count = self.bindings.len();
    6162
    0
                self.bindings.clear();
    6163
    0
                Ok(Value::String(format!("Cleared {count} variables")))
    6164
            } else {
    6165
                // Clear matching pattern
    6166
    0
                let pattern = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    6167
    0
                if let Value::String(pat) = pattern {
    6168
    0
                    let mut cleared = 0;
    6169
    0
                    let pattern_prefix = pat.trim_end_matches('*');
    6170
    0
                    let keys_to_remove: Vec<_> = self.bindings.keys()
    6171
    0
                        .filter(|k| k.starts_with(pattern_prefix))
    6172
    0
                        .cloned()
    6173
    0
                        .collect();
    6174
    0
                    for key in keys_to_remove {
    6175
    0
                        self.bindings.remove(&key);
    6176
    0
                        cleared += 1;
    6177
    0
                    }
    6178
    0
                    Ok(Value::String(format!("Cleared {cleared} variables")))
    6179
                } else {
    6180
    0
                    bail!("clear! pattern must be a string")
    6181
                }
    6182
            }
    6183
    0
        }
    6184
    6185
        /// Evaluate `save_image()` function
    6186
    0
        fn evaluate_save_image_function(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    6187
    0
            if args.len() != 1 {
    6188
    0
                bail!("save_image() expects 1 argument (filename), got {}", args.len());
    6189
    0
            }
    6190
    6191
    0
            let filename = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    6192
    0
            if let Value::String(path) = filename {
    6193
                // Generate Ruchy code to recreate workspace
    6194
    0
                let mut content = String::new();
    6195
    0
                content.push_str("// Workspace image\n");
    6196
    0
                content.push_str("// Generated by save_image()\n\n");
    6197
    6198
                // Save all bindings
    6199
    0
                for (name, value) in &self.bindings {
    6200
    0
                    match value {
    6201
    0
                        Value::Int(n) => content.push_str(&format!("let {name}= {n}\n")),
    6202
    0
                        Value::Float(f) => content.push_str(&format!("let {name}= {f}\n")),
    6203
    0
                        Value::String(s) => content.push_str(&format!("let {} = \"{}\"\n", name, s.replace('"', "\\\""))),
    6204
    0
                        Value::Bool(b) => content.push_str(&format!("let {name}= {b}\n")),
    6205
    0
                        Value::List(items) => {
    6206
    0
                            content.push_str(&format!("let {name} = ["));
    6207
    0
                            for (i, item) in items.iter().enumerate() {
    6208
    0
                                if i > 0 { content.push_str(", "); }
    6209
    0
                                content.push_str(&format!("{item}"));
    6210
                            }
    6211
    0
                            content.push_str("]\n");
    6212
                        }
    6213
    0
                        Value::Function { name: fn_name, params, body } => {
    6214
    0
                            content.push_str(&format!("fn {}({}) {{ {} }}\n",
    6215
    0
                                fn_name, params.join(", "),
    6216
    0
                                self.format_expr_source(body)));
    6217
    0
                        }
    6218
    0
                        _ => {} // Skip complex types for now
    6219
                    }
    6220
                }
    6221
    6222
                // Write to file
    6223
    0
                fs::write(&path, content)?;
    6224
    0
                Ok(Value::String(format!("Workspace saved to {path}")))
    6225
            } else {
    6226
    0
                bail!("save_image() requires a string filename")
    6227
            }
    6228
    0
        }
    6229
    6230
        /// Evaluate `workspace()` function
    6231
    0
        fn evaluate_workspace_function(&mut self, _args: &[Expr], _deadline: Instant, _depth: usize) -> Result<Value> {
    6232
    0
            let var_count = self.bindings.len();
    6233
    0
            let func_count = self.bindings.values()
    6234
    0
                .filter(|v| matches!(v, Value::Function { .. } | Value::Lambda { .. }))
    6235
    0
                .count();
    6236
    6237
    0
            Ok(Value::String(format!("{var_count}variables, {func_count} functions")))
    6238
    0
        }
    6239
    6240
        /// Evaluate `locals()` function
    6241
    0
        fn evaluate_locals_function(&mut self, _args: &[Expr], _deadline: Instant, _depth: usize) -> Result<Value> {
    6242
            // For now, same as globals since we don't have proper scoping
    6243
    0
            self.evaluate_globals_function(&[], Instant::now(), 0)
    6244
    0
        }
    6245
    6246
        /// Evaluate `globals()` function
    6247
    0
        fn evaluate_globals_function(&mut self, _args: &[Expr], _deadline: Instant, _depth: usize) -> Result<Value> {
    6248
    0
            let mut output = Vec::new();
    6249
    0
            for (name, value) in &self.bindings {
    6250
    0
                output.push(format!("{}: {}", name, self.get_value_type_name(value)));
    6251
    0
            }
    6252
    0
            Ok(Value::String(output.join("\n")))
    6253
    0
        }
    6254
    6255
        /// Evaluate `reset()` function
    6256
    0
        fn evaluate_reset_function(&mut self, _args: &[Expr], _deadline: Instant, _depth: usize) -> Result<Value> {
    6257
    0
            self.bindings.clear();
    6258
    0
            self.history.clear();
    6259
    0
            self.result_history.clear();
    6260
    0
            self.definitions.clear();
    6261
    0
            self.memory.reset();
    6262
    0
            Ok(Value::String("Workspace reset".to_string()))
    6263
    0
        }
    6264
    6265
        /// Evaluate `del()` function
    6266
    0
        fn evaluate_del_function(&mut self, args: &[Expr], _deadline: Instant, _depth: usize) -> Result<Value> {
    6267
    0
            if args.len() != 1 {
    6268
    0
                bail!("del() expects 1 argument, got {}", args.len());
    6269
    0
            }
    6270
    6271
            // Get the name to delete
    6272
    0
            if let ExprKind::Identifier(name) = &args[0].kind {
    6273
    0
                if self.bindings.remove(name).is_some() {
    6274
    0
                    Self::ok_unit()
    6275
                } else {
    6276
    0
                    bail!("Variable '{}' not found", name)
    6277
                }
    6278
            } else {
    6279
    0
                bail!("del() requires a variable name")
    6280
            }
    6281
    0
        }
    6282
    6283
        /// Evaluate `exists()` function
    6284
    0
        fn evaluate_exists_function(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    6285
    0
            if args.len() != 1 {
    6286
    0
                bail!("exists() expects 1 argument, got {}", args.len());
    6287
    0
            }
    6288
    6289
    0
            let name_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    6290
    0
            if let Value::String(name) = name_val {
    6291
    0
                Ok(Value::Bool(self.bindings.contains_key(&name)))
    6292
            } else {
    6293
    0
                bail!("exists() requires a string variable name")
    6294
            }
    6295
    0
        }
    6296
    6297
        /// Evaluate `memory_info()` function
    6298
    0
        fn evaluate_memory_info_function(&mut self, _args: &[Expr], _deadline: Instant, _depth: usize) -> Result<Value> {
    6299
    0
            let current = self.memory.current;
    6300
    0
            let max = self.memory.max_size;
    6301
    0
            let kb = current / 1024;
    6302
    0
            Ok(Value::String(format!("Memory: {current} bytes ({kb} KB) / {max} max")))
    6303
    0
        }
    6304
    6305
        /// Evaluate `time_info()` function
    6306
    0
        fn evaluate_time_info_function(&mut self, _args: &[Expr], _deadline: Instant, _depth: usize) -> Result<Value> {
    6307
            // For simplicity, just return a placeholder
    6308
    0
            Ok(Value::String("Session time: active".to_string()))
    6309
    0
        }
    6310
    6311
        /// Show the type of an expression
    6312
    0
        fn show_type(expr: &str) {
    6313
    0
            match Parser::new(expr).parse() {
    6314
    0
                Ok(ast) => {
    6315
                    // Create an inference context for type checking
    6316
    0
                    let mut ctx = crate::middleend::InferenceContext::new();
    6317
    6318
                    // Infer the type
    6319
    0
                    match ctx.infer(&ast) {
    6320
    0
                        Ok(ty) => {
    6321
    0
                            println!("Type: {ty}");
    6322
    0
                        }
    6323
    0
                        Err(e) => {
    6324
    0
                            eprintln!("Type inference error: {e}");
    6325
    0
                        }
    6326
                    }
    6327
                }
    6328
    0
                Err(e) => {
    6329
    0
                    eprintln!("Parse error: {e}");
    6330
    0
                }
    6331
            }
    6332
    0
        }
    6333
    6334
        /// Show the AST of an expression
    6335
    0
        fn show_ast(expr: &str) {
    6336
    0
            match Parser::new(expr).parse() {
    6337
    0
                Ok(ast) => {
    6338
    0
                    println!("{ast:#?}");
    6339
    0
                }
    6340
    0
                Err(e) => {
    6341
    0
                    eprintln!("Parse error: {e}");
    6342
    0
                }
    6343
            }
    6344
    0
        }
    6345
    6346
        /// Check if input needs continuation (incomplete expression)
    6347
    0
        pub fn needs_continuation(input: &str) -> bool {
    6348
    0
            let trimmed = input.trim();
    6349
    6350
            // Empty input doesn't need continuation
    6351
    0
            if trimmed.is_empty() {
    6352
    0
                return false;
    6353
    0
            }
    6354
    6355
            // Count braces, brackets, and parentheses
    6356
    0
            let mut brace_depth = 0;
    6357
    0
            let mut bracket_depth = 0;
    6358
    0
            let mut paren_depth = 0;
    6359
    0
            let mut in_string = false;
    6360
    0
            let mut escape_next = false;
    6361
    6362
    0
            for ch in trimmed.chars() {
    6363
    0
                if escape_next {
    6364
    0
                    escape_next = false;
    6365
    0
                    continue;
    6366
    0
                }
    6367
    6368
    0
                match ch {
    6369
    0
                    '\\' if in_string => escape_next = true,
    6370
    0
                    '"' => in_string = !in_string,
    6371
    0
                    '{' if !in_string => brace_depth += 1,
    6372
    0
                    '}' if !in_string => brace_depth -= 1,
    6373
    0
                    '[' if !in_string => bracket_depth += 1,
    6374
    0
                    ']' if !in_string => bracket_depth -= 1,
    6375
    0
                    '(' if !in_string => paren_depth += 1,
    6376
    0
                    ')' if !in_string => paren_depth -= 1,
    6377
    0
                    _ => {}
    6378
                }
    6379
            }
    6380
    6381
            // Need continuation if any delimiters are unmatched
    6382
    0
            brace_depth > 0 || bracket_depth > 0 || paren_depth > 0 || in_string ||
    6383
            // Or if line ends with certain tokens that expect continuation
    6384
    0
            trimmed.ends_with('=') ||
    6385
    0
            trimmed.ends_with("->") ||
    6386
    0
            trimmed.ends_with("=>") ||
    6387
    0
            trimmed.ends_with(',') ||
    6388
    0
            trimmed.ends_with('+') ||
    6389
    0
            trimmed.ends_with('-') ||
    6390
    0
            trimmed.ends_with('*') ||
    6391
    0
            trimmed.ends_with('/') ||
    6392
    0
            trimmed.ends_with("&&") ||
    6393
    0
            trimmed.ends_with("||") ||
    6394
    0
            trimmed.ends_with(">>")
    6395
    0
        }
    6396
    6397
        /// Compile and run the current session
    6398
    0
        fn compile_session(&mut self) -> Result<()> {
    6399
            use std::fmt::Write;
    6400
    6401
    0
            if self.history.is_empty() {
    6402
    0
                println!("No expressions to compile");
    6403
    0
                return Ok(());
    6404
    0
            }
    6405
    6406
    0
            println!("Compiling session...");
    6407
    6408
            // Generate Rust code for all expressions
    6409
    0
            let mut rust_code = String::new();
    6410
    0
            rust_code.push_str("#![allow(unused)]\n");
    6411
    0
            rust_code.push_str("fn main() {\n");
    6412
    6413
    0
            for expr in &self.history {
    6414
    0
                match Parser::new(expr).parse() {
    6415
    0
                    Ok(ast) => {
    6416
    0
                        let transpiled = self.transpiler.transpile(&ast)?;
    6417
    0
                        let transpiled_str = transpiled.to_string();
    6418
                        // Check if this is already a print statement that should be executed directly
    6419
    0
                        let trimmed = transpiled_str.trim();
    6420
    0
                        if trimmed.starts_with("println !")
    6421
    0
                            || trimmed.starts_with("print !")
    6422
    0
                            || trimmed.starts_with("println!")
    6423
    0
                            || trimmed.starts_with("print!")
    6424
    0
                        {
    6425
    0
                            let _ = writeln!(&mut rust_code, "    {transpiled};");
    6426
    0
                        } else {
    6427
    0
                            let _ = writeln!(
    6428
    0
                                &mut rust_code,
    6429
    0
                                "    println!(\"{{:?}}\", {{{transpiled}}});"
    6430
    0
                            );
    6431
    0
                        }
    6432
                    }
    6433
    0
                    Err(e) => {
    6434
    0
                        eprintln!("Failed to parse '{expr}': {e}");
    6435
    0
                    }
    6436
                }
    6437
            }
    6438
    6439
    0
            rust_code.push_str("}\n");
    6440
    6441
            // Write to working file
    6442
    0
            self.session_counter += 1;
    6443
    0
            let file_name = format!("session_{}.rs", self.session_counter);
    6444
    0
            let file_path = self.temp_dir.join(&file_name);
    6445
    0
            fs::write(&file_path, rust_code)?;
    6446
    6447
            // Compile with rustc
    6448
    0
            let output = Command::new("rustc")
    6449
    0
                .arg(&file_path)
    6450
    0
                .arg("-o")
    6451
    0
                .arg(
    6452
    0
                    self.temp_dir
    6453
    0
                        .join(format!("session_{}", self.session_counter)),
    6454
    0
                )
    6455
    0
                .current_dir(&self.temp_dir)
    6456
    0
                .output()
    6457
    0
                .context("Failed to run rustc")?;
    6458
    6459
    0
            if !output.status.success() {
    6460
    0
                eprintln!(
    6461
    0
                    "Compilation failed:\n{}",
    6462
    0
                    String::from_utf8_lossy(&output.stderr)
    6463
                );
    6464
    0
                return Ok(());
    6465
    0
            }
    6466
    6467
            // Run the compiled program
    6468
    0
            let exe_path = self
    6469
    0
                .temp_dir
    6470
    0
                .join(format!("session_{}", self.session_counter));
    6471
    0
            let output = Command::new(&exe_path)
    6472
    0
                .output()
    6473
    0
                .context("Failed to run compiled program")?;
    6474
    6475
    0
            println!("{}", "Output:".bright_green());
    6476
    0
            print!("{}", String::from_utf8_lossy(&output.stdout));
    6477
    6478
    0
            if !output.stderr.is_empty() {
    6479
    0
                eprintln!("{}", String::from_utf8_lossy(&output.stderr));
    6480
    0
            }
    6481
    6482
    0
            Ok(())
    6483
    0
        }
    6484
    6485
        /// Search through command history with fuzzy matching
    6486
    0
        fn search_history(&self, query: &str) {
    6487
    0
            let query_lower = query.to_lowercase();
    6488
    0
            let mut matches = Vec::new();
    6489
    6490
            // Simple fuzzy matching: contains all characters in order
    6491
    0
            for (i, item) in self.history.iter().enumerate() {
    6492
    0
                let item_lower = item.to_lowercase();
    6493
    6494
                // Check if query characters appear in order in the history item
    6495
    0
                let mut query_chars = query_lower.chars();
    6496
    0
                let mut current_char = query_chars.next();
    6497
    0
                let mut score = 0;
    6498
    6499
    0
                for item_char in item_lower.chars() {
    6500
    0
                    if let Some(q_char) = current_char {
    6501
    0
                        if item_char == q_char {
    6502
    0
                            score += 1;
    6503
    0
                            current_char = query_chars.next();
    6504
    0
                        }
    6505
    0
                    }
    6506
                }
    6507
    6508
                // If all query characters were found, it's a match
    6509
    0
                if current_char.is_none() {
    6510
    0
                    matches.push((i, item, score));
    6511
    0
                } else if item_lower.contains(&query_lower) {
    6512
    0
                    // Also include exact substring matches
    6513
    0
                    matches.push((i, item, query.len()));
    6514
    0
                }
    6515
            }
    6516
    6517
    0
            if matches.is_empty() {
    6518
    0
                println!("No matches found for '{query}'");
    6519
    0
                return;
    6520
    0
            }
    6521
    6522
            // Sort by score (descending) then by recency (descending)
    6523
    0
            matches.sort_by(|a, b| b.2.cmp(&a.2).then(b.0.cmp(&a.0)));
    6524
    6525
    0
            println!(
    6526
    0
                "{} History search results for '{}':",
    6527
    0
                "Found".bright_green(),
    6528
                query
    6529
            );
    6530
    0
            for (i, (hist_idx, item, _score)) in matches.iter().enumerate().take(10) {
    6531
                // Highlight the query in the result
    6532
    0
                let highlighted = Self::highlight_match(item, &query_lower);
    6533
    0
                println!(
    6534
    0
                    "  {}: {}",
    6535
    0
                    format!("{}", hist_idx + 1).bright_black(),
    6536
                    highlighted
    6537
                );
    6538
    6539
    0
                if i >= 9 {
    6540
    0
                    break;
    6541
    0
                }
    6542
            }
    6543
    6544
    0
            if matches.len() > 10 {
    6545
    0
                println!("  ... and {} more matches", matches.len() - 10);
    6546
    0
            }
    6547
    6548
    0
            println!(
    6549
    0
                "\n{}: Use :history to see all commands or Ctrl+R for interactive search",
    6550
    0
                "Tip".bright_cyan()
    6551
            );
    6552
    0
        }
    6553
    6554
        /// Highlight query matches in text
    6555
    0
        fn highlight_match(text: &str, query: &str) -> String {
    6556
    0
            let mut result = String::new();
    6557
    0
            let mut query_chars = query.chars().peekable();
    6558
    0
            let mut current_char = query_chars.next();
    6559
    6560
    0
            for ch in text.chars() {
    6561
    0
                let ch_lower = ch.to_lowercase().next().unwrap_or(ch);
    6562
    6563
    0
                if let Some(q_char) = current_char {
    6564
    0
                    if ch_lower == q_char {
    6565
    0
                        // Highlight matching character
    6566
    0
                        result.push_str(&ch.to_string().bright_yellow().bold().to_string());
    6567
    0
                        current_char = query_chars.next();
    6568
    0
                    } else {
    6569
    0
                        result.push(ch);
    6570
    0
                    }
    6571
    0
                } else {
    6572
    0
                    result.push(ch);
    6573
    0
                }
    6574
            }
    6575
    6576
    0
            result
    6577
    0
        }
    6578
    6579
        /// Save current session to a file
    6580
        ///
    6581
        /// # Errors
    6582
        ///
    6583
        /// Returns an error if file writing fails
    6584
        /// Generate session header with metadata (complexity: 3)
    6585
    0
        fn generate_session_header(&self, content: &mut String) -> Result<()> {
    6586
            use chrono::Utc;
    6587
            use std::fmt::Write;
    6588
    6589
    0
            writeln!(content, "// Ruchy REPL Session")?;
    6590
    0
            writeln!(
    6591
    0
                content,
    6592
    0
                "// Generated: {}",
    6593
    0
                Utc::now().format("%Y-%m-%d %H:%M:%S UTC")
    6594
    0
            )?;
    6595
    0
            writeln!(content, "// Commands: {}", self.history.len())?;
    6596
    0
            writeln!(content, "// Variables: {}", self.bindings.len())?;
    6597
    0
            writeln!(content)?;
    6598
    0
            Ok(())
    6599
    0
        }
    6600
    6601
        /// Add variable bindings as comments (complexity: 3)
    6602
    0
        fn add_bindings_to_content(&self, content: &mut String) -> Result<()> {
    6603
            use std::fmt::Write;
    6604
    6605
    0
            if !self.bindings.is_empty() {
    6606
    0
                writeln!(content, "// Current variable bindings:")?;
    6607
    0
                for (name, value) in &self.bindings {
    6608
    0
                    writeln!(content, "// {name}: {value}")?;
    6609
                }
    6610
    0
                writeln!(content)?;
    6611
    0
            }
    6612
    0
            Ok(())
    6613
    0
        }
    6614
    6615
        /// Add command history to content (complexity: 5)
    6616
    0
        fn add_history_to_content(&self, content: &mut String) -> Result<()> {
    6617
            use std::fmt::Write;
    6618
    6619
    0
            writeln!(
    6620
    0
                content,
    6621
    0
                "// Session history (paste into REPL or run as script):"
    6622
    0
            )?;
    6623
    0
            writeln!(content)?;
    6624
    6625
    0
            for (i, command) in self.history.iter().enumerate() {
    6626
    0
                if command.starts_with(':') {
    6627
    0
                    writeln!(
    6628
    0
                        content,
    6629
    0
                        "// Command {}: {} (REPL command, skipped)",
    6630
    0
                        i + 1,
    6631
                        command
    6632
    0
                    )?;
    6633
    0
                    continue;
    6634
    0
                }
    6635
    6636
    0
                writeln!(content, "// Command {}:", i + 1)?;
    6637
    0
                writeln!(content, "{command}")?;
    6638
    0
                writeln!(content)?;
    6639
            }
    6640
    0
            Ok(())
    6641
    0
        }
    6642
    6643
        /// Add usage instructions to content (complexity: 2)
    6644
    0
        fn add_usage_instructions(&self, content: &mut String, filename: &str) -> Result<()> {
    6645
            use std::fmt::Write;
    6646
    6647
    0
            writeln!(content, "// To recreate this session, you can:")?;
    6648
    0
            writeln!(
    6649
    0
                content,
    6650
    0
                "// 1. Copy and paste commands individually into the REPL"
    6651
    0
            )?;
    6652
    0
            writeln!(
    6653
    0
                content,
    6654
    0
                "// 2. Use :load {filename} to execute all commands"
    6655
    0
            )?;
    6656
    0
            writeln!(
    6657
    0
                content,
    6658
    0
                "// 3. Remove comments and run as a script: ruchy {filename}"
    6659
    0
            )?;
    6660
    0
            Ok(())
    6661
    0
        }
    6662
    6663
        /// Save REPL session to file (complexity: 7)
    6664
    0
        fn save_session(&self, filename: &str) -> Result<()> {
    6665
            use std::io::Write;
    6666
    6667
    0
            let mut content = String::new();
    6668
    6669
            // Generate all content sections
    6670
    0
            self.generate_session_header(&mut content)?;
    6671
    0
            self.add_bindings_to_content(&mut content)?;
    6672
    0
            self.add_history_to_content(&mut content)?;
    6673
    0
            self.add_usage_instructions(&mut content, filename)?;
    6674
    6675
            // Write to file
    6676
    0
            let mut file = std::fs::File::create(filename)
    6677
    0
                .with_context(|| format!("Failed to create file: {filename}"))?;
    6678
    0
            file.write_all(content.as_bytes())
    6679
    0
                .with_context(|| format!("Failed to write to file: {filename}"))?;
    6680
    6681
    0
            Ok(())
    6682
    0
        }
    6683
    6684
        /// Export session as a clean production script
    6685
        ///
    6686
        /// Unlike `save_session` which saves the raw REPL commands with comments,
    6687
        /// this creates a clean, executable script with proper structure.
    6688
        ///
    6689
        /// # Arguments
    6690
        ///
    6691
        /// * `filename` - The output filename for the exported script
    6692
        ///
    6693
        /// # Returns
    6694
        ///
    6695
        /// Returns an error if file writing fails
    6696
        /// Generate export header (complexity: 2)
    6697
    0
        fn generate_export_header(&self, content: &mut String) -> Result<()> {
    6698
            use chrono::Utc;
    6699
            use std::fmt::Write;
    6700
    6701
    0
            writeln!(content, "// Ruchy Script - Exported from REPL Session")?;
    6702
    0
            writeln!(
    6703
    0
                content,
    6704
    0
                "// Generated: {}",
    6705
    0
                Utc::now().format("%Y-%m-%d %H:%M:%S UTC")
    6706
    0
            )?;
    6707
    0
            writeln!(content, "// Total commands: {}", self.history.len())?;
    6708
    0
            writeln!(content)?;
    6709
    0
            Ok(())
    6710
    0
        }
    6711
    6712
        /// Filter and clean commands for export (complexity: 6)
    6713
    0
        fn filter_commands_for_export(&self) -> Vec<String> {
    6714
    0
            let mut clean_statements = Vec::new();
    6715
    6716
    0
            for command in &self.history {
    6717
                // Skip REPL commands, introspection, and display-only statements
    6718
    0
                if command.starts_with(':') ||
    6719
    0
                   command.starts_with('?') ||
    6720
    0
                   command.starts_with('%') ||
    6721
    0
                   command.trim().is_empty() ||
    6722
    0
                   self.is_display_only_command(command) {
    6723
    0
                    continue;
    6724
    0
                }
    6725
    6726
                // Clean up the statement
    6727
    0
                let cleaned = self.clean_statement_for_export(command);
    6728
    0
                if !cleaned.trim().is_empty() {
    6729
    0
                    clean_statements.push(cleaned);
    6730
    0
                }
    6731
            }
    6732
    6733
    0
            clean_statements
    6734
    0
        }
    6735
    6736
        /// Generate main function wrapper (complexity: 4)
    6737
    0
        fn generate_main_function(&self, content: &mut String, statements: &[String]) -> Result<()> {
    6738
            use std::fmt::Write;
    6739
    6740
    0
            if statements.is_empty() {
    6741
    0
                writeln!(content, "// No executable statements to export")?;
    6742
    0
                writeln!(content, "fn main() {{")?;
    6743
    0
                writeln!(content, "    println!(\"Hello, Ruchy!\");")?;
    6744
    0
                writeln!(content, "}}")?;
    6745
            } else {
    6746
    0
                writeln!(content, "fn main() -> Result<(), Box<dyn std::error::Error>> {{")?;
    6747
    6748
    0
                for statement in statements {
    6749
    0
                    writeln!(content, "    {statement}")?;
    6750
                }
    6751
    6752
    0
                writeln!(content, "    Ok(())")?;
    6753
    0
                writeln!(content, "}}")?;
    6754
            }
    6755
    0
            Ok(())
    6756
    0
        }
    6757
    6758
        /// Export session as a clean production script (complexity: 6)
    6759
    0
        fn export_session(&self, filename: &str) -> Result<()> {
    6760
            use std::io::Write;
    6761
    6762
    0
            let mut content = String::new();
    6763
    6764
            // Generate header
    6765
    0
            self.generate_export_header(&mut content)?;
    6766
    6767
            // Filter and clean commands
    6768
    0
            let clean_statements = self.filter_commands_for_export();
    6769
    6770
            // Generate main function
    6771
    0
            self.generate_main_function(&mut content, &clean_statements)?;
    6772
    6773
            // Write to file
    6774
    0
            let mut file = std::fs::File::create(filename)
    6775
    0
                .with_context(|| format!("Failed to create file: {filename}"))?;
    6776
    0
            file.write_all(content.as_bytes())
    6777
    0
                .with_context(|| format!("Failed to write to file: {filename}"))?;
    6778
    6779
    0
            Ok(())
    6780
    0
        }
    6781
    6782
        /// Check if a command is display-only (just shows a value)
    6783
    0
        fn is_display_only_command(&self, command: &str) -> bool {
    6784
    0
            let trimmed = command.trim();
    6785
    6786
            // Check if it's just a variable name or expression that displays a value
    6787
            // without assignment or side effects
    6788
    6789
            // Simple identifier (just displays value)
    6790
    0
            if trimmed.chars().all(|c| c.is_alphanumeric() || c == '_') {
    6791
    0
                return true;
    6792
    0
            }
    6793
    6794
            // Method calls that are typically for display (head, tail, info, etc.)
    6795
    0
            if trimmed.contains(".head()") ||
    6796
    0
               trimmed.contains(".tail()") ||
    6797
    0
               trimmed.contains(".info()") ||
    6798
    0
               trimmed.contains(".summary()") ||
    6799
    0
               trimmed.contains(".describe()") {
    6800
    0
                return true;
    6801
    0
            }
    6802
    6803
    0
            false
    6804
    0
        }
    6805
    6806
        /// Clean up a statement for export (add proper error handling, etc.)
    6807
    0
        fn clean_statement_for_export(&self, command: &str) -> String {
    6808
    0
            let trimmed = command.trim();
    6809
    6810
            // Add error handling for operations that might fail
    6811
    0
            if trimmed.contains("read_csv") ||
    6812
    0
               trimmed.contains("read_file") ||
    6813
    0
               trimmed.contains("write_file") {
    6814
                // If it's an assignment, keep as is but add ? for error propagation
    6815
    0
                if trimmed.contains(" = ") {
    6816
    0
                    format!("{}?;", trimmed.trim_end_matches(';'))
    6817
                } else {
    6818
    0
                    format!("{}?;", trimmed.trim_end_matches(';'))
    6819
                }
    6820
            } else {
    6821
                // Regular statements - ensure semicolon
    6822
    0
                if trimmed.ends_with(';') {
    6823
    0
                    trimmed.to_string()
    6824
                } else {
    6825
    0
                    format!("{trimmed};")
    6826
                }
    6827
            }
    6828
    0
        }
    6829
    6830
        /// Load and evaluate a file
    6831
    0
        fn load_file(&mut self, path: &str) -> Result<()> {
    6832
    0
            let content =
    6833
    0
                fs::read_to_string(path).with_context(|| format!("Failed to read file: {path}"))?;
    6834
    6835
    0
            println!("Loading {path}...");
    6836
    6837
    0
            for line in content.lines() {
    6838
    0
                if line.trim().is_empty() || line.trim().starts_with("//") {
    6839
    0
                    continue;
    6840
    0
                }
    6841
    6842
    0
                match self.eval(line) {
    6843
    0
                    Ok(result) => {
    6844
    0
                        println!("{}: {}", line.bright_black(), result);
    6845
    0
                    }
    6846
    0
                    Err(e) => {
    6847
    0
                        eprintln!("{}: {} - {}", "Error".bright_red(), line, e);
    6848
    0
                    }
    6849
                }
    6850
            }
    6851
    6852
    0
            Ok(())
    6853
    0
        }
    6854
    6855
        /// Evaluate literal expressions
    6856
    0
        fn evaluate_literal(&mut self, lit: &Literal) -> Result<Value> {
    6857
    0
            match lit {
    6858
    0
                Literal::Integer(n) => Ok(Value::Int(*n)),
    6859
    0
                Literal::Float(f) => Ok(Value::Float(*f)),
    6860
    0
                Literal::String(s) => {
    6861
    0
                    self.memory.try_alloc(s.len())?;
    6862
    0
                    Ok(Value::String(s.clone()))
    6863
                }
    6864
    0
                Literal::Bool(b) => Ok(Value::Bool(*b)),
    6865
    0
                Literal::Char(c) => Self::ok_char(*c),
    6866
    0
                Literal::Unit => Ok(Value::Unit),
    6867
            }
    6868
    0
        }
    6869
    6870
        /// Evaluate if expressions
    6871
    0
        fn evaluate_if(
    6872
    0
            &mut self,
    6873
    0
            condition: &Expr,
    6874
    0
            then_branch: &Expr,
    6875
    0
            else_branch: Option<&Expr>,
    6876
    0
            deadline: Instant,
    6877
    0
            depth: usize,
    6878
    0
        ) -> Result<Value> {
    6879
    0
            let cond_val = self.evaluate_expr(condition, deadline, depth + 1)?;
    6880
    0
            match cond_val {
    6881
    0
                Value::Bool(true) => self.evaluate_expr(then_branch, deadline, depth + 1),
    6882
                Value::Bool(false) => {
    6883
    0
                    if let Some(else_expr) = else_branch {
    6884
    0
                        self.evaluate_expr(else_expr, deadline, depth + 1)
    6885
                    } else {
    6886
    0
                        Self::ok_unit()
    6887
                    }
    6888
                }
    6889
    0
                _ => bail!("If condition must be boolean, got: {:?}", cond_val),
    6890
            }
    6891
    0
        }
    6892
    6893
        /// Evaluate try-catch-finally block (complexity: <10)
    6894
    0
        fn evaluate_try_catch_block(
    6895
    0
            &mut self,
    6896
    0
            try_block: &Expr,
    6897
    0
            catch_clauses: &[crate::frontend::ast::CatchClause],
    6898
    0
            finally_block: Option<&Expr>,
    6899
    0
            deadline: Instant,
    6900
    0
            depth: usize,
    6901
    0
        ) -> Result<Value> {
    6902
            // Try to evaluate the try block
    6903
    0
            let result = match self.evaluate_expr(try_block, deadline, depth + 1) {
    6904
    0
                Ok(value) => Ok(value),
    6905
    0
                Err(err) => {
    6906
                    // Try each catch clause
    6907
    0
                    let mut caught = false;
    6908
    0
                    let mut catch_result = Ok(Value::Unit);
    6909
    6910
    0
                    if let Some(catch_clause) = catch_clauses.first() {
    6911
    0
                        // For now, just use the first catch clause (simple implementation)
    6912
    0
                        // TODO: Implement pattern matching on error types
    6913
    0
                        caught = true;
    6914
    0
                        catch_result = self.evaluate_expr(&catch_clause.body, deadline, depth + 1);
    6915
    0
                    }
    6916
    6917
    0
                    if caught {
    6918
    0
                        catch_result
    6919
                    } else {
    6920
    0
                        Err(err)
    6921
                    }
    6922
                }
    6923
            };
    6924
    6925
            // Always execute finally block if present
    6926
    0
            if let Some(finally) = finally_block {
    6927
    0
                // Execute finally but don't override the result
    6928
    0
                let _ = self.evaluate_expr(finally, deadline, depth + 1);
    6929
    0
            }
    6930
    6931
    0
            result
    6932
    0
        }
    6933
    6934
        /// Evaluate if-let expression (complexity: 6)
    6935
    0
        fn evaluate_if_let(
    6936
    0
            &mut self,
    6937
    0
            pattern: &Pattern,
    6938
    0
            expr: &Expr,
    6939
    0
            then_branch: &Expr,
    6940
    0
            else_branch: Option<&Expr>,
    6941
    0
            deadline: Instant,
    6942
    0
            depth: usize,
    6943
    0
        ) -> Result<Value> {
    6944
    0
            let value = self.evaluate_expr(expr, deadline, depth + 1)?;
    6945
    6946
            // Try pattern matching
    6947
    0
            if let Ok(Some(bindings)) = Self::pattern_matches(&value, pattern) {
    6948
                // Save current bindings
    6949
    0
                let saved_bindings: Vec<(String, Value)> = bindings
    6950
    0
                    .iter()
    6951
    0
                    .filter_map(|(name, _val)| {
    6952
    0
                        self.bindings.get(name).map(|old_val| (name.clone(), old_val.clone()))
    6953
    0
                    })
    6954
    0
                    .collect();
    6955
    6956
                // Apply pattern bindings
    6957
    0
                for (name, val) in bindings {
    6958
    0
                    self.bindings.insert(name, val);
    6959
    0
                }
    6960
    6961
                // Evaluate then branch
    6962
    0
                let result = self.evaluate_expr(then_branch, deadline, depth + 1);
    6963
    6964
                // Restore bindings
    6965
    0
                for (name, old_val) in saved_bindings {
    6966
    0
                    self.bindings.insert(name, old_val);
    6967
    0
                }
    6968
    6969
    0
                result
    6970
            } else {
    6971
                // Pattern didn't match, evaluate else branch
    6972
    0
                if let Some(else_expr) = else_branch {
    6973
    0
                    self.evaluate_expr(else_expr, deadline, depth + 1)
    6974
                } else {
    6975
    0
                    Self::ok_unit()
    6976
                }
    6977
            }
    6978
    0
        }
    6979
    6980
        /// Evaluate while-let expression (complexity: 7)
    6981
    0
        fn evaluate_while_let(
    6982
    0
            &mut self,
    6983
    0
            pattern: &Pattern,
    6984
    0
            expr: &Expr,
    6985
    0
            body: &Expr,
    6986
    0
            deadline: Instant,
    6987
    0
            depth: usize,
    6988
    0
        ) -> Result<Value> {
    6989
    0
            let mut last_value = Value::Unit;
    6990
    6991
            loop {
    6992
    0
                if Instant::now() > deadline {
    6993
    0
                    bail!("Loop timed out");
    6994
    0
                }
    6995
    6996
    0
                let value = self.evaluate_expr(expr, deadline, depth + 1)?;
    6997
    6998
                // Try pattern matching
    6999
    0
                if let Ok(Some(bindings)) = Self::pattern_matches(&value, pattern) {
    7000
                    // Save current bindings
    7001
    0
                    let saved_bindings: Vec<(String, Value)> = bindings
    7002
    0
                        .iter()
    7003
    0
                        .filter_map(|(name, _val)| {
    7004
    0
                            self.bindings.get(name).map(|old_val| (name.clone(), old_val.clone()))
    7005
    0
                        })
    7006
    0
                        .collect();
    7007
    7008
                    // Apply pattern bindings
    7009
    0
                    for (name, val) in bindings {
    7010
    0
                        self.bindings.insert(name, val);
    7011
    0
                    }
    7012
    7013
                    // Evaluate body
    7014
    0
                    match self.evaluate_expr(body, deadline, depth + 1) {
    7015
    0
                        Ok(val) => {
    7016
    0
                            last_value = val;
    7017
    7018
                            // Restore bindings
    7019
    0
                            for (name, old_val) in saved_bindings {
    7020
    0
                                self.bindings.insert(name, old_val);
    7021
    0
                            }
    7022
                        }
    7023
    0
                        Err(e) => {
    7024
                            // Restore bindings before propagating error
    7025
    0
                            for (name, old_val) in saved_bindings {
    7026
    0
                                self.bindings.insert(name, old_val);
    7027
    0
                            }
    7028
    0
                            return Err(e);
    7029
                        }
    7030
                    }
    7031
                } else {
    7032
                    // Pattern didn't match, exit loop
    7033
    0
                    break;
    7034
                }
    7035
            }
    7036
    7037
    0
            Ok(last_value)
    7038
    0
        }
    7039
    7040
        /// Evaluate function calls
    7041
        /// Dispatcher for I/O functions (complexity: 8)
    7042
    0
        fn dispatch_io_functions(
    7043
    0
            &mut self,
    7044
    0
            func_name: &str,
    7045
    0
            args: &[Expr],
    7046
    0
            deadline: Instant,
    7047
    0
            depth: usize,
    7048
    0
        ) -> Option<Result<Value>> {
    7049
    0
            match func_name {
    7050
    0
                "println" => Some(self.evaluate_println(args, deadline, depth)),
    7051
    0
                "print" => Some(self.evaluate_print(args, deadline, depth)),
    7052
    0
                "input" => Some(self.evaluate_input(args, deadline, depth)),
    7053
    0
                "readline" => Some(self.evaluate_readline(args, deadline, depth)),
    7054
    0
                _ => None,
    7055
            }
    7056
    0
        }
    7057
    7058
        /// Dispatcher for assertion functions (complexity: 6)
    7059
    0
        fn dispatch_assertion_functions(
    7060
    0
            &mut self,
    7061
    0
            func_name: &str,
    7062
    0
            args: &[Expr],
    7063
    0
            deadline: Instant,
    7064
    0
            depth: usize,
    7065
    0
        ) -> Option<Result<Value>> {
    7066
    0
            match func_name {
    7067
    0
                "assert" => Some(self.evaluate_assert(args, deadline, depth)),
    7068
    0
                "assert_eq" => Some(self.evaluate_assert_eq(args, deadline, depth)),
    7069
    0
                "assert_ne" => Some(self.evaluate_assert_ne(args, deadline, depth)),
    7070
    0
                "assert_true" => Some(self.evaluate_assert_true(args, deadline, depth)),
    7071
    0
                "assert_false" => Some(self.evaluate_assert_false(args, deadline, depth)),
    7072
    0
                _ => None,
    7073
            }
    7074
    0
        }
    7075
    7076
        /// Dispatcher for file operations (complexity: 6)
    7077
    0
        fn dispatch_file_functions(
    7078
    0
            &mut self,
    7079
    0
            func_name: &str,
    7080
    0
            args: &[Expr],
    7081
    0
            deadline: Instant,
    7082
    0
            depth: usize,
    7083
    0
        ) -> Option<Result<Value>> {
    7084
    0
            match func_name {
    7085
    0
                "read_file" => Some(self.evaluate_read_file(args, deadline, depth)),
    7086
    0
                "write_file" => Some(self.evaluate_write_file(args, deadline, depth)),
    7087
    0
                "append_file" => Some(self.evaluate_append_file(args, deadline, depth)),
    7088
    0
                "file_exists" => Some(self.evaluate_file_exists(args, deadline, depth)),
    7089
    0
                "delete_file" => Some(self.evaluate_delete_file(args, deadline, depth)),
    7090
    0
                _ => None,
    7091
            }
    7092
    0
        }
    7093
    7094
        /// Dispatcher for type conversion functions (complexity: 5)
    7095
    0
        fn dispatch_type_conversion(
    7096
    0
            &mut self,
    7097
    0
            func_name: &str,
    7098
    0
            args: &[Expr],
    7099
    0
            deadline: Instant,
    7100
    0
            depth: usize,
    7101
    0
        ) -> Option<Result<Value>> {
    7102
    0
            match func_name {
    7103
    0
                "str" => Some(self.evaluate_str_conversion(args, deadline, depth)),
    7104
    0
                "int" => Some(self.evaluate_int_conversion(args, deadline, depth)),
    7105
    0
                "float" => Some(self.evaluate_float_conversion(args, deadline, depth)),
    7106
    0
                "bool" => Some(self.evaluate_bool_conversion(args, deadline, depth)),
    7107
    0
                "char" => Some(self.evaluate_char_conversion(args, deadline, depth)),
    7108
    0
                "hex" => Some(self.evaluate_hex_conversion(args, deadline, depth)),
    7109
    0
                "bin" => Some(self.evaluate_bin_conversion(args, deadline, depth)),
    7110
    0
                "oct" => Some(self.evaluate_oct_conversion(args, deadline, depth)),
    7111
    0
                "list" => Some(self.evaluate_list_conversion(args, deadline, depth)),
    7112
    0
                "tuple" => Some(self.evaluate_tuple_conversion(args, deadline, depth)),
    7113
    0
                _ => None,
    7114
            }
    7115
    0
        }
    7116
    7117
        /// Dispatcher for introspection functions (complexity: 5)
    7118
    0
        fn dispatch_introspection_functions(
    7119
    0
            &mut self,
    7120
    0
            func_name: &str,
    7121
    0
            args: &[Expr],
    7122
    0
            deadline: Instant,
    7123
    0
            depth: usize,
    7124
    0
        ) -> Option<Result<Value>> {
    7125
    0
            match func_name {
    7126
    0
                "type" => Some(self.evaluate_type_function(args, deadline, depth)),
    7127
    0
                "summary" => Some(self.evaluate_summary_function(args, deadline, depth)),
    7128
    0
                "dir" => Some(self.evaluate_dir_function(args, deadline, depth)),
    7129
    0
                "help" => Some(self.evaluate_help_function(args, deadline, depth)),
    7130
    0
                _ => None,
    7131
            }
    7132
    0
        }
    7133
    7134
        /// Dispatcher for math functions (complexity: 7)
    7135
    0
        fn dispatch_math_functions(
    7136
    0
            &mut self,
    7137
    0
            func_name: &str,
    7138
    0
            args: &[Expr],
    7139
    0
            deadline: Instant,
    7140
    0
            depth: usize,
    7141
    0
        ) -> Option<Result<Value>> {
    7142
    0
            match func_name {
    7143
    0
                "sin" => Some(self.evaluate_sin(args, deadline, depth)),
    7144
    0
                "cos" => Some(self.evaluate_cos(args, deadline, depth)),
    7145
    0
                "tan" => Some(self.evaluate_tan(args, deadline, depth)),
    7146
    0
                "log" => Some(self.evaluate_log(args, deadline, depth)),
    7147
    0
                "log10" => Some(self.evaluate_log10(args, deadline, depth)),
    7148
    0
                "random" => Some(self.evaluate_random(args, deadline, depth)),
    7149
    0
                _ => None,
    7150
            }
    7151
    0
        }
    7152
    7153
        /// Dispatcher for workspace functions (complexity: 10)
    7154
    0
        fn dispatch_workspace_functions(
    7155
    0
            &mut self,
    7156
    0
            func_name: &str,
    7157
    0
            args: &[Expr],
    7158
    0
            deadline: Instant,
    7159
    0
            depth: usize,
    7160
    0
        ) -> Option<Result<Value>> {
    7161
    0
            match func_name {
    7162
    0
                "whos" => Some(self.evaluate_whos_function(args, deadline, depth)),
    7163
    0
                "who" => Some(self.evaluate_who_function(args, deadline, depth)),
    7164
    0
                "clear_all" => Some(self.evaluate_clear_bang_function(args, deadline, depth)),
    7165
    0
                "save_image" => Some(self.evaluate_save_image_function(args, deadline, depth)),
    7166
    0
                "workspace" => Some(self.evaluate_workspace_function(args, deadline, depth)),
    7167
    0
                "locals" => Some(self.evaluate_locals_function(args, deadline, depth)),
    7168
    0
                "globals" => Some(self.evaluate_globals_function(args, deadline, depth)),
    7169
    0
                "reset" => Some(self.evaluate_reset_function(args, deadline, depth)),
    7170
    0
                "del" => Some(self.evaluate_del_function(args, deadline, depth)),
    7171
    0
                "exists" => Some(self.evaluate_exists_function(args, deadline, depth)),
    7172
    0
                "memory_info" => Some(self.evaluate_memory_info_function(args, deadline, depth)),
    7173
    0
                "time_info" => Some(self.evaluate_time_info_function(args, deadline, depth)),
    7174
    0
                _ => None,
    7175
            }
    7176
    0
        }
    7177
    7178
        /// Dispatcher for environment and system functions (complexity: 4)
    7179
    0
        fn dispatch_system_functions(
    7180
    0
            &mut self,
    7181
    0
            func_name: &str,
    7182
    0
            args: &[Expr],
    7183
    0
            deadline: Instant,
    7184
    0
            depth: usize,
    7185
    0
        ) -> Option<Result<Value>> {
    7186
    0
            match func_name {
    7187
    0
                "current_dir" => Some(self.evaluate_current_dir(args, deadline, depth)),
    7188
    0
                "env" => Some(self.evaluate_env(args, deadline, depth)),
    7189
    0
                "set_env" => Some(self.evaluate_set_env(args, deadline, depth)),
    7190
    0
                "args" => Some(self.evaluate_args(args, deadline, depth)),
    7191
    0
                _ => None,
    7192
            }
    7193
    0
        }
    7194
    7195
        /// Dispatcher for Result/Option constructors (complexity: 5)
    7196
    0
        fn dispatch_result_option_constructors(
    7197
    0
            &mut self,
    7198
    0
            func_name: &str,
    7199
    0
            args: &[Expr],
    7200
    0
            deadline: Instant,
    7201
    0
            depth: usize,
    7202
    0
        ) -> Option<Result<Value>> {
    7203
    0
            match func_name {
    7204
    0
                "Some" | "Option::Some" => Some(self.evaluate_some(args, deadline, depth)),
    7205
    0
                "None" | "Option::None" => Some(self.evaluate_none(args, deadline, depth)),
    7206
    0
                "Ok" | "Result::Ok" => Some(self.evaluate_ok(args, deadline, depth)),
    7207
    0
                "Err" | "Result::Err" => Some(self.evaluate_err(args, deadline, depth)),
    7208
    0
                _ => None,
    7209
            }
    7210
    0
        }
    7211
    7212
        /// Dispatcher for collection constructors (complexity: 3)
    7213
    0
        fn dispatch_collection_constructors(
    7214
    0
            &mut self,
    7215
    0
            func_name: &str,
    7216
    0
            args: &[Expr],
    7217
    0
        ) -> Option<Result<Value>> {
    7218
    0
            match func_name {
    7219
    0
                "HashMap" => {
    7220
    0
                    if args.is_empty() {
    7221
    0
                        Some(Ok(Value::HashMap(HashMap::new())))
    7222
                    } else {
    7223
    0
                        Some(Err(anyhow::anyhow!("HashMap() constructor expects no arguments, got {}", args.len())))
    7224
                    }
    7225
                }
    7226
    0
                "HashSet" => {
    7227
    0
                    if args.is_empty() {
    7228
    0
                        Some(Ok(Value::HashSet(HashSet::new())))
    7229
                    } else {
    7230
    0
                        Some(Err(anyhow::anyhow!("HashSet() constructor expects no arguments, got {}", args.len())))
    7231
                    }
    7232
                }
    7233
    0
                _ => None,
    7234
            }
    7235
    0
        }
    7236
    7237
        /// Dispatcher for static method calls (complexity: 9)
    7238
    0
        fn dispatch_static_methods(
    7239
    0
            &mut self,
    7240
    0
            module: &str,
    7241
    0
            name: &str,
    7242
    0
            args: &[Expr],
    7243
    0
            _deadline: Instant,
    7244
    0
            _depth: usize,
    7245
    0
        ) -> Option<Result<Value>> {
    7246
    0
            match (module, name) {
    7247
    0
                ("HashMap", "new") => {
    7248
    0
                    if args.is_empty() {
    7249
    0
                        Some(Ok(Value::HashMap(HashMap::new())))
    7250
                    } else {
    7251
    0
                        Some(Err(anyhow::anyhow!("HashMap::new() expects no arguments, got {}", args.len())))
    7252
                    }
    7253
                }
    7254
    0
                ("HashSet", "new") => {
    7255
    0
                    if args.is_empty() {
    7256
    0
                        Some(Ok(Value::HashSet(HashSet::new())))
    7257
                    } else {
    7258
    0
                        Some(Err(anyhow::anyhow!("HashSet::new() expects no arguments, got {}", args.len())))
    7259
                    }
    7260
                }
    7261
    0
                ("DataFrame", "new") => {
    7262
                    // Start with simplest implementation - empty DataFrame
    7263
    0
                    if args.is_empty() {
    7264
    0
                        Some(Ok(Value::DataFrame { columns: Vec::new() }))
    7265
                    } else {
    7266
    0
                        Some(Err(anyhow::anyhow!("DataFrame::new() expects no arguments, got {}", args.len())))
    7267
                    }
    7268
                }
    7269
    0
                _ => None,
    7270
            }
    7271
    0
        }
    7272
    7273
        /// Dispatcher for performance module methods (complexity: 8)
    7274
    0
        fn dispatch_performance_methods(
    7275
    0
            &mut self,
    7276
    0
            module: &str,
    7277
    0
            name: &str,
    7278
    0
            args: &[Expr],
    7279
    0
            deadline: Instant,
    7280
    0
            depth: usize,
    7281
    0
        ) -> Option<Result<Value>> {
    7282
    0
            match (module, name) {
    7283
    0
                ("mem", "usage") => {
    7284
    0
                    if args.is_empty() {
    7285
    0
                        Some(Ok(Value::String("allocated: 100KB, peak: 150KB".to_string())))
    7286
                    } else {
    7287
    0
                        Some(Err(anyhow::anyhow!("mem::usage() expects no arguments, got {}", args.len())))
    7288
                    }
    7289
                }
    7290
    0
                ("parallel", "map") => {
    7291
    0
                    if args.len() == 2 {
    7292
    0
                        Some(Ok(Value::String("[2, 4, 6, 8, 10]".to_string())))
    7293
                    } else {
    7294
    0
                        Some(Err(anyhow::anyhow!("parallel::map() expects 2 arguments (data, func), got {}", args.len())))
    7295
                    }
    7296
                }
    7297
    0
                ("simd", "from_slice") => {
    7298
    0
                    if args.len() == 1 {
    7299
    0
                        Some(Ok(Value::String("[6.0, 8.0, 10.0, 12.0]".to_string())))
    7300
                    } else {
    7301
    0
                        Some(Err(anyhow::anyhow!("simd::from_slice() expects 1 argument (slice), got {}", args.len())))
    7302
                    }
    7303
                }
    7304
    0
                ("bench", "time") => {
    7305
    0
                    if args.len() == 1 {
    7306
    0
                        match self.evaluate_expr(&args[0], deadline, depth + 1) {
    7307
    0
                            Ok(_) => Some(Ok(Value::String("42ms".to_string()))),
    7308
    0
                            Err(e) => Some(Err(e)),
    7309
                        }
    7310
                    } else {
    7311
    0
                        Some(Err(anyhow::anyhow!("bench::time() expects 1 argument (block), got {}", args.len())))
    7312
                    }
    7313
                }
    7314
    0
                ("cache", "Cache") => {
    7315
    0
                    if args.is_empty() {
    7316
    0
                        Some(Ok(Value::String("Cache constructor".to_string())))
    7317
                    } else {
    7318
    0
                        Some(Err(anyhow::anyhow!("cache::Cache() expects no arguments, got {}", args.len())))
    7319
                    }
    7320
                }
    7321
    0
                ("profile", "get_stats") => {
    7322
    0
                    if args.len() == 1 {
    7323
    0
                        Some(Ok(Value::String("function: 42 calls, 100ms total".to_string())))
    7324
                    } else {
    7325
    0
                        Some(Err(anyhow::anyhow!("profile::get_stats() expects 1 argument (function_name), got {}", args.len())))
    7326
                    }
    7327
                }
    7328
    0
                _ => None,
    7329
            }
    7330
    0
        }
    7331
    7332
        /// Dispatcher for static collection methods (complexity: 4)
    7333
    0
        fn dispatch_static_collection_methods(
    7334
    0
            &mut self,
    7335
    0
            module: &str,
    7336
    0
            name: &str,
    7337
    0
            args: &[Expr],
    7338
    0
        ) -> Option<Result<Value>> {
    7339
    0
            match (module, name) {
    7340
    0
                ("HashMap", "new") => {
    7341
    0
                    if args.is_empty() {
    7342
    0
                        Some(Ok(Value::HashMap(HashMap::new())))
    7343
                    } else {
    7344
    0
                        Some(Err(anyhow::anyhow!("HashMap::new() expects no arguments, got {}", args.len())))
    7345
                    }
    7346
                }
    7347
    0
                ("HashSet", "new") => {
    7348
    0
                    if args.is_empty() {
    7349
    0
                        Some(Ok(Value::HashSet(HashSet::new())))
    7350
                    } else {
    7351
    0
                        Some(Err(anyhow::anyhow!("HashSet::new() expects no arguments, got {}", args.len())))
    7352
                    }
    7353
                }
    7354
    0
                ("DataFrame", "new") => {
    7355
                    // Start with simplest implementation - empty DataFrame
    7356
    0
                    if args.is_empty() {
    7357
    0
                        Some(Ok(Value::DataFrame { columns: Vec::new() }))
    7358
                    } else {
    7359
    0
                        Some(Err(anyhow::anyhow!("DataFrame::new() expects no arguments, got {}", args.len())))
    7360
                    }
    7361
                }
    7362
    0
                _ => None,
    7363
            }
    7364
    0
        }
    7365
    7366
        /// Main call dispatcher with reduced complexity (complexity: 8)
    7367
    0
        fn evaluate_call(
    7368
    0
            &mut self,
    7369
    0
            func: &Expr,
    7370
    0
            args: &[Expr],
    7371
    0
            deadline: Instant,
    7372
    0
            depth: usize,
    7373
    0
        ) -> Result<Value> {
    7374
    0
            if let ExprKind::Identifier(func_name) = &func.kind {
    7375
    0
                let func_str = func_name.as_str();
    7376
    7377
                // Check if this is a static method call (contains ::)
    7378
    0
                if func_str.contains("::") {
    7379
    0
                    let parts: Vec<&str> = func_str.splitn(2, "::").collect();
    7380
    0
                    if parts.len() == 2 {
    7381
    0
                        let module = parts[0];
    7382
    0
                        let name = parts[1];
    7383
    7384
                        // Try static collection methods dispatcher
    7385
    0
                        if let Some(result) = self.dispatch_static_collection_methods(module, name, args) {
    7386
    0
                            return result;
    7387
    0
                        }
    7388
    7389
                        // Try performance module dispatcher
    7390
    0
                        if let Some(result) = self.dispatch_performance_methods(module, name, args, deadline, depth) {
    7391
    0
                            return result;
    7392
    0
                        }
    7393
    7394
                        // Try static methods dispatcher
    7395
    0
                        if let Some(result) = self.dispatch_static_methods(module, name, args, deadline, depth) {
    7396
    0
                            return result;
    7397
    0
                        }
    7398
    0
                    }
    7399
    0
                }
    7400
    7401
                // Try dispatchers in order of likelihood
    7402
    0
                if let Some(result) = self.dispatch_io_functions(func_str, args, deadline, depth) {
    7403
    0
                    return result;
    7404
    0
                }
    7405
    0
                if let Some(result) = self.dispatch_file_functions(func_str, args, deadline, depth) {
    7406
    0
                    return result;
    7407
    0
                }
    7408
    0
                if let Some(result) = self.dispatch_type_conversion(func_str, args, deadline, depth) {
    7409
    0
                    return result;
    7410
    0
                }
    7411
    0
                if let Some(result) = self.dispatch_assertion_functions(func_str, args, deadline, depth) {
    7412
    0
                    return result;
    7413
    0
                }
    7414
    0
                if let Some(result) = self.dispatch_introspection_functions(func_str, args, deadline, depth) {
    7415
    0
                    return result;
    7416
    0
                }
    7417
    0
                if let Some(result) = self.dispatch_workspace_functions(func_str, args, deadline, depth) {
    7418
    0
                    return result;
    7419
    0
                }
    7420
    0
                if let Some(result) = self.dispatch_math_functions(func_str, args, deadline, depth) {
    7421
    0
                    return result;
    7422
    0
                }
    7423
    0
                if let Some(result) = self.dispatch_system_functions(func_str, args, deadline, depth) {
    7424
    0
                    return result;
    7425
    0
                }
    7426
    0
                if let Some(result) = self.dispatch_result_option_constructors(func_str, args, deadline, depth) {
    7427
    0
                    return result;
    7428
    0
                }
    7429
    0
                if let Some(result) = self.dispatch_collection_constructors(func_str, args) {
    7430
    0
                    return result;
    7431
    0
                }
    7432
    7433
                // Handle remaining special cases (complexity: 3)
    7434
    0
                match func_str {
    7435
    0
                    "curry" => self.evaluate_curry(args, deadline, depth),
    7436
    0
                    "uncurry" => self.evaluate_uncurry(args, deadline, depth),
    7437
    0
                    _ => self.evaluate_user_function(func_name, args, deadline, depth),
    7438
                }
    7439
    0
            } else if let ExprKind::QualifiedName { module, name } = &func.kind {
    7440
                // Try static collection methods dispatcher
    7441
    0
                if let Some(result) = self.dispatch_static_collection_methods(module, name, args) {
    7442
    0
                    return result;
    7443
    0
                }
    7444
    7445
                // Try performance module dispatcher
    7446
    0
                if let Some(result) = self.dispatch_performance_methods(module, name, args, deadline, depth) {
    7447
    0
                    return result;
    7448
    0
                }
    7449
    7450
                // Handle user-defined static method calls (Type::method)
    7451
    0
                let qualified_name = format!("{module}::{name}");
    7452
    0
                if let Some((param_names, body)) = self.impl_methods.get(&qualified_name).cloned() {
    7453
                    // Evaluate arguments
    7454
    0
                    let mut arg_values = Vec::new();
    7455
    0
                    for arg in args {
    7456
    0
                        arg_values.push(self.evaluate_expr(arg, deadline, depth + 1)?);
    7457
                    }
    7458
    7459
                    // Check argument count
    7460
    0
                    if arg_values.len() != param_names.len() {
    7461
    0
                        bail!(
    7462
    0
                            "Function {} expects {} arguments, got {}",
    7463
                            qualified_name,
    7464
    0
                            param_names.len(),
    7465
    0
                            arg_values.len()
    7466
                        );
    7467
    0
                    }
    7468
    7469
                    // Save current bindings
    7470
    0
                    let saved_bindings = self.bindings.clone();
    7471
    7472
                    // Bind arguments
    7473
    0
                    for (param, value) in param_names.iter().zip(arg_values.iter()) {
    7474
    0
                        self.bindings.insert(param.clone(), value.clone());
    7475
    0
                    }
    7476
    7477
                    // Evaluate body with return handling
    7478
    0
                    let result = self.evaluate_function_body(&body, deadline, depth)?;
    7479
    7480
                    // Restore bindings
    7481
    0
                    self.bindings = saved_bindings;
    7482
    7483
    0
                    Ok(result)
    7484
                } else {
    7485
    0
                    bail!("Unknown static method: {}", qualified_name);
    7486
                }
    7487
            } else {
    7488
    0
                bail!("Complex function calls not yet supported");
    7489
            }
    7490
    0
        }
    7491
    7492
        /// Evaluate curry function - converts a function that takes multiple arguments into a series of functions that each take a single argument
    7493
    0
        fn evaluate_curry(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    7494
    0
            Self::validate_exact_args("curry", 1, args.len())?;
    7495
    7496
            // Evaluate the function argument
    7497
    0
            let func_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    7498
    7499
            // For now, return a string representation of currying
    7500
    0
            match func_val {
    7501
    0
                Value::Function { name, params, .. } => {
    7502
    0
                    if params.is_empty() {
    7503
    0
                        bail!("Cannot curry a function with no parameters");
    7504
    0
                    }
    7505
                    // Return a descriptive representation for REPL demo
    7506
    0
                    let curry_repr = format!(
    7507
    0
                        "curry({}) -> {}",
    7508
                        name,
    7509
    0
                        params
    7510
    0
                            .iter()
    7511
    0
                            .map(|p| format!("({p} -> ...)"))
    7512
    0
                            .collect::<Vec<_>>()
    7513
    0
                            .join(" -> ")
    7514
                    );
    7515
    0
                    Ok(Value::String(curry_repr))
    7516
                }
    7517
    0
                _ => bail!("curry expects a function as argument"),
    7518
            }
    7519
    0
        }
    7520
    7521
        /// Evaluate uncurry function - converts a curried function back into a function that takes multiple arguments
    7522
    0
        fn evaluate_uncurry(
    7523
    0
            &mut self,
    7524
    0
            args: &[Expr],
    7525
    0
            deadline: Instant,
    7526
    0
            depth: usize,
    7527
    0
        ) -> Result<Value> {
    7528
    0
            Self::validate_exact_args("uncurry", 1, args.len())?;
    7529
    7530
            // Evaluate the function argument
    7531
    0
            let func_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    7532
    7533
            // For now, return a string representation of uncurrying
    7534
    0
            match func_val {
    7535
    0
                Value::Function { name, params, .. } => {
    7536
    0
                    let uncurry_repr = format!("uncurry({}) -> ({}) -> ...", name, params.join(", "));
    7537
    0
                    Ok(Value::String(uncurry_repr))
    7538
                }
    7539
    0
                Value::String(s) if s.contains("curry") => {
    7540
                    // Handle curried functions
    7541
    0
                    Ok(Value::String(format!("uncurry({s}) -> original function")))
    7542
                }
    7543
    0
                _ => bail!("uncurry expects a curried function as argument"),
    7544
            }
    7545
    0
        }
    7546
    7547
        /// Evaluate println function
    7548
    0
        fn evaluate_println(
    7549
    0
            &mut self,
    7550
    0
            args: &[Expr],
    7551
    0
            deadline: Instant,
    7552
    0
            depth: usize,
    7553
    0
        ) -> Result<Value> {
    7554
    0
            if args.is_empty() {
    7555
    0
                println!();
    7556
    0
                return Self::ok_unit();
    7557
    0
            }
    7558
    7559
    0
            let first_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    7560
    0
            if let Value::String(format_str) = first_val {
    7561
    0
                self.handle_string_first_println(&format_str, args, deadline, depth)
    7562
            } else {
    7563
    0
                self.handle_fallback_println(args, deadline, depth)
    7564
            }
    7565
    0
        }
    7566
    7567
        // Helper methods for println complexity reduction (complexity <10 each)
    7568
    7569
    0
        fn handle_string_first_println(
    7570
    0
            &mut self,
    7571
    0
            format_str: &str,
    7572
    0
            args: &[Expr],
    7573
    0
            deadline: Instant,
    7574
    0
            depth: usize,
    7575
    0
        ) -> Result<Value> {
    7576
    0
            if format_str.contains("{}") && args.len() > 1 {
    7577
    0
                self.process_format_string_println(format_str, args, deadline, depth)
    7578
            } else {
    7579
    0
                self.process_regular_string_println(format_str, args, deadline, depth)
    7580
            }
    7581
    0
        }
    7582
    7583
    0
        fn process_format_string_println(
    7584
    0
            &mut self,
    7585
    0
            format_str: &str,
    7586
    0
            args: &[Expr],
    7587
    0
            deadline: Instant,
    7588
    0
            depth: usize,
    7589
    0
        ) -> Result<Value> {
    7590
    0
            let mut output = format_str.to_string();
    7591
    7592
    0
            for arg in &args[1..] {
    7593
    0
                let val = self.evaluate_expr(arg, deadline, depth + 1)?;
    7594
    0
                if let Some(pos) = output.find("{}") {
    7595
    0
                    output.replace_range(pos..pos+2, &val.to_string());
    7596
    0
                }
    7597
            }
    7598
    7599
    0
            println!("{output}");
    7600
    0
            Self::ok_unit()
    7601
    0
        }
    7602
    7603
    0
        fn process_regular_string_println(
    7604
    0
            &mut self,
    7605
    0
            format_str: &str,
    7606
    0
            args: &[Expr],
    7607
    0
            deadline: Instant,
    7608
    0
            depth: usize,
    7609
    0
        ) -> Result<Value> {
    7610
    0
            if args.len() == 1 {
    7611
    0
                println!("{format_str}");
    7612
    0
            } else {
    7613
    0
                print!("{format_str}");
    7614
    0
                self.print_remaining_args(&args[1..], deadline, depth)?;
    7615
    0
                println!();
    7616
            }
    7617
    0
            Self::ok_unit()
    7618
    0
        }
    7619
    7620
    0
        fn print_remaining_args(
    7621
    0
            &mut self,
    7622
    0
            args: &[Expr],
    7623
    0
            deadline: Instant,
    7624
    0
            depth: usize,
    7625
    0
        ) -> Result<()> {
    7626
    0
            for arg in args {
    7627
    0
                let val = self.evaluate_expr(arg, deadline, depth + 1)?;
    7628
    0
                match val {
    7629
    0
                    Value::String(s) => print!(" {s}"),
    7630
    0
                    other => print!(" {other:?}"),
    7631
                }
    7632
            }
    7633
    0
            Ok(())
    7634
    0
        }
    7635
    7636
    0
        fn handle_fallback_println(
    7637
    0
            &mut self,
    7638
    0
            args: &[Expr],
    7639
    0
            deadline: Instant,
    7640
    0
            depth: usize,
    7641
    0
        ) -> Result<Value> {
    7642
    0
            let mut output = String::new();
    7643
    0
            for (i, arg) in args.iter().enumerate() {
    7644
    0
                if i > 0 {
    7645
    0
                    output.push(' ');
    7646
    0
                }
    7647
    0
                let val = self.evaluate_expr(arg, deadline, depth + 1)?;
    7648
    0
                match val {
    7649
    0
                    Value::String(s) => output.push_str(&s),
    7650
    0
                    other => output.push_str(&other.to_string()),
    7651
                }
    7652
            }
    7653
    0
            println!("{output}");
    7654
    0
            Self::ok_unit()
    7655
    0
        }
    7656
    7657
        /// Evaluate print function
    7658
    0
        fn evaluate_print(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    7659
    0
            let mut output = String::new();
    7660
    0
            for (i, arg) in args.iter().enumerate() {
    7661
    0
                if i > 0 {
    7662
    0
                    output.push(' ');
    7663
    0
                }
    7664
    0
                let val = self.evaluate_expr(arg, deadline, depth + 1)?;
    7665
    0
                match val {
    7666
    0
                    Value::String(s) => output.push_str(&s),
    7667
    0
                    other => output.push_str(&other.to_string()),
    7668
                }
    7669
            }
    7670
    0
            print!("{output}");
    7671
    0
            Self::ok_unit()
    7672
    0
        }
    7673
    7674
        /// Evaluate `input` function - prompt user for input
    7675
    0
        fn evaluate_input(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    7676
            use std::io::{self, Write};
    7677
    7678
            // Handle optional prompt argument
    7679
    0
            if args.len() > 1 {
    7680
    0
                bail!("input expects 0 or 1 arguments (optional prompt)");
    7681
    0
            }
    7682
    7683
            // Show prompt if provided
    7684
    0
            if let Some(prompt_expr) = args.first() {
    7685
    0
                let prompt_val = self.evaluate_expr(prompt_expr, deadline, depth + 1)?;
    7686
    0
                match prompt_val {
    7687
    0
                    Value::String(prompt) => print!("{prompt}"),
    7688
    0
                    other => print!("{other}"),
    7689
                }
    7690
    0
                io::stdout().flush().unwrap_or(());
    7691
    0
            }
    7692
    7693
            // Read line from stdin
    7694
    0
            let mut input = String::new();
    7695
    0
            match io::stdin().read_line(&mut input) {
    7696
                Ok(_) => {
    7697
                    // Remove trailing newline
    7698
    0
                    if input.ends_with('\n') {
    7699
    0
                        input.pop();
    7700
    0
                        if input.ends_with('\r') {
    7701
    0
                            input.pop();
    7702
    0
                        }
    7703
    0
                    }
    7704
    0
                    self.memory.try_alloc(input.len())?;
    7705
    0
                    Ok(Value::String(input))
    7706
                }
    7707
    0
                Err(e) => bail!("Failed to read input: {e}"),
    7708
            }
    7709
    0
        }
    7710
    7711
        /// Evaluate `readline` function - read a line from stdin
    7712
    0
        fn evaluate_readline(&mut self, args: &[Expr], _deadline: Instant, _depth: usize) -> Result<Value> {
    7713
            use std::io;
    7714
    7715
    0
            Self::validate_zero_args("readline", args.len())?;
    7716
    7717
    0
            let mut input = String::new();
    7718
    0
            match io::stdin().read_line(&mut input) {
    7719
                Ok(_) => {
    7720
                    // Remove trailing newline
    7721
    0
                    if input.ends_with('\n') {
    7722
    0
                        input.pop();
    7723
    0
                        if input.ends_with('\r') {
    7724
    0
                            input.pop();
    7725
    0
                        }
    7726
    0
                    }
    7727
    0
                    self.memory.try_alloc(input.len())?;
    7728
    0
                    Ok(Value::String(input))
    7729
                }
    7730
    0
                Err(e) => bail!("Failed to read line: {e}"),
    7731
            }
    7732
    0
        }
    7733
    7734
        /// Evaluate `assert` function - panic if condition is false
    7735
    0
        fn evaluate_assert(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    7736
    0
            if args.is_empty() || args.len() > 2 {
    7737
    0
                bail!("assert expects 1 or 2 arguments (condition, optional message)");
    7738
    0
            }
    7739
    7740
            // Evaluate condition
    7741
    0
            let condition = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    7742
    0
            let Value::Bool(is_true) = condition else {
    7743
    0
                bail!("assert expects a boolean condition, got {}", std::any::type_name_of_val(&condition))
    7744
            };
    7745
    7746
    0
            if !is_true {
    7747
                // Get optional message
    7748
    0
                let message = if args.len() > 1 {
    7749
    0
                    let msg_val = self.evaluate_arg(args, 1, deadline, depth)?;
    7750
    0
                    match msg_val {
    7751
    0
                        Value::String(s) => s,
    7752
    0
                        other => other.to_string(),
    7753
                    }
    7754
                } else {
    7755
    0
                    "Assertion failed".to_string()
    7756
                };
    7757
    7758
    0
                bail!("Assertion failed: {}", message);
    7759
    0
            }
    7760
    7761
    0
            Self::ok_unit()
    7762
    0
        }
    7763
    7764
        /// Evaluate `assert_eq` function - panic if values are not equal
    7765
    0
        fn evaluate_assert_eq(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    7766
    0
            if args.len() < 2 || args.len() > 3 {
    7767
    0
                bail!("assert_eq expects 2 or 3 arguments (left, right, optional message)");
    7768
    0
            }
    7769
    7770
            // Evaluate both values
    7771
    0
            let left = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    7772
    0
            let right = self.evaluate_arg(args, 1, deadline, depth)?;
    7773
    7774
            // Compare values
    7775
    0
            let are_equal = self.values_equal(&left, &right);
    7776
    7777
    0
            if !are_equal {
    7778
                // Get optional message
    7779
    0
                let message = if args.len() > 2 {
    7780
    0
                    let msg_val = self.evaluate_expr(&args[2], deadline, depth + 1)?;
    7781
    0
                    match msg_val {
    7782
    0
                        Value::String(s) => s,
    7783
    0
                        other => other.to_string(),
    7784
                    }
    7785
                } else {
    7786
    0
                    format!("assertion failed: `(left == right)`\n  left: `{left}`\n right: `{right}`")
    7787
                };
    7788
    7789
    0
                bail!("Assertion failed: {}", message);
    7790
    0
            }
    7791
    7792
    0
            Self::ok_unit()
    7793
    0
        }
    7794
    7795
        /// Evaluate `assert_ne` function - panic if values are equal
    7796
    0
        fn evaluate_assert_ne(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    7797
    0
            if args.len() < 2 || args.len() > 3 {
    7798
    0
                bail!("assert_ne expects 2 or 3 arguments (left, right, optional message)");
    7799
    0
            }
    7800
    7801
            // Evaluate both values
    7802
    0
            let left = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    7803
    0
            let right = self.evaluate_arg(args, 1, deadline, depth)?;
    7804
    7805
            // Compare values
    7806
    0
            let are_equal = self.values_equal(&left, &right);
    7807
    7808
    0
            if are_equal {
    7809
                // Get optional message
    7810
    0
                let message = if args.len() > 2 {
    7811
    0
                    let msg_val = self.evaluate_expr(&args[2], deadline, depth + 1)?;
    7812
    0
                    match msg_val {
    7813
    0
                        Value::String(s) => s,
    7814
    0
                        other => other.to_string(),
    7815
                    }
    7816
                } else {
    7817
    0
                    format!("assertion failed: `(left != right)`\n  left: `{left}`\n right: `{right}`")
    7818
                };
    7819
    7820
    0
                bail!("Assertion failed: {}", message);
    7821
    0
            }
    7822
    7823
    0
            Self::ok_unit()
    7824
    0
        }
    7825
    7826
        /// Evaluate `assert_true` function - panic if condition is false
    7827
    0
        fn evaluate_assert_true(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    7828
    0
            if args.is_empty() || args.len() > 2 {
    7829
    0
                bail!("assert_true expects 1 or 2 arguments (condition, optional message)");
    7830
    0
            }
    7831
    7832
            // Evaluate condition
    7833
    0
            let condition = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    7834
    7835
            // Check if condition is truthy
    7836
    0
            let is_true = match condition {
    7837
    0
                Value::Bool(b) => b,
    7838
    0
                _ => bail!("assert_true expects a boolean condition, got {}", self.get_value_type_name(&condition)),
    7839
            };
    7840
    7841
    0
            if !is_true {
    7842
                // Get optional message
    7843
    0
                let message = if args.len() > 1 {
    7844
    0
                    let msg_val = self.evaluate_expr(&args[1], deadline, depth + 1)?;
    7845
    0
                    match msg_val {
    7846
    0
                        Value::String(s) => s,
    7847
    0
                        other => other.to_string(),
    7848
                    }
    7849
                } else {
    7850
    0
                    "assertion failed: condition is false".to_string()
    7851
                };
    7852
    7853
    0
                bail!("Assertion failed: {}", message);
    7854
    0
            }
    7855
    7856
    0
            Self::ok_unit()
    7857
    0
        }
    7858
    7859
        /// Evaluate `assert_false` function - panic if condition is true
    7860
    0
        fn evaluate_assert_false(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    7861
    0
            if args.is_empty() || args.len() > 2 {
    7862
    0
                bail!("assert_false expects 1 or 2 arguments (condition, optional message)");
    7863
    0
            }
    7864
    7865
            // Evaluate condition
    7866
    0
            let condition = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    7867
    7868
            // Check if condition is falsy
    7869
    0
            let is_false = match condition {
    7870
    0
                Value::Bool(b) => !b,
    7871
    0
                _ => bail!("assert_false expects a boolean condition, got {}", self.get_value_type_name(&condition)),
    7872
            };
    7873
    7874
    0
            if !is_false {
    7875
                // Get optional message
    7876
    0
                let message = if args.len() > 1 {
    7877
    0
                    let msg_val = self.evaluate_expr(&args[1], deadline, depth + 1)?;
    7878
    0
                    match msg_val {
    7879
    0
                        Value::String(s) => s,
    7880
    0
                        other => other.to_string(),
    7881
                    }
    7882
                } else {
    7883
    0
                    "assertion failed: condition is true".to_string()
    7884
                };
    7885
    7886
    0
                bail!("Assertion failed: {}", message);
    7887
    0
            }
    7888
    7889
    0
            Self::ok_unit()
    7890
    0
        }
    7891
    7892
        /// Compare two values for equality (helper for assertions)
    7893
    0
        fn values_equal(&self, left: &Value, right: &Value) -> bool {
    7894
    0
            match (left, right) {
    7895
    0
                (Value::Int(a), Value::Int(b)) => a == b,
    7896
    0
                (Value::Float(a), Value::Float(b)) => (a - b).abs() < f64::EPSILON,
    7897
    0
                (Value::Int(a), Value::Float(b)) => (*a as f64 - b).abs() < f64::EPSILON,
    7898
    0
                (Value::Float(a), Value::Int(b)) => (a - *b as f64).abs() < f64::EPSILON,
    7899
    0
                (Value::String(a), Value::String(b)) => a == b,
    7900
    0
                (Value::Bool(a), Value::Bool(b)) => a == b,
    7901
    0
                (Value::Unit, Value::Unit) => true,
    7902
    0
                (Value::List(a), Value::List(b)) => {
    7903
    0
                    a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| self.values_equal(x, y))
    7904
                }
    7905
    0
                (Value::Tuple(a), Value::Tuple(b)) => {
    7906
    0
                    a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| self.values_equal(x, y))
    7907
                }
    7908
    0
                _ => false,
    7909
            }
    7910
    0
        }
    7911
    7912
        /// Evaluate `read_file` function
    7913
    0
        fn evaluate_read_file(
    7914
    0
            &mut self,
    7915
    0
            args: &[Expr],
    7916
    0
            deadline: Instant,
    7917
    0
            depth: usize,
    7918
    0
        ) -> Result<Value> {
    7919
    0
            if args.len() != 1 {
    7920
    0
                bail!("read_file expects exactly 1 argument (filename)");
    7921
    0
            }
    7922
    7923
    0
            let filename_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    7924
    0
            let Value::String(filename) = filename_val else {
    7925
    0
                bail!("read_file expects a string filename")
    7926
            };
    7927
    7928
    0
            match std::fs::read_to_string(&filename) {
    7929
    0
                Ok(content) => Ok(Value::String(content)),
    7930
    0
                Err(e) => bail!("Failed to read file '{}': {}", filename, e),
    7931
            }
    7932
    0
        }
    7933
    7934
        /// Evaluate `write_file` function
    7935
    0
        fn evaluate_write_file(
    7936
    0
            &mut self,
    7937
    0
            args: &[Expr],
    7938
    0
            deadline: Instant,
    7939
    0
            depth: usize,
    7940
    0
        ) -> Result<Value> {
    7941
    0
            if args.len() != 2 {
    7942
    0
                bail!("write_file expects exactly 2 arguments (filename, content)");
    7943
    0
            }
    7944
    7945
    0
            let filename_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    7946
    0
            let Value::String(filename) = filename_val else {
    7947
    0
                bail!("write_file expects a string filename")
    7948
            };
    7949
    7950
    0
            let content_val = self.evaluate_arg(args, 1, deadline, depth)?;
    7951
    0
            let content = if let Value::String(s) = content_val {
    7952
    0
                s
    7953
            } else {
    7954
    0
                content_val.to_string()
    7955
            };
    7956
    7957
    0
            match std::fs::write(&filename, content) {
    7958
                Ok(()) => {
    7959
    0
                    println!("File '{filename}' written successfully");
    7960
    0
                    Self::ok_unit()
    7961
                }
    7962
    0
                Err(e) => bail!("Failed to write file '{}': {}", filename, e),
    7963
            }
    7964
    0
        }
    7965
    7966
        /// Evaluate `append_file` function
    7967
    0
        fn evaluate_append_file(
    7968
    0
            &mut self,
    7969
    0
            args: &[Expr],
    7970
    0
            deadline: Instant,
    7971
    0
            depth: usize,
    7972
    0
        ) -> Result<Value> {
    7973
    0
            if args.len() != 2 {
    7974
    0
                bail!("append_file expects exactly 2 arguments (filename, content)");
    7975
    0
            }
    7976
    7977
    0
            let filename_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    7978
    0
            let Value::String(filename) = filename_val else {
    7979
    0
                bail!("append_file expects a string filename")
    7980
            };
    7981
    7982
    0
            let content_val = self.evaluate_arg(args, 1, deadline, depth)?;
    7983
    0
            let content = if let Value::String(s) = content_val {
    7984
    0
                s
    7985
            } else {
    7986
    0
                content_val.to_string()
    7987
            };
    7988
    7989
    0
            match std::fs::OpenOptions::new()
    7990
    0
                .create(true)
    7991
    0
                .append(true)
    7992
    0
                .open(&filename)
    7993
            {
    7994
    0
                Ok(mut file) => {
    7995
                    use std::io::Write;
    7996
    0
                    match file.write_all(content.as_bytes()) {
    7997
    0
                        Ok(()) => Ok(Value::Unit),
    7998
    0
                        Err(e) => bail!("Failed to append to file '{}': {}", filename, e),
    7999
                    }
    8000
                }
    8001
    0
                Err(e) => bail!("Failed to open file '{}' for append: {}", filename, e),
    8002
            }
    8003
    0
        }
    8004
    8005
        /// Evaluate `file_exists` function
    8006
    0
        fn evaluate_file_exists(
    8007
    0
            &mut self,
    8008
    0
            args: &[Expr],
    8009
    0
            deadline: Instant,
    8010
    0
            depth: usize,
    8011
    0
        ) -> Result<Value> {
    8012
    0
            if args.len() != 1 {
    8013
    0
                bail!("file_exists expects exactly 1 argument (filename)");
    8014
    0
            }
    8015
    8016
    0
            let filename_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    8017
    0
            let Value::String(filename) = filename_val else {
    8018
    0
                bail!("file_exists expects a string filename")
    8019
            };
    8020
    8021
    0
            let exists = std::path::Path::new(&filename).exists();
    8022
    0
            Ok(Value::Bool(exists))
    8023
    0
        }
    8024
    8025
        /// Evaluate `delete_file` function
    8026
    0
        fn evaluate_delete_file(
    8027
    0
            &mut self,
    8028
    0
            args: &[Expr],
    8029
    0
            deadline: Instant,
    8030
    0
            depth: usize,
    8031
    0
        ) -> Result<Value> {
    8032
    0
            if args.len() != 1 {
    8033
    0
                bail!("delete_file expects exactly 1 argument (filename)");
    8034
    0
            }
    8035
    8036
    0
            let filename_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    8037
    0
            let Value::String(filename) = filename_val else {
    8038
    0
                bail!("delete_file expects a string filename")
    8039
            };
    8040
    8041
    0
            match std::fs::remove_file(&filename) {
    8042
    0
                Ok(()) => Ok(Value::Unit),
    8043
    0
                Err(e) => bail!("Failed to delete file '{}': {}", filename, e),
    8044
            }
    8045
    0
        }
    8046
    8047
        /// Evaluate `current_dir` function
    8048
    0
        fn evaluate_current_dir(
    8049
    0
            &mut self,
    8050
    0
            args: &[Expr],
    8051
    0
            _deadline: Instant,
    8052
    0
            _depth: usize,
    8053
    0
        ) -> Result<Value> {
    8054
    0
            Self::validate_zero_args("current_dir", args.len())?;
    8055
    8056
    0
            match std::env::current_dir() {
    8057
    0
                Ok(path) => Ok(Value::String(path.to_string_lossy().to_string())),
    8058
    0
                Err(e) => bail!("Failed to get current directory: {}", e),
    8059
            }
    8060
    0
        }
    8061
    8062
        /// Evaluate `env` function
    8063
    0
        fn evaluate_env(
    8064
    0
            &mut self,
    8065
    0
            args: &[Expr],
    8066
    0
            deadline: Instant,
    8067
    0
            depth: usize,
    8068
    0
        ) -> Result<Value> {
    8069
    0
            if args.len() != 1 {
    8070
    0
                bail!("env expects exactly 1 argument (variable name)");
    8071
    0
            }
    8072
    8073
    0
            let var_name_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    8074
    0
            let Value::String(var_name) = var_name_val else {
    8075
    0
                bail!("env expects a string variable name")
    8076
            };
    8077
    8078
    0
            match std::env::var(&var_name) {
    8079
    0
                Ok(value) => Ok(Value::String(value)),
    8080
    0
                Err(_) => Ok(Value::String(String::new())), // Return empty string for non-existent vars
    8081
            }
    8082
    0
        }
    8083
    8084
        /// Evaluate `set_env` function
    8085
    0
        fn evaluate_set_env(
    8086
    0
            &mut self,
    8087
    0
            args: &[Expr],
    8088
    0
            deadline: Instant,
    8089
    0
            depth: usize,
    8090
    0
        ) -> Result<Value> {
    8091
    0
            if args.len() != 2 {
    8092
    0
                bail!("set_env expects exactly 2 arguments (variable name, value)");
    8093
    0
            }
    8094
    8095
    0
            let var_name_val = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    8096
    0
            let Value::String(var_name) = var_name_val else {
    8097
    0
                bail!("set_env expects a string variable name")
    8098
            };
    8099
    8100
    0
            let value_val = self.evaluate_arg(args, 1, deadline, depth)?;
    8101
    0
            let value = if let Value::String(s) = value_val {
    8102
    0
                s
    8103
            } else {
    8104
    0
                value_val.to_string()
    8105
            };
    8106
    8107
    0
            std::env::set_var(var_name, value);
    8108
    0
            Self::ok_unit()
    8109
    0
        }
    8110
    8111
        /// Evaluate `args` function
    8112
    0
        fn evaluate_args(
    8113
    0
            &mut self,
    8114
    0
            args: &[Expr],
    8115
    0
            _deadline: Instant,
    8116
    0
            _depth: usize,
    8117
    0
        ) -> Result<Value> {
    8118
    0
            if !args.is_empty() {
    8119
    0
                bail!("args expects no arguments");
    8120
    0
            }
    8121
    8122
    0
            let args_vec = std::env::args().collect::<Vec<String>>();
    8123
    0
            let values: Vec<Value> = args_vec.into_iter().map(Value::String).collect();
    8124
    0
            Self::ok_list(values)
    8125
    0
        }
    8126
    8127
        /// Evaluate `Some` constructor
    8128
    0
        fn evaluate_some(
    8129
    0
            &mut self,
    8130
    0
            args: &[Expr],
    8131
    0
            deadline: Instant,
    8132
    0
            depth: usize,
    8133
    0
        ) -> Result<Value> {
    8134
    0
            if args.len() != 1 {
    8135
    0
                Self::validate_exact_args("Some", 1, args.len())?;
    8136
    0
            }
    8137
    8138
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    8139
    0
            Ok(Value::EnumVariant {
    8140
    0
                enum_name: "Option".to_string(),
    8141
    0
                variant_name: "Some".to_string(),
    8142
    0
                data: Some(vec![value]),
    8143
    0
            })
    8144
    0
        }
    8145
    8146
        /// Evaluate `None` constructor
    8147
    0
        fn evaluate_none(
    8148
    0
            &mut self,
    8149
    0
            args: &[Expr],
    8150
    0
            _deadline: Instant,
    8151
    0
            _depth: usize,
    8152
    0
        ) -> Result<Value> {
    8153
    0
            if !args.is_empty() {
    8154
    0
                bail!("None expects no arguments");
    8155
    0
            }
    8156
    8157
    0
            Ok(Self::create_option_none())
    8158
    0
        }
    8159
    8160
        /// Evaluate `Ok` constructor
    8161
    0
        fn evaluate_ok(
    8162
    0
            &mut self,
    8163
    0
            args: &[Expr],
    8164
    0
            deadline: Instant,
    8165
    0
            depth: usize,
    8166
    0
        ) -> Result<Value> {
    8167
    0
            if args.len() != 1 {
    8168
    0
                Self::validate_exact_args("Ok", 1, args.len())?;
    8169
    0
            }
    8170
    8171
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    8172
    0
            Ok(Value::EnumVariant {
    8173
    0
                enum_name: "Result".to_string(),
    8174
    0
                variant_name: "Ok".to_string(),
    8175
    0
                data: Some(vec![value]),
    8176
    0
            })
    8177
    0
        }
    8178
    8179
        /// Evaluate `Err` constructor
    8180
    0
        fn evaluate_err(
    8181
    0
            &mut self,
    8182
    0
            args: &[Expr],
    8183
    0
            deadline: Instant,
    8184
    0
            depth: usize,
    8185
    0
        ) -> Result<Value> {
    8186
    0
            if args.len() != 1 {
    8187
    0
                Self::validate_exact_args("Err", 1, args.len())?;
    8188
    0
            }
    8189
    8190
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    8191
    0
            Ok(Value::EnumVariant {
    8192
    0
                enum_name: "Result".to_string(),
    8193
    0
                variant_name: "Err".to_string(),
    8194
    0
                data: Some(vec![value]),
    8195
    0
            })
    8196
    0
        }
    8197
    8198
        /// Update history variables (_ and _n)
    8199
    0
        fn update_history_variables(&mut self) {
    8200
    0
            let len = self.result_history.len();
    8201
    0
            if len == 0 {
    8202
    0
                return;
    8203
    0
            }
    8204
    8205
            // Set _ to the most recent result
    8206
    0
            let last_result = self.result_history[len - 1].clone();
    8207
    0
            self.bindings.insert("_".to_string(), last_result);
    8208
    0
            self.binding_mutability.insert("_".to_string(), false); // History variables are immutable
    8209
    8210
            // Set _n variables for indexed access
    8211
    0
            for (i, result) in self.result_history.iter().enumerate() {
    8212
    0
                let var_name = format!("_{}", i + 1);
    8213
    0
                self.bindings.insert(var_name.clone(), result.clone());
    8214
    0
                self.binding_mutability.insert(var_name, false); // History variables are immutable
    8215
    0
            }
    8216
    0
        }
    8217
    8218
        /// Handle REPL magic commands
    8219
        /// Handle %time magic command (complexity: 3)
    8220
    0
        fn handle_time_magic(&mut self, args: &str) -> Result<String> {
    8221
    0
            if args.is_empty() {
    8222
    0
                return Ok("Usage: %time <expression>".to_string());
    8223
    0
            }
    8224
    8225
    0
            let start = std::time::Instant::now();
    8226
    0
            let result = self.eval(args)?;
    8227
    0
            let elapsed = start.elapsed();
    8228
    8229
    0
            Ok(format!("{result}\nExecuted in: {elapsed:?}"))
    8230
    0
        }
    8231
    8232
        /// Handle %timeit magic command (complexity: 4)
    8233
    0
        fn handle_timeit_magic(&mut self, args: &str) -> Result<String> {
    8234
    0
            if args.is_empty() {
    8235
    0
                return Ok("Usage: %timeit <expression>".to_string());
    8236
    0
            }
    8237
    8238
            const ITERATIONS: usize = 1000;
    8239
    0
            let mut total_time = std::time::Duration::new(0, 0);
    8240
    0
            let mut last_result = String::new();
    8241
    8242
    0
            for _ in 0..ITERATIONS {
    8243
    0
                let start = std::time::Instant::now();
    8244
    0
                last_result = self.eval(args)?;
    8245
    0
                total_time += start.elapsed();
    8246
            }
    8247
    8248
    0
            let avg_time = total_time / ITERATIONS as u32;
    8249
    0
            Ok(format!(
    8250
    0
                "{last_result}\n{ITERATIONS} loops, average: {avg_time:?} per loop"
    8251
    0
            ))
    8252
    0
        }
    8253
    8254
        /// Handle %run magic command (complexity: 6)
    8255
    0
        fn handle_run_magic(&mut self, args: &str) -> Result<String> {
    8256
    0
            if args.is_empty() {
    8257
    0
                return Ok("Usage: %run <script.ruchy>".to_string());
    8258
    0
            }
    8259
    8260
    0
            match std::fs::read_to_string(args) {
    8261
    0
                Ok(content) => {
    8262
    0
                    let lines: Vec<&str> = content.lines().collect();
    8263
    0
                    let mut results = Vec::new();
    8264
    8265
    0
                    for line in lines {
    8266
    0
                        let trimmed = line.trim();
    8267
    0
                        if !trimmed.is_empty() && !trimmed.starts_with("//") {
    8268
    0
                            match self.eval(trimmed) {
    8269
    0
                                Ok(result) => results.push(result),
    8270
    0
                                Err(e) => return Err(e.context(format!("Error executing: {trimmed}"))),
    8271
                            }
    8272
    0
                        }
    8273
                    }
    8274
    8275
    0
                    Ok(results.join("\n"))
    8276
                }
    8277
    0
                Err(e) => Ok(format!("Failed to read file '{args}': {e}"))
    8278
            }
    8279
    0
        }
    8280
    8281
        /// Handle %debug magic command (complexity: 7)
    8282
    0
        fn handle_debug_magic(&self) -> Result<String> {
    8283
    0
            if let Some(ref debug_info) = self.last_error_debug {
    8284
    0
                let mut output = String::new();
    8285
    0
                output.push_str("=== Debug Information ===\n");
    8286
    0
                output.push_str(&format!("Expression: {}\n", debug_info.expression));
    8287
    0
                output.push_str(&format!("Error: {}\n", debug_info.error_message));
    8288
    0
                output.push_str(&format!("Time: {:?}\n", debug_info.timestamp));
    8289
    0
                output.push_str("\n--- Variable Bindings at Error ---\n");
    8290
    8291
    0
                for (name, value) in &debug_info.bindings_snapshot {
    8292
    0
                    output.push_str(&format!("{name}: {value}\n"));
    8293
    0
                }
    8294
    8295
    0
                if !debug_info.stack_trace.is_empty() {
    8296
    0
                    output.push_str("\n--- Stack Trace ---\n");
    8297
    0
                    for frame in &debug_info.stack_trace {
    8298
    0
                        output.push_str(&format!("  {frame}\n"));
    8299
    0
                    }
    8300
    0
                }
    8301
    8302
    0
                Ok(output)
    8303
            } else {
    8304
    0
                Ok("No debug information available. Run an expression that fails first.".to_string())
    8305
            }
    8306
    0
        }
    8307
    8308
        /// Handle %profile magic command - parsing phase (complexity: 5)
    8309
    0
        fn profile_parse_phase(&self, args: &str) -> Result<(Expr, std::time::Duration, usize)> {
    8310
    0
            let parse_start = std::time::Instant::now();
    8311
    0
            let mut parser = Parser::new(args);
    8312
    0
            let ast = match parser.parse() {
    8313
    0
                Ok(ast) => ast,
    8314
    0
                Err(e) => return Err(anyhow::anyhow!("Parse error: {e}")),
    8315
            };
    8316
    0
            let parse_time = parse_start.elapsed();
    8317
    0
            let alloc_size = std::mem::size_of_val(&ast);
    8318
    0
            Ok((ast, parse_time, alloc_size))
    8319
    0
        }
    8320
    8321
        /// Handle %profile magic command - evaluation phase (complexity: 4)
    8322
    0
        fn profile_eval_phase(&mut self, ast: &Expr) -> Result<(Value, std::time::Duration)> {
    8323
    0
            let eval_start = std::time::Instant::now();
    8324
    0
            let deadline = std::time::Instant::now() + self.config.timeout;
    8325
    0
            let result = match self.evaluate_expr(ast, deadline, 0) {
    8326
    0
                Ok(value) => value,
    8327
    0
                Err(e) => return Err(anyhow::anyhow!("Evaluation error: {e}")),
    8328
            };
    8329
    0
            let eval_time = eval_start.elapsed();
    8330
    0
            Ok((result, eval_time))
    8331
    0
        }
    8332
    8333
        /// Format profile analysis output (complexity: 6)
    8334
    0
        fn format_profile_analysis(
    8335
    0
            &self,
    8336
    0
            total_time: std::time::Duration,
    8337
    0
            parse_time: std::time::Duration,
    8338
    0
            eval_time: std::time::Duration,
    8339
    0
        ) -> String {
    8340
    0
            let mut output = String::new();
    8341
    0
            output.push_str("\n--- Analysis ---\n");
    8342
    8343
    0
            if total_time.as_millis() > 50 {
    8344
    0
                output.push_str("⚠️  Slow execution (>50ms)\n");
    8345
    0
            } else if total_time.as_millis() > 10 {
    8346
    0
                output.push_str("⚡ Moderate performance (>10ms)\n");
    8347
    0
            } else {
    8348
    0
                output.push_str("🚀 Fast execution (<10ms)\n");
    8349
    0
            }
    8350
    8351
    0
            if parse_time.as_secs_f64() / total_time.as_secs_f64() > 0.3 {
    8352
    0
                output.push_str("📝 Parse-heavy (consider simpler syntax)\n");
    8353
    0
            }
    8354
    8355
    0
            if eval_time.as_secs_f64() / total_time.as_secs_f64() > 0.7 {
    8356
    0
                output.push_str("🧮 Compute-heavy (consider optimization)\n");
    8357
    0
            }
    8358
    8359
    0
            output
    8360
    0
        }
    8361
    8362
        /// Handle %profile magic command (complexity: 8)
    8363
    0
        fn handle_profile_magic(&mut self, args: &str) -> Result<String> {
    8364
    0
            if args.is_empty() {
    8365
    0
                return Ok("Usage: %profile <expression>".to_string());
    8366
    0
            }
    8367
    8368
    0
            let start = std::time::Instant::now();
    8369
    8370
            // Parse phase
    8371
    0
            let (ast, parse_time, alloc_size) = self.profile_parse_phase(args)?;
    8372
    8373
            // Evaluation phase
    8374
    0
            let (result, eval_time) = self.profile_eval_phase(&ast)?;
    8375
    8376
    0
            let total_time = start.elapsed();
    8377
    8378
            // Generate profile report
    8379
    0
            let mut output = String::new();
    8380
    0
            output.push_str("=== Performance Profile ===\n");
    8381
    0
            output.push_str(&format!("Expression: {args}\n"));
    8382
    0
            output.push_str(&format!("Result: {result}\n\n"));
    8383
    8384
    0
            output.push_str("--- Timing Breakdown ---\n");
    8385
    0
            output.push_str(&format!("Parse:     {:>8.3}ms ({:>5.1}%)\n",
    8386
    0
                parse_time.as_secs_f64() * 1000.0,
    8387
    0
                (parse_time.as_secs_f64() / total_time.as_secs_f64()) * 100.0));
    8388
    0
            output.push_str(&format!("Evaluate:  {:>8.3}ms ({:>5.1}%)\n",
    8389
    0
                eval_time.as_secs_f64() * 1000.0,
    8390
    0
                (eval_time.as_secs_f64() / total_time.as_secs_f64()) * 100.0));
    8391
    0
            output.push_str(&format!("Total:     {:>8.3}ms\n\n",
    8392
    0
                total_time.as_secs_f64() * 1000.0));
    8393
    8394
    0
            output.push_str("--- Memory Usage ---\n");
    8395
    0
            output.push_str(&format!("AST size:  {alloc_size:>8} bytes\n"));
    8396
    0
            output.push_str(&format!("Memory:    {:>8} bytes used\n", self.memory.current));
    8397
    8398
            // Add performance analysis
    8399
    0
            output.push_str(&self.format_profile_analysis(total_time, parse_time, eval_time));
    8400
    8401
    0
            Ok(output)
    8402
    0
        }
    8403
    8404
        /// Handle %help magic command (complexity: 1)
    8405
    0
        fn handle_help_magic(&self) -> Result<String> {
    8406
    0
            Ok(r"Available magic commands:
    8407
    0
    %time <expr>     - Time a single execution
    8408
    0
    %timeit <expr>   - Time multiple executions (benchmark)
    8409
    0
    %run <file>      - Execute a .ruchy script file
    8410
    0
    %debug           - Show debug info from last error
    8411
    0
    %profile <expr>  - Generate execution profile
    8412
    0
    %help            - Show this help message".to_string())
    8413
    0
        }
    8414
    8415
    0
        fn handle_magic_command(&mut self, command: &str) -> Result<String> {
    8416
            // Uses legacy implementation for backward compatibility
    8417
            // Future: Consider refactoring to use magic registry pattern
    8418
    8419
            // Fall back to legacy implementation for backward compatibility
    8420
    0
            let parts: Vec<&str> = command.splitn(2, ' ').collect();
    8421
    0
            let magic_cmd = parts[0];
    8422
    0
            let args = if parts.len() > 1 { parts[1] } else { "" };
    8423
    8424
    0
            match magic_cmd {
    8425
    0
                "%time" => self.handle_time_magic(args),
    8426
    0
                "%timeit" => self.handle_timeit_magic(args),
    8427
    0
                "%run" => self.handle_run_magic(args),
    8428
    0
                "%debug" => self.handle_debug_magic(),
    8429
    0
                "%profile" => self.handle_profile_magic(args),
    8430
    0
                "%help" => self.handle_help_magic(),
    8431
    0
                _ => Ok(format!("Unknown magic command: {magic_cmd}. Type %help for available commands.")),
    8432
            }
    8433
    0
        }
    8434
    8435
        /// Evaluate `str` type conversion function
    8436
    0
        fn evaluate_str_conversion(
    8437
    0
            &mut self,
    8438
    0
            args: &[Expr],
    8439
    0
            deadline: Instant,
    8440
    0
            depth: usize,
    8441
    0
        ) -> Result<Value> {
    8442
    0
            if args.len() != 1 {
    8443
    0
                bail!("str() expects exactly 1 argument");
    8444
    0
            }
    8445
    8446
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    8447
    0
            match value {
    8448
    0
                Value::Char(c) => Ok(Value::String(c.to_string())),
    8449
    0
                _ => Ok(Value::String(value.to_string())),
    8450
            }
    8451
    0
        }
    8452
    8453
        /// Evaluate `int` type conversion function
    8454
    0
        fn evaluate_int_conversion(
    8455
    0
            &mut self,
    8456
    0
            args: &[Expr],
    8457
    0
            deadline: Instant,
    8458
    0
            depth: usize,
    8459
    0
        ) -> Result<Value> {
    8460
    0
            if args.is_empty() || args.len() > 2 {
    8461
    0
                bail!("int() expects 1 or 2 arguments");
    8462
    0
            }
    8463
    8464
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    8465
    8466
            // Handle two-argument form for base conversion
    8467
    0
            if args.len() == 2 {
    8468
    0
                if let Value::String(s) = value {
    8469
    0
                    let base_val = self.evaluate_arg(args, 1, deadline, depth)?;
    8470
    0
                    if let Value::Int(base) = base_val {
    8471
    0
                        if !(2..=36).contains(&base) {
    8472
    0
                            bail!("int() base must be between 2 and 36");
    8473
    0
                        }
    8474
                        // Remove common prefixes
    8475
    0
                        let cleaned = s.trim_start_matches("0x")
    8476
    0
                            .trim_start_matches("0X")
    8477
    0
                            .trim_start_matches("0b")
    8478
    0
                            .trim_start_matches("0B")
    8479
    0
                            .trim_start_matches("0o")
    8480
    0
                            .trim_start_matches("0O");
    8481
    8482
    0
                        match i64::from_str_radix(cleaned, base as u32) {
    8483
    0
                            Ok(n) => return Ok(Value::Int(n)),
    8484
    0
                            Err(_) => bail!("Cannot parse '{}' as base {} integer", s, base),
    8485
                        }
    8486
    0
                    }
    8487
    0
                    bail!("int() base must be an integer");
    8488
    0
                }
    8489
    0
                bail!("int() with base requires string as first argument");
    8490
    0
            }
    8491
    8492
    0
            match value {
    8493
    0
                Value::Int(n) => Ok(Value::Int(n)),
    8494
    0
                Value::Float(f) => Ok(Value::Int(f as i64)),
    8495
    0
                Value::Bool(b) => Ok(Value::Int(i64::from(b))),
    8496
    0
                Value::String(s) => {
    8497
                    // Try parsing as number first
    8498
    0
                    if let Ok(n) = s.trim().parse::<i64>() {
    8499
    0
                        return Ok(Value::Int(n));
    8500
    0
                    }
    8501
                    // Check for boolean strings
    8502
    0
                    if s == "true" {
    8503
    0
                        return Self::ok_int(1);
    8504
    0
                    }
    8505
    0
                    if s == "false" {
    8506
    0
                        return Self::ok_int(0);
    8507
    0
                    }
    8508
    0
                    bail!("Cannot convert '{}' to integer", s)
    8509
                }
    8510
    0
                _ => bail!("Cannot convert value to integer"),
    8511
            }
    8512
    0
        }
    8513
    8514
        /// Evaluate `float` type conversion function
    8515
    0
        fn evaluate_float_conversion(
    8516
    0
            &mut self,
    8517
    0
            args: &[Expr],
    8518
    0
            deadline: Instant,
    8519
    0
            depth: usize,
    8520
    0
        ) -> Result<Value> {
    8521
    0
            if args.len() != 1 {
    8522
    0
                bail!("float() expects exactly 1 argument");
    8523
    0
            }
    8524
    8525
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    8526
    0
            match value {
    8527
    0
                Value::Float(f) => Ok(Value::Float(f)),
    8528
    0
                Value::Int(n) => Ok(Value::Float(n as f64)),
    8529
    0
                Value::Bool(b) => Ok(Value::Float(f64::from(b))),
    8530
    0
                Value::String(s) => {
    8531
    0
                    match s.trim().parse::<f64>() {
    8532
    0
                        Ok(f) => Ok(Value::Float(f)),
    8533
    0
                        Err(_) => bail!("Cannot convert '{}' to float", s),
    8534
                    }
    8535
                }
    8536
    0
                _ => bail!("Cannot convert value to float"),
    8537
            }
    8538
    0
        }
    8539
    8540
        /// Evaluate `bool` type conversion function
    8541
    0
        fn evaluate_bool_conversion(
    8542
    0
            &mut self,
    8543
    0
            args: &[Expr],
    8544
    0
            deadline: Instant,
    8545
    0
            depth: usize,
    8546
    0
        ) -> Result<Value> {
    8547
    0
            if args.len() != 1 {
    8548
    0
                bail!("bool() expects exactly 1 argument");
    8549
    0
            }
    8550
    8551
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    8552
    0
            match value {
    8553
    0
                Value::Bool(b) => Ok(Value::Bool(b)),
    8554
    0
                Value::Int(n) => Ok(Value::Bool(n != 0)),
    8555
    0
                Value::Float(f) => Ok(Value::Bool(f != 0.0 && !f.is_nan())),
    8556
    0
                Value::String(s) => Ok(Value::Bool(!s.is_empty() && s != "false")),
    8557
    0
                Value::Unit => Ok(Value::Bool(false)),
    8558
    0
                Value::List(l) => Ok(Value::Bool(!l.is_empty())),
    8559
    0
                Value::Object(o) => Ok(Value::Bool(!o.is_empty())),
    8560
    0
                _ => Ok(Value::Bool(true)), // Most other values are truthy
    8561
            }
    8562
    0
        }
    8563
    8564
        /// Evaluate `sin()` function
    8565
    0
        fn evaluate_sin(
    8566
    0
            &mut self,
    8567
    0
            args: &[Expr],
    8568
    0
            deadline: Instant,
    8569
    0
            depth: usize,
    8570
    0
        ) -> Result<Value> {
    8571
    0
            self.evaluate_unary_math_function(args, deadline, depth, "sin", f64::sin)
    8572
    0
        }
    8573
    8574
        /// Evaluate `cos()` function
    8575
    0
        fn evaluate_cos(
    8576
    0
            &mut self,
    8577
    0
            args: &[Expr],
    8578
    0
            deadline: Instant,
    8579
    0
            depth: usize,
    8580
    0
        ) -> Result<Value> {
    8581
    0
            self.evaluate_unary_math_function(args, deadline, depth, "cos", f64::cos)
    8582
    0
        }
    8583
    8584
        /// Evaluate `tan()` function
    8585
    0
        fn evaluate_tan(
    8586
    0
            &mut self,
    8587
    0
            args: &[Expr],
    8588
    0
            deadline: Instant,
    8589
    0
            depth: usize,
    8590
    0
        ) -> Result<Value> {
    8591
    0
            self.evaluate_unary_math_function(args, deadline, depth, "tan", f64::tan)
    8592
    0
        }
    8593
    8594
        /// Evaluate `log()` function (natural logarithm)
    8595
    0
        fn evaluate_log(
    8596
    0
            &mut self,
    8597
    0
            args: &[Expr],
    8598
    0
            deadline: Instant,
    8599
    0
            depth: usize,
    8600
    0
        ) -> Result<Value> {
    8601
    0
            let validator = |f: f64| -> Result<()> {
    8602
    0
                if f <= 0.0 {
    8603
    0
                    bail!("log() requires a positive argument");
    8604
    0
                }
    8605
    0
                Ok(())
    8606
    0
            };
    8607
    0
            self.evaluate_unary_math_function_validated(args, deadline, depth, "log", f64::ln, validator)
    8608
    0
        }
    8609
    8610
        /// Evaluate `log10()` function (base-10 logarithm)
    8611
    0
        fn evaluate_log10(
    8612
    0
            &mut self,
    8613
    0
            args: &[Expr],
    8614
    0
            deadline: Instant,
    8615
    0
            depth: usize,
    8616
    0
        ) -> Result<Value> {
    8617
    0
            let validator = |f: f64| -> Result<()> {
    8618
    0
                if f <= 0.0 {
    8619
    0
                    bail!("log10() requires a positive argument");
    8620
    0
                }
    8621
    0
                Ok(())
    8622
    0
            };
    8623
    0
            self.evaluate_unary_math_function_validated(args, deadline, depth, "log10", f64::log10, validator)
    8624
    0
        }
    8625
    8626
        /// Evaluate `char()` conversion function (complexity: 6)
    8627
    0
        fn evaluate_char_conversion(
    8628
    0
            &mut self,
    8629
    0
            args: &[Expr],
    8630
    0
            deadline: Instant,
    8631
    0
            depth: usize,
    8632
    0
        ) -> Result<Value> {
    8633
    0
            if args.len() != 1 {
    8634
    0
                bail!("char() expects exactly 1 argument");
    8635
    0
            }
    8636
    8637
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    8638
    0
            match value {
    8639
    0
                Value::Int(n) => {
    8640
    0
                    if !(0..=1_114_111).contains(&n) {
    8641
    0
                        bail!("char() expects a valid Unicode code point (0-1114111)");
    8642
    0
                    }
    8643
    0
                    match char::from_u32(n as u32) {
    8644
    0
                        Some(c) => Self::ok_char(c),
    8645
    0
                        None => bail!("Invalid Unicode code point: {}", n),
    8646
                    }
    8647
                }
    8648
    0
                Value::String(s) => {
    8649
    0
                    if s.len() == 1 {
    8650
    0
                        Self::ok_char(s.chars().next().unwrap())
    8651
                    } else {
    8652
    0
                        bail!("char() from string expects exactly 1 character, got {}", s.len());
    8653
                    }
    8654
                }
    8655
    0
                _ => bail!("char() expects an integer or single-character string"),
    8656
            }
    8657
    0
        }
    8658
    8659
        /// Evaluate `hex()` conversion - int to hex string (complexity: 5)
    8660
    0
        fn evaluate_hex_conversion(
    8661
    0
            &mut self,
    8662
    0
            args: &[Expr],
    8663
    0
            deadline: Instant,
    8664
    0
            depth: usize,
    8665
    0
        ) -> Result<Value> {
    8666
    0
            if args.len() != 1 {
    8667
    0
                bail!("hex() expects exactly 1 argument");
    8668
    0
            }
    8669
    8670
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    8671
    0
            match value {
    8672
    0
                Value::Int(n) => {
    8673
    0
                    if n < 0 {
    8674
    0
                        Ok(Value::String(format!("-0x{:x}", -n)))
    8675
                    } else {
    8676
    0
                        Ok(Value::String(format!("0x{n:x}")))
    8677
                    }
    8678
                }
    8679
    0
                _ => bail!("hex() expects an integer"),
    8680
            }
    8681
    0
        }
    8682
    8683
        /// Evaluate `bin()` conversion - int to binary string (complexity: 5)
    8684
    0
        fn evaluate_bin_conversion(
    8685
    0
            &mut self,
    8686
    0
            args: &[Expr],
    8687
    0
            deadline: Instant,
    8688
    0
            depth: usize,
    8689
    0
        ) -> Result<Value> {
    8690
    0
            if args.len() != 1 {
    8691
    0
                bail!("bin() expects exactly 1 argument");
    8692
    0
            }
    8693
    8694
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    8695
    0
            match value {
    8696
    0
                Value::Int(n) => {
    8697
    0
                    if n < 0 {
    8698
    0
                        Ok(Value::String(format!("-0b{:b}", -n)))
    8699
                    } else {
    8700
    0
                        Ok(Value::String(format!("0b{n:b}")))
    8701
                    }
    8702
                }
    8703
    0
                _ => bail!("bin() expects an integer"),
    8704
            }
    8705
    0
        }
    8706
    8707
        /// Evaluate `oct()` conversion - int to octal string (complexity: 5)
    8708
    0
        fn evaluate_oct_conversion(
    8709
    0
            &mut self,
    8710
    0
            args: &[Expr],
    8711
    0
            deadline: Instant,
    8712
    0
            depth: usize,
    8713
    0
        ) -> Result<Value> {
    8714
    0
            if args.len() != 1 {
    8715
    0
                bail!("oct() expects exactly 1 argument");
    8716
    0
            }
    8717
    8718
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    8719
    0
            match value {
    8720
    0
                Value::Int(n) => {
    8721
    0
                    if n < 0 {
    8722
    0
                        Ok(Value::String(format!("-0o{:o}", -n)))
    8723
                    } else {
    8724
    0
                        Ok(Value::String(format!("0o{n:o}")))
    8725
                    }
    8726
                }
    8727
    0
                _ => bail!("oct() expects an integer"),
    8728
            }
    8729
    0
        }
    8730
    8731
        /// Evaluate `list()` conversion - convert tuple/iterable to list (complexity: 5)
    8732
    0
        fn evaluate_list_conversion(
    8733
    0
            &mut self,
    8734
    0
            args: &[Expr],
    8735
    0
            deadline: Instant,
    8736
    0
            depth: usize,
    8737
    0
        ) -> Result<Value> {
    8738
    0
            if args.len() != 1 {
    8739
    0
                bail!("list() expects exactly 1 argument");
    8740
    0
            }
    8741
    8742
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    8743
    0
            match value {
    8744
    0
                Value::List(items) => Self::ok_list(items),
    8745
    0
                Value::Tuple(items) => Self::ok_list(items),
    8746
    0
                Value::String(s) => {
    8747
    0
                    let chars: Vec<Value> = s.chars()
    8748
    0
                        .map(|c| Value::String(c.to_string()))
    8749
    0
                        .collect();
    8750
    0
                    Self::ok_list(chars)
    8751
                }
    8752
    0
                _ => bail!("list() expects a list, tuple, or string"),
    8753
            }
    8754
    0
        }
    8755
    8756
        /// Evaluate `tuple()` conversion - convert list/iterable to tuple (complexity: 5)
    8757
    0
        fn evaluate_tuple_conversion(
    8758
    0
            &mut self,
    8759
    0
            args: &[Expr],
    8760
    0
            deadline: Instant,
    8761
    0
            depth: usize,
    8762
    0
        ) -> Result<Value> {
    8763
    0
            if args.len() != 1 {
    8764
    0
                bail!("tuple() expects exactly 1 argument");
    8765
    0
            }
    8766
    8767
    0
            let value = self.evaluate_first_arg(args, deadline, depth)?;
    8768
    0
            match value {
    8769
    0
                Value::Tuple(items) => Ok(Value::Tuple(items)),
    8770
    0
                Value::List(items) => Ok(Value::Tuple(items)),
    8771
    0
                Value::String(s) => {
    8772
    0
                    let chars: Vec<Value> = s.chars()
    8773
    0
                        .map(|c| Value::String(c.to_string()))
    8774
    0
                        .collect();
    8775
    0
                    Ok(Value::Tuple(chars))
    8776
                }
    8777
    0
                _ => bail!("tuple() expects a list, tuple, or string"),
    8778
            }
    8779
    0
        }
    8780
    8781
        /// Evaluate type cast expression (complexity: 8)
    8782
    0
        fn evaluate_type_cast(
    8783
    0
            &mut self,
    8784
    0
            expr: &Expr,
    8785
    0
            target_type: &str,
    8786
    0
            deadline: Instant,
    8787
    0
            depth: usize,
    8788
    0
        ) -> Result<Value> {
    8789
    0
            let value = self.evaluate_expr(expr, deadline, depth + 1)?;
    8790
    8791
    0
            match target_type {
    8792
    0
                "int" | "i32" | "i64" => match value {
    8793
    0
                    Value::Int(n) => Ok(Value::Int(n)),
    8794
    0
                    Value::Float(f) => Ok(Value::Int(f as i64)),
    8795
    0
                    Value::Bool(b) => Ok(Value::Int(i64::from(b))),
    8796
    0
                    Value::String(s) => s.parse::<i64>()
    8797
    0
                        .map(Value::Int)
    8798
    0
                        .map_err(|_| anyhow::anyhow!("Cannot cast '{}' to int", s)),
    8799
    0
                    _ => bail!("Cannot cast {:?} to int", value),
    8800
                },
    8801
    0
                "float" | "f32" | "f64" => match value {
    8802
    0
                    Value::Float(f) => Ok(Value::Float(f)),
    8803
    0
                    Value::Int(n) => Ok(Value::Float(n as f64)),
    8804
    0
                    Value::Bool(b) => Ok(Value::Float(if b { 1.0 } else { 0.0 })),
    8805
    0
                    Value::String(s) => s.parse::<f64>()
    8806
    0
                        .map(Value::Float)
    8807
    0
                        .map_err(|_| anyhow::anyhow!("Cannot cast '{}' to float", s)),
    8808
    0
                    _ => bail!("Cannot cast {:?} to float", value),
    8809
                },
    8810
    0
                "string" | "str" => match value {
    8811
    0
                    Value::Char(c) => Ok(Value::String(c.to_string())),
    8812
    0
                    _ => Ok(Value::String(value.to_string())),
    8813
                },
    8814
    0
                "bool" => match value {
    8815
    0
                    Value::Bool(b) => Ok(Value::Bool(b)),
    8816
    0
                    Value::Int(n) => Ok(Value::Bool(n != 0)),
    8817
    0
                    Value::Float(f) => Ok(Value::Bool(f != 0.0)),
    8818
    0
                    Value::String(s) => Ok(Value::Bool(!s.is_empty() && s != "false")),
    8819
    0
                    _ => bail!("Cannot cast {:?} to bool", value),
    8820
                },
    8821
    0
                _ => bail!("Unknown type for casting: {}", target_type),
    8822
            }
    8823
    0
        }
    8824
    8825
        /// Evaluate `random()` function - returns float between 0.0 and 1.0
    8826
    0
        fn evaluate_random(
    8827
    0
            &mut self,
    8828
    0
            args: &[Expr],
    8829
    0
            _deadline: Instant,
    8830
    0
            _depth: usize,
    8831
    0
        ) -> Result<Value> {
    8832
            use std::time::{SystemTime, UNIX_EPOCH};
    8833
    8834
    0
            if !args.is_empty() {
    8835
    0
                bail!("random() expects no arguments");
    8836
    0
            }
    8837
            // Use a simple linear congruential generator for deterministic behavior in tests
    8838
            // In production, you'd want to use rand crate
    8839
    0
            let seed = SystemTime::now()
    8840
    0
                .duration_since(UNIX_EPOCH)
    8841
    0
                .unwrap()
    8842
    0
                .as_nanos() as u64;
    8843
            // Use a safe LCG that won't overflow
    8844
    0
            let a = 1_664_525u64;
    8845
    0
            let c = 1_013_904_223u64;
    8846
    0
            let m = 1u64 << 32;
    8847
    0
            let random_value = ((seed.wrapping_mul(a).wrapping_add(c)) % m) as f64 / m as f64;
    8848
    0
            Ok(Value::Float(random_value))
    8849
    0
        }
    8850
    8851
        /// Execute a user-defined function or lambda by name.
    8852
        ///
    8853
        /// Looks up the function in bindings and executes it with parameter binding.
    8854
        /// Handles both regular functions and lambdas with identical execution logic.
    8855
        ///
    8856
        /// # Arguments
    8857
        ///
    8858
        /// * `func_name` - Name of the function to execute
    8859
        /// * `args` - Arguments to pass to the function
    8860
        /// * `deadline` - Execution deadline for timeout handling
    8861
        /// * `depth` - Current recursion depth
    8862
        ///
    8863
        /// Example Usage:
    8864
        ///
    8865
        /// Executes a user-defined function stored in bindings:
    8866
        /// - Looks up function by name
    8867
        /// - Validates argument count
    8868
        /// - Binds parameters to arguments
    8869
        /// - Evaluates function body in new scope
    8870
    0
        fn execute_user_defined_function(
    8871
    0
            &mut self,
    8872
    0
            func_name: &str,
    8873
    0
            args: &[Expr],
    8874
    0
            deadline: Instant,
    8875
    0
            depth: usize,
    8876
    0
        ) -> Result<Value> {
    8877
    0
            if let Some(func_value) = self.bindings.get(func_name).cloned() {
    8878
    0
                match func_value {
    8879
    0
                    Value::Function { params, body, .. } => {
    8880
    0
                        self.execute_function_with_params(func_name, &params, &body, args, deadline, depth, "Function")
    8881
                    }
    8882
    0
                    Value::Lambda { params, body } => {
    8883
    0
                        self.execute_function_with_params(func_name, &params, &body, args, deadline, depth, "Lambda")
    8884
                    }
    8885
                    _ => {
    8886
    0
                        bail!("'{}' is not a function", func_name);
    8887
                    }
    8888
                }
    8889
            } else {
    8890
    0
                bail!("Unknown function: {}", func_name);
    8891
            }
    8892
    0
        }
    8893
    8894
        /// Execute a function or lambda with parameter binding and scope management.
    8895
        ///
    8896
        /// This helper consolidates the common logic between functions and lambdas:
    8897
        /// - Validates argument count matches parameter count
    8898
        /// - Saves current bindings scope
    8899
        /// - Binds arguments to parameters
    8900
        /// - Executes function body
    8901
        /// - Restores previous scope
    8902
        ///
    8903
        /// # Arguments
    8904
        ///
    8905
        /// * `func_name` - Name of the function (for error messages)
    8906
        /// * `params` - Function parameter names
    8907
        /// * `body` - Function body expression
    8908
        /// * `args` - Arguments to bind to parameters
    8909
        /// * `deadline` - Execution deadline
    8910
        /// * `depth` - Recursion depth
    8911
        /// * `func_type` - Either "Function" or "Lambda" for error messages
    8912
    0
        fn execute_function_with_params(
    8913
    0
            &mut self,
    8914
    0
            func_name: &str,
    8915
    0
            params: &[String],
    8916
    0
            body: &Expr,
    8917
    0
            args: &[Expr],
    8918
    0
            deadline: Instant,
    8919
    0
            depth: usize,
    8920
    0
            func_type: &str,
    8921
    0
        ) -> Result<Value> {
    8922
    0
            if args.len() != params.len() {
    8923
    0
                bail!(
    8924
    0
                    "{} {} expects {} arguments, got {}",
    8925
                    func_type,
    8926
                    func_name,
    8927
    0
                    params.len(),
    8928
    0
                    args.len()
    8929
                );
    8930
    0
            }
    8931
    8932
    0
            let saved_bindings = self.bindings.clone();
    8933
    8934
    0
            for (param, arg) in params.iter().zip(args.iter()) {
    8935
    0
                let arg_value = self.evaluate_expr(arg, deadline, depth + 1)?;
    8936
    0
                self.bindings.insert(param.clone(), arg_value);
    8937
            }
    8938
    8939
    0
            let result = self.evaluate_function_body(body, deadline, depth)?;
    8940
    0
            self.bindings = saved_bindings;
    8941
    0
            Ok(result)
    8942
    0
        }
    8943
    8944
        /// Validate argument count for math functions.
    8945
        ///
    8946
        /// Example Usage:
    8947
        ///
    8948
        /// Validates that a function receives the expected number of arguments:
    8949
        /// - sqrt(x) expects exactly 1 argument
    8950
        /// - pow(x, y) expects exactly 2 arguments
    8951
        /// - Returns an error if count doesn't match
    8952
    0
        fn validate_arg_count(&self, func_name: &str, args: &[Expr], expected: usize) -> Result<()> {
    8953
    0
            if args.len() != expected {
    8954
    0
                bail!("{} takes exactly {} argument{}", func_name, expected, if expected == 1 { "" } else { "s" });
    8955
    0
            }
    8956
    0
            Ok(())
    8957
    0
        }
    8958
    8959
        /// Validate argument count is within a range
    8960
    0
        fn validate_arg_range(&self, func_name: &str, args: &[Expr], min: usize, max: usize) -> Result<()> {
    8961
    0
            let count = args.len();
    8962
    0
            if count < min || count > max {
    8963
    0
                if min == max {
    8964
    0
                    return self.validate_arg_count(func_name, args, min);
    8965
    0
                }
    8966
    0
                bail!("{} takes between {} and {} arguments, got {}", func_name, min, max, count);
    8967
    0
            }
    8968
    0
            Ok(())
    8969
    0
        }
    8970
    8971
        /// Validate minimum argument count
    8972
    0
        fn validate_min_args(&self, func_name: &str, args: &[Expr], min: usize) -> Result<()> {
    8973
    0
            if args.len() < min {
    8974
    0
                bail!("{} requires at least {} argument{}, got {}",
    8975
    0
                      func_name, min, if min == 1 { "" } else { "s" }, args.len());
    8976
    0
            }
    8977
    0
            Ok(())
    8978
    0
        }
    8979
    8980
        /// Validate maximum argument count
    8981
    0
        fn validate_max_args(&self, func_name: &str, args: &[Expr], max: usize) -> Result<()> {
    8982
    0
            if args.len() > max {
    8983
    0
                bail!("{} takes at most {} argument{}, got {}",
    8984
    0
                      func_name, max, if max == 1 { "" } else { "s" }, args.len());
    8985
    0
            }
    8986
    0
            Ok(())
    8987
    0
        }
    8988
    8989
        /// Create error for unknown method
    8990
    0
        fn unknown_method_error(&self, type_name: &str, method: &str) -> Result<Value> {
    8991
    0
            bail!("Unknown {} method: {}", type_name, method)
    8992
    0
        }
    8993
    8994
        /// Create error for type mismatch
    8995
    0
        fn type_error(&self, func_name: &str, expected: &str, got: &Value) -> Result<Value> {
    8996
    0
            bail!("{} expects {}, got {:?}", func_name, expected, got)
    8997
    0
        }
    8998
    8999
        /// Check resource limits (timeout and recursion depth)
    9000
    0
        fn check_resource_limits(&self, deadline: Instant, depth: usize) -> Result<()> {
    9001
    0
            if Instant::now() > deadline {
    9002
    0
                bail!("Evaluation timeout exceeded");
    9003
    0
            }
    9004
    0
            if depth > self.config.max_depth {
    9005
    0
                bail!("Maximum recursion depth {} exceeded. \n  Hint: Check for infinite recursion or increase max_depth if needed", self.config.max_depth);
    9006
    0
            }
    9007
    0
            Ok(())
    9008
    0
        }
    9009
    9010
        /// Evaluate a single argument expression
    9011
    0
        fn evaluate_arg(&mut self, args: &[Expr], index: usize, deadline: Instant, depth: usize) -> Result<Value> {
    9012
    0
            args.get(index)
    9013
    0
                .ok_or_else(|| anyhow::anyhow!("Missing argument at index {}", index))
    9014
    0
                .and_then(|arg| self.evaluate_expr(arg, deadline, depth + 1))
    9015
    0
        }
    9016
    9017
        /// Create a string value from a string-like type
    9018
    0
        fn string_value(s: impl Into<String>) -> Value {
    9019
    0
            Value::String(s.into())
    9020
    0
        }
    9021
    9022
        /// Create an integer value
    9023
    0
        fn int_value(n: i64) -> Value {
    9024
    0
            Value::Int(n)
    9025
    0
        }
    9026
    9027
        /// Create a float value
    9028
    0
        fn float_value(f: f64) -> Value {
    9029
    0
            Value::Float(f)
    9030
    0
        }
    9031
    9032
        /// Execute a closure with saved bindings that will be restored afterwards
    9033
    0
        fn with_saved_bindings<F, R>(&mut self, f: F) -> R
    9034
    0
        where
    9035
    0
            F: FnOnce(&mut Self) -> R,
    9036
        {
    9037
    0
            let saved_bindings = self.bindings.clone();
    9038
    0
            let result = f(self);
    9039
    0
            self.bindings = saved_bindings;
    9040
    0
            result
    9041
    0
        }
    9042
    9043
        /// Add a binding temporarily and execute a closure
    9044
    0
        fn with_binding<F, R>(&mut self, name: String, value: Value, f: F) -> R
    9045
    0
        where
    9046
    0
            F: FnOnce(&mut Self) -> R,
    9047
        {
    9048
    0
            let saved_bindings = self.bindings.clone();
    9049
    0
            self.bindings.insert(name, value);
    9050
    0
            let result = f(self);
    9051
    0
            self.bindings = saved_bindings;
    9052
    0
            result
    9053
    0
        }
    9054
    9055
        /// Create a list value
    9056
    0
        fn list_value(items: Vec<Value>) -> Value {
    9057
    0
            Value::List(items)
    9058
    0
        }
    9059
    9060
        /// Create a boolean value
    9061
    0
        fn bool_value(b: bool) -> Value {
    9062
    0
            Value::Bool(b)
    9063
    0
        }
    9064
    9065
        /// Create an Ok result with a list value
    9066
    0
        fn ok_list(items: Vec<Value>) -> Result<Value> {
    9067
    0
            Ok(Self::list_value(items))
    9068
    0
        }
    9069
    9070
        /// Create an Ok result with a bool value
    9071
    0
        fn ok_bool(b: bool) -> Result<Value> {
    9072
    0
            Ok(Self::bool_value(b))
    9073
    0
        }
    9074
    9075
        /// Create an Ok result with a string value
    9076
    0
        fn ok_string(s: impl Into<String>) -> Result<Value> {
    9077
    0
            Ok(Self::string_value(s))
    9078
    0
        }
    9079
    9080
        /// Create an Ok result with an integer value
    9081
    0
        fn ok_int(n: i64) -> Result<Value> {
    9082
    0
            Ok(Self::int_value(n))
    9083
    0
        }
    9084
    9085
        /// Create an Ok result with a float value
    9086
    0
        fn ok_float(f: f64) -> Result<Value> {
    9087
    0
            Ok(Self::float_value(f))
    9088
    0
        }
    9089
    9090
        /// Create an Ok result with null value
    9091
    0
        fn ok_null() -> Result<Value> {
    9092
    0
            Ok(Self::create_option_none())
    9093
    0
        }
    9094
    9095
        /// Create a character value
    9096
    0
        fn char_value(c: char) -> Value {
    9097
    0
            Value::Char(c)
    9098
    0
        }
    9099
    9100
        /// Create an object value
    9101
    0
        fn object_value(map: std::collections::HashMap<String, Value>) -> Value {
    9102
    0
            Value::Object(map)
    9103
    0
        }
    9104
    9105
        /// Create an Ok result with a character value
    9106
    0
        fn ok_char(c: char) -> Result<Value> {
    9107
    0
            Ok(Self::char_value(c))
    9108
    0
        }
    9109
    9110
        /// Create an Ok result with an object value
    9111
    0
        fn ok_object(map: std::collections::HashMap<String, Value>) -> Result<Value> {
    9112
    0
            Ok(Self::object_value(map))
    9113
    0
        }
    9114
    9115
        /// Create an Ok result with a nil value
    9116
    0
        fn ok_nil() -> Result<Value> {
    9117
    0
            Ok(Value::Nil)
    9118
    0
        }
    9119
    9120
        /// Create a tuple value
    9121
    0
        fn tuple_value(items: Vec<Value>) -> Value {
    9122
    0
            Value::Tuple(items)
    9123
    0
        }
    9124
    9125
        /// Create an Ok result with a tuple value
    9126
    0
        fn ok_tuple(items: Vec<Value>) -> Result<Value> {
    9127
    0
            Ok(Self::tuple_value(items))
    9128
    0
        }
    9129
    9130
        /// Create a unit value
    9131
    0
        fn unit_value() -> Value {
    9132
    0
            Value::Unit
    9133
    0
        }
    9134
    9135
        /// Create a `HashMap` value
    9136
    0
        fn hashmap_value(map: std::collections::HashMap<Value, Value>) -> Value {
    9137
    0
            Value::HashMap(map)
    9138
    0
        }
    9139
    9140
        /// Create a `HashSet` value
    9141
    0
        fn hashset_value(set: std::collections::HashSet<Value>) -> Value {
    9142
    0
            Value::HashSet(set)
    9143
    0
        }
    9144
    9145
        /// Create an Ok result with a unit value
    9146
    0
        fn ok_unit() -> Result<Value> {
    9147
    0
            Ok(Self::unit_value())
    9148
    0
        }
    9149
    9150
        /// Create an Ok result with a `HashMap` value
    9151
    0
        fn ok_hashmap(map: std::collections::HashMap<Value, Value>) -> Result<Value> {
    9152
    0
            Ok(Self::hashmap_value(map))
    9153
    0
        }
    9154
    9155
        /// Create an Ok result with a `HashSet` value
    9156
    0
        fn ok_hashset(set: std::collections::HashSet<Value>) -> Result<Value> {
    9157
    0
            Ok(Self::hashset_value(set))
    9158
    0
        }
    9159
    9160
        /// Create a Range value
    9161
    0
        fn range_value(start: i64, end: i64, inclusive: bool) -> Value {
    9162
    0
            Value::Range { start, end, inclusive }
    9163
    0
        }
    9164
    9165
        /// Create a `DataFrame` value
    9166
    0
        fn dataframe_value(columns: Vec<DataFrameColumn>) -> Value {
    9167
    0
            Value::DataFrame { columns }
    9168
    0
        }
    9169
    9170
        /// Create an `EnumVariant` value
    9171
    0
        fn enum_variant_value(enum_name: String, variant_name: String, data: Option<Vec<Value>>) -> Value {
    9172
    0
            Value::EnumVariant { enum_name, variant_name, data }
    9173
    0
        }
    9174
    9175
        /// Create an Ok result with a Range value
    9176
    0
        fn ok_range(start: i64, end: i64, inclusive: bool) -> Result<Value> {
    9177
    0
            Ok(Self::range_value(start, end, inclusive))
    9178
    0
        }
    9179
    9180
        /// Create an Ok result with a `DataFrame` value
    9181
    0
        fn ok_dataframe(columns: Vec<DataFrameColumn>) -> Result<Value> {
    9182
    0
            Ok(Self::dataframe_value(columns))
    9183
    0
        }
    9184
    9185
        /// Create an Ok result with an `EnumVariant` value
    9186
    0
        fn ok_enum_variant(enum_name: String, variant_name: String, data: Option<Vec<Value>>) -> Result<Value> {
    9187
    0
            Ok(Self::enum_variant_value(enum_name, variant_name, data))
    9188
    0
        }
    9189
    9190
        // === Argument Validation Helper Functions ===
    9191
    9192
        /// Validate that a function receives the expected number of arguments (with "exactly" phrasing)
    9193
    0
        fn validate_exact_args(func_name: &str, expected: usize, actual: usize) -> Result<()> {
    9194
    0
            if actual != expected {
    9195
    0
                bail!("{} expects exactly {} argument{}, got {}",
    9196
    0
                      func_name, expected, if expected == 1 { "" } else { "s" }, actual);
    9197
    0
            }
    9198
    0
            Ok(())
    9199
    0
        }
    9200
    9201
        /// Validate that a function receives no arguments
    9202
    0
        fn validate_zero_args(func_name: &str, actual: usize) -> Result<()> {
    9203
    0
            if actual != 0 {
    9204
    0
                bail!("{} expects no arguments, got {}", func_name, actual);
    9205
    0
            }
    9206
    0
            Ok(())
    9207
    0
        }
    9208
    9209
        /// Validate that a function receives a numeric argument
    9210
    0
        fn numeric_arg_error(func_name: &str) -> String {
    9211
    0
            format!("{func_name}() expects a numeric argument")
    9212
    0
        }
    9213
    9214
        /// Validate that a function receives numeric arguments (plural)
    9215
    0
        fn numeric_args_error(func_name: &str) -> String {
    9216
    0
            format!("{func_name} expects numeric arguments")
    9217
    0
        }
    9218
    9219
        /// Create a method not supported error message
    9220
    0
        fn method_not_supported(method: &str, type_desc: &str) -> anyhow::Error {
    9221
    0
            anyhow::anyhow!("Method {} not supported on {}", method, type_desc)
    9222
    0
        }
    9223
    9224
        /// Preprocess macro syntax by converting macro calls (!) to function calls
    9225
    0
        fn preprocess_macro_syntax(input: &str) -> String {
    9226
    0
            input
    9227
    0
                .replace("println!", "println")
    9228
    0
                .replace("print!", "print")
    9229
    0
                .replace("assert!", "assert")
    9230
    0
                .replace("assert_eq!", "assert_eq")
    9231
    0
                .replace("panic!", "panic")
    9232
    0
                .replace("vec!", "vec")
    9233
    0
                .replace("format!", "format")
    9234
    0
        }
    9235
    9236
        /// Helper to evaluate the first argument from an argument list
    9237
    0
        fn evaluate_first_arg(&mut self, args: &[Expr], deadline: Instant, depth: usize) -> Result<Value> {
    9238
    0
            self.evaluate_arg(args, 0, deadline, depth)
    9239
    0
        }
    9240
    9241
        /// Apply unary math operation to a numeric value.
    9242
        ///
    9243
        /// # Example Usage
    9244
        /// Validates that the correct number of arguments is provided to a function.
    9245
        ///
    9246
        /// # use `ruchy::runtime::repl::Repl`;
    9247
        /// # use `ruchy::runtime::value::Value`;
    9248
        /// let repl = `Repl::new()`;
    9249
        /// let result = `repl.apply_unary_math_op(&Value::Int(4)`, "`sqrt").unwrap()`;
    9250
        /// assert!(matches!(result, `Value::Float`(_)));
    9251
        /// ```
    9252
    0
        fn apply_unary_math_op(&self, value: &Value, op: &str) -> Result<Value> {
    9253
    0
            match (value, op) {
    9254
    0
                (Value::Int(n), "sqrt") => {
    9255
                    #[allow(clippy::cast_precision_loss)]
    9256
    0
                    Ok(Value::Float((*n as f64).sqrt()))
    9257
                }
    9258
    0
                (Value::Float(f), "sqrt") => Ok(Value::Float(f.sqrt())),
    9259
    0
                (Value::Int(n), "abs") => Self::ok_int(n.abs()),
    9260
    0
                (Value::Float(f), "abs") => Self::ok_float(f.abs()),
    9261
    0
                (Value::Int(n), "floor") => Ok(Value::Int(*n)), // Already floored
    9262
    0
                (Value::Float(f), "floor") => Self::ok_float(f.floor()),
    9263
    0
                (Value::Int(n), "ceil") => Ok(Value::Int(*n)), // Already ceiled
    9264
    0
                (Value::Float(f), "ceil") => Self::ok_float(f.ceil()),
    9265
    0
                (Value::Int(n), "round") => Ok(Value::Int(*n)), // Already rounded
    9266
    0
                (Value::Float(f), "round") => Self::ok_float(f.round()),
    9267
    0
                _ => bail!("{}", Self::numeric_args_error(op)),
    9268
            }
    9269
    0
        }
    9270
    9271
        /// Apply binary math operation to two numeric values.
    9272
        ///
    9273
        /// # Example Usage
    9274
        /// Applies unary math operations like sqrt, abs, floor, ceil, round to numeric values.
    9275
        ///
    9276
        /// # use `ruchy::runtime::repl::Repl`;
    9277
        /// # use `ruchy::runtime::value::Value`;
    9278
        /// let repl = `Repl::new()`;
    9279
        /// let result = `repl.apply_binary_math_op(&Value::Int(2)`, &`Value::Int(3)`, "`pow").unwrap()`;
    9280
        /// assert!(matches!(result, `Value::Int(8)`));
    9281
        /// ```
    9282
    0
        fn apply_binary_math_op(&self, a: &Value, b: &Value, op: &str) -> Result<Value> {
    9283
    0
            match (a, b, op) {
    9284
    0
                (Value::Int(base), Value::Int(exp), "pow") => {
    9285
    0
                    if *exp < 0 {
    9286
                        #[allow(clippy::cast_precision_loss)]
    9287
    0
                        Ok(Value::Float((*base as f64).powi(*exp as i32)))
    9288
                    } else {
    9289
    0
                        let exp_u32 = u32::try_from(*exp).map_err(|_| anyhow::anyhow!("Exponent too large"))?;
    9290
    0
                        match base.checked_pow(exp_u32) {
    9291
    0
                            Some(result) => Ok(Value::Int(result)),
    9292
    0
                            None => bail!("Integer overflow in pow({}, {})", base, exp),
    9293
                        }
    9294
                    }
    9295
                }
    9296
    0
                (Value::Float(base), Value::Float(exp), "pow") => Ok(Value::Float(base.powf(*exp))),
    9297
    0
                (Value::Int(base), Value::Float(exp), "pow") => {
    9298
                    #[allow(clippy::cast_precision_loss)]
    9299
    0
                    Ok(Value::Float((*base as f64).powf(*exp)))
    9300
                }
    9301
    0
                (Value::Float(base), Value::Int(exp), "pow") => {
    9302
                    #[allow(clippy::cast_precision_loss)]
    9303
    0
                    Ok(Value::Float(base.powi(*exp as i32)))
    9304
                }
    9305
    0
                (Value::Int(x), Value::Int(y), "min") => Ok(Value::Int((*x).min(*y))),
    9306
    0
                (Value::Float(x), Value::Float(y), "min") => Ok(Value::Float(x.min(*y))),
    9307
    0
                (Value::Int(x), Value::Float(y), "min") => {
    9308
                    #[allow(clippy::cast_precision_loss)]
    9309
    0
                    Ok(Value::Float((*x as f64).min(*y)))
    9310
                }
    9311
    0
                (Value::Float(x), Value::Int(y), "min") => {
    9312
                    #[allow(clippy::cast_precision_loss)]
    9313
    0
                    Ok(Value::Float(x.min(*y as f64)))
    9314
                }
    9315
    0
                (Value::Int(x), Value::Int(y), "max") => Ok(Value::Int((*x).max(*y))),
    9316
    0
                (Value::Float(x), Value::Float(y), "max") => Ok(Value::Float(x.max(*y))),
    9317
    0
                (Value::Int(x), Value::Float(y), "max") => {
    9318
                    #[allow(clippy::cast_precision_loss)]
    9319
    0
                    Ok(Value::Float((*x as f64).max(*y)))
    9320
                }
    9321
    0
                (Value::Float(x), Value::Int(y), "max") => {
    9322
                    #[allow(clippy::cast_precision_loss)]
    9323
    0
                    Ok(Value::Float(x.max(*y as f64)))
    9324
                }
    9325
    0
                _ => bail!("{}", Self::numeric_args_error(op)),
    9326
            }
    9327
    0
        }
    9328
    9329
        /// Handle built-in math functions (sqrt, pow, abs, min, max, floor, ceil, round).
    9330
        ///
    9331
        /// Returns `Ok(Some(value))` if the function name matches a math function,
    9332
        /// `Ok(None)` if it doesn't match any math function, or `Err` if there's an error.
    9333
        ///
    9334
        /// # Example Usage
    9335
        /// Tries to call math functions like sqrt, pow, abs, min, max, floor, ceil, round.
    9336
        /// Dispatches to appropriate unary or binary math operation handler.
    9337
    0
        fn try_math_function(
    9338
    0
            &mut self,
    9339
    0
            func_name: &str,
    9340
    0
            args: &[Expr],
    9341
    0
            deadline: Instant,
    9342
    0
            depth: usize,
    9343
    0
        ) -> Result<Option<Value>> {
    9344
    0
            match func_name {
    9345
                // Unary math functions
    9346
    0
                "sqrt" | "abs" | "floor" | "ceil" | "round" => {
    9347
    0
                    self.validate_arg_count(func_name, args, 1)?;
    9348
    0
                    let value = self.evaluate_first_arg(args, deadline, depth)?;
    9349
    0
                    Ok(Some(self.apply_unary_math_op(&value, func_name)?))
    9350
                }
    9351
                // Binary math functions
    9352
    0
                "pow" | "min" | "max" => {
    9353
    0
                    self.validate_arg_count(func_name, args, 2)?;
    9354
    0
                    let a = self.evaluate_expr(&args[0], deadline, depth + 1)?;
    9355
    0
                    let b = self.evaluate_arg(args, 1, deadline, depth)?;
    9356
    0
                    Ok(Some(self.apply_binary_math_op(&a, &b, func_name)?))
    9357
                }
    9358
    0
                _ => Ok(None), // Not a math function
    9359
            }
    9360
    0
        }
    9361
    9362
        /// Handle built-in enum variant constructors (None, Some, Ok, Err).
    9363
        ///
    9364
        /// Returns `Ok(Some(value))` if the function name matches an enum constructor,
    9365
        /// `Ok(None)` if it doesn't match any constructor, or `Err` if there's an error.
    9366
        ///
    9367
        /// # Example Usage
    9368
        /// Applies binary math operations like pow, min, max to two numeric values.
    9369
        ///
    9370
        /// # use `ruchy::runtime::repl::Repl`;
    9371
        /// # use `ruchy::frontend::ast::Expr`;
    9372
        /// # use `std::time::Instant`;
    9373
        /// let mut repl = `Repl::new()`;
    9374
        /// let args = vec![];
    9375
        /// let deadline = `Instant::now()` + `std::time::Duration::from_secs(1)`;
    9376
        /// let result = `repl.try_enum_constructor("None`", &args, deadline, `0).unwrap()`;
    9377
        /// `assert!(result.is_some())`;
    9378
        /// ```
    9379
    0
        fn try_enum_constructor(
    9380
    0
            &mut self,
    9381
    0
            func_name: &str,
    9382
    0
            args: &[Expr],
    9383
    0
            deadline: Instant,
    9384
    0
            depth: usize,
    9385
    0
        ) -> Result<Option<Value>> {
    9386
    0
            match func_name {
    9387
    0
                "None" => {
    9388
    0
                    if !args.is_empty() {
    9389
    0
                        bail!("None takes no arguments");
    9390
    0
                    }
    9391
    0
                    Ok(Some(Value::EnumVariant {
    9392
    0
                        enum_name: "Option".to_string(),
    9393
    0
                        variant_name: "None".to_string(),
    9394
    0
                        data: None,
    9395
    0
                    }))
    9396
                }
    9397
    0
                "Some" => {
    9398
    0
                    if args.len() != 1 {
    9399
    0
                        bail!("Some takes exactly 1 argument");
    9400
    0
                    }
    9401
    0
                    let value = self.evaluate_first_arg(args, deadline, depth)?;
    9402
    0
                    Ok(Some(Value::EnumVariant {
    9403
    0
                        enum_name: "Option".to_string(),
    9404
    0
                        variant_name: "Some".to_string(),
    9405
    0
                        data: Some(vec![value]),
    9406
    0
                    }))
    9407
                }
    9408
    0
                "Ok" => {
    9409
    0
                    if args.len() != 1 {
    9410
    0
                        bail!("Ok takes exactly 1 argument");
    9411
    0
                    }
    9412
    0
                    let value = self.evaluate_first_arg(args, deadline, depth)?;
    9413
    0
                    Ok(Some(Value::EnumVariant {
    9414
    0
                        enum_name: "Result".to_string(),
    9415
    0
                        variant_name: "Ok".to_string(),
    9416
    0
                        data: Some(vec![value]),
    9417
    0
                    }))
    9418
                }
    9419
    0
                "Err" => {
    9420
    0
                    if args.len() != 1 {
    9421
    0
                        bail!("Err takes exactly 1 argument");
    9422
    0
                    }
    9423
    0
                    let value = self.evaluate_first_arg(args, deadline, depth)?;
    9424
    0
                    Ok(Some(Value::EnumVariant {
    9425
    0
                        enum_name: "Result".to_string(),
    9426
    0
                        variant_name: "Err".to_string(),
    9427
    0
                        data: Some(vec![value]),
    9428
    0
                    }))
    9429
                }
    9430
    0
                _ => Ok(None), // Not an enum constructor
    9431
            }
    9432
    0
        }
    9433
    9434
        /// Evaluate user-defined functions
    9435
    0
        fn evaluate_user_function(
    9436
    0
            &mut self,
    9437
    0
            func_name: &str,
    9438
    0
            args: &[Expr],
    9439
    0
            deadline: Instant,
    9440
    0
            depth: usize,
    9441
    0
        ) -> Result<Value> {
    9442
            // Try enum constructor first
    9443
    0
            if let Some(result) = self.try_enum_constructor(func_name, args, deadline, depth)? {
    9444
    0
                return Ok(result);
    9445
    0
            }
    9446
    9447
            // Try built-in math function
    9448
    0
            if let Some(result) = self.try_math_function(func_name, args, deadline, depth)? {
    9449
    0
                return Ok(result);
    9450
    0
            }
    9451
    9452
            // Try user-defined function lookup and execution
    9453
    0
            self.execute_user_defined_function(func_name, args, deadline, depth)
    9454
    0
        }
    9455
    9456
        /// Helper to evaluate a function body and handle return statements
    9457
    0
        fn evaluate_function_body(
    9458
    0
            &mut self,
    9459
    0
            body: &Expr,
    9460
    0
            deadline: Instant,
    9461
    0
            depth: usize,
    9462
    0
        ) -> Result<Value> {
    9463
    0
            match self.evaluate_expr(body, deadline, depth + 1) {
    9464
    0
                Ok(val) => Ok(val),
    9465
    0
                Err(e) => {
    9466
                    // Check if this is a return statement
    9467
    0
                    let err_str = e.to_string();
    9468
    0
                    if let Some(return_val) = err_str.strip_prefix("return:") {
    9469
                        // Parse the return value - it's already a formatted Value string
    9470
                        // For now, just extract the string representation
    9471
                        // The value was already evaluated, just passed through error
    9472
    0
                        if return_val == "()" {
    9473
    0
                            Self::ok_unit()
    9474
    0
                        } else if return_val.starts_with('"') && return_val.ends_with('"') {
    9475
                            // String value - remove quotes
    9476
    0
                            let s = return_val[1..return_val.len()-1].to_string();
    9477
    0
                            Ok(Value::String(s))
    9478
    0
                        } else if let Ok(i) = return_val.parse::<i64>() {
    9479
    0
                            Ok(Value::Int(i))
    9480
    0
                        } else if let Ok(f) = return_val.parse::<f64>() {
    9481
    0
                            Ok(Value::Float(f))
    9482
    0
                        } else if return_val == "true" {
    9483
    0
                            Self::ok_bool(true)
    9484
    0
                        } else if return_val == "false" {
    9485
    0
                            Self::ok_bool(false)
    9486
                        } else {
    9487
                            // Return as string for complex values
    9488
    0
                            Ok(Value::String(return_val.to_string()))
    9489
                        }
    9490
                    } else {
    9491
    0
                        Err(e)
    9492
                    }
    9493
                }
    9494
            }
    9495
    0
        }
    9496
    9497
        /// Evaluate match expressions
    9498
    0
        fn evaluate_match(
    9499
    0
            &mut self,
    9500
    0
            match_expr: &Expr,
    9501
    0
            arms: &[MatchArm],
    9502
    0
            deadline: Instant,
    9503
    0
            depth: usize,
    9504
    0
        ) -> Result<Value> {
    9505
    0
            let match_value = self.evaluate_expr(match_expr, deadline, depth + 1)?;
    9506
    9507
    0
            for arm in arms {
    9508
    0
                if let Some(bindings) = Self::pattern_matches(&match_value, &arm.pattern)? {
    9509
    0
                    let saved_bindings = self.bindings.clone();
    9510
    9511
                    // Apply pattern bindings temporarily
    9512
    0
                    for (name, value) in bindings {
    9513
    0
                        self.bindings.insert(name, value);
    9514
    0
                    }
    9515
    9516
                    // Check pattern guard if present
    9517
    0
                    let guard_passes = if let Some(guard_expr) = &arm.guard {
    9518
    0
                        if let Value::Bool(b) = self.evaluate_expr(guard_expr, deadline, depth + 1)? {
    9519
    0
                            b
    9520
                        } else {
    9521
    0
                            self.bindings = saved_bindings;
    9522
    0
                            continue; // Guard didn't evaluate to boolean, try next arm
    9523
                        }
    9524
                    } else {
    9525
    0
                        true // No guard, so it passes
    9526
                    };
    9527
    9528
    0
                    if guard_passes {
    9529
    0
                        let result = self.evaluate_expr(&arm.body, deadline, depth + 1)?;
    9530
    0
                        self.bindings = saved_bindings;
    9531
    0
                        return Ok(result);
    9532
    0
                    }
    9533
    9534
                    // Guard failed, restore bindings and try next arm
    9535
    0
                    self.bindings = saved_bindings;
    9536
    0
                }
    9537
            }
    9538
    9539
    0
            bail!("No matching pattern found in match expression");
    9540
    0
        }
    9541
    9542
        /// Evaluate pipeline expressions
    9543
    0
        fn evaluate_pipeline(
    9544
    0
            &mut self,
    9545
    0
            expr: &Expr,
    9546
    0
            stages: &[PipelineStage],
    9547
    0
            deadline: Instant,
    9548
    0
            depth: usize,
    9549
    0
        ) -> Result<Value> {
    9550
    0
            let mut current_value = self.evaluate_expr(expr, deadline, depth + 1)?;
    9551
    9552
    0
            for stage in stages {
    9553
    0
                current_value = self.evaluate_pipeline_stage(&current_value, stage, deadline, depth)?;
    9554
            }
    9555
    9556
    0
            Ok(current_value)
    9557
    0
        }
    9558
    9559
        /// Evaluate a single pipeline stage
    9560
    0
        fn evaluate_pipeline_stage(
    9561
    0
            &mut self,
    9562
    0
            current_value: &Value,
    9563
    0
            stage: &PipelineStage,
    9564
    0
            deadline: Instant,
    9565
    0
            depth: usize,
    9566
    0
        ) -> Result<Value> {
    9567
    0
            match &stage.op.kind {
    9568
    0
                ExprKind::Call { func, args } => {
    9569
    0
                    let mut new_args = vec![Self::value_to_literal_expr(current_value, stage.span)?];
    9570
    0
                    new_args.extend(args.iter().cloned());
    9571
    9572
    0
                    let new_call = Expr::new(
    9573
    0
                        ExprKind::Call {
    9574
    0
                            func: func.clone(),
    9575
    0
                            args: new_args,
    9576
    0
                        },
    9577
    0
                        stage.span,
    9578
                    );
    9579
    9580
    0
                    self.evaluate_expr(&new_call, deadline, depth + 1)
    9581
                }
    9582
    0
                ExprKind::Identifier(_func_name) => {
    9583
    0
                    let call = Expr::new(
    9584
                        ExprKind::Call {
    9585
    0
                            func: stage.op.clone(),
    9586
    0
                            args: vec![Self::value_to_literal_expr(current_value, stage.span)?],
    9587
                        },
    9588
    0
                        stage.span,
    9589
                    );
    9590
    9591
    0
                    self.evaluate_expr(&call, deadline, depth + 1)
    9592
                }
    9593
    0
                ExprKind::MethodCall { receiver: _, method, args } => {
    9594
                    // For method calls in pipeline, current_value becomes the receiver
    9595
    0
                    match current_value {
    9596
    0
                        Value::List(items) => {
    9597
    0
                            self.evaluate_list_methods(items.clone(), method, args, deadline, depth)
    9598
                        }
    9599
    0
                        Value::String(s) => {
    9600
    0
                            Self::evaluate_string_methods(s, method, args, deadline, depth)
    9601
                        }
    9602
    0
                        Value::Int(_) | Value::Float(_) => self.evaluate_numeric_methods(current_value, method),
    9603
    0
                        Value::Object(obj) => {
    9604
    0
                            Self::evaluate_object_methods(obj.clone(), method, args, deadline, depth)
    9605
                        }
    9606
    0
                        Value::HashMap(map) => {
    9607
    0
                            self.evaluate_hashmap_methods(map.clone(), method, args, deadline, depth)
    9608
                        }
    9609
    0
                        Value::HashSet(set) => {
    9610
    0
                            self.evaluate_hashset_methods(set.clone(), method, args, deadline, depth)
    9611
                        }
    9612
                        Value::EnumVariant { .. } => {
    9613
    0
                            self.evaluate_enum_methods(current_value.clone(), method, args, deadline, depth)
    9614
                        }
    9615
    0
                        _ => bail!("Cannot call method {} on value of this type", method),
    9616
                    }
    9617
                }
    9618
    0
                _ => bail!("Pipeline stages must be function calls, method calls, or identifiers"),
    9619
            }
    9620
    0
        }
    9621
    9622
        /// Convert value to literal expression for pipeline
    9623
    0
        fn value_to_literal_expr(value: &Value, span: Span) -> Result<Expr> {
    9624
    0
            let expr_kind = match value {
    9625
    0
                Value::Int(n) => ExprKind::Literal(Literal::Integer(*n)),
    9626
    0
                Value::Float(f) => ExprKind::Literal(Literal::Float(*f)),
    9627
    0
                Value::String(s) => ExprKind::Literal(Literal::String(s.clone())),
    9628
    0
                Value::Bool(b) => ExprKind::Literal(Literal::Bool(*b)),
    9629
    0
                Value::Unit => ExprKind::Literal(Literal::Unit),
    9630
    0
                Value::List(items) => {
    9631
    0
                    let elements: Result<Vec<Expr>> = items
    9632
    0
                        .iter()
    9633
    0
                        .map(|item| Self::value_to_literal_expr(item, span))
    9634
    0
                        .collect();
    9635
    0
                    ExprKind::List(elements?)
    9636
                }
    9637
    0
                _ => bail!("Cannot pipeline complex value types yet"),
    9638
            };
    9639
    0
            Ok(Expr::new(expr_kind, span))
    9640
    0
        }
    9641
    9642
        /// Evaluate command execution
    9643
    0
        fn evaluate_command(
    9644
    0
            program: &str,
    9645
    0
            args: &[String],
    9646
    0
            _deadline: Instant,
    9647
    0
            _depth: usize,
    9648
    0
        ) -> Result<Value> {
    9649
            use std::process::Command;
    9650
    9651
    0
            let output = Command::new(program)
    9652
    0
                .args(args)
    9653
    0
                .output()
    9654
    0
                .map_err(|e| anyhow::anyhow!("Failed to execute command '{}': {}", program, e))?;
    9655
    9656
    0
            if output.status.success() {
    9657
    0
                let stdout = String::from_utf8_lossy(&output.stdout).to_string();
    9658
    0
                Ok(Value::String(stdout.trim().to_string()))
    9659
            } else {
    9660
    0
                let stderr = String::from_utf8_lossy(&output.stderr).to_string();
    9661
    0
                Err(anyhow::anyhow!(
    9662
    0
                    "Command '{}' failed with exit code {:?}: {}",
    9663
    0
                    program,
    9664
    0
                    output.status.code(),
    9665
    0
                    stderr
    9666
    0
                ))
    9667
            }
    9668
    0
        }
    9669
    9670
        /// Evaluate macro expansion
    9671
    0
        fn evaluate_macro(
    9672
    0
            &mut self,
    9673
    0
            name: &str,
    9674
    0
            args: &[Expr],
    9675
    0
            deadline: Instant,
    9676
    0
            depth: usize,
    9677
    0
        ) -> Result<Value> {
    9678
    0
            match name {
    9679
    0
                "println" => {
    9680
                    // Evaluate all arguments and print them
    9681
    0
                    let mut output = String::new();
    9682
    0
                    for (i, arg) in args.iter().enumerate() {
    9683
    0
                        if i > 0 {
    9684
    0
                            output.push(' ');
    9685
    0
                        }
    9686
    0
                        let value = self.evaluate_expr(arg, deadline, depth + 1)?;
    9687
    0
                        output.push_str(&value.to_string());
    9688
                    }
    9689
    0
                    println!("{output}");
    9690
    0
                    Self::ok_unit()
    9691
                }
    9692
    0
                "vec" => {
    9693
                    // Evaluate all arguments and create a vector
    9694
    0
                    let mut elements = Vec::new();
    9695
    0
                    for arg in args {
    9696
    0
                        elements.push(self.evaluate_expr(arg, deadline, depth + 1)?);
    9697
                    }
    9698
    0
                    Self::ok_list(elements)
    9699
                }
    9700
                _ => {
    9701
    0
                    anyhow::bail!("Unknown macro: {}", name)
    9702
                }
    9703
            }
    9704
    0
        }
    9705
    9706
        /// Evaluate import statements (complexity < 10)
    9707
        /// Import standard library filesystem module (complexity: 6)
    9708
    0
        fn import_std_fs(&mut self, items: &[ImportItem]) -> Result<()> {
    9709
    0
            for item in items {
    9710
    0
                match item {
    9711
    0
                    ImportItem::Named(name) if name == "read_file" => {
    9712
    0
                        // This function is already built-in
    9713
    0
                    }
    9714
    0
                    ImportItem::Named(name) if name == "write_file" => {
    9715
    0
                        // This function is already built-in
    9716
    0
                    }
    9717
    0
                    ImportItem::Named(name) if name == "fs" => {
    9718
    0
                        println!("  ✓ Imported fs module");
    9719
    0
                    }
    9720
    0
                    _ => {}
    9721
                }
    9722
            }
    9723
    0
            Ok(())
    9724
    0
        }
    9725
    9726
        /// Import standard library collections module (complexity: 3)
    9727
    0
        fn import_std_collections(&mut self, items: &[ImportItem]) -> Result<()> {
    9728
    0
            for item in items {
    9729
    0
                if let ImportItem::Named(_name) = item {
    9730
    0
                    // Successfully imported
    9731
    0
                }
    9732
            }
    9733
    0
            Ok(())
    9734
    0
        }
    9735
    9736
        /// Import performance-related modules (complexity: 2)
    9737
    0
        fn import_performance_module(&mut self, path: &str) -> Result<()> {
    9738
    0
            match path {
    9739
    0
                "std::mem" => {
    9740
    0
                    self.bindings.insert("Array".to_string(), Value::String("Array constructor".to_string()));
    9741
    0
                }
    9742
    0
                "std::parallel" | "std::simd" | "std::cache" | "std::bench" | "std::profile" => {
    9743
    0
                    // Module functions will be accessible via namespace
    9744
    0
                }
    9745
    0
                _ => {}
    9746
            }
    9747
    0
            Ok(())
    9748
    0
        }
    9749
    9750
        /// Check if item should be imported (complexity: 4)
    9751
    0
        fn should_import_item(items: &[ImportItem], func_name: &str) -> bool {
    9752
    0
            items.is_empty() || items.iter().any(|item| match item {
    9753
    0
                ImportItem::Wildcard => true,
    9754
    0
                ImportItem::Named(item_name) => item_name == func_name,
    9755
    0
                ImportItem::Aliased { name: item_name, .. } => item_name == func_name,
    9756
    0
            })
    9757
    0
        }
    9758
    9759
        /// Import functions from cache (complexity: 3)
    9760
    0
        fn import_from_cache(&mut self, cached_functions: &HashMap<String, Value>, items: &[ImportItem]) {
    9761
    0
            for (func_name, func_value) in cached_functions {
    9762
    0
                if Self::should_import_item(items, func_name) {
    9763
    0
                    self.bindings.insert(func_name.clone(), func_value.clone());
    9764
    0
                }
    9765
            }
    9766
    0
        }
    9767
    9768
        /// Load and cache a module from file (complexity: 7)
    9769
    0
        fn load_and_cache_module(&mut self, path: &str, items: &[ImportItem]) -> Result<()> {
    9770
    0
            let module_path = format!("{path}.ruchy");
    9771
    9772
    0
            if !std::path::Path::new(&module_path).exists() {
    9773
    0
                bail!("Module not found: {}", path);
    9774
    0
            }
    9775
    9776
            // Read and parse the module file
    9777
    0
            let module_content = std::fs::read_to_string(&module_path)
    9778
    0
                .with_context(|| format!("Failed to read module file: {module_path}"))?;
    9779
    9780
    0
            let mut parser = crate::frontend::Parser::new(&module_content);
    9781
    0
            let module_ast = parser.parse()
    9782
    0
                .with_context(|| format!("Failed to parse module: {module_path}"))?;
    9783
    9784
            // Extract and cache all functions from the module
    9785
    0
            let mut module_functions = HashMap::new();
    9786
    0
            self.extract_module_functions(&module_ast, &mut module_functions)?;
    9787
    9788
            // Store in cache for future imports
    9789
    0
            self.module_cache.insert(path.to_string(), module_functions.clone());
    9790
    9791
            // Import requested functions into current scope
    9792
    0
            self.import_from_cache(&module_functions, items);
    9793
    9794
    0
            Ok(())
    9795
    0
        }
    9796
    9797
        /// Main import dispatcher (complexity: 8)
    9798
    0
        fn evaluate_import(&mut self, path: &str, items: &[ImportItem]) -> Result<Value> {
    9799
            // Handle standard library imports
    9800
    0
            match path {
    9801
    0
                "std::fs" | "std::fs::read_file" => {
    9802
    0
                    self.import_std_fs(items)?;
    9803
                }
    9804
    0
                "std::collections" => {
    9805
    0
                    self.import_std_collections(items)?;
    9806
                }
    9807
    0
                "std::mem" | "std::parallel" | "std::simd" | "std::cache" | "std::bench" | "std::profile" => {
    9808
    0
                    self.import_performance_module(path)?;
    9809
                }
    9810
                _ => {
    9811
                    // Check cache first
    9812
    0
                    if let Some(cached_functions) = self.module_cache.get(path).cloned() {
    9813
    0
                        self.import_from_cache(&cached_functions, items);
    9814
    0
                    } else {
    9815
                        // Load from file and cache
    9816
    0
                        self.load_and_cache_module(path, items)?;
    9817
                    }
    9818
                }
    9819
            }
    9820
    9821
    0
            Self::ok_unit()
    9822
    0
        }
    9823
    9824
        /// Extract functions from a module AST into a `HashMap` for caching
    9825
    0
        fn extract_module_functions(&mut self, module_ast: &Expr, functions_map: &mut HashMap<String, Value>) -> Result<()> {
    9826
            // Extract all functions from the module for caching
    9827
    0
            if let ExprKind::Block(exprs) = &module_ast.kind {
    9828
    0
                for expr in exprs {
    9829
    0
                    if let ExprKind::Function { name, params, body, .. } = &expr.kind {
    9830
                        // Extract function and store in cache map
    9831
    0
                        let param_names: Vec<String> = params.iter()
    9832
    0
                            .map(|p| match &p.pattern {
    9833
    0
                                Pattern::Identifier(name) => name.clone(),
    9834
    0
                                _ => "unknown".to_string(), // Simplified for now
    9835
    0
                            })
    9836
    0
                            .collect();
    9837
    9838
    0
                        let function_value = Value::Function {
    9839
    0
                            name: name.clone(),
    9840
    0
                            params: param_names,
    9841
    0
                            body: body.clone(),
    9842
    0
                        };
    9843
    0
                        functions_map.insert(name.clone(), function_value);
    9844
    0
                    }
    9845
                }
    9846
    0
            } else if let ExprKind::Function { name, params, body, .. } = &module_ast.kind {
    9847
                // Single function module
    9848
    0
                let param_names: Vec<String> = params.iter()
    9849
    0
                    .map(|p| match &p.pattern {
    9850
    0
                        Pattern::Identifier(name) => name.clone(),
    9851
    0
                        _ => "unknown".to_string(), // Simplified for now
    9852
    0
                    })
    9853
    0
                    .collect();
    9854
    9855
    0
                let function_value = Value::Function {
    9856
    0
                    name: name.clone(),
    9857
    0
                    params: param_names,
    9858
    0
                    body: body.clone(),
    9859
    0
                };
    9860
    0
                functions_map.insert(name.clone(), function_value);
    9861
    0
            }
    9862
    9863
    0
            Ok(())
    9864
    0
        }
    9865
    9866
        /// Evaluate export statements (complexity < 10)
    9867
    0
        fn evaluate_export(&mut self, _items: &[String]) -> Result<Value> {
    9868
            // For now, just track the export
    9869
            // Real implementation would:
    9870
            // 1. Mark items for export
    9871
            // 2. Make them available to importing modules
    9872
    9873
            // Export handling
    9874
    9875
    0
            Self::ok_unit()
    9876
    0
        }
    9877
    9878
        /// Handle package mode commands
    9879
    0
        fn handle_pkg_command(&mut self, input: &str) -> Result<String> {
    9880
    0
            let parts: Vec<&str> = input.split_whitespace().collect();
    9881
    0
            match parts.first().copied() {
    9882
    0
                Some("search") if parts.len() > 1 => {
    9883
    0
                    Ok(format!("Searching for packages matching '{}'...", parts[1]))
    9884
                }
    9885
    0
                Some("install") if parts.len() > 1 => {
    9886
    0
                    Ok(format!("Installing package '{}'...", parts[1]))
    9887
                }
    9888
    0
                Some("list") => {
    9889
    0
                    Ok("Installed packages:\n(Package management not yet implemented)".to_string())
    9890
                }
    9891
                _ => {
    9892
    0
                    Ok("Package commands: search <query>, install <package>, list".to_string())
    9893
                }
    9894
            }
    9895
    0
        }
    9896
    9897
        /// Show comprehensive help menu
    9898
    0
        fn show_help_menu(&self) -> Result<String> {
    9899
    0
            Ok(r"🔧 Ruchy REPL Help Menu
    9900
    0
    9901
    0
    📋 COMMANDS:
    9902
    0
      :help [topic]  - Show help for specific topic or this menu
    9903
    0
      :quit, :q      - Exit the REPL
    9904
    0
      :clear         - Clear variables and history
    9905
    0
      :history       - Show command history
    9906
    0
      :env           - Show environment variables
    9907
    0
      :type <expr>   - Show type of expression
    9908
    0
      :ast <expr>    - Show abstract syntax tree
    9909
    0
      :inspect <var> - Detailed variable inspection
    9910
    0
    9911
    0
    🎯 MODES:
    9912
    0
      :normal        - Standard evaluation mode
    9913
    0
      :help          - Help documentation mode (current)
    9914
    0
      :debug         - Debug mode with detailed output
    9915
    0
      :time          - Time mode showing execution duration
    9916
    0
      :test          - Test mode with assertions
    9917
    0
      :math          - Enhanced math mode
    9918
    0
      :sql           - SQL query mode (experimental)
    9919
    0
      :shell         - Shell command mode
    9920
    0
    9921
    0
    💡 LANGUAGE TOPICS (type topic name for details):
    9922
    0
      fn             - Function definitions
    9923
    0
      let            - Variable declarations
    9924
    0
      if             - Conditional expressions
    9925
    0
      for            - Loop constructs
    9926
    0
      match          - Pattern matching
    9927
    0
      while          - While loops
    9928
    0
    9929
    0
    🚀 FEATURES:
    9930
    0
      • Arithmetic: +, -, *, /, %, **
    9931
    0
      • Comparisons: ==, !=, <, >, <=, >=
    9932
    0
      • Logical: &&, ||, !
    9933
    0
      • Arrays: [1, 2, 3], indexing with arr[0]
    9934
    0
      • Objects: {key: value}, access with obj.key
    9935
    0
      • String methods: .length(), .to_upper(), .to_lower()
    9936
    0
      • Math functions: sqrt(), pow(), abs(), sin(), cos(), etc.
    9937
    0
      • History: _1, _2, _3 (previous results)
    9938
    0
      • Shell commands: !ls, !pwd, !echo hello
    9939
    0
      • Introspection: ?variable, ??variable (detailed)
    9940
    0
    9941
    0
    Type :normal to exit help mode.
    9942
    0
    ".to_string())
    9943
    0
        }
    9944
    9945
        /// Handle help mode commands
    9946
    0
        fn handle_help_command(&mut self, keyword: &str) -> Result<String> {
    9947
    0
            let help_text = match keyword {
    9948
    0
                "fn" | "function" => "fn - Define a function\nSyntax: fn name(params) { body }\nExample: fn add(a, b) { a + b }".to_string(),
    9949
    0
                "let" | "variable" | "var" => "let - Bind a value to a variable\nSyntax: let name = value\nExample: let x = 42\nMutable: let mut x = 42".to_string(),
    9950
    0
                "if" | "conditional" => "if - Conditional execution\nSyntax: if condition { then } else { otherwise }\nExample: if x > 0 { \"positive\" } else { \"negative\" }".to_string(),
    9951
    0
                "for" | "loop" => "for - Loop over a collection\nSyntax: for item in collection { body }\nExample: for x in [1,2,3] { println(x) }\nRange: for i in 1..5 { println(i) }".to_string(),
    9952
    0
                "while" => "while - Loop with condition\nSyntax: while condition { body }\nExample: while x < 10 { x = x + 1 }".to_string(),
    9953
    0
                "match" | "pattern" => "match - Pattern matching\nSyntax: match value { pattern => result, ... }\nExample: match x { 0 => \"zero\", _ => \"nonzero\" }\nGuards: match x { n if n > 0 => \"positive\", _ => \"other\" }".to_string(),
    9954
    0
                "array" | "list" => "Arrays - Collections of values\nSyntax: [item1, item2, ...]\nExample: let arr = [1, 2, 3]\nAccess: arr[0], arr.length(), arr.first(), arr.last()".to_string(),
    9955
    0
                "object" | "dict" => "Objects - Key-value pairs\nSyntax: {key: value, ...}\nExample: let obj = {name: \"Alice\", age: 30}\nAccess: obj.name, obj.age".to_string(),
    9956
    0
                "string" => "Strings - Text values\nSyntax: \"text\" or 'text'\nMethods: .length(), .to_upper(), .to_lower()\nConcatenation: \"hello\" + \" world\"".to_string(),
    9957
    0
                "math" => "Math Functions - Mathematical operations\nBasic: +, -, *, /, %, **\nFunctions: sqrt(x), pow(x,y), abs(x), min(x,y), max(x,y)\nTrig: sin(x), cos(x), tan(x)\nRounding: floor(x), ceil(x), round(x)".to_string(),
    9958
    0
                "commands" | ":" => self.show_help_menu()?,
    9959
    0
                _ => format!("No help available for '{keyword}'\n\nAvailable topics:\nfn, let, if, for, while, match, array, object, string, math\n\nType 'commands' or ':' for command help.\nType :normal to exit help mode."),
    9960
            };
    9961
    0
            Ok(help_text)
    9962
    0
        }
    9963
    9964
        /// Handle math mode commands
    9965
    0
        fn handle_math_command(&mut self, expr: &str) -> Result<String> {
    9966
            // For now, just evaluate normally but could add special math functions
    9967
    0
            let deadline = Instant::now() + self.config.timeout;
    9968
    0
            let mut parser = Parser::new(expr);
    9969
    0
            let ast = parser.parse().context("Failed to parse math expression")?;
    9970
    0
            let value = self.evaluate_expr(&ast, deadline, 0)?;
    9971
    0
            Ok(format!("= {value}"))
    9972
    0
        }
    9973
    9974
        /// Handle debug mode evaluation
    9975
    0
        fn handle_debug_evaluation(&mut self, input: &str) -> Result<String> {
    9976
            // Use enhanced debug evaluation per progressive modes specification
    9977
    0
            self.handle_enhanced_debug_evaluation(input)
    9978
    0
        }
    9979
    9980
        /// Enhanced debug mode evaluation with detailed traces
    9981
    0
        fn handle_enhanced_debug_evaluation(&mut self, input: &str) -> Result<String> {
    9982
    0
            let start = Instant::now();
    9983
    9984
            // Parse timing
    9985
    0
            let parse_start = Instant::now();
    9986
    0
            let mut parser = Parser::new(input);
    9987
    0
            let ast = parser.parse().context("Failed to parse input")?;
    9988
    0
            let parse_time = parse_start.elapsed();
    9989
    9990
            // Type checking timing (placeholder)
    9991
    0
            let type_start = Instant::now();
    9992
            // Type checking would go here
    9993
    0
            let type_time = type_start.elapsed();
    9994
    9995
            // Evaluation timing
    9996
    0
            let eval_start = Instant::now();
    9997
    0
            let deadline = Instant::now() + self.config.timeout;
    9998
    0
            let value = self.evaluate_expr(&ast, deadline, 0)?;
    9999
    0
            let eval_time = eval_start.elapsed();
    10000
    10001
            // Memory allocation (simplified)
    10002
    0
            let alloc_bytes = 64; // Placeholder
    10003
    10004
    0
            let _total_time = start.elapsed();
    10005
    10006
            // Format trace according to specification
    10007
    0
            let trace = format!(
    10008
    0
                "┌─ Trace ────────┐\n\
    10009
    0
                │ parse:   {:>5.1}ms │\n\
    10010
    0
                │ type:    {:>5.1}ms │\n\
    10011
    0
                │ eval:    {:>5.1}ms │\n\
    10012
    0
                │ alloc:   {:>5}B   │\n\
    10013
    0
                └────────────────┘\n\
    10014
    0
                {}: {} = {}",
    10015
    0
                parse_time.as_secs_f64() * 1000.0,
    10016
    0
                type_time.as_secs_f64() * 1000.0,
    10017
    0
                eval_time.as_secs_f64() * 1000.0,
    10018
                alloc_bytes,
    10019
    0
                input.trim(),
    10020
    0
                self.infer_type(&value),
    10021
                value
    10022
            );
    10023
    10024
    0
            Ok(trace)
    10025
    0
        }
    10026
    10027
        /// Handle timed evaluation
    10028
    0
        fn handle_timed_evaluation(&mut self, input: &str) -> Result<String> {
    10029
    0
            let start = Instant::now();
    10030
    10031
            // Parse
    10032
    0
            let mut parser = Parser::new(input);
    10033
    0
            let ast = parser.parse().context("Failed to parse input")?;
    10034
    10035
            // Evaluate
    10036
    0
            let deadline = Instant::now() + self.config.timeout;
    10037
    0
            let value = self.evaluate_expr(&ast, deadline, 0)?;
    10038
    10039
    0
            let elapsed = start.elapsed();
    10040
    0
            Ok(format!("{value}\n⏱ Time: {elapsed:?}"))
    10041
    0
        }
    10042
    10043
        /// Generate a stack trace from an error
    10044
    0
        fn generate_stack_trace(&self, error: &anyhow::Error) -> Vec<String> {
    10045
    0
            let mut stack_trace = Vec::new();
    10046
    10047
            // Add the main error
    10048
    0
            stack_trace.push(format!("Error: {error}"));
    10049
    10050
            // Add error chain
    10051
    0
            let mut current = error.source();
    10052
    0
            while let Some(err) = current {
    10053
    0
                stack_trace.push(format!("Caused by: {err}"));
    10054
    0
                current = err.source();
    10055
    0
            }
    10056
    10057
            // Add current evaluation context if available
    10058
    0
            if let Some(last_expr) = self.history.last() {
    10059
    0
                stack_trace.push(format!("Last successful expression: {last_expr}"));
    10060
    0
            }
    10061
    10062
    0
            stack_trace
    10063
    0
        }
    10064
    10065
        /// Detect progressive mode activation via attributes like #[test] and #[debug]
    10066
    0
        fn detect_mode_activation(&self, input: &str) -> Option<ReplMode> {
    10067
    0
            let trimmed = input.trim();
    10068
    10069
    0
            if trimmed.starts_with("#[test]") {
    10070
    0
                Some(ReplMode::Test)
    10071
    0
            } else if trimmed.starts_with("#[debug]") {
    10072
    0
                Some(ReplMode::Debug)
    10073
            } else {
    10074
    0
                None
    10075
            }
    10076
    0
        }
    10077
    10078
        /// Handle test mode evaluation with assertions and table tests
    10079
    0
        fn handle_test_evaluation(&mut self, input: &str) -> Result<String> {
    10080
    0
            let trimmed = input.trim();
    10081
    10082
            // Handle assert statements
    10083
    0
            if let Some(stripped) = trimmed.strip_prefix("assert ") {
    10084
    0
                return self.handle_assertion(stripped);
    10085
    0
            }
    10086
    10087
            // Handle table_test! macro
    10088
    0
            if trimmed.starts_with("table_test!(") {
    10089
    0
                return self.handle_table_test(trimmed);
    10090
    0
            }
    10091
    10092
            // Regular evaluation with test result formatting
    10093
    0
            let result = self.eval_internal(input)?;
    10094
    0
            Ok(format!("✓ {result}"))
    10095
    0
        }
    10096
    10097
        /// Handle assertion statements in test mode
    10098
    0
        fn handle_assertion(&mut self, assertion: &str) -> Result<String> {
    10099
            // Parse and evaluate the assertion
    10100
    0
            let mut parser = Parser::new(assertion);
    10101
    0
            let expr = parser.parse().context("Failed to parse assertion")?;
    10102
    10103
    0
            let deadline = Instant::now() + self.config.timeout;
    10104
    0
            let result = self.evaluate_expr(&expr, deadline, 0)?;
    10105
    10106
    0
            match result {
    10107
    0
                Value::Bool(true) => Ok("✓ Pass".to_string()),
    10108
    0
                Value::Bool(false) => Ok("✗ Fail: assertion failed".to_string()),
    10109
    0
                _ => Ok(format!("✗ Fail: assertion must be boolean, got {result}")),
    10110
            }
    10111
    0
        }
    10112
    10113
        /// Handle table test macro
    10114
    0
        fn handle_table_test(&mut self, _input: &str) -> Result<String> {
    10115
            // This is a simplified implementation - in a full version you'd parse the table_test! macro properly
    10116
            // For now, just indicate successful parsing
    10117
    0
            Ok("✓ Table test recognized (full implementation pending)".to_string())
    10118
    0
        }
    10119
    10120
        /// Simple type inference for display purposes
    10121
    0
        fn infer_type(&self, value: &Value) -> &'static str {
    10122
    0
            match value {
    10123
    0
                Value::Int(_) => "Int",
    10124
    0
                Value::Float(_) => "Float",
    10125
    0
                Value::String(_) => "String",
    10126
    0
                Value::Bool(_) => "Bool",
    10127
    0
                Value::Char(_) => "Char",
    10128
    0
                Value::Unit => "Unit",
    10129
    0
                Value::List(_) => "List",
    10130
    0
                Value::Tuple(_) => "Tuple",
    10131
    0
                Value::Object(_) => "Object",
    10132
    0
                Value::Function { .. } => "Function",
    10133
    0
                Value::Lambda { .. } => "Lambda",
    10134
    0
                Value::DataFrame { .. } => "DataFrame",
    10135
    0
                Value::HashMap(_) => "HashMap",
    10136
    0
                Value::HashSet(_) => "HashSet",
    10137
    0
                Value::Range { .. } => "Range",
    10138
    0
                Value::EnumVariant { .. } => "EnumVariant",
    10139
    0
                Value::Nil => "Nil",
    10140
            }
    10141
    0
        }
    10142
    10143
        /// Format size/length information for value (complexity: 8)
    10144
    0
        fn format_value_size(&self, value: &Value) -> String {
    10145
    0
            match value {
    10146
    0
                Value::List(l) => format!("│ Length: {:<20} │\n", l.len()),
    10147
    0
                Value::String(s) => format!("│ Length: {} chars{:<11} │\n", s.len(), ""),
    10148
    0
                Value::Object(o) => format!("│ Fields: {:<20} │\n", o.len()),
    10149
    0
                Value::HashMap(m) => format!("│ Entries: {:<19} │\n", m.len()),
    10150
    0
                Value::HashSet(s) => format!("│ Size: {:<22} │\n", s.len()),
    10151
    0
                Value::Tuple(t) => format!("│ Elements: {:<18} │\n", t.len()),
    10152
    0
                Value::DataFrame { columns, .. } => {
    10153
    0
                    if let Some(first_col) = columns.first() {
    10154
    0
                        let row_count = first_col.values.len();
    10155
    0
                        format!("│ Columns: {:<19} │\n│ Rows: {row_count:<22} │\n", columns.len())
    10156
                    } else {
    10157
    0
                        String::new()
    10158
                    }
    10159
                }
    10160
                _ => {
    10161
                    // Show value preview for simple types
    10162
    0
                    let preview = format!("{value}");
    10163
    0
                    if preview.len() <= 24 {
    10164
    0
                        format!("│ Value: {preview:<21} │\n")
    10165
                    } else {
    10166
    0
                        let truncated = &preview[..21];
    10167
    0
                        format!("│ Value: {truncated}... │\n")
    10168
                    }
    10169
                }
    10170
            }
    10171
    0
        }
    10172
    10173
        /// Format interactive options for value (complexity: 3)
    10174
    0
        fn format_value_options(&self, value: &Value) -> String {
    10175
    0
            let mut output = String::new();
    10176
    0
            output.push_str("│ Options:                   │\n");
    10177
    10178
    0
            match value {
    10179
    0
                Value::List(_) | Value::Object(_) | Value::HashMap(_) => {
    10180
    0
                    output.push_str("│ [Enter] Browse entries     │\n");
    10181
    0
                    output.push_str("│ [S] Statistics             │\n");
    10182
    0
                }
    10183
    0
                Value::Function { .. } | Value::Lambda { .. } => {
    10184
    0
                    output.push_str("│ [P] Show parameters        │\n");
    10185
    0
                    output.push_str("│ [B] Show body              │\n");
    10186
    0
                }
    10187
    0
                _ => {
    10188
    0
                    output.push_str("│ [V] Show full value        │\n");
    10189
    0
                    output.push_str("│ [T] Type details           │\n");
    10190
    0
                }
    10191
            }
    10192
    10193
    0
            output.push_str("│ [M] Memory layout          │\n");
    10194
    0
            output
    10195
    0
        }
    10196
    10197
        /// Create inspector header (complexity: 2)
    10198
    0
        fn create_inspector_header(&self, var_name: &str, value: &Value) -> String {
    10199
    0
            let mut output = String::new();
    10200
    0
            output.push_str("┌─ Inspector ────────────────┐\n");
    10201
    0
            output.push_str(&format!("│ Variable: {var_name:<17} │\n"));
    10202
    0
            output.push_str(&format!("│ Type: {:<22} │\n", self.infer_type(value)));
    10203
    0
            output
    10204
    0
        }
    10205
    10206
        /// Inspect a value in detail (for :inspect command) (complexity: 4)
    10207
    0
        fn inspect_value(&self, var_name: &str) -> String {
    10208
    0
            if let Some(value) = self.bindings.get(var_name) {
    10209
    0
                let mut output = String::new();
    10210
    10211
                // Header with variable name and type
    10212
    0
                output.push_str(&self.create_inspector_header(var_name, value));
    10213
    10214
                // Size/length information
    10215
    0
                output.push_str(&self.format_value_size(value));
    10216
    10217
                // Memory estimation
    10218
    0
                let memory_size = self.estimate_memory_size(value);
    10219
    0
                output.push_str(&format!("│ Memory: ~{:<18} │\n", format!("{memory_size} bytes")));
    10220
    10221
                // Separator line
    10222
    0
                output.push_str("│                            │\n");
    10223
    10224
                // Interactive options
    10225
    0
                output.push_str(&self.format_value_options(value));
    10226
    10227
                // Footer
    10228
    0
                output.push_str("└────────────────────────────┘");
    10229
    10230
    0
                output
    10231
            } else {
    10232
    0
                format!("Variable '{var_name}' not found. Use :env to list all variables.")
    10233
            }
    10234
    0
        }
    10235
    10236
        /// Estimate memory size of a value (simplified)
    10237
    0
        fn estimate_memory_size(&self, value: &Value) -> usize {
    10238
    0
            match value {
    10239
    0
                Value::Int(_) => 8,
    10240
    0
                Value::Float(_) => 8,
    10241
    0
                Value::Bool(_) => 1,
    10242
    0
                Value::Char(_) => 4,
    10243
    0
                Value::Unit => 0,
    10244
    0
                Value::String(s) => s.len() + 24, // String overhead + content
    10245
    0
                Value::List(l) => 24 + l.len() * 8, // Vec overhead + pointers
    10246
    0
                Value::Tuple(t) => 8 + t.len() * 8,
    10247
    0
                Value::Object(o) => 24 + o.len() * 32, // HashMap overhead
    10248
    0
                Value::HashMap(m) => 24 + m.len() * 48,
    10249
    0
                Value::HashSet(s) => 24 + s.len() * 16,
    10250
    0
                Value::Function { .. } | Value::Lambda { .. } => 64, // Simplified
    10251
    0
                Value::DataFrame { columns, .. } => {
    10252
    0
                    24 + columns.len() * 64 // Simplified estimate
    10253
                }
    10254
    0
                Value::Range { .. } => 16,
    10255
    0
                Value::EnumVariant { .. } => 32,
    10256
    0
                Value::Nil => 0,
    10257
            }
    10258
    0
        }
    10259
    10260
        /// Run the REPL with session recording enabled
    10261
        ///
    10262
        /// This method creates a session recorder that tracks all inputs, outputs,
    10263
        /// and state changes during the REPL session. The recorded session can be
    10264
        /// replayed later for testing or educational purposes.
    10265
        ///
    10266
        /// # Arguments
    10267
        /// * `record_file` - Path to save the recorded session
    10268
        ///
    10269
        /// # Returns
    10270
        /// Returns `Ok(())` on successful completion, or an error if recording fails
    10271
        ///
    10272
        /// # Errors
    10273
        /// Returns error if recording initialization fails or I/O operations fail
    10274
    0
        pub fn run_with_recording(&mut self, record_file: &Path) -> Result<()> {
    10275
            // Delegate to refactored version with reduced complexity
    10276
            // Original complexity: 44, New complexity: 15
    10277
    0
            self.run_with_recording_refactored(record_file)
    10278
    0
        }
    10279
    10280
        // Helper methods for reduced complexity REPL::run
    10281
    10282
    0
        fn setup_readline_editor(&self) -> Result<rustyline::Editor<RuchyCompleter, DefaultHistory>> {
    10283
    0
            let config = Config::builder()
    10284
    0
                .history_ignore_space(true)
    10285
    0
                .history_ignore_dups(true)?
    10286
    0
                .completion_type(CompletionType::List)
    10287
    0
                .edit_mode(EditMode::Emacs)
    10288
    0
                .build();
    10289
    10290
    0
            let mut rl = rustyline::Editor::<RuchyCompleter, DefaultHistory>::with_config(config)?;
    10291
    10292
    0
            let completer = RuchyCompleter::new();
    10293
    0
            rl.set_helper(Some(completer));
    10294
    10295
    0
            let history_path = self.temp_dir.join("history.txt");
    10296
    0
            let _ = rl.load_history(&history_path);
    10297
    10298
    0
            Ok(rl)
    10299
    0
        }
    10300
    10301
    0
        fn format_prompt(&self, in_multiline: bool) -> String {
    10302
    0
            if in_multiline {
    10303
    0
                format!("{} ", "   ...".bright_black())
    10304
            } else {
    10305
    0
                format!("{} ", self.get_prompt().bright_green())
    10306
            }
    10307
    0
        }
    10308
    10309
    0
        fn process_input_line(
    10310
    0
            &mut self,
    10311
    0
            line: &str,
    10312
    0
            rl: &mut rustyline::Editor<RuchyCompleter, DefaultHistory>,
    10313
    0
            multiline_state: &mut MultilineState
    10314
    0
        ) -> Result<bool> {
    10315
            // Skip empty lines unless in multiline mode
    10316
    0
            if line.trim().is_empty() && !multiline_state.in_multiline {
    10317
    0
                return Ok(false);
    10318
    0
            }
    10319
    10320
            // Handle commands (only when not in multiline mode)
    10321
    0
            if !multiline_state.in_multiline && line.starts_with(':') {
    10322
    0
                return self.process_command(line);
    10323
    0
            }
    10324
    10325
            // Process regular expression input
    10326
    0
            self.process_expression_input(line, rl, multiline_state)
    10327
    0
        }
    10328
    10329
    0
        fn process_command(&mut self, line: &str) -> Result<bool> {
    10330
    0
            let (should_quit, output) = self.handle_command_with_output(line)?;
    10331
    0
            if !output.is_empty() {
    10332
    0
                println!("{output}");
    10333
    0
            }
    10334
    0
            Ok(should_quit)
    10335
    0
        }
    10336
    10337
    0
        fn process_expression_input(
    10338
    0
            &mut self,
    10339
    0
            line: &str,
    10340
    0
            rl: &mut rustyline::Editor<RuchyCompleter, DefaultHistory>,
    10341
    0
            multiline_state: &mut MultilineState
    10342
    0
        ) -> Result<bool> {
    10343
            // Check if this starts a multiline expression
    10344
    0
            if !multiline_state.in_multiline && Self::needs_continuation(line) {
    10345
    0
                multiline_state.start_multiline(line);
    10346
    0
                return Ok(false);
    10347
    0
            }
    10348
    10349
    0
            if multiline_state.in_multiline {
    10350
    0
                self.process_multiline_input(line, rl, multiline_state)
    10351
            } else {
    10352
    0
                self.process_single_line_input(line, rl)
    10353
            }
    10354
    0
        }
    10355
    10356
    0
        fn process_multiline_input(
    10357
    0
            &mut self,
    10358
    0
            line: &str,
    10359
    0
            rl: &mut rustyline::Editor<RuchyCompleter, DefaultHistory>,
    10360
    0
            multiline_state: &mut MultilineState
    10361
    0
        ) -> Result<bool> {
    10362
    0
            multiline_state.accumulate_line(line);
    10363
    10364
    0
            if !Self::needs_continuation(&multiline_state.buffer) {
    10365
    0
                let _ = rl.add_history_entry(multiline_state.buffer.as_str());
    10366
    0
                self.evaluate_and_print(&multiline_state.buffer);
    10367
    0
                multiline_state.reset();
    10368
    0
            }
    10369
    10370
    0
            Ok(false)
    10371
    0
        }
    10372
    10373
    0
        fn process_single_line_input(
    10374
    0
            &mut self,
    10375
    0
            line: &str,
    10376
    0
            rl: &mut rustyline::Editor<RuchyCompleter, DefaultHistory>
    10377
    0
        ) -> Result<bool> {
    10378
    0
            let _ = rl.add_history_entry(line);
    10379
    0
            self.evaluate_and_print(line);
    10380
    0
            Ok(false)
    10381
    0
        }
    10382
    10383
    0
        fn evaluate_and_print(&mut self, expression: &str) {
    10384
    0
            match self.eval(expression) {
    10385
    0
                Ok(result) => {
    10386
    0
                    println!("{}", result.bright_white());
    10387
    0
                }
    10388
    0
                Err(e) => {
    10389
    0
                    eprintln!("{}: {}", "Error".bright_red().bold(), e);
    10390
    0
                }
    10391
            }
    10392
    0
        }
    10393
    }
    10394
    10395
    // Helper struct for managing multiline state
    10396
    #[derive(Debug)]
    10397
    struct MultilineState {
    10398
        buffer: String,
    10399
        in_multiline: bool,
    10400
    }
    10401
    10402
    impl MultilineState {
    10403
    0
        fn new() -> Self {
    10404
    0
            Self {
    10405
    0
                buffer: String::new(),
    10406
    0
                in_multiline: false,
    10407
    0
            }
    10408
    0
        }
    10409
    10410
    0
        fn start_multiline(&mut self, line: &str) {
    10411
    0
            self.buffer = line.to_string();
    10412
    0
            self.in_multiline = true;
    10413
    0
        }
    10414
    10415
    0
        fn accumulate_line(&mut self, line: &str) {
    10416
    0
            self.buffer.push('\n');
    10417
    0
            self.buffer.push_str(line);
    10418
    0
        }
    10419
    10420
    0
        fn reset(&mut self) {
    10421
    0
            self.buffer.clear();
    10422
    0
            self.in_multiline = false;
    10423
    0
        }
    10424
    }