1use super::*;
2
3use cl_ast::{Expr, Sym};
4use cl_lexer::error::{Error as LexError, Reason};
5use std::fmt::Display;
6pub type PResult<T> = Result<T, Error>;
7
8#[derive(Clone, Debug, PartialEq, Eq)]
10pub struct Error {
11 pub in_file: Sym,
12 pub reason: ErrorKind,
13 pub while_parsing: Parsing,
14 pub loc: Loc,
15}
16impl std::error::Error for Error {}
17
18#[derive(Clone, Debug, PartialEq, Eq)]
20pub enum ErrorKind {
21 Lexical(LexError),
22 EndOfInput,
23 UnmatchedParentheses,
24 UnmatchedCurlyBraces,
25 UnmatchedSquareBrackets,
26 Unexpected(TokenKind),
27 ExpectedToken {
28 want: TokenKind,
29 got: TokenKind,
30 },
31 ExpectedParsing {
32 want: Parsing,
33 },
34 InvalidPattern(Box<Expr>),
35 Todo(&'static str),
37}
38impl From<LexError> for ErrorKind {
39 fn from(value: LexError) -> Self {
40 match value.reason() {
41 Reason::EndOfFile => Self::EndOfInput,
42 _ => Self::Lexical(value),
43 }
44 }
45}
46
47#[derive(Clone, Copy, Debug, PartialEq, Eq)]
49pub enum Parsing {
50 Mutability,
51 Visibility,
52 Identifier,
53 Literal,
54
55 File,
56
57 Attrs,
58 Meta,
59 MetaKind,
60
61 Item,
62 ItemKind,
63 Generics,
64 Alias,
65 Const,
66 Static,
67 Module,
68 ModuleKind,
69 Function,
70 Param,
71 Struct,
72 StructKind,
73 StructMember,
74 Enum,
75 EnumKind,
76 Variant,
77 VariantKind,
78 Impl,
79 ImplKind,
80 Use,
81 UseTree,
82
83 Ty,
84 TyKind,
85 TySlice,
86 TyArray,
87 TyTuple,
88 TyRef,
89 TyFn,
90
91 Path,
92 PathPart,
93
94 Stmt,
95 StmtKind,
96 Let,
97
98 Expr,
99 ExprKind,
100 Closure,
101 Assign,
102 AssignKind,
103 Binary,
104 BinaryKind,
105 Unary,
106 UnaryKind,
107 Cast,
108 Index,
109 Structor,
110 Fielder,
111 Call,
112 Member,
113 Array,
114 ArrayRep,
115 AddrOf,
116 Block,
117 Group,
118 Tuple,
119 Loop,
120 While,
121 If,
122 For,
123 Else,
124 Break,
125 Return,
126 Continue,
127
128 Pattern,
129 Match,
130 MatchArm,
131}
132
133impl Display for Error {
134 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135 let Self { in_file, reason, while_parsing, loc } = self;
136 match reason {
137 ErrorKind::Todo(_) => write!(f, "{in_file}:{loc} {reason} {while_parsing:?}"),
139 ErrorKind::Lexical(e) => write!(f, "{e} (while parsing {while_parsing})"),
141 _ => {
142 if !in_file.is_empty() {
143 write!(f, "{in_file}:")?
144 }
145 write!(f, "{loc}: {reason} while parsing {while_parsing}")
146 }
147 }
148 }
149}
150impl Display for ErrorKind {
151 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
152 match self {
153 ErrorKind::Lexical(e) => e.fmt(f),
154 ErrorKind::EndOfInput => write!(f, "End of input"),
155 ErrorKind::UnmatchedParentheses => write!(f, "Unmatched parentheses"),
156 ErrorKind::UnmatchedCurlyBraces => write!(f, "Unmatched curly braces"),
157 ErrorKind::UnmatchedSquareBrackets => write!(f, "Unmatched square brackets"),
158 ErrorKind::Unexpected(t) => write!(f, "Encountered unexpected token `{t}`"),
159 ErrorKind::ExpectedToken { want: e, got: g } => write!(f, "Expected `{e}`, got `{g}`"),
160 ErrorKind::ExpectedParsing { want } => write!(f, "Expected {want}"),
161 ErrorKind::InvalidPattern(got) => write!(f, "Got invalid `{got}`"),
162 ErrorKind::Todo(unfinished) => write!(f, "TODO: {unfinished}"),
163 }
164 }
165}
166impl Display for Parsing {
167 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
168 match self {
169 Parsing::Visibility => "a visibility qualifier",
170 Parsing::Mutability => "a mutability qualifier",
171 Parsing::Identifier => "an identifier",
172 Parsing::Literal => "a literal",
173
174 Parsing::File => "a file",
175
176 Parsing::Attrs => "an attribute-set",
177 Parsing::Meta => "an attribute",
178 Parsing::MetaKind => "an attribute's arguments",
179 Parsing::Item => "an item",
180 Parsing::ItemKind => "an item",
181 Parsing::Generics => "a list of type arguments",
182 Parsing::Alias => "a type alias",
183 Parsing::Const => "a const item",
184 Parsing::Static => "a static variable",
185 Parsing::Module => "a module",
186 Parsing::ModuleKind => "a module",
187 Parsing::Function => "a function",
188 Parsing::Param => "a function parameter",
189 Parsing::Struct => "a struct",
190 Parsing::StructKind => "a struct",
191 Parsing::StructMember => "a struct member",
192 Parsing::Enum => "an enum",
193 Parsing::EnumKind => "an enum",
194 Parsing::Variant => "an enum variant",
195 Parsing::VariantKind => "an enum variant",
196 Parsing::Impl => "an impl block",
197 Parsing::ImplKind => "the target of an impl block",
198 Parsing::Use => "a use item",
199 Parsing::UseTree => "a use-tree",
200
201 Parsing::Ty => "a type",
202 Parsing::TyKind => "a type",
203 Parsing::TySlice => "a slice type",
204 Parsing::TyArray => "an array type",
205 Parsing::TyTuple => "a tuple of types",
206 Parsing::TyRef => "a reference type",
207 Parsing::TyFn => "a function pointer type",
208
209 Parsing::Path => "a path",
210 Parsing::PathPart => "a path component",
211
212 Parsing::Stmt => "a statement",
213 Parsing::StmtKind => "a statement",
214 Parsing::Let => "a local variable declaration",
215
216 Parsing::Expr => "an expression",
217 Parsing::ExprKind => "an expression",
218 Parsing::Closure => "an anonymous function",
219 Parsing::Assign => "an assignment",
220 Parsing::AssignKind => "an assignment operator",
221 Parsing::Binary => "a binary expression",
222 Parsing::BinaryKind => "a binary operator",
223 Parsing::Unary => "a unary expression",
224 Parsing::UnaryKind => "a unary operator",
225 Parsing::Cast => "an `as`-casting expression",
226 Parsing::Index => "an indexing expression",
227 Parsing::Structor => "a struct constructor expression",
228 Parsing::Fielder => "a struct field expression",
229 Parsing::Call => "a call expression",
230 Parsing::Member => "a member access expression",
231 Parsing::Array => "an array",
232 Parsing::ArrayRep => "an array of form [k;N]",
233 Parsing::AddrOf => "a borrow op",
234 Parsing::Block => "a block",
235 Parsing::Group => "a grouped expression",
236 Parsing::Tuple => "a tuple",
237 Parsing::Loop => "an unconditional loop expression",
238 Parsing::While => "a while expression",
239 Parsing::If => "an if expression",
240 Parsing::For => "a for expression",
241 Parsing::Else => "an else block",
242 Parsing::Break => "a break expression",
243 Parsing::Return => "a return expression",
244 Parsing::Continue => "a continue expression",
245
246 Parsing::Pattern => "a pattern",
247 Parsing::Match => "a match expression",
248 Parsing::MatchArm => "a match arm",
249 }
250 .fmt(f)
251 }
252}