Skip to main content

crisp_parser/
parser.rs

1use crisp_ast::{
2    Span,
3    expr::{
4        BinaryOp, Block, Expr, ExprKind, FieldInit, MatchArm, Ownership, Param, Stmt, StringPart,
5        StringParts, UnaryOp,
6    },
7    ident::Ident,
8    item::{
9        ConstDef, ExternBlock, ExternFn, FieldDef, FunctionDef, ImplBlock, Item, ShapeDef,
10        ShapeField, SourceFile, TestDef, TraitDef, TraitItem, TypeBody, TypeDef, UseDecl,
11        UseImport, VariantDef,
12    },
13    pat::{FieldPat, Pat, PatKind},
14    ty::{ErrorType, Type, TypeBound, TypeKind},
15};
16use crisp_lexer::{Kw, Token, TokenKind, lex};
17use thiserror::Error;
18
19#[derive(Debug, Error)]
20pub enum ParseError {
21    #[error("lex error: {0}")]
22    Lex(#[from] crisp_lexer::LexError),
23    #[error("{}", format_unexpected(.expected, .found, .pos, .help))]
24    Unexpected {
25        expected: &'static str,
26        found: TokenKind,
27        pos: u32,
28        help: Option<&'static str>,
29    },
30    #[error("unexpected end of file, expected {expected}")]
31    UnexpectedEof { expected: &'static str },
32    #[error("invalid pattern at byte {pos}")]
33    InvalidPat { pos: u32 },
34}
35
36fn format_unexpected(
37    expected: &&'static str,
38    found: &TokenKind,
39    pos: &u32,
40    help: &Option<&'static str>,
41) -> String {
42    let mut msg = format!("unexpected token {found:?} at byte {pos}, expected {expected}");
43    if let Some(h) = help {
44        msg.push_str("\nhelp: ");
45        msg.push_str(h);
46    }
47    msg
48}
49
50pub struct Parser {
51    tokens: Vec<Token>,
52    pos: usize,
53    /// When false, `Name { … }` is not parsed as a struct literal (Rust-style
54    /// restriction for `if`/`while`/`for` conditions so `{` can start the body).
55    allow_struct_lit: bool,
56}
57
58impl Parser {
59    pub fn new(source: &str) -> Result<Self, ParseError> {
60        Ok(Self {
61            tokens: lex(source)?,
62            pos: 0,
63            allow_struct_lit: true,
64        })
65    }
66
67    fn with_no_struct_lit<T>(
68        &mut self,
69        f: impl FnOnce(&mut Self) -> Result<T, ParseError>,
70    ) -> Result<T, ParseError> {
71        let prev = self.allow_struct_lit;
72        self.allow_struct_lit = false;
73        let result = f(self);
74        self.allow_struct_lit = prev;
75        result
76    }
77
78    pub fn parse_file(&mut self) -> Result<SourceFile, ParseError> {
79        let start = self.current_start();
80        let mut items = Vec::new();
81        while !self.check(TokenKind::Eof) {
82            items.push(self.parse_item()?);
83        }
84        let end = if items.is_empty() {
85            start
86        } else {
87            items.last().unwrap().span().end
88        };
89        Ok(SourceFile {
90            items,
91            span: Span::new(start, end),
92        })
93    }
94
95    pub fn parse_module(&mut self) -> Result<Vec<Item>, ParseError> {
96        Ok(self.parse_file()?.items)
97    }
98
99    // ── Items ─────────────────────────────────────────────────────────────
100
101    fn parse_item(&mut self) -> Result<Item, ParseError> {
102        let pub_span = if self.match_kw(Kw::Pub) {
103            Some(self.previous_span())
104        } else {
105            None
106        };
107        let is_pub = pub_span.is_some();
108
109        if self.match_kw(Kw::Type) {
110            return Ok(Item::TypeDef(self.parse_type_def(is_pub)?));
111        }
112        if self.match_kw(Kw::Trait) {
113            return Ok(Item::TraitDef(self.parse_trait_def()?));
114        }
115        if self.match_kw(Kw::Shape) {
116            return Ok(Item::ShapeDef(self.parse_shape_def()?));
117        }
118        if self.match_kw(Kw::Impl) {
119            return Ok(Item::Impl(self.parse_impl_block()?));
120        }
121        if self.match_kw(Kw::Use) {
122            return Ok(Item::Use(self.parse_use_decl(is_pub)?));
123        }
124        if self.match_kw(Kw::Extern) {
125            return Ok(Item::Extern(self.parse_extern_block()?));
126        }
127        if self.match_kw(Kw::TestCompileFail) {
128            return Ok(Item::TestCompileFail(self.parse_test_def()?));
129        }
130        if self.match_kw(Kw::Test) {
131            return Ok(Item::Test(self.parse_test_def()?));
132        }
133
134        let name = self.expect_ident()?;
135        if self.check(TokenKind::Lt) || self.check(TokenKind::LParen) {
136            return Ok(Item::Function(
137                self.parse_function_after_name(is_pub, name)?,
138            ));
139        }
140        if self.check(TokenKind::Assign) {
141            self.advance();
142            let value = self.parse_expr()?;
143            let span = name.span.merge(value.span);
144            return Ok(Item::Const(ConstDef { name, value, span }));
145        }
146
147        Err(self.unexpected("item", self.peek_kind()))
148    }
149
150    fn parse_function_after_name(
151        &mut self,
152        is_pub: bool,
153        name: Ident,
154    ) -> Result<FunctionDef, ParseError> {
155        let start = name.span.start;
156        let generics = self.parse_optional_generics()?;
157        self.expect(TokenKind::LParen)?;
158        let params = self.parse_params()?;
159        self.expect(TokenKind::RParen)?;
160        let ret_type = if self.match_token(TokenKind::Arrow) {
161            Some(self.parse_type()?)
162        } else {
163            None
164        };
165        let error_type = if self.check(TokenKind::Bang) {
166            Some(self.parse_error_type()?)
167        } else {
168            None
169        };
170        self.expect(TokenKind::Assign)?;
171        let body = self.parse_expr()?;
172        let end = body.span.end;
173        Ok(FunctionDef {
174            is_pub,
175            name,
176            generics,
177            params,
178            ret_type,
179            error_type,
180            body,
181            span: Span::new(start, end),
182        })
183    }
184
185    fn parse_params(&mut self) -> Result<Vec<Param>, ParseError> {
186        let mut params = Vec::new();
187        if self.check(TokenKind::RParen) {
188            return Ok(params);
189        }
190        loop {
191            params.push(self.parse_param()?);
192            if !self.match_token(TokenKind::Comma) {
193                break;
194            }
195        }
196        Ok(params)
197    }
198
199    fn parse_param(&mut self) -> Result<Param, ParseError> {
200        let start = self.current_start();
201        let lifetime = if self.check_lifetime() {
202            Some(self.parse_lifetime_ident()?)
203        } else {
204            None
205        };
206        let ownership = if self.match_kw(Kw::Own) {
207            Some(Ownership::Own)
208        } else if self.match_token(TokenKind::AmpMut) {
209            Some(Ownership::RefMut)
210        } else if self.match_token(TokenKind::Amp) {
211            Some(Ownership::Ref)
212        } else {
213            None
214        };
215        let name = self.expect_ident()?;
216        let ty = if self.match_token(TokenKind::Colon) {
217            Some(self.parse_type()?)
218        } else {
219            None
220        };
221        Ok(Param {
222            lifetime,
223            ownership,
224            name,
225            ty,
226            span: Span::new(start, self.previous_end()),
227        })
228    }
229
230    fn parse_type_def(&mut self, is_pub: bool) -> Result<TypeDef, ParseError> {
231        let start = self.previous_start();
232        let name = self.expect_ident()?;
233        let generics = self.parse_optional_generics()?;
234        self.expect(TokenKind::Assign)?;
235        let (body, end) = if self.match_token(TokenKind::LBrace) {
236            let fields = self.parse_struct_fields()?;
237            self.expect(TokenKind::RBrace)?;
238            let end = self.previous_end();
239            (TypeBody::Struct(fields), end)
240        } else if self.match_token(TokenKind::Pipe) {
241            let variants = self.parse_enum_variants()?;
242            (TypeBody::Enum(variants), self.previous_end())
243        } else {
244            let ty = self.parse_type()?;
245            (TypeBody::Alias(ty.clone()), ty.span.end)
246        };
247        Ok(TypeDef {
248            is_pub,
249            name,
250            generics,
251            body,
252            span: Span::new(start, end),
253        })
254    }
255
256    fn parse_struct_fields(&mut self) -> Result<Vec<FieldDef>, ParseError> {
257        let mut fields = Vec::new();
258        while !self.check(TokenKind::RBrace) && !self.check(TokenKind::Eof) {
259            let start = self.current_start();
260            let name = self.expect_ident()?;
261            self.expect(TokenKind::Colon)?;
262            let ty = self.parse_type()?;
263            let default = if self.match_token(TokenKind::Assign) {
264                Some(self.parse_expr()?)
265            } else {
266                None
267            };
268            fields.push(FieldDef {
269                name,
270                ty,
271                default,
272                span: Span::new(start, self.previous_end()),
273            });
274        }
275        Ok(fields)
276    }
277
278    fn parse_enum_variants(&mut self) -> Result<Vec<VariantDef>, ParseError> {
279        let mut variants = Vec::new();
280        loop {
281            let start = self.current_start();
282            let name = self.expect_ident()?;
283            let fields = if self.match_token(TokenKind::LParen) {
284                let mut types = Vec::new();
285                while !self.check(TokenKind::RParen) {
286                    types.push(self.parse_type()?);
287                    if !self.match_token(TokenKind::Comma) {
288                        break;
289                    }
290                }
291                self.expect(TokenKind::RParen)?;
292                types
293            } else {
294                vec![]
295            };
296            variants.push(VariantDef {
297                name,
298                fields,
299                span: Span::new(start, self.previous_end()),
300            });
301            if !self.match_token(TokenKind::Pipe) {
302                break;
303            }
304        }
305        Ok(variants)
306    }
307
308    fn parse_trait_def(&mut self) -> Result<TraitDef, ParseError> {
309        let start = self.previous_start();
310        let name = self.expect_ident()?;
311        let generics = self.parse_optional_generics()?;
312        self.expect(TokenKind::Assign)?;
313        self.expect(TokenKind::LBrace)?;
314        let mut items = Vec::new();
315        while !self.check(TokenKind::RBrace) && !self.check(TokenKind::Eof) {
316            items.push(self.parse_trait_item()?);
317        }
318        self.expect(TokenKind::RBrace)?;
319        Ok(TraitDef {
320            name,
321            generics,
322            items,
323            span: Span::new(start, self.previous_end()),
324        })
325    }
326
327    fn parse_trait_item(&mut self) -> Result<TraitItem, ParseError> {
328        let start = self.current_start();
329        let name = self.expect_ident()?;
330        self.expect(TokenKind::LParen)?;
331        let params = self.parse_params()?;
332        self.expect(TokenKind::RParen)?;
333        let ret_type = if self.match_token(TokenKind::Arrow) {
334            Some(self.parse_type()?)
335        } else {
336            None
337        };
338        let default_body = if self.match_token(TokenKind::Assign) {
339            Some(self.parse_expr()?)
340        } else {
341            None
342        };
343        Ok(TraitItem {
344            name,
345            params,
346            ret_type,
347            default_body,
348            span: Span::new(start, self.previous_end()),
349        })
350    }
351
352    fn parse_shape_def(&mut self) -> Result<ShapeDef, ParseError> {
353        let start = self.previous_start();
354        let name = self.expect_ident()?;
355        let generics = self.parse_optional_generics()?;
356        self.expect(TokenKind::Assign)?;
357        self.expect(TokenKind::LBrace)?;
358        let mut fields = Vec::new();
359        while !self.check(TokenKind::RBrace) && !self.check(TokenKind::Eof) {
360            fields.push(self.parse_shape_field()?);
361        }
362        self.expect(TokenKind::RBrace)?;
363        Ok(ShapeDef {
364            name,
365            generics,
366            fields,
367            span: Span::new(start, self.previous_end()),
368        })
369    }
370
371    fn parse_shape_field(&mut self) -> Result<ShapeField, ParseError> {
372        let start = self.current_start();
373        let name = self.expect_ident()?;
374        if self.match_token(TokenKind::Colon) {
375            let ty = self.parse_type()?;
376            return Ok(ShapeField::Data {
377                name,
378                ty,
379                span: Span::new(start, self.previous_end()),
380            });
381        }
382        self.expect(TokenKind::LParen)?;
383        let params = self.parse_params()?;
384        self.expect(TokenKind::RParen)?;
385        self.expect(TokenKind::Arrow)?;
386        let ret_type = self.parse_type()?;
387        Ok(ShapeField::Method {
388            name,
389            params,
390            ret_type,
391            span: Span::new(start, self.previous_end()),
392        })
393    }
394
395    fn parse_impl_block(&mut self) -> Result<ImplBlock, ParseError> {
396        let start = self.previous_start();
397        let first = self.expect_ident()?;
398        let trait_args = self.parse_optional_type_args()?;
399        let (trait_name, ty) = if self.match_kw(Kw::For) {
400            let ty = self.parse_type()?;
401            (Some(first), ty)
402        } else {
403            (
404                None,
405                Type {
406                    kind: TypeKind::Named(first.clone()),
407                    span: first.span,
408                },
409            )
410        };
411        let mut items = Vec::new();
412        if self.match_token(TokenKind::Assign) {
413            self.expect(TokenKind::LBrace)?;
414            while !self.check(TokenKind::RBrace) && !self.check(TokenKind::Eof) {
415                let is_pub = self.match_kw(Kw::Pub);
416                let name = self.expect_ident()?;
417                items.push(self.parse_function_after_name(is_pub, name)?);
418            }
419            self.expect(TokenKind::RBrace)?;
420        }
421        Ok(ImplBlock {
422            trait_name,
423            trait_args,
424            ty,
425            items,
426            span: Span::new(start, self.previous_end()),
427        })
428    }
429
430    fn parse_use_decl(&mut self, is_pub: bool) -> Result<UseDecl, ParseError> {
431        let start = self.previous_start();
432        let mut path = vec![self.expect_ident()?];
433        // Crisp module paths use `.`; spec §14.2 also writes `use rust::crate` — accept both.
434        while self.match_token(TokenKind::Dot) || self.match_colon_colon() {
435            path.push(self.expect_ident()?);
436        }
437        let imports = if self.match_token(TokenKind::LBrace) {
438            let mut list = Vec::new();
439            while !self.check(TokenKind::RBrace) {
440                let s = self.current_start();
441                let name = self.expect_ident()?;
442                let alias = if self.match_kw(Kw::As) {
443                    Some(self.expect_ident()?)
444                } else {
445                    None
446                };
447                list.push(UseImport {
448                    name,
449                    alias,
450                    span: Span::new(s, self.previous_end()),
451                });
452                if !self.match_token(TokenKind::Comma) {
453                    break;
454                }
455            }
456            self.expect(TokenKind::RBrace)?;
457            Some(list)
458        } else {
459            None
460        };
461        Ok(UseDecl {
462            is_pub,
463            path,
464            imports,
465            span: Span::new(start, self.previous_end()),
466        })
467    }
468
469    fn parse_extern_block(&mut self) -> Result<ExternBlock, ParseError> {
470        let start = self.previous_start();
471        let abi = self.expect_string_lit()?;
472        self.expect(TokenKind::LBrace)?;
473        let mut functions = Vec::new();
474        while !self.check(TokenKind::RBrace) && !self.check(TokenKind::Eof) {
475            let s = self.current_start();
476            let name = self.expect_ident()?;
477            self.expect(TokenKind::LParen)?;
478            let params = self.parse_params()?;
479            self.expect(TokenKind::RParen)?;
480            let ret_type = if self.match_token(TokenKind::Arrow) {
481                Some(self.parse_type()?)
482            } else {
483                None
484            };
485            functions.push(ExternFn {
486                name,
487                params,
488                ret_type,
489                span: Span::new(s, self.previous_end()),
490            });
491        }
492        self.expect(TokenKind::RBrace)?;
493        Ok(ExternBlock {
494            abi,
495            functions,
496            span: Span::new(start, self.previous_end()),
497        })
498    }
499
500    fn parse_test_def(&mut self) -> Result<TestDef, ParseError> {
501        let start = self.previous_start();
502        let name = self.expect_string_lit()?;
503        self.expect(TokenKind::Assign)?;
504        let body = self.parse_block()?;
505        let end = body.span.end;
506        Ok(TestDef {
507            name,
508            body,
509            span: Span::new(start, end),
510        })
511    }
512
513    // ── Types ─────────────────────────────────────────────────────────────
514
515    fn parse_type(&mut self) -> Result<Type, ParseError> {
516        let start = self.current_start();
517        if self.match_token(TokenKind::Question) {
518            let inner = self.parse_type()?;
519            return Ok(Type {
520                kind: TypeKind::Option(Box::new(inner)),
521                span: Span::new(start, self.previous_end()),
522            });
523        }
524        if self.match_token(TokenKind::AmpMut) {
525            let inner = self.parse_type()?;
526            return Ok(Type {
527                kind: TypeKind::Ref {
528                    mutable: true,
529                    inner: Box::new(inner),
530                },
531                span: Span::new(start, self.previous_end()),
532            });
533        }
534        if self.match_token(TokenKind::Amp) {
535            let inner = self.parse_type()?;
536            return Ok(Type {
537                kind: TypeKind::Ref {
538                    mutable: false,
539                    inner: Box::new(inner),
540                },
541                span: Span::new(start, self.previous_end()),
542            });
543        }
544        if self.match_token(TokenKind::LParen) {
545            if self.check(TokenKind::RParen) {
546                self.advance();
547                return Ok(Type {
548                    kind: TypeKind::Unit,
549                    span: Span::new(start, self.previous_end()),
550                });
551            }
552            let mut types = vec![self.parse_type()?];
553            while self.match_token(TokenKind::Comma) {
554                types.push(self.parse_type()?);
555            }
556            self.expect(TokenKind::RParen)?;
557            if types.len() == 1 && self.check(TokenKind::Arrow) {
558                self.advance();
559                let ret = self.parse_type()?;
560                return Ok(Type {
561                    kind: TypeKind::Fn {
562                        params: types,
563                        ret: Box::new(ret),
564                    },
565                    span: Span::new(start, self.previous_end()),
566                });
567            }
568            return Ok(Type {
569                kind: TypeKind::Tuple(types),
570                span: Span::new(start, self.previous_end()),
571            });
572        }
573        if self.match_token(TokenKind::LBracket) {
574            let elem = self.parse_type()?;
575            if self.match_token(TokenKind::Semi) && self.is_int() {
576                let TokenKind::Int(n) = self.advance().kind else {
577                    unreachable!();
578                };
579                self.expect(TokenKind::RBracket)?;
580                return Ok(Type {
581                    kind: TypeKind::Array {
582                        elem: Box::new(elem),
583                        len: n as u64,
584                    },
585                    span: Span::new(start, self.previous_end()),
586                });
587            }
588            self.expect(TokenKind::RBracket)?;
589            return Ok(Type {
590                kind: TypeKind::Slice(Box::new(elem)),
591                span: Span::new(start, self.previous_end()),
592            });
593        }
594
595        let base = self.parse_type_primary()?;
596        let mut ty = base;
597        if self.match_token(TokenKind::Lt) {
598            let mut args = vec![self.parse_type()?];
599            while self.match_token(TokenKind::Comma) {
600                args.push(self.parse_type()?);
601            }
602            self.expect(TokenKind::Gt)?;
603            ty = Type {
604                kind: TypeKind::Generic {
605                    base: Box::new(ty),
606                    args,
607                },
608                span: Span::new(start, self.previous_end()),
609            };
610        }
611        while self.match_token(TokenKind::Plus) {
612            let mut bounds = vec![self.parse_type_bound()?];
613            while self.match_token(TokenKind::Plus) {
614                bounds.push(self.parse_type_bound()?);
615            }
616            ty = Type {
617                kind: TypeKind::Constrained {
618                    inner: Box::new(ty),
619                    bounds,
620                },
621                span: Span::new(start, self.previous_end()),
622            };
623        }
624        Ok(ty)
625    }
626
627    fn parse_type_primary(&mut self) -> Result<Type, ParseError> {
628        let start = self.current_start();
629        if let Some(kw) = self.match_kw_opt() {
630            let name = match kw {
631                Kw::True | Kw::False => "bool",
632                _ => return Err(self.unexpected("type", TokenKind::Kw(kw))),
633            };
634            return Ok(Type {
635                kind: TypeKind::Named(Ident::new(name, Span::new(start, self.previous_end()))),
636                span: Span::new(start, self.previous_end()),
637            });
638        }
639        let name = self.expect_ident()?;
640        let kind = match name.name.as_str() {
641            "Never" => TypeKind::Never,
642            "()" => TypeKind::Unit,
643            _ => TypeKind::Named(name.clone()),
644        };
645        Ok(Type {
646            kind,
647            span: name.span,
648        })
649    }
650
651    fn parse_type_bound(&mut self) -> Result<TypeBound, ParseError> {
652        if self.match_kw(Kw::Shape) {
653            return Ok(TypeBound::Shape(self.expect_ident()?));
654        }
655        Ok(TypeBound::Trait(self.expect_ident()?))
656    }
657
658    fn parse_error_type(&mut self) -> Result<ErrorType, ParseError> {
659        let start = self.current_start();
660        self.expect(TokenKind::Bang)?;
661        if self.match_kw(Kw::False) {
662            // !never — use Never keyword path; accept `!never` as ident
663        }
664        let first = self.parse_type()?;
665        let mut variants = vec![first];
666        while self.match_token(TokenKind::Pipe) {
667            variants.push(self.parse_type()?);
668        }
669        Ok(ErrorType {
670            variants,
671            span: Span::new(start, self.previous_end()),
672        })
673    }
674
675    fn parse_optional_generics(&mut self) -> Result<Vec<Ident>, ParseError> {
676        if !self.match_token(TokenKind::Lt) {
677            return Ok(vec![]);
678        }
679        let mut names = vec![self.expect_ident()?];
680        while self.match_token(TokenKind::Comma) {
681            names.push(self.expect_ident()?);
682        }
683        self.expect(TokenKind::Gt)?;
684        Ok(names)
685    }
686
687    fn parse_optional_type_args(&mut self) -> Result<Vec<Type>, ParseError> {
688        if !self.match_token(TokenKind::Lt) {
689            return Ok(vec![]);
690        }
691        let mut args = vec![self.parse_type()?];
692        while self.match_token(TokenKind::Comma) {
693            args.push(self.parse_type()?);
694        }
695        self.expect(TokenKind::Gt)?;
696        Ok(args)
697    }
698
699    // ── Expressions ───────────────────────────────────────────────────────
700
701    fn parse_expr(&mut self) -> Result<Expr, ParseError> {
702        self.parse_pipe()
703    }
704
705    fn parse_pipe(&mut self) -> Result<Expr, ParseError> {
706        let mut left = self.parse_assign()?;
707        while self.match_token(TokenKind::PipeGt) {
708            let right = self.parse_assign()?;
709            let span = left.span.merge(right.span);
710            left = Expr {
711                kind: ExprKind::Pipe {
712                    left: Box::new(left),
713                    right: Box::new(right),
714                },
715                span,
716            };
717        }
718        left = self.parse_catch_suffix(left)?;
719        Ok(left)
720    }
721
722    fn parse_catch_suffix(&mut self, expr: Expr) -> Result<Expr, ParseError> {
723        let mut arms = Vec::new();
724        while self.match_kw(Kw::Catch) {
725            let start = self.previous_start();
726            let pat = self.parse_pat()?;
727            self.expect(TokenKind::Arrow)?;
728            let body = self.parse_pipe()?;
729            let body_end = body.span.end;
730            arms.push(crisp_ast::expr::CatchArm {
731                pat,
732                body,
733                span: Span::new(start, body_end),
734            });
735        }
736        if arms.is_empty() {
737            return Ok(expr);
738        }
739        let expr_start = expr.span.start;
740        let end = arms.last().map(|a| a.span.end).unwrap_or(expr.span.end);
741        Ok(Expr {
742            kind: ExprKind::Catch {
743                body: Box::new(expr),
744                arms,
745            },
746            span: Span::new(expr_start, end),
747        })
748    }
749
750    fn parse_assign(&mut self) -> Result<Expr, ParseError> {
751        let expr = self.parse_or()?;
752        if self.match_token(TokenKind::Assign) {
753            let (name, id_span) = match &expr.kind {
754                ExprKind::Ident(id) => (id.name.clone(), id.span),
755                _ => return Err(self.unexpected("assignable identifier", self.peek_kind())),
756            };
757            let value = self.parse_assign()?;
758            let span = id_span.merge(value.span);
759            return Ok(Expr {
760                kind: ExprKind::Assign {
761                    target: Ident::new(name, id_span),
762                    value: Box::new(value),
763                },
764                span,
765            });
766        }
767        Ok(expr)
768    }
769
770    fn parse_or(&mut self) -> Result<Expr, ParseError> {
771        self.parse_binary(Self::parse_and, TokenKind::Or, BinaryOp::Or)
772    }
773
774    fn parse_and(&mut self) -> Result<Expr, ParseError> {
775        self.parse_binary(Self::parse_equality, TokenKind::And, BinaryOp::And)
776    }
777
778    fn parse_equality(&mut self) -> Result<Expr, ParseError> {
779        let mut left = self.parse_comparison()?;
780        while matches!(self.peek_kind(), TokenKind::EqEq | TokenKind::Ne) {
781            let op = match self.advance().kind {
782                TokenKind::EqEq => BinaryOp::Eq,
783                TokenKind::Ne => BinaryOp::Ne,
784                _ => unreachable!(),
785            };
786            let right = self.parse_comparison()?;
787            let span = left.span.merge(right.span);
788            left = Expr {
789                kind: ExprKind::Binary {
790                    op,
791                    left: Box::new(left),
792                    right: Box::new(right),
793                },
794                span,
795            };
796        }
797        Ok(left)
798    }
799
800    fn parse_comparison(&mut self) -> Result<Expr, ParseError> {
801        let mut left = self.parse_concat()?;
802        while matches!(
803            self.peek_kind(),
804            TokenKind::Lt | TokenKind::Le | TokenKind::Gt | TokenKind::Ge
805        ) {
806            let op = match self.advance().kind {
807                TokenKind::Lt => BinaryOp::Lt,
808                TokenKind::Le => BinaryOp::Le,
809                TokenKind::Gt => BinaryOp::Gt,
810                TokenKind::Ge => BinaryOp::Ge,
811                _ => unreachable!(),
812            };
813            let right = self.parse_concat()?;
814            let span = left.span.merge(right.span);
815            left = Expr {
816                kind: ExprKind::Binary {
817                    op,
818                    left: Box::new(left),
819                    right: Box::new(right),
820                },
821                span,
822            };
823        }
824        Ok(left)
825    }
826
827    fn parse_concat(&mut self) -> Result<Expr, ParseError> {
828        self.parse_binary(Self::parse_additive, TokenKind::PlusPlus, BinaryOp::Concat)
829    }
830
831    fn parse_additive(&mut self) -> Result<Expr, ParseError> {
832        let mut left = self.parse_multiplicative()?;
833        loop {
834            let op = match self.peek_kind() {
835                TokenKind::Plus => BinaryOp::Add,
836                TokenKind::Minus => BinaryOp::Sub,
837                _ => break,
838            };
839            self.advance();
840            let right = self.parse_multiplicative()?;
841            let span = left.span.merge(right.span);
842            left = Expr {
843                kind: ExprKind::Binary {
844                    op,
845                    left: Box::new(left),
846                    right: Box::new(right),
847                },
848                span,
849            };
850        }
851        Ok(left)
852    }
853
854    fn parse_multiplicative(&mut self) -> Result<Expr, ParseError> {
855        let mut left = self.parse_power()?;
856        loop {
857            let op = match self.peek_kind() {
858                TokenKind::Star => BinaryOp::Mul,
859                TokenKind::Slash => BinaryOp::Div,
860                TokenKind::Percent => BinaryOp::Mod,
861                _ => break,
862            };
863            self.advance();
864            let right = self.parse_power()?;
865            let span = left.span.merge(right.span);
866            left = Expr {
867                kind: ExprKind::Binary {
868                    op,
869                    left: Box::new(left),
870                    right: Box::new(right),
871                },
872                span,
873            };
874        }
875        Ok(left)
876    }
877
878    fn parse_power(&mut self) -> Result<Expr, ParseError> {
879        let mut left = self.parse_unary()?;
880        if self.match_token(TokenKind::StarStar) {
881            let right = self.parse_power()?;
882            let span = left.span.merge(right.span);
883            left = Expr {
884                kind: ExprKind::Binary {
885                    op: BinaryOp::Pow,
886                    left: Box::new(left),
887                    right: Box::new(right),
888                },
889                span,
890            };
891        }
892        Ok(left)
893    }
894
895    fn parse_unary(&mut self) -> Result<Expr, ParseError> {
896        let start = self.current_start();
897        if self.match_token(TokenKind::Bang) {
898            let expr = self.parse_unary()?;
899            let end = expr.span.end;
900            return Ok(Expr {
901                kind: ExprKind::Unary {
902                    op: UnaryOp::Not,
903                    expr: Box::new(expr),
904                },
905                span: Span::new(start, end),
906            });
907        }
908        if self.match_token(TokenKind::Minus) {
909            let expr = self.parse_unary()?;
910            let end = expr.span.end;
911            return Ok(Expr {
912                kind: ExprKind::Unary {
913                    op: UnaryOp::Neg,
914                    expr: Box::new(expr),
915                },
916                span: Span::new(start, end),
917            });
918        }
919        if self.match_kw(Kw::Async) {
920            let body = self.parse_unary()?;
921            let end = body.span.end;
922            return Ok(Expr {
923                kind: ExprKind::Async(Box::new(body)),
924                span: Span::new(start, end),
925            });
926        }
927        if self.match_kw(Kw::Await) {
928            let body = self.parse_unary()?;
929            let end = body.span.end;
930            return Ok(Expr {
931                kind: ExprKind::Await(Box::new(body)),
932                span: Span::new(start, end),
933            });
934        }
935        if self.match_kw(Kw::Spawn) {
936            let body = self.parse_unary()?;
937            let end = body.span.end;
938            return Ok(Expr {
939                kind: ExprKind::Spawn(Box::new(body)),
940                span: Span::new(start, end),
941            });
942        }
943        if self.match_kw(Kw::Unsafe) {
944            let body = self.parse_unary()?;
945            let end = body.span.end;
946            return Ok(Expr {
947                kind: ExprKind::Unsafe(Box::new(body)),
948                span: Span::new(start, end),
949            });
950        }
951        if self.match_kw(Kw::Return) {
952            let value = if self.check_expr_start() {
953                Some(Box::new(self.parse_expr()?))
954            } else {
955                None
956            };
957            let end = value
958                .as_ref()
959                .map(|v| v.span.end)
960                .unwrap_or(self.previous_end());
961            return Ok(Expr {
962                kind: ExprKind::Return(value),
963                span: Span::new(start, end),
964            });
965        }
966        if self.match_kw(Kw::Break) {
967            let value = if self.check_expr_start() {
968                Some(Box::new(self.parse_expr()?))
969            } else {
970                None
971            };
972            let end = value
973                .as_ref()
974                .map(|v| v.span.end)
975                .unwrap_or(self.previous_end());
976            return Ok(Expr {
977                kind: ExprKind::Break(value),
978                span: Span::new(start, end),
979            });
980        }
981        if self.match_kw(Kw::Continue) {
982            return Ok(Expr {
983                kind: ExprKind::Continue,
984                span: Span::new(start, self.previous_end()),
985            });
986        }
987        if self.match_kw(Kw::Throw) {
988            let expr = self.parse_unary()?;
989            let end = expr.span.end;
990            return Ok(Expr {
991                kind: ExprKind::Throw(Box::new(expr)),
992                span: Span::new(start, end),
993            });
994        }
995        self.parse_postfix()
996    }
997
998    fn parse_postfix(&mut self) -> Result<Expr, ParseError> {
999        let mut expr = self.parse_primary()?;
1000        loop {
1001            match self.peek_kind() {
1002                TokenKind::LParen => {
1003                    self.advance();
1004                    let args = self.parse_args()?;
1005                    self.expect(TokenKind::RParen)?;
1006                    let span = expr
1007                        .span
1008                        .merge(Span::new(self.previous_start(), self.previous_end()));
1009                    expr = Expr {
1010                        kind: ExprKind::Call {
1011                            func: Box::new(expr),
1012                            args,
1013                        },
1014                        span,
1015                    };
1016                }
1017                TokenKind::Dot => {
1018                    self.advance();
1019                    let field = self.expect_ident()?;
1020                    let span = expr.span.merge(field.span);
1021                    expr = Expr {
1022                        kind: ExprKind::Field {
1023                            base: Box::new(expr),
1024                            field,
1025                        },
1026                        span,
1027                    };
1028                }
1029                TokenKind::LBracket => {
1030                    self.advance();
1031                    let index = self.parse_expr()?;
1032                    self.expect(TokenKind::RBracket)?;
1033                    let span = expr.span.merge(index.span);
1034                    expr = Expr {
1035                        kind: ExprKind::Index {
1036                            base: Box::new(expr),
1037                            index: Box::new(index),
1038                        },
1039                        span,
1040                    };
1041                }
1042                TokenKind::Question => {
1043                    self.advance();
1044                    let span = expr
1045                        .span
1046                        .merge(Span::new(self.previous_start(), self.previous_end()));
1047                    expr = Expr {
1048                        kind: ExprKind::Try(Box::new(expr)),
1049                        span,
1050                    };
1051                }
1052                _ => break,
1053            }
1054        }
1055        Ok(expr)
1056    }
1057
1058    fn parse_primary(&mut self) -> Result<Expr, ParseError> {
1059        let start = self.current_start();
1060        match self.peek_kind() {
1061            TokenKind::Int(n) => {
1062                self.advance();
1063                Ok(Expr {
1064                    kind: ExprKind::Int(n),
1065                    span: Span::new(start, self.previous_end()),
1066                })
1067            }
1068            TokenKind::Float(f) => {
1069                self.advance();
1070                Ok(Expr {
1071                    kind: ExprKind::Float(f),
1072                    span: Span::new(start, self.previous_end()),
1073                })
1074            }
1075            TokenKind::String(ref s) => {
1076                self.advance();
1077                Ok(Expr {
1078                    kind: ExprKind::Str(self.parse_string_parts(s, start)?),
1079                    span: Span::new(start, self.previous_end()),
1080                })
1081            }
1082            TokenKind::Char(c) => {
1083                self.advance();
1084                Ok(Expr {
1085                    kind: ExprKind::Char(c),
1086                    span: Span::new(start, self.previous_end()),
1087                })
1088            }
1089            TokenKind::Kw(Kw::True) => {
1090                self.advance();
1091                Ok(Expr {
1092                    kind: ExprKind::Bool(true),
1093                    span: Span::new(start, self.previous_end()),
1094                })
1095            }
1096            TokenKind::Kw(Kw::False) => {
1097                self.advance();
1098                Ok(Expr {
1099                    kind: ExprKind::Bool(false),
1100                    span: Span::new(start, self.previous_end()),
1101                })
1102            }
1103            TokenKind::Kw(Kw::None) => {
1104                self.advance();
1105                Ok(self.parse_none_some_call(false, start)?)
1106            }
1107            TokenKind::Kw(Kw::Some) => {
1108                self.advance();
1109                Ok(self.parse_none_some_call(true, start)?)
1110            }
1111            TokenKind::Ident(_) | TokenKind::Kw(_) => {
1112                if self.match_kw(Kw::If) {
1113                    return self.parse_if_expr(start);
1114                }
1115                if self.match_kw(Kw::Match) {
1116                    return self.parse_match_expr(start);
1117                }
1118                if self.match_kw(Kw::For) {
1119                    return self.parse_for_expr(start);
1120                }
1121                if self.match_kw(Kw::While) {
1122                    return self.parse_while_expr(start);
1123                }
1124                if self.match_kw(Kw::Loop) {
1125                    return self.parse_loop_expr(start);
1126                }
1127                let id = self.expect_ident_or_kw_as_ident()?;
1128                let span = id.span;
1129                // struct literal: Name { ... } (disabled in if/while/for heads)
1130                if self.allow_struct_lit && self.check(TokenKind::LBrace) {
1131                    return self.parse_struct_lit(id);
1132                }
1133                Ok(Expr {
1134                    kind: ExprKind::Ident(id),
1135                    span,
1136                })
1137            }
1138            TokenKind::LBrace => Ok(Expr {
1139                kind: ExprKind::Block(self.parse_block()?),
1140                span: Span::new(start, self.previous_end()),
1141            }),
1142            TokenKind::LParen => {
1143                self.advance();
1144                if self.check(TokenKind::RParen) {
1145                    self.advance();
1146                    return Ok(Expr {
1147                        kind: ExprKind::Unit,
1148                        span: Span::new(start, self.previous_end()),
1149                    });
1150                }
1151                if self.check(TokenKind::Pipe)
1152                    || (self.is_ident() && self.peek_kind_at(1) == TokenKind::Pipe)
1153                {
1154                    return self.parse_lambda(start);
1155                }
1156                let expr = self.parse_expr()?;
1157                self.expect(TokenKind::RParen)?;
1158                Ok(expr)
1159            }
1160            TokenKind::Pipe => self.parse_lambda(start),
1161            _ => Err(self.unexpected("expression", self.peek_kind())),
1162        }
1163    }
1164
1165    fn parse_none_some_call(&mut self, some: bool, start: u32) -> Result<Expr, ParseError> {
1166        if self.match_token(TokenKind::LParen) {
1167            let inner = self.parse_expr()?;
1168            self.expect(TokenKind::RParen)?;
1169            let name = if some { "some" } else { "none" };
1170            return Ok(Expr {
1171                kind: ExprKind::Call {
1172                    func: Box::new(Expr {
1173                        kind: ExprKind::Ident(Ident::new(name, Span::new(start, start))),
1174                        span: Span::new(start, start),
1175                    }),
1176                    args: if some { vec![inner] } else { vec![] },
1177                },
1178                span: Span::new(start, self.previous_end()),
1179            });
1180        }
1181        let name = if some { "some" } else { "none" };
1182        Ok(Expr {
1183            kind: ExprKind::Ident(Ident::new(name, Span::new(start, self.previous_end()))),
1184            span: Span::new(start, self.previous_end()),
1185        })
1186    }
1187
1188    fn parse_lambda(&mut self, start: u32) -> Result<Expr, ParseError> {
1189        self.expect(TokenKind::Pipe)?;
1190        let params = self.parse_params()?;
1191        self.expect(TokenKind::Pipe)?;
1192        let body = self.parse_expr()?;
1193        let end = body.span.end;
1194        Ok(Expr {
1195            kind: ExprKind::Lambda {
1196                params,
1197                body: Box::new(body),
1198            },
1199            span: Span::new(start, end),
1200        })
1201    }
1202
1203    fn parse_if_expr(&mut self, start: u32) -> Result<Expr, ParseError> {
1204        let cond = self.with_no_struct_lit(|p| p.parse_expr())?;
1205        let then_branch = if self.match_kw(Kw::Then) {
1206            Box::new(self.parse_expr()?)
1207        } else {
1208            Box::new(Expr {
1209                kind: ExprKind::Block(self.parse_block()?),
1210                span: Span::new(self.current_start(), self.previous_end()),
1211            })
1212        };
1213        let else_branch = if self.match_kw(Kw::Else) {
1214            if self.check(TokenKind::Kw(Kw::If)) {
1215                Some(Box::new(self.parse_if_expr(self.current_start())?))
1216            } else if self.check(TokenKind::LBrace) {
1217                Some(Box::new(Expr {
1218                    kind: ExprKind::Block(self.parse_block()?),
1219                    span: Span::new(self.current_start(), self.previous_end()),
1220                }))
1221            } else {
1222                Some(Box::new(self.parse_expr()?))
1223            }
1224        } else {
1225            None
1226        };
1227        let end = else_branch
1228            .as_ref()
1229            .map(|e| e.span.end)
1230            .unwrap_or(then_branch.span.end);
1231        Ok(Expr {
1232            kind: ExprKind::If {
1233                cond: Box::new(cond),
1234                then_branch,
1235                else_branch,
1236            },
1237            span: Span::new(start, end),
1238        })
1239    }
1240
1241    fn parse_match_expr(&mut self, start: u32) -> Result<Expr, ParseError> {
1242        let scrutinee = self.parse_match_scrutinee()?;
1243        self.expect(TokenKind::LBrace)?;
1244        let mut arms = Vec::new();
1245        while !self.check(TokenKind::RBrace) {
1246            arms.push(self.parse_match_arm()?);
1247        }
1248        self.expect(TokenKind::RBrace)?;
1249        Ok(Expr {
1250            kind: ExprKind::Match {
1251                scrutinee: Box::new(scrutinee),
1252                arms,
1253            },
1254            span: Span::new(start, self.previous_end()),
1255        })
1256    }
1257
1258    /// Scrutinee parsing that does not treat `name {` as a struct literal.
1259    /// `match color { … }` would otherwise consume `color { … }` as `StructLit`.
1260    fn parse_match_scrutinee(&mut self) -> Result<Expr, ParseError> {
1261        if matches!(self.peek_kind(), TokenKind::Ident(_))
1262            && matches!(self.peek_kind_at(1), TokenKind::LBrace)
1263        {
1264            let id = self.expect_ident()?;
1265            return Ok(Expr {
1266                kind: ExprKind::Ident(id.clone()),
1267                span: id.span,
1268            });
1269        }
1270        self.parse_expr()
1271    }
1272
1273    fn parse_match_arm(&mut self) -> Result<MatchArm, ParseError> {
1274        let start = self.current_start();
1275        let pat = self.parse_pat()?;
1276        let guard = if self.match_kw(Kw::If) {
1277            Some(self.parse_expr()?)
1278        } else {
1279            None
1280        };
1281        if !self.match_token(TokenKind::Arrow) {
1282            return Err(ParseError::Unexpected {
1283                expected: "`->`",
1284                found: self.peek_kind(),
1285                pos: self.current_start(),
1286                help: Some(
1287                    "if the match scrutinee is a struct literal, wrap it in parentheses: \
1288match (Name { field: value }) { ... }",
1289                ),
1290            });
1291        }
1292        let body = self.parse_expr()?;
1293        let end = body.span.end;
1294        Ok(MatchArm {
1295            pat,
1296            guard,
1297            body,
1298            span: Span::new(start, end),
1299        })
1300    }
1301
1302    fn parse_for_expr(&mut self, start: u32) -> Result<Expr, ParseError> {
1303        let pat = self.parse_pat()?;
1304        self.expect_kw(Kw::In)?;
1305        let iter = self.with_no_struct_lit(|p| p.parse_expr())?;
1306        let body = Expr {
1307            kind: ExprKind::Block(self.parse_block()?),
1308            span: Span::new(self.current_start(), self.previous_end()),
1309        };
1310        let end = body.span.end;
1311        Ok(Expr {
1312            kind: ExprKind::For {
1313                pat,
1314                iter: Box::new(iter),
1315                body: Box::new(body),
1316            },
1317            span: Span::new(start, end),
1318        })
1319    }
1320
1321    fn parse_while_expr(&mut self, start: u32) -> Result<Expr, ParseError> {
1322        let cond = self.with_no_struct_lit(|p| p.parse_expr())?;
1323        let body = Expr {
1324            kind: ExprKind::Block(self.parse_block()?),
1325            span: Span::new(self.current_start(), self.previous_end()),
1326        };
1327        let end = body.span.end;
1328        Ok(Expr {
1329            kind: ExprKind::While {
1330                cond: Box::new(cond),
1331                body: Box::new(body),
1332            },
1333            span: Span::new(start, end),
1334        })
1335    }
1336
1337    fn parse_loop_expr(&mut self, start: u32) -> Result<Expr, ParseError> {
1338        let body = Expr {
1339            kind: ExprKind::Block(self.parse_block()?),
1340            span: Span::new(self.current_start(), self.previous_end()),
1341        };
1342        let end = body.span.end;
1343        Ok(Expr {
1344            kind: ExprKind::Loop(Box::new(body)),
1345            span: Span::new(start, end),
1346        })
1347    }
1348
1349    fn parse_struct_lit(&mut self, name: Ident) -> Result<Expr, ParseError> {
1350        let start = name.span.start;
1351        self.expect(TokenKind::LBrace)?;
1352        let mut fields = Vec::new();
1353        while !self.check(TokenKind::RBrace) {
1354            let s = self.current_start();
1355            let fname = self.expect_ident()?;
1356            self.expect(TokenKind::Colon)?;
1357            let value = self.parse_expr()?;
1358            fields.push(FieldInit {
1359                name: fname,
1360                value,
1361                span: Span::new(s, self.previous_end()),
1362            });
1363        }
1364        self.expect(TokenKind::RBrace)?;
1365        Ok(Expr {
1366            kind: ExprKind::StructLit { name, fields },
1367            span: Span::new(start, self.previous_end()),
1368        })
1369    }
1370
1371    fn parse_block(&mut self) -> Result<Block, ParseError> {
1372        let start = self.current_start();
1373        self.expect(TokenKind::LBrace)?;
1374        let mut stmts = Vec::new();
1375        let mut tail = None;
1376        while !self.check(TokenKind::RBrace) && !self.check(TokenKind::Eof) {
1377            let saved = self.pos;
1378            if let Ok(stmt) = self.try_parse_binding_stmt() {
1379                stmts.push(stmt);
1380                continue;
1381            }
1382            self.pos = saved;
1383
1384            if self.is_ident() && self.peek_kind_at(1) == TokenKind::Assign {
1385                let target = self.expect_ident()?;
1386                self.advance();
1387                let value = self.parse_expr()?;
1388                stmts.push(Stmt::Assign { target, value });
1389                continue;
1390            }
1391
1392            let expr = self.parse_expr()?;
1393            if self.check(TokenKind::RBrace) {
1394                tail = Some(Box::new(expr));
1395                break;
1396            }
1397            stmts.push(Stmt::Expr(expr));
1398        }
1399        self.expect(TokenKind::RBrace)?;
1400        Ok(Block {
1401            stmts,
1402            tail,
1403            span: Span::new(start, self.previous_end()),
1404        })
1405    }
1406
1407    fn try_parse_binding_stmt(&mut self) -> Result<Stmt, ParseError> {
1408        let pat = self.parse_pat()?;
1409        let mutable = if self.match_token(TokenKind::MutColonEq) {
1410            true
1411        } else if self.match_token(TokenKind::ColonEq) {
1412            false
1413        } else {
1414            return Err(ParseError::Unexpected {
1415                expected: "`:=` or `mut:`=",
1416                found: self.peek_kind(),
1417                pos: self.current_start(),
1418                help: None,
1419            });
1420        };
1421        let value = self.parse_expr()?;
1422        Ok(Stmt::Bind {
1423            pat,
1424            mutable,
1425            value,
1426        })
1427    }
1428
1429    // ── Patterns ──────────────────────────────────────────────────────────
1430
1431    fn parse_pat(&mut self) -> Result<Pat, ParseError> {
1432        let start = self.current_start();
1433        if let TokenKind::Ident(name) = self.peek_kind()
1434            && name == "_"
1435        {
1436            self.advance();
1437            return Ok(Pat {
1438                kind: PatKind::Wildcard,
1439                span: Span::new(start, self.previous_end()),
1440            });
1441        }
1442        if self.is_int() || self.is_string() {
1443            let expr = self.parse_primary()?;
1444            return Ok(Pat {
1445                kind: PatKind::Literal(Box::new(expr)),
1446                span: Span::new(start, self.previous_end()),
1447            });
1448        }
1449        if self.match_token(TokenKind::LParen) {
1450            if self.check(TokenKind::RParen) {
1451                self.advance();
1452                return Ok(Pat {
1453                    kind: PatKind::Literal(Box::new(Expr {
1454                        kind: ExprKind::Unit,
1455                        span: Span::new(start, self.previous_end()),
1456                    })),
1457                    span: Span::new(start, self.previous_end()),
1458                });
1459            }
1460            let mut pats = vec![self.parse_pat()?];
1461            while self.match_token(TokenKind::Comma) {
1462                pats.push(self.parse_pat()?);
1463            }
1464            self.expect(TokenKind::RParen)?;
1465            return Ok(Pat {
1466                kind: PatKind::Tuple(pats),
1467                span: Span::new(start, self.previous_end()),
1468            });
1469        }
1470        if self.match_token(TokenKind::LBrace) {
1471            let name = self.expect_ident()?;
1472            let mut fields = Vec::new();
1473            let mut rest = None;
1474            while !self.check(TokenKind::RBrace) {
1475                if self.match_token(TokenKind::DotDot) {
1476                    rest = Some(self.expect_ident()?);
1477                    break;
1478                }
1479                let fname = self.expect_ident()?;
1480                let pat = if self.match_token(TokenKind::Colon) {
1481                    Some(self.parse_pat()?)
1482                } else {
1483                    None
1484                };
1485                fields.push(FieldPat {
1486                    name: fname,
1487                    pat,
1488                    span: Span::new(start, self.previous_end()),
1489                });
1490            }
1491            self.expect(TokenKind::RBrace)?;
1492            return Ok(Pat {
1493                kind: PatKind::Struct { name, fields, rest },
1494                span: Span::new(start, self.previous_end()),
1495            });
1496        }
1497        let name = self.expect_ident()?;
1498        // Qualified enum pattern: Color.Red / Color.Custom(r, g, b)
1499        if self.match_token(TokenKind::Dot) {
1500            let variant = self.expect_ident()?;
1501            let args = if self.match_token(TokenKind::LParen) {
1502                let mut args = Vec::new();
1503                while !self.check(TokenKind::RParen) {
1504                    args.push(self.parse_pat()?);
1505                    if !self.match_token(TokenKind::Comma) {
1506                        break;
1507                    }
1508                }
1509                self.expect(TokenKind::RParen)?;
1510                args
1511            } else {
1512                vec![]
1513            };
1514            return Ok(Pat {
1515                kind: PatKind::Enum {
1516                    name,
1517                    variant,
1518                    args,
1519                },
1520                span: Span::new(start, self.previous_end()),
1521            });
1522        }
1523        // Unqualified ctor pattern: Custom(r, g, b) — variant name equals type slot
1524        if self.match_token(TokenKind::LParen) {
1525            let mut args = Vec::new();
1526            while !self.check(TokenKind::RParen) {
1527                args.push(self.parse_pat()?);
1528                if !self.match_token(TokenKind::Comma) {
1529                    break;
1530                }
1531            }
1532            self.expect(TokenKind::RParen)?;
1533            return Ok(Pat {
1534                kind: PatKind::Enum {
1535                    name: name.clone(),
1536                    variant: name,
1537                    args,
1538                },
1539                span: Span::new(start, self.previous_end()),
1540            });
1541        }
1542        Ok(Pat {
1543            kind: PatKind::Ident(name),
1544            span: Span::new(start, self.previous_end()),
1545        })
1546    }
1547
1548    // ── Helpers ───────────────────────────────────────────────────────────
1549
1550    fn parse_binary<F>(
1551        &mut self,
1552        mut next: F,
1553        tok: TokenKind,
1554        op: BinaryOp,
1555    ) -> Result<Expr, ParseError>
1556    where
1557        F: FnMut(&mut Self) -> Result<Expr, ParseError>,
1558    {
1559        let mut left = next(self)?;
1560        while self.check(tok.clone()) {
1561            self.advance();
1562            let right = next(self)?;
1563            let span = left.span.merge(right.span);
1564            left = Expr {
1565                kind: ExprKind::Binary {
1566                    op,
1567                    left: Box::new(left),
1568                    right: Box::new(right),
1569                },
1570                span,
1571            };
1572        }
1573        Ok(left)
1574    }
1575
1576    #[allow(clippy::while_let_on_iterator)]
1577    fn parse_string_parts(&mut self, s: &str, start: u32) -> Result<StringParts, ParseError> {
1578        let mut parts = Vec::new();
1579        let mut lit = String::new();
1580        let mut chars = s.chars().peekable();
1581        let iter = chars.by_ref();
1582        while let Some(c) = iter.next() {
1583            if c == '{' {
1584                if !lit.is_empty() {
1585                    parts.push(StringPart::Lit(std::mem::take(&mut lit)));
1586                }
1587                let mut depth = 1i32;
1588                let mut expr_text = String::new();
1589                while let Some(ch) = iter.next() {
1590                    if ch == '{' {
1591                        depth += 1;
1592                    }
1593                    if ch == '}' {
1594                        depth -= 1;
1595                        if depth == 0 {
1596                            break;
1597                        }
1598                    }
1599                    expr_text.push(ch);
1600                }
1601                let mut sub = Parser::new(&expr_text)?;
1602                let expr = sub.parse_expr()?;
1603                parts.push(StringPart::Expr(Box::new(expr)));
1604            } else {
1605                lit.push(c);
1606            }
1607        }
1608        if !lit.is_empty() {
1609            parts.push(StringPart::Lit(lit));
1610        }
1611        if parts.is_empty() {
1612            parts.push(StringPart::Lit(String::new()));
1613        }
1614        let _ = start;
1615        Ok(StringParts(parts))
1616    }
1617
1618    fn parse_args(&mut self) -> Result<Vec<Expr>, ParseError> {
1619        let mut args = Vec::new();
1620        if self.check(TokenKind::RParen) {
1621            return Ok(args);
1622        }
1623        loop {
1624            args.push(self.parse_expr()?);
1625            if !self.match_token(TokenKind::Comma) {
1626                break;
1627            }
1628        }
1629        Ok(args)
1630    }
1631
1632    fn is_ident(&self) -> bool {
1633        matches!(self.peek_kind(), TokenKind::Ident(_))
1634    }
1635
1636    fn is_int(&self) -> bool {
1637        matches!(self.peek_kind(), TokenKind::Int(_))
1638    }
1639
1640    fn is_string(&self) -> bool {
1641        matches!(self.peek_kind(), TokenKind::String(_))
1642    }
1643
1644    fn check_expr_start(&self) -> bool {
1645        !matches!(
1646            self.peek_kind(),
1647            TokenKind::RBrace | TokenKind::Eof | TokenKind::RParen
1648        )
1649    }
1650
1651    fn check_lifetime(&self) -> bool {
1652        matches!(self.peek_kind(), TokenKind::Lifetime(_))
1653    }
1654
1655    fn parse_lifetime_ident(&mut self) -> Result<Ident, ParseError> {
1656        let t = self.advance();
1657        let TokenKind::Lifetime(name) = t.kind else {
1658            return Err(self.unexpected("lifetime", t.kind));
1659        };
1660        Ok(Ident::new(name, Span::new(t.start, t.end)))
1661    }
1662
1663    fn expect_ident(&mut self) -> Result<Ident, ParseError> {
1664        let t = self.advance();
1665        match t.kind {
1666            TokenKind::Ident(name) => Ok(Ident::new(name, Span::new(t.start, t.end))),
1667            other => Err(ParseError::Unexpected {
1668                expected: "identifier",
1669                found: other,
1670                pos: t.start,
1671                help: None,
1672            }),
1673        }
1674    }
1675
1676    fn expect_ident_or_kw_as_ident(&mut self) -> Result<Ident, ParseError> {
1677        self.expect_ident()
1678    }
1679
1680    fn expect_string_lit(&mut self) -> Result<String, ParseError> {
1681        let t = self.advance();
1682        match t.kind {
1683            TokenKind::String(s) => Ok(s),
1684            other => Err(ParseError::Unexpected {
1685                expected: "string literal",
1686                found: other,
1687                pos: t.start,
1688                help: None,
1689            }),
1690        }
1691    }
1692
1693    fn expect_kw(&mut self, kw: Kw) -> Result<(), ParseError> {
1694        if self.match_kw(kw) {
1695            Ok(())
1696        } else {
1697            Err(self.unexpected(
1698                std::str::from_utf8(kw_bytes(kw)).unwrap_or("keyword"),
1699                self.peek_kind(),
1700            ))
1701        }
1702    }
1703
1704    fn expect(&mut self, kind: TokenKind) -> Result<(), ParseError> {
1705        if self.match_token(kind.clone()) {
1706            Ok(())
1707        } else {
1708            Err(self.unexpected("token", self.peek_kind()))
1709        }
1710    }
1711
1712    fn match_kw(&mut self, kw: Kw) -> bool {
1713        if matches!(self.peek_kind(), TokenKind::Kw(k) if k == kw) {
1714            self.advance();
1715            true
1716        } else {
1717            false
1718        }
1719    }
1720
1721    fn match_kw_opt(&mut self) -> Option<Kw> {
1722        if let TokenKind::Kw(kw) = self.peek_kind() {
1723            let k = kw;
1724            self.advance();
1725            Some(k)
1726        } else {
1727            None
1728        }
1729    }
1730
1731    fn match_token(&mut self, kind: TokenKind) -> bool {
1732        if self.check(kind.clone()) {
1733            self.advance();
1734            true
1735        } else {
1736            false
1737        }
1738    }
1739
1740    /// Path separator `::` (two `Colon` tokens), for `use rust::serde_json { … }`.
1741    fn match_colon_colon(&mut self) -> bool {
1742        if self.check(TokenKind::Colon) && self.peek_kind_at(1) == TokenKind::Colon {
1743            self.advance();
1744            self.advance();
1745            true
1746        } else {
1747            false
1748        }
1749    }
1750
1751    fn check(&self, kind: TokenKind) -> bool {
1752        self.peek_kind() == kind
1753    }
1754
1755    fn peek_kind(&self) -> TokenKind {
1756        self.tokens
1757            .get(self.pos)
1758            .map(|t| t.kind.clone())
1759            .unwrap_or(TokenKind::Eof)
1760    }
1761
1762    fn peek_kind_at(&self, offset: usize) -> TokenKind {
1763        self.tokens
1764            .get(self.pos + offset)
1765            .map(|t| t.kind.clone())
1766            .unwrap_or(TokenKind::Eof)
1767    }
1768
1769    fn advance(&mut self) -> Token {
1770        let t = self.tokens[self.pos].clone();
1771        if !matches!(t.kind, TokenKind::Eof) {
1772            self.pos += 1;
1773        }
1774        t
1775    }
1776
1777    fn current_start(&self) -> u32 {
1778        self.tokens.get(self.pos).map(|t| t.start).unwrap_or(0)
1779    }
1780
1781    fn previous_start(&self) -> u32 {
1782        if self.pos == 0 {
1783            0
1784        } else {
1785            self.tokens[self.pos - 1].start
1786        }
1787    }
1788
1789    fn previous_end(&self) -> u32 {
1790        if self.pos == 0 {
1791            0
1792        } else {
1793            self.tokens[self.pos - 1].end
1794        }
1795    }
1796
1797    fn previous_span(&self) -> Span {
1798        Span::new(self.previous_start(), self.previous_end())
1799    }
1800
1801    fn unexpected(&self, expected: &'static str, found: TokenKind) -> ParseError {
1802        ParseError::Unexpected {
1803            expected,
1804            found,
1805            pos: self.current_start(),
1806            help: None,
1807        }
1808    }
1809}
1810
1811fn kw_bytes(_kw: Kw) -> &'static [u8] {
1812    b"keyword"
1813}
1814
1815trait ItemSpan {
1816    fn span(&self) -> Span;
1817}
1818
1819impl ItemSpan for Item {
1820    fn span(&self) -> Span {
1821        match self {
1822            Item::Function(f) => f.span,
1823            Item::TypeDef(t) => t.span,
1824            Item::TraitDef(t) => t.span,
1825            Item::ShapeDef(s) => s.span,
1826            Item::Impl(i) => i.span,
1827            Item::Use(u) => u.span,
1828            Item::Const(c) => c.span,
1829            Item::Extern(e) => e.span,
1830            Item::Test(t) => t.span,
1831            Item::TestCompileFail(t) => t.span,
1832        }
1833    }
1834}