cl_parser/parser/
error.rs1use 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#[derive(Clone, Copy, Debug, PartialEq, Eq)]
8pub enum ParseError {
9 EOF(Span),
11 UnexpectedEOF(Span),
13 ExpectedEOF(TKind, Span),
15 FromLexer(LexError),
16 Expected(TKind, TKind, Span),
17 NotLiteral(TKind, Span),
18 NotUse(TKind, Span),
19 NotPattern(TKind, PatPrec, Span),
20 NotBind(TKind, Span),
21 NotPrefix(TKind, Span),
22 NotInfix(TKind, Span),
23 NotPostfix(TKind, Span),
24}
25
26pub use ParseError::EOF;
27
28impl Error for ParseError {}
29impl Display for ParseError {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 match self {
32 Self::EOF(loc) => write!(f, "{loc}: Reached end of input."),
33 Self::UnexpectedEOF(loc) => write!(f, "{loc}: Unexpected end of input."),
34 Self::ExpectedEOF(tk, loc) => write!(f, "{loc}: Expected end of input, got {tk:?}."),
35 Self::FromLexer(e) => e.fmt(f),
36 Self::Expected(e, tk, loc) => write!(f, "{loc}: Expected {e:?}, got {tk:?}."),
37 Self::NotLiteral(tk, loc) => write!(f, "{loc}: {tk:?} is not valid in a literal."),
38 Self::NotUse(tk, loc) => write!(f, "{loc}: {tk:?} is no use!"),
39 Self::NotPattern(tk, prec, loc) => {
40 write!(f, "{loc}: {tk:?} is not valid in a {prec:?} pattern.")
41 }
42 Self::NotBind(bind, loc) => {
43 write!(f, "{loc}: {bind:?} is not valid in a bind expression.")
44 }
45 Self::NotPrefix(tk, loc) => write!(f, "{loc}: {tk:?} is not a prefix operator."),
46 Self::NotInfix(tk, loc) => write!(f, "{loc}: {tk:?} is not a infix operator."),
47 Self::NotPostfix(tk, loc) => write!(f, "{loc}: {tk:?} is not a postfix operator."),
48 }
49 }
50}
51
52pub type PResult<T> = Result<T, ParseError>;
53
54pub trait PResultExt<T> {
55 fn no_eof(self) -> PResult<T>;
56 fn allow_eof(self) -> PResult<Option<T>>;
57 fn is_eof(&self) -> bool;
58}
59
60impl<T> PResultExt<T> for PResult<T> {
61 fn no_eof(self) -> Self {
62 match self {
63 Err(ParseError::EOF(span)) => Err(ParseError::UnexpectedEOF(span)),
64 other => other,
65 }
66 }
67 fn allow_eof(self) -> PResult<Option<T>> {
68 match self {
69 Ok(t) => Ok(Some(t)),
70 Err(ParseError::EOF(_)) => Ok(None),
71 Err(e) => Err(e),
72 }
73 }
74 fn is_eof(&self) -> bool {
75 matches!(self, Err(ParseError::EOF(_)))
76 }
77}
78
79pub fn no_eof<T>(f: impl FnOnce() -> PResult<T>) -> PResult<T> {
81 f().no_eof()
82}