1use miette::Diagnostic;
7use crate::{eval::*, model::OutputType, parse::*, resolve::*, syntax::*, ty::*, value::*};
8use thiserror::Error;
9
10#[derive(Debug, Error, Diagnostic)]
12#[allow(missing_docs)]
13pub enum EvalError {
14 #[error("Not implemented: {0}")]
16 Todo(String),
17
18 #[error("List index out of bounds: {index} >= {len}")]
20 ListIndexOutOfBounds {
21 index: usize,
23 len: usize,
25 },
26
27 #[error("Type mismatch for `{id}`: expected {expected}, got {found}")]
29 TypeMismatch {
30 id: Identifier,
32 expected: Type,
34 found: Type,
36 },
37
38 #[error("Array elements have different types: {0}")]
40 ArrayElementsDifferentTypes(TypeList),
41
42 #[error("Symbol {0} not found.")]
44 SymbolNotFound(QualifiedName),
45
46 #[error("No symbols found to use in {0}")]
48 NoSymbolsToUse(QualifiedName),
49
50 #[error("Unexpectedly found symbol {0}")]
52 SymbolFound(QualifiedName),
53
54 #[error("Symbol `{0}` cannot be called.")]
56 SymbolCannotBeCalled(QualifiedName),
57
58 #[error("Ambiguous symbol {0} might be one of the following: {1}")]
60 AmbiguousSymbol(QualifiedName, QualifiedNames),
61
62 #[error("Local symbol not found: {0}")]
64 LocalNotFound(Identifier),
65
66 #[error("Property not found: {0}")]
68 PropertyNotFound(Identifier),
69
70 #[error("Not a property id: {0}")]
72 NoPropertyId(QualifiedName),
73
74 #[error("Argument count mismatch: expected {expected}, got {found} in {args}")]
76 ArgumentCountMismatch {
77 args: String,
79 expected: usize,
81 found: usize,
83 },
84
85 #[error("Invalid argument type: {0}")]
87 InvalidArgumentType(Type),
88
89 #[error("Unexpected argument: {0}: {1}")]
91 UnexpectedArgument(Identifier, Type),
92
93 #[error("Assertion failed: {0}")]
95 AssertionFailed(String),
96
97 #[error("Expected type `{expected}`, found type `{found}")]
99 ExpectedType {
100 expected: Type,
102 found: Type,
104 },
105
106 #[error("Diagnostic error: {0}")]
108 DiagError(#[from] DiagError),
109
110 #[error("Local stack needed to store {0}")]
112 LocalStackEmpty(Identifier),
113
114 #[error("Unexpected stack frame of type '{1}' cannot store {0}")]
116 WrongStackFrame(Identifier, &'static str),
117
118 #[error("Value Error: {0}")]
120 ValueError(#[from] ValueError),
121
122 #[error("Unknown method `{0}`")]
124 UnknownMethod(QualifiedName),
125
126 #[error("Parsing error {0}")]
128 ParseError(#[from] ParseError),
129
130 #[error("{0} statement not available here")]
132 StatementNotSupported(&'static str),
133
134 #[error("Properties have not been initialized: {0}")]
136 UninitializedProperties(IdentifierList),
137
138 #[error("Unexpected {0} {1} within expression")]
140 UnexpectedNested(&'static str, Identifier),
141
142 #[error("No variables allowed in {0}")]
144 NoVariablesAllowedIn(&'static str),
145
146 #[error("Attribute error: {0}")]
148 AttributeError(#[from] AttributeError),
149
150 #[error("Missing arguments: {0}")]
152 MissingArguments(IdentifierList),
153
154 #[error("Too many arguments: {0}")]
156 TooManyArguments(IdentifierList),
157
158 #[error("Builtin error: {0}")]
160 BuiltinError(String),
161
162 #[error("Parameter not found by type '{0}'")]
164 ParameterByTypeNotFound(Type),
165
166 #[error("Multiplicity not allowed '{0}'")]
168 MultiplicityNotAllowed(IdentifierList),
169
170 #[error("Cannot mix 2d and 3d geometries")]
172 CannotMixGeometry,
173
174 #[error("If condition is not a boolean: {0}")]
176 IfConditionIsNotBool(String),
177
178 #[error("Workbench {name} cannot find initialization for those arguments")]
180 #[diagnostic(help("Possible initializations: \n\t{}", possible_params.join("\n\t")))]
181 NoInitializationFound {
182 #[label("Got: {name}( {actual_params} )")]
183 src_ref: SrcRef,
184 name: Identifier,
185 actual_params: String,
186 possible_params: Vec<String>
187 },
188
189 #[error("Workbench plan incomplete. Missing properties: {0}")]
191 BuildingPlanIncomplete(IdentifierList),
192
193 #[error("This expression statement did not produce any model")]
195 EmptyModelExpression,
196
197 #[error("{0} {1} has empty body")]
199 WarnEmptyWorkbench(String, Identifier),
200
201 #[error("The {0} workbench produced a 2D output, but expected {2} output.")]
203 WorkbenchInvalidOutput(WorkbenchKind, OutputType, OutputType),
204
205 #[error("The {0} workbench will produce no {1} output.")]
207 WorkbenchNoOutput(WorkbenchKind, OutputType),
208
209 #[error("Unexpected source file {0} in expression")]
211 InvalidSelfReference(Identifier),
212
213 #[error("Resolve error: {0}")]
215 ResolveError(ResolveError),
216
217 #[error("{0} is not operation.")]
219 NotAnOperation(QualifiedName),
220
221 #[error("Calling operation on empty geometry")]
223 OperationOnEmptyGeometry,
224
225 #[error("Cannot call operation without workpiece.")]
227 CannotCallOperationWithoutWorkpiece,
228
229 #[error("Missing return statement in {0}")]
231 MissingReturn(QualifiedName),
232
233 #[error("Missing model in workbench")]
235 NoModelInWorkbench,
236
237 #[error("Found a symbol and a property with names {0} and {1}")]
239 AmbiguousProperty(QualifiedName, Identifier),
240
241 #[error("Value {name} already in defined: {value}")]
243 #[diagnostic(help("Values in microcad are immutable"))]
244 ValueAlreadyDefined {
245 #[label(primary, "{name} is already defined")]
247 location: SrcRef,
248 name: Identifier,
250 value: String,
252 #[label("Previously defined here")]
254 previous_location: SrcRef,
255 },
256
257 #[error("Assignment failed because {0} is not an l-value")]
259 NotAnLValue(Identifier),
260
261 #[error("Symbol {what} is private from within {within}")]
263 SymbolIsPrivate {
264 what: QualifiedName,
266 within: QualifiedName,
268 },
269
270 #[error("Symbol {what} (aliased from {alias}) is private from within {within}")]
272 SymbolBehindAliasIsPrivate {
273 what: QualifiedName,
275 alias: QualifiedName,
277 within: QualifiedName,
279 },
280
281 #[error("Unused global symbol {0}.")]
283 UnusedGlobalSymbol(String),
284
285 #[error("Unused local {0}.")]
287 UnusedLocal(Identifier),
288
289 #[error("Evaluation aborted because of prior resolve errors!")]
291 ResolveFailed,
292
293 #[error("Bad range, first number ({0}) must be smaller than last ({1})")]
295 BadRange(i64, i64),
296}
297
298pub type EvalResult<T> = std::result::Result<T, EvalError>;
300
301impl From<ResolveError> for EvalError {
302 fn from(err: ResolveError) -> Self {
303 match err {
304 ResolveError::SymbolNotFound(name) => EvalError::SymbolNotFound(name),
305 other => EvalError::ResolveError(other),
306 }
307 }
308}