cl_parser/
parser.rs

1use super::*;
2use crate::error::{
3    Error,
4    ErrorKind::{self, *},
5    PResult, Parsing,
6};
7use cl_ast::*;
8use cl_lexer::Lexer;
9
10// Precedence climbing expression parser
11mod prec;
12
13/// Parses a sequence of [Tokens](Token) into an [AST](cl_ast)
14#[derive(Debug)]
15pub struct Parser<'t> {
16    /// Name of the file being parsed
17    file: Sym,
18    /// Lazy tokenizer
19    lexer: Lexer<'t>,
20    /// Look-ahead buffer
21    next: Option<Token>,
22    /// The location of the current token
23    loc: Loc,
24}
25
26/// Basic parser functionality
27impl<'t> Parser<'t> {
28    pub fn new(filename: impl AsRef<str>, lexer: Lexer<'t>) -> Self {
29        Self { file: filename.as_ref().into(), loc: Loc::from(&lexer), lexer, next: None }
30    }
31
32    /// Gets the location of the last consumed [Token]
33    pub fn loc(&self) -> Loc {
34        self.loc
35    }
36
37    /// Attempts to parse anything that implements the [Parse] trait
38    #[inline]
39    pub fn parse<P: Parse<'t>>(&mut self) -> PResult<P> {
40        P::parse(self)
41    }
42
43    /// Constructs an [Error]
44    pub fn error(&self, reason: ErrorKind, while_parsing: Parsing) -> Error {
45        Error { in_file: self.file, reason, while_parsing, loc: self.loc }
46    }
47
48    /// Internal impl of peek and consume
49    fn consume_from_lexer(&mut self, while_parsing: Parsing) -> PResult<Token> {
50        loop {
51            let tok = self
52                .lexer
53                .scan()
54                .map_err(|e| self.error(e.into(), while_parsing))?;
55            match tok.ty {
56                TokenKind::Comment | TokenKind::Invalid => continue,
57                _ => break Ok(tok),
58            }
59        }
60    }
61
62    /// Looks ahead one token
63    ///
64    /// Stores the token in an internal lookahead buffer
65    pub fn peek(&mut self, while_parsing: Parsing) -> PResult<&Token> {
66        if self.next.is_none() {
67            self.next = Some(self.consume_from_lexer(while_parsing)?);
68        }
69        self.next.as_ref().ok_or_else(|| unreachable!())
70    }
71
72    /// Looks ahead at the next [Token]'s [TokenKind]
73    pub fn peek_kind(&mut self, while_parsing: Parsing) -> PResult<TokenKind> {
74        self.peek(while_parsing).map(|t| t.ty)
75    }
76
77    /// Consumes a previously peeked [Token], returning it.
78    /// Returns [None] when there is no peeked token.
79    ///
80    /// This avoids the overhead of constructing an [Error]
81    pub fn consume_peeked(&mut self) -> Option<Token> {
82        // location must be updated whenever a token is pulled from the lexer
83        self.loc = Loc::from(&self.lexer);
84        self.next.take()
85    }
86
87    /// Consumes one [Token]
88    pub fn consume(&mut self, while_parsing: Parsing) -> PResult<Token> {
89        match self.consume_peeked() {
90            Some(token) => Ok(token),
91            None => self.consume_from_lexer(while_parsing),
92        }
93    }
94
95    /// Consumes the next [Token] if it matches the pattern [TokenKind]
96    pub fn match_type(&mut self, want: TokenKind, while_parsing: Parsing) -> PResult<Token> {
97        let got = self.peek_kind(while_parsing)?;
98        if got == want {
99            Ok(self.consume_peeked().expect("should not fail after peek"))
100        } else {
101            Err(self.error(ExpectedToken { want, got }, while_parsing))
102        }
103    }
104}
105
106// the three matched delimiter pairs
107/// Square brackets: `[` `]`
108const BRACKETS: (TokenKind, TokenKind) = (TokenKind::LBrack, TokenKind::RBrack);
109
110/// Curly braces: `{` `}`
111const CURLIES: (TokenKind, TokenKind) = (TokenKind::LCurly, TokenKind::RCurly);
112
113/// Parentheses: `(` `)`
114const PARENS: (TokenKind, TokenKind) = (TokenKind::LParen, TokenKind::RParen);
115
116/// Parses constructions of the form `delim.0 f delim.1` (i.e. `(` `foobar` `)`)
117const fn delim<'t, T>(
118    f: impl Fn(&mut Parser<'t>) -> PResult<T>,
119    delim: (TokenKind, TokenKind),
120    while_parsing: Parsing,
121) -> impl Fn(&mut Parser<'t>) -> PResult<T> {
122    move |parser| {
123        parser.match_type(delim.0, while_parsing)?;
124        let out = f(parser)?;
125        parser.match_type(delim.1, while_parsing)?;
126        Ok(out)
127    }
128}
129
130/// Parses constructions of the form `(f sep ~until)*`
131///
132/// where `~until` is a negative lookahead assertion
133const fn sep<'t, T>(
134    f: impl Fn(&mut Parser<'t>) -> PResult<T>,
135    sep: TokenKind,
136    until: TokenKind,
137    while_parsing: Parsing,
138) -> impl Fn(&mut Parser<'t>) -> PResult<Vec<T>> {
139    move |parser| {
140        let mut args = vec![];
141        while until != parser.peek_kind(while_parsing)? {
142            args.push(f(parser)?);
143            if sep != parser.peek_kind(while_parsing)? {
144                break;
145            }
146            parser.consume_peeked();
147        }
148        Ok(args)
149    }
150}
151
152/// Parses constructions of the form `(f ~until)*`
153///
154/// where `~until` is a negative lookahead assertion
155const fn rep<'t, T>(
156    f: impl Fn(&mut Parser<'t>) -> PResult<T>,
157    until: TokenKind,
158    while_parsing: Parsing,
159) -> impl Fn(&mut Parser<'t>) -> PResult<Vec<T>> {
160    move |parser| {
161        let mut out = vec![];
162        while until != parser.peek_kind(while_parsing)? {
163            out.push(f(parser)?)
164        }
165        Ok(out)
166    }
167}
168
169/// Expands to a pattern which matches item-like [TokenKind]s
170macro item_like() {
171    TokenKind::Hash
172        | TokenKind::Pub
173        | TokenKind::Type
174        | TokenKind::Const
175        | TokenKind::Static
176        | TokenKind::Mod
177        | TokenKind::Fn
178        | TokenKind::Struct
179        | TokenKind::Enum
180        | TokenKind::Impl
181        | TokenKind::Use
182}
183
184/// Expands to a pattern which matches literal-like [TokenKind]s
185macro literal_like() {
186    TokenKind::True | TokenKind::False | TokenKind::Literal
187}
188
189/// Expands to a pattern which matches path-like [TokenKinds](TokenKind)
190macro path_like() {
191    TokenKind::Super | TokenKind::SelfTy | TokenKind::Identifier | TokenKind::ColonColon
192}
193
194pub trait Parse<'t>: Sized {
195    /// Parses a Self from the provided [Parser]
196    fn parse(p: &mut Parser<'t>) -> PResult<Self>;
197}
198
199impl Parse<'_> for Sym {
200    /// [Sym] = [`Identifier`](TokenKind::Identifier)
201    fn parse(p: &mut Parser) -> PResult<Sym> {
202        let tok = p.match_type(TokenKind::Identifier, Parsing::Identifier)?;
203        match tok.data() {
204            TokenData::String(ident) => Ok(ident.into()),
205            _ => panic!("Expected token data for {tok:?}"),
206        }
207    }
208}
209
210impl Parse<'_> for Mutability {
211    /// [Mutability] = `mut`?
212    #[inline]
213    fn parse(p: &mut Parser) -> PResult<Mutability> {
214        Ok(match p.match_type(TokenKind::Mut, Parsing::Mutability) {
215            Ok(_) => Mutability::Mut,
216            Err(_) => Mutability::Not,
217        })
218    }
219}
220
221impl Parse<'_> for Visibility {
222    /// [Visibility] = `pub`?
223    #[inline]
224    fn parse(p: &mut Parser) -> PResult<Self> {
225        Ok(match p.match_type(TokenKind::Pub, Parsing::Visibility) {
226            Ok(_) => Visibility::Public,
227            Err(_) => Visibility::Private,
228        })
229    }
230}
231
232impl Parse<'_> for Literal {
233    /// [Literal] = [LITERAL](TokenKind::Literal) | `true` | `false`
234    fn parse(p: &mut Parser) -> PResult<Literal> {
235        let Token { ty, data, .. } = p.consume(Parsing::Literal)?;
236        match ty {
237            TokenKind::True => return Ok(Literal::Bool(true)),
238            TokenKind::False => return Ok(Literal::Bool(false)),
239            TokenKind::Literal => (),
240            t => return Err(p.error(Unexpected(t), Parsing::Literal)),
241        }
242        Ok(match data {
243            TokenData::String(v) => Literal::String(v),
244            TokenData::Character(v) => Literal::Char(v),
245            TokenData::Integer(v) => Literal::Int(v),
246            TokenData::Float(v) => Literal::Float(v.to_bits()),
247            _ => panic!("Expected token data for {ty:?}"),
248        })
249    }
250}
251
252impl Parse<'_> for File {
253    /// Parses a [File]
254    fn parse(p: &mut Parser<'_>) -> PResult<Self> {
255        let mut items = vec![];
256        while match p.peek_kind(Parsing::File) {
257            Ok(TokenKind::RCurly) | Err(Error { reason: EndOfInput, .. }) => false,
258            Ok(_) => true,
259            Err(e) => Err(e)?,
260        } {
261            items.push(Item::parse(p)?);
262            let _ = p.match_type(TokenKind::Semi, Parsing::File);
263        }
264        Ok(File { name: p.file.to_ref(), items })
265    }
266}
267
268impl Parse<'_> for Attrs {
269    /// Parses an [attribute set](Attrs)
270    fn parse(p: &mut Parser) -> PResult<Attrs> {
271        if p.match_type(TokenKind::Hash, Parsing::Attrs).is_err() {
272            return Ok(Attrs { meta: vec![] });
273        }
274        let meta = delim(
275            sep(Meta::parse, TokenKind::Comma, BRACKETS.1, Parsing::Attrs),
276            BRACKETS,
277            Parsing::Attrs,
278        )(p)?;
279        Ok(Attrs { meta })
280    }
281}
282
283impl Parse<'_> for Meta {
284    /// Parses a single [attribute](Meta)
285    fn parse(p: &mut Parser) -> PResult<Meta> {
286        Ok(Meta { name: Sym::parse(p)?, kind: MetaKind::parse(p)? })
287    }
288}
289
290impl Parse<'_> for MetaKind {
291    /// Parses data associated with a [Meta] attribute
292    fn parse(p: &mut Parser) -> PResult<MetaKind> {
293        const P: Parsing = Parsing::Meta;
294        let tuple = delim(sep(Parse::parse, TokenKind::Comma, PARENS.1, P), PARENS, P);
295        Ok(match p.peek_kind(P) {
296            Ok(TokenKind::Eq) => {
297                p.consume_peeked();
298                MetaKind::Equals(p.parse()?)
299            }
300            Ok(TokenKind::LParen) => MetaKind::Func(tuple(p)?),
301            _ => MetaKind::Plain,
302        })
303    }
304}
305
306// --- Items ---
307
308impl Parse<'_> for Item {
309    /// Parses an [Item]
310    ///
311    /// See also: [ItemKind::parse]
312    fn parse(p: &mut Parser<'_>) -> PResult<Self> {
313        let start = p.loc();
314        Ok(Item {
315            attrs: Attrs::parse(p)?,
316            vis: Visibility::parse(p)?,
317            kind: ItemKind::parse(p)?,
318            span: Span(start, p.loc()),
319        })
320    }
321}
322
323impl Parse<'_> for ItemKind {
324    /// Parses an [ItemKind]
325    ///
326    /// See also: [Item::parse]
327    fn parse(p: &mut Parser) -> PResult<Self> {
328        Ok(match p.peek_kind(Parsing::Item)? {
329            TokenKind::Type => ItemKind::Alias(p.parse()?),
330            TokenKind::Const => ItemKind::Const(p.parse()?),
331            TokenKind::Static => ItemKind::Static(p.parse()?),
332            TokenKind::Mod => ItemKind::Module(p.parse()?),
333            TokenKind::Fn => ItemKind::Function(p.parse()?),
334            TokenKind::Struct => ItemKind::Struct(p.parse()?),
335            TokenKind::Enum => ItemKind::Enum(p.parse()?),
336            TokenKind::Impl => ItemKind::Impl(p.parse()?),
337            TokenKind::Use => ItemKind::Use(p.parse()?),
338            t => Err(p.error(Unexpected(t), Parsing::Item))?,
339        })
340    }
341}
342
343impl Parse<'_> for Generics {
344    fn parse(p: &mut Parser<'_>) -> PResult<Self> {
345        const P: Parsing = Parsing::Generics;
346        let vars = match p.peek_kind(P)? {
347            TokenKind::Lt => delim(
348                sep(Sym::parse, TokenKind::Comma, TokenKind::Gt, P),
349                (TokenKind::Lt, TokenKind::Gt),
350                P,
351            )(p)?,
352            _ => Vec::new(),
353        };
354        Ok(Generics { vars })
355    }
356}
357
358impl Parse<'_> for Alias {
359    /// Parses a [`type` alias](Alias)
360    fn parse(p: &mut Parser<'_>) -> PResult<Self> {
361        const P: Parsing = Parsing::Alias;
362        p.consume_peeked();
363
364        let out = Ok(Alias {
365            name: Sym::parse(p)?,
366            from: if p.match_type(TokenKind::Eq, P).is_ok() {
367                Some(p.parse()?)
368            } else {
369                None
370            },
371        });
372        p.match_type(TokenKind::Semi, P)?;
373        out
374    }
375}
376
377impl Parse<'_> for Const {
378    /// Parses a [compile-time constant](Const)
379    fn parse(p: &mut Parser) -> PResult<Const> {
380        const P: Parsing = Parsing::Const;
381        p.consume_peeked();
382
383        let out = Ok(Const {
384            name: Sym::parse(p)?,
385            ty: {
386                p.match_type(TokenKind::Colon, P)?;
387                Ty::parse(p)?.into()
388            },
389            init: {
390                p.match_type(TokenKind::Eq, P)?;
391                p.parse()?
392            },
393        });
394        p.match_type(TokenKind::Semi, P)?;
395        out
396    }
397}
398
399impl Parse<'_> for Static {
400    /// Parses a [`static` item](Static)
401    fn parse(p: &mut Parser) -> PResult<Static> {
402        const P: Parsing = Parsing::Static;
403        p.consume_peeked();
404
405        let out = Ok(Static {
406            mutable: Mutability::parse(p)?,
407            name: Sym::parse(p)?,
408            ty: {
409                p.match_type(TokenKind::Colon, P)?;
410                p.parse()?
411            },
412            init: {
413                p.match_type(TokenKind::Eq, P)?;
414                p.parse()?
415            },
416        });
417        p.match_type(TokenKind::Semi, P)?;
418        out
419    }
420}
421
422impl Parse<'_> for Module {
423    /// Parses a [Module]
424    fn parse(p: &mut Parser<'_>) -> PResult<Self> {
425        p.consume_peeked();
426
427        Ok(Module {
428            name: Sym::parse(p)?,
429            file: {
430                const P: Parsing = Parsing::ModuleKind;
431                let inline = delim(Parse::parse, CURLIES, P);
432
433                match p.peek_kind(P)? {
434                    TokenKind::LCurly => Some(inline(p)?),
435                    TokenKind::Semi => {
436                        p.consume_peeked();
437                        None
438                    }
439                    got => Err(p.error(ExpectedToken { want: TokenKind::Semi, got }, P))?,
440                }
441            },
442        })
443    }
444}
445
446impl Parse<'_> for Function {
447    /// Parses a [Function] definition
448    fn parse(p: &mut Parser) -> PResult<Function> {
449        const P: Parsing = Parsing::Function;
450        p.consume_peeked();
451
452        let name = Sym::parse(p)?;
453        let gens = Generics::parse(p)?;
454        let (bind, types) = delim(FnSig::parse, PARENS, P)(p)?;
455        let sign = TyFn {
456            args: Box::new(match types.len() {
457                0 => TyKind::Empty,
458                _ => TyKind::Tuple(TyTuple { types }),
459            }),
460            rety: Ok(match p.match_type(TokenKind::Arrow, Parsing::TyFn) {
461                Ok(_) => Some(Ty::parse(p)?),
462                Err(_) => None,
463            })?
464            .map(Box::new),
465        };
466        Ok(Function {
467            name,
468            gens,
469            sign,
470            bind,
471            body: match p.peek_kind(P)? {
472                TokenKind::Semi => {
473                    p.consume_peeked();
474                    None
475                }
476                _ => Some(Expr::parse(p)?),
477            },
478        })
479    }
480}
481
482type FnSig = (Pattern, Vec<TyKind>);
483
484impl Parse<'_> for FnSig {
485    /// Parses the parameter list of a Function
486    fn parse(p: &mut Parser) -> PResult<FnSig> {
487        const P: Parsing = Parsing::Function;
488        let (mut params, mut types) = (vec![], vec![]);
489        while Ok(TokenKind::RParen) != p.peek_kind(P) {
490            let (param, ty) = TypedParam::parse(p)?;
491            params.push(param);
492            types.push(ty);
493            if p.match_type(TokenKind::Comma, P).is_err() {
494                break;
495            }
496        }
497        Ok((Pattern::Tuple(params), types))
498    }
499}
500
501type TypedParam = (Pattern, TyKind);
502
503impl Parse<'_> for TypedParam {
504    /// Parses a single function parameter
505    fn parse(p: &mut Parser) -> PResult<(Pattern, TyKind)> {
506        Ok((
507            Pattern::parse(p)?,
508            if p.match_type(TokenKind::Colon, Parsing::Param).is_ok() {
509                TyKind::parse(p)?
510            } else {
511                TyKind::Infer
512            },
513        ))
514    }
515}
516
517impl Parse<'_> for Struct {
518    /// Parses a [`struct` definition](Struct)
519    fn parse(p: &mut Parser) -> PResult<Struct> {
520        p.match_type(TokenKind::Struct, Parsing::Struct)?;
521        Ok(Struct { name: Sym::parse(p)?, gens: Generics::parse(p)?, kind: StructKind::parse(p)? })
522    }
523}
524
525impl Parse<'_> for StructKind {
526    /// Parses the various [kinds of Struct](StructKind)
527    fn parse(p: &mut Parser<'_>) -> PResult<Self> {
528        const P: Parsing = Parsing::StructKind;
529        Ok(match p.peek_kind(P) {
530            Ok(TokenKind::LParen) => StructKind::Tuple(delim(
531                sep(Ty::parse, TokenKind::Comma, PARENS.1, P),
532                PARENS,
533                P,
534            )(p)?),
535            Ok(TokenKind::LCurly) => StructKind::Struct(delim(
536                sep(StructMember::parse, TokenKind::Comma, CURLIES.1, P),
537                CURLIES,
538                P,
539            )(p)?),
540            Ok(_) | Err(Error { reason: ErrorKind::EndOfInput, .. }) => StructKind::Empty,
541            Err(e) => Err(e)?,
542        })
543    }
544}
545
546impl Parse<'_> for StructMember {
547    /// Parses a single [StructMember]
548    fn parse(p: &mut Parser) -> PResult<StructMember> {
549        const P: Parsing = Parsing::StructMember;
550        Ok(StructMember {
551            vis: Visibility::parse(p)?,
552            name: Sym::parse(p)?,
553            ty: {
554                p.match_type(TokenKind::Colon, P)?;
555                Ty::parse(p)?
556            },
557        })
558    }
559}
560
561impl Parse<'_> for Enum {
562    /// Parses an [`enum`](Enum) definition
563    fn parse(p: &mut Parser) -> PResult<Enum> {
564        p.match_type(TokenKind::Enum, Parsing::Enum)?;
565        Ok(Enum {
566            name: Sym::parse(p)?,
567            gens: Generics::parse(p)?,
568            variants: {
569                const P: Parsing = Parsing::EnumKind;
570                match p.peek_kind(P)? {
571                    TokenKind::LCurly => delim(
572                        sep(Variant::parse, TokenKind::Comma, TokenKind::RCurly, P),
573                        CURLIES,
574                        P,
575                    )(p)?,
576                    t => Err(p.error(Unexpected(t), P))?,
577                }
578            },
579        })
580    }
581}
582
583impl Parse<'_> for Variant {
584    /// Parses an [`enum`](Enum) [Variant]
585    fn parse(p: &mut Parser) -> PResult<Variant> {
586        let name = Sym::parse(p)?;
587        let kind;
588        let body;
589
590        if p.match_type(TokenKind::Eq, Parsing::Variant).is_ok() {
591            kind = StructKind::Empty;
592            body = Some(Box::new(Expr::parse(p)?));
593        } else {
594            kind = StructKind::parse(p)?;
595            body = None;
596        }
597
598        Ok(Variant { name, kind, body })
599    }
600}
601
602impl Parse<'_> for Impl {
603    fn parse(p: &mut Parser) -> PResult<Impl> {
604        const P: Parsing = Parsing::Impl;
605        p.match_type(TokenKind::Impl, P)?;
606
607        Ok(Impl { target: ImplKind::parse(p)?, body: delim(File::parse, CURLIES, P)(p)? })
608    }
609}
610
611impl Parse<'_> for ImplKind {
612    fn parse(p: &mut Parser<'_>) -> PResult<Self> {
613        const P: Parsing = Parsing::ImplKind;
614
615        let target = Ty::parse(p)?;
616
617        if p.match_type(TokenKind::For, P).is_err() {
618            Ok(ImplKind::Type(target))
619        } else if let TyKind::Path(impl_trait) = target.kind {
620            Ok(ImplKind::Trait { impl_trait, for_type: Ty::parse(p)?.into() })
621        } else {
622            Err(Error {
623                in_file: p.file,
624                reason: ExpectedParsing { want: Parsing::Path },
625                while_parsing: P,
626                loc: target.span.head,
627            })?
628        }
629    }
630}
631
632impl Parse<'_> for Use {
633    fn parse(p: &mut Parser) -> PResult<Use> {
634        const P: Parsing = Parsing::Use;
635        p.match_type(TokenKind::Use, P)?;
636
637        let absolute = p.match_type(TokenKind::ColonColon, P).is_ok();
638        let tree = UseTree::parse(p)?;
639        p.match_type(TokenKind::Semi, P)?;
640        Ok(Use { tree, absolute })
641    }
642}
643
644impl Parse<'_> for UseTree {
645    fn parse(p: &mut Parser) -> PResult<Self> {
646        const P: Parsing = Parsing::UseTree;
647        // glob import
648        Ok(match p.peek_kind(P)? {
649            TokenKind::Star => {
650                p.consume_peeked();
651                UseTree::Glob
652            }
653            TokenKind::LCurly => UseTree::Tree(delim(
654                sep(Parse::parse, TokenKind::Comma, CURLIES.1, P),
655                CURLIES,
656                P,
657            )(p)?),
658            TokenKind::Super | TokenKind::Identifier => {
659                let name = PathPart::parse(p)?;
660                if p.match_type(TokenKind::ColonColon, P).is_ok() {
661                    UseTree::Path(name, Box::new(UseTree::parse(p)?))
662                } else {
663                    let PathPart::Ident(name) = name else {
664                        Err(p.error(ErrorKind::ExpectedParsing { want: Parsing::Identifier }, P))?
665                    };
666                    if p.match_type(TokenKind::As, P).is_ok() {
667                        UseTree::Alias(name, p.parse()?)
668                    } else {
669                        UseTree::Name(name)
670                    }
671                }
672            }
673            t => Err(p.error(Unexpected(t), Parsing::UseTree))?,
674        })
675    }
676}
677
678// --- Types ---
679
680impl Parse<'_> for Ty {
681    /// Parses a [Ty]
682    ///
683    /// See also: [TyKind::parse]
684    fn parse(p: &mut Parser<'_>) -> PResult<Self> {
685        let start = p.loc();
686        Ok(Ty { kind: TyKind::parse(p)?, span: Span(start, p.loc()) })
687    }
688}
689
690impl Parse<'_> for TyKind {
691    /// Parses a [TyKind]
692    ///
693    /// See also: [Ty::parse]
694    fn parse(p: &mut Parser) -> PResult<TyKind> {
695        const P: Parsing = Parsing::TyKind;
696        let out = match p.peek_kind(P)? {
697            TokenKind::Bang => {
698                p.consume_peeked();
699                TyKind::Never
700            }
701            TokenKind::Amp | TokenKind::AmpAmp => TyRef::parse(p)?.into(),
702            TokenKind::LBrack => {
703                p.match_type(BRACKETS.0, Parsing::TySlice)?;
704                let ty = TyKind::parse(p)?;
705                let (out, kind) = match p.match_type(TokenKind::Semi, Parsing::TyArray).is_ok() {
706                    true => {
707                        let literal = p.match_type(TokenKind::Literal, Parsing::TyArray)?;
708                        let &TokenData::Integer(count) = literal.data() else {
709                            Err(p.error(Unexpected(TokenKind::Literal), Parsing::TyArray))?
710                        };
711                        (
712                            TyKind::Array(TyArray { ty: Box::new(ty), count: count as _ }),
713                            Parsing::TyArray,
714                        )
715                    }
716                    false => (
717                        TyKind::Slice(TySlice { ty: Box::new(ty) }),
718                        Parsing::TySlice,
719                    ),
720                };
721                p.match_type(BRACKETS.1, kind)?;
722                out
723            }
724            TokenKind::LParen => {
725                let out = TyTuple::parse(p)?;
726                match out.types.is_empty() {
727                    true => TyKind::Empty,
728                    false => TyKind::Tuple(out),
729                }
730            }
731            TokenKind::Fn => TyFn::parse(p)?.into(),
732            path_like!() => {
733                let path = Path::parse(p)?;
734                if path.is_sinkhole() {
735                    TyKind::Infer
736                } else {
737                    TyKind::Path(path)
738                }
739            }
740            t => Err(p.error(Unexpected(t), P))?,
741        };
742
743        Ok(out)
744    }
745}
746
747impl Parse<'_> for TyTuple {
748    /// [TyTuple] = `(` ([Ty] `,`)* [Ty]? `)`
749    fn parse(p: &mut Parser) -> PResult<TyTuple> {
750        const P: Parsing = Parsing::TyTuple;
751        Ok(TyTuple {
752            types: delim(sep(TyKind::parse, TokenKind::Comma, PARENS.1, P), PARENS, P)(p)?,
753        })
754    }
755}
756
757impl Parse<'_> for TyRef {
758    /// [TyRef] = (`&`|`&&`)* [Path]
759    fn parse(p: &mut Parser) -> PResult<TyRef> {
760        const P: Parsing = Parsing::TyRef;
761        let mut count = 0;
762        loop {
763            match p.peek_kind(P)? {
764                TokenKind::Amp => count += 1,
765                TokenKind::AmpAmp => count += 2,
766                _ => break,
767            }
768            p.consume_peeked();
769        }
770        Ok(TyRef { count, mutable: p.parse()?, to: p.parse()? })
771    }
772}
773
774impl Parse<'_> for TyFn {
775    /// [TyFn] = `fn` [TyTuple] (-> [Ty])?
776    fn parse(p: &mut Parser) -> PResult<TyFn> {
777        const P: Parsing = Parsing::TyFn;
778        p.match_type(TokenKind::Fn, P)?;
779
780        let args = delim(sep(TyKind::parse, TokenKind::Comma, PARENS.1, P), PARENS, P)(p)?;
781
782        Ok(TyFn {
783            args: Box::new(match args {
784                t if t.is_empty() => TyKind::Empty,
785                types => TyKind::Tuple(TyTuple { types }),
786            }),
787            rety: match p.match_type(TokenKind::Arrow, Parsing::TyFn) {
788                Ok(_) => Some(Ty::parse(p)?),
789                Err(_) => None,
790            }
791            .map(Into::into),
792        })
793    }
794}
795
796// --- Paths ---
797
798impl Parse<'_> for Path {
799    /// Parses a [Path]
800    ///
801    /// See also: [PathPart::parse], [Sym::parse]
802    ///
803    /// [Path] = `::` *RelativePath*? | *RelativePath* \
804    /// *RelativePath* = [PathPart] (`::` [PathPart])*
805    fn parse(p: &mut Parser) -> PResult<Path> {
806        const P: Parsing = Parsing::Path;
807        let absolute = p.match_type(TokenKind::ColonColon, P).is_ok();
808        let mut parts = vec![];
809
810        if absolute {
811            match PathPart::parse(p) {
812                Ok(part) => parts.push(part),
813                Err(_) => return Ok(Path { absolute, parts }),
814            }
815        } else {
816            parts.push(PathPart::parse(p)?)
817        };
818
819        while p.match_type(TokenKind::ColonColon, Parsing::Path).is_ok() {
820            parts.push(PathPart::parse(p)?)
821        }
822
823        Ok(Path { absolute, parts })
824    }
825}
826
827impl Parse<'_> for PathPart {
828    /// [PathPart] = `super` | `self` | [`Identifier`](TokenKind::Identifier)
829    fn parse(p: &mut Parser) -> PResult<PathPart> {
830        const P: Parsing = Parsing::PathPart;
831        let out = match p.peek_kind(P)? {
832            TokenKind::Super => PathPart::SuperKw,
833            TokenKind::SelfTy => PathPart::SelfTy,
834            TokenKind::Identifier => PathPart::Ident(Sym::parse(p)?),
835            t => return Err(p.error(Unexpected(t), P)),
836        };
837        // Note: this relies on identifier not peeking
838        p.consume_peeked();
839        Ok(out)
840    }
841}
842
843// --- Statements ---
844
845impl Parse<'_> for Stmt {
846    /// Parses a [Stmt]
847    ///
848    /// See also: [StmtKind::parse]
849    fn parse(p: &mut Parser) -> PResult<Stmt> {
850        let start = p.loc();
851        Ok(Stmt {
852            kind: StmtKind::parse(p)?,
853            semi: match p.match_type(TokenKind::Semi, Parsing::Stmt) {
854                Ok(_) => Semi::Terminated,
855                _ => Semi::Unterminated,
856            },
857            span: Span(start, p.loc()),
858        })
859    }
860}
861
862impl Parse<'_> for StmtKind {
863    /// Parses a [StmtKind]
864    ///
865    /// See also: [Stmt::parse]
866    fn parse(p: &mut Parser) -> PResult<StmtKind> {
867        Ok(match p.peek_kind(Parsing::StmtKind)? {
868            TokenKind::Semi => StmtKind::Empty,
869            item_like!() => StmtKind::Item(p.parse()?),
870            _ => StmtKind::Expr(p.parse()?),
871        })
872    }
873}
874
875// --- Expressions ---
876
877impl Parse<'_> for Expr {
878    /// Parses an [Expr]
879    fn parse(p: &mut Parser) -> PResult<Expr> {
880        prec::expr(p, 0)
881    }
882}
883
884impl Parse<'_> for Closure {
885    fn parse(p: &mut Parser<'_>) -> PResult<Self> {
886        let args = sep(
887            Pattern::parse,
888            TokenKind::Comma,
889            TokenKind::Bar,
890            Parsing::Closure,
891        );
892
893        let arg = match p.peek_kind(Parsing::Closure)? {
894            TokenKind::BarBar => {
895                p.consume_peeked();
896                Box::new(Pattern::Tuple(vec![]))
897            }
898            _ => Box::new(delim(
899                |p| args(p).map(Pattern::Tuple),
900                (TokenKind::Bar, TokenKind::Bar),
901                Parsing::Closure,
902            )(p)?),
903        };
904        let body = p.parse()?;
905        Ok(Closure { arg, body })
906    }
907}
908
909impl Parse<'_> for Quote {
910    fn parse(p: &mut Parser<'_>) -> PResult<Self> {
911        let quote = delim(
912            Expr::parse,
913            (TokenKind::Grave, TokenKind::Grave),
914            Parsing::ExprKind,
915        )(p)?
916        .into();
917        Ok(Quote { quote })
918    }
919}
920
921impl Parse<'_> for Let {
922    fn parse(p: &mut Parser) -> PResult<Let> {
923        p.consume_peeked();
924        Ok(Let {
925            mutable: p.parse()?,
926            name: p.parse()?,
927            ty: if p.match_type(TokenKind::Colon, Parsing::Let).is_ok() {
928                Some(p.parse()?)
929            } else {
930                None
931            },
932            init: if p.match_type(TokenKind::Eq, Parsing::Let).is_ok() {
933                Some(condition(p)?.into())
934            } else {
935                None
936            },
937        })
938    }
939}
940
941impl Parse<'_> for MemberKind {
942    fn parse(p: &mut Parser) -> PResult<MemberKind> {
943        const P: Parsing = Parsing::Member;
944        const DEL: (TokenKind, TokenKind) = PARENS; // delimiter
945        match p.peek_kind(P)? {
946            TokenKind::Identifier => {
947                let name = Sym::parse(p)?;
948                if p.match_type(DEL.0, P).is_err() {
949                    Ok(MemberKind::Struct(name))
950                } else {
951                    let exprs = sep(Expr::parse, TokenKind::Comma, DEL.1, P)(p)?;
952                    p.match_type(DEL.1, P)?; // should succeed
953                    Ok(MemberKind::Call(name, Tuple { exprs }))
954                }
955            }
956            TokenKind::Literal => {
957                let name = Literal::parse(p)?; // TODO: Maybe restrict this to just
958                Ok(MemberKind::Tuple(name))
959            }
960            t => Err(p.error(Unexpected(t), P)),
961        }
962    }
963}
964
965impl Parse<'_> for Fielder {
966    /// [Fielder] = [`Identifier`](TokenKind::Identifier) (`:` [Expr])?
967    fn parse(p: &mut Parser) -> PResult<Fielder> {
968        const P: Parsing = Parsing::Fielder;
969        Ok(Fielder {
970            name: Sym::parse(p)?,
971            init: match p.match_type(TokenKind::Colon, P) {
972                Ok(_) => Some(p.parse()?),
973                Err(_) => None,
974            },
975        })
976    }
977}
978
979impl Parse<'_> for AddrOf {
980    /// [AddrOf] = (`&`|`&&`)* [Expr]
981    fn parse(p: &mut Parser) -> PResult<AddrOf> {
982        const P: Parsing = Parsing::AddrOf;
983        match p.peek_kind(P)? {
984            TokenKind::Amp => {
985                p.consume_peeked();
986                Ok(AddrOf { mutable: p.parse()?, expr: p.parse()? })
987            }
988            TokenKind::AmpAmp => {
989                let start = p.loc();
990                p.consume_peeked();
991                Ok(AddrOf {
992                    mutable: Mutability::Not,
993                    expr: Expr {
994                        kind: ExprKind::AddrOf(AddrOf {
995                            mutable: Mutability::parse(p)?,
996                            expr: p.parse()?,
997                        }),
998                        span: Span(start, p.loc()),
999                    }
1000                    .into(),
1001                })
1002            }
1003            got => Err(p.error(ExpectedToken { want: TokenKind::Amp, got }, P)),
1004        }
1005    }
1006}
1007
1008impl Parse<'_> for Block {
1009    /// [Block] = `{` [Stmt]* `}`
1010    fn parse(p: &mut Parser) -> PResult<Block> {
1011        const A_BLOCK: Parsing = Parsing::Block;
1012        Ok(Block { stmts: delim(rep(Parse::parse, CURLIES.1, A_BLOCK), CURLIES, A_BLOCK)(p)? })
1013    }
1014}
1015
1016/// Conditions (which precede curly-braced blocks) get special treatment
1017fn condition(p: &mut Parser) -> PResult<Expr> {
1018    prec::expr(p, prec::Precedence::Condition.level())
1019}
1020
1021impl Parse<'_> for While {
1022    /// [While] = `while` [Expr] [Block] [Else]?
1023    #[rustfmt::skip]
1024    fn parse(p: &mut Parser) -> PResult<While> {
1025        p.match_type(TokenKind::While, Parsing::While)?;
1026        Ok(While {
1027            cond: condition(p)?.into(),
1028            pass: Block::parse(p)?.into(),
1029            fail: Else::parse(p)?
1030        })
1031    }
1032}
1033
1034impl Parse<'_> for If {
1035    /// [If] = <code>`if` [Expr] [Block] [Else]?</code>
1036    #[rustfmt::skip] // second line is barely not long enough
1037    fn parse(p: &mut Parser) -> PResult<If> {
1038        p.match_type(TokenKind::If, Parsing::If)?;
1039        Ok(If {
1040            cond: condition(p)?.into(),
1041            pass: Block::parse(p)?.into(),
1042            fail: Else::parse(p)?,
1043        })
1044    }
1045}
1046
1047impl Parse<'_> for For {
1048    /// [For]: `for` [Pattern] `in` [Expr] [Block] [Else]?
1049    #[rustfmt::skip]
1050    fn parse(p: &mut Parser) -> PResult<For> {
1051        Ok(For {
1052            bind: delim(Parse::parse, (TokenKind::For, TokenKind::In), Parsing::For)(p)?,
1053            cond: condition(p)?.into(),
1054            pass: p.parse()?,
1055            fail: Else::parse(p)?,
1056        })
1057    }
1058}
1059
1060impl Parse<'_> for Else {
1061    /// [Else]: (`else` [Block])?
1062    fn parse(p: &mut Parser) -> PResult<Else> {
1063        match p.peek_kind(Parsing::Else) {
1064            Ok(TokenKind::Else) => {
1065                p.consume_peeked();
1066                Ok(Else { body: Some(p.parse()?) })
1067            }
1068            Ok(_) | Err(Error { reason: EndOfInput, .. }) => Ok(None.into()),
1069            Err(e) => Err(e),
1070        }
1071    }
1072}
1073
1074impl Parse<'_> for Break {
1075    /// [Break] = `break` (*unconsumed* `;` | [Expr])
1076    fn parse(p: &mut Parser) -> PResult<Break> {
1077        p.match_type(TokenKind::Break, Parsing::Break)?;
1078        Ok(Break { body: ret_body(p, Parsing::Break)? })
1079    }
1080}
1081
1082impl Parse<'_> for Return {
1083    /// [Return] = `return` (*unconsumed* `;` | [Expr])
1084    fn parse(p: &mut Parser) -> PResult<Return> {
1085        p.match_type(TokenKind::Return, Parsing::Return)?;
1086        Ok(Return { body: ret_body(p, Parsing::Return)? })
1087    }
1088}
1089
1090fn pathpattern(p: &mut Parser<'_>) -> PResult<Pattern> {
1091    const P: Parsing = Parsing::Pattern;
1092    let name = Path::parse(p)?;
1093
1094    let struct_members = |p: &mut Parser| {
1095        let name = p.parse()?;
1096        let pat = if p.match_type(TokenKind::Colon, P).is_ok() {
1097            Some(p.parse()?)
1098        } else {
1099            None
1100        };
1101        Ok((name, pat))
1102    };
1103
1104    Ok(match p.peek_kind(Parsing::Pattern)? {
1105        TokenKind::LCurly => Pattern::Struct(
1106            name,
1107            delim(
1108                sep(struct_members, TokenKind::Comma, TokenKind::RCurly, P),
1109                CURLIES,
1110                P,
1111            )(p)?,
1112        ),
1113        TokenKind::LParen => Pattern::TupleStruct(
1114            name,
1115            delim(
1116                sep(Parse::parse, TokenKind::Comma, TokenKind::RParen, P),
1117                PARENS,
1118                P,
1119            )(p)?,
1120        ),
1121        _ => name
1122            .as_sym()
1123            .map(Pattern::Name)
1124            .unwrap_or(Pattern::Path(name)),
1125    })
1126}
1127
1128impl Parse<'_> for Pattern {
1129    fn parse(p: &mut Parser<'_>) -> PResult<Self> {
1130        const P: Parsing = Parsing::Pattern;
1131        let head = match p.peek_kind(P)? {
1132            // Name, Path, Struct, TupleStruct
1133            TokenKind::Identifier => pathpattern(p)?,
1134            // Literal
1135            TokenKind::Literal => Pattern::Literal(p.parse()?),
1136            // Rest
1137            TokenKind::DotDot => {
1138                p.consume_peeked();
1139                if matches!(
1140                    p.peek_kind(P),
1141                    Ok(TokenKind::Identifier | TokenKind::Literal)
1142                ) {
1143                    Pattern::Rest(Some(p.parse()?))
1144                } else {
1145                    Pattern::Rest(None)
1146                }
1147            }
1148            // Ref
1149            TokenKind::Amp => {
1150                p.consume_peeked();
1151                Pattern::Ref(p.parse()?, p.parse()?)
1152            }
1153            // Ref(Ref)
1154            TokenKind::AmpAmp => {
1155                p.consume_peeked();
1156                Pattern::Ref(
1157                    Mutability::Not,
1158                    Box::new(Pattern::Ref(p.parse()?, p.parse()?)),
1159                )
1160            }
1161            // Tuple
1162            TokenKind::LParen => Pattern::Tuple(delim(
1163                sep(Parse::parse, TokenKind::Comma, TokenKind::RParen, P),
1164                PARENS,
1165                P,
1166            )(p)?),
1167            // Array
1168            TokenKind::LBrack => Pattern::Array(delim(
1169                sep(Parse::parse, TokenKind::Comma, TokenKind::RBrack, P),
1170                BRACKETS,
1171                P,
1172            )(p)?),
1173            _ => {
1174                let bad_expr = p.parse()?;
1175                Err(p.error(ErrorKind::InvalidPattern(bad_expr), P))?
1176            }
1177        };
1178
1179        match p.peek_kind(P) {
1180            Ok(TokenKind::DotDot) => {
1181                p.consume_peeked();
1182                Ok(Pattern::RangeExc(head.into(), p.parse()?))
1183            }
1184            Ok(TokenKind::DotDotEq) => {
1185                p.consume_peeked();
1186                Ok(Pattern::RangeInc(head.into(), p.parse()?))
1187            }
1188            _ => Ok(head),
1189        }
1190    }
1191}
1192
1193impl Parse<'_> for Match {
1194    /// [Match] = `match` [Expr] `{` [MatchArm],* `}`
1195    fn parse(p: &mut Parser<'_>) -> PResult<Self> {
1196        p.match_type(TokenKind::Match, Parsing::Match)?;
1197        Ok(Match {
1198            scrutinee: condition(p)?.into(),
1199            arms: delim(
1200                sep(MatchArm::parse, TokenKind::Comma, CURLIES.1, Parsing::Match),
1201                CURLIES,
1202                Parsing::Match,
1203            )(p)?,
1204        })
1205    }
1206}
1207
1208impl Parse<'_> for MatchArm {
1209    /// [MatchArm] = [Pattern] `=>` [Expr]
1210    fn parse(p: &mut Parser<'_>) -> PResult<Self> {
1211        let pat = Pattern::parse(p)?;
1212        p.match_type(TokenKind::FatArrow, Parsing::MatchArm)?;
1213        let expr = Expr::parse(p)?;
1214        Ok(MatchArm(pat, expr))
1215    }
1216}
1217
1218/// ret_body = (*unconsumed* `;` | [Expr])
1219fn ret_body(p: &mut Parser, while_parsing: Parsing) -> PResult<Option<Box<Expr>>> {
1220    Ok(match p.peek_kind(while_parsing)? {
1221        TokenKind::Semi => None,
1222        _ => Some(p.parse()?),
1223    })
1224}
1225
1226impl<'t, P: Parse<'t>> Parse<'t> for Box<P> {
1227    fn parse(p: &mut Parser<'t>) -> PResult<Self> {
1228        p.parse().map(Box::new)
1229    }
1230}