Skip to main content

cl_parser/parser/
error.rs

1use super::pat::Prec as PatPrec;
2use cl_lexer::LexError;
3use cl_structures::span::Span;
4use cl_token::TKind;
5use std::{error::Error, fmt::Display};
6
7/// All the ways a [Parser](crate::parser::Parser) can fail
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9pub enum ParseError {
10    /// Reached the expected end of input.
11    EOF(Span),
12    /// *Unexpectedly* reached end of input.
13    UnexpectedEOF(Span),
14    /// Did not reach end of enput when expected.
15    ExpectedEOF(TKind, Span),
16    /// The [`Lexer`](cl_lexer::Lexer) didn't like that.
17    FromLexer(LexError),
18    /// Expected [`TKind`] `0`, got [`TKind`] `1` at [`struct@Span`]
19    Expected(TKind, TKind, Span),
20    /// Tried to parse a literal, but got [`TKind`] instead, at [`struct@Span`]
21    NotLiteral(TKind, Span),
22    /// Tried to parse a use item, but got [`TKind`] instead, at [`struct@Span`]
23    NotUse(TKind, Span),
24    /// Tried to parse a pattern, but got [`TKind`] at [`PatPrec`] instead, at [`struct@Span`]
25    NotPattern(TKind, PatPrec, Span),
26    /// Tried to parse a bind item, but got [`TKind`] instead, at [`struct@Span`]
27    NotBind(TKind, Span),
28    /// Tried to parse a prefix expression, but got [`TKind`] instead, at [`struct@Span`]
29    NotPrefix(TKind, Span),
30    /// Tried to parse an infix expression, but got [`TKind`] instead, at [`struct@Span`]
31    NotInfix(TKind, Span),
32    /// Tried to parse a postfix expression, but got [`TKind`] instead, at [`struct@Span`]
33    NotPostfix(TKind, Span),
34}
35
36pub use ParseError::EOF;
37
38impl Error for ParseError {}
39impl Display for ParseError {
40    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41        match self {
42            Self::EOF(loc) => write!(f, "{loc}: Reached end of input."),
43            Self::UnexpectedEOF(loc) => write!(f, "{loc}: Unexpected end of input."),
44            Self::ExpectedEOF(tk, loc) => write!(f, "{loc}: Expected end of input, got {tk:?}."),
45            Self::FromLexer(e) => e.fmt(f),
46            Self::Expected(e, tk, loc) => write!(f, "{loc}: Expected {e:?}, got {tk:?}."),
47            Self::NotLiteral(tk, loc) => write!(f, "{loc}: {tk:?} is not valid in a literal."),
48            Self::NotUse(tk, loc) => write!(f, "{loc}: {tk:?} is no use!"),
49            Self::NotPattern(tk, prec, loc) => {
50                write!(f, "{loc}: {tk:?} is not valid in a {prec:?} pattern.")
51            }
52            Self::NotBind(bind, loc) => {
53                write!(f, "{loc}: {bind:?} is not valid in a bind expression.")
54            }
55            Self::NotPrefix(tk, loc) => write!(f, "{loc}: {tk:?} is not a prefix operator."),
56            Self::NotInfix(tk, loc) => write!(f, "{loc}: {tk:?} is not a infix operator."),
57            Self::NotPostfix(tk, loc) => write!(f, "{loc}: {tk:?} is not a postfix operator."),
58        }
59    }
60}
61
62pub type PResult<T> = Result<T, ParseError>;
63
64pub trait PResultExt<T> {
65    fn no_eof(self) -> PResult<T>;
66    fn allow_eof(self) -> PResult<Option<T>>;
67    fn is_eof(&self) -> bool;
68}
69
70impl<T> PResultExt<T> for PResult<T> {
71    fn no_eof(self) -> Self {
72        match self {
73            Err(ParseError::EOF(span)) => Err(ParseError::UnexpectedEOF(span)),
74            other => other,
75        }
76    }
77    fn allow_eof(self) -> PResult<Option<T>> {
78        match self {
79            Ok(t) => Ok(Some(t)),
80            Err(ParseError::EOF(_)) => Ok(None),
81            Err(e) => Err(e),
82        }
83    }
84    fn is_eof(&self) -> bool {
85        matches!(self, Err(ParseError::EOF(_)))
86    }
87}
88
89/// Opens a scope where [`ParseError::EOF`] is unexpected (See [`PResultExt::no_eof`])
90pub fn no_eof<T>(f: impl FnOnce() -> PResult<T>) -> PResult<T> {
91    f().no_eof()
92}