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/frontend/parser/expressions.rs
Line
Count
Source
1
//! Basic expression parsing - minimal version with only used functions
2
3
use super::{ParserState, *};
4
5
0
pub fn parse_prefix(state: &mut ParserState) -> Result<Expr> {
6
0
    let Some((token, span)) = state.tokens.peek() else {
7
0
        bail!("Unexpected end of input - expected expression");
8
    };
9
10
0
    let token_clone = token.clone();
11
0
    let span_clone = *span;
12
13
0
    match token_clone {
14
        // Literal tokens - delegated to focused helper
15
        Token::Integer(_) | Token::Float(_) | Token::String(_) | 
16
        Token::FString(_) | Token::Char(_) | Token::Bool(_) => {
17
0
            parse_literal_token(state, token_clone, span_clone)
18
        }
19
        // Identifier tokens - delegated to focused helper
20
        Token::Identifier(_) | Token::Underscore => {
21
0
            parse_identifier_token(state, token_clone, span_clone)
22
        }
23
        // Unary operator tokens - delegated to focused helper
24
        Token::Minus | Token::Bang => {
25
0
            parse_unary_operator_token(state, token_clone, span_clone)
26
        }
27
        // Function/block tokens - delegated to focused helper
28
        Token::Fun | Token::Fn | Token::LeftBrace => {
29
0
            parse_function_block_token(state, token_clone)
30
        }
31
        // Variable declaration tokens - delegated to focused helper
32
        Token::Let | Token::Var => {
33
0
            parse_variable_declaration_token(state, token_clone)
34
        }
35
        // Control flow tokens - delegated to focused helper
36
        Token::If | Token::Match | Token::While | Token::For | Token::Try => {
37
0
            parse_control_flow_token(state, token_clone)
38
        }
39
        // Module declaration token
40
        Token::Mod => {
41
0
            parse_module_declaration(state)
42
        }
43
        // Lambda expression tokens - delegated to focused helper
44
        Token::Pipe | Token::OrOr => {
45
0
            parse_lambda_token(state, token_clone)
46
        }
47
        // Parentheses tokens - delegated to focused helper (unit, grouping, tuples, lambdas)
48
        Token::LeftParen => {
49
0
            parse_parentheses_token(state, span_clone)
50
        }
51
        // Data structure definition tokens - delegated to focused helper
52
        Token::Struct | Token::Trait | Token::Impl => {
53
0
            parse_data_structure_token(state, token_clone)
54
        }
55
        // Import/module tokens - delegated to focused helper
56
        Token::Import | Token::Use => {
57
0
            parse_import_token(state, token_clone)
58
        }
59
        // Special definition tokens - delegated to focused helper
60
        Token::DataFrame | Token::Actor => {
61
0
            parse_special_definition_token(state, token_clone)
62
        }
63
        // Control statement tokens - delegated to focused helper
64
        Token::Pub | Token::Break | Token::Continue | Token::Return => {
65
0
            parse_control_statement_token(state, token_clone, span_clone)
66
        }
67
        // Collection/enum definition tokens - delegated to focused helper
68
        Token::LeftBracket | Token::Enum => {
69
0
            parse_collection_enum_token(state, token_clone)
70
        }
71
        // Constructor tokens - delegated to focused helper
72
        Token::Some | Token::None | Token::Ok | Token::Err | Token::Result | Token::Option => {
73
0
            parse_constructor_token(state, token_clone, span_clone)
74
        }
75
0
        _ => bail!("Unexpected token: {:?}", token_clone),
76
    }
77
0
}
78
79
/// Parse literal tokens (Integer, Float, String, Char, Bool, `FString`)
80
/// Extracted from `parse_prefix` to reduce complexity
81
0
fn parse_literal_token(state: &mut ParserState, token: Token, span: Span) -> Result<Expr> {
82
0
    match token {
83
0
        Token::Integer(value) => {
84
0
            state.tokens.advance();
85
0
            Ok(Expr::new(ExprKind::Literal(Literal::Integer(value)), span))
86
        }
87
0
        Token::Float(value) => {
88
0
            state.tokens.advance();
89
0
            Ok(Expr::new(ExprKind::Literal(Literal::Float(value)), span))
90
        }
91
0
        Token::String(value) => {
92
0
            state.tokens.advance();
93
0
            Ok(Expr::new(ExprKind::Literal(Literal::String(value)), span))
94
        }
95
0
        Token::FString(template) => {
96
0
            state.tokens.advance();
97
            // Parse f-string template into parts with proper interpolation
98
0
            let parts = parse_fstring_into_parts(&template)?;
99
0
            Ok(Expr::new(ExprKind::StringInterpolation { parts }, span))
100
        }
101
0
        Token::Char(value) => {
102
0
            state.tokens.advance();
103
0
            Ok(Expr::new(ExprKind::Literal(Literal::Char(value)), span))
104
        }
105
0
        Token::Bool(value) => {
106
0
            state.tokens.advance();
107
0
            Ok(Expr::new(ExprKind::Literal(Literal::Bool(value)), span))
108
        }
109
0
        _ => bail!("Expected literal token, got: {:?}", token),
110
    }
111
0
}
112
113
/// Parse identifier tokens (Identifier, Underscore, fat arrow lambdas)
114
/// Extracted from `parse_prefix` to reduce complexity
115
0
fn parse_identifier_token(state: &mut ParserState, token: Token, span: Span) -> Result<Expr> {
116
0
    match token {
117
0
        Token::Identifier(name) => {
118
0
            state.tokens.advance();
119
            
120
            // Check for module path: math::add
121
0
            if matches!(state.tokens.peek(), Some((Token::ColonColon, _))) {
122
0
                let mut path = vec![name];
123
                
124
0
                while matches!(state.tokens.peek(), Some((Token::ColonColon, _))) {
125
0
                    state.tokens.advance(); // consume ::
126
                    
127
0
                    if let Some((Token::Identifier(segment), _)) = state.tokens.peek() {
128
0
                        path.push(segment.clone());
129
0
                        state.tokens.advance();
130
0
                    } else {
131
0
                        bail!("Expected identifier after '::'");
132
                    }
133
                }
134
                
135
                // Create a qualified name expression
136
0
                let qualified_name = path.join("::");
137
0
                Ok(Expr::new(ExprKind::Identifier(qualified_name), span))
138
            }
139
            // Check for fat arrow lambda: x => x * 2
140
0
            else if matches!(state.tokens.peek(), Some((Token::FatArrow, _))) {
141
0
                state.tokens.advance(); // consume =>
142
0
                let body = Box::new(super::parse_expr_recursive(state)?);
143
0
                let params = vec![Param {
144
0
                    pattern: Pattern::Identifier(name),
145
0
                    ty: Type {
146
0
                        kind: TypeKind::Named("_".to_string()),
147
0
                        span,
148
0
                    },
149
0
                    default_value: None,
150
0
                    is_mutable: false,
151
0
                    span,
152
0
                }];
153
0
                Ok(Expr::new(ExprKind::Lambda { params, body }, span))
154
            // Check for macro syntax: println! etc.
155
0
            } else if matches!(state.tokens.peek(), Some((Token::Bang, _))) {
156
                // This is a macro call like println!
157
0
                state.tokens.advance(); // consume !
158
                
159
                // Convert macro syntax to regular function call
160
                // println! -> println, assert! -> assert, etc.
161
0
                Ok(Expr::new(ExprKind::Identifier(name), span))
162
            } else {
163
0
                Ok(Expr::new(ExprKind::Identifier(name), span))
164
            }
165
        }
166
        Token::Underscore => {
167
0
            state.tokens.advance();
168
0
            Ok(Expr::new(ExprKind::Identifier("_".to_string()), span))
169
        }
170
0
        _ => bail!("Expected identifier token, got: {:?}", token),
171
    }
172
0
}
173
174
/// Parse unary operator tokens (Minus, Bang)
175
/// Extracted from `parse_prefix` to reduce complexity
176
0
fn parse_unary_operator_token(state: &mut ParserState, token: Token, span: Span) -> Result<Expr> {
177
0
    match token {
178
        Token::Minus => {
179
0
            state.tokens.advance();
180
0
            let expr = super::parse_expr_with_precedence_recursive(state, 13)?; // High precedence for unary
181
0
            Ok(Expr::new(ExprKind::Unary { 
182
0
                op: UnaryOp::Negate, 
183
0
                operand: Box::new(expr) 
184
0
            }, span))
185
        }
186
        Token::Bang => {
187
0
            state.tokens.advance();
188
0
            let expr = super::parse_expr_with_precedence_recursive(state, 13)?;
189
0
            Ok(Expr::new(ExprKind::Unary { 
190
0
                op: UnaryOp::Not, 
191
0
                operand: Box::new(expr) 
192
0
            }, span))
193
        }
194
0
        _ => bail!("Expected unary operator token, got: {:?}", token),
195
    }
196
0
}
197
198
/// Parse parentheses tokens - either unit type (), grouped expression (expr), or tuple (a, b, c)
199
/// Extracted from `parse_prefix` to reduce complexity
200
0
fn parse_parentheses_token(state: &mut ParserState, span: Span) -> Result<Expr> {
201
0
    state.tokens.advance();
202
    // Check for unit type ()
203
0
    if matches!(state.tokens.peek(), Some((Token::RightParen, _))) {
204
0
        state.tokens.advance();
205
0
        Ok(Expr::new(ExprKind::Literal(Literal::Unit), span))
206
    } else {
207
        // Parse first expression
208
0
        let first_expr = super::parse_expr_recursive(state)?;
209
        
210
        // Check if we have a comma (tuple) or just closing paren (grouped expr)
211
0
        if matches!(state.tokens.peek(), Some((Token::Comma, _))) {
212
            // This is a tuple, parse remaining elements
213
0
            let mut elements = vec![first_expr];
214
            
215
0
            while matches!(state.tokens.peek(), Some((Token::Comma, _))) {
216
0
                state.tokens.advance(); // consume comma
217
                
218
                // Check for trailing comma before closing paren
219
0
                if matches!(state.tokens.peek(), Some((Token::RightParen, _))) {
220
0
                    break;
221
0
                }
222
                
223
0
                elements.push(super::parse_expr_recursive(state)?);
224
            }
225
            
226
0
            state.tokens.expect(&Token::RightParen)?;
227
0
            Ok(Expr::new(ExprKind::Tuple(elements), span))
228
        } else {
229
            // Just a grouped expression
230
0
            state.tokens.expect(&Token::RightParen)?;
231
            
232
            // Check if this is a lambda: (x) => expr
233
0
            if matches!(state.tokens.peek(), Some((Token::FatArrow, _))) {
234
0
                parse_lambda_from_expr(state, first_expr, span)
235
            } else {
236
0
                Ok(first_expr)
237
            }
238
        }
239
    }
240
0
}
241
242
/// Parse pub token - handles public declarations for functions, structs, traits, impl blocks
243
/// Extracted from `parse_prefix` to reduce complexity
244
0
fn parse_pub_token(state: &mut ParserState) -> Result<Expr> {
245
0
    state.tokens.advance();
246
    // Get the next token to determine what follows pub
247
0
    let mut expr = parse_prefix(state)?;
248
    // Mark the expression as public if it supports it
249
0
    match &mut expr.kind {
250
0
        ExprKind::Function { is_pub, .. } => *is_pub = true,
251
0
        ExprKind::Struct { is_pub, .. } => *is_pub = true,
252
0
        ExprKind::Trait { is_pub, .. } => *is_pub = true,
253
0
        ExprKind::Impl { is_pub, .. } => *is_pub = true,
254
0
        _ => {} // Other expressions don't have is_pub
255
    }
256
0
    Ok(expr)
257
0
}
258
259
/// Parse break token with optional label
260
/// Extracted from `parse_prefix` to reduce complexity
261
0
fn parse_break_token(state: &mut ParserState, span: Span) -> Result<Expr> {
262
0
    state.tokens.advance();
263
    // Optional label
264
0
    let label = if let Some((Token::Identifier(name), _)) = state.tokens.peek() {
265
0
        let label = Some(name.clone());
266
0
        state.tokens.advance();
267
0
        label
268
    } else {
269
0
        None
270
    };
271
0
    Ok(Expr::new(ExprKind::Break { label }, span))
272
0
}
273
274
/// Parse continue token with optional label
275
/// Extracted from `parse_prefix` to reduce complexity
276
0
fn parse_continue_token(state: &mut ParserState, span: Span) -> Result<Expr> {
277
0
    state.tokens.advance();
278
    // Optional label
279
0
    let label = if let Some((Token::Identifier(name), _)) = state.tokens.peek() {
280
0
        let label = Some(name.clone());
281
0
        state.tokens.advance();
282
0
        label
283
    } else {
284
0
        None
285
    };
286
0
    Ok(Expr::new(ExprKind::Continue { label }, span))
287
0
}
288
289
/// Parse return token with optional expression
290
/// Extracted from `parse_prefix` to reduce complexity
291
0
fn parse_return_token(state: &mut ParserState, span: Span) -> Result<Expr> {
292
0
    state.tokens.advance();
293
    // Check if there's an expression to return
294
0
    let value = if matches!(state.tokens.peek(), Some((Token::Semicolon, _))) 
295
0
        || state.tokens.peek().is_none() {
296
        // No expression, just return
297
0
        None
298
    } else {
299
        // Parse the return expression
300
0
        Some(Box::new(super::parse_expr_recursive(state)?))
301
    };
302
0
    Ok(Expr::new(ExprKind::Return { value }, span))
303
0
}
304
305
/// Parse constructor tokens (Some, None, Ok, Err, Result, Option)
306
/// Extracted from `parse_prefix` to reduce complexity
307
0
fn parse_constructor_token(state: &mut ParserState, token: Token, span: Span) -> Result<Expr> {
308
0
    let constructor_name = match token {
309
0
        Token::Some => "Some",
310
0
        Token::None => "None", 
311
0
        Token::Ok => "Ok",
312
0
        Token::Err => "Err",
313
0
        Token::Result => "Result",
314
0
        Token::Option => "Option",
315
0
        _ => bail!("Expected constructor token, got: {:?}", token),
316
    };
317
    
318
0
    state.tokens.advance();
319
    
320
    // Check if this is a qualified name like Option::Some
321
0
    if matches!(state.tokens.peek(), Some((Token::ColonColon, _))) {
322
0
        state.tokens.advance(); // consume ::
323
        
324
0
        if let Some((next_token, _)) = state.tokens.peek() {
325
0
            let variant_name = match next_token.clone() {
326
0
                Token::Some => "Some".to_string(),
327
0
                Token::None => "None".to_string(),
328
0
                Token::Ok => "Ok".to_string(),
329
0
                Token::Err => "Err".to_string(),
330
0
                Token::Identifier(name) => name,
331
0
                _ => bail!("Expected variant name after '::'"),
332
            };
333
            
334
0
            state.tokens.advance();
335
0
            let qualified_name = format!("{constructor_name}::{variant_name}");
336
0
            return Ok(Expr::new(ExprKind::Identifier(qualified_name), span));
337
0
        }
338
0
        bail!("Expected variant name after '::'");
339
0
    }
340
    
341
0
    Ok(Expr::new(ExprKind::Identifier(constructor_name.to_string()), span))
342
0
}
343
344
/// Parse control flow tokens (If, Match, While, For, Try)
345
/// Extracted from `parse_prefix` to reduce complexity
346
0
fn parse_control_flow_token(state: &mut ParserState, token: Token) -> Result<Expr> {
347
0
    match token {
348
0
        Token::If => parse_if_expression(state),
349
0
        Token::Match => parse_match_expression(state),
350
0
        Token::While => parse_while_loop(state),
351
0
        Token::For => parse_for_loop(state),
352
0
        Token::Try => parse_try_catch(state),
353
0
        _ => bail!("Expected control flow token, got: {:?}", token),
354
    }
355
0
}
356
357
/// Parse try-catch-finally block
358
/// Complexity: <10 (structured error handling)
359
0
fn parse_try_catch(state: &mut ParserState) -> Result<Expr> {
360
0
    let start_span = state.tokens.expect(&Token::Try)?;
361
    
362
0
    let try_block = parse_try_block(state)?;
363
0
    let catch_clauses = parse_catch_clauses(state)?;
364
0
    let finally_block = parse_finally_block(state)?;
365
    
366
0
    validate_try_catch_structure(&catch_clauses, finally_block.as_deref())?;
367
    
368
0
    Ok(Expr::new(
369
0
        ExprKind::TryCatch {
370
0
            try_block,
371
0
            catch_clauses,
372
0
            finally_block,
373
0
        },
374
0
        start_span,
375
0
    ))
376
0
}
377
378
/// Parse module declaration: mod name { body }
379
/// Complexity: <5 (simple structure)
380
0
fn parse_module_declaration(state: &mut ParserState) -> Result<Expr> {
381
0
    let start_span = state.tokens.expect(&Token::Mod)?;
382
    
383
    // Parse module name
384
0
    let name = if let Some((Token::Identifier(n), _)) = state.tokens.peek() {
385
0
        let n = n.clone();
386
0
        state.tokens.advance();
387
0
        n
388
    } else {
389
0
        bail!("Expected module name after 'mod'");
390
    };
391
    
392
    // Parse module body with visibility support
393
0
    state.tokens.expect(&Token::LeftBrace)?;
394
0
    let body = Box::new(parse_module_body(state)?);
395
    
396
0
    Ok(Expr::new(
397
0
        ExprKind::Module { name, body },
398
0
        start_span,
399
0
    ))
400
0
}
401
402
/// Parse module body with support for visibility modifiers (pub)
403
0
fn parse_module_body(state: &mut ParserState) -> Result<Expr> {
404
0
    let start_span = state.tokens.peek().map_or(Span { start: 0, end: 0 }, |t| t.1);
405
0
    let mut exprs = Vec::new();
406
    
407
0
    while !matches!(state.tokens.peek(), Some((Token::RightBrace, _))) {
408
        // Check for visibility modifier
409
0
        let is_pub = if matches!(state.tokens.peek(), Some((Token::Pub, _))) {
410
0
            state.tokens.advance();
411
0
            true
412
        } else {
413
0
            false
414
        };
415
        
416
        // Parse the item with visibility
417
0
        let expr = if matches!(state.tokens.peek(), Some((Token::Fun, _))) {
418
0
            super::functions::parse_function_with_visibility(state, is_pub)?
419
0
        } else if is_pub {
420
0
            bail!("'pub' can only be used with function declarations in modules");
421
        } else {
422
            // Regular expression without visibility
423
0
            super::parse_expr_recursive(state)?
424
        };
425
        
426
0
        exprs.push(expr);
427
        
428
        // Skip optional semicolons
429
0
        if matches!(state.tokens.peek(), Some((Token::Semicolon, _))) {
430
0
            state.tokens.advance();
431
0
        }
432
    }
433
    
434
0
    state.tokens.expect(&Token::RightBrace)?;
435
    
436
0
    Ok(Expr::new(ExprKind::Block(exprs), start_span))
437
0
}
438
439
/// Parse data structure definition tokens (Struct, Trait, Impl)
440
/// Extracted from `parse_prefix` to reduce complexity
441
0
fn parse_data_structure_token(state: &mut ParserState, token: Token) -> Result<Expr> {
442
0
    match token {
443
0
        Token::Struct => parse_struct_definition(state),
444
0
        Token::Trait => parse_trait_definition(state),
445
0
        Token::Impl => parse_impl_block(state),
446
0
        _ => bail!("Expected data structure token, got: {:?}", token),
447
    }
448
0
}
449
450
/// Parse import/module tokens (Import, Use)
451
/// Extracted from `parse_prefix` to reduce complexity
452
0
fn parse_import_token(state: &mut ParserState, token: Token) -> Result<Expr> {
453
0
    match token {
454
0
        Token::Import => parse_import_statement(state),
455
0
        Token::Use => parse_use_statement(state),
456
0
        _ => bail!("Expected import token, got: {:?}", token),
457
    }
458
0
}
459
460
/// Parse lambda expression tokens (Pipe, `OrOr`)\
461
/// Extracted from `parse_prefix` to reduce complexity
462
0
fn parse_lambda_token(state: &mut ParserState, token: Token) -> Result<Expr> {
463
0
    match token {
464
0
        Token::Pipe => parse_lambda_expression(state),
465
0
        Token::OrOr => parse_lambda_no_params(state),
466
0
        _ => bail!("Expected lambda token, got: {:?}", token),
467
    }
468
0
}
469
470
/// Parse function/block tokens (Fun, Fn, `LeftBrace`)
471
/// Extracted from `parse_prefix` to reduce complexity
472
0
fn parse_function_block_token(state: &mut ParserState, token: Token) -> Result<Expr> {
473
0
    match token {
474
0
        Token::Fun | Token::Fn => super::functions::parse_function(state),
475
0
        Token::LeftBrace => super::collections::parse_block(state),
476
0
        _ => bail!("Expected function/block token, got: {:?}", token),
477
    }
478
0
}
479
480
/// Parse variable declaration tokens (Let, Var)
481
/// Extracted from `parse_prefix` to reduce complexity
482
0
fn parse_variable_declaration_token(state: &mut ParserState, token: Token) -> Result<Expr> {
483
0
    match token {
484
0
        Token::Let => parse_let_statement(state),
485
0
        Token::Var => parse_var_statement(state),
486
0
        _ => bail!("Expected variable declaration token, got: {:?}", token),
487
    }
488
0
}
489
490
/// Parse special definition tokens (`DataFrame`, Actor)
491
/// Extracted from `parse_prefix` to reduce complexity
492
0
fn parse_special_definition_token(state: &mut ParserState, token: Token) -> Result<Expr> {
493
0
    match token {
494
        Token::DataFrame => {
495
            // Check if this is df! (literal) or df (identifier)
496
0
            if matches!(state.tokens.peek(), Some((Token::Bang, _))) {
497
0
                parse_dataframe_literal(state)
498
            } else {
499
                // Treat 'df' as a regular identifier for method calls, etc.
500
                // Consume the DataFrame token since we're handling it as identifier
501
0
                state.tokens.advance();
502
0
                Ok(Expr::new(
503
0
                    ExprKind::Identifier("df".to_string()),
504
0
                    Span::default(),
505
0
                ))
506
            }
507
        }
508
0
        Token::Actor => parse_actor_definition(state),
509
0
        _ => bail!("Expected special definition token, got: {:?}", token),
510
    }
511
0
}
512
513
/// Parse control statement tokens (Pub, Break, Continue, Return)
514
/// Extracted from `parse_prefix` to reduce complexity
515
0
fn parse_control_statement_token(state: &mut ParserState, token: Token, span: Span) -> Result<Expr> {
516
0
    match token {
517
0
        Token::Pub => parse_pub_token(state),
518
0
        Token::Break => parse_break_token(state, span),
519
0
        Token::Continue => parse_continue_token(state, span), 
520
0
        Token::Return => parse_return_token(state, span),
521
0
        _ => bail!("Expected control statement token, got: {:?}", token),
522
    }
523
0
}
524
525
/// Parse collection/enum definition tokens (`LeftBracket`, Enum)
526
/// Extracted from `parse_prefix` to reduce complexity
527
0
fn parse_collection_enum_token(state: &mut ParserState, token: Token) -> Result<Expr> {
528
0
    match token {
529
0
        Token::LeftBracket => parse_list_literal(state),
530
0
        Token::Enum => parse_enum_definition(state),
531
0
        _ => bail!("Expected collection/enum token, got: {:?}", token),
532
    }
533
0
}
534
535
/// Parse let statement: let [mut] name [: type] = value [in body]
536
0
fn parse_let_statement(state: &mut ParserState) -> Result<Expr> {
537
0
    let start_span = state.tokens.expect(&Token::Let)?;
538
    
539
    // Check for optional 'mut' keyword
540
0
    let is_mutable = parse_let_mutability(state);
541
    
542
    // Parse variable name or destructuring pattern
543
0
    let pattern = parse_let_pattern(state, is_mutable)?;
544
    
545
    // Parse optional type annotation
546
0
    let type_annotation = parse_let_type_annotation(state)?;
547
    
548
    // Parse '=' token
549
0
    state.tokens.expect(&Token::Equal)?;
550
    
551
    // Parse value expression
552
0
    let value = Box::new(super::parse_expr_recursive(state)?);
553
    
554
    // Parse optional 'in' clause for let expressions
555
0
    let body = parse_let_in_clause(state, value.span)?;
556
    
557
    // Create the appropriate expression based on pattern type
558
0
    create_let_expression(pattern, type_annotation, value, body, is_mutable, start_span)
559
0
}
560
561
/// Parse mutability for let statement
562
/// Extracted from `parse_let_statement` to reduce complexity
563
0
fn parse_let_mutability(state: &mut ParserState) -> bool {
564
0
    if matches!(state.tokens.peek(), Some((Token::Mut, _))) {
565
0
        state.tokens.advance();
566
0
        true
567
    } else {
568
0
        false
569
    }
570
0
}
571
572
/// Parse pattern for let statement (identifier or destructuring)
573
/// Extracted from `parse_let_statement` to reduce complexity
574
0
fn parse_let_pattern(state: &mut ParserState, is_mutable: bool) -> Result<Pattern> {
575
0
    match state.tokens.peek() {
576
0
        Some((Token::Identifier(name), _)) => {
577
0
            let name = name.clone();
578
0
            state.tokens.advance();
579
0
            Ok(Pattern::Identifier(name))
580
        }
581
        Some((Token::DataFrame, _)) => {
582
            // Allow 'df' as a variable name (common in data science)
583
0
            state.tokens.advance();
584
0
            Ok(Pattern::Identifier("df".to_string()))
585
        }
586
        Some((Token::LeftParen, _)) => {
587
            // Parse tuple destructuring: (x, y) = (1, 2)
588
0
            parse_tuple_pattern(state)
589
        }
590
        Some((Token::LeftBracket, _)) => {
591
            // Parse list destructuring: [a, b] = [1, 2]
592
0
            parse_list_pattern(state)
593
        }
594
        Some((Token::LeftBrace, _)) => {
595
            // Parse struct destructuring: {name, age} = obj
596
0
            parse_struct_pattern(state)
597
        }
598
0
        _ => bail!("Expected identifier or pattern after 'let{}'", 
599
0
                   if is_mutable { " mut" } else { "" })
600
    }
601
0
}
602
603
/// Parse optional type annotation for let statement
604
/// Extracted from `parse_let_statement` to reduce complexity
605
0
fn parse_let_type_annotation(state: &mut ParserState) -> Result<Option<Type>> {
606
0
    if matches!(state.tokens.peek(), Some((Token::Colon, _))) {
607
0
        state.tokens.advance(); // consume ':'
608
0
        Ok(Some(super::utils::parse_type(state)?))
609
    } else {
610
0
        Ok(None)
611
    }
612
0
}
613
614
/// Parse optional 'in' clause for let expressions
615
/// Extracted from `parse_let_statement` to reduce complexity
616
0
fn parse_let_in_clause(state: &mut ParserState, value_span: Span) -> Result<Box<Expr>> {
617
0
    if matches!(state.tokens.peek(), Some((Token::In, _))) {
618
0
        state.tokens.advance(); // consume 'in'
619
0
        Ok(Box::new(super::parse_expr_recursive(state)?))
620
    } else {
621
        // For let statements (no 'in'), body is unit
622
0
        Ok(Box::new(Expr::new(ExprKind::Literal(Literal::Unit), value_span)))
623
    }
624
0
}
625
626
/// Create the appropriate let expression based on pattern type
627
/// Extracted from `parse_let_statement` to reduce complexity
628
0
fn create_let_expression(
629
0
    pattern: Pattern,
630
0
    type_annotation: Option<Type>,
631
0
    value: Box<Expr>,
632
0
    body: Box<Expr>,
633
0
    is_mutable: bool,
634
0
    start_span: Span,
635
0
) -> Result<Expr> {
636
0
    let end_span = body.span;
637
    
638
0
    match &pattern {
639
0
        Pattern::Identifier(name) => {
640
0
            Ok(Expr::new(
641
0
                ExprKind::Let {
642
0
                    name: name.clone(),
643
0
                    type_annotation,
644
0
                    value,
645
0
                    body,
646
0
                    is_mutable,
647
0
                },
648
0
                start_span.merge(end_span),
649
0
            ))
650
        }
651
        Pattern::Tuple(_) | Pattern::List(_) => {
652
            // For destructuring patterns, use LetPattern variant
653
0
            Ok(Expr::new(
654
0
                ExprKind::LetPattern {
655
0
                    pattern,
656
0
                    type_annotation,
657
0
                    value,
658
0
                    body,
659
0
                    is_mutable,
660
0
                },
661
0
                start_span.merge(end_span),
662
0
            ))
663
        }
664
        Pattern::Wildcard | Pattern::Literal(_) | Pattern::QualifiedName(_) | Pattern::Struct { .. } 
665
        | Pattern::Range { .. } | Pattern::Or(_) | Pattern::Rest | Pattern::RestNamed(_) 
666
        | Pattern::WithDefault { .. } | Pattern::Ok(_) | Pattern::Err(_) | Pattern::Some(_) | Pattern::None => {
667
            // For other pattern types, use LetPattern variant
668
0
            Ok(Expr::new(
669
0
                ExprKind::LetPattern {
670
0
                    pattern,
671
0
                    type_annotation,
672
0
                    value,
673
0
                    body,
674
0
                    is_mutable,
675
0
                },
676
0
                start_span.merge(end_span),
677
0
            ))
678
        }
679
    }
680
0
}
681
682
/// Parse var statement: var name [: type] = value
683
/// var is implicitly mutable (like let mut)
684
0
fn parse_var_statement(state: &mut ParserState) -> Result<Expr> {
685
0
    let start_span = state.tokens.expect(&Token::Var)?;
686
    
687
    // var is always mutable
688
0
    let is_mutable = true;
689
    
690
    // Parse variable name or destructuring pattern
691
0
    let pattern = match state.tokens.peek() {
692
0
        Some((Token::Identifier(name), _)) => {
693
0
            let name = name.clone();
694
0
            state.tokens.advance();
695
0
            Pattern::Identifier(name)
696
        }
697
        Some((Token::DataFrame, _)) => {
698
            // Allow 'df' as a variable name (common in data science)
699
0
            state.tokens.advance();
700
0
            Pattern::Identifier("df".to_string())
701
        }
702
        Some((Token::LeftParen, _)) => {
703
            // Parse tuple destructuring: (x, y) = (1, 2)
704
0
            parse_tuple_pattern(state)?
705
        }
706
        Some((Token::LeftBracket, _)) => {
707
            // Parse list destructuring: [a, b] = [1, 2]
708
0
            parse_list_pattern(state)?
709
        }
710
0
        _ => bail!("Expected identifier or pattern after 'var'")
711
    };
712
    
713
    // Parse optional type annotation
714
0
    let type_annotation = if matches!(state.tokens.peek(), Some((Token::Colon, _))) {
715
0
        state.tokens.advance();
716
0
        Some(super::utils::parse_type(state)?)
717
    } else {
718
0
        None
719
    };
720
    
721
    // Parse '=' token
722
0
    state.tokens.expect(&Token::Equal)?;
723
    
724
    // Parse value expression
725
0
    let value = Box::new(super::parse_expr_recursive(state)?);
726
    
727
    // var doesn't support 'in' syntax, just creates a mutable binding
728
0
    let body = Box::new(Expr::new(ExprKind::Literal(Literal::Unit), value.span));
729
    
730
0
    let end_span = value.span;
731
    
732
    // Handle different pattern types
733
0
    match &pattern {
734
0
        Pattern::Identifier(name) => {
735
            // Simple identifier binding
736
0
            Ok(Expr::new(
737
0
                ExprKind::Let {
738
0
                    name: name.clone(),
739
0
                    type_annotation,
740
0
                    value,
741
0
                    body,
742
0
                    is_mutable,
743
0
                },
744
0
                start_span.merge(end_span),
745
0
            ))
746
        }
747
        _ => {
748
            // For all other patterns (tuple, list, etc), use LetPattern variant
749
0
            Ok(Expr::new(
750
0
                ExprKind::LetPattern {
751
0
                    pattern,
752
0
                    type_annotation,
753
0
                    value,
754
0
                    body,
755
0
                    is_mutable,
756
0
                },
757
0
                start_span.merge(end_span),
758
0
            ))
759
        }
760
    }
761
0
}
762
763
0
pub fn parse_tuple_pattern(state: &mut ParserState) -> Result<Pattern> {
764
0
    state.tokens.expect(&Token::LeftParen)?;
765
0
    let mut patterns = Vec::new();
766
    
767
0
    while !matches!(state.tokens.peek(), Some((Token::RightParen, _))) {
768
        // Parse nested pattern recursively
769
0
        let pattern = match state.tokens.peek() {
770
0
            Some((Token::Identifier(name), _)) => {
771
0
                let name = name.clone();
772
0
                state.tokens.advance();
773
0
                Pattern::Identifier(name)
774
            }
775
            Some((Token::LeftParen, _)) => {
776
                // Nested tuple pattern
777
0
                parse_tuple_pattern(state)?
778
            }
779
            Some((Token::LeftBracket, _)) => {
780
                // Nested list pattern
781
0
                parse_list_pattern(state)?
782
            }
783
            Some((Token::LeftBrace, _)) => {
784
                // Nested struct pattern
785
0
                parse_struct_pattern(state)?
786
            }
787
            Some((Token::Underscore, _)) => {
788
0
                state.tokens.advance();
789
0
                Pattern::Wildcard
790
            }
791
0
            _ => bail!("Expected identifier, tuple, list, struct, or wildcard in tuple pattern"),
792
        };
793
0
        patterns.push(pattern);
794
        
795
        // Only consume comma if not at end
796
0
        if matches!(state.tokens.peek(), Some((Token::Comma, _))) {
797
0
            state.tokens.advance();
798
            // If we hit RightParen after comma, break (trailing comma case)
799
0
            if matches!(state.tokens.peek(), Some((Token::RightParen, _))) {
800
0
                break;
801
0
            }
802
0
        } else if !matches!(state.tokens.peek(), Some((Token::RightParen, _))) {
803
0
            bail!("Expected ',' or ')' in tuple pattern");
804
0
        }
805
    }
806
    
807
0
    state.tokens.expect(&Token::RightParen)?;
808
0
    Ok(Pattern::Tuple(patterns))
809
0
}
810
811
0
pub fn parse_struct_pattern(state: &mut ParserState) -> Result<Pattern> {
812
0
    state.tokens.advance(); // consume '{'
813
    
814
0
    let mut fields = Vec::new();
815
0
    let mut is_first = true;
816
    
817
0
    while let Some((token, _)) = state.tokens.peek() {
818
0
        if matches!(token, Token::RightBrace) {
819
0
            state.tokens.advance(); // consume '}'
820
0
            break;
821
0
        }
822
        
823
0
        if !is_first {
824
0
            if matches!(state.tokens.peek(), Some((Token::Comma, _))) {
825
0
                state.tokens.advance(); // consume ','
826
0
            } else {
827
0
                bail!("Expected comma between struct pattern fields");
828
            }
829
0
        }
830
0
        is_first = false;
831
        
832
        // Parse field name
833
0
        if let Some((Token::Identifier(name), _)) = state.tokens.peek() {
834
0
            let field_name = name.clone();
835
0
            state.tokens.advance();
836
0
            
837
0
            // For now, support shorthand syntax only: {name, age}
838
0
            // TODO: Support full syntax: {name: pattern, age: other_pattern}
839
0
            let field = crate::frontend::ast::StructPatternField {
840
0
                name: field_name.clone(),
841
0
                pattern: None, // Shorthand means field name is the variable name
842
0
            };
843
0
            fields.push(field);
844
0
        } else {
845
0
            bail!("Expected identifier in struct pattern");
846
        }
847
    }
848
    
849
0
    Ok(Pattern::Struct {
850
0
        name: String::new(), // Anonymous struct pattern (empty name)
851
0
        fields,
852
0
        has_rest: false, // No rest patterns in basic struct destructuring
853
0
    })
854
0
}
855
856
0
pub fn parse_list_pattern(state: &mut ParserState) -> Result<Pattern> {
857
0
    state.tokens.expect(&Token::LeftBracket)?;
858
0
    let mut patterns = Vec::new();
859
    
860
0
    while !matches!(state.tokens.peek(), Some((Token::RightBracket, _))) {
861
0
        let pattern = match state.tokens.peek() {
862
0
            Some((Token::Identifier(name), _)) => {
863
0
                let name = name.clone();
864
0
                state.tokens.advance();
865
                
866
                // Check for default value: identifier = expr
867
0
                if matches!(state.tokens.peek(), Some((Token::Equal, _))) {
868
0
                    state.tokens.advance(); // consume '='
869
0
                    let default_expr = super::parse_expr_recursive(state)?;
870
0
                    Pattern::WithDefault {
871
0
                        pattern: Box::new(Pattern::Identifier(name)),
872
0
                        default: Box::new(default_expr),
873
0
                    }
874
                } else {
875
0
                    Pattern::Identifier(name)
876
                }
877
            }
878
            Some((Token::DotDotDot, _)) => {
879
                // Rest pattern: ...rest or ...
880
0
                state.tokens.advance(); // consume ...
881
                // Check if named rest pattern
882
0
                if let Some((Token::Identifier(name), _)) = state.tokens.peek() {
883
0
                    let name = name.clone();
884
0
                    state.tokens.advance();
885
0
                    Pattern::RestNamed(name)
886
                } else {
887
0
                    Pattern::Rest
888
                }
889
            }
890
            Some((Token::LeftParen, _)) => {
891
                // Nested tuple pattern in list
892
0
                parse_tuple_pattern(state)?
893
            }
894
            Some((Token::LeftBracket, _)) => {
895
                // Nested list pattern
896
0
                parse_list_pattern(state)?
897
            }
898
            Some((Token::Underscore, _)) => {
899
0
                state.tokens.advance();
900
0
                Pattern::Wildcard
901
            }
902
0
            _ => bail!("Expected identifier, tuple, list, wildcard, or rest pattern in list pattern"),
903
        };
904
0
        patterns.push(pattern);
905
        
906
0
        if matches!(state.tokens.peek(), Some((Token::Comma, _))) {
907
0
            state.tokens.advance();
908
            // Break if we hit the closing bracket after comma
909
0
            if matches!(state.tokens.peek(), Some((Token::RightBracket, _))) {
910
0
                break;
911
0
            }
912
0
        } else if !matches!(state.tokens.peek(), Some((Token::RightBracket, _))) {
913
0
            bail!("Expected ',' or ']' in list pattern");
914
0
        }
915
    }
916
    
917
0
    state.tokens.expect(&Token::RightBracket)?;
918
0
    Ok(Pattern::List(patterns))
919
0
}
920
921
/// Parse if expression: if condition { `then_branch` } [else { `else_branch` }]
922
/// Also handles if-let: if let pattern = expr { `then_branch` } [else { `else_branch` }]
923
/// Complexity: <10 (split into helper functions)
924
0
fn parse_if_expression(state: &mut ParserState) -> Result<Expr> {
925
0
    let start_span = state.tokens.expect(&Token::If)?;
926
    
927
    // Check for if-let syntax
928
0
    if matches!(state.tokens.peek(), Some((Token::Let, _))) {
929
0
        parse_if_let_expression(state, start_span)
930
    } else {
931
0
        parse_regular_if_expression(state, start_span)
932
    }
933
0
}
934
935
/// Parse if-let expression: if let pattern = expr { then } [else { else }]
936
/// Complexity: <10
937
0
fn parse_if_let_expression(state: &mut ParserState, start_span: Span) -> Result<Expr> {
938
0
    state.tokens.advance(); // consume 'let'
939
    
940
    // Parse the pattern
941
0
    let pattern = parse_match_pattern(state)
942
0
        .map_err(|e| anyhow::anyhow!("Expected pattern after 'if let': {}", e))?;
943
    
944
    // Expect '='
945
0
    state.tokens.expect(&Token::Equal)
946
0
        .map_err(|e| anyhow::anyhow!("Expected '=' after pattern in if-let: {}", e))?;
947
    
948
    // Parse the expression to match against
949
0
    let expr = Box::new(super::parse_expr_recursive(state)
950
0
        .map_err(|e| anyhow::anyhow!("Expected expression after '=' in if-let: {}", e))?);
951
    
952
    // Parse then branch
953
0
    let then_branch = Box::new(super::parse_expr_recursive(state)
954
0
        .map_err(|e| anyhow::anyhow!("Expected body after if-let condition, typically {{ ... }}: {}", e))?);
955
    
956
    // Parse optional else branch
957
0
    let else_branch = parse_else_branch(state)?;
958
    
959
0
    Ok(Expr::new(
960
0
        ExprKind::IfLet {
961
0
            pattern,
962
0
            expr,
963
0
            then_branch,
964
0
            else_branch,
965
0
        },
966
0
        start_span,
967
0
    ))
968
0
}
969
970
/// Parse regular if expression: if condition { then } [else { else }]
971
/// Complexity: <10
972
0
fn parse_regular_if_expression(state: &mut ParserState, start_span: Span) -> Result<Expr> {
973
    // Parse condition with better error context
974
0
    let condition = Box::new(super::parse_expr_recursive(state)
975
0
        .map_err(|e| anyhow::anyhow!("Expected condition after 'if': {}", e))?);
976
    
977
    // Parse then branch (expect block) with better error context
978
0
    let then_branch = Box::new(super::parse_expr_recursive(state)
979
0
        .map_err(|e| anyhow::anyhow!("Expected body after if condition, typically {{ ... }}: {}", e))?);
980
    
981
    // Parse optional else branch
982
0
    let else_branch = parse_else_branch(state)?;
983
    
984
0
    Ok(Expr::new(
985
0
        ExprKind::If {
986
0
            condition,
987
0
            then_branch,
988
0
            else_branch,
989
0
        },
990
0
        start_span,
991
0
    ))
992
0
}
993
994
/// Parse else branch for if/if-let expressions
995
/// Complexity: <10
996
0
fn parse_else_branch(state: &mut ParserState) -> Result<Option<Box<Expr>>> {
997
0
    if matches!(state.tokens.peek(), Some((Token::Else, _))) {
998
0
        state.tokens.advance(); // consume 'else'
999
        
1000
        // Check for else-if or else-if-let
1001
0
        if matches!(state.tokens.peek(), Some((Token::If, _))) {
1002
            // Let the recursive call handle else-if or else-if-let
1003
0
            Ok(Some(Box::new(parse_if_expression(state)?)))
1004
        } else {
1005
0
            Ok(Some(Box::new(super::parse_expr_recursive(state)
1006
0
                .map_err(|e| anyhow::anyhow!("Expected body after 'else', typically {{ ... }}: {}", e))?)))
1007
        }
1008
    } else {
1009
0
        Ok(None)
1010
    }
1011
0
}
1012
1013
/// Parse match expression: match expr { pattern => result, ... }
1014
/// Complexity target: <10 (using helper functions for TDG compliance)
1015
0
fn parse_match_expression(state: &mut ParserState) -> Result<Expr> {
1016
0
    let start_span = state.tokens.expect(&Token::Match)?;
1017
    
1018
    // Parse the expression to match on
1019
0
    let expr = Box::new(super::parse_expr_recursive(state)
1020
0
        .map_err(|e| anyhow::anyhow!("Expected expression after 'match': {}", e))?);
1021
    
1022
    // Expect opening brace for match arms
1023
0
    state.tokens.expect(&Token::LeftBrace)
1024
0
        .map_err(|_| anyhow::anyhow!("Expected '{{' after match expression"))?;
1025
    
1026
    // Parse match arms
1027
0
    let arms = parse_match_arms(state)?;
1028
    
1029
    // Expect closing brace
1030
0
    state.tokens.expect(&Token::RightBrace)
1031
0
        .map_err(|_| anyhow::anyhow!("Expected '}}' after match arms"))?;
1032
    
1033
0
    Ok(Expr::new(
1034
0
        ExprKind::Match { expr, arms },
1035
0
        start_span,
1036
0
    ))
1037
0
}
1038
1039
/// Parse match arms with low complexity (helper function for TDG compliance)
1040
0
fn parse_match_arms(state: &mut ParserState) -> Result<Vec<MatchArm>> {
1041
0
    let mut arms = Vec::new();
1042
    
1043
0
    while !matches!(state.tokens.peek(), Some((Token::RightBrace, _)) | None) {
1044
        // Parse single arm
1045
0
        let arm = parse_single_match_arm(state)?;
1046
0
        arms.push(arm);
1047
        
1048
        // Optional comma
1049
0
        if matches!(state.tokens.peek(), Some((Token::Comma, _))) {
1050
0
            state.tokens.advance();
1051
0
        }
1052
        
1053
        // Check if we're done
1054
0
        if matches!(state.tokens.peek(), Some((Token::RightBrace, _))) {
1055
0
            break;
1056
0
        }
1057
    }
1058
    
1059
0
    if arms.is_empty() {
1060
0
        bail!("Match expression must have at least one arm");
1061
0
    }
1062
    
1063
0
    Ok(arms)
1064
0
}
1065
1066
/// Parse a single match arm: pattern [if guard] => expr
1067
/// Complexity: <5 (simple sequential parsing)
1068
0
fn parse_single_match_arm(state: &mut ParserState) -> Result<MatchArm> {
1069
0
    let start_span = state.tokens.peek().map(|(_, s)| *s)
1070
0
        .unwrap_or_default();
1071
    
1072
    // Parse pattern
1073
0
    let pattern = parse_match_pattern(state)?;
1074
    
1075
    // Parse optional guard (if condition)
1076
0
    let guard = if matches!(state.tokens.peek(), Some((Token::If, _))) {
1077
0
        state.tokens.advance(); // consume 'if'
1078
0
        Some(Box::new(super::parse_expr_recursive(state)?))
1079
    } else {
1080
0
        None
1081
    };
1082
    
1083
    // Expect => token
1084
0
    state.tokens.expect(&Token::FatArrow)
1085
0
        .map_err(|_| anyhow::anyhow!("Expected '=>' in match arm"))?;
1086
    
1087
    // Parse result expression
1088
0
    let body = Box::new(super::parse_expr_recursive(state)?);
1089
    
1090
0
    let end_span = body.span;
1091
    
1092
0
    Ok(MatchArm {
1093
0
        pattern,
1094
0
        guard,
1095
0
        body,
1096
0
        span: start_span.merge(end_span),
1097
0
    })
1098
0
}
1099
1100
/// Parse match pattern with low complexity
1101
/// Complexity: <5 (simple pattern matching)
1102
0
fn parse_match_pattern(state: &mut ParserState) -> Result<Pattern> {
1103
0
    if state.tokens.peek().is_none() {
1104
0
        bail!("Expected pattern in match arm");
1105
0
    }
1106
    
1107
    // Delegate to focused helper functions
1108
0
    let pattern = parse_single_pattern(state)?;
1109
    
1110
    // Handle multiple patterns with | (or)
1111
0
    if matches!(state.tokens.peek(), Some((Token::Pipe, _))) {
1112
0
        parse_or_pattern(state, pattern)
1113
    } else {
1114
0
        Ok(pattern)
1115
    }
1116
0
}
1117
1118
/// Parse a single pattern (delegates to specific pattern parsers)
1119
/// Complexity: <8
1120
0
fn parse_single_pattern(state: &mut ParserState) -> Result<Pattern> {
1121
0
    let Some((token, _span)) = state.tokens.peek() else {
1122
0
        bail!("Expected pattern");
1123
    };
1124
    
1125
0
    match token {
1126
0
        Token::Underscore => parse_wildcard_pattern(state),
1127
        Token::Integer(_) | Token::Float(_) | Token::String(_) | 
1128
0
        Token::Char(_) | Token::Bool(_) => parse_literal_pattern(state),
1129
0
        Token::Some | Token::None => parse_option_pattern(state),
1130
0
        Token::Ok | Token::Err => parse_result_pattern(state),
1131
0
        Token::Identifier(_) => parse_identifier_or_constructor_pattern(state),
1132
0
        Token::LeftParen => parse_match_tuple_pattern(state),
1133
0
        Token::LeftBracket => parse_match_list_pattern(state),
1134
0
        _ => bail!("Unexpected token in pattern: {:?}", token)
1135
    }
1136
0
}
1137
1138
/// Parse wildcard pattern: _
1139
/// Complexity: 1
1140
0
fn parse_wildcard_pattern(state: &mut ParserState) -> Result<Pattern> {
1141
0
    state.tokens.advance();
1142
0
    Ok(Pattern::Wildcard)
1143
0
}
1144
1145
/// Parse literal patterns: integers, floats, strings, chars, booleans
1146
/// Complexity: <5
1147
0
fn parse_literal_pattern(state: &mut ParserState) -> Result<Pattern> {
1148
0
    let Some((token, _span)) = state.tokens.peek() else {
1149
0
        bail!("Expected literal pattern");
1150
    };
1151
    
1152
0
    let pattern = match token {
1153
0
        Token::Integer(val) => {
1154
0
            let val = *val;
1155
0
            state.tokens.advance();
1156
            
1157
            // Check for range patterns: 1..5 or 1..=5
1158
0
            match state.tokens.peek() {
1159
                Some((Token::DotDot, _)) => {
1160
0
                    state.tokens.advance(); // consume '..'
1161
                    
1162
                    // Parse end value
1163
0
                    if let Some((Token::Integer(end_val), _)) = state.tokens.peek() {
1164
0
                        let end_val = *end_val;
1165
0
                        state.tokens.advance();
1166
                        
1167
0
                        Pattern::Range {
1168
0
                            start: Box::new(Pattern::Literal(Literal::Integer(val))),
1169
0
                            end: Box::new(Pattern::Literal(Literal::Integer(end_val))),
1170
0
                            inclusive: false, // exclusive range
1171
0
                        }
1172
                    } else {
1173
0
                        bail!("Expected integer after range operator");
1174
                    }
1175
                }
1176
                Some((Token::DotDotEqual, _)) => {
1177
0
                    state.tokens.advance(); // consume '..='
1178
                    
1179
                    // Parse end value
1180
0
                    if let Some((Token::Integer(end_val), _)) = state.tokens.peek() {
1181
0
                        let end_val = *end_val;
1182
0
                        state.tokens.advance();
1183
                        
1184
0
                        Pattern::Range {
1185
0
                            start: Box::new(Pattern::Literal(Literal::Integer(val))),
1186
0
                            end: Box::new(Pattern::Literal(Literal::Integer(end_val))),
1187
0
                            inclusive: true, // inclusive range
1188
0
                        }
1189
                    } else {
1190
0
                        bail!("Expected integer after range operator");
1191
                    }
1192
                }
1193
                _ => {
1194
0
                    Pattern::Literal(Literal::Integer(val))
1195
                }
1196
            }
1197
        }
1198
0
        Token::Float(val) => {
1199
0
            let val = *val;
1200
0
            state.tokens.advance();
1201
0
            Pattern::Literal(Literal::Float(val))
1202
        }
1203
0
        Token::String(s) => {
1204
0
            let s = s.clone();
1205
0
            state.tokens.advance();
1206
0
            Pattern::Literal(Literal::String(s))
1207
        }
1208
0
        Token::Char(c) => {
1209
0
            let c = *c;
1210
0
            state.tokens.advance();
1211
0
            Pattern::Literal(Literal::Char(c))
1212
        }
1213
0
        Token::Bool(b) => {
1214
0
            let b = *b;
1215
0
            state.tokens.advance();
1216
0
            Pattern::Literal(Literal::Bool(b))
1217
        }
1218
0
        _ => bail!("Expected literal pattern, got: {:?}", token)
1219
    };
1220
    
1221
0
    Ok(pattern)
1222
0
}
1223
1224
/// Parse Option patterns: Some, None
1225
/// Complexity: <5
1226
0
fn parse_option_pattern(state: &mut ParserState) -> Result<Pattern> {
1227
0
    let Some((token, _span)) = state.tokens.peek() else {
1228
0
        bail!("Expected Option pattern");
1229
    };
1230
    
1231
0
    match token {
1232
        Token::Some => {
1233
0
            state.tokens.advance();
1234
0
            if matches!(state.tokens.peek(), Some((Token::LeftParen, _))) {
1235
0
                parse_constructor_pattern(state, "Some".to_string())
1236
            } else {
1237
0
                Ok(Pattern::Identifier("Some".to_string()))
1238
            }
1239
        }
1240
        Token::None => {
1241
0
            state.tokens.advance();
1242
0
            if matches!(state.tokens.peek(), Some((Token::LeftParen, _))) {
1243
0
                parse_constructor_pattern(state, "None".to_string())
1244
            } else {
1245
0
                Ok(Pattern::Identifier("None".to_string()))
1246
            }
1247
        }
1248
0
        _ => bail!("Expected Some or None pattern")
1249
    }
1250
0
}
1251
1252
/// Parse Result patterns (Ok/Err)
1253
/// Complexity: 4
1254
0
fn parse_result_pattern(state: &mut ParserState) -> Result<Pattern> {
1255
0
    let Some((token, _span)) = state.tokens.peek() else {
1256
0
        bail!("Expected Result pattern");
1257
    };
1258
    
1259
0
    match token {
1260
        Token::Ok => {
1261
0
            state.tokens.advance();
1262
0
            if matches!(state.tokens.peek(), Some((Token::LeftParen, _))) {
1263
0
                parse_constructor_pattern(state, "Ok".to_string())
1264
            } else {
1265
0
                Ok(Pattern::Identifier("Ok".to_string()))
1266
            }
1267
        }
1268
        Token::Err => {
1269
0
            state.tokens.advance();
1270
0
            if matches!(state.tokens.peek(), Some((Token::LeftParen, _))) {
1271
0
                parse_constructor_pattern(state, "Err".to_string())
1272
            } else {
1273
0
                Ok(Pattern::Identifier("Err".to_string()))
1274
            }
1275
        }
1276
0
        _ => bail!("Expected Ok or Err pattern")
1277
    }
1278
0
}
1279
1280
/// Parse identifier or constructor patterns
1281
/// Complexity: <5
1282
0
fn parse_identifier_or_constructor_pattern(state: &mut ParserState) -> Result<Pattern> {
1283
0
    let Some((Token::Identifier(name), _span)) = state.tokens.peek() else {
1284
0
        bail!("Expected identifier pattern");
1285
    };
1286
    
1287
0
    let name = name.clone();
1288
0
    state.tokens.advance();
1289
    
1290
    // Check for enum-like patterns: Ok(x), Err(e), etc.
1291
0
    if matches!(state.tokens.peek(), Some((Token::LeftParen, _))) {
1292
0
        parse_constructor_pattern(state, name)
1293
    } else {
1294
0
        Ok(Pattern::Identifier(name))
1295
    }
1296
0
}
1297
1298
/// Parse match tuple pattern: (a, b, c)
1299
/// Complexity: <7
1300
0
fn parse_match_tuple_pattern(state: &mut ParserState) -> Result<Pattern> {
1301
0
    state.tokens.expect(&Token::LeftParen)?;
1302
    
1303
    // Check for empty tuple ()
1304
0
    if matches!(state.tokens.peek(), Some((Token::RightParen, _))) {
1305
0
        state.tokens.advance();
1306
0
        return Ok(Pattern::Tuple(vec![]));
1307
0
    }
1308
    
1309
    // Parse pattern elements
1310
0
    let mut patterns = vec![parse_match_pattern(state)?];
1311
    
1312
0
    while matches!(state.tokens.peek(), Some((Token::Comma, _))) {
1313
0
        state.tokens.advance(); // consume comma
1314
0
        if matches!(state.tokens.peek(), Some((Token::RightParen, _))) {
1315
0
            break; // trailing comma
1316
0
        }
1317
0
        patterns.push(parse_match_pattern(state)?);
1318
    }
1319
    
1320
0
    state.tokens.expect(&Token::RightParen)?;
1321
0
    Ok(Pattern::Tuple(patterns))
1322
0
}
1323
1324
/// Parse list pattern in match: [], [a], [a, b], [head, ...tail]
1325
/// Complexity: <8
1326
0
fn parse_match_list_pattern(state: &mut ParserState) -> Result<Pattern> {
1327
0
    state.tokens.expect(&Token::LeftBracket)?;
1328
    
1329
    // Check for empty list []
1330
0
    if matches!(state.tokens.peek(), Some((Token::RightBracket, _))) {
1331
0
        state.tokens.advance();
1332
0
        return Ok(Pattern::List(vec![]));
1333
0
    }
1334
    
1335
    // Parse pattern elements
1336
0
    let mut patterns = vec![];
1337
    
1338
    loop {
1339
        // Check for rest pattern ...tail
1340
0
        if matches!(state.tokens.peek(), Some((Token::DotDotDot, _))) {
1341
0
            state.tokens.advance();
1342
0
            if let Some((Token::Identifier(name), _)) = state.tokens.peek() {
1343
0
                let name = name.clone();
1344
0
                state.tokens.advance();
1345
0
                patterns.push(Pattern::RestNamed(name));
1346
0
                break;
1347
0
            }
1348
0
            bail!("Expected identifier after ... in list pattern");
1349
0
        }
1350
        
1351
0
        patterns.push(parse_match_pattern(state)?);
1352
        
1353
0
        if matches!(state.tokens.peek(), Some((Token::Comma, _))) {
1354
0
            state.tokens.advance();
1355
0
            if matches!(state.tokens.peek(), Some((Token::RightBracket, _))) {
1356
0
                break; // trailing comma
1357
0
            }
1358
        } else {
1359
0
            break;
1360
        }
1361
    }
1362
    
1363
0
    state.tokens.expect(&Token::RightBracket)?;
1364
0
    Ok(Pattern::List(patterns))
1365
0
}
1366
1367
/// Parse constructor pattern: Some(x), Ok(value), etc.
1368
/// Complexity: <5
1369
0
fn parse_constructor_pattern(state: &mut ParserState, name: String) -> Result<Pattern> {
1370
0
    state.tokens.expect(&Token::LeftParen)?;
1371
    
1372
    // Parse the pattern arguments
1373
0
    let patterns = parse_constructor_arguments(state)?;
1374
    
1375
0
    state.tokens.expect(&Token::RightParen)?;
1376
    
1377
    // Delegate pattern creation to helper
1378
0
    create_constructor_pattern(name, patterns)
1379
0
}
1380
1381
/// Parse constructor arguments (complexity: 6)
1382
0
fn parse_constructor_arguments(state: &mut ParserState) -> Result<Vec<Pattern>> {
1383
    // Check for empty tuple
1384
0
    if matches!(state.tokens.peek(), Some((Token::RightParen, _))) {
1385
0
        return Ok(vec![]);
1386
0
    }
1387
    
1388
0
    let mut patterns = vec![parse_match_pattern(state)?];
1389
    
1390
    // Parse additional patterns if comma-separated
1391
0
    while matches!(state.tokens.peek(), Some((Token::Comma, _))) {
1392
0
        state.tokens.advance(); // consume comma
1393
0
        if matches!(state.tokens.peek(), Some((Token::RightParen, _))) {
1394
0
            break; // trailing comma
1395
0
        }
1396
0
        patterns.push(parse_match_pattern(state)?);
1397
    }
1398
    
1399
0
    Ok(patterns)
1400
0
}
1401
1402
/// Create appropriate pattern based on constructor name (complexity: 8)
1403
0
fn create_constructor_pattern(name: String, patterns: Vec<Pattern>) -> Result<Pattern> {
1404
0
    match (name.as_str(), patterns.len()) {
1405
0
        ("Ok", 1) => {
1406
            // Ok(pattern) - Result success case
1407
0
            Ok(Pattern::Ok(Box::new(patterns.into_iter().next().unwrap())))
1408
        }
1409
0
        ("Err", 1) => {
1410
            // Err(pattern) - Result error case
1411
0
            Ok(Pattern::Err(Box::new(patterns.into_iter().next().unwrap())))
1412
        }
1413
0
        ("Some", 1) => {
1414
            // Some(pattern) - Option success case
1415
0
            Ok(Pattern::Some(Box::new(patterns.into_iter().next().unwrap())))
1416
        }
1417
0
        ("None", 0) => {
1418
            // None - Option empty case
1419
0
            Ok(Pattern::None)
1420
        }
1421
        (_, 1) => {
1422
            // Single argument constructor - for simplicity, use the inner pattern
1423
0
            Ok(patterns.into_iter().next().unwrap())
1424
        }
1425
0
        (name, 0) => {
1426
            // Empty constructor - return as identifier
1427
0
            Ok(Pattern::Identifier(name.to_string()))
1428
        }
1429
        (_, _) => {
1430
            // Multiple arguments - use tuple pattern
1431
0
            Ok(Pattern::Tuple(patterns))
1432
        }
1433
    }
1434
0
}
1435
1436
/// Parse or-pattern: pattern | pattern | ...
1437
/// Complexity: <5
1438
0
fn parse_or_pattern(state: &mut ParserState, first: Pattern) -> Result<Pattern> {
1439
0
    let mut patterns = vec![first];
1440
    
1441
0
    while matches!(state.tokens.peek(), Some((Token::Pipe, _))) {
1442
0
        state.tokens.advance(); // consume '|'
1443
        
1444
        // Need to parse the next pattern without recursing into or-patterns again
1445
0
        let next = parse_single_pattern(state)?;
1446
0
        patterns.push(next);
1447
    }
1448
    
1449
    // Use the Or pattern variant for multiple alternatives
1450
0
    if patterns.len() == 1 {
1451
0
        Ok(patterns.into_iter().next().unwrap())
1452
    } else {
1453
0
        Ok(Pattern::Or(patterns))
1454
    }
1455
0
}
1456
1457
/// Parse a single pattern without checking for | (helper to avoid recursion)
1458
/// Complexity: <5
1459
1460
/// Parse while loop: while condition { body }
1461
/// Complexity: <5 (simple structure)
1462
0
fn parse_while_loop(state: &mut ParserState) -> Result<Expr> {
1463
0
    let start_span = state.tokens.expect(&Token::While)?;
1464
    
1465
    // Check for while-let syntax
1466
0
    if matches!(state.tokens.peek(), Some((Token::Let, _))) {
1467
0
        state.tokens.advance(); // consume 'let'
1468
        
1469
        // Parse the pattern
1470
0
        let pattern = parse_match_pattern(state)
1471
0
            .map_err(|e| anyhow::anyhow!("Expected pattern after 'while let': {}", e))?;
1472
        
1473
        // Expect '='
1474
0
        state.tokens.expect(&Token::Equal)
1475
0
            .map_err(|e| anyhow::anyhow!("Expected '=' after pattern in while-let: {}", e))?;
1476
        
1477
        // Parse the expression to match against
1478
0
        let expr = Box::new(super::parse_expr_recursive(state)
1479
0
            .map_err(|e| anyhow::anyhow!("Expected expression after '=' in while-let: {}", e))?);
1480
        
1481
        // Parse body (expect block)
1482
0
        let body = Box::new(super::parse_expr_recursive(state)
1483
0
            .map_err(|e| anyhow::anyhow!("Expected body after while-let condition: {}", e))?);
1484
        
1485
0
        Ok(Expr::new(
1486
0
            ExprKind::WhileLet {
1487
0
                pattern,
1488
0
                expr,
1489
0
                body,
1490
0
            },
1491
0
            start_span,
1492
0
        ))
1493
    } else {
1494
        // Regular while loop
1495
        // Parse condition
1496
0
        let condition = Box::new(super::parse_expr_recursive(state)
1497
0
            .map_err(|e| anyhow::anyhow!("Expected condition after 'while': {}", e))?);
1498
        
1499
        // Parse body (expect block)
1500
0
        let body = Box::new(super::parse_expr_recursive(state)
1501
0
            .map_err(|e| anyhow::anyhow!("Expected body after while condition: {}", e))?);
1502
        
1503
0
        Ok(Expr::new(
1504
0
            ExprKind::While { condition, body },
1505
0
            start_span,
1506
0
        ))
1507
    }
1508
0
}
1509
1510
/// Parse for loop: for pattern in iterator { body }
1511
/// Complexity: <5 (simple structure)
1512
0
fn parse_for_loop(state: &mut ParserState) -> Result<Expr> {
1513
0
    let start_span = state.tokens.expect(&Token::For)?;
1514
    
1515
    // Parse pattern (e.g., "i" in "for i in ...")
1516
0
    let pattern = parse_for_pattern(state)?;
1517
    
1518
    // Expect 'in' keyword
1519
0
    state.tokens.expect(&Token::In)
1520
0
        .map_err(|_| anyhow::anyhow!("Expected 'in' after for pattern"))?;
1521
    
1522
    // Parse iterator expression
1523
0
    let iterator = Box::new(super::parse_expr_recursive(state)
1524
0
        .map_err(|e| anyhow::anyhow!("Expected iterator after 'in': {}", e))?);
1525
    
1526
    // Parse body (expect block)
1527
0
    let body = Box::new(super::parse_expr_recursive(state)
1528
0
        .map_err(|e| anyhow::anyhow!("Expected body after for iterator: {}", e))?);
1529
    
1530
    // Get the var name from the pattern for backward compatibility
1531
0
    let var = pattern.primary_name();
1532
    
1533
0
    Ok(Expr::new(
1534
0
        ExprKind::For { 
1535
0
            var,
1536
0
            pattern: Some(pattern), 
1537
0
            iter: iterator, 
1538
0
            body 
1539
0
        },
1540
0
        start_span,
1541
0
    ))
1542
0
}
1543
1544
/// Parse for loop pattern (simple version)
1545
/// Complexity: <3
1546
0
fn parse_for_pattern(state: &mut ParserState) -> Result<Pattern> {
1547
0
    let Some((token, _)) = state.tokens.peek() else {
1548
0
        bail!("Expected pattern in for loop");
1549
    };
1550
    
1551
0
    match token {
1552
0
        Token::Identifier(name) => {
1553
0
            let name = name.clone();
1554
0
            state.tokens.advance();
1555
0
            Ok(Pattern::Identifier(name))
1556
        }
1557
        Token::Underscore => {
1558
0
            state.tokens.advance();
1559
0
            Ok(Pattern::Wildcard)
1560
        }
1561
        Token::LeftParen => {
1562
            // Parse tuple pattern: (x, y)
1563
0
            parse_tuple_pattern(state)
1564
        }
1565
        Token::LeftBracket => {
1566
            // Parse list pattern: [x, y]
1567
0
            parse_list_pattern(state)
1568
        }
1569
0
        _ => bail!("Expected identifier, underscore, or destructuring pattern in for loop")
1570
    }
1571
0
}
1572
1573
/// Parse an array element which might be a spread expression (...expr) or regular expression
1574
0
fn parse_array_element(state: &mut ParserState) -> Result<Expr> {
1575
0
    if matches!(state.tokens.peek(), Some((Token::DotDotDot, _))) {
1576
0
        let start_span = state.tokens.expect(&Token::DotDotDot)?; // consume ...
1577
0
        let expr = super::parse_expr_recursive(state)?;
1578
0
        Ok(Expr::new(ExprKind::Spread { expr: Box::new(expr) }, start_span))
1579
    } else {
1580
0
        super::parse_expr_recursive(state)
1581
    }
1582
0
}
1583
1584
0
fn parse_list_literal(state: &mut ParserState) -> Result<Expr> {
1585
    // Parse [ expr, expr, ... ] or [expr for var in iter if cond]
1586
0
    let start_span = state.tokens.expect(&Token::LeftBracket)?;
1587
    
1588
    // Handle empty list
1589
0
    if matches!(state.tokens.peek(), Some((Token::RightBracket, _))) {
1590
0
        state.tokens.advance();
1591
0
        return Ok(Expr::new(ExprKind::List(vec![]), start_span));
1592
0
    }
1593
    
1594
    // Parse first element/expression (might be spread)
1595
0
    let first_expr = parse_array_element(state)?;
1596
    
1597
    // Check if this is a list comprehension
1598
0
    if matches!(state.tokens.peek(), Some((Token::For, _))) {
1599
0
        return parse_list_comprehension_body(state, first_expr, start_span);
1600
0
    }
1601
    
1602
    // Regular list literal
1603
0
    let mut elements = vec![first_expr];
1604
    
1605
    // Parse remaining elements
1606
0
    while matches!(state.tokens.peek(), Some((Token::Comma, _))) {
1607
0
        state.tokens.advance();
1608
        
1609
        // Check for trailing comma
1610
0
        if matches!(state.tokens.peek(), Some((Token::RightBracket, _))) {
1611
0
            break;
1612
0
        }
1613
        
1614
0
        elements.push(parse_array_element(state)?);
1615
    }
1616
    
1617
0
    state.tokens.expect(&Token::RightBracket)
1618
0
        .map_err(|_| anyhow::anyhow!("Expected ']' to close list literal"))?;
1619
    
1620
0
    Ok(Expr::new(ExprKind::List(elements), start_span))
1621
0
}
1622
1623
0
fn parse_list_comprehension_body(
1624
0
    state: &mut ParserState,
1625
0
    expr: Expr,
1626
0
    start_span: Span,
1627
0
) -> Result<Expr> {
1628
    // Parse: for var in iter [if cond]
1629
0
    state.tokens.expect(&Token::For)?;
1630
    
1631
    // Parse variable
1632
0
    let var = if let Some((Token::Identifier(n), _)) = state.tokens.peek() {
1633
0
        let name = n.clone();
1634
0
        state.tokens.advance();
1635
0
        name
1636
    } else {
1637
0
        bail!("Expected variable name in list comprehension");
1638
    };
1639
    
1640
0
    state.tokens.expect(&Token::In)?;
1641
    
1642
    // Parse iterator
1643
0
    let iter = super::parse_expr_recursive(state)?;
1644
    
1645
    // Parse optional condition
1646
0
    let condition = if matches!(state.tokens.peek(), Some((Token::If, _))) {
1647
0
        state.tokens.advance();
1648
0
        Some(Box::new(super::parse_expr_recursive(state)?))
1649
    } else {
1650
0
        None
1651
    };
1652
    
1653
0
    state.tokens.expect(&Token::RightBracket)?;
1654
    
1655
0
    Ok(Expr::new(
1656
0
        ExprKind::ListComprehension {
1657
0
            element: Box::new(expr),
1658
0
            variable: var,
1659
0
            iterable: Box::new(iter),
1660
0
            condition,
1661
0
        },
1662
0
        start_span,
1663
0
    ))
1664
0
}
1665
1666
0
fn parse_lambda_no_params(state: &mut ParserState) -> Result<Expr> {
1667
    // Parse || body
1668
0
    let start_span = state.tokens.expect(&Token::OrOr)?;
1669
    
1670
    // Parse the body
1671
0
    let body = Box::new(super::parse_expr_recursive(state)?);
1672
    
1673
0
    Ok(Expr::new(ExprKind::Lambda { 
1674
0
        params: vec![], 
1675
0
        body 
1676
0
    }, start_span))
1677
0
}
1678
1679
0
fn parse_lambda_from_expr(state: &mut ParserState, expr: Expr, start_span: Span) -> Result<Expr> {
1680
    // Convert (x) => expr syntax
1681
0
    state.tokens.advance(); // consume =>
1682
    
1683
    // Convert the expression to a parameter
1684
0
    let param = match &expr.kind {
1685
0
        ExprKind::Identifier(name) => Param {
1686
0
            pattern: Pattern::Identifier(name.clone()),
1687
0
            ty: Type {
1688
0
                kind: TypeKind::Named("_".to_string()),
1689
0
                span: expr.span,
1690
0
            },
1691
0
            default_value: None,
1692
0
            is_mutable: false,
1693
0
            span: expr.span,
1694
0
        },
1695
0
        _ => bail!("Expected identifier in lambda parameter")
1696
    };
1697
    
1698
    // Parse the body
1699
0
    let body = Box::new(super::parse_expr_recursive(state)?);
1700
    
1701
0
    Ok(Expr::new(ExprKind::Lambda {
1702
0
        params: vec![param],
1703
0
        body,
1704
0
    }, start_span))
1705
0
}
1706
1707
0
fn parse_lambda_expression(state: &mut ParserState) -> Result<Expr> {
1708
    // Parse |param, param| body or |param| body
1709
0
    let start_span = state.tokens.expect(&Token::Pipe)?;
1710
    
1711
0
    let mut params = Vec::new();
1712
    
1713
    // Parse parameters
1714
0
    while !matches!(state.tokens.peek(), Some((Token::Pipe, _))) {
1715
0
        if let Some((Token::Identifier(name), _)) = state.tokens.peek() {
1716
0
            params.push(Pattern::Identifier(name.clone()));
1717
0
            state.tokens.advance();
1718
            
1719
            // Check for comma
1720
0
            if matches!(state.tokens.peek(), Some((Token::Comma, _))) {
1721
0
                state.tokens.advance();
1722
0
            }
1723
        } else {
1724
0
            bail!("Expected parameter name in lambda");
1725
        }
1726
    }
1727
    
1728
0
    state.tokens.expect(&Token::Pipe)
1729
0
        .map_err(|_| anyhow::anyhow!("Expected '|' after lambda parameters"))?;
1730
    
1731
    // Parse body
1732
0
    let body = Box::new(super::parse_expr_recursive(state)?);
1733
    
1734
    // Convert Pattern to Param for Lambda
1735
0
    let params = params.into_iter().map(|p| Param {
1736
0
        pattern: p,
1737
0
        ty: Type {
1738
0
            kind: TypeKind::Named("_".to_string()),
1739
0
            span: start_span,
1740
0
        },
1741
0
        span: start_span,
1742
        is_mutable: false,
1743
0
        default_value: None,
1744
0
    }).collect();
1745
    
1746
0
    Ok(Expr::new(ExprKind::Lambda { params, body }, start_span))
1747
0
}
1748
1749
0
fn parse_struct_definition(state: &mut ParserState) -> Result<Expr> {
1750
    // Parse struct Name<T> { field: Type, ... }
1751
0
    let start_span = state.tokens.expect(&Token::Struct)?;
1752
0
    let name = parse_struct_name(state)?;
1753
0
    let type_params = parse_optional_generics(state)?;
1754
0
    let struct_fields = parse_struct_fields(state)?;
1755
    
1756
0
    Ok(Expr::new(ExprKind::Struct {
1757
0
        name,
1758
0
        type_params,
1759
0
        fields: struct_fields,
1760
0
        is_pub: false,
1761
0
    }, start_span))
1762
0
}
1763
1764
/// Parse struct name identifier - complexity: 4
1765
0
fn parse_struct_name(state: &mut ParserState) -> Result<String> {
1766
0
    if let Some((Token::Identifier(n), _)) = state.tokens.peek() {
1767
0
        let name = n.clone();
1768
0
        state.tokens.advance();
1769
0
        Ok(name)
1770
    } else {
1771
0
        bail!("Expected struct name after 'struct'");
1772
    }
1773
0
}
1774
1775
/// Parse struct field definitions - complexity: 6
1776
0
fn parse_struct_fields(state: &mut ParserState) -> Result<Vec<StructField>> {
1777
0
    state.tokens.expect(&Token::LeftBrace)?;
1778
0
    let mut fields = Vec::new();
1779
    
1780
0
    while !matches!(state.tokens.peek(), Some((Token::RightBrace, _))) {
1781
0
        let (field_name, field_type) = parse_single_struct_field(state)?;
1782
0
        fields.push((field_name, field_type));
1783
        
1784
0
        if matches!(state.tokens.peek(), Some((Token::Comma, _))) {
1785
0
            state.tokens.advance();
1786
0
        }
1787
    }
1788
    
1789
0
    state.tokens.expect(&Token::RightBrace)?;
1790
    
1791
    // Convert to proper Struct variant with StructField
1792
0
    Ok(fields.into_iter().map(|(name, ty)| StructField {
1793
0
        name,
1794
0
        ty,
1795
        is_pub: false,
1796
0
    }).collect())
1797
0
}
1798
1799
/// Parse a single struct field (name: Type) - complexity: 5
1800
0
fn parse_single_struct_field(state: &mut ParserState) -> Result<(String, Type)> {
1801
0
    let field_name = if let Some((Token::Identifier(n), _)) = state.tokens.peek() {
1802
0
        let name = n.clone();
1803
0
        state.tokens.advance();
1804
0
        name
1805
    } else {
1806
0
        bail!("Expected field name in struct");
1807
    };
1808
    
1809
0
    state.tokens.expect(&Token::Colon)?;
1810
0
    let field_type = super::utils::parse_type(state)?;
1811
    
1812
0
    Ok((field_name, field_type))
1813
0
}
1814
1815
0
fn parse_trait_definition(state: &mut ParserState) -> Result<Expr> {
1816
    // Parse trait Name { fun method(self) -> Type ... }
1817
0
    let start_span = state.tokens.expect(&Token::Trait)?;
1818
    
1819
    // Get trait name
1820
0
    let name = if let Some((Token::Identifier(n), _)) = state.tokens.peek() {
1821
0
        let name = n.clone();
1822
0
        state.tokens.advance();
1823
0
        name
1824
    } else {
1825
0
        bail!("Expected trait name after 'trait'");
1826
    };
1827
    
1828
    // Parse { methods }
1829
0
    state.tokens.expect(&Token::LeftBrace)?;
1830
    
1831
0
    let mut methods = Vec::new();
1832
    
1833
    // Parse methods
1834
0
    while !matches!(state.tokens.peek(), Some((Token::RightBrace, _))) {
1835
        // Expect 'fun' keyword
1836
0
        state.tokens.expect(&Token::Fun)?;
1837
        
1838
        // Parse method name
1839
0
        let method_name = if let Some((Token::Identifier(n), _)) = state.tokens.peek() {
1840
0
            let name = n.clone();
1841
0
            state.tokens.advance();
1842
0
            name
1843
        } else {
1844
0
            bail!("Expected method name in trait");
1845
        };
1846
        
1847
        // For now, skip the rest of the method signature
1848
        // This is a simplified implementation
1849
0
        methods.push(method_name);
1850
        
1851
        // Skip to end of line or next method
1852
0
        while !matches!(state.tokens.peek(), Some((Token::Fun | Token::RightBrace, _))) 
1853
0
              && state.tokens.peek().is_some() {
1854
0
            state.tokens.advance();
1855
0
        }
1856
    }
1857
    
1858
0
    state.tokens.expect(&Token::RightBrace)?;
1859
    
1860
    // Convert to proper Trait variant with TraitMethod
1861
0
    let trait_methods = methods.into_iter().map(|name| TraitMethod {
1862
0
        name,
1863
0
        params: vec![],
1864
0
        return_type: None,
1865
0
        body: None,
1866
        is_pub: true,
1867
0
    }).collect();
1868
    
1869
0
    Ok(Expr::new(ExprKind::Trait {
1870
0
        name,
1871
0
        type_params: vec![],
1872
0
        methods: trait_methods,
1873
0
        is_pub: false,
1874
0
    }, start_span))
1875
0
}
1876
1877
0
fn parse_impl_block(state: &mut ParserState) -> Result<Expr> {
1878
0
    let start_span = state.tokens.expect(&Token::Impl)?;
1879
    
1880
    // Parse impl header (trait and type names)
1881
0
    let (trait_name, type_name) = parse_impl_header(state)?;
1882
    
1883
    // Parse impl body (methods)
1884
0
    state.tokens.expect(&Token::LeftBrace)?;
1885
0
    skip_impl_body(state)?;
1886
0
    state.tokens.expect(&Token::RightBrace)?;
1887
    
1888
0
    Ok(Expr::new(ExprKind::Impl {
1889
0
        type_params: vec![],
1890
0
        trait_name,
1891
0
        for_type: type_name,
1892
0
        methods: vec![],
1893
0
        is_pub: false,
1894
0
    }, start_span))
1895
0
}
1896
1897
/// Parse impl header to get trait and type names (complexity: 8)
1898
0
fn parse_impl_header(state: &mut ParserState) -> Result<(Option<String>, String)> {
1899
    // Parse first identifier (trait or type name)
1900
0
    let first_name = parse_optional_identifier(state);
1901
    
1902
    // Check for "for" keyword to determine if first was trait
1903
0
    if matches!(state.tokens.peek(), Some((Token::For, _))) {
1904
0
        state.tokens.advance();
1905
0
        let type_name = parse_required_identifier(state, "type name after 'for' in impl")?;
1906
0
        Ok((first_name, type_name))
1907
0
    } else if let Some(type_name) = first_name {
1908
        // impl Type { ... } case
1909
0
        Ok((None, type_name))
1910
    } else {
1911
0
        bail!("Expected type or trait name in impl");
1912
    }
1913
0
}
1914
1915
/// Parse optional identifier (complexity: 3)
1916
0
fn parse_optional_identifier(state: &mut ParserState) -> Option<String> {
1917
0
    if let Some((Token::Identifier(n), _)) = state.tokens.peek() {
1918
0
        let name = n.clone();
1919
0
        state.tokens.advance();
1920
0
        Some(name)
1921
    } else {
1922
0
        None
1923
    }
1924
0
}
1925
1926
/// Parse required identifier with error message (complexity: 3)
1927
0
fn parse_required_identifier(state: &mut ParserState, context: &str) -> Result<String> {
1928
0
    if let Some((Token::Identifier(n), _)) = state.tokens.peek() {
1929
0
        let name = n.clone();
1930
0
        state.tokens.advance();
1931
0
        Ok(name)
1932
    } else {
1933
0
        bail!("Expected {}", context)
1934
    }
1935
0
}
1936
1937
/// Skip impl body by tracking brace depth (complexity: 5)
1938
0
fn skip_impl_body(state: &mut ParserState) -> Result<()> {
1939
0
    let mut depth = 1;
1940
0
    while depth > 0 && state.tokens.peek().is_some() {
1941
0
        match state.tokens.peek() {
1942
0
            Some((Token::LeftBrace, _)) => depth += 1,
1943
0
            Some((Token::RightBrace, _)) => depth -= 1,
1944
0
            _ => {}
1945
        }
1946
0
        if depth > 0 {
1947
0
            state.tokens.advance();
1948
0
        }
1949
    }
1950
0
    Ok(())
1951
0
}
1952
1953
0
fn parse_import_statement(state: &mut ParserState) -> Result<Expr> {
1954
    // Parse import path::to::module
1955
0
    let start_span = state.tokens.expect(&Token::Import)?;
1956
    
1957
    // Parse module path
1958
0
    let mut path_parts = Vec::new();
1959
    
1960
    // Get first identifier
1961
0
    if let Some((Token::Identifier(name), _)) = state.tokens.peek() {
1962
0
        path_parts.push(name.clone());
1963
0
        state.tokens.advance();
1964
0
    } else {
1965
0
        bail!("Expected module path after 'import'");
1966
    }
1967
    
1968
    // Parse additional path segments
1969
0
    while matches!(state.tokens.peek(), Some((Token::ColonColon, _))) {
1970
0
        state.tokens.advance(); // consume ::
1971
0
        if let Some((Token::Identifier(name), _)) = state.tokens.peek() {
1972
0
            path_parts.push(name.clone());
1973
0
            state.tokens.advance();
1974
0
        } else {
1975
0
            bail!("Expected identifier after '::'");
1976
        }
1977
    }
1978
    
1979
0
    let path = path_parts.join("::");
1980
    
1981
0
    Ok(Expr::new(ExprKind::Import {
1982
0
        path,
1983
0
        items: vec![],
1984
0
    }, start_span))
1985
0
}
1986
1987
0
fn parse_use_statement(state: &mut ParserState) -> Result<Expr> {
1988
    // Parse use path::to::Type or use path::to::{Type1, Type2}
1989
0
    let start_span = state.tokens.expect(&Token::Use)?;
1990
    
1991
    // Parse module path
1992
0
    let mut path_parts = Vec::new();
1993
    
1994
    // Get first identifier
1995
0
    if let Some((Token::Identifier(name), _)) = state.tokens.peek() {
1996
0
        path_parts.push(name.clone());
1997
0
        state.tokens.advance();
1998
0
    } else {
1999
0
        bail!("Expected module path after 'use'");
2000
    }
2001
    
2002
    // Parse additional path segments
2003
0
    while matches!(state.tokens.peek(), Some((Token::ColonColon, _))) {
2004
0
        state.tokens.advance(); // consume ::
2005
        
2006
        // Check for { imports }
2007
0
        if matches!(state.tokens.peek(), Some((Token::LeftBrace, _))) {
2008
0
            state.tokens.advance();
2009
0
            let mut items = Vec::new();
2010
            
2011
            // Parse imported items
2012
0
            while !matches!(state.tokens.peek(), Some((Token::RightBrace, _))) {
2013
0
                if let Some((Token::Identifier(name), _)) = state.tokens.peek() {
2014
0
                    items.push(ImportItem::Named(name.clone()));
2015
0
                    state.tokens.advance();
2016
                    
2017
                    // Check for comma
2018
0
                    if matches!(state.tokens.peek(), Some((Token::Comma, _))) {
2019
0
                        state.tokens.advance();
2020
0
                    }
2021
                } else {
2022
0
                    bail!("Expected identifier in import list");
2023
                }
2024
            }
2025
            
2026
0
            state.tokens.expect(&Token::RightBrace)?;
2027
            
2028
0
            let path = path_parts.join("::");
2029
0
            return Ok(Expr::new(ExprKind::Import { path, items }, start_span));
2030
0
        } else if let Some((Token::Identifier(name), _)) = state.tokens.peek() {
2031
0
            path_parts.push(name.clone());
2032
0
            state.tokens.advance();
2033
0
        } else {
2034
0
            bail!("Expected identifier or '{{' after '::'");
2035
        }
2036
    }
2037
    
2038
    // Simple use statement (use fully::qualified::Name)
2039
0
    let path = path_parts.join("::");
2040
0
    let last_part = path_parts.last().unwrap().clone();
2041
    
2042
0
    Ok(Expr::new(ExprKind::Import {
2043
0
        path,
2044
0
        items: vec![ImportItem::Named(last_part)],
2045
0
    }, start_span))
2046
0
}
2047
2048
0
fn parse_dataframe_literal(state: &mut ParserState) -> Result<Expr> {
2049
    // Parse df![...] macro syntax - DataFrame token already consumed by caller
2050
0
    let start_span = parse_dataframe_header(state)?;
2051
0
    let columns = parse_dataframe_columns(state)?;
2052
0
    state.tokens.expect(&Token::RightBracket)?;
2053
    
2054
    // Convert to DataFrame expression
2055
0
    let df_columns = create_dataframe_columns(columns);
2056
0
    Ok(Expr::new(ExprKind::DataFrame { columns: df_columns }, start_span))
2057
0
}
2058
2059
/// Parse dataframe header: df![
2060
/// Complexity: 3
2061
0
fn parse_dataframe_header(state: &mut ParserState) -> Result<Span> {
2062
0
    let start_span = state.tokens.expect(&Token::DataFrame)?;
2063
0
    state.tokens.expect(&Token::Bang)?;
2064
0
    state.tokens.expect(&Token::LeftBracket)?;
2065
0
    Ok(start_span)
2066
0
}
2067
2068
/// Parse all dataframe columns
2069
/// Complexity: <5
2070
0
fn parse_dataframe_columns(state: &mut ParserState) -> Result<Vec<(String, Expr)>> {
2071
0
    let mut columns = Vec::new();
2072
    
2073
0
    while !matches!(state.tokens.peek(), Some((Token::RightBracket, _))) {
2074
0
        let column = parse_single_dataframe_column(state)?;
2075
0
        columns.push(column);
2076
        
2077
        // Check for comma separator
2078
0
        if matches!(state.tokens.peek(), Some((Token::Comma, _))) {
2079
0
            state.tokens.advance();
2080
0
        }
2081
    }
2082
    
2083
0
    Ok(columns)
2084
0
}
2085
2086
/// Parse a single dataframe column: "name" => [values]
2087
/// Complexity: <5
2088
0
fn parse_single_dataframe_column(state: &mut ParserState) -> Result<(String, Expr)> {
2089
0
    let col_name = parse_dataframe_column_name(state)?;
2090
0
    state.tokens.expect(&Token::FatArrow)?;
2091
0
    let values = parse_dataframe_column_values(state)?;
2092
0
    Ok((col_name, values))
2093
0
}
2094
2095
/// Parse dataframe column name (string or identifier)
2096
/// Complexity: 3
2097
0
fn parse_dataframe_column_name(state: &mut ParserState) -> Result<String> {
2098
0
    match state.tokens.peek() {
2099
0
        Some((Token::String(name), _)) => {
2100
0
            let name = name.clone();
2101
0
            state.tokens.advance();
2102
0
            Ok(name)
2103
        }
2104
0
        Some((Token::Identifier(name), _)) => {
2105
0
            let name = name.clone();
2106
0
            state.tokens.advance();
2107
0
            Ok(name)
2108
        }
2109
0
        _ => bail!("Expected column name (string or identifier) in dataframe")
2110
    }
2111
0
}
2112
2113
/// Parse dataframe column values (must be a list)
2114
/// Complexity: 2
2115
0
fn parse_dataframe_column_values(state: &mut ParserState) -> Result<Expr> {
2116
0
    if matches!(state.tokens.peek(), Some((Token::LeftBracket, _))) {
2117
0
        parse_list_literal(state)
2118
    } else {
2119
0
        bail!("Expected list of values after => in dataframe column")
2120
    }
2121
0
}
2122
2123
/// Convert parsed columns to `DataFrameColumn` structs
2124
/// Complexity: <5
2125
0
fn create_dataframe_columns(columns: Vec<(String, Expr)>) -> Vec<DataFrameColumn> {
2126
0
    columns.into_iter().map(|(name, values)| {
2127
0
        let value_exprs = match values.kind {
2128
0
            ExprKind::List(exprs) => exprs,
2129
0
            _ => vec![values], // Fallback for non-list
2130
        };
2131
0
        DataFrameColumn {
2132
0
            name,
2133
0
            values: value_exprs,
2134
0
        }
2135
0
    }).collect()
2136
0
}
2137
2138
0
fn parse_enum_definition(state: &mut ParserState) -> Result<Expr> {
2139
0
    let start_span = state.tokens.expect(&Token::Enum)?;
2140
0
    let name = parse_enum_name(state)?;
2141
0
    let type_params = parse_optional_generics(state)?;
2142
0
    let variants = parse_enum_variants(state)?;
2143
    
2144
0
    Ok(Expr::new(ExprKind::Enum {
2145
0
        name,
2146
0
        type_params,
2147
0
        variants,
2148
0
        is_pub: false,
2149
0
    }, start_span))
2150
0
}
2151
2152
0
fn parse_enum_name(state: &mut ParserState) -> Result<String> {
2153
0
    match state.tokens.peek() {
2154
0
        Some((Token::Identifier(n), _)) => {
2155
0
            let name = n.clone();
2156
0
            state.tokens.advance();
2157
0
            Ok(name)
2158
        }
2159
        Some((Token::Option, _)) => {
2160
0
            state.tokens.advance();
2161
0
            Ok("Option".to_string())
2162
        }
2163
        Some((Token::Result, _)) => {
2164
0
            state.tokens.advance();
2165
0
            Ok("Result".to_string())
2166
        }
2167
0
        _ => bail!("Expected enum name after 'enum'")
2168
    }
2169
0
}
2170
2171
0
fn parse_optional_generics(state: &mut ParserState) -> Result<Vec<String>> {
2172
0
    if matches!(state.tokens.peek(), Some((Token::Less, _))) {
2173
0
        parse_generic_params(state)
2174
    } else {
2175
0
        Ok(vec![])
2176
    }
2177
0
}
2178
2179
0
fn parse_enum_variants(state: &mut ParserState) -> Result<Vec<EnumVariant>> {
2180
0
    state.tokens.expect(&Token::LeftBrace)?;
2181
0
    let mut variants = Vec::new();
2182
    
2183
0
    while !matches!(state.tokens.peek(), Some((Token::RightBrace, _))) {
2184
0
        variants.push(parse_single_variant(state)?);
2185
        
2186
0
        if matches!(state.tokens.peek(), Some((Token::Comma, _))) {
2187
0
            state.tokens.advance();
2188
0
        }
2189
    }
2190
    
2191
0
    state.tokens.expect(&Token::RightBrace)?;
2192
0
    Ok(variants)
2193
0
}
2194
2195
0
fn parse_single_variant(state: &mut ParserState) -> Result<EnumVariant> {
2196
0
    let variant_name = parse_variant_name(state)?;
2197
    
2198
    // Check for discriminant value: = <integer>
2199
0
    let discriminant = if matches!(state.tokens.peek(), Some((Token::Equal, _))) {
2200
0
        state.tokens.advance(); // consume =
2201
0
        parse_variant_discriminant(state)?
2202
    } else {
2203
0
        None
2204
    };
2205
    
2206
    // Check for fields (tuple variants)
2207
0
    let fields = if discriminant.is_none() {
2208
0
        parse_variant_fields(state)?
2209
    } else {
2210
0
        None // Can't have both discriminant and fields
2211
    };
2212
    
2213
0
    Ok(EnumVariant {
2214
0
        name: variant_name,
2215
0
        fields,
2216
0
        discriminant,
2217
0
    })
2218
0
}
2219
2220
/// Parse discriminant value for enum variant
2221
/// Complexity: <5
2222
0
fn parse_variant_discriminant(state: &mut ParserState) -> Result<Option<i64>> {
2223
0
    match state.tokens.peek() {
2224
0
        Some((Token::Integer(val), _)) => {
2225
0
            let value = *val;
2226
0
            state.tokens.advance();
2227
0
            Ok(Some(value))
2228
        }
2229
        Some((Token::Minus, _)) => {
2230
0
            state.tokens.advance(); // consume -
2231
0
            match state.tokens.peek() {
2232
0
                Some((Token::Integer(val), _)) => {
2233
0
                    let value = -(*val);
2234
0
                    state.tokens.advance();
2235
0
                    Ok(Some(value))
2236
                }
2237
0
                _ => bail!("Expected integer after - in enum discriminant")
2238
            }
2239
        }
2240
0
        _ => bail!("Expected integer value for enum discriminant")
2241
    }
2242
0
}
2243
2244
0
fn parse_variant_name(state: &mut ParserState) -> Result<String> {
2245
0
    match state.tokens.peek() {
2246
0
        Some((Token::Identifier(n), _)) => {
2247
0
            let name = n.clone();
2248
0
            state.tokens.advance();
2249
0
            Ok(name)
2250
        }
2251
        Some((Token::Some, _)) => {
2252
0
            state.tokens.advance();
2253
0
            Ok("Some".to_string())
2254
        }
2255
        Some((Token::None, _)) => {
2256
0
            state.tokens.advance();
2257
0
            Ok("None".to_string())
2258
        }
2259
        Some((Token::Ok, _)) => {
2260
0
            state.tokens.advance();
2261
0
            Ok("Ok".to_string())
2262
        }
2263
        Some((Token::Err, _)) => {
2264
0
            state.tokens.advance();
2265
0
            Ok("Err".to_string())
2266
        }
2267
0
        _ => bail!("Expected variant name in enum")
2268
    }
2269
0
}
2270
2271
0
fn parse_variant_fields(state: &mut ParserState) -> Result<Option<Vec<Type>>> {
2272
0
    if !matches!(state.tokens.peek(), Some((Token::LeftParen, _))) {
2273
0
        return Ok(None);
2274
0
    }
2275
    
2276
0
    state.tokens.advance();
2277
0
    let mut field_types = Vec::new();
2278
    
2279
0
    while !matches!(state.tokens.peek(), Some((Token::RightParen, _))) {
2280
0
        field_types.push(super::utils::parse_type(state)?);
2281
        
2282
0
        if matches!(state.tokens.peek(), Some((Token::Comma, _))) {
2283
0
            state.tokens.advance();
2284
0
        }
2285
    }
2286
    
2287
0
    state.tokens.expect(&Token::RightParen)?;
2288
0
    Ok(Some(field_types))
2289
0
}
2290
2291
0
fn parse_generic_params(state: &mut ParserState) -> Result<Vec<String>> {
2292
    // Parse <T, U, ...>
2293
0
    state.tokens.expect(&Token::Less)?;
2294
0
    let mut params = Vec::new();
2295
    
2296
0
    while !matches!(state.tokens.peek(), Some((Token::Greater, _))) {
2297
0
        if let Some((Token::Identifier(name), _)) = state.tokens.peek() {
2298
0
            params.push(name.clone());
2299
0
            state.tokens.advance();
2300
            
2301
            // Check for comma
2302
0
            if matches!(state.tokens.peek(), Some((Token::Comma, _))) {
2303
0
                state.tokens.advance();
2304
0
            }
2305
        } else {
2306
0
            bail!("Expected type parameter name");
2307
        }
2308
    }
2309
    
2310
0
    state.tokens.expect(&Token::Greater)?;
2311
0
    Ok(params)
2312
0
}
2313
2314
0
fn parse_actor_definition(state: &mut ParserState) -> Result<Expr> {
2315
    // Parse actor Name { state: fields, receive handlers }
2316
0
    let start_span = state.tokens.expect(&Token::Actor)?;
2317
    
2318
    // Get actor name
2319
0
    let name = parse_actor_name(state)?;
2320
    
2321
    // Parse { body }
2322
0
    state.tokens.expect(&Token::LeftBrace)?;
2323
    
2324
    // Parse actor body components
2325
0
    let (state_fields, handlers) = parse_actor_body(state)?;
2326
    
2327
0
    state.tokens.expect(&Token::RightBrace)?;
2328
    
2329
    // Create the actor expression
2330
0
    create_actor_expression(name, state_fields, handlers, start_span)
2331
0
}
2332
2333
/// Parse actor name
2334
/// Extracted from `parse_actor_definition` to reduce complexity
2335
0
fn parse_actor_name(state: &mut ParserState) -> Result<String> {
2336
0
    if let Some((Token::Identifier(n), _)) = state.tokens.peek() {
2337
0
        let name = n.clone();
2338
0
        state.tokens.advance();
2339
0
        Ok(name)
2340
    } else {
2341
0
        bail!("Expected actor name after 'actor'");
2342
    }
2343
0
}
2344
2345
/// Parse actor body including state fields and handlers
2346
/// Extracted from `parse_actor_definition` to reduce complexity
2347
0
fn parse_actor_body(state: &mut ParserState) -> Result<(Vec<(String, Type, Option<Box<Expr>>)>, Vec<String>)> {
2348
0
    let mut state_fields = Vec::new();
2349
0
    let mut handlers = Vec::new();
2350
    
2351
0
    while !matches!(state.tokens.peek(), Some((Token::RightBrace, _))) {
2352
0
        match state.tokens.peek() {
2353
            Some((Token::State, _)) => {
2354
0
                let field = parse_actor_state_field(state)?;
2355
0
                state_fields.push(field);
2356
            }
2357
            Some((Token::Receive, _)) => {
2358
0
                let new_handlers = parse_actor_receive_block(state)?;
2359
0
                handlers.extend(new_handlers);
2360
            }
2361
            Some((Token::Identifier(_), _)) => {
2362
0
                let field = parse_actor_bare_field(state)?;
2363
0
                state_fields.push(field);
2364
            }
2365
0
            _ => {
2366
0
                // Skip unknown tokens
2367
0
                state.tokens.advance();
2368
0
            }
2369
        }
2370
    }
2371
    
2372
0
    Ok((state_fields, handlers))
2373
0
}
2374
2375
/// Parse state field with 'state' keyword
2376
/// Extracted from `parse_actor_body` to reduce complexity
2377
0
fn parse_actor_state_field(state: &mut ParserState) -> Result<(String, Type, Option<Box<Expr>>)> {
2378
0
    state.tokens.advance(); // consume 'state'
2379
    
2380
0
    if let Some((Token::Identifier(field_name), _)) = state.tokens.peek() {
2381
0
        let field = field_name.clone();
2382
0
        state.tokens.advance();
2383
        
2384
        // Parse : Type
2385
0
        state.tokens.expect(&Token::Colon)?;
2386
0
        let field_type = super::utils::parse_type(state)?;
2387
        
2388
        // Optional = initial_value
2389
0
        let initial_value = if matches!(state.tokens.peek(), Some((Token::Equal, _))) {
2390
0
            state.tokens.advance();
2391
0
            Some(Box::new(super::parse_expr_recursive(state)?))
2392
        } else {
2393
0
            None
2394
        };
2395
        
2396
0
        Ok((field, field_type, initial_value))
2397
    } else {
2398
0
        bail!("Expected field name after 'state'");
2399
    }
2400
0
}
2401
2402
/// Parse receive block with handlers
2403
/// Extracted from `parse_actor_body` to reduce complexity
2404
0
fn parse_actor_receive_block(state: &mut ParserState) -> Result<Vec<String>> {
2405
0
    state.tokens.advance(); // consume 'receive'
2406
0
    state.tokens.expect(&Token::LeftBrace)?;
2407
    
2408
0
    let mut handlers = Vec::new();
2409
    
2410
0
    while !matches!(state.tokens.peek(), Some((Token::RightBrace, _))) {
2411
0
        if let Some((Token::Identifier(handler_name), _)) = state.tokens.peek() {
2412
0
            handlers.push(handler_name.clone());
2413
0
            state.tokens.advance();
2414
            
2415
            // Skip => value for now
2416
0
            state.tokens.expect(&Token::FatArrow)?;
2417
0
            super::parse_expr_recursive(state)?; // Skip the value
2418
            
2419
            // Optional comma
2420
0
            if matches!(state.tokens.peek(), Some((Token::Comma, _))) {
2421
0
                state.tokens.advance();
2422
0
            }
2423
        } else {
2424
0
            bail!("Expected handler name in receive block");
2425
        }
2426
    }
2427
    
2428
0
    state.tokens.expect(&Token::RightBrace)?;
2429
0
    Ok(handlers)
2430
0
}
2431
2432
/// Parse bare field definition
2433
/// Extracted from `parse_actor_body` to reduce complexity
2434
0
fn parse_actor_bare_field(state: &mut ParserState) -> Result<(String, Type, Option<Box<Expr>>)> {
2435
0
    if let Some((Token::Identifier(field_name), _)) = state.tokens.peek() {
2436
0
        let field = field_name.clone();
2437
0
        state.tokens.advance();
2438
        
2439
        // Parse : Type
2440
0
        state.tokens.expect(&Token::Colon)?;
2441
0
        let field_type = super::utils::parse_type(state)?;
2442
        
2443
        // Optional comma
2444
0
        if matches!(state.tokens.peek(), Some((Token::Comma, _))) {
2445
0
            state.tokens.advance();
2446
0
        }
2447
        
2448
0
        Ok((field, field_type, None))
2449
    } else {
2450
0
        bail!("Expected field name in actor");
2451
    }
2452
0
}
2453
2454
/// Create the final actor expression
2455
/// Extracted from `parse_actor_definition` to reduce complexity
2456
0
fn create_actor_expression(
2457
0
    name: String,
2458
0
    state_fields: Vec<(String, Type, Option<Box<Expr>>)>,
2459
0
    handlers: Vec<String>,
2460
0
    start_span: Span,
2461
0
) -> Result<Expr> {
2462
    // Create an Actor expression with proper types
2463
0
    let actor_state = state_fields.into_iter().map(|(name, ty, _init)| StructField {
2464
0
        name,
2465
0
        ty,
2466
        is_pub: false,
2467
0
    }).collect();
2468
    
2469
    // For now, create simple handlers
2470
0
    let actor_handlers = handlers.into_iter().map(|name| ActorHandler {
2471
0
        message_type: name,
2472
0
        params: vec![],
2473
0
        body: Box::new(Expr::new(ExprKind::Block(vec![]), start_span)),
2474
0
    }).collect();
2475
    
2476
0
    Ok(Expr::new(ExprKind::Actor { 
2477
0
        name, 
2478
0
        state: actor_state,
2479
0
        handlers: actor_handlers,
2480
0
    }, start_span))
2481
0
}
2482
2483
0
pub fn token_to_binary_op(token: &Token) -> Option<BinaryOp> {
2484
    // Try each category of operators
2485
0
    map_arithmetic_operator(token)
2486
0
        .or_else(|| map_comparison_operator(token))
2487
0
        .or_else(|| map_logical_operator(token))
2488
0
        .or_else(|| map_bitwise_operator(token))
2489
0
}
2490
2491
/// Map arithmetic tokens to binary operators
2492
/// Extracted from `token_to_binary_op` to reduce complexity
2493
0
fn map_arithmetic_operator(token: &Token) -> Option<BinaryOp> {
2494
0
    match token {
2495
0
        Token::Plus => Some(BinaryOp::Add),
2496
0
        Token::Minus => Some(BinaryOp::Subtract),
2497
0
        Token::Star => Some(BinaryOp::Multiply),
2498
0
        Token::Slash => Some(BinaryOp::Divide),
2499
0
        Token::Percent => Some(BinaryOp::Modulo),
2500
0
        Token::Power => Some(BinaryOp::Power),
2501
0
        _ => None,
2502
    }
2503
0
}
2504
2505
/// Map comparison tokens to binary operators
2506
/// Extracted from `token_to_binary_op` to reduce complexity
2507
0
fn map_comparison_operator(token: &Token) -> Option<BinaryOp> {
2508
0
    match token {
2509
0
        Token::EqualEqual => Some(BinaryOp::Equal),
2510
0
        Token::NotEqual => Some(BinaryOp::NotEqual),
2511
0
        Token::Less => Some(BinaryOp::Less),
2512
0
        Token::LessEqual => Some(BinaryOp::LessEqual),
2513
0
        Token::Greater => Some(BinaryOp::Greater),
2514
0
        Token::GreaterEqual => Some(BinaryOp::GreaterEqual),
2515
0
        _ => None,
2516
    }
2517
0
}
2518
2519
/// Map logical tokens to binary operators
2520
/// Extracted from `token_to_binary_op` to reduce complexity
2521
0
fn map_logical_operator(token: &Token) -> Option<BinaryOp> {
2522
0
    match token {
2523
0
        Token::AndAnd => Some(BinaryOp::And),
2524
0
        Token::OrOr => Some(BinaryOp::Or),
2525
0
        Token::NullCoalesce => Some(BinaryOp::NullCoalesce),
2526
0
        _ => None,
2527
    }
2528
0
}
2529
2530
/// Map bitwise tokens to binary operators
2531
/// Extracted from `token_to_binary_op` to reduce complexity
2532
0
fn map_bitwise_operator(token: &Token) -> Option<BinaryOp> {
2533
0
    match token {
2534
0
        Token::Ampersand => Some(BinaryOp::BitwiseAnd),
2535
0
        Token::Pipe => Some(BinaryOp::BitwiseOr),
2536
0
        Token::Caret => Some(BinaryOp::BitwiseXor),
2537
0
        Token::LeftShift => Some(BinaryOp::LeftShift),
2538
0
        _ => None,
2539
    }
2540
0
}
2541
2542
0
pub fn get_precedence(op: BinaryOp) -> i32 {
2543
0
    match op {
2544
0
        BinaryOp::Or => 1,
2545
0
        BinaryOp::NullCoalesce => 2,
2546
0
        BinaryOp::And => 3,
2547
0
        BinaryOp::BitwiseOr => 4,
2548
0
        BinaryOp::BitwiseXor => 5,
2549
0
        BinaryOp::BitwiseAnd => 6,
2550
0
        BinaryOp::Equal | BinaryOp::NotEqual => 7,
2551
0
        BinaryOp::Less | BinaryOp::LessEqual | BinaryOp::Greater | BinaryOp::GreaterEqual => 8,
2552
0
        BinaryOp::LeftShift => 9,
2553
0
        BinaryOp::Add | BinaryOp::Subtract => 10,
2554
0
        BinaryOp::Multiply | BinaryOp::Divide | BinaryOp::Modulo => 11,
2555
0
        BinaryOp::Power => 12,
2556
    }
2557
0
}
2558
2559
/// Parse f-string content into interpolation parts
2560
0
fn parse_fstring_into_parts(input: &str) -> Result<Vec<StringPart>> {
2561
    use crate::frontend::parser::Parser;
2562
    
2563
0
    let mut parts = Vec::new();
2564
0
    let mut current = String::new();
2565
0
    let mut chars = input.chars().peekable();
2566
    
2567
0
    while let Some(ch) = chars.next() {
2568
0
        if ch == '{' {
2569
0
            if chars.peek() == Some(&'{') {
2570
0
                // Escaped brace
2571
0
                chars.next();
2572
0
                current.push('{');
2573
0
            } else {
2574
                // Save text part if any
2575
0
                if !current.is_empty() {
2576
0
                    parts.push(StringPart::Text(current.clone()));
2577
0
                    current.clear();
2578
0
                }
2579
                
2580
                // Extract and parse expression
2581
0
                let expr_str = extract_fstring_expr(&mut chars)?;
2582
0
                let mut parser = Parser::new(&expr_str);
2583
0
                let expr = parser.parse_expr()?;
2584
0
                parts.push(StringPart::Expr(Box::new(expr)));
2585
            }
2586
0
        } else if ch == '}' {
2587
0
            if chars.peek() == Some(&'}') {
2588
0
                // Escaped brace
2589
0
                chars.next();
2590
0
                current.push('}');
2591
0
            } else {
2592
0
                bail!("Unmatched '}}' in f-string");
2593
            }
2594
0
        } else {
2595
0
            current.push(ch);
2596
0
        }
2597
    }
2598
    
2599
    // Add remaining text
2600
0
    if !current.is_empty() {
2601
0
        parts.push(StringPart::Text(current));
2602
0
    }
2603
    
2604
0
    Ok(parts)
2605
0
}
2606
2607
/// Extract expression from f-string between braces
2608
0
fn extract_fstring_expr(chars: &mut std::iter::Peekable<std::str::Chars>) -> Result<String> {
2609
0
    let mut expr = String::new();
2610
0
    let mut depth = 1;
2611
    
2612
0
    for ch in chars.by_ref() {
2613
0
        if ch == '{' {
2614
0
            depth += 1;
2615
0
            expr.push(ch);
2616
0
        } else if ch == '}' {
2617
0
            depth -= 1;
2618
0
            if depth == 0 {
2619
0
                return Ok(expr);
2620
0
            }
2621
0
            expr.push(ch);
2622
0
        } else {
2623
0
            expr.push(ch);
2624
0
        }
2625
    }
2626
    
2627
0
    bail!("Unclosed interpolation in f-string")
2628
0
}
2629
2630
/// Helper for parsing try block (complexity: 3)
2631
0
fn parse_try_block(state: &mut ParserState) -> Result<Box<Expr>> {
2632
0
    state.tokens.expect(&Token::LeftBrace)?;
2633
0
    Ok(Box::new(super::collections::parse_block(state)?))
2634
0
}
2635
2636
/// Helper for parsing catch clauses (complexity: 8)
2637
0
fn parse_catch_clauses(state: &mut ParserState) -> Result<Vec<crate::frontend::ast::CatchClause>> {
2638
    use crate::frontend::ast::CatchClause;
2639
0
    let mut catch_clauses = Vec::new();
2640
    
2641
0
    while matches!(state.tokens.peek(), Some((Token::Catch, _))) {
2642
0
        state.tokens.advance(); // consume 'catch'
2643
        
2644
0
        let pattern = parse_catch_pattern(state)?;
2645
0
        let body = parse_catch_body(state)?;
2646
        
2647
0
        catch_clauses.push(CatchClause { pattern, body });
2648
    }
2649
    
2650
0
    Ok(catch_clauses)
2651
0
}
2652
2653
/// Helper for parsing catch pattern (complexity: 5)
2654
0
fn parse_catch_pattern(state: &mut ParserState) -> Result<Pattern> {
2655
0
    state.tokens.expect(&Token::LeftParen)?;
2656
0
    let pattern = if let Some((Token::Identifier(name), _)) = state.tokens.peek() {
2657
0
        let name = name.clone();
2658
0
        state.tokens.advance();
2659
0
        Pattern::Identifier(name)
2660
    } else {
2661
0
        bail!("Expected identifier in catch clause");
2662
    };
2663
0
    state.tokens.expect(&Token::RightParen)?;
2664
0
    Ok(pattern)
2665
0
}
2666
2667
/// Helper for parsing catch body (complexity: 3)
2668
0
fn parse_catch_body(state: &mut ParserState) -> Result<Box<Expr>> {
2669
0
    state.tokens.expect(&Token::LeftBrace)?;
2670
0
    Ok(Box::new(super::collections::parse_block(state)?))
2671
0
}
2672
2673
/// Helper for parsing optional finally block (complexity: 6)
2674
0
fn parse_finally_block(state: &mut ParserState) -> Result<Option<Box<Expr>>> {
2675
0
    if matches!(state.tokens.peek(), Some((Token::Finally, _))) {
2676
0
        state.tokens.advance(); // consume 'finally'
2677
0
        state.tokens.expect(&Token::LeftBrace)?;
2678
0
        Ok(Some(Box::new(super::collections::parse_block(state)?)))
2679
    } else {
2680
0
        Ok(None)
2681
    }
2682
0
}
2683
2684
/// Helper for validating try-catch structure (complexity: 3)
2685
0
fn validate_try_catch_structure(
2686
0
    catch_clauses: &[crate::frontend::ast::CatchClause], 
2687
0
    finally_block: Option<&Expr>
2688
0
) -> Result<()> {
2689
0
    if catch_clauses.is_empty() && finally_block.is_none() {
2690
0
        bail!("Try block must have at least one catch clause or a finally block");
2691
0
    }
2692
0
    Ok(())
2693
0
}