1#![allow(unused, unused_assignments)]
7
8use crate::{eval::*, model::OutputType, parse::*, resolve::*, syntax::*, ty::*, value::*};
9use microcad_lang_base::{DiagError, SrcRef};
10use miette::Diagnostic;
11use thiserror::Error;
12
13#[derive(Debug, Error, Diagnostic)]
15#[allow(missing_docs)]
16pub enum EvalError {
17 #[error("Not implemented: {0}")]
19 Todo(String),
20
21 #[error("List index out of bounds: {index} >= {len}")]
23 ListIndexOutOfBounds {
24 index: usize,
26 len: usize,
28 },
29
30 #[error("Type mismatch for `{id}`: expected {expected}, got {found}")]
32 TypeMismatch {
33 id: Identifier,
35 expected: Type,
37 found: Type,
39 },
40
41 #[error("Array elements have different types: {0}")]
43 ArrayElementsDifferentTypes(TypeList),
44
45 #[error("Symbol {0} not found.")]
47 SymbolNotFound(QualifiedName),
48
49 #[error("No symbols found to use in {0}")]
51 NoSymbolsToUse(QualifiedName),
52
53 #[error("Symbol `{0}` cannot be called.")]
55 SymbolCannotBeCalled(QualifiedName),
56
57 #[error("Ambiguous symbol {0} might be one of the following: {1}")]
59 AmbiguousSymbol(QualifiedName, QualifiedNames),
60
61 #[error("Local symbol not found: {0}")]
63 LocalNotFound(Identifier),
64
65 #[error("Property not found: {0}")]
67 PropertyNotFound(Identifier),
68
69 #[error("Not a property id: {0}")]
71 NoPropertyId(QualifiedName),
72
73 #[error("Argument count mismatch: expected {expected}, got {found} in {args}")]
75 ArgumentCountMismatch {
76 args: String,
78 expected: usize,
80 found: usize,
82 },
83
84 #[error("Invalid argument type: {0}")]
86 InvalidArgumentType(Type),
87
88 #[error("Unexpected argument: {0}: {1}")]
90 UnexpectedArgument(Identifier, Type),
91
92 #[error("Assertion failed: {0}")]
94 AssertionFailed(String),
95
96 #[error("Expected type `{expected}`, found type `{found}")]
98 ExpectedType {
99 expected: Type,
101 found: Type,
103 },
104
105 #[error("Diagnostic error: {0}")]
107 DiagError(#[from] DiagError),
108
109 #[error("Local stack needed to store {0}")]
111 LocalStackEmpty(Identifier),
112
113 #[error("Unexpected stack frame of type '{1}' cannot store {0}")]
115 WrongStackFrame(Identifier, &'static str),
116
117 #[error("Value Error: {0}")]
119 ValueError(#[from] ValueError),
120
121 #[error("Unknown method `{0}`")]
123 UnknownMethod(QualifiedName),
124
125 #[error("Parsing error {0}")]
127 ParseError(#[from] ParseError),
128
129 #[error("{0} statement not available here")]
131 StatementNotSupported(&'static str),
132
133 #[error("Properties have not been initialized: {0}")]
135 UninitializedProperties(IdentifierList),
136
137 #[error("Unexpected {0} {1} within expression")]
139 UnexpectedNested(&'static str, Identifier),
140
141 #[error("No variables allowed in {0}")]
143 NoVariablesAllowedIn(&'static str),
144
145 #[error("Attribute error: {0}")]
147 AttributeError(#[from] AttributeError),
148
149 #[error("Missing arguments: {0}")]
151 MissingArguments(IdentifierList),
152
153 #[error("Too many arguments: {0}")]
155 TooManyArguments(IdentifierList),
156
157 #[error("Arguments match by identifier but have incompatible types: {0}")]
159 IdMatchButNotType(String),
160
161 #[error("Builtin error: {0}")]
163 BuiltinError(String),
164
165 #[error("Parameter not found by type '{0}'")]
167 ParameterByTypeNotFound(Type),
168
169 #[error("Multiplicity not allowed '{0}'")]
171 MultiplicityNotAllowed(IdentifierList),
172
173 #[error("Cannot mix 2d and 3d geometries")]
175 CannotMixGeometry,
176
177 #[error("If condition is not a boolean: {condition}")]
179 IfConditionIsNotBool {
180 condition: String,
181 #[label("Not a boolean")]
182 src_ref: SrcRef,
183 },
184
185 #[error("Workbench {name} cannot find initialization for those arguments")]
187 #[diagnostic(help("Possible initializations: \n\t{}", possible_params.join("\n\t")))]
188 NoInitializationFound {
189 #[label("Got: {name}( {actual_params} )")]
190 src_ref: SrcRef,
191 name: Identifier,
192 actual_params: String,
193 possible_params: Vec<String>,
194 },
195 #[error("Workbench {name} has ambiguous initialization for those arguments")]
197 #[diagnostic(help("Ambiguous initializations: \n\t{}", ambiguous_params.join("\n\t")))]
198 AmbiguousInitialization {
199 #[label("Got: {name}( {actual_params} )")]
200 src_ref: SrcRef,
201 name: Identifier,
202 actual_params: String,
203 ambiguous_params: Vec<String>,
204 },
205
206 #[error("Building plan incomplete. Missing properties: {0}")]
208 BuildingPlanIncomplete(IdentifierList),
209
210 #[error("This expression statement did not produce any model")]
212 EmptyModelExpression,
213
214 #[error("{0} {1} has empty body")]
216 WarnEmptyWorkbench(String, Identifier),
217
218 #[error("The {kind} workbench produced a {produced} output, but expected a {expected} output.")]
220 WorkbenchInvalidOutput {
221 kind: WorkbenchKind,
222 produced: OutputType,
223 expected: OutputType,
224 },
225
226 #[error("The {0} workbench will produce no {1} output.")]
228 WorkbenchNoOutput(WorkbenchKind, OutputType),
229
230 #[error("Unexpected source file {0} in expression")]
232 InvalidSelfReference(Identifier),
233
234 #[error("Resolve error: {0}")]
236 #[diagnostic(transparent)]
237 ResolveError(ResolveError),
238
239 #[error("{0} is not operation.")]
241 NotAnOperation(QualifiedName),
242
243 #[error("Calling operation on empty geometry")]
245 OperationOnEmptyGeometry,
246
247 #[error("Cannot call operation without workpiece.")]
249 CannotCallOperationWithoutWorkpiece,
250
251 #[error("Missing return statement in {0}")]
253 MissingReturn(QualifiedName),
254
255 #[error("Missing model in workbench")]
257 NoModelInWorkbench,
258
259 #[error("Found a symbol and a property with names {0} and {1}")]
261 AmbiguousProperty(QualifiedName, Identifier),
262
263 #[error("Value {name} already in defined: {value}")]
265 #[diagnostic(help("Values in microcad are immutable"))]
266 ValueAlreadyDefined {
267 #[label(primary, "{name} is already defined")]
269 location: SrcRef,
270 name: Identifier,
272 value: String,
274 #[label("Previously defined here")]
276 previous_location: SrcRef,
277 },
278
279 #[error("Assignment failed because {0} is not an l-value")]
281 NotAnLValue(Identifier),
282
283 #[error("Symbol {what} is private from within {within}")]
285 SymbolIsPrivate {
286 what: QualifiedName,
288 within: QualifiedName,
290 },
291
292 #[error("Symbol {what} (aliased from {alias}) is private from within {within}")]
294 SymbolBehindAliasIsPrivate {
295 what: QualifiedName,
297 alias: QualifiedName,
299 within: QualifiedName,
301 },
302
303 #[error("Unused global symbol {0}.")]
305 UnusedGlobalSymbol(String),
306
307 #[error("Unused local {0}.")]
309 UnusedLocal(Identifier),
310
311 #[error("Evaluation aborted because of prior resolve errors!")]
313 ResolveFailed,
314
315 #[error("Bad range, first number ({0}) must be smaller than last ({1})")]
317 BadRange(i64, i64),
318
319 #[error("Ambiguous type '{ty}' in tuple")]
321 AmbiguousType {
322 ty: Type,
323 #[label(
324 "Some unnamed values in this tuple share the same type '{ty}'.\nMaybe check the units or use identifiers in this tuple."
325 )]
326 src_ref: SrcRef,
327 },
328}
329
330pub type EvalResult<T> = std::result::Result<T, EvalError>;
332
333impl From<ResolveError> for EvalError {
334 fn from(err: ResolveError) -> Self {
335 match err {
336 ResolveError::SymbolNotFound(name) => EvalError::SymbolNotFound(name),
337 other => EvalError::ResolveError(other),
338 }
339 }
340}