1use crate::ast::expressions::DatexExpression;
2use crate::compiler::precompiler::precompiled_ast::RichAst;
3use crate::parser::errors::{ParserError, SpannedParserError};
4use crate::serde::error::DeserializationError;
5use crate::type_inference::error::{
6 DetailedTypeErrors, SpannedTypeError, TypeError,
7};
8use core::fmt::{Display, Formatter};
9use core::ops::Range;
10
11#[derive(Debug, Clone)]
12pub enum CompilerError {
13 UnexpectedTerm(Box<DatexExpression>),
14 SerializationError,
15 BigDecimalOutOfBoundsError,
17 IntegerOutOfBoundsError,
18 InvalidPlaceholderCount,
19 TooManyApplyArguments, NonStaticValue,
21 UndeclaredVariable(String),
22 InvalidRedeclaration(String),
23 SubvariantNotFound(String, String),
24 ScopePopError,
25 InvalidSlotName(String),
26 AssignmentToConst(String),
27 AssignmentToImmutableReference(String),
28 AssignmentToImmutableValue(String),
29 OnceScopeUsedMultipleTimes,
30 TypeError(TypeError),
31 ParserError(ParserError),
32}
33
34#[derive(Debug)]
36pub struct SpannedCompilerError {
37 pub error: CompilerError,
38 pub span: Option<Range<usize>>,
39}
40
41impl SpannedCompilerError {
42 pub fn new_with_span(
43 error: CompilerError,
44 span: Range<usize>,
45 ) -> SpannedCompilerError {
46 SpannedCompilerError {
47 error,
48 span: Some(span),
49 }
50 }
51}
52
53impl Display for SpannedCompilerError {
54 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
55 core::write!(
56 f,
57 "{} ({})",
58 self.error,
59 self.span
60 .as_ref()
61 .map(|s| format!("{}..{}", s.start, s.end))
62 .unwrap_or("?".to_string())
63 )
64 }
65}
66
67impl From<SpannedTypeError> for SpannedCompilerError {
68 fn from(value: SpannedTypeError) -> Self {
69 SpannedCompilerError {
70 span: value.span,
71 error: value.error.into(),
72 }
73 }
74}
75
76impl From<SpannedParserError> for SpannedCompilerError {
77 fn from(value: SpannedParserError) -> Self {
78 SpannedCompilerError {
79 span: Some(value.span),
80 error: CompilerError::ParserError(value.error),
81 }
82 }
83}
84
85impl From<CompilerError> for SpannedCompilerError {
86 fn from(value: CompilerError) -> Self {
87 SpannedCompilerError {
88 error: value,
89 span: None,
90 }
91 }
92}
93
94impl From<SpannedCompilerError> for DeserializationError {
95 fn from(e: SpannedCompilerError) -> Self {
96 DeserializationError::CompilerError(e)
97 }
98}
99
100#[derive(Debug, Default)]
101pub struct DetailedCompilerErrors {
102 pub errors: Vec<SpannedCompilerError>,
103}
104
105impl DetailedCompilerErrors {
106 pub fn has_errors(&self) -> bool {
107 !self.errors.is_empty()
108 }
109
110 pub fn append(&mut self, mut errors: DetailedCompilerErrors) {
111 self.errors.append(&mut errors.errors);
112 }
113}
114
115impl Display for DetailedCompilerErrors {
116 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
117 for error in self.errors.iter() {
118 writeln!(f, "{}", error)?;
119 }
120 Ok(())
121 }
122}
123
124impl DetailedCompilerErrors {
125 pub fn record_error_with_span(
126 &mut self,
127 error: CompilerError,
128 span: Range<usize>,
129 ) {
130 self.record_error(SpannedCompilerError {
131 error,
132 span: Some(span),
133 });
134 }
135}
136
137impl From<DetailedTypeErrors> for DetailedCompilerErrors {
138 fn from(value: DetailedTypeErrors) -> Self {
139 DetailedCompilerErrors {
140 errors: value
141 .errors
142 .into_iter()
143 .map(SpannedCompilerError::from)
144 .collect(),
145 }
146 }
147}
148
149impl ErrorCollector<SpannedCompilerError> for DetailedCompilerErrors {
150 fn record_error(&mut self, error: SpannedCompilerError) {
151 self.errors.push(error);
152 }
153}
154
155#[derive(Debug)]
156pub enum SimpleOrDetailedCompilerError {
157 Simple(SpannedCompilerError),
158 Detailed(DetailedCompilerErrors),
159}
160
161impl From<CompilerError> for SimpleOrDetailedCompilerError {
162 fn from(value: CompilerError) -> Self {
163 SimpleOrDetailedCompilerError::Simple(SpannedCompilerError::from(value))
164 }
165}
166
167impl From<SpannedCompilerError> for SimpleOrDetailedCompilerError {
168 fn from(value: SpannedCompilerError) -> Self {
169 SimpleOrDetailedCompilerError::Simple(value)
170 }
171}
172
173#[derive(Debug)]
174pub struct DetailedCompilerErrorsWithRichAst {
175 pub errors: DetailedCompilerErrors,
176 pub ast: RichAst,
177}
178
179#[derive(Debug)]
180pub struct DetailedCompilerErrorsWithMaybeRichAst {
181 pub errors: DetailedCompilerErrors,
182 pub ast: Option<RichAst>,
183}
184
185impl From<DetailedCompilerErrorsWithRichAst>
186 for DetailedCompilerErrorsWithMaybeRichAst
187{
188 fn from(value: DetailedCompilerErrorsWithRichAst) -> Self {
189 DetailedCompilerErrorsWithMaybeRichAst {
190 errors: value.errors,
191 ast: Some(value.ast),
192 }
193 }
194}
195
196#[derive(Debug)]
199pub enum SimpleCompilerErrorOrDetailedCompilerErrorWithRichAst {
200 Detailed(DetailedCompilerErrorsWithRichAst),
202 Simple(SpannedCompilerError),
204}
205
206impl From<SimpleCompilerErrorOrDetailedCompilerErrorWithRichAst>
207 for SimpleOrDetailedCompilerError
208{
209 fn from(
210 value: SimpleCompilerErrorOrDetailedCompilerErrorWithRichAst,
211 ) -> Self {
212 match value {
213 SimpleCompilerErrorOrDetailedCompilerErrorWithRichAst::Simple(
214 error,
215 ) => SimpleOrDetailedCompilerError::Simple(error),
216 SimpleCompilerErrorOrDetailedCompilerErrorWithRichAst::Detailed(
217 error_with_ast,
218 ) => SimpleOrDetailedCompilerError::Detailed(error_with_ast.errors),
219 }
220 }
221}
222
223impl From<SpannedCompilerError>
224 for SimpleCompilerErrorOrDetailedCompilerErrorWithRichAst
225{
226 fn from(
227 value: SpannedCompilerError,
228 ) -> SimpleCompilerErrorOrDetailedCompilerErrorWithRichAst {
229 SimpleCompilerErrorOrDetailedCompilerErrorWithRichAst::Simple(value)
230 }
231}
232
233impl From<Vec<SpannedParserError>> for DetailedCompilerErrors {
234 fn from(value: Vec<SpannedParserError>) -> Self {
235 DetailedCompilerErrors {
236 errors: value.into_iter().map(SpannedCompilerError::from).collect(),
237 }
238 }
239}
240
241impl From<TypeError> for SimpleOrDetailedCompilerError {
242 fn from(value: TypeError) -> Self {
243 SimpleOrDetailedCompilerError::Simple(SpannedCompilerError::from(
245 CompilerError::from(value),
246 ))
247 }
248}
249
250impl From<TypeError> for CompilerError {
251 fn from(value: TypeError) -> Self {
252 CompilerError::TypeError(value)
253 }
254}
255
256impl Display for CompilerError {
257 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
258 match self {
259 CompilerError::InvalidRedeclaration(name) => {
260 core::write!(f, "Invalid redeclaration of {name}")
261 }
262 CompilerError::UnexpectedTerm(rule) => {
263 core::write!(f, "Unexpected term: {rule:?}")
264 }
265 CompilerError::SubvariantNotFound(name, variant) => {
266 core::write!(
267 f,
268 "Subvariant {variant} does not exist for {name}"
269 )
270 }
271 CompilerError::SerializationError => {
272 core::write!(f, "Serialization error")
273 }
274 CompilerError::BigDecimalOutOfBoundsError => {
275 core::write!(f, "BigDecimal out of bounds error")
276 }
277 CompilerError::IntegerOutOfBoundsError => {
278 core::write!(f, "Integer out of bounds error")
279 }
280 CompilerError::InvalidPlaceholderCount => {
281 core::write!(f, "Invalid placeholder count")
282 }
283 CompilerError::NonStaticValue => {
284 core::write!(f, "Encountered non-static value")
285 }
286 CompilerError::UndeclaredVariable(var) => {
287 core::write!(f, "Undeclared variable: {var}")
288 }
289 CompilerError::ScopePopError => {
290 core::write!(f, "Could not pop scope, stack is empty")
291 }
292 CompilerError::InvalidSlotName(name) => {
293 core::write!(f, "Slot #{name} does not exist")
294 }
295 CompilerError::AssignmentToConst(name) => {
296 core::write!(f, "Cannot assign new value to const {name}")
297 }
298 CompilerError::OnceScopeUsedMultipleTimes => {
299 core::write!(
300 f,
301 "Scope cannot be used multiple times, set 'once' to false to use a scope multiple times"
302 )
303 }
304 CompilerError::AssignmentToImmutableValue(name) => {
305 core::write!(f, "Cannot assign to immutable value: {name}")
306 }
307 CompilerError::AssignmentToImmutableReference(name) => {
308 core::write!(f, "Cannot assign to immutable reference: {name}")
309 }
310 CompilerError::TypeError(err) => {
311 core::write!(f, "{}", err)
312 }
313 CompilerError::ParserError(err) => {
314 core::write!(f, "{:?}", err)
315 }
316 CompilerError::TooManyApplyArguments => {
317 core::write!(
318 f,
319 "Apply has too many arguments (max 255 allowed)"
320 )
321 }
322 }
323 }
324}
325
326pub enum MaybeAction<T> {
329 Skip,
331 Do(T),
333}
334
335pub trait ErrorCollector<E> {
336 fn record_error(&mut self, error: E);
337}
338
339pub fn collect_or_pass_error<T, E, Collector: ErrorCollector<E>>(
345 collected_errors: &mut Option<Collector>,
346 result: Result<T, E>,
347) -> Result<MaybeAction<T>, E> {
348 if let Err(error) = result {
349 if let Some(collected_errors) = collected_errors {
350 collected_errors.record_error(error);
351 Ok(MaybeAction::Skip)
352 } else {
353 Err(error)
354 }
355 } else {
356 result.map(MaybeAction::Do)
357 }
358}