## 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/backend/transpiler/statements.rs

    Line
    Count
    Source
    1
    //! Statement and control flow transpilation
    2
    3
    #![allow(clippy::missing_errors_doc)]
    4
    #![allow(clippy::wildcard_imports)]
    5
    #![allow(clippy::collapsible_else_if)]
    6
    7
    use super::*;
    8
    use crate::frontend::ast::{CatchClause, Literal, Param, Pattern, PipelineStage, UnaryOp};
    9
    use anyhow::{Result, bail};
    10
    use proc_macro2::TokenStream;
    11
    use quote::{format_ident, quote};
    12
    13
    impl Transpiler {
    14
        /// Checks if a variable is mutated (reassigned or modified) in an expression tree
    15
    0
        fn is_variable_mutated(name: &str, expr: &Expr) -> bool {
    16
            use crate::frontend::ast::ExprKind;
    17
    18
    0
            match &expr.kind {
    19
                // Direct assignment to the variable
    20
    0
                ExprKind::Assign { target, value: _ } => {
    21
    0
                    if let ExprKind::Identifier(var_name) = &target.kind {
    22
    0
                        if var_name == name {
    23
    0
                            return true;
    24
    0
                        }
    25
    0
                    }
    26
    0
                    false
    27
                }
    28
                // Compound assignment (+=, -=, etc.)
    29
    0
                ExprKind::CompoundAssign { target, value: _, .. } => {
    30
    0
                    if let ExprKind::Identifier(var_name) = &target.kind {
    31
    0
                        if var_name == name {
    32
    0
                            return true;
    33
    0
                        }
    34
    0
                    }
    35
    0
                    false
    36
                }
    37
                // Pre/Post increment/decrement
    38
    0
                ExprKind::PreIncrement { target } |
    39
    0
                ExprKind::PostIncrement { target } |
    40
    0
                ExprKind::PreDecrement { target } |
    41
    0
                ExprKind::PostDecrement { target } => {
    42
    0
                    if let ExprKind::Identifier(var_name) = &target.kind {
    43
    0
                        if var_name == name {
    44
    0
                            return true;
    45
    0
                        }
    46
    0
                    }
    47
    0
                    false
    48
                }
    49
                // Check in blocks
    50
    0
                ExprKind::Block(exprs) => {
    51
    0
                    exprs.iter().any(|e| Self::is_variable_mutated(name, e))
    52
                }
    53
                // Check in if branches
    54
    0
                ExprKind::If { condition, then_branch, else_branch } => {
    55
    0
                    Self::is_variable_mutated(name, condition) ||
    56
    0
                    Self::is_variable_mutated(name, then_branch) ||
    57
    0
                    else_branch.as_ref().is_some_and(|e| Self::is_variable_mutated(name, e))
    58
                }
    59
                // Check in while loops
    60
    0
                ExprKind::While { condition, body } => {
    61
    0
                    Self::is_variable_mutated(name, condition) ||
    62
    0
                    Self::is_variable_mutated(name, body)
    63
                }
    64
                // Check in for loops
    65
    0
                ExprKind::For { body, .. } => {
    66
    0
                    Self::is_variable_mutated(name, body)
    67
                }
    68
                // Check in match expressions
    69
    0
                ExprKind::Match { expr, arms } => {
    70
    0
                    Self::is_variable_mutated(name, expr) ||
    71
    0
                    arms.iter().any(|arm| Self::is_variable_mutated(name, &arm.body))
    72
                }
    73
                // Check in nested let expressions
    74
    0
                ExprKind::Let { body, .. } | ExprKind::LetPattern { body, .. } => {
    75
    0
                    Self::is_variable_mutated(name, body)
    76
                }
    77
                // Check in function bodies
    78
    0
                ExprKind::Function { body, .. } => {
    79
    0
                    Self::is_variable_mutated(name, body)
    80
                }
    81
                // Check in lambda bodies
    82
    0
                ExprKind::Lambda { body, .. } => {
    83
    0
                    Self::is_variable_mutated(name, body)
    84
                }
    85
                // Check binary operations
    86
    0
                ExprKind::Binary { left, right, .. } => {
    87
    0
                    Self::is_variable_mutated(name, left) ||
    88
    0
                    Self::is_variable_mutated(name, right)
    89
                }
    90
                // Check unary operations
    91
    0
                ExprKind::Unary { operand, .. } => {
    92
    0
                    Self::is_variable_mutated(name, operand)
    93
                }
    94
                // Check function/method calls
    95
    0
                ExprKind::Call { func, args } => {
    96
    0
                    Self::is_variable_mutated(name, func) ||
    97
    0
                    args.iter().any(|a| Self::is_variable_mutated(name, a))
    98
                }
    99
    0
                ExprKind::MethodCall { receiver, args, .. } => {
    100
    0
                    Self::is_variable_mutated(name, receiver) ||
    101
    0
                    args.iter().any(|a| Self::is_variable_mutated(name, a))
    102
                }
    103
                // Other expressions don't contain mutations
    104
    0
                _ => false,
    105
            }
    106
    0
        }
    107
    108
        /// Transpiles if expressions
    109
    0
        pub fn transpile_if(
    110
    0
            &self,
    111
    0
            condition: &Expr,
    112
    0
            then_branch: &Expr,
    113
    0
            else_branch: Option<&Expr>,
    114
    0
        ) -> Result<TokenStream> {
    115
    0
            let cond_tokens = self.transpile_expr(condition)?;
    116
    0
            let then_tokens = self.transpile_expr(then_branch)?;
    117
    118
    0
            if let Some(else_expr) = else_branch {
    119
    0
                let else_tokens = self.transpile_expr(else_expr)?;
    120
    0
                Ok(quote! {
    121
    0
                    if #cond_tokens {
    122
    0
                        #then_tokens
    123
    0
                    } else {
    124
    0
                        #else_tokens
    125
    0
                    }
    126
    0
                })
    127
            } else {
    128
    0
                Ok(quote! {
    129
    0
                    if #cond_tokens {
    130
    0
                        #then_tokens
    131
    0
                    }
    132
    0
                })
    133
            }
    134
    0
        }
    135
    136
        /// Transpiles let bindings
    137
    0
        pub fn transpile_let(
    138
    0
            &self,
    139
    0
            name: &str,
    140
    0
            value: &Expr,
    141
    0
            body: &Expr,
    142
    0
            is_mutable: bool,
    143
    0
        ) -> Result<TokenStream> {
    144
            // Handle Rust reserved keywords by prefixing with r#
    145
    0
            let safe_name = if Self::is_rust_reserved_keyword(name) {
    146
    0
                format!("r#{name}")
    147
            } else {
    148
    0
                name.to_string()
    149
            };
    150
    0
            let name_ident = format_ident!("{}", safe_name);
    151
    152
            // Auto-detect mutability: check if variable is in the mutable_vars set or is reassigned in body
    153
    0
            let effective_mutability = is_mutable ||
    154
    0
                                      self.mutable_vars.contains(name) ||
    155
    0
                                      Self::is_variable_mutated(name, body);
    156
    157
            // Convert string literals to String type at variable declaration time
    158
            // This ensures string variables are String, not &str, making function calls work
    159
    0
            let value_tokens = match &value.kind {
    160
    0
                crate::frontend::ast::ExprKind::Literal(crate::frontend::ast::Literal::String(s)) => {
    161
    0
                    quote! { #s.to_string() }
    162
                }
    163
    0
                _ => self.transpile_expr(value)?
    164
            };
    165
    166
            // HOTFIX: If body is Unit, this is a top-level let statement without scoping
    167
    0
            if matches!(body.kind, crate::frontend::ast::ExprKind::Literal(crate::frontend::ast::Literal::Unit)) {
    168
    0
                if effective_mutability {
    169
    0
                    Ok(quote! { let mut #name_ident = #value_tokens; })
    170
                } else {
    171
    0
                    Ok(quote! { let #name_ident = #value_tokens; })
    172
                }
    173
            } else {
    174
                // Check if body is a Block containing sequential let statements
    175
                // This flattens nested let expressions to avoid excessive nesting
    176
    0
                if let crate::frontend::ast::ExprKind::Block(exprs) = &body.kind {
    177
                    // Flatten sequential let statements into a single block
    178
    0
                    let mut statements = Vec::new();
    179
    180
                    // Add the current let statement
    181
    0
                    if effective_mutability {
    182
    0
                        statements.push(quote! { let mut #name_ident = #value_tokens; });
    183
    0
                    } else {
    184
    0
                        statements.push(quote! { let #name_ident = #value_tokens; });
    185
    0
                    }
    186
    187
                    // Add all the block expressions
    188
    0
                    for (i, expr) in exprs.iter().enumerate() {
    189
    0
                        let expr_tokens = self.transpile_expr(expr)?;
    190
    191
                        // Check if this is a Let expression with Unit body (standalone let statement)
    192
                        // These already have semicolons from transpile_let
    193
    0
                        let is_standalone_let = matches!(&expr.kind,
    194
    0
                            crate::frontend::ast::ExprKind::Let { body, .. }
    195
    0
                            if matches!(body.kind, crate::frontend::ast::ExprKind::Literal(crate::frontend::ast::Literal::Unit))
    196
                        );
    197
    198
    0
                        if is_standalone_let {
    199
    0
                            // Standalone let statements already have semicolons
    200
    0
                            statements.push(expr_tokens);
    201
    0
                        } else if i < exprs.len() - 1 {
    202
    0
                            // Not the last statement - add semicolon
    203
    0
                            statements.push(quote! { #expr_tokens; });
    204
    0
                        } else {
    205
                            // Last expression - check if it's void
    206
    0
                            if self.is_void_expression(expr) {
    207
    0
                                statements.push(quote! { #expr_tokens; });
    208
    0
                            } else {
    209
    0
                                statements.push(expr_tokens);
    210
    0
                            }
    211
                        }
    212
                    }
    213
    214
    0
                    Ok(quote! { #(#statements)* })
    215
                } else {
    216
                    // Traditional let-in expression with proper scoping
    217
    0
                    let body_tokens = self.transpile_expr(body)?;
    218
    0
                    if effective_mutability {
    219
    0
                        Ok(quote! {
    220
    0
                            {
    221
    0
                                let mut #name_ident = #value_tokens;
    222
    0
                                #body_tokens
    223
    0
                            }
    224
    0
                        })
    225
                    } else {
    226
    0
                        Ok(quote! {
    227
    0
                            {
    228
    0
                                let #name_ident = #value_tokens;
    229
    0
                                #body_tokens
    230
    0
                            }
    231
    0
                        })
    232
                    }
    233
                }
    234
            }
    235
    0
        }
    236
    237
        /// Transpiles let pattern bindings (destructuring)
    238
    0
        pub fn transpile_let_pattern(
    239
    0
            &self,
    240
    0
            pattern: &crate::frontend::ast::Pattern,
    241
    0
            value: &Expr,
    242
    0
            body: &Expr,
    243
    0
        ) -> Result<TokenStream> {
    244
    0
            let pattern_tokens = self.transpile_pattern(pattern)?;
    245
    0
            let value_tokens = self.transpile_expr(value)?;
    246
    247
            // HOTFIX: If body is Unit, this is a top-level let statement without scoping
    248
    0
            if matches!(body.kind, crate::frontend::ast::ExprKind::Literal(crate::frontend::ast::Literal::Unit)) {
    249
    0
                Ok(quote! { let #pattern_tokens = #value_tokens })
    250
            } else {
    251
                // Traditional let-in expression with proper scoping
    252
    0
                let body_tokens = self.transpile_expr(body)?;
    253
    0
                Ok(quote! {
    254
    0
                    {
    255
    0
                        let #pattern_tokens = #value_tokens;
    256
    0
                        #body_tokens
    257
    0
                    }
    258
    0
                })
    259
            }
    260
    0
        }
    261
    262
        /// Check if function name suggests numeric operations
    263
    0
        fn looks_like_numeric_function(&self, name: &str) -> bool {
    264
    0
            matches!(name,
    265
    0
                "add" | "subtract" | "multiply" | "divide" | "sum" | "product" |
    266
    0
                "min" | "max" | "abs" | "sqrt" | "pow" | "mod" | "gcd" | "lcm" |
    267
    0
                "factorial" | "fibonacci" | "prime" | "even" | "odd" | "square" | "cube" |
    268
    0
                "double" | "triple" | "quadruple"  // Added common numeric function names
    269
            )
    270
    0
        }
    271
    272
    273
        /// Check if expression is a void/unit function call
    274
    0
        fn is_void_function_call(&self, expr: &Expr) -> bool {
    275
    0
            match &expr.kind {
    276
    0
                crate::frontend::ast::ExprKind::Call { func, .. } => {
    277
    0
                    if let crate::frontend::ast::ExprKind::Identifier(name) = &func.kind {
    278
                        // Comprehensive list of void functions
    279
    0
                        matches!(name.as_str(),
    280
                            // Output functions
    281
    0
                            "println" | "print" | "eprintln" | "eprint" |
    282
                            // Debug functions
    283
    0
                            "dbg" | "debug" | "trace" | "info" | "warn" | "error" |
    284
                            // Control flow functions
    285
    0
                            "panic" | "assert" | "assert_eq" | "assert_ne" |
    286
    0
                            "todo" | "unimplemented" | "unreachable"
    287
                        )
    288
                    } else {
    289
    0
                        false
    290
                    }
    291
                }
    292
    0
                _ => false
    293
            }
    294
    0
        }
    295
    296
        /// Check if an expression is void (returns unit/nothing)
    297
    0
        fn is_void_expression(&self, expr: &Expr) -> bool {
    298
    0
            match &expr.kind {
    299
                // Unit literal is void
    300
    0
                crate::frontend::ast::ExprKind::Literal(crate::frontend::ast::Literal::Unit) => true,
    301
    302
                // Void function calls
    303
    0
                crate::frontend::ast::ExprKind::Call { .. } if self.is_void_function_call(expr) => true,
    304
    305
                // Assignments are void
    306
                crate::frontend::ast::ExprKind::Assign { .. } |
    307
    0
                crate::frontend::ast::ExprKind::CompoundAssign { .. } => true,
    308
    309
                // Loops are void
    310
                crate::frontend::ast::ExprKind::While { .. } |
    311
    0
                crate::frontend::ast::ExprKind::For { .. } => true,
    312
    313
                // Let bindings - check the body expression
    314
    0
                crate::frontend::ast::ExprKind::Let { body, .. } => {
    315
    0
                    self.is_void_expression(body)
    316
                }
    317
    318
                // Block - check last expression
    319
    0
                crate::frontend::ast::ExprKind::Block(exprs) => {
    320
    0
                    exprs.last().is_none_or(|e| self.is_void_expression(e))
    321
                }
    322
    323
                // If expression - both branches must be void
    324
    0
                crate::frontend::ast::ExprKind::If { then_branch, else_branch, .. } => {
    325
    0
                    self.is_void_expression(then_branch) &&
    326
    0
                    else_branch.as_ref().is_none_or(|e| self.is_void_expression(e))
    327
                }
    328
    329
                // Match expression - all arms must be void
    330
    0
                crate::frontend::ast::ExprKind::Match { arms, .. } => {
    331
    0
                    arms.iter().all(|arm| self.is_void_expression(&arm.body))
    332
                }
    333
    334
                // Return without value is void
    335
    0
                crate::frontend::ast::ExprKind::Return { value } if value.is_none() => true,
    336
    337
                // Everything else produces a value
    338
    0
                _ => false
    339
            }
    340
    0
        }
    341
    342
        /// Check if expression has a non-unit value (i.e., returns something meaningful)
    343
    0
        fn has_non_unit_expression(&self, body: &Expr) -> bool {
    344
    0
            !self.is_void_expression(body)
    345
    0
        }
    346
    347
    348
        /// Transpiles function definitions
    349
        #[allow(clippy::too_many_arguments)]
    350
        /// Infer parameter type based on usage in function body
    351
    0
        fn infer_param_type(&self, param: &Param, body: &Expr, func_name: &str) -> TokenStream {
    352
            use super::type_inference::{is_param_used_as_function, is_param_used_numerically, is_param_used_as_function_argument};
    353
    354
    0
            if is_param_used_as_function(&param.name(), body) {
    355
    0
                quote! { impl Fn(i32) -> i32 }
    356
    0
            } else if is_param_used_numerically(&param.name(), body) ||
    357
    0
                      self.looks_like_numeric_function(func_name) ||
    358
    0
                      is_param_used_as_function_argument(&param.name(), body) {
    359
    0
                quote! { i32 }
    360
            } else {
    361
    0
                quote! { String }
    362
            }
    363
    0
        }
    364
    365
        /// Generate parameter tokens with proper type inference
    366
    0
        fn generate_param_tokens(&self, params: &[Param], body: &Expr, func_name: &str) -> Result<Vec<TokenStream>> {
    367
    0
            params
    368
    0
                .iter()
    369
    0
                .map(|p| {
    370
    0
                    let param_name = format_ident!("{}", p.name());
    371
    0
                    let type_tokens = if let Ok(tokens) = self.transpile_type(&p.ty) {
    372
    0
                        let token_str = tokens.to_string();
    373
    0
                        if token_str == "_" {
    374
    0
                            self.infer_param_type(p, body, func_name)
    375
                        } else {
    376
    0
                            tokens
    377
                        }
    378
                    } else {
    379
    0
                        self.infer_param_type(p, body, func_name)
    380
                    };
    381
    0
                    Ok(quote! { #param_name: #type_tokens })
    382
    0
                })
    383
    0
                .collect()
    384
    0
        }
    385
    386
        /// Generate return type tokens based on function analysis
    387
    0
        fn generate_return_type_tokens(&self, name: &str, return_type: Option<&Type>, body: &Expr) -> Result<TokenStream> {
    388
            // FIRST CHECK: Override for test functions
    389
    0
            if name.starts_with("test_") {
    390
    0
                return Ok(quote! {});
    391
    0
            }
    392
    393
    0
            if let Some(ty) = return_type {
    394
    0
                let ty_tokens = self.transpile_type(ty)?;
    395
    0
                Ok(quote! { -> #ty_tokens })
    396
    0
            } else if name == "main" {
    397
    0
                Ok(quote! {})
    398
    0
            } else if self.looks_like_numeric_function(name) {
    399
    0
                Ok(quote! { -> i32 })
    400
    0
            } else if self.has_non_unit_expression(body) {
    401
    0
                Ok(quote! { -> i32 })
    402
            } else {
    403
    0
                Ok(quote! {})
    404
            }
    405
    0
        }
    406
    407
        /// Generate body tokens with async support
    408
    0
        fn generate_body_tokens(&self, body: &Expr, is_async: bool) -> Result<TokenStream> {
    409
    0
            if is_async {
    410
    0
                let mut async_transpiler = Transpiler::new();
    411
    0
                async_transpiler.in_async_context = true;
    412
    0
                async_transpiler.transpile_expr(body)
    413
            } else {
    414
                // Check if body is already a block to avoid double-wrapping
    415
    0
                match &body.kind {
    416
    0
                    ExprKind::Block(exprs) => {
    417
                        // For function bodies that are blocks, transpile the contents directly
    418
    0
                        if exprs.len() == 1 {
    419
                            // Single expression block - transpile the expression directly
    420
    0
                            self.transpile_expr(&exprs[0])
    421
                        } else {
    422
                            // Multiple expressions - need proper semicolons between statements
    423
    0
                            let mut statements = Vec::new();
    424
    0
                            for (i, expr) in exprs.iter().enumerate() {
    425
    0
                                let expr_tokens = self.transpile_expr(expr)?;
    426
    427
                                // Add semicolons to all statements except the last one
    428
                                // (unless it's a void expression that needs a semicolon)
    429
    0
                                if i < exprs.len() - 1 {
    430
    0
                                    // Not the last statement - always add semicolon
    431
    0
                                    statements.push(quote! { #expr_tokens; });
    432
    0
                                } else {
    433
                                    // Last statement - check if it's void
    434
    0
                                    if self.is_void_expression(expr) {
    435
    0
                                        // Void expressions should have semicolons
    436
    0
                                        statements.push(quote! { #expr_tokens; });
    437
    0
                                    } else {
    438
    0
                                        // Non-void last expression - no semicolon (it's the return value)
    439
    0
                                        statements.push(expr_tokens);
    440
    0
                                    }
    441
                                }
    442
                            }
    443
    444
    0
                            if statements.is_empty() {
    445
    0
                                Ok(quote! {})
    446
                            } else {
    447
    0
                                Ok(quote! { #(#statements)* })
    448
                            }
    449
                        }
    450
                    },
    451
                    _ => {
    452
                        // Not a block - transpile normally
    453
    0
                        self.transpile_expr(body)
    454
                    }
    455
                }
    456
            }
    457
    0
        }
    458
    459
        /// Generate type parameter tokens with trait bound support
    460
    0
        fn generate_type_param_tokens(&self, type_params: &[String]) -> Result<Vec<TokenStream>> {
    461
    0
            Ok(type_params
    462
    0
                .iter()
    463
    0
                .map(|p| {
    464
    0
                    if p.contains(':') {
    465
                        // Complex trait bound - parse as TokenStream
    466
    0
                        p.parse().unwrap_or_else(|_| quote! { T })
    467
                    } else {
    468
                        // Simple type parameter
    469
    0
                        let ident = format_ident!("{}", p);
    470
    0
                        quote! { #ident }
    471
                    }
    472
    0
                })
    473
    0
                .collect())
    474
    0
        }
    475
    476
        /// Generate complete function signature
    477
    0
        fn generate_function_signature(
    478
    0
            &self,
    479
    0
            is_pub: bool,
    480
    0
            is_async: bool,
    481
    0
            fn_name: &proc_macro2::Ident,
    482
    0
            type_param_tokens: &[TokenStream],
    483
    0
            param_tokens: &[TokenStream],
    484
    0
            return_type_tokens: &TokenStream,
    485
    0
            body_tokens: &TokenStream,
    486
    0
            attributes: &[crate::frontend::ast::Attribute],
    487
    0
        ) -> Result<TokenStream> {
    488
            // Override return type for test functions
    489
    0
            let final_return_type = if fn_name.to_string().starts_with("test_") {
    490
    0
                quote! {}
    491
            } else {
    492
    0
                return_type_tokens.clone()
    493
            };
    494
    0
            let visibility = if is_pub { quote! { pub } } else { quote! {} };
    495
    496
            // Generate attribute tokens
    497
    0
            let attr_tokens: Vec<TokenStream> = attributes.iter()
    498
    0
                .map(|attr| {
    499
    0
                    let attr_name = format_ident!("{}", attr.name);
    500
    0
                    if attr.args.is_empty() {
    501
    0
                        quote! { #[#attr_name] }
    502
                    } else {
    503
    0
                        let args: Vec<TokenStream> = attr.args.iter()
    504
    0
                            .map(|arg| arg.parse().unwrap_or_else(|_| quote! { #arg }))
    505
    0
                            .collect();
    506
    0
                        quote! { #[#attr_name(#(#args),*)] }
    507
                    }
    508
    0
                })
    509
    0
                .collect();
    510
    511
    0
            Ok(match (type_param_tokens.is_empty(), is_async) {
    512
    0
                (true, false) => quote! {
    513
                    #(#attr_tokens)*
    514
                    #visibility fn #fn_name(#(#param_tokens),*) #final_return_type {
    515
                        #body_tokens
    516
                    }
    517
                },
    518
    0
                (true, true) => quote! {
    519
                    #(#attr_tokens)*
    520
                    #visibility async fn #fn_name(#(#param_tokens),*) #final_return_type {
    521
                        #body_tokens
    522
                    }
    523
                },
    524
    0
                (false, false) => quote! {
    525
                    #(#attr_tokens)*
    526
                    #visibility fn #fn_name<#(#type_param_tokens),*>(#(#param_tokens),*) #final_return_type {
    527
                        #body_tokens
    528
                    }
    529
                },
    530
    0
                (false, true) => quote! {
    531
                    #(#attr_tokens)*
    532
                    #visibility async fn #fn_name<#(#type_param_tokens),*>(#(#param_tokens),*) #final_return_type {
    533
                        #body_tokens
    534
                    }
    535
                },
    536
            })
    537
    0
        }
    538
    539
    0
        pub fn transpile_function(
    540
    0
            &self,
    541
    0
            name: &str,
    542
    0
            type_params: &[String],
    543
    0
            params: &[Param],
    544
    0
            body: &Expr,
    545
    0
            is_async: bool,
    546
    0
            return_type: Option<&Type>,
    547
    0
            is_pub: bool,
    548
    0
            attributes: &[crate::frontend::ast::Attribute],
    549
    0
        ) -> Result<TokenStream> {
    550
    0
            let fn_name = format_ident!("{}", name);
    551
    0
            let param_tokens = self.generate_param_tokens(params, body, name)?;
    552
    0
            let body_tokens = self.generate_body_tokens(body, is_async)?;
    553
    554
            // Check for #[test] attribute and override return type if found
    555
    0
            let has_test_attribute = attributes.iter().any(|attr| attr.name == "test");
    556
    557
    0
            let effective_return_type = if has_test_attribute {
    558
    0
                None // Test functions should have unit return type
    559
            } else {
    560
    0
                return_type
    561
            };
    562
    563
    0
            let return_type_tokens = self.generate_return_type_tokens(name, effective_return_type, body)?;
    564
    0
            let type_param_tokens = self.generate_type_param_tokens(type_params)?;
    565
    566
    0
            self.generate_function_signature(
    567
    0
                is_pub,
    568
    0
                is_async,
    569
    0
                &fn_name,
    570
    0
                &type_param_tokens,
    571
    0
                &param_tokens,
    572
    0
                &return_type_tokens,
    573
    0
                &body_tokens,
    574
    0
                attributes
    575
            )
    576
    0
        }
    577
    578
        /// Transpiles lambda expressions
    579
    0
        pub fn transpile_lambda(&self, params: &[Param], body: &Expr) -> Result<TokenStream> {
    580
    0
            let param_names: Vec<_> = params
    581
    0
                .iter()
    582
    0
                .map(|p| format_ident!("{}", p.name()))
    583
    0
                .collect();
    584
    0
            let body_tokens = self.transpile_expr(body)?;
    585
    586
            // Generate closure with proper formatting (no spaces around commas)
    587
    0
            if param_names.is_empty() {
    588
    0
                Ok(quote! { || #body_tokens })
    589
            } else {
    590
                // Use a more controlled approach to avoid extra spaces
    591
    0
                let param_list = param_names
    592
    0
                    .iter()
    593
    0
                    .map(std::string::ToString::to_string)
    594
    0
                    .collect::<Vec<_>>()
    595
    0
                    .join(",");
    596
    0
                let closure_str = format!("|{param_list}| {body_tokens}");
    597
    0
                closure_str
    598
    0
                    .parse()
    599
    0
                    .map_err(|e| anyhow::anyhow!("Failed to parse closure: {}", e))
    600
            }
    601
    0
        }
    602
    603
        /// Transpiles function calls
    604
        ///
    605
        /// # Examples
    606
        ///
    607
        /// ```
    608
        /// use ruchy::{Transpiler, Parser};
    609
        ///
    610
        /// let transpiler = Transpiler::new();
    611
        /// let mut parser = Parser::new(r#"println("Hello, {}", name)"#);
    612
        /// let ast = parser.parse().unwrap();
    613
        /// let result = transpiler.transpile(&ast).unwrap().to_string();
    614
        /// assert!(result.contains("println !"));
    615
        /// assert!(result.contains("Hello, {}"));
    616
        /// ```
    617
        ///
    618
        /// ```
    619
        /// use ruchy::{Transpiler, Parser};
    620
        ///
    621
        /// let transpiler = Transpiler::new();
    622
        /// let mut parser = Parser::new(r#"println("Simple message")"#);
    623
        /// let ast = parser.parse().unwrap();
    624
        /// let result = transpiler.transpile(&ast).unwrap().to_string();
    625
        /// assert!(result.contains("println !"));
    626
        /// assert!(result.contains("Simple message"));
    627
        /// ```
    628
        ///
    629
        /// ```
    630
        /// use ruchy::{Transpiler, Parser};
    631
        ///
    632
        /// let transpiler = Transpiler::new();
    633
        /// let mut parser = Parser::new("some_function(\"test\")");
    634
        /// let ast = parser.parse().unwrap();
    635
        /// let result = transpiler.transpile(&ast).unwrap().to_string();
    636
        /// assert!(result.contains("some_function"));
    637
        /// assert!(result.contains("test"));
    638
        /// ```
    639
    0
        pub fn transpile_call(&self, func: &Expr, args: &[Expr]) -> Result<TokenStream> {
    640
    0
            let func_tokens = self.transpile_expr(func)?;
    641
    642
            // Check if this is a built-in function with special handling
    643
    0
            if let ExprKind::Identifier(name) = &func.kind {
    644
    0
                let base_name = if name.ends_with('!') {
    645
    0
                    name.strip_suffix('!').unwrap_or(name)
    646
                } else {
    647
    0
                    name
    648
                };
    649
    650
                // Try specialized handlers in order of precedence
    651
    0
                if let Some(result) = self.try_transpile_print_macro(&func_tokens, base_name, args)? {
    652
    0
                    return Ok(result);
    653
    0
                }
    654
    655
    0
                if let Some(result) = self.try_transpile_math_function(base_name, args)? {
    656
    0
                    return Ok(result);
    657
    0
                }
    658
    659
    0
                if let Some(result) = self.try_transpile_input_function(base_name, args)? {
    660
    0
                    return Ok(result);
    661
    0
                }
    662
    663
    0
                if let Some(result) = self.try_transpile_assert_function(&func_tokens, base_name, args)? {
    664
    0
                    return Ok(result);
    665
    0
                }
    666
    667
    0
                if let Some(result) = self.try_transpile_type_conversion(base_name, args)? {
    668
    0
                    return Ok(result);
    669
    0
                }
    670
    671
    0
                if let Some(result) = self.try_transpile_math_functions(base_name, args)? {
    672
    0
                    return Ok(result);
    673
    0
                }
    674
    675
    0
                if let Some(result) = self.try_transpile_collection_constructor(base_name, args)? {
    676
    0
                    return Ok(result);
    677
    0
                }
    678
    679
    0
                if let Some(result) = self.try_transpile_dataframe_function(base_name, args)? {
    680
    0
                    return Ok(result);
    681
    0
                }
    682
    0
            }
    683
    684
            // Default: regular function call with string conversion
    685
    0
            self.transpile_regular_function_call(&func_tokens, args)
    686
    0
        }
    687
    688
    689
        /// Transpiles println/print with string interpolation directly
    690
    0
        fn transpile_print_with_interpolation(
    691
    0
            &self,
    692
    0
            func_name: &str,
    693
    0
            parts: &[crate::frontend::ast::StringPart],
    694
    0
        ) -> Result<TokenStream> {
    695
    0
            if parts.is_empty() {
    696
    0
                let func_tokens = proc_macro2::Ident::new(func_name, proc_macro2::Span::call_site());
    697
    0
                return Ok(quote! { #func_tokens!("") });
    698
    0
            }
    699
    700
    0
            let mut format_string = String::new();
    701
    0
            let mut args = Vec::new();
    702
    703
    0
            for part in parts {
    704
    0
                match part {
    705
    0
                    crate::frontend::ast::StringPart::Text(s) => {
    706
    0
                        // Escape any format specifiers in literal parts
    707
    0
                        format_string.push_str(&s.replace('{', "{{").replace('}', "}}"));
    708
    0
                    }
    709
    0
                    crate::frontend::ast::StringPart::Expr(expr) => {
    710
    0
                        format_string.push_str("{}");
    711
    0
                        let expr_tokens = self.transpile_expr(expr)?;
    712
    0
                        args.push(expr_tokens);
    713
                    }
    714
    0
                    crate::frontend::ast::StringPart::ExprWithFormat { expr, format_spec } => {
    715
                        // Include the format specifier in the format string
    716
    0
                        format_string.push('{');
    717
    0
                        format_string.push_str(format_spec);
    718
    0
                        format_string.push('}');
    719
    0
                        let expr_tokens = self.transpile_expr(expr)?;
    720
    0
                        args.push(expr_tokens);
    721
                    }
    722
                }
    723
            }
    724
    725
    0
            let func_tokens = proc_macro2::Ident::new(func_name, proc_macro2::Span::call_site());
    726
    727
    0
            Ok(quote! {
    728
                #func_tokens!(#format_string #(, #args)*)
    729
            })
    730
    0
        }
    731
    732
        /// Transpiles method calls
    733
        #[allow(clippy::cognitive_complexity)]
    734
    0
        pub fn transpile_method_call(
    735
    0
            &self,
    736
    0
            object: &Expr,
    737
    0
            method: &str,
    738
    0
            args: &[Expr],
    739
    0
        ) -> Result<TokenStream> {
    740
            // Check if this is part of a DataFrame builder pattern
    741
    0
            if method == "column" || method == "build" {
    742
                // Build the full method call expression to check for builder pattern
    743
    0
                let method_call_expr = Expr {
    744
    0
                    kind: ExprKind::MethodCall {
    745
    0
                        receiver: Box::new(object.clone()),
    746
    0
                        method: method.to_string(),
    747
    0
                        args: args.to_vec(),
    748
    0
                    },
    749
    0
                    span: object.span,
    750
    0
                    attributes: vec![],
    751
    0
                };
    752
    753
    0
                if let Some(tokens) = self.transpile_dataframe_builder(&method_call_expr)? {
    754
    0
                    return Ok(tokens);
    755
    0
                }
    756
    0
            }
    757
    758
            // Use the old implementation for other cases
    759
    0
            self.transpile_method_call_old(object, method, args)
    760
    0
        }
    761
    762
        #[allow(dead_code)]
    763
    0
        fn transpile_method_call_old(
    764
    0
            &self,
    765
    0
            object: &Expr,
    766
    0
            method: &str,
    767
    0
            args: &[Expr],
    768
    0
        ) -> Result<TokenStream> {
    769
    0
            let obj_tokens = self.transpile_expr(object)?;
    770
    0
            let method_ident = format_ident!("{}", method);
    771
    0
            let arg_tokens: Result<Vec<_>> = args.iter().map(|a| self.transpile_expr(a)).collect();
    772
    0
            let arg_tokens = arg_tokens?;
    773
    774
            // Check DataFrame methods FIRST before generic collection methods
    775
    0
            if self.is_dataframe_expr(object) && matches!(method,
    776
    0
                "get" | "rows" | "columns" | "select" | "filter" | "sort" |
    777
    0
                "head" | "tail" | "mean" | "std" | "min" | "max" | "sum" | "count"
    778
            ) {
    779
    0
                return self.transpile_dataframe_method(object, method, args);
    780
    0
            }
    781
    782
            // Dispatch to specialized handlers based on method category
    783
    0
            match method {
    784
                // Iterator operations (map, filter, reduce)
    785
    0
                "map" | "filter" | "reduce" => {
    786
    0
                    self.transpile_iterator_methods(&obj_tokens, method, &arg_tokens)
    787
                }
    788
                // HashMap/HashSet methods (get, contains_key, items, etc.)
    789
    0
                "get" | "contains_key" | "keys" | "values" | "entry" | "items" |
    790
    0
                "update" | "add" => {
    791
    0
                    self.transpile_map_set_methods(&obj_tokens, &method_ident, method, &arg_tokens)
    792
                }
    793
                // Set operations (union, intersection, difference, symmetric_difference)
    794
    0
                "union" | "intersection" | "difference" | "symmetric_difference" => {
    795
    0
                    self.transpile_set_operations(&obj_tokens, method, &arg_tokens)
    796
                }
    797
                // Common collection methods (insert, remove, clear, len, is_empty, iter)
    798
    0
                "insert" | "remove" | "clear" | "len" | "is_empty" | "iter" => {
    799
    0
                    Ok(quote! { #obj_tokens.#method_ident(#(#arg_tokens),*) })
    800
                }
    801
                // DataFrame operations - use special handling for correct Polars API
    802
    0
                "select" | "groupby" | "group_by" | "agg" | "sort" | "mean" | "std" | "min"
    803
    0
                | "max" | "sum" | "count" | "drop_nulls" | "fill_null" | "pivot"
    804
    0
                | "melt" | "head" | "tail" | "sample" | "describe" | "rows" | "columns" | "column" | "build" => {
    805
                    // Check if this is a DataFrame operation
    806
    0
                    if self.is_dataframe_expr(object) {
    807
    0
                        self.transpile_dataframe_method(object, method, args)
    808
                    } else {
    809
    0
                        Ok(quote! { #obj_tokens.#method_ident(#(#arg_tokens),*) })
    810
                    }
    811
                }
    812
                // String methods (Python-style and Rust-style)
    813
    0
                "to_s" | "to_string" | "to_upper" | "to_lower" | "upper" | "lower" |
    814
    0
                "length" | "substring" | "strip" | "lstrip" | "rstrip" |
    815
    0
                "startswith" | "endswith" | "split" | "replace" => {
    816
    0
                    self.transpile_string_methods(&obj_tokens, method, &arg_tokens)
    817
                }
    818
                // List/Vec methods (Python-style)
    819
    0
                "append" => {
    820
                    // Python's append() -> Rust's push()
    821
    0
                    Ok(quote! { #obj_tokens.push(#(#arg_tokens),*) })
    822
                }
    823
    0
                "extend" => {
    824
                    // Python's extend() -> Rust's extend()
    825
    0
                    Ok(quote! { #obj_tokens.extend(#(#arg_tokens),*) })
    826
                }
    827
                // Collection methods that work as-is (not already handled above)
    828
    0
                "push" | "pop" | "contains" => {
    829
    0
                    Ok(quote! { #obj_tokens.#method_ident(#(#arg_tokens),*) })
    830
                }
    831
                // Advanced collection methods (slice, concat, flatten, unique, join)
    832
    0
                "slice" | "concat" | "flatten" | "unique" | "join" => {
    833
    0
                    self.transpile_advanced_collection_methods(&obj_tokens, method, &arg_tokens)
    834
                }
    835
                _ => {
    836
                    // Regular method call
    837
    0
                    Ok(quote! { #obj_tokens.#method_ident(#(#arg_tokens),*) })
    838
                }
    839
            }
    840
    0
        }
    841
    842
        /// Handle iterator operations: map, filter, reduce
    843
    0
        fn transpile_iterator_methods(&self, obj_tokens: &TokenStream, method: &str, arg_tokens: &[TokenStream]) -> Result<TokenStream> {
    844
    0
            match method {
    845
    0
                "map" => {
    846
                    // vec.map(f) -> vec.iter().map(f).collect::<Vec<_>>()
    847
    0
                    Ok(quote! { #obj_tokens.iter().map(#(#arg_tokens),*).collect::<Vec<_>>() })
    848
                }
    849
    0
                "filter" => {
    850
                    // vec.filter(f) -> vec.into_iter().filter(f).collect::<Vec<_>>()
    851
    0
                    Ok(quote! { #obj_tokens.into_iter().filter(#(#arg_tokens),*).collect::<Vec<_>>() })
    852
                }
    853
    0
                "reduce" => {
    854
                    // vec.reduce(f) -> vec.into_iter().reduce(f)
    855
    0
                    Ok(quote! { #obj_tokens.into_iter().reduce(#(#arg_tokens),*) })
    856
                }
    857
    0
                _ => unreachable!("Non-iterator method passed to transpile_iterator_methods"),
    858
            }
    859
    0
        }
    860
    861
        /// Handle HashMap/HashSet methods: get, `contains_key`, items, etc.
    862
    0
        fn transpile_map_set_methods(&self, obj_tokens: &TokenStream, method_ident: &proc_macro2::Ident, method: &str, arg_tokens: &[TokenStream]) -> Result<TokenStream> {
    863
    0
            match method {
    864
    0
                "get" => {
    865
                    // HashMap.get() returns Option<&V>, but we want owned values
    866
    0
                    Ok(quote! { #obj_tokens.#method_ident(#(#arg_tokens),*).cloned() })
    867
                }
    868
    0
                "contains_key" | "keys" | "values" | "entry" | "contains" => {
    869
    0
                    Ok(quote! { #obj_tokens.#method_ident(#(#arg_tokens),*) })
    870
                }
    871
    0
                "items" => {
    872
                    // HashMap.items() -> iterator of (K, V) tuples (not references)
    873
    0
                    Ok(quote! { #obj_tokens.iter().map(|(k, v)| (k.clone(), v.clone())) })
    874
                }
    875
    0
                "update" => {
    876
                    // Python dict.update(other) -> Rust HashMap.extend(other)
    877
    0
                    Ok(quote! { #obj_tokens.extend(#(#arg_tokens),*) })
    878
                }
    879
    0
                "add" => {
    880
                    // Python set.add(item) -> Rust HashSet.insert(item)
    881
    0
                    Ok(quote! { #obj_tokens.insert(#(#arg_tokens),*) })
    882
                }
    883
    0
                _ => unreachable!("Non-map/set method {} passed to transpile_map_set_methods", method),
    884
            }
    885
    0
        }
    886
    887
        /// Handle `HashSet` set operations: union, intersection, difference, `symmetric_difference`
    888
    0
        fn transpile_set_operations(&self, obj_tokens: &TokenStream, method: &str, arg_tokens: &[TokenStream]) -> Result<TokenStream> {
    889
    0
            if arg_tokens.len() != 1 {
    890
    0
                bail!("{} requires exactly 1 argument", method);
    891
    0
            }
    892
    0
            let other = &arg_tokens[0];
    893
    0
            let method_ident = format_ident!("{}", method);
    894
    0
            Ok(quote! {
    895
    0
                {
    896
    0
                    use std::collections::HashSet;
    897
    0
                    #obj_tokens.#method_ident(&#other).cloned().collect::<HashSet<_>>()
    898
    0
                }
    899
    0
            })
    900
    0
        }
    901
    902
        /// Handle string methods: Python-style and Rust-style
    903
    0
        fn transpile_string_methods(&self, obj_tokens: &TokenStream, method: &str, arg_tokens: &[TokenStream]) -> Result<TokenStream> {
    904
    0
            match method {
    905
    0
                "to_s" | "to_string" => {
    906
                    // Convert any value to string - already a String stays String
    907
    0
                    Ok(quote! { #obj_tokens })
    908
                }
    909
    0
                "to_upper" | "upper" => {
    910
    0
                    let rust_method = format_ident!("to_uppercase");
    911
    0
                    Ok(quote! { #obj_tokens.#rust_method(#(#arg_tokens),*) })
    912
                }
    913
    0
                "to_lower" | "lower" => {
    914
    0
                    let rust_method = format_ident!("to_lowercase");
    915
    0
                    Ok(quote! { #obj_tokens.#rust_method(#(#arg_tokens),*) })
    916
                }
    917
    0
                "strip" => {
    918
    0
                    Ok(quote! { #obj_tokens.trim().to_string() })
    919
                }
    920
    0
                "lstrip" => {
    921
    0
                    Ok(quote! { #obj_tokens.trim_start() })
    922
                }
    923
    0
                "rstrip" => {
    924
    0
                    Ok(quote! { #obj_tokens.trim_end() })
    925
                }
    926
    0
                "startswith" => {
    927
    0
                    Ok(quote! { #obj_tokens.starts_with(#(#arg_tokens),*) })
    928
                }
    929
    0
                "endswith" => {
    930
    0
                    Ok(quote! { #obj_tokens.ends_with(#(#arg_tokens),*) })
    931
                }
    932
    0
                "split" => {
    933
    0
                    Ok(quote! { #obj_tokens.split(#(#arg_tokens),*) })
    934
                }
    935
    0
                "replace" => {
    936
    0
                    Ok(quote! { #obj_tokens.replace(#(#arg_tokens),*) })
    937
                }
    938
    0
                "length" => {
    939
                    // Map Ruchy's length() to Rust's len()
    940
    0
                    let rust_method = format_ident!("len");
    941
    0
                    Ok(quote! { #obj_tokens.#rust_method(#(#arg_tokens),*) })
    942
                }
    943
    0
                "substring" => {
    944
                    // string.substring(start, end) -> string.chars().skip(start).take(end-start).collect()
    945
    0
                    if arg_tokens.len() != 2 {
    946
    0
                        bail!("substring requires exactly 2 arguments");
    947
    0
                    }
    948
    0
                    let start = &arg_tokens[0];
    949
    0
                    let end = &arg_tokens[1];
    950
    0
                    Ok(quote! {
    951
    0
                        #obj_tokens.chars()
    952
    0
                            .skip(#start as usize)
    953
    0
                            .take((#end as usize).saturating_sub(#start as usize))
    954
    0
                            .collect::<String>()
    955
    0
                    })
    956
                }
    957
    0
                _ => unreachable!("Non-string method {} passed to transpile_string_methods", method),
    958
            }
    959
    0
        }
    960
    961
        /// Handle advanced collection methods: slice, concat, flatten, unique, join
    962
    0
        fn transpile_advanced_collection_methods(&self, obj_tokens: &TokenStream, method: &str, arg_tokens: &[TokenStream]) -> Result<TokenStream> {
    963
    0
            match method {
    964
    0
                "slice" => {
    965
                    // vec.slice(start, end) -> vec[start..end].to_vec()
    966
    0
                    if arg_tokens.len() != 2 {
    967
    0
                        bail!("slice requires exactly 2 arguments");
    968
    0
                    }
    969
    0
                    let start = &arg_tokens[0];
    970
    0
                    let end = &arg_tokens[1];
    971
    0
                    Ok(quote! { #obj_tokens[#start as usize..#end as usize].to_vec() })
    972
                }
    973
    0
                "concat" => {
    974
                    // vec.concat(other) -> [vec, other].concat()
    975
    0
                    if arg_tokens.len() != 1 {
    976
    0
                        bail!("concat requires exactly 1 argument");
    977
    0
                    }
    978
    0
                    let other = &arg_tokens[0];
    979
    0
                    Ok(quote! { [#obj_tokens, #other].concat() })
    980
                }
    981
    0
                "flatten" => {
    982
                    // vec.flatten() -> vec.into_iter().flatten().collect()
    983
    0
                    if !arg_tokens.is_empty() {
    984
    0
                        bail!("flatten requires no arguments");
    985
    0
                    }
    986
    0
                    Ok(quote! { #obj_tokens.into_iter().flatten().collect::<Vec<_>>() })
    987
                }
    988
    0
                "unique" => {
    989
                    // vec.unique() -> vec.into_iter().collect::<HashSet<_>>().into_iter().collect()
    990
    0
                    if !arg_tokens.is_empty() {
    991
    0
                        bail!("unique requires no arguments");
    992
    0
                    }
    993
    0
                    Ok(quote! {
    994
    0
                        {
    995
    0
                            use std::collections::HashSet;
    996
    0
                            #obj_tokens.into_iter().collect::<HashSet<_>>().into_iter().collect::<Vec<_>>()
    997
    0
                        }
    998
    0
                    })
    999
                }
    1000
    0
                "join" => {
    1001
                    // vec.join(separator) -> vec.join(separator) (for Vec<String>)
    1002
    0
                    if arg_tokens.len() != 1 {
    1003
    0
                        bail!("join requires exactly 1 argument");
    1004
    0
                    }
    1005
    0
                    let separator = &arg_tokens[0];
    1006
    0
                    Ok(quote! { #obj_tokens.join(&#separator) })
    1007
                }
    1008
    0
                _ => unreachable!("Non-advanced-collection method passed to transpile_advanced_collection_methods"),
    1009
            }
    1010
    0
        }
    1011
    1012
        /// Transpiles blocks
    1013
    0
        pub fn transpile_block(&self, exprs: &[Expr]) -> Result<TokenStream> {
    1014
    0
            if exprs.is_empty() {
    1015
    0
                return Ok(quote! { {} });
    1016
    0
            }
    1017
    1018
    0
            let mut statements = Vec::new();
    1019
    1020
    0
            for (i, expr) in exprs.iter().enumerate() {
    1021
    0
                let expr_tokens = self.transpile_expr(expr)?;
    1022
    1023
                // HOTFIX: Never add semicolon to the last expression in a block (it should be the return value)
    1024
    0
                if i < exprs.len() - 1 {
    1025
    0
                    statements.push(quote! { #expr_tokens; });
    1026
    0
                } else {
    1027
    0
                    statements.push(expr_tokens);
    1028
    0
                }
    1029
            }
    1030
    1031
    0
            Ok(quote! {
    1032
                {
    1033
                    #(#statements)*
    1034
                }
    1035
            })
    1036
    0
        }
    1037
    1038
    1039
        /// Transpiles pipeline expressions
    1040
    0
        pub fn transpile_pipeline(&self, expr: &Expr, stages: &[PipelineStage]) -> Result<TokenStream> {
    1041
    0
            let mut result = self.transpile_expr(expr)?;
    1042
    1043
    0
            for stage in stages {
    1044
                // Each stage contains an expression to apply
    1045
    0
                let stage_expr = &stage.op;
    1046
    1047
                // Apply the stage - check what kind of expression it is
    1048
    0
                match &stage_expr.kind {
    1049
    0
                    ExprKind::Call { func, args } => {
    1050
    0
                        let func_tokens = self.transpile_expr(func)?;
    1051
    0
                        let arg_tokens: Result<Vec<_>> =
    1052
    0
                            args.iter().map(|a| self.transpile_expr(a)).collect();
    1053
    0
                        let arg_tokens = arg_tokens?;
    1054
    1055
                        // Pipeline passes the previous result as the first argument
    1056
    0
                        result = quote! { #func_tokens(#result #(, #arg_tokens)*) };
    1057
                    }
    1058
    0
                    ExprKind::MethodCall { method, args, .. } => {
    1059
    0
                        let method_ident = format_ident!("{}", method);
    1060
    0
                        let arg_tokens: Result<Vec<_>> =
    1061
    0
                            args.iter().map(|a| self.transpile_expr(a)).collect();
    1062
    0
                        let arg_tokens = arg_tokens?;
    1063
    1064
    0
                        result = quote! { #result.#method_ident(#(#arg_tokens),*) };
    1065
                    }
    1066
                    _ => {
    1067
                        // For other expressions, apply them directly
    1068
    0
                        let stage_tokens = self.transpile_expr(stage_expr)?;
    1069
    0
                        result = quote! { #stage_tokens(#result) };
    1070
                    }
    1071
                }
    1072
            }
    1073
    1074
    0
            Ok(result)
    1075
    0
        }
    1076
    1077
        /// Transpiles for loops
    1078
    0
        pub fn transpile_for(&self, var: &str, pattern: Option<&Pattern>, iter: &Expr, body: &Expr) -> Result<TokenStream> {
    1079
    0
            let iter_tokens = self.transpile_expr(iter)?;
    1080
    0
            let body_tokens = self.transpile_expr(body)?;
    1081
    1082
            // If we have a pattern, use it for destructuring
    1083
    0
            if let Some(pat) = pattern {
    1084
    0
                let pattern_tokens = self.transpile_pattern(pat)?;
    1085
    0
                Ok(quote! {
    1086
    0
                    for #pattern_tokens in #iter_tokens {
    1087
    0
                        #body_tokens
    1088
    0
                    }
    1089
    0
                })
    1090
            } else {
    1091
                // Fall back to simple variable
    1092
    0
                let var_ident = format_ident!("{}", var);
    1093
    0
                Ok(quote! {
    1094
    0
                    for #var_ident in #iter_tokens {
    1095
    0
                        #body_tokens
    1096
    0
                    }
    1097
    0
                })
    1098
            }
    1099
    0
        }
    1100
    1101
        /// Transpiles while loops
    1102
    0
        pub fn transpile_while(&self, condition: &Expr, body: &Expr) -> Result<TokenStream> {
    1103
    0
            let cond_tokens = self.transpile_expr(condition)?;
    1104
    0
            let body_tokens = self.transpile_expr(body)?;
    1105
    1106
    0
            Ok(quote! {
    1107
    0
                while #cond_tokens {
    1108
    0
                    #body_tokens
    1109
    0
                }
    1110
    0
            })
    1111
    0
        }
    1112
    1113
        /// Transpile if-let expression (complexity: 5)
    1114
    0
        pub fn transpile_if_let(
    1115
    0
            &self,
    1116
    0
            pattern: &Pattern,
    1117
    0
            expr: &Expr,
    1118
    0
            then_branch: &Expr,
    1119
    0
            else_branch: Option<&Expr>,
    1120
    0
        ) -> Result<TokenStream> {
    1121
    0
            let expr_tokens = self.transpile_expr(expr)?;
    1122
    0
            let pattern_tokens = self.transpile_pattern(pattern)?;
    1123
    0
            let then_tokens = self.transpile_expr(then_branch)?;
    1124
    1125
    0
            if let Some(else_expr) = else_branch {
    1126
    0
                let else_tokens = self.transpile_expr(else_expr)?;
    1127
    0
                Ok(quote! {
    1128
    0
                    if let #pattern_tokens = #expr_tokens {
    1129
    0
                        #then_tokens
    1130
    0
                    } else {
    1131
    0
                        #else_tokens
    1132
    0
                    }
    1133
    0
                })
    1134
            } else {
    1135
    0
                Ok(quote! {
    1136
    0
                    if let #pattern_tokens = #expr_tokens {
    1137
    0
                        #then_tokens
    1138
    0
                    }
    1139
    0
                })
    1140
            }
    1141
    0
        }
    1142
    1143
        /// Transpile while-let expression (complexity: 4)
    1144
    0
        pub fn transpile_while_let(
    1145
    0
            &self,
    1146
    0
            pattern: &Pattern,
    1147
    0
            expr: &Expr,
    1148
    0
            body: &Expr,
    1149
    0
        ) -> Result<TokenStream> {
    1150
    0
            let expr_tokens = self.transpile_expr(expr)?;
    1151
    0
            let pattern_tokens = self.transpile_pattern(pattern)?;
    1152
    0
            let body_tokens = self.transpile_expr(body)?;
    1153
    1154
    0
            Ok(quote! {
    1155
    0
                while let #pattern_tokens = #expr_tokens {
    1156
    0
                    #body_tokens
    1157
    0
                }
    1158
    0
            })
    1159
    0
        }
    1160
    1161
    0
        pub fn transpile_loop(&self, body: &Expr) -> Result<TokenStream> {
    1162
    0
            let body_tokens = self.transpile_expr(body)?;
    1163
    1164
    0
            Ok(quote! {
    1165
    0
                loop {
    1166
    0
                    #body_tokens
    1167
    0
                }
    1168
    0
            })
    1169
    0
        }
    1170
    1171
        /// Transpiles try-catch-finally blocks
    1172
    0
        pub fn transpile_try_catch(
    1173
    0
            &self,
    1174
    0
            try_block: &Expr,
    1175
    0
            catch_clauses: &[CatchClause],
    1176
    0
            finally_block: Option<&Expr>
    1177
    0
        ) -> Result<TokenStream> {
    1178
            // For now, we'll transpile try-catch to a match on Result
    1179
            // This is a simplified implementation that handles the common case
    1180
    0
            let try_body = self.transpile_expr(try_block)?;
    1181
    1182
    0
            if catch_clauses.is_empty() {
    1183
    0
                bail!("Try block must have at least one catch clause");
    1184
    0
            }
    1185
    1186
            // Generate the catch handling
    1187
    0
            let catch_pattern = if let Pattern::Identifier(name) = &catch_clauses[0].pattern {
    1188
    0
                let ident = format_ident!("{}", name);
    1189
    0
                quote! { #ident }
    1190
    0
            } else { quote! { _e } };
    1191
    1192
    0
            let catch_body = self.transpile_expr(&catch_clauses[0].body)?;
    1193
    1194
            // If there's a finally block, we need to ensure it runs
    1195
    0
            let result = if let Some(finally) = finally_block {
    1196
    0
                let finally_tokens = self.transpile_expr(finally)?;
    1197
    0
                quote! {
    1198
                    {
    1199
                        let _result = (|| -> Result<_, Box<dyn std::error::Error>> {
    1200
                            Ok(#try_body)
    1201
                        })();
    1202
    1203
                        let _final_result = match _result {
    1204
                            Ok(val) => val,
    1205
                            Err(#catch_pattern) => #catch_body
    1206
                        };
    1207
    1208
                        #finally_tokens;
    1209
                        _final_result
    1210
                    }
    1211
                }
    1212
            } else {
    1213
                // Simple try-catch without finally
    1214
    0
                quote! {
    1215
                    match (|| -> Result<_, Box<dyn std::error::Error>> {
    1216
                        Ok(#try_body)
    1217
                    })() {
    1218
                        Ok(val) => val,
    1219
                        Err(#catch_pattern) => #catch_body
    1220
                    }
    1221
                }
    1222
            };
    1223
    1224
    0
            Ok(result)
    1225
    0
        }
    1226
    1227
        /// Transpiles list comprehensions
    1228
    0
        pub fn transpile_list_comprehension(
    1229
    0
            &self,
    1230
    0
            expr: &Expr,
    1231
    0
            var: &str,
    1232
    0
            iter: &Expr,
    1233
    0
            filter: Option<&Expr>,
    1234
    0
        ) -> Result<TokenStream> {
    1235
    0
            let var_ident = format_ident!("{}", var);
    1236
    0
            let iter_tokens = self.transpile_expr(iter)?;
    1237
    0
            let expr_tokens = self.transpile_expr(expr)?;
    1238
    1239
    0
            if let Some(filter_expr) = filter {
    1240
    0
                let filter_tokens = self.transpile_expr(filter_expr)?;
    1241
    0
                Ok(quote! {
    1242
    0
                    #iter_tokens
    1243
    0
                        .into_iter()
    1244
    0
                        .filter(|#var_ident| #filter_tokens)
    1245
    0
                        .map(|#var_ident| #expr_tokens)
    1246
    0
                        .collect::<Vec<_>>()
    1247
    0
                })
    1248
            } else {
    1249
    0
                Ok(quote! {
    1250
    0
                    #iter_tokens
    1251
    0
                        .into_iter()
    1252
    0
                        .map(|#var_ident| #expr_tokens)
    1253
    0
                        .collect::<Vec<_>>()
    1254
    0
                })
    1255
            }
    1256
    0
        }
    1257
    1258
    1259
        /// Transpiles module declarations
    1260
    0
        pub fn transpile_module(&self, name: &str, body: &Expr) -> Result<TokenStream> {
    1261
    0
            let module_name = format_ident!("{}", name);
    1262
    0
            let body_tokens = self.transpile_expr(body)?;
    1263
    1264
    0
            Ok(quote! {
    1265
    0
                mod #module_name {
    1266
    0
                    #body_tokens
    1267
    0
                }
    1268
    0
            })
    1269
    0
        }
    1270
    1271
    1272
        /// Static method for transpiling inline imports (backward compatibility)
    1273
    0
        pub fn transpile_import(path: &str, items: &[crate::frontend::ast::ImportItem]) -> TokenStream {
    1274
    1275
    1276
            // All imports should have module-level scope, not be wrapped in blocks
    1277
            // This includes both std library imports and local module imports
    1278
    0
            Self::transpile_import_inline(path, items)
    1279
    0
        }
    1280
    1281
        /// Handle `std::fs` imports and generate file operation functions
    1282
    0
        fn transpile_std_fs_import(items: &[crate::frontend::ast::ImportItem]) -> TokenStream {
    1283
            use crate::frontend::ast::ImportItem;
    1284
    1285
    0
            let mut tokens = TokenStream::new();
    1286
    1287
            // Always include std::fs for file operations
    1288
    0
            tokens.extend(quote! { use std::fs; });
    1289
    1290
    0
            if items.is_empty() || items.iter().any(|i| matches!(i, ImportItem::Wildcard)) {
    1291
    0
                // Import all file operations
    1292
    0
                tokens.extend(Self::generate_all_file_operations());
    1293
    0
            } else {
    1294
                // Import specific operations
    1295
    0
                for item in items {
    1296
    0
                    match item {
    1297
    0
                        ImportItem::Named(name) => {
    1298
    0
                            match name.as_str() {
    1299
    0
                                "read_file" => tokens.extend(Self::generate_read_file_function()),
    1300
    0
                                "write_file" => tokens.extend(Self::generate_write_file_function()),
    1301
    0
                                _ => {
    1302
    0
                                    // Unknown std::fs function, generate stub or error
    1303
    0
                                    let func_name = format_ident!("{}", name);
    1304
    0
                                    tokens.extend(quote! {
    1305
    0
                                        fn #func_name() -> ! {
    1306
    0
                                            panic!("std::fs::{} not yet implemented", #name);
    1307
    0
                                        }
    1308
    0
                                    });
    1309
    0
                                }
    1310
                            }
    1311
                        }
    1312
    0
                        ImportItem::Aliased { name, alias } => {
    1313
    0
                            let alias_ident = format_ident!("{}", alias);
    1314
    0
                            match name.as_str() {
    1315
    0
                                "read_file" => {
    1316
    0
                                    tokens.extend(quote! {
    1317
    0
                                        fn #alias_ident(filename: String) -> String {
    1318
    0
                                            fs::read_to_string(filename).unwrap_or_else(|e| panic!("Failed to read file: {}", e))
    1319
    0
                                        }
    1320
    0
                                    });
    1321
    0
                                }
    1322
    0
                                "write_file" => {
    1323
    0
                                    tokens.extend(quote! {
    1324
    0
                                        fn #alias_ident(filename: String, content: String) {
    1325
    0
                                            fs::write(filename, content).unwrap_or_else(|e| panic!("Failed to write file: {}", e));
    1326
    0
                                        }
    1327
    0
                                    });
    1328
    0
                                }
    1329
    0
                                _ => {
    1330
    0
                                    tokens.extend(quote! {
    1331
    0
                                        fn #alias_ident() -> ! {
    1332
    0
                                            panic!("std::fs::{} not yet implemented", #name);
    1333
    0
                                        }
    1334
    0
                                    });
    1335
    0
                                }
    1336
                            }
    1337
                        }
    1338
    0
                        ImportItem::Wildcard => {
    1339
    0
                            tokens.extend(Self::generate_all_file_operations());
    1340
    0
                        }
    1341
                    }
    1342
                }
    1343
            }
    1344
    1345
    0
            tokens
    1346
    0
        }
    1347
    1348
        /// Generate `read_file` function
    1349
    0
        fn generate_read_file_function() -> TokenStream {
    1350
    0
            quote! {
    1351
                fn read_file(filename: String) -> String {
    1352
                    fs::read_to_string(filename).unwrap_or_else(|e| panic!("Failed to read file: {}", e))
    1353
                }
    1354
            }
    1355
    0
        }
    1356
    1357
        /// Generate `write_file` function
    1358
    0
        fn generate_write_file_function() -> TokenStream {
    1359
    0
            quote! {
    1360
                fn write_file(filename: String, content: String) {
    1361
                    fs::write(filename, content).unwrap_or_else(|e| panic!("Failed to write file: {}", e));
    1362
                }
    1363
            }
    1364
    0
        }
    1365
    1366
        /// Generate all file operation functions
    1367
    0
        fn generate_all_file_operations() -> TokenStream {
    1368
    0
            let read_func = Self::generate_read_file_function();
    1369
    0
            let write_func = Self::generate_write_file_function();
    1370
    1371
    0
            quote! {
    1372
                #read_func
    1373
                #write_func
    1374
            }
    1375
    0
        }
    1376
    1377
        /// Handle `std::fs` imports with path-based syntax (import `std::fs::read_file`)
    1378
    0
        fn transpile_std_fs_import_with_path(path: &str, items: &[crate::frontend::ast::ImportItem]) -> TokenStream {
    1379
            use crate::frontend::ast::ImportItem;
    1380
    1381
    1382
    0
            let mut tokens = TokenStream::new();
    1383
    1384
            // Always include std::fs for file operations
    1385
    0
            tokens.extend(quote! { use std::fs; });
    1386
    1387
    0
            if path == "std::fs" {
    1388
                // Wildcard import or specific items from std::fs
    1389
                // Special case: if path is "std::fs" and items contain Named("fs"), treat as wildcard
    1390
    0
                let is_wildcard_import = items.is_empty()
    1391
    0
                    || items.iter().any(|i| matches!(i, ImportItem::Wildcard))
    1392
    0
                    || (items.len() == 1 && matches!(&items[0], ImportItem::Named(name) if name == "fs"));
    1393
    1394
    0
                if is_wildcard_import {
    1395
    0
                    // Import all file operations for wildcard or empty imports
    1396
    0
                    tokens.extend(Self::generate_all_file_operations());
    1397
    0
                } else {
    1398
                    // Import specific operations
    1399
    0
                    for item in items {
    1400
    0
                        match item {
    1401
    0
                            ImportItem::Named(name) => {
    1402
    0
                                match name.as_str() {
    1403
    0
                                    "read_file" => tokens.extend(Self::generate_read_file_function()),
    1404
    0
                                    "write_file" => tokens.extend(Self::generate_write_file_function()),
    1405
    0
                                    _ => {} // Ignore unknown functions
    1406
                                }
    1407
                            }
    1408
                            ImportItem::Wildcard => {
    1409
    0
                                tokens.extend(Self::generate_all_file_operations());
    1410
    0
                                break;
    1411
                            }
    1412
    0
                            ImportItem::Aliased { name, alias: _ } => {
    1413
                                // Handle aliased imports like "read_file as rf"
    1414
    0
                                match name.as_str() {
    1415
    0
                                    "read_file" => tokens.extend(Self::generate_read_file_function()),
    1416
    0
                                    "write_file" => tokens.extend(Self::generate_write_file_function()),
    1417
    0
                                    _ => {} // Ignore unknown functions
    1418
                                }
    1419
                            }
    1420
                        }
    1421
                    }
    1422
                }
    1423
    0
            } else if path.starts_with("std::fs::") {
    1424
                // Path-based import like std::fs::read_file
    1425
    0
                let function_name = path.strip_prefix("std::fs::").unwrap_or("");
    1426
    0
                match function_name {
    1427
    0
                    "read_file" => tokens.extend(Self::generate_read_file_function()),
    1428
    0
                    "write_file" => tokens.extend(Self::generate_write_file_function()),
    1429
    0
                    _ => {} // Ignore unknown functions
    1430
                }
    1431
    0
            }
    1432
    1433
    0
            tokens
    1434
    0
        }
    1435
    1436
        /// Handle `std::process` imports with process management functions
    1437
    0
        fn transpile_std_process_import(_path: &str, _items: &[crate::frontend::ast::ImportItem]) -> TokenStream {
    1438
            // Generate process functions
    1439
    0
            quote! {
    1440
                mod process {
    1441
                    pub fn current_pid() -> i32 {
    1442
                        std::process::id() as i32
    1443
                    }
    1444
    1445
                    pub fn exit(code: i32) {
    1446
                        std::process::exit(code);
    1447
                    }
    1448
    1449
                    pub fn spawn(command: &str) -> Result<i32, String> {
    1450
                        match std::process::Command::new(command).spawn() {
    1451
                            Ok(child) => Ok(child.id() as i32),
    1452
                            Err(e) => Err(e.to_string()),
    1453
                        }
    1454
                    }
    1455
                }
    1456
            }
    1457
    0
        }
    1458
    1459
        /// Handle `std::system` imports with system information functions
    1460
    0
        fn transpile_std_system_import(_path: &str, _items: &[crate::frontend::ast::ImportItem]) -> TokenStream {
    1461
            // Generate system functions
    1462
    0
            quote! {
    1463
                mod system {
    1464
                    pub fn get_env(key: &str) -> Option<String> {
    1465
                        std::env::var(key).ok()
    1466
                    }
    1467
    1468
                    pub fn set_env(key: &str, value: &str) {
    1469
                        std::env::set_var(key, value);
    1470
                    }
    1471
    1472
                    pub fn os_name() -> String {
    1473
                        std::env::consts::OS.to_string()
    1474
                    }
    1475
    1476
                    pub fn arch() -> String {
    1477
                        std::env::consts::ARCH.to_string()
    1478
                    }
    1479
                }
    1480
            }
    1481
    0
        }
    1482
    1483
        /// Handle `std::signal` imports with signal handling functions
    1484
    0
        fn transpile_std_signal_import(_path: &str, _items: &[crate::frontend::ast::ImportItem]) -> TokenStream {
    1485
            // For now, just provide stubs as signal handling is complex and platform-specific
    1486
    0
            quote! {
    1487
                // Import signal constants at top level
    1488
                const SIGINT: i32 = 2;
    1489
                const SIGTERM: i32 = 15;
    1490
                const SIGKILL: i32 = 9;
    1491
    1492
                // Also import exit function for signal handlers
    1493
                fn exit(code: i32) {
    1494
                    std::process::exit(code);
    1495
                }
    1496
    1497
                mod signal {
    1498
                    pub const SIGINT: i32 = 2;
    1499
                    pub const SIGTERM: i32 = 15;
    1500
                    pub const SIGKILL: i32 = 9;
    1501
    1502
                    pub fn on(_signal: i32, _handler: impl Fn()) {
    1503
                        // Signal handling would require unsafe code and platform-specific logic
    1504
                        // For now, this is a stub
    1505
                    }
    1506
                }
    1507
            }
    1508
    0
        }
    1509
    1510
        /// Handle `std::net` imports with networking functions
    1511
    0
        fn transpile_std_net_import(_path: &str, _items: &[crate::frontend::ast::ImportItem]) -> TokenStream {
    1512
            // Generate networking functions and re-export std types
    1513
    0
            quote! {
    1514
                mod net {
    1515
                    pub use std::net::*;
    1516
    1517
                    pub struct TcpListener;
    1518
    1519
                    impl TcpListener {
    1520
                        pub fn bind(addr: String) -> Result<Self, String> {
    1521
                            println!("Would bind TCP listener to: {}", addr);
    1522
                            Ok(TcpListener)
    1523
                        }
    1524
    1525
                        pub fn accept(&self) -> Result<TcpStream, String> {
    1526
                            println!("Would accept connection");
    1527
                            Ok(TcpStream)
    1528
                        }
    1529
                    }
    1530
    1531
                    pub struct TcpStream;
    1532
    1533
                    impl TcpStream {
    1534
                        pub fn connect(addr: String) -> Result<Self, String> {
    1535
                            println!("Would connect to: {}", addr);
    1536
                            Ok(TcpStream)
    1537
                        }
    1538
                    }
    1539
                }
    1540
    1541
                // Also make available as module for http submodules
    1542
                mod http {
    1543
                    pub struct Server {
    1544
                        addr: String,
    1545
                    }
    1546
    1547
                    impl Server {
    1548
                        pub fn new(addr: String) -> Self {
    1549
                            println!("Creating HTTP server on: {}", addr);
    1550
                            Server { addr }
    1551
                        }
    1552
    1553
                        pub fn listen(&self) {
    1554
                            println!("HTTP server listening on: {}", self.addr);
    1555
                        }
    1556
                    }
    1557
                }
    1558
            }
    1559
    0
        }
    1560
    1561
    0
        fn transpile_std_mem_import(_path: &str, _items: &[crate::frontend::ast::ImportItem]) -> TokenStream {
    1562
            // Generate memory management functions
    1563
    0
            quote! {
    1564
                mod mem {
    1565
                    pub struct Array<T> {
    1566
                        data: Vec<T>,
    1567
                    }
    1568
    1569
                    impl<T: Clone> Array<T> {
    1570
                        pub fn new(size: usize, default_value: T) -> Self {
    1571
                            Array {
    1572
                                data: vec![default_value; size],
    1573
                            }
    1574
                        }
    1575
                    }
    1576
    1577
                    pub struct MemoryInfo {
    1578
                        pub allocated: usize,
    1579
                        pub peak: usize,
    1580
                    }
    1581
    1582
                    impl std::fmt::Display for MemoryInfo {
    1583
                        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
    1584
                            write!(f, "allocated: {}KB, peak: {}KB", self.allocated / 1024, self.peak / 1024)
    1585
                        }
    1586
                    }
    1587
    1588
                    pub fn usage() -> MemoryInfo {
    1589
                        MemoryInfo {
    1590
                            allocated: 1024 * 100, // 100KB stub
    1591
                            peak: 1024 * 150,      // 150KB stub
    1592
                        }
    1593
                    }
    1594
                }
    1595
            }
    1596
    0
        }
    1597
    1598
    0
        fn transpile_std_parallel_import(_path: &str, _items: &[crate::frontend::ast::ImportItem]) -> TokenStream {
    1599
            // Generate parallel processing functions
    1600
    0
            quote! {
    1601
                mod parallel {
    1602
                    pub fn map<T, U, F>(data: Vec<T>, func: F) -> Vec<U>
    1603
                    where
    1604
                        T: Send,
    1605
                        U: Send,
    1606
                        F: Fn(T) -> U + Send + Sync,
    1607
                    {
    1608
                        // Simple sequential implementation for now (stub)
    1609
                        data.into_iter().map(func).collect()
    1610
                    }
    1611
    1612
                    pub fn filter<T, F>(data: Vec<T>, predicate: F) -> Vec<T>
    1613
                    where
    1614
                        T: Send,
    1615
                        F: Fn(&T) -> bool + Send + Sync,
    1616
                    {
    1617
                        data.into_iter().filter(|x| predicate(x)).collect()
    1618
                    }
    1619
    1620
                    pub fn reduce<T, F>(data: Vec<T>, func: F) -> Option<T>
    1621
                    where
    1622
                        T: Send,
    1623
                        F: Fn(T, T) -> T + Send + Sync,
    1624
                    {
    1625
                        data.into_iter().reduce(func)
    1626
                    }
    1627
                }
    1628
            }
    1629
    0
        }
    1630
    1631
    0
        fn transpile_std_simd_import(_path: &str, _items: &[crate::frontend::ast::ImportItem]) -> TokenStream {
    1632
            // Generate SIMD vectorization functions
    1633
    0
            quote! {
    1634
                mod simd {
    1635
                    use std::ops::Add;
    1636
    1637
                    pub struct SimdVec<T> {
    1638
                        data: Vec<T>,
    1639
                    }
    1640
    1641
                    impl<T> SimdVec<T> {
    1642
                        pub fn from_slice(slice: &[T]) -> Self
    1643
                        where
    1644
                            T: Clone,
    1645
                        {
    1646
                            SimdVec {
    1647
                                data: slice.to_vec(),
    1648
                            }
    1649
                        }
    1650
                    }
    1651
    1652
                    impl<T> Add for SimdVec<T>
    1653
                    where
    1654
                        T: Add<Output = T> + Copy,
    1655
                    {
    1656
                        type Output = SimdVec<T>;
    1657
    1658
                        fn add(self, other: SimdVec<T>) -> SimdVec<T> {
    1659
                            let result: Vec<T> = self.data.iter()
    1660
                                .zip(other.data.iter())
    1661
                                .map(|(&a, &b)| a + b)
    1662
                                .collect();
    1663
                            SimdVec { data: result }
    1664
                        }
    1665
                    }
    1666
    1667
                    impl<T> std::fmt::Display for SimdVec<T>
    1668
                    where
    1669
                        T: std::fmt::Display,
    1670
                    {
    1671
                        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
    1672
                            write!(f, "[{}]", self.data.iter().map(|x| format!("{}", x)).collect::<Vec<_>>().join(", "))
    1673
                        }
    1674
                    }
    1675
    1676
                    pub fn from_slice<T: Clone>(slice: &[T]) -> SimdVec<T> {
    1677
                        SimdVec::from_slice(slice)
    1678
                    }
    1679
                }
    1680
            }
    1681
    0
        }
    1682
    1683
    0
        fn transpile_std_cache_import(_path: &str, _items: &[crate::frontend::ast::ImportItem]) -> TokenStream {
    1684
            // Generate caching functions - placeholder for @memoize attribute support
    1685
    0
            quote! {
    1686
                mod cache {
    1687
                    use std::collections::HashMap;
    1688
    1689
                    pub struct Cache<K, V> {
    1690
                        data: HashMap<K, V>,
    1691
                    }
    1692
    1693
                    impl<K, V> Cache<K, V>
    1694
                    where
    1695
                        K: std::hash::Hash + Eq,
    1696
                    {
    1697
                        pub fn new() -> Self {
    1698
                            Cache {
    1699
                                data: HashMap::new(),
    1700
                            }
    1701
                        }
    1702
    1703
                        pub fn get(&self, key: &K) -> Option<&V> {
    1704
                            self.data.get(key)
    1705
                        }
    1706
    1707
                        pub fn insert(&mut self, key: K, value: V) -> Option<V> {
    1708
                            self.data.insert(key, value)
    1709
                        }
    1710
                    }
    1711
                }
    1712
            }
    1713
    0
        }
    1714
    1715
    0
        fn transpile_std_bench_import(_path: &str, _items: &[crate::frontend::ast::ImportItem]) -> TokenStream {
    1716
            // Generate benchmarking functions
    1717
    0
            quote! {
    1718
                mod bench {
    1719
                    use std::time::{Duration, Instant};
    1720
    1721
                    pub struct BenchmarkResult {
    1722
                        pub elapsed: u128,
    1723
                    }
    1724
    1725
                    impl BenchmarkResult {
    1726
                        pub fn new(elapsed: Duration) -> Self {
    1727
                            BenchmarkResult {
    1728
                                elapsed: elapsed.as_millis(),
    1729
                            }
    1730
                        }
    1731
                    }
    1732
    1733
                    impl std::fmt::Display for BenchmarkResult {
    1734
                        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
    1735
                            write!(f, "{}ms", self.elapsed)
    1736
                        }
    1737
                    }
    1738
    1739
                    pub fn time<F, T>(mut func: F) -> BenchmarkResult
    1740
                    where
    1741
                        F: FnMut() -> T,
    1742
                    {
    1743
                        let start = Instant::now();
    1744
                        let _ = func();
    1745
                        let elapsed = start.elapsed();
    1746
                        BenchmarkResult::new(elapsed)
    1747
                    }
    1748
                }
    1749
            }
    1750
    0
        }
    1751
    1752
    0
        fn transpile_std_profile_import(_path: &str, _items: &[crate::frontend::ast::ImportItem]) -> TokenStream {
    1753
            // Generate profiling functions - placeholder for @hot_path attribute support
    1754
    0
            quote! {
    1755
                mod profile {
    1756
                    pub struct ProfileInfo {
    1757
                        pub function_name: String,
    1758
                        pub call_count: usize,
    1759
                        pub total_time: u128,
    1760
                    }
    1761
    1762
                    impl std::fmt::Display for ProfileInfo {
    1763
                        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
    1764
                            write!(f, "{}: {} calls, {}ms total",
    1765
                                   self.function_name, self.call_count, self.total_time)
    1766
                        }
    1767
                    }
    1768
    1769
                    pub fn get_stats(function_name: &str) -> ProfileInfo {
    1770
                        ProfileInfo {
    1771
                            function_name: function_name.to_string(),
    1772
                            call_count: 42, // Stub values
    1773
                            total_time: 100,
    1774
                        }
    1775
                    }
    1776
                }
    1777
            }
    1778
    0
        }
    1779
    1780
        /// Handle `std::system` imports with system information functions
    1781
        /// Core inline import transpilation logic - REFACTORED FOR COMPLEXITY REDUCTION
    1782
        /// Original: 48 cyclomatic complexity, Target: <20
    1783
    0
        pub fn transpile_import_inline(path: &str, items: &[crate::frontend::ast::ImportItem]) -> TokenStream {
    1784
            // Try std module handlers first (complexity: delegated)
    1785
    0
            if let Some(result) = Self::handle_std_module_import(path, items) {
    1786
    0
                return result;
    1787
    0
            }
    1788
    1789
            // Fall back to generic import handling (complexity: delegated)
    1790
    0
            Self::handle_generic_import(path, items)
    1791
    0
        }
    1792
    1793
        /// Extract std module dispatcher (complexity ~12)
    1794
    0
        fn handle_std_module_import(path: &str, items: &[crate::frontend::ast::ImportItem]) -> Option<TokenStream> {
    1795
    0
            if path.starts_with("std::fs") {
    1796
    0
                return Some(Self::transpile_std_fs_import_with_path(path, items));
    1797
    0
            }
    1798
    0
            if path.starts_with("std::process") {
    1799
    0
                return Some(Self::transpile_std_process_import(path, items));
    1800
    0
            }
    1801
    0
            if path.starts_with("std::system") {
    1802
    0
                return Some(Self::transpile_std_system_import(path, items));
    1803
    0
            }
    1804
    0
            if path.starts_with("std::signal") {
    1805
    0
                return Some(Self::transpile_std_signal_import(path, items));
    1806
    0
            }
    1807
    0
            if path.starts_with("std::net") {
    1808
    0
                return Some(Self::transpile_std_net_import(path, items));
    1809
    0
            }
    1810
    0
            if path.starts_with("std::mem") {
    1811
    0
                return Some(Self::transpile_std_mem_import(path, items));
    1812
    0
            }
    1813
    0
            if path.starts_with("std::parallel") {
    1814
    0
                return Some(Self::transpile_std_parallel_import(path, items));
    1815
    0
            }
    1816
    0
            if path.starts_with("std::simd") {
    1817
    0
                return Some(Self::transpile_std_simd_import(path, items));
    1818
    0
            }
    1819
    0
            if path.starts_with("std::cache") {
    1820
    0
                return Some(Self::transpile_std_cache_import(path, items));
    1821
    0
            }
    1822
    0
            if path.starts_with("std::bench") {
    1823
    0
                return Some(Self::transpile_std_bench_import(path, items));
    1824
    0
            }
    1825
    0
            if path.starts_with("std::profile") {
    1826
    0
                return Some(Self::transpile_std_profile_import(path, items));
    1827
    0
            }
    1828
    0
            None
    1829
    0
        }
    1830
    1831
        /// Extract generic import handling (complexity ~8)
    1832
    0
        fn handle_generic_import(path: &str, items: &[crate::frontend::ast::ImportItem]) -> TokenStream {
    1833
    1834
    0
            let path_tokens = Self::path_to_tokens(path);
    1835
    1836
    0
            if items.is_empty() {
    1837
    0
                quote! { use #path_tokens::*; }
    1838
    0
            } else if items.len() == 1 {
    1839
    0
                Self::handle_single_import_item(&path_tokens, path, &items[0])
    1840
            } else {
    1841
    0
                Self::handle_multiple_import_items(&path_tokens, items)
    1842
            }
    1843
    0
        }
    1844
    1845
        /// Extract path tokenization (complexity ~4)
    1846
    0
        fn path_to_tokens(path: &str) -> TokenStream {
    1847
    0
            let mut path_tokens = TokenStream::new();
    1848
    0
            let segments: Vec<_> = path.split("::").collect();
    1849
    1850
    0
            for (i, segment) in segments.iter().enumerate() {
    1851
    0
                if i > 0 {
    1852
    0
                    path_tokens.extend(quote! { :: });
    1853
    0
                }
    1854
    0
                if !segment.is_empty() {
    1855
    0
                    let seg_ident = format_ident!("{}", segment);
    1856
    0
                    path_tokens.extend(quote! { #seg_ident });
    1857
    0
                }
    1858
            }
    1859
    1860
    0
            path_tokens
    1861
    0
        }
    1862
    1863
        /// Extract single item handling (complexity ~5)
    1864
    0
        fn handle_single_import_item(
    1865
    0
            path_tokens: &TokenStream,
    1866
    0
            path: &str,
    1867
    0
            item: &crate::frontend::ast::ImportItem
    1868
    0
        ) -> TokenStream {
    1869
            use crate::frontend::ast::ImportItem;
    1870
    1871
    0
            match item {
    1872
    0
                ImportItem::Named(name) => {
    1873
    0
                    if path.ends_with(&format!("::{name}")) {
    1874
    0
                        quote! { use #path_tokens; }
    1875
                    } else {
    1876
    0
                        let item_ident = format_ident!("{}", name);
    1877
    0
                        quote! { use #path_tokens::#item_ident; }
    1878
                    }
    1879
                }
    1880
    0
                ImportItem::Aliased { name, alias } => {
    1881
    0
                    let name_ident = format_ident!("{}", name);
    1882
    0
                    let alias_ident = format_ident!("{}", alias);
    1883
    0
                    quote! { use #path_tokens::#name_ident as #alias_ident; }
    1884
                }
    1885
    0
                ImportItem::Wildcard => quote! { use #path_tokens::*; },
    1886
            }
    1887
    0
        }
    1888
    1889
        /// Extract multiple items handling (complexity ~3)
    1890
    0
        fn handle_multiple_import_items(
    1891
    0
            path_tokens: &TokenStream,
    1892
    0
            items: &[crate::frontend::ast::ImportItem]
    1893
    0
        ) -> TokenStream {
    1894
    0
            let item_tokens = Self::process_import_items(items);
    1895
    0
            quote! { use #path_tokens::{#(#item_tokens),*}; }
    1896
    0
        }
    1897
    1898
        /// Extract import items processing (complexity ~3)
    1899
    0
        fn process_import_items(items: &[crate::frontend::ast::ImportItem]) -> Vec<TokenStream> {
    1900
            use crate::frontend::ast::ImportItem;
    1901
    1902
    0
            items.iter().map(|item| match item {
    1903
    0
                ImportItem::Named(name) => {
    1904
    0
                    let name_ident = format_ident!("{}", name);
    1905
    0
                    quote! { #name_ident }
    1906
                }
    1907
    0
                ImportItem::Aliased { name, alias } => {
    1908
    0
                    let name_ident = format_ident!("{}", name);
    1909
    0
                    let alias_ident = format_ident!("{}", alias);
    1910
    0
                    quote! { #name_ident as #alias_ident }
    1911
                }
    1912
    0
                ImportItem::Wildcard => quote! { * },
    1913
    0
            }).collect()
    1914
    0
        }
    1915
    1916
        /// Transpiles export statements
    1917
    0
        pub fn transpile_export(items: &[String]) -> TokenStream {
    1918
    0
            let item_idents: Vec<_> = items.iter().map(|s| format_ident!("{}", s)).collect();
    1919
    1920
    0
            if items.len() == 1 {
    1921
    0
                let item = &item_idents[0];
    1922
    0
                quote! { pub use #item; }
    1923
            } else {
    1924
    0
                quote! { pub use {#(#item_idents),*}; }
    1925
            }
    1926
    0
        }
    1927
    1928
        /// Handle print/debug macros (println, print, dbg, panic)
    1929
        ///
    1930
        /// # Examples
    1931
        ///
    1932
        /// ```
    1933
        /// use ruchy::{Transpiler, Parser};
    1934
        ///
    1935
        /// // Test println macro handling
    1936
        /// let transpiler = Transpiler::new();
    1937
        /// let mut parser = Parser::new("println(42)");
    1938
        /// let ast = parser.parse().unwrap();
    1939
        /// let result = transpiler.transpile(&ast).unwrap().to_string();
    1940
        /// assert!(result.contains("println !"));
    1941
        /// assert!(result.contains("{}"));
    1942
        /// ```
    1943
    0
        fn try_transpile_print_macro(
    1944
    0
            &self,
    1945
    0
            func_tokens: &TokenStream,
    1946
    0
            base_name: &str,
    1947
    0
            args: &[Expr]
    1948
    0
        ) -> Result<Option<TokenStream>> {
    1949
    0
            if !(base_name == "println" || base_name == "print" || base_name == "dbg" || base_name == "panic") {
    1950
    0
                return Ok(None);
    1951
    0
            }
    1952
    1953
            // Handle single argument with string interpolation
    1954
    0
            if (base_name == "println" || base_name == "print") && args.len() == 1 {
    1955
    0
                if let ExprKind::StringInterpolation { parts } = &args[0].kind {
    1956
    0
                    return Ok(Some(self.transpile_print_with_interpolation(base_name, parts)?));
    1957
    0
                }
    1958
                // For single non-string arguments, add smart format string
    1959
    0
                if !matches!(&args[0].kind, ExprKind::Literal(Literal::String(_))) {
    1960
    0
                    let arg_tokens = self.transpile_expr(&args[0])?;
    1961
                    // Use Debug formatting for safety - works with all types including Vec, tuples, etc.
    1962
    0
                    let format_str = "{:?}";
    1963
    0
                    return Ok(Some(quote! { #func_tokens!(#format_str, #arg_tokens) }));
    1964
    0
                }
    1965
    0
            }
    1966
    1967
            // Handle multiple arguments
    1968
    0
            if args.len() > 1 {
    1969
    0
                return self.transpile_print_multiple_args(func_tokens, args);
    1970
    0
            }
    1971
    1972
            // Single string literal or simple case
    1973
    0
            let arg_tokens: Result<Vec<_>> = args.iter().map(|a| self.transpile_expr(a)).collect();
    1974
    0
            let arg_tokens = arg_tokens?;
    1975
    0
            Ok(Some(quote! { #func_tokens!(#(#arg_tokens),*) }))
    1976
    0
        }
    1977
    1978
        /// Handle multiple arguments for print macros
    1979
    0
        fn transpile_print_multiple_args(
    1980
    0
            &self,
    1981
    0
            func_tokens: &TokenStream,
    1982
    0
            args: &[Expr]
    1983
    0
        ) -> Result<Option<TokenStream>> {
    1984
            // FIXED: Don't treat first string argument as format string
    1985
            // Instead, treat all arguments as values to print with spaces
    1986
    0
            if args.is_empty() {
    1987
    0
                return Ok(Some(quote! { #func_tokens!() }));
    1988
    0
            }
    1989
    1990
    0
            let all_args: Result<Vec<_>> = args.iter().map(|a| self.transpile_expr(a)).collect();
    1991
    0
            let all_args = all_args?;
    1992
    1993
    0
            if args.len() == 1 {
    1994
                // Single argument - check if it's a string-like expression
    1995
    0
                match &args[0].kind {
    1996
                    ExprKind::Literal(Literal::String(_)) |
    1997
                    ExprKind::StringInterpolation { .. } => {
    1998
                        // String literal or interpolation - use Display format
    1999
    0
                        Ok(Some(quote! { #func_tokens!("{}", #(#all_args)*) }))
    2000
                    }
    2001
                    ExprKind::Identifier(_) => {
    2002
                        // For identifiers, we can't know the type at compile time
    2003
                        // Use a runtime check to decide format
    2004
    0
                        let arg = &all_args[0];
    2005
    0
                        let printing_logic = self.generate_value_printing_tokens(quote! { #arg }, quote! { #func_tokens });
    2006
    0
                        Ok(Some(printing_logic))
    2007
                    }
    2008
                    _ => {
    2009
                        // Other types - use Debug format for complex types
    2010
    0
                        Ok(Some(quote! { #func_tokens!("{:?}", #(#all_args)*) }))
    2011
                    }
    2012
                }
    2013
            } else {
    2014
                // Multiple arguments - check if first is format string
    2015
    0
                if let ExprKind::Literal(Literal::String(format_str)) = &args[0].kind {
    2016
    0
                    if format_str.contains("{}") {
    2017
                        // First argument is a format string, rest are values
    2018
    0
                        let format_arg = &all_args[0];
    2019
    0
                        let value_args = &all_args[1..];
    2020
    0
                        Ok(Some(quote! { #func_tokens!(#format_arg, #(#value_args),*) }))
    2021
                    } else {
    2022
                        // First argument is regular string, treat all as separate values
    2023
    0
                        let format_parts: Vec<_> = args.iter().map(|arg| {
    2024
    0
                            match &arg.kind {
    2025
    0
                                ExprKind::Literal(Literal::String(_)) => "{}",
    2026
    0
                                _ => "{:?}"
    2027
                            }
    2028
    0
                        }).collect();
    2029
    0
                        let format_str = format_parts.join(" ");
    2030
    0
                        Ok(Some(quote! { #func_tokens!(#format_str, #(#all_args),*) }))
    2031
                    }
    2032
                } else {
    2033
                    // No format string, treat all as separate values
    2034
    0
                    let format_parts: Vec<_> = args.iter().map(|arg| {
    2035
    0
                        match &arg.kind {
    2036
    0
                            ExprKind::Literal(Literal::String(_)) => "{}",
    2037
    0
                            _ => "{:?}"
    2038
                        }
    2039
    0
                    }).collect();
    2040
    0
                    let format_str = format_parts.join(" ");
    2041
    0
                    Ok(Some(quote! { #func_tokens!(#format_str, #(#all_args),*) }))
    2042
                }
    2043
            }
    2044
    0
        }
    2045
    2046
        /// Handle math functions (sqrt, pow, abs, min, max, floor, ceil, round)
    2047
        ///
    2048
        /// # Examples
    2049
        ///
    2050
        /// ```
    2051
        /// use ruchy::{Transpiler, Parser};
    2052
        ///
    2053
        /// let transpiler = Transpiler::new();
    2054
        /// let mut parser = Parser::new("sqrt(4.0)");
    2055
        /// let ast = parser.parse().unwrap();
    2056
        /// let result = transpiler.transpile(&ast).unwrap().to_string();
    2057
        /// assert!(result.contains("sqrt"));
    2058
        /// ```
    2059
    0
        fn try_transpile_math_function(&self, base_name: &str, args: &[Expr]) -> Result<Option<TokenStream>> {
    2060
    0
            match (base_name, args.len()) {
    2061
    0
                ("sqrt", 1) => self.transpile_sqrt(&args[0]).map(Some),
    2062
    0
                ("pow", 2) => self.transpile_pow(&args[0], &args[1]).map(Some),
    2063
    0
                ("abs", 1) => self.transpile_abs(&args[0]).map(Some),
    2064
    0
                ("min", 2) => self.transpile_min(&args[0], &args[1]).map(Some),
    2065
    0
                ("max", 2) => self.transpile_max(&args[0], &args[1]).map(Some),
    2066
    0
                ("floor", 1) => self.transpile_floor(&args[0]).map(Some),
    2067
    0
                ("ceil", 1) => self.transpile_ceil(&args[0]).map(Some),
    2068
    0
                ("round", 1) => self.transpile_round(&args[0]).map(Some),
    2069
    0
                _ => Ok(None)
    2070
            }
    2071
    0
        }
    2072
    2073
    0
        fn transpile_sqrt(&self, arg: &Expr) -> Result<TokenStream> {
    2074
    0
            let arg_tokens = self.transpile_expr(arg)?;
    2075
    0
            Ok(quote! { (#arg_tokens as f64).sqrt() })
    2076
    0
        }
    2077
    2078
    0
        fn transpile_pow(&self, base: &Expr, exp: &Expr) -> Result<TokenStream> {
    2079
    0
            let base_tokens = self.transpile_expr(base)?;
    2080
    0
            let exp_tokens = self.transpile_expr(exp)?;
    2081
    0
            Ok(quote! { (#base_tokens as f64).powf(#exp_tokens as f64) })
    2082
    0
        }
    2083
    2084
    0
        fn transpile_abs(&self, arg: &Expr) -> Result<TokenStream> {
    2085
    0
            let arg_tokens = self.transpile_expr(arg)?;
    2086
            // Check if arg is negative literal to handle type
    2087
    0
            if let ExprKind::Unary { op: UnaryOp::Negate, operand } = &arg.kind {
    2088
    0
                if matches!(&operand.kind, ExprKind::Literal(Literal::Float(_))) {
    2089
    0
                    return Ok(quote! { (#arg_tokens).abs() });
    2090
    0
                }
    2091
    0
            }
    2092
            // For all other cases, use standard abs
    2093
    0
            Ok(quote! { #arg_tokens.abs() })
    2094
    0
        }
    2095
    2096
    0
        fn transpile_min(&self, a: &Expr, b: &Expr) -> Result<TokenStream> {
    2097
    0
            let a_tokens = self.transpile_expr(a)?;
    2098
    0
            let b_tokens = self.transpile_expr(b)?;
    2099
            // Check if args are float literals to determine type
    2100
    0
            let is_float = matches!(&a.kind, ExprKind::Literal(Literal::Float(_)))
    2101
    0
                || matches!(&b.kind, ExprKind::Literal(Literal::Float(_)));
    2102
    0
            if is_float {
    2103
    0
                Ok(quote! { (#a_tokens as f64).min(#b_tokens as f64) })
    2104
            } else {
    2105
    0
                Ok(quote! { std::cmp::min(#a_tokens, #b_tokens) })
    2106
            }
    2107
    0
        }
    2108
    2109
    0
        fn transpile_max(&self, a: &Expr, b: &Expr) -> Result<TokenStream> {
    2110
    0
            let a_tokens = self.transpile_expr(a)?;
    2111
    0
            let b_tokens = self.transpile_expr(b)?;
    2112
            // Check if args are float literals to determine type
    2113
    0
            let is_float = matches!(&a.kind, ExprKind::Literal(Literal::Float(_)))
    2114
    0
                || matches!(&b.kind, ExprKind::Literal(Literal::Float(_)));
    2115
    0
            if is_float {
    2116
    0
                Ok(quote! { (#a_tokens as f64).max(#b_tokens as f64) })
    2117
            } else {
    2118
    0
                Ok(quote! { std::cmp::max(#a_tokens, #b_tokens) })
    2119
            }
    2120
    0
        }
    2121
    2122
    0
        fn transpile_floor(&self, arg: &Expr) -> Result<TokenStream> {
    2123
    0
            let arg_tokens = self.transpile_expr(arg)?;
    2124
    0
            Ok(quote! { (#arg_tokens as f64).floor() })
    2125
    0
        }
    2126
    2127
    0
        fn transpile_ceil(&self, arg: &Expr) -> Result<TokenStream> {
    2128
    0
            let arg_tokens = self.transpile_expr(arg)?;
    2129
    0
            Ok(quote! { (#arg_tokens as f64).ceil() })
    2130
    0
        }
    2131
    2132
    0
        fn transpile_round(&self, arg: &Expr) -> Result<TokenStream> {
    2133
    0
            let arg_tokens = self.transpile_expr(arg)?;
    2134
    0
            Ok(quote! { (#arg_tokens as f64).round() })
    2135
    0
        }
    2136
    2137
        /// Handle input functions (input, readline)
    2138
        ///
    2139
        /// # Examples
    2140
        ///
    2141
        /// ```
    2142
        /// use ruchy::{Transpiler, Parser};
    2143
        ///
    2144
        /// let transpiler = Transpiler::new();
    2145
        /// let mut parser = Parser::new("input()");
    2146
        /// let ast = parser.parse().unwrap();
    2147
        /// let result = transpiler.transpile(&ast).unwrap().to_string();
    2148
        /// assert!(result.contains("read_line"));
    2149
        /// ```
    2150
    0
        fn try_transpile_input_function(&self, base_name: &str, args: &[Expr]) -> Result<Option<TokenStream>> {
    2151
    0
            match base_name {
    2152
    0
                "input" => {
    2153
    0
                    if args.len() > 1 {
    2154
    0
                        bail!("input expects 0 or 1 arguments (optional prompt)");
    2155
    0
                    }
    2156
    0
                    if args.is_empty() {
    2157
    0
                        Ok(Some(self.generate_input_without_prompt()))
    2158
                    } else {
    2159
    0
                        let prompt = self.transpile_expr(&args[0])?;
    2160
    0
                        Ok(Some(self.generate_input_with_prompt(prompt)))
    2161
                    }
    2162
                }
    2163
    0
                "readline" if args.is_empty() => {
    2164
    0
                    Ok(Some(self.generate_input_without_prompt()))
    2165
                }
    2166
    0
                _ => Ok(None)
    2167
            }
    2168
    0
        }
    2169
    2170
        /// Generate input reading code without prompt
    2171
    0
        fn generate_input_without_prompt(&self) -> TokenStream {
    2172
    0
            quote! {
    2173
                {
    2174
                    let mut input = String::new();
    2175
                    std::io::stdin().read_line(&mut input).expect("Failed to read input");
    2176
                    if input.ends_with('\n') {
    2177
                        input.pop();
    2178
                        if input.ends_with('\r') {
    2179
                            input.pop();
    2180
                        }
    2181
                    }
    2182
                    input
    2183
                }
    2184
            }
    2185
    0
        }
    2186
    2187
        /// Generate input reading code with prompt
    2188
    0
        fn generate_input_with_prompt(&self, prompt: TokenStream) -> TokenStream {
    2189
    0
            quote! {
    2190
                {
    2191
                    print!("{}", #prompt);
    2192
                    std::io::Write::flush(&mut std::io::stdout()).unwrap();
    2193
                    let mut input = String::new();
    2194
                    std::io::stdin().read_line(&mut input).expect("Failed to read input");
    2195
                    if input.ends_with('\n') {
    2196
                        input.pop();
    2197
                        if input.ends_with('\r') {
    2198
                            input.pop();
    2199
                        }
    2200
                    }
    2201
                    input
    2202
                }
    2203
            }
    2204
    0
        }
    2205
    2206
        /// Try to transpile type conversion functions (str, int, float, bool)
    2207
        ///
    2208
        /// # Examples
    2209
        ///
    2210
        /// ```rust
    2211
        /// # use ruchy::backend::transpiler::Transpiler;
    2212
        /// let transpiler = Transpiler::new();
    2213
        /// // str(42) -> 42.to_string()
    2214
        /// // int("42") -> "42".parse::<i64>().unwrap()
    2215
        /// // float(42) -> 42 as f64
    2216
        /// // bool(1) -> 1 != 0
    2217
        /// ```
    2218
    0
        fn try_transpile_type_conversion(&self, base_name: &str, args: &[Expr]) -> Result<Option<TokenStream>> {
    2219
            // Delegate to refactored version with reduced complexity
    2220
            // Original complexity: 62, New complexity: <20 per function
    2221
    0
            self.try_transpile_type_conversion_refactored(base_name, args)
    2222
    0
        }
    2223
    2224
        // Old implementation kept for reference (will be removed after verification)
    2225
        #[allow(dead_code)]
    2226
    0
        pub fn try_transpile_type_conversion_old(&self, base_name: &str, args: &[Expr]) -> Result<Option<TokenStream>> {
    2227
    0
            match base_name {
    2228
    0
                "str" => self.transpile_str_conversion(args).map(Some),
    2229
    0
                "int" => self.transpile_int_conversion(args).map(Some),
    2230
    0
                "float" => self.transpile_float_conversion(args).map(Some),
    2231
    0
                "bool" => self.transpile_bool_conversion(args).map(Some),
    2232
    0
                _ => Ok(None)
    2233
            }
    2234
    0
        }
    2235
    2236
        /// Handle `str()` type conversion - extract string representation
    2237
    0
        fn transpile_str_conversion(&self, args: &[Expr]) -> Result<TokenStream> {
    2238
    0
            if args.len() != 1 {
    2239
    0
                bail!("str() expects exactly 1 argument");
    2240
    0
            }
    2241
    0
            let value = self.transpile_expr(&args[0])?;
    2242
    0
            Ok(quote! { format!("{}", #value) })
    2243
    0
        }
    2244
    2245
        /// Handle `int()` type conversion with literal-specific optimizations
    2246
    0
        fn transpile_int_conversion(&self, args: &[Expr]) -> Result<TokenStream> {
    2247
    0
            if args.len() != 1 {
    2248
    0
                bail!("int() expects exactly 1 argument");
    2249
    0
            }
    2250
    2251
            // Check if the argument is a literal for compile-time optimizations
    2252
    0
            match &args[0].kind {
    2253
                ExprKind::Literal(Literal::String(_)) => {
    2254
    0
                    let value = self.transpile_expr(&args[0])?;
    2255
    0
                    Ok(quote! { #value.parse::<i64>().expect("Failed to parse integer") })
    2256
                }
    2257
    0
                ExprKind::StringInterpolation { parts } if parts.len() == 1 => {
    2258
    0
                    if let crate::frontend::ast::StringPart::Text(_) = &parts[0] {
    2259
    0
                        let value = self.transpile_expr(&args[0])?;
    2260
    0
                        Ok(quote! { #value.parse::<i64>().expect("Failed to parse integer") })
    2261
                    } else {
    2262
    0
                        self.transpile_int_generic(&args[0])
    2263
                    }
    2264
                }
    2265
                ExprKind::Literal(Literal::Float(_)) => {
    2266
    0
                    let value = self.transpile_expr(&args[0])?;
    2267
    0
                    Ok(quote! { (#value as i64) })
    2268
                }
    2269
                ExprKind::Literal(Literal::Bool(_)) => {
    2270
    0
                    let value = self.transpile_expr(&args[0])?;
    2271
    0
                    Ok(quote! { if #value { 1i64 } else { 0i64 } })
    2272
                }
    2273
    0
                _ => self.transpile_int_generic(&args[0])
    2274
            }
    2275
    0
        }
    2276
    2277
        /// Generic int conversion for non-literal expressions
    2278
    0
        fn transpile_int_generic(&self, expr: &Expr) -> Result<TokenStream> {
    2279
    0
            let value = self.transpile_expr(expr)?;
    2280
    0
            Ok(quote! { (#value as i64) })
    2281
    0
        }
    2282
    2283
        /// Handle `float()` type conversion with literal-specific optimizations
    2284
    0
        fn transpile_float_conversion(&self, args: &[Expr]) -> Result<TokenStream> {
    2285
    0
            if args.len() != 1 {
    2286
    0
                bail!("float() expects exactly 1 argument");
    2287
    0
            }
    2288
    2289
            // Check if the argument is a literal for compile-time optimizations
    2290
    0
            match &args[0].kind {
    2291
                ExprKind::Literal(Literal::String(_)) => {
    2292
    0
                    let value = self.transpile_expr(&args[0])?;
    2293
    0
                    Ok(quote! { #value.parse::<f64>().expect("Failed to parse float") })
    2294
                }
    2295
    0
                ExprKind::StringInterpolation { parts } if parts.len() == 1 => {
    2296
    0
                    if let crate::frontend::ast::StringPart::Text(_) = &parts[0] {
    2297
    0
                        let value = self.transpile_expr(&args[0])?;
    2298
    0
                        Ok(quote! { #value.parse::<f64>().expect("Failed to parse float") })
    2299
                    } else {
    2300
    0
                        self.transpile_float_generic(&args[0])
    2301
                    }
    2302
                }
    2303
                ExprKind::Literal(Literal::Integer(_)) => {
    2304
    0
                    let value = self.transpile_expr(&args[0])?;
    2305
    0
                    Ok(quote! { (#value as f64) })
    2306
                }
    2307
    0
                _ => self.transpile_float_generic(&args[0])
    2308
            }
    2309
    0
        }
    2310
    2311
        /// Generic float conversion for non-literal expressions
    2312
    0
        fn transpile_float_generic(&self, expr: &Expr) -> Result<TokenStream> {
    2313
    0
            let value = self.transpile_expr(expr)?;
    2314
    0
            Ok(quote! { (#value as f64) })
    2315
    0
        }
    2316
    2317
        /// Handle `bool()` type conversion with type-specific logic
    2318
    0
        fn transpile_bool_conversion(&self, args: &[Expr]) -> Result<TokenStream> {
    2319
    0
            if args.len() != 1 {
    2320
    0
                bail!("bool() expects exactly 1 argument");
    2321
    0
            }
    2322
    2323
            // Check the type of the argument to generate appropriate conversion
    2324
    0
            match &args[0].kind {
    2325
                ExprKind::Literal(Literal::Integer(_)) => {
    2326
    0
                    let value = self.transpile_expr(&args[0])?;
    2327
    0
                    Ok(quote! { (#value != 0) })
    2328
                }
    2329
                ExprKind::Literal(Literal::String(_)) => {
    2330
    0
                    let value = self.transpile_expr(&args[0])?;
    2331
    0
                    Ok(quote! { !#value.is_empty() })
    2332
                }
    2333
    0
                ExprKind::StringInterpolation { parts } if parts.len() == 1 => {
    2334
    0
                    let value = self.transpile_expr(&args[0])?;
    2335
    0
                    Ok(quote! { !#value.is_empty() })
    2336
                }
    2337
                ExprKind::Literal(Literal::Bool(_)) => {
    2338
                    // Boolean already, just pass through
    2339
    0
                    let value = self.transpile_expr(&args[0])?;
    2340
    0
                    Ok(value)
    2341
                }
    2342
                _ => {
    2343
                    // Generic case - for numbers check != 0
    2344
    0
                    let value = self.transpile_expr(&args[0])?;
    2345
    0
                    Ok(quote! { (#value != 0) })
    2346
                }
    2347
            }
    2348
    0
        }
    2349
    2350
        /// Try to transpile advanced math functions (sin, cos, tan, log, log10, random)
    2351
        ///
    2352
        /// # Examples
    2353
        ///
    2354
        /// ```rust
    2355
        /// # use ruchy::backend::transpiler::Transpiler;
    2356
        /// let transpiler = Transpiler::new();
    2357
        /// // sin(x) -> x.sin()
    2358
        /// // cos(x) -> x.cos()
    2359
        /// // log(x) -> x.ln()
    2360
        /// // random() -> rand::random::<f64>()
    2361
        /// ```
    2362
    0
        fn try_transpile_math_functions(&self, base_name: &str, args: &[Expr]) -> Result<Option<TokenStream>> {
    2363
    0
            match base_name {
    2364
    0
                "sin" | "cos" | "tan" => {
    2365
    0
                    if args.len() != 1 {
    2366
    0
                        bail!("{}() expects exactly 1 argument", base_name);
    2367
    0
                    }
    2368
    0
                    let value = self.transpile_expr(&args[0])?;
    2369
    0
                    let method = proc_macro2::Ident::new(base_name, proc_macro2::Span::call_site());
    2370
    0
                    Ok(Some(quote! { ((#value as f64).#method()) }))
    2371
                }
    2372
    0
                "log" => {
    2373
    0
                    if args.len() != 1 {
    2374
    0
                        bail!("log() expects exactly 1 argument");
    2375
    0
                    }
    2376
    0
                    let value = self.transpile_expr(&args[0])?;
    2377
    0
                    Ok(Some(quote! { ((#value as f64).ln()) }))
    2378
                }
    2379
    0
                "log10" => {
    2380
    0
                    if args.len() != 1 {
    2381
    0
                        bail!("log10() expects exactly 1 argument");
    2382
    0
                    }
    2383
    0
                    let value = self.transpile_expr(&args[0])?;
    2384
    0
                    Ok(Some(quote! { ((#value as f64).log10()) }))
    2385
                }
    2386
    0
                "random" => {
    2387
    0
                    if !args.is_empty() {
    2388
    0
                        bail!("random() expects no arguments");
    2389
    0
                    }
    2390
                    // Use a simple pseudo-random generator
    2391
    0
                    Ok(Some(quote! {
    2392
    0
                        {
    2393
    0
                            use std::time::{SystemTime, UNIX_EPOCH};
    2394
    0
                            let seed = SystemTime::now()
    2395
    0
                                .duration_since(UNIX_EPOCH)
    2396
    0
                                .unwrap()
    2397
    0
                                .as_nanos() as u64;
    2398
    0
                            // Use a safe LCG that won't overflow
    2399
    0
                            let a = 1664525u64;
    2400
    0
                            let c = 1013904223u64;
    2401
    0
                            let m = 1u64 << 32;
    2402
    0
                            ((seed.wrapping_mul(a).wrapping_add(c)) % m) as f64 / m as f64
    2403
    0
                        }
    2404
    0
                    }))
    2405
                }
    2406
    0
                _ => Ok(None)
    2407
            }
    2408
    0
        }
    2409
    2410
        /// Handle assert functions (assert, `assert_eq`, `assert_ne`)
    2411
        ///
    2412
        /// # Examples
    2413
        ///
    2414
        /// ```
    2415
        /// use ruchy::{Transpiler, Parser};
    2416
        ///
    2417
        /// let transpiler = Transpiler::new();
    2418
        /// let mut parser = Parser::new("assert(true)");
    2419
        /// let ast = parser.parse().unwrap();
    2420
        /// let result = transpiler.transpile(&ast).unwrap().to_string();
    2421
        /// assert!(result.contains("assert !"));
    2422
        /// ```
    2423
    0
        fn try_transpile_assert_function(
    2424
    0
            &self,
    2425
    0
            _func_tokens: &TokenStream,
    2426
    0
            base_name: &str,
    2427
    0
            args: &[Expr]
    2428
    0
        ) -> Result<Option<TokenStream>> {
    2429
    0
            match base_name {
    2430
    0
                "assert" => {
    2431
    0
                    if args.is_empty() || args.len() > 2 {
    2432
    0
                        bail!("assert expects 1 or 2 arguments (condition, optional message)");
    2433
    0
                    }
    2434
    0
                    let condition = self.transpile_expr(&args[0])?;
    2435
    0
                    if args.len() == 1 {
    2436
    0
                        Ok(Some(quote! { assert!(#condition) }))
    2437
                    } else {
    2438
    0
                        let message = self.transpile_expr(&args[1])?;
    2439
    0
                        Ok(Some(quote! { assert!(#condition, "{}", #message) }))
    2440
                    }
    2441
                }
    2442
    0
                "assert_eq" => {
    2443
    0
                    if args.len() < 2 || args.len() > 3 {
    2444
    0
                        bail!("assert_eq expects 2 or 3 arguments (left, right, optional message)");
    2445
    0
                    }
    2446
    0
                    let left = self.transpile_expr(&args[0])?;
    2447
    0
                    let right = self.transpile_expr(&args[1])?;
    2448
    0
                    if args.len() == 2 {
    2449
    0
                        Ok(Some(quote! { assert_eq!(#left, #right) }))
    2450
                    } else {
    2451
    0
                        let message = self.transpile_expr(&args[2])?;
    2452
    0
                        Ok(Some(quote! { assert_eq!(#left, #right, "{}", #message) }))
    2453
                    }
    2454
                }
    2455
    0
                "assert_ne" => {
    2456
    0
                    if args.len() < 2 || args.len() > 3 {
    2457
    0
                        bail!("assert_ne expects 2 or 3 arguments (left, right, optional message)");
    2458
    0
                    }
    2459
    0
                    let left = self.transpile_expr(&args[0])?;
    2460
    0
                    let right = self.transpile_expr(&args[1])?;
    2461
    0
                    if args.len() == 2 {
    2462
    0
                        Ok(Some(quote! { assert_ne!(#left, #right) }))
    2463
                    } else {
    2464
    0
                        let message = self.transpile_expr(&args[2])?;
    2465
    0
                        Ok(Some(quote! { assert_ne!(#left, #right, "{}", #message) }))
    2466
                    }
    2467
                }
    2468
    0
                _ => Ok(None)
    2469
            }
    2470
    0
        }
    2471
    2472
        /// Handle collection constructors (`HashMap`, `HashSet`)
    2473
        ///
    2474
        /// # Examples
    2475
        ///
    2476
        /// ```
    2477
        /// use ruchy::{Transpiler, Parser};
    2478
        ///
    2479
        /// let transpiler = Transpiler::new();
    2480
        /// let mut parser = Parser::new("HashMap()");
    2481
        /// let ast = parser.parse().unwrap();
    2482
        /// let result = transpiler.transpile(&ast).unwrap().to_string();
    2483
        /// assert!(result.contains("HashMap"));
    2484
        /// ```
    2485
    0
        fn try_transpile_collection_constructor(&self, base_name: &str, args: &[Expr]) -> Result<Option<TokenStream>> {
    2486
    0
            match (base_name, args.len()) {
    2487
    0
                ("HashMap", 0) => Ok(Some(quote! { std::collections::HashMap::new() })),
    2488
    0
                ("HashSet", 0) => Ok(Some(quote! { std::collections::HashSet::new() })),
    2489
    0
                _ => Ok(None)
    2490
            }
    2491
    0
        }
    2492
    2493
        /// Handle `DataFrame` functions (col)
    2494
        ///
    2495
        /// # Examples
    2496
        ///
    2497
        /// ```
    2498
        /// use ruchy::{Transpiler, Parser};
    2499
        ///
    2500
        /// let transpiler = Transpiler::new();
    2501
        /// let mut parser = Parser::new(r#"col("name")"#);
    2502
        /// let ast = parser.parse().unwrap();
    2503
        /// let result = transpiler.transpile(&ast).unwrap().to_string();
    2504
        /// assert!(result.contains("polars"));
    2505
        /// ```
    2506
    0
        fn try_transpile_dataframe_function(&self, base_name: &str, args: &[Expr]) -> Result<Option<TokenStream>> {
    2507
            // Handle DataFrame static methods
    2508
    0
            if base_name.starts_with("DataFrame::") {
    2509
    0
                let method = base_name.strip_prefix("DataFrame::").unwrap();
    2510
    0
                match method {
    2511
    0
                    "new" if args.is_empty() => {
    2512
    0
                        return Ok(Some(quote! { polars::prelude::DataFrame::empty() }));
    2513
                    }
    2514
    0
                    "from_csv" if args.len() == 1 => {
    2515
    0
                        let path_tokens = self.transpile_expr(&args[0])?;
    2516
    0
                        return Ok(Some(quote! {
    2517
    0
                            polars::prelude::CsvReader::from_path(#path_tokens)
    2518
    0
                                .unwrap()
    2519
    0
                                .finish()
    2520
    0
                                .unwrap()
    2521
    0
                        }));
    2522
                    }
    2523
    0
                    _ => {}
    2524
                }
    2525
    0
            }
    2526
    2527
            // Handle col() function for column references
    2528
    0
            if base_name == "col" && args.len() == 1 {
    2529
    0
                if let ExprKind::Literal(Literal::String(col_name)) = &args[0].kind {
    2530
    0
                    return Ok(Some(quote! { polars::prelude::col(#col_name) }));
    2531
    0
                }
    2532
    0
            }
    2533
    0
            Ok(None)
    2534
    0
        }
    2535
    2536
        /// Handle regular function calls with string literal conversion
    2537
        ///
    2538
        /// # Examples
    2539
        ///
    2540
        /// ```
    2541
        /// use ruchy::{Transpiler, Parser};
    2542
        ///
    2543
        /// let transpiler = Transpiler::new();
    2544
        /// let mut parser = Parser::new(r#"my_func("test")"#);
    2545
        /// let ast = parser.parse().unwrap();
    2546
        /// let result = transpiler.transpile(&ast).unwrap().to_string();
    2547
        /// assert!(result.contains("my_func"));
    2548
        /// ```
    2549
    0
        fn transpile_regular_function_call(
    2550
    0
            &self,
    2551
    0
            func_tokens: &TokenStream,
    2552
    0
            args: &[Expr]
    2553
    0
        ) -> Result<TokenStream> {
    2554
            // Get function name for signature lookup
    2555
    0
            let func_name = func_tokens.to_string().trim().to_string();
    2556
    2557
            // Apply type coercion based on function signature
    2558
    0
            let arg_tokens: Result<Vec<_>> = if let Some(signature) = self.function_signatures.get(&func_name) {
    2559
    0
                args.iter().enumerate().map(|(i, arg)| {
    2560
    0
                    let base_tokens = self.transpile_expr(arg)?;
    2561
    2562
                    // Apply String/&str coercion if needed
    2563
    0
                    if let Some(expected_type) = signature.param_types.get(i) {
    2564
    0
                        self.apply_string_coercion(arg, &base_tokens, expected_type)
    2565
                    } else {
    2566
    0
                        Ok(base_tokens)
    2567
                    }
    2568
    0
                }).collect()
    2569
            } else {
    2570
                // No signature info - transpile as-is
    2571
    0
                args.iter().map(|a| self.transpile_expr(a)).collect()
    2572
            };
    2573
    2574
    0
            let arg_tokens = arg_tokens?;
    2575
    0
            Ok(quote! { #func_tokens(#(#arg_tokens),*) })
    2576
    0
        }
    2577
    2578
        /// Apply String/&str coercion based on expected type
    2579
    0
        fn apply_string_coercion(
    2580
    0
            &self,
    2581
    0
            arg: &Expr,
    2582
    0
            tokens: &TokenStream,
    2583
    0
            expected_type: &str
    2584
    0
        ) -> Result<TokenStream> {
    2585
            use crate::frontend::ast::{ExprKind, Literal};
    2586
    2587
    0
            match (&arg.kind, expected_type) {
    2588
                // String literal to String parameter: add .to_string()
    2589
    0
                (ExprKind::Literal(Literal::String(_)), "String") => {
    2590
    0
                    Ok(quote! { #tokens.to_string() })
    2591
                }
    2592
                // String literal to &str parameter: keep as-is
    2593
    0
                (ExprKind::Literal(Literal::String(_)), expected) if expected.starts_with('&') => {
    2594
    0
                    Ok(tokens.clone())
    2595
                }
    2596
                // Variable that might be &str to String parameter
    2597
    0
                (ExprKind::Identifier(_), "String") => {
    2598
                    // For now, assume string variables are String type from auto-conversion
    2599
                    // This matches the existing behavior in transpile_let
    2600
    0
                    Ok(tokens.clone())
    2601
                }
    2602
                // No coercion needed
    2603
    0
                _ => Ok(tokens.clone())
    2604
            }
    2605
    0
        }
    2606
    }
    2607
    2608
    #[cfg(test)]
    2609
    #[allow(clippy::single_char_pattern)]
    2610
    mod tests {
    2611
        use super::*;
    2612
        use crate::Parser;
    2613
    2614
        fn create_transpiler() -> Transpiler {
    2615
            Transpiler::new()
    2616
        }
    2617
    2618
        #[test]
    2619
        fn test_transpile_if_with_else() {
    2620
            let transpiler = create_transpiler();
    2621
            let code = "if true { 1 } else { 2 }";
    2622
            let mut parser = Parser::new(code);
    2623
            let ast = parser.parse().unwrap();
    2624
    2625
            let result = transpiler.transpile(&ast).unwrap();
    2626
            let rust_str = result.to_string();
    2627
    2628
            assert!(rust_str.contains("if"));
    2629
            assert!(rust_str.contains("else"));
    2630
        }
    2631
    2632
        #[test]
    2633
        fn test_transpile_if_without_else() {
    2634
            let transpiler = create_transpiler();
    2635
            let code = "if true { 1 }";
    2636
            let mut parser = Parser::new(code);
    2637
            let ast = parser.parse().unwrap();
    2638
    2639
            let result = transpiler.transpile(&ast).unwrap();
    2640
            let rust_str = result.to_string();
    2641
    2642
            assert!(rust_str.contains("if"));
    2643
            assert!(!rust_str.contains("else"));
    2644
        }
    2645
    2646
        #[test]
    2647
        fn test_transpile_let_binding() {
    2648
            let transpiler = create_transpiler();
    2649
            let code = "let x = 5; x";
    2650
            let mut parser = Parser::new(code);
    2651
            let ast = parser.parse().unwrap();
    2652
    2653
            let result = transpiler.transpile(&ast).unwrap();
    2654
            let rust_str = result.to_string();
    2655
    2656
            assert!(rust_str.contains("let"));
    2657
            assert!(rust_str.contains("x"));
    2658
            assert!(rust_str.contains("5"));
    2659
        }
    2660
    2661
        #[test]
    2662
        fn test_transpile_mutable_let() {
    2663
            let transpiler = create_transpiler();
    2664
            let code = "let mut x = 5; x";
    2665
            let mut parser = Parser::new(code);
    2666
            let ast = parser.parse().unwrap();
    2667
    2668
            let result = transpiler.transpile(&ast).unwrap();
    2669
            let rust_str = result.to_string();
    2670
    2671
            assert!(rust_str.contains("mut"));
    2672
        }
    2673
    2674
        #[test]
    2675
        fn test_transpile_for_loop() {
    2676
            let transpiler = create_transpiler();
    2677
            let code = "for x in [1, 2, 3] { x }";
    2678
            let mut parser = Parser::new(code);
    2679
            let ast = parser.parse().unwrap();
    2680
    2681
            let result = transpiler.transpile(&ast).unwrap();
    2682
            let rust_str = result.to_string();
    2683
    2684
            assert!(rust_str.contains("for"));
    2685
            assert!(rust_str.contains("in"));
    2686
        }
    2687
    2688
        #[test]
    2689
        fn test_transpile_while_loop() {
    2690
            let transpiler = create_transpiler();
    2691
            let code = "while true { }";
    2692
            let mut parser = Parser::new(code);
    2693
            let ast = parser.parse().unwrap();
    2694
    2695
            let result = transpiler.transpile(&ast).unwrap();
    2696
            let rust_str = result.to_string();
    2697
    2698
            assert!(rust_str.contains("while"));
    2699
        }
    2700
    2701
        #[test]
    2702
        fn test_function_with_parameters() {
    2703
            let transpiler = create_transpiler();
    2704
            let code = "fun add(x, y) { x + y }";
    2705
            let mut parser = Parser::new(code);
    2706
            let ast = parser.parse().unwrap();
    2707
    2708
            let result = transpiler.transpile(&ast).unwrap();
    2709
            let rust_str = result.to_string();
    2710
    2711
            assert!(rust_str.contains("fn add"));
    2712
            assert!(rust_str.contains("x"));
    2713
            assert!(rust_str.contains("y"));
    2714
        }
    2715
    2716
        #[test]
    2717
        fn test_function_without_parameters() {
    2718
            let transpiler = create_transpiler();
    2719
            let code = "fun hello() { \"world\" }";
    2720
            let mut parser = Parser::new(code);
    2721
            let ast = parser.parse().unwrap();
    2722
    2723
            let result = transpiler.transpile(&ast).unwrap();
    2724
            let rust_str = result.to_string();
    2725
    2726
            assert!(rust_str.contains("fn hello"));
    2727
            assert!(rust_str.contains("()"));
    2728
        }
    2729
    2730
        #[test]
    2731
        fn test_looks_like_numeric_function() {
    2732
            let transpiler = create_transpiler();
    2733
    2734
            // Test known numeric function names
    2735
            assert!(transpiler.looks_like_numeric_function("double"));
    2736
            assert!(transpiler.looks_like_numeric_function("add"));
    2737
            assert!(transpiler.looks_like_numeric_function("square"));
    2738
    2739
            // Test non-numeric function names
    2740
            assert!(!transpiler.looks_like_numeric_function("hello"));
    2741
            assert!(!transpiler.looks_like_numeric_function("main"));
    2742
            assert!(!transpiler.looks_like_numeric_function("test"));
    2743
        }
    2744
    2745
        #[test]
    2746
        fn test_match_expression() {
    2747
            let transpiler = create_transpiler();
    2748
            let code = "match x { 1 => \"one\", _ => \"other\" }";
    2749
            let mut parser = Parser::new(code);
    2750
            let ast = parser.parse().unwrap();
    2751
    2752
            let result = transpiler.transpile(&ast).unwrap();
    2753
            let rust_str = result.to_string();
    2754
    2755
            assert!(rust_str.contains("match"));
    2756
        }
    2757
    2758
        #[test]
    2759
        fn test_lambda_expression() {
    2760
            let transpiler = create_transpiler();
    2761
            let code = "(x) => x + 1";
    2762
            let mut parser = Parser::new(code);
    2763
            let ast = parser.parse().unwrap();
    2764
    2765
            let result = transpiler.transpile(&ast).unwrap();
    2766
            let rust_str = result.to_string();
    2767
    2768
            // Lambda should be transpiled to closure
    2769
            assert!(rust_str.contains("|") || rust_str.contains("move"));
    2770
        }
    2771
    2772
        #[test]
    2773
        fn test_reserved_keyword_handling() {
    2774
            let transpiler = create_transpiler();
    2775
            let code = "let final = 5; final";  // Use regular keyword, not r# syntax
    2776
            let mut parser = Parser::new(code);
    2777
            let ast = parser.parse().unwrap();
    2778
    2779
            let result = transpiler.transpile(&ast).unwrap();
    2780
            let rust_str = result.to_string();
    2781
    2782
            // Should handle Rust reserved keywords by prefixing with r#
    2783
            assert!(rust_str.contains("r#final") || rust_str.contains("final"));
    2784
        }
    2785
    2786
        #[test]
    2787
        fn test_generic_function() {
    2788
            let transpiler = create_transpiler();
    2789
            let code = "fun identity<T>(x: T) -> T { x }";
    2790
            let mut parser = Parser::new(code);
    2791
            let ast = parser.parse().unwrap();
    2792
    2793
            let result = transpiler.transpile(&ast).unwrap();
    2794
            let rust_str = result.to_string();
    2795
    2796
            assert!(rust_str.contains("fn identity"));
    2797
        }
    2798
    2799
        #[test]
    2800
        fn test_main_function_special_case() {
    2801
            let transpiler = create_transpiler();
    2802
            let code = "fun main() { println(\"Hello\") }";
    2803
            let mut parser = Parser::new(code);
    2804
            let ast = parser.parse().unwrap();
    2805
    2806
            let result = transpiler.transpile(&ast).unwrap();
    2807
            let rust_str = result.to_string();
    2808
    2809
            // main should not have explicit return type
    2810
            assert!(!rust_str.contains("fn main() ->"));
    2811
            assert!(!rust_str.contains("fn main () ->"));
    2812
        }
    2813
    2814
        #[test]
    2815
        fn test_dataframe_function_call() {
    2816
            let transpiler = create_transpiler();
    2817
            let code = "col(\"name\")";
    2818
            let mut parser = Parser::new(code);
    2819
            let ast = parser.parse().unwrap();
    2820
    2821
            let result = transpiler.transpile(&ast).unwrap();
    2822
            let rust_str = result.to_string();
    2823
    2824
            // Should transpile DataFrame column access
    2825
            assert!(rust_str.contains("polars") || rust_str.contains("col"));
    2826
        }
    2827
    2828
        #[test]
    2829
        fn test_regular_function_call_string_conversion() {
    2830
            let transpiler = create_transpiler();
    2831
            let code = "my_func(\"test\")";
    2832
            let mut parser = Parser::new(code);
    2833
            let ast = parser.parse().unwrap();
    2834
    2835
            let result = transpiler.transpile(&ast).unwrap();
    2836
            let rust_str = result.to_string();
    2837
    2838
            // Regular function calls should convert string literals
    2839
            assert!(rust_str.contains("my_func"));
    2840
            assert!(rust_str.contains("to_string") || rust_str.contains("\"test\""));
    2841
        }
    2842
    2843
        #[test]
    2844
        fn test_nested_expressions() {
    2845
            let transpiler = create_transpiler();
    2846
            let code = "if true { let x = 5; x + 1 } else { 0 }";
    2847
            let mut parser = Parser::new(code);
    2848
            let ast = parser.parse().unwrap();
    2849
    2850
            let result = transpiler.transpile(&ast).unwrap();
    2851
            let rust_str = result.to_string();
    2852
    2853
            // Should handle nested let inside if
    2854
            assert!(rust_str.contains("if"));
    2855
            assert!(rust_str.contains("let"));
    2856
            assert!(rust_str.contains("else"));
    2857
        }
    2858
    2859
        #[test]
    2860
        fn test_type_inference_integration() {
    2861
            let transpiler = create_transpiler();
    2862
    2863
            // Test function parameter as function
    2864
            let code1 = "fun apply(f, x) { f(x) }";
    2865
            let mut parser1 = Parser::new(code1);
    2866
            let ast1 = parser1.parse().unwrap();
    2867
            let result1 = transpiler.transpile(&ast1).unwrap();
    2868
            let rust_str1 = result1.to_string();
    2869
            assert!(rust_str1.contains("impl Fn"));
    2870
    2871
            // Test numeric parameter
    2872
            let code2 = "fun double(n) { n * 2 }";
    2873
            let mut parser2 = Parser::new(code2);
    2874
            let ast2 = parser2.parse().unwrap();
    2875
            let result2 = transpiler.transpile(&ast2).unwrap();
    2876
            let rust_str2 = result2.to_string();
    2877
            assert!(rust_str2.contains("n : i32") || rust_str2.contains("n: i32"));
    2878
    2879
            // Test string parameter
    2880
            let code3 = "fun greet(name) { \"Hello \" + name }";
    2881
            let mut parser3 = Parser::new(code3);
    2882
            let ast3 = parser3.parse().unwrap();
    2883
            let result3 = transpiler.transpile(&ast3).unwrap();
    2884
            let rust_str3 = result3.to_string();
    2885
            assert!(rust_str3.contains("name : String") || rust_str3.contains("name: String"));
    2886
        }
    2887
    2888
        #[test]
    2889
        fn test_return_type_inference() {
    2890
            let transpiler = create_transpiler();
    2891
    2892
            // Test numeric function gets return type
    2893
            let code = "fun double(n) { n * 2 }";
    2894
            let mut parser = Parser::new(code);
    2895
            let ast = parser.parse().unwrap();
    2896
            let result = transpiler.transpile(&ast).unwrap();
    2897
            let rust_str = result.to_string();
    2898
            assert!(rust_str.contains("-> i32"));
    2899
        }
    2900
    2901
        #[test]
    2902
        fn test_void_function_no_return_type() {
    2903
            let transpiler = create_transpiler();
    2904
            let code = "fun print_hello() { println(\"Hello\") }";
    2905
            let mut parser = Parser::new(code);
    2906
            let ast = parser.parse().unwrap();
    2907
            let result = transpiler.transpile(&ast).unwrap();
    2908
            let rust_str = result.to_string();
    2909
    2910
            // Should not have explicit return type for void functions
    2911
            assert!(!rust_str.contains("-> "));
    2912
        }
    2913
    2914
        #[test]
    2915
        fn test_complex_function_combinations() {
    2916
            let transpiler = create_transpiler();
    2917
            let code = "fun transform(f, n, m) { f(n + m) * 2 }";
    2918
            let mut parser = Parser::new(code);
    2919
            let ast = parser.parse().unwrap();
    2920
            let result = transpiler.transpile(&ast).unwrap();
    2921
            let rust_str = result.to_string();
    2922
    2923
            // f should be function, n and m should be i32
    2924
            assert!(rust_str.contains("impl Fn"));
    2925
            assert!(rust_str.contains("n : i32") || rust_str.contains("n: i32"));
    2926
            assert!(rust_str.contains("m : i32") || rust_str.contains("m: i32"));
    2927
        }
    2928
    }