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