Skip to main content

virtual_rust/
parser.rs

1//! Recursive-descent parser that transforms a token stream into an AST.
2//!
3//! # Operator Precedence (lowest → highest)
4//!
5//! 1. Assignment (`=`, `+=`, `-=`, …)
6//! 2. Logical OR (`||`)
7//! 3. Logical AND (`&&`)
8//! 4. Comparison (`==`, `!=`, `<`, `>`, `<=`, `>=`)
9//! 5. Bitwise OR (`|`)
10//! 6. Bitwise XOR (`^`)
11//! 7. Bitwise AND (`&`)
12//! 8. Shift (`<<`, `>>`)
13//! 9. Additive (`+`, `-`)
14//! 10. Multiplicative (`*`, `/`, `%`)
15//! 11. Type cast (`as`)
16//! 12. Unary (`-`, `!`, `&`, `*`)
17//! 13. Postfix (`.method()`, `[index]`, `(args)`)
18//! 14. Primary (literals, identifiers, blocks, closures)
19
20use crate::ast::*;
21use crate::token::Token;
22
23/// Recursive-descent parser for a subset of Rust syntax.
24pub struct Parser {
25    tokens: Vec<Token>,
26    pos: usize,
27}
28
29/// A parse-time error with a human-readable message.
30#[derive(Debug)]
31pub struct ParseError {
32    pub message: String,
33}
34
35impl ParseError {
36    fn new(message: impl Into<String>) -> Self {
37        ParseError {
38            message: message.into(),
39        }
40    }
41}
42
43impl std::fmt::Display for ParseError {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        write!(f, "Parse error: {}", self.message)
46    }
47}
48
49// ── Token navigation ─────────────────────────────────────────────────────
50
51impl Parser {
52    pub fn new(tokens: Vec<Token>) -> Self {
53        Parser { tokens, pos: 0 }
54    }
55
56    /// Returns the current token without advancing.
57    fn current(&self) -> &Token {
58        self.tokens.get(self.pos).unwrap_or(&Token::Eof)
59    }
60
61    /// Returns the next token (one ahead) without advancing.
62    fn peek(&self) -> &Token {
63        self.tokens.get(self.pos + 1).unwrap_or(&Token::Eof)
64    }
65
66    /// Consumes and returns the current token.
67    fn advance(&mut self) -> Token {
68        let tok = self.current().clone();
69        self.pos += 1;
70        tok
71    }
72
73    /// Consumes the current token if it matches `expected`, otherwise errors.
74    fn expect(&mut self, expected: &Token) -> Result<Token, ParseError> {
75        if std::mem::discriminant(self.current()) == std::mem::discriminant(expected) {
76            Ok(self.advance())
77        } else {
78            Err(ParseError::new(format!(
79                "Expected {expected:?}, found {:?}",
80                self.current()
81            )))
82        }
83    }
84
85    /// Consumes the current token if it matches `expected`. Returns whether it matched.
86    fn eat(&mut self, expected: &Token) -> bool {
87        if std::mem::discriminant(self.current()) == std::mem::discriminant(expected) {
88            self.advance();
89            true
90        } else {
91            false
92        }
93    }
94
95    // ── Program & statements ─────────────────────────────────────────
96
97    /// Parses the entire program as a sequence of top-level statements.
98    pub fn parse_program(&mut self) -> Result<Vec<Expr>, ParseError> {
99        let mut stmts = Vec::new();
100        while *self.current() != Token::Eof {
101            stmts.push(self.parse_statement()?);
102        }
103        Ok(stmts)
104    }
105
106    /// Parses a single statement (let, fn, if, while, loop, for, etc.).
107    fn parse_statement(&mut self) -> Result<Expr, ParseError> {
108        match self.current() {
109            Token::Let => self.parse_let(),
110            Token::Fn => self.parse_fn_def(),
111            Token::If => self.parse_if(),
112            Token::While => self.parse_while(),
113            Token::Loop => self.parse_loop(),
114            Token::For => self.parse_for(),
115            Token::Return => self.parse_return(),
116            Token::Break => self.parse_break(),
117            Token::Continue => {
118                self.advance();
119                self.eat(&Token::Semicolon);
120                Ok(Expr::Continue)
121            }
122            Token::Struct => self.parse_struct_def(),
123            Token::LBrace => self.parse_block(),
124            _ => {
125                let expr = self.parse_expr()?;
126                self.eat(&Token::Semicolon);
127                Ok(expr)
128            }
129        }
130    }
131
132    // ── Let binding ──────────────────────────────────────────────────
133
134    fn parse_let(&mut self) -> Result<Expr, ParseError> {
135        self.expect(&Token::Let)?;
136        let mutable = self.eat(&Token::Mut);
137
138        let name = match self.advance() {
139            Token::Ident(name) => name,
140            Token::Underscore => "_".to_string(),
141            other => {
142                return Err(ParseError::new(format!(
143                    "Expected identifier after let, found {other:?}"
144                )));
145            }
146        };
147
148        let type_ann = if self.eat(&Token::Colon) {
149            Some(self.parse_type()?)
150        } else {
151            None
152        };
153
154        let value = if self.eat(&Token::Eq) {
155            Some(Box::new(self.parse_expr()?))
156        } else {
157            None
158        };
159
160        self.eat(&Token::Semicolon);
161
162        Ok(Expr::Let {
163            name,
164            mutable,
165            type_ann,
166            value,
167        })
168    }
169
170    // ── Type annotations ─────────────────────────────────────────────
171
172    fn parse_type(&mut self) -> Result<Type, ParseError> {
173        // Handle reference types: &T, &mut T
174        if self.eat(&Token::Ampersand) {
175            let mutable = self.eat(&Token::Mut);
176            let inner = self.parse_type()?;
177            return Ok(Type::Reference(Box::new(inner), mutable));
178        }
179
180        // Map simple type-keyword tokens to their AST type
181        let simple = match self.current() {
182            Token::I8 => Some(Type::I8),
183            Token::I16 => Some(Type::I16),
184            Token::I32 => Some(Type::I32),
185            Token::I64 => Some(Type::I64),
186            Token::I128 => Some(Type::I128),
187            Token::U8 => Some(Type::U8),
188            Token::U16 => Some(Type::U16),
189            Token::U32 => Some(Type::U32),
190            Token::U64 => Some(Type::U64),
191            Token::U128 => Some(Type::U128),
192            Token::F32 => Some(Type::F32),
193            Token::F64 => Some(Type::F64),
194            Token::Bool => Some(Type::Bool),
195            Token::Char => Some(Type::Char),
196            Token::Str | Token::String_ => Some(Type::String),
197            Token::Usize => Some(Type::Usize),
198            Token::Isize => Some(Type::Isize),
199            _ => None,
200        };
201        if let Some(ty) = simple {
202            self.advance();
203            return Ok(ty);
204        }
205
206        let ty = match self.current() {
207            Token::LParen => {
208                self.advance();
209                if self.eat(&Token::RParen) {
210                    return Ok(Type::Unit);
211                }
212                let mut types = vec![self.parse_type()?];
213                while self.eat(&Token::Comma) {
214                    types.push(self.parse_type()?);
215                }
216                self.expect(&Token::RParen)?;
217                Type::Tuple(types)
218            }
219            Token::LBracket => {
220                self.advance();
221                let inner = self.parse_type()?;
222                let size = if self.eat(&Token::Semicolon) {
223                    let size_expr = self.parse_expr()?;
224                    match size_expr {
225                        Expr::IntLiteral(n) => Some(n as usize),
226                        _ => None,
227                    }
228                } else {
229                    None
230                };
231                self.expect(&Token::RBracket)?;
232                Type::Array(Box::new(inner), size)
233            }
234            Token::Ident(name) => {
235                let name = name.clone();
236                self.advance();
237                match name.as_str() {
238                    "Vec" => {
239                        if self.eat(&Token::Lt) {
240                            let inner = self.parse_type()?;
241                            self.expect(&Token::Gt)?;
242                            Type::Vec(Box::new(inner))
243                        } else {
244                            Type::Custom(name)
245                        }
246                    }
247                    "Option" => {
248                        if self.eat(&Token::Lt) {
249                            let inner = self.parse_type()?;
250                            self.expect(&Token::Gt)?;
251                            Type::Option(Box::new(inner))
252                        } else {
253                            Type::Custom(name)
254                        }
255                    }
256                    _ => Type::Custom(name),
257                }
258            }
259            _ => {
260                return Err(ParseError::new(format!(
261                    "Expected type, found {:?}",
262                    self.current()
263                )));
264            }
265        };
266
267        Ok(ty)
268    }
269
270    // ── Function definitions ──────────────────────────────────────────
271
272    fn parse_fn_def(&mut self) -> Result<Expr, ParseError> {
273        self.expect(&Token::Fn)?;
274        let name = self.expect_ident("function name")?;
275
276        self.expect(&Token::LParen)?;
277        let mut params = Vec::new();
278        while *self.current() != Token::RParen {
279            let param_name = match self.advance() {
280                Token::Ident(name) => name,
281                Token::Underscore => "_".to_string(),
282                other => {
283                    return Err(ParseError::new(format!(
284                        "Expected parameter name, found {other:?}"
285                    )));
286                }
287            };
288            self.expect(&Token::Colon)?;
289            let param_type = self.parse_type()?;
290            params.push((param_name, param_type));
291            if !self.eat(&Token::Comma) {
292                break;
293            }
294        }
295        self.expect(&Token::RParen)?;
296
297        let return_type = if self.eat(&Token::Arrow) {
298            Some(self.parse_type()?)
299        } else {
300            None
301        };
302
303        let body = Box::new(self.parse_block()?);
304
305        Ok(Expr::FnDef {
306            name,
307            params,
308            return_type,
309            body,
310        })
311    }
312
313    // ── Block & control flow ────────────────────────────────────────
314
315    fn parse_block(&mut self) -> Result<Expr, ParseError> {
316        self.expect(&Token::LBrace)?;
317        let mut stmts = Vec::new();
318        while *self.current() != Token::RBrace && *self.current() != Token::Eof {
319            stmts.push(self.parse_statement()?);
320        }
321        self.expect(&Token::RBrace)?;
322        Ok(Expr::Block(stmts))
323    }
324
325    fn parse_if(&mut self) -> Result<Expr, ParseError> {
326        self.expect(&Token::If)?;
327        let condition = Box::new(self.parse_expr()?);
328        let then_block = Box::new(self.parse_block()?);
329
330        let else_block = if self.eat(&Token::Else) {
331            if *self.current() == Token::If {
332                Some(Box::new(self.parse_if()?))
333            } else {
334                Some(Box::new(self.parse_block()?))
335            }
336        } else {
337            None
338        };
339
340        Ok(Expr::If {
341            condition,
342            then_block,
343            else_block,
344        })
345    }
346
347    fn parse_while(&mut self) -> Result<Expr, ParseError> {
348        self.expect(&Token::While)?;
349        let condition = Box::new(self.parse_expr()?);
350        let body = Box::new(self.parse_block()?);
351        Ok(Expr::While { condition, body })
352    }
353
354    fn parse_loop(&mut self) -> Result<Expr, ParseError> {
355        self.expect(&Token::Loop)?;
356        let body = Box::new(self.parse_block()?);
357        Ok(Expr::Loop { body })
358    }
359
360    fn parse_for(&mut self) -> Result<Expr, ParseError> {
361        self.expect(&Token::For)?;
362        let var = match self.advance() {
363            Token::Ident(name) => name,
364            Token::Underscore => "_".to_string(),
365            other => {
366                return Err(ParseError::new(format!(
367                    "Expected variable name in for loop, found {other:?}"
368                )));
369            }
370        };
371        self.expect(&Token::In)?;
372        let iterator = Box::new(self.parse_expr()?);
373        let body = Box::new(self.parse_block()?);
374        Ok(Expr::For {
375            var,
376            iterator,
377            body,
378        })
379    }
380
381    fn parse_return(&mut self) -> Result<Expr, ParseError> {
382        self.expect(&Token::Return)?;
383        if *self.current() == Token::Semicolon || *self.current() == Token::RBrace {
384            self.eat(&Token::Semicolon);
385            Ok(Expr::Return(None))
386        } else {
387            let value = self.parse_expr()?;
388            self.eat(&Token::Semicolon);
389            Ok(Expr::Return(Some(Box::new(value))))
390        }
391    }
392
393    fn parse_break(&mut self) -> Result<Expr, ParseError> {
394        self.expect(&Token::Break)?;
395        if *self.current() == Token::Semicolon || *self.current() == Token::RBrace {
396            self.eat(&Token::Semicolon);
397            Ok(Expr::Break(None))
398        } else {
399            let value = self.parse_expr()?;
400            self.eat(&Token::Semicolon);
401            Ok(Expr::Break(Some(Box::new(value))))
402        }
403    }
404
405    // ── Struct definitions ─────────────────────────────────────────────
406
407    fn parse_struct_def(&mut self) -> Result<Expr, ParseError> {
408        self.expect(&Token::Struct)?;
409        let name = self.expect_ident("struct name")?;
410
411        self.expect(&Token::LBrace)?;
412        let mut fields = Vec::new();
413        while *self.current() != Token::RBrace {
414            self.eat(&Token::Pub); // skip optional `pub`
415            let field_name = self.expect_ident("field name")?;
416            self.expect(&Token::Colon)?;
417            let field_type = self.parse_type()?;
418            fields.push((field_name, field_type));
419            if !self.eat(&Token::Comma) {
420                break;
421            }
422        }
423        self.expect(&Token::RBrace)?;
424
425        Ok(Expr::StructDef { name, fields })
426    }
427
428    // ── Match expressions ────────────────────────────────────────────
429
430    fn parse_match(&mut self) -> Result<Expr, ParseError> {
431        self.expect(&Token::Match)?;
432        let expr = Box::new(self.parse_expr()?);
433        self.expect(&Token::LBrace)?;
434
435        let mut arms = Vec::new();
436        while *self.current() != Token::RBrace {
437            let pattern = self.parse_pattern()?;
438            self.expect(&Token::FatArrow)?;
439
440            let body = if *self.current() == Token::LBrace {
441                self.parse_block()?
442            } else {
443                self.parse_expr()?
444            };
445
446            self.eat(&Token::Comma);
447            arms.push(MatchArm { pattern, body });
448        }
449        self.expect(&Token::RBrace)?;
450
451        Ok(Expr::Match { expr, arms })
452    }
453
454    fn parse_pattern(&mut self) -> Result<Pattern, ParseError> {
455        let first = self.parse_single_pattern()?;
456
457        if self.eat(&Token::Pipe) {
458            let mut patterns = vec![first];
459            patterns.push(self.parse_single_pattern()?);
460            while self.eat(&Token::Pipe) {
461                patterns.push(self.parse_single_pattern()?);
462            }
463            Ok(Pattern::Or(patterns))
464        } else {
465            Ok(first)
466        }
467    }
468
469    fn parse_single_pattern(&mut self) -> Result<Pattern, ParseError> {
470        match self.current() {
471            Token::Underscore => {
472                self.advance();
473                Ok(Pattern::Wildcard)
474            }
475            Token::IntLiteral(_)
476            | Token::FloatLiteral(_)
477            | Token::StringLiteral(_)
478            | Token::CharLiteral(_)
479            | Token::BoolLiteral(_) => {
480                let lit = self.parse_primary()?;
481                // Check for range pattern
482                if *self.current() == Token::DotDot || *self.current() == Token::DotDotEq {
483                    let inclusive = *self.current() == Token::DotDotEq;
484                    self.advance();
485                    let end = self.parse_primary()?;
486                    Ok(Pattern::Range {
487                        start: Box::new(lit),
488                        end: Box::new(end),
489                        inclusive,
490                    })
491                } else {
492                    Ok(Pattern::Literal(lit))
493                }
494            }
495            Token::Minus => {
496                self.advance();
497                if let Token::IntLiteral(n) = self.current().clone() {
498                    self.advance();
499                    Ok(Pattern::Literal(Expr::IntLiteral(-n)))
500                } else {
501                    Err(ParseError::new(format!(
502                        "Expected number after minus in pattern, found {:?}",
503                        self.current()
504                    )))
505                }
506            }
507            Token::Ident(_) => {
508                let Token::Ident(name) = self.advance() else {
509                    unreachable!()
510                };
511                Ok(Pattern::Ident(name))
512            }
513            _ => Err(ParseError::new(format!(
514                "Expected pattern, found {:?}",
515                self.current()
516            ))),
517        }
518    }
519
520    // ── Expression parsing (by precedence) ───────────────────────────
521
522    fn parse_expr(&mut self) -> Result<Expr, ParseError> {
523        self.parse_assignment()
524    }
525
526    /// Assignment: `=`, `+=`, `-=`, `*=`, `/=`, `%=`
527    fn parse_assignment(&mut self) -> Result<Expr, ParseError> {
528        let expr = self.parse_or()?;
529
530        // Check for compound assignment operators
531        let compound_op = match self.current() {
532            Token::PlusEq => Some(BinOp::Add),
533            Token::MinusEq => Some(BinOp::Sub),
534            Token::StarEq => Some(BinOp::Mul),
535            Token::SlashEq => Some(BinOp::Div),
536            Token::PercentEq => Some(BinOp::Mod),
537            _ => None,
538        };
539
540        if let Some(op) = compound_op {
541            self.advance();
542            let value = self.parse_expr()?;
543            return Ok(Expr::CompoundAssign {
544                target: Box::new(expr),
545                op,
546                value: Box::new(value),
547            });
548        }
549
550        if self.eat(&Token::Eq) {
551            let value = self.parse_expr()?;
552            return Ok(Expr::Assign {
553                target: Box::new(expr),
554                value: Box::new(value),
555            });
556        }
557
558        Ok(expr)
559    }
560
561    fn parse_or(&mut self) -> Result<Expr, ParseError> {
562        let mut left = self.parse_and()?;
563        while *self.current() == Token::Or {
564            self.advance();
565            let right = self.parse_and()?;
566            left = Expr::BinaryOp {
567                left: Box::new(left),
568                op: BinOp::Or,
569                right: Box::new(right),
570            };
571        }
572        Ok(left)
573    }
574
575    fn parse_and(&mut self) -> Result<Expr, ParseError> {
576        let mut left = self.parse_comparison()?;
577        while *self.current() == Token::And {
578            self.advance();
579            let right = self.parse_comparison()?;
580            left = Expr::BinaryOp {
581                left: Box::new(left),
582                op: BinOp::And,
583                right: Box::new(right),
584            };
585        }
586        Ok(left)
587    }
588
589    fn parse_comparison(&mut self) -> Result<Expr, ParseError> {
590        let mut left = self.parse_bitwise_or()?;
591        loop {
592            let op = match self.current() {
593                Token::EqEq => BinOp::Eq,
594                Token::NotEq => BinOp::NotEq,
595                Token::Lt => BinOp::Lt,
596                Token::LtEq => BinOp::LtEq,
597                Token::Gt => BinOp::Gt,
598                Token::GtEq => BinOp::GtEq,
599                _ => break,
600            };
601            self.advance();
602            let right = self.parse_bitwise_or()?;
603            left = Expr::BinaryOp {
604                left: Box::new(left),
605                op,
606                right: Box::new(right),
607            };
608        }
609        Ok(left)
610    }
611
612    fn parse_bitwise_or(&mut self) -> Result<Expr, ParseError> {
613        let mut left = self.parse_bitwise_xor()?;
614        while *self.current() == Token::Pipe {
615            self.advance();
616            let right = self.parse_bitwise_xor()?;
617            left = Expr::BinaryOp {
618                left: Box::new(left),
619                op: BinOp::BitOr,
620                right: Box::new(right),
621            };
622        }
623        Ok(left)
624    }
625
626    fn parse_bitwise_xor(&mut self) -> Result<Expr, ParseError> {
627        let mut left = self.parse_bitwise_and()?;
628        while *self.current() == Token::Caret {
629            self.advance();
630            let right = self.parse_bitwise_and()?;
631            left = Expr::BinaryOp {
632                left: Box::new(left),
633                op: BinOp::BitXor,
634                right: Box::new(right),
635            };
636        }
637        Ok(left)
638    }
639
640    fn parse_bitwise_and(&mut self) -> Result<Expr, ParseError> {
641        let mut left = self.parse_shift()?;
642        while *self.current() == Token::Ampersand {
643            self.advance();
644            let right = self.parse_shift()?;
645            left = Expr::BinaryOp {
646                left: Box::new(left),
647                op: BinOp::BitAnd,
648                right: Box::new(right),
649            };
650        }
651        Ok(left)
652    }
653
654    fn parse_shift(&mut self) -> Result<Expr, ParseError> {
655        let mut left = self.parse_additive()?;
656        loop {
657            let op = match self.current() {
658                Token::Shl => BinOp::Shl,
659                Token::Shr => BinOp::Shr,
660                _ => break,
661            };
662            self.advance();
663            let right = self.parse_additive()?;
664            left = Expr::BinaryOp {
665                left: Box::new(left),
666                op,
667                right: Box::new(right),
668            };
669        }
670        Ok(left)
671    }
672
673    fn parse_additive(&mut self) -> Result<Expr, ParseError> {
674        let mut left = self.parse_multiplicative()?;
675        loop {
676            let op = match self.current() {
677                Token::Plus => BinOp::Add,
678                Token::Minus => BinOp::Sub,
679                _ => break,
680            };
681            self.advance();
682            let right = self.parse_multiplicative()?;
683            left = Expr::BinaryOp {
684                left: Box::new(left),
685                op,
686                right: Box::new(right),
687            };
688        }
689        Ok(left)
690    }
691
692    fn parse_multiplicative(&mut self) -> Result<Expr, ParseError> {
693        let mut left = self.parse_type_cast()?;
694        loop {
695            let op = match self.current() {
696                Token::Star => BinOp::Mul,
697                Token::Slash => BinOp::Div,
698                Token::Percent => BinOp::Mod,
699                _ => break,
700            };
701            self.advance();
702            let right = self.parse_type_cast()?;
703            left = Expr::BinaryOp {
704                left: Box::new(left),
705                op,
706                right: Box::new(right),
707            };
708        }
709        Ok(left)
710    }
711
712    fn parse_type_cast(&mut self) -> Result<Expr, ParseError> {
713        let mut expr = self.parse_unary()?;
714        while self.eat(&Token::As) {
715            let target_type = self.parse_type()?;
716            expr = Expr::TypeCast {
717                expr: Box::new(expr),
718                target_type,
719            };
720        }
721        Ok(expr)
722    }
723
724    /// Unary: `-`, `!`, `&`, `*`
725    fn parse_unary(&mut self) -> Result<Expr, ParseError> {
726        match self.current() {
727            Token::Minus => {
728                self.advance();
729                let expr = self.parse_unary()?;
730                Ok(Expr::UnaryOp {
731                    op: UnaryOp::Neg,
732                    expr: Box::new(expr),
733                })
734            }
735            Token::Not => {
736                self.advance();
737                let expr = self.parse_unary()?;
738                Ok(Expr::UnaryOp {
739                    op: UnaryOp::Not,
740                    expr: Box::new(expr),
741                })
742            }
743            Token::Ampersand => {
744                self.advance();
745                let mutable = self.eat(&Token::Mut);
746                let expr = self.parse_unary()?;
747                Ok(Expr::Ref {
748                    expr: Box::new(expr),
749                    mutable,
750                })
751            }
752            Token::Star => {
753                self.advance();
754                let expr = self.parse_unary()?;
755                Ok(Expr::Deref(Box::new(expr)))
756            }
757            _ => self.parse_postfix(),
758        }
759    }
760
761    /// Postfix: `.method()`, `.field`, `[index]`, `(args)`, `..`, `..=`
762    fn parse_postfix(&mut self) -> Result<Expr, ParseError> {
763        let mut expr = self.parse_primary()?;
764
765        loop {
766            match self.current() {
767                Token::Dot => {
768                    self.advance();
769                    let method_name = self.expect_ident("method/field name after '.'")?;
770
771                    if *self.current() == Token::LParen {
772                        self.advance();
773                        let args = self.parse_args()?;
774                        self.expect(&Token::RParen)?;
775                        expr = Expr::MethodCall {
776                            object: Box::new(expr),
777                            method: method_name,
778                            args,
779                        };
780                    } else {
781                        expr = Expr::FieldAccess {
782                            object: Box::new(expr),
783                            field: method_name,
784                        };
785                    }
786                }
787                Token::LBracket => {
788                    self.advance();
789                    let index = self.parse_expr()?;
790                    self.expect(&Token::RBracket)?;
791                    expr = Expr::Index {
792                        object: Box::new(expr),
793                        index: Box::new(index),
794                    };
795                }
796                Token::LParen => {
797                    // Function call on an expression
798                    if let Expr::Ident(ref name) = expr {
799                        let name = name.clone();
800                        self.advance();
801                        let args = self.parse_args()?;
802                        self.expect(&Token::RParen)?;
803                        expr = Expr::FnCall { name, args };
804                    } else {
805                        break;
806                    }
807                }
808                _ => break,
809            }
810        }
811
812        // Check for range expressions
813        if *self.current() == Token::DotDot || *self.current() == Token::DotDotEq {
814            let inclusive = *self.current() == Token::DotDotEq;
815            self.advance();
816            // Check if there's an end expression
817            let end = if *self.current() != Token::RBrace
818                && *self.current() != Token::RParen
819                && *self.current() != Token::RBracket
820                && *self.current() != Token::Semicolon
821                && *self.current() != Token::Comma
822                && *self.current() != Token::Eof
823            {
824                Some(Box::new(self.parse_additive()?))
825            } else {
826                None
827            };
828            expr = Expr::Range {
829                start: Some(Box::new(expr)),
830                end,
831                inclusive,
832            };
833        }
834
835        Ok(expr)
836    }
837
838    /// Primary: literals, identifiers, macros, struct init, blocks, closures.
839    fn parse_primary(&mut self) -> Result<Expr, ParseError> {
840        match self.current().clone() {
841            Token::IntLiteral(n) => {
842                self.advance();
843                Ok(Expr::IntLiteral(n))
844            }
845            Token::FloatLiteral(n) => {
846                self.advance();
847                Ok(Expr::FloatLiteral(n))
848            }
849            Token::StringLiteral(s) => {
850                self.advance();
851                Ok(Expr::StringLiteral(s))
852            }
853            Token::CharLiteral(c) => {
854                self.advance();
855                Ok(Expr::CharLiteral(c))
856            }
857            Token::BoolLiteral(b) => {
858                self.advance();
859                Ok(Expr::BoolLiteral(b))
860            }
861            Token::Ident(name) => {
862                self.advance();
863
864                // Check for macro invocation: name!(...)
865                if *self.current() == Token::Not
866                    && (*self.peek() == Token::LParen || *self.peek() == Token::LBracket)
867                {
868                    self.advance(); // eat !
869
870                    if name == "vec" {
871                        self.expect(&Token::LBracket)?;
872                        let args = self.parse_args()?;
873                        self.expect(&Token::RBracket)?;
874                        return Ok(Expr::VecMacro(args));
875                    }
876
877                    let (open, close) = if *self.current() == Token::LBracket {
878                        (Token::LBracket, Token::RBracket)
879                    } else {
880                        (Token::LParen, Token::RParen)
881                    };
882                    self.expect(&open)?;
883                    let args = self.parse_macro_args()?;
884                    self.expect(&close)?;
885                    return Ok(Expr::MacroCall { name, args });
886                }
887
888                // Check for struct initialization: Name { ... }
889                if *self.current() == Token::LBrace && self.is_struct_init_context(&name) {
890                    return self.parse_struct_init(name);
891                }
892
893                // Check for function call: name(...)
894                if *self.current() == Token::LParen {
895                    self.advance();
896                    let args = self.parse_args()?;
897                    self.expect(&Token::RParen)?;
898                    return Ok(Expr::FnCall { name, args });
899                }
900
901                // Check for path call: name::method(...)
902                if *self.current() == Token::ColonColon {
903                    self.advance();
904                    let method = self.expect_ident("method name after '::'")?;
905
906                    let full_name = format!("{}::{}", name, method);
907
908                    if *self.current() == Token::LParen {
909                        self.advance();
910                        let args = self.parse_args()?;
911                        self.expect(&Token::RParen)?;
912                        return Ok(Expr::FnCall {
913                            name: full_name,
914                            args,
915                        });
916                    }
917
918                    return Ok(Expr::Ident(full_name));
919                }
920
921                Ok(Expr::Ident(name))
922            }
923            Token::LParen => {
924                self.advance();
925                if *self.current() == Token::RParen {
926                    self.advance();
927                    return Ok(Expr::Unit);
928                }
929
930                let expr = self.parse_expr()?;
931
932                // Check if it's a tuple
933                if *self.current() == Token::Comma {
934                    let mut elements = vec![expr];
935                    while self.eat(&Token::Comma) {
936                        if *self.current() == Token::RParen {
937                            break;
938                        }
939                        elements.push(self.parse_expr()?);
940                    }
941                    self.expect(&Token::RParen)?;
942                    return Ok(Expr::TupleLiteral(elements));
943                }
944
945                self.expect(&Token::RParen)?;
946                Ok(expr)
947            }
948            Token::LBracket => {
949                self.advance();
950                if *self.current() == Token::RBracket {
951                    self.advance();
952                    return Ok(Expr::ArrayLiteral(Vec::new()));
953                }
954
955                let first = self.parse_expr()?;
956
957                // Check for array repeat syntax: [expr; count]
958                if self.eat(&Token::Semicolon) {
959                    let count = self.parse_expr()?;
960                    self.expect(&Token::RBracket)?;
961                    return Ok(Expr::ArrayRepeat {
962                        value: Box::new(first),
963                        count: Box::new(count),
964                    });
965                }
966
967                let mut elements = vec![first];
968                while self.eat(&Token::Comma) {
969                    if *self.current() == Token::RBracket {
970                        break;
971                    }
972                    elements.push(self.parse_expr()?);
973                }
974                self.expect(&Token::RBracket)?;
975                Ok(Expr::ArrayLiteral(elements))
976            }
977            Token::If => self.parse_if(),
978            Token::Match => self.parse_match(),
979            Token::Loop => self.parse_loop(),
980            Token::While => self.parse_while(),
981            Token::For => self.parse_for(),
982            Token::LBrace => self.parse_block(),
983            Token::Pipe => {
984                // Closure: |params| body
985                self.advance();
986                let mut params = Vec::new();
987                while *self.current() != Token::Pipe {
988                    let name = self.expect_ident("closure parameter name")?;
989                    let type_ann = if self.eat(&Token::Colon) {
990                        Some(self.parse_type()?)
991                    } else {
992                        None
993                    };
994                    params.push((name, type_ann));
995                    if !self.eat(&Token::Comma) {
996                        break;
997                    }
998                }
999                self.expect(&Token::Pipe)?;
1000                let body = if *self.current() == Token::LBrace {
1001                    self.parse_block()?
1002                } else {
1003                    self.parse_expr()?
1004                };
1005                Ok(Expr::Closure {
1006                    params,
1007                    body: Box::new(body),
1008                })
1009            }
1010            Token::Or => {
1011                // Empty closure: || body
1012                self.advance();
1013                let body = if *self.current() == Token::LBrace {
1014                    self.parse_block()?
1015                } else {
1016                    self.parse_expr()?
1017                };
1018                Ok(Expr::Closure {
1019                    params: Vec::new(),
1020                    body: Box::new(body),
1021                })
1022            }
1023            _ => Err(ParseError::new(format!(
1024                "Unexpected token: {:?}",
1025                self.current()
1026            ))),
1027        }
1028    }
1029
1030    // ── Argument lists ───────────────────────────────────────────────
1031
1032    fn parse_args(&mut self) -> Result<Vec<Expr>, ParseError> {
1033        let mut args = Vec::new();
1034        if *self.current() == Token::RParen || *self.current() == Token::RBracket {
1035            return Ok(args);
1036        }
1037        args.push(self.parse_expr()?);
1038        while self.eat(&Token::Comma) {
1039            if *self.current() == Token::RParen || *self.current() == Token::RBracket {
1040                break;
1041            }
1042            args.push(self.parse_expr()?);
1043        }
1044        Ok(args)
1045    }
1046
1047    fn parse_macro_args(&mut self) -> Result<Vec<Expr>, ParseError> {
1048        let mut args = Vec::new();
1049        if *self.current() == Token::RParen || *self.current() == Token::RBracket {
1050            return Ok(args);
1051        }
1052        // First argument (for println! this is typically a format string)
1053        args.push(self.parse_expr()?);
1054        while self.eat(&Token::Comma) {
1055            if *self.current() == Token::RParen || *self.current() == Token::RBracket {
1056                break;
1057            }
1058            args.push(self.parse_expr()?);
1059        }
1060        Ok(args)
1061    }
1062
1063    // ── Struct initialization ────────────────────────────────────────
1064
1065    fn parse_struct_init(&mut self, name: String) -> Result<Expr, ParseError> {
1066        self.expect(&Token::LBrace)?;
1067        let mut fields = Vec::new();
1068        while *self.current() != Token::RBrace {
1069            let field_name = self.expect_ident("field name")?;
1070
1071            let value = if self.eat(&Token::Colon) {
1072                self.parse_expr()?
1073            } else {
1074                // Shorthand: { x } is equivalent to { x: x }
1075                Expr::Ident(field_name.clone())
1076            };
1077
1078            fields.push((field_name, value));
1079            if !self.eat(&Token::Comma) {
1080                break;
1081            }
1082        }
1083        self.expect(&Token::RBrace)?;
1084        Ok(Expr::StructInit { name, fields })
1085    }
1086
1087    fn is_struct_init_context(&self, name: &str) -> bool {
1088        // Heuristic: if the name starts with an uppercase letter, it's likely a struct
1089        name.chars().next().is_some_and(|c| c.is_uppercase())
1090    }
1091
1092    // ── Helpers ──────────────────────────────────────────────────────
1093
1094    /// Consumes the current token if it's an identifier, returning the name.
1095    fn expect_ident(&mut self, context: &str) -> Result<String, ParseError> {
1096        match self.advance() {
1097            Token::Ident(name) => Ok(name),
1098            other => Err(ParseError::new(format!(
1099                "Expected {context}, found {other:?}"
1100            ))),
1101        }
1102    }
1103}