ampc/syntax/
parser.rs

1//! The parser for the Amp compiler.
2
3use crate::Context;
4
5use super::token::TokenIter;
6
7/// An error that occurred during a [Parse] run.
8#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
9pub enum Recoverable {
10    /// The parser was not able to find a match in the token list.  The token iterator has not been
11    /// advanced and no diagnostics have been reported.
12    Yes,
13
14    /// The token iterator has been advanced and a diagnostic has been reported.
15    No,
16}
17
18/// [Result<T, Recoverable>] methods.
19pub trait IfRecoverable<T> {
20    /// Calls the provided callback if this value is a [`Recoverable::Yes`] error type.  If this
21    /// value is [Recoverable], returns the result of the provided callback, wrapped in [`Err`].
22    fn if_recoverable(self, callback: impl FnMut() -> Recoverable) -> Result<T, Recoverable>;
23}
24
25impl<T> IfRecoverable<T> for Result<T, Recoverable> {
26    fn if_recoverable(self, mut callback: impl FnMut() -> Recoverable) -> Result<T, Recoverable> {
27        match self {
28            Self::Err(Recoverable::Yes) => Err(callback()),
29            res => res,
30        }
31    }
32}
33
34/// A trait for parser segments.
35pub trait Parse<T> {
36    /// Parses a value from the provided tokens.
37    fn parse(&mut self, cx: &mut Context, tokens: &mut TokenIter) -> Result<T, Recoverable>;
38}
39
40impl<T, F: FnMut(&mut Context, &mut TokenIter) -> Result<T, Recoverable>> Parse<T> for F {
41    fn parse(&mut self, cx: &mut Context, tokens: &mut TokenIter) -> Result<T, Recoverable> {
42        self(cx, tokens)
43    }
44}