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)]
9pub enum ParseError {
10 EOF(Span),
12 UnexpectedEOF(Span),
14 ExpectedEOF(TKind, Span),
16 FromLexer(LexError),
18 Expected(TKind, TKind, Span),
20 NotLiteral(TKind, Span),
22 NotUse(TKind, Span),
24 NotPattern(TKind, PatPrec, Span),
26 NotBind(TKind, Span),
28 NotPrefix(TKind, Span),
30 NotInfix(TKind, Span),
32 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
89pub fn no_eof<T>(f: impl FnOnce() -> PResult<T>) -> PResult<T> {
91 f().no_eof()
92}