microcad_lang/eval/
eval_error.rs

1// Copyright © 2024-2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! Evaluation error
5
6use crate::{eval::*, model::OutputType, parse::*, resolve::*, syntax::*, ty::*, value::*};
7use thiserror::Error;
8
9/// Evaluation error.
10#[derive(Debug, Error)]
11pub enum EvalError {
12    /// Can't find a project file by it's qualified name.
13    #[error("Not implemented: {0}")]
14    Todo(String),
15
16    /// List index out of bounds.
17    #[error("List index out of bounds: {index} >= {len}")]
18    ListIndexOutOfBounds {
19        /// Wrong index
20        index: usize,
21        /// Length of list
22        len: usize,
23    },
24
25    /// Parameter type mismatch.
26    #[error("Type mismatch for `{id}`: expected {expected}, got {found}")]
27    TypeMismatch {
28        /// Parameter name
29        id: Identifier,
30        /// Expected type
31        expected: Type,
32        /// Found type
33        found: Type,
34    },
35
36    /// Array elements have different types.
37    #[error("Array elements have different types: {0}")]
38    ArrayElementsDifferentTypes(TypeList),
39
40    /// Symbol not found.
41    #[error("Symbol {0} not found.")]
42    SymbolNotFound(QualifiedName),
43
44    /// Given symbol has not children which can be used.
45    #[error("No symbols found to use in {0}")]
46    NoSymbolsToUse(QualifiedName),
47
48    /// Symbol was not expected to be found (e.g. `assert_invalid`).
49    #[error("Unexpectedly found symbol {0}")]
50    SymbolFound(QualifiedName),
51
52    /// The symbol cannot be called, e.g. when it is a source file or a module.
53    #[error("Symbol `{0}` cannot be called {1}.")]
54    SymbolCannotBeCalled(QualifiedName, Box<SymbolDefinition>),
55
56    /// Found ambiguous symbols.
57    #[error("Ambiguous symbol {ambiguous} might be one of the following:\n{others}")]
58    AmbiguousSymbol {
59        /// Searched name
60        ambiguous: QualifiedName,
61        /// Symbols which matches the name
62        others: Symbols,
63    },
64
65    /// Local Symbol not found.
66    #[error("Local symbol not found: {0}")]
67    LocalNotFound(Identifier),
68
69    /// A property of a value was not found.
70    #[error("Property not found: {0}")]
71    PropertyNotFound(Identifier),
72
73    /// Argument count mismatch.
74    #[error("Argument count mismatch: expected {expected}, got {found} in {args}")]
75    ArgumentCountMismatch {
76        /// Argument list including the error
77        args: ArgumentValueList,
78        /// Expected number of arguments
79        expected: usize,
80        /// Found number of arguments
81        found: usize,
82    },
83
84    /// Called assertion
85    #[error("assert called with wrong number of arguments.")]
86    AssertWrongSignature(ArgumentValueList),
87
88    /// Invalid argument type.
89    #[error("Invalid argument type: {0}")]
90    InvalidArgumentType(Type),
91
92    /// Unexpected argument.
93    #[error("Unexpected argument: {0}: {1}")]
94    UnexpectedArgument(Identifier, Type),
95
96    /// Assertion failed.
97    #[error("Assertion failed: {0}")]
98    AssertionFailed(String),
99
100    /// Different type expected.
101    #[error("Expected type `{expected}`, found type `{found}")]
102    ExpectedType {
103        /// Expected type.
104        expected: Type,
105        /// Found type.
106        found: Type,
107    },
108
109    /// Cannot continue evaluation after error limit has been reached.
110    #[error("Error limit reached: Stopped evaluation after {0} errors")]
111    ErrorLimitReached(u32),
112
113    /// No locals  available on stack.
114    #[error("Local stack needed to store {0}")]
115    LocalStackEmpty(Identifier),
116
117    /// Unexpected stack frame type
118    #[error("Unexpected stack frame of type '{1}' cannot store {0}")]
119    WrongStackFrame(Identifier, &'static str),
120
121    /// Value Error.
122    #[error("Value Error: {0}")]
123    ValueError(#[from] ValueError),
124
125    /// Unknown method.
126    #[error("Unknown method `{0}`")]
127    UnknownMethod(QualifiedName),
128
129    /// Parser Error
130    #[error("Parsing error {0}")]
131    ParseError(#[from] ParseError),
132
133    /// Statement is not supported in this context.
134    #[error("{0} statement not available here")]
135    StatementNotSupported(&'static str),
136
137    /// Properties are not initialized.
138    #[error("Properties have not been initialized: {0}")]
139    UninitializedProperties(IdentifierList),
140
141    /// Unexpected element within expression.
142    #[error("Unexpected {0} {1} within expression")]
143    UnexpectedNested(&'static str, Identifier),
144
145    /// No variables allowed in definition
146    #[error("No variables allowed in {0}")]
147    NoVariablesAllowedIn(&'static str),
148
149    /// Error when evaluating attributes.
150    #[error("Attribute error: {0}")]
151    AttributeError(#[from] AttributeError),
152
153    /// Missing arguments
154    #[error("Missing arguments: {0}")]
155    MissingArguments(IdentifierList),
156
157    /// Missing arguments
158    #[error("Too many arguments: {0}")]
159    TooManyArguments(IdentifierList),
160
161    /// Builtin error
162    #[error("Builtin error: {0}")]
163    BuiltinError(String),
164
165    /// Parameter not found by type in ParameterValueList
166    #[error("Parameter not found by type '{0}'")]
167    ParameterByTypeNotFound(Type),
168
169    /// Trying to use multiplicity where it is not allowed
170    #[error("Multiplicity not allowed '{0}'")]
171    MultiplicityNotAllowed(IdentifierList),
172
173    /// An error if you try to mix 2d and 3d geometries.
174    #[error("Cannot mix 2d and 3d geometries")]
175    CannotMixGeometry,
176
177    /// A condition of an if statement is not a boolean
178    #[error("If condition is not a boolean: {0}")]
179    IfConditionIsNotBool(Value),
180
181    /// Workbench didn't find a initialization routine matching the given arguments
182    #[error("Workbench {0} cannot find initialization for those arguments")]
183    NoInitializationFound(Identifier),
184
185    /// Initializer missed to set a property from plan
186    #[error("Workbench plan incomplete. Missing properties: {0}")]
187    BuildingPlanIncomplete(IdentifierList),
188
189    /// This errors happens if the expression is supposed to produce models but did not.
190    #[error("This expression statement did not produce any model")]
191    EmptyModelExpression,
192
193    /// This error happens if the workbench produced a different output type.
194    #[error("The {0} workbench produced a 2D output, but expected {2} output.")]
195    WorkbenchInvalidOutput(WorkbenchKind, OutputType, OutputType),
196
197    /// This error happens if the workbench produced a different output type.
198    #[error("The {0} workbench will produce no {1} output.")]
199    WorkbenchNoOutput(WorkbenchKind, OutputType),
200
201    /// Unexpected source file in expression
202    #[error("Unexpected source file {0} in expression")]
203    InvalidSelfReference(Identifier),
204
205    /// Resolve Error
206    #[error("Resolve error {0}")]
207    ResolveError(#[from] ResolveError),
208
209    /// Unexpected source file in expression
210    #[error("{0} is not operation.")]
211    NotAnOperation(QualifiedName),
212
213    /// Calling an operation on an empty geometry, e.g.: `{}.op()`.
214    #[error("Calling operation on empty geometry")]
215    OperationOnEmptyGeometry,
216
217    /// Cannot call operation without workpiece, e.g. `op()`.
218    #[error("Cannot call operation without workpiece.")]
219    CannotCallOperationWithoutWorkpiece,
220
221    /// Function missing return statement
222    #[error("Missing return statement in {0}")]
223    MissingReturn(QualifiedName),
224
225    /// There is no model in this workbench
226    #[error("Missing model in workbench")]
227    NoModelInWorkbench,
228
229    /// Found a symbol and a property with that name
230    #[error("Found a symbol and a property with names {0} and {1}")]
231    AmbiguousProperty(QualifiedName, Identifier),
232
233    /// Assignment failed because value already has been initialized
234    #[error("Value {0} already has been initialized with {1} (at line {2})")]
235    ValueAlreadyInitialized(Identifier, Value, SrcRef),
236
237    /// Assignment failed because left side is not an l-value
238    #[error("Assignment failed because {0} is not an l-value")]
239    NotAnLValue(Identifier),
240
241    /// Found symbol but it's not visible to user
242    #[error("Symbol {what} is private from within {within}")]
243    SymbolIsPrivate {
244        /// what was searched
245        what: QualifiedName,
246        /// where it was searched
247        within: QualifiedName,
248    },
249
250    /// Found symbol but it's not visible to user
251    #[error("Symbol {what} (aliased from {alias}) is private from within {within}")]
252    SymbolBehindAliasIsPrivate {
253        /// what was searched
254        what: QualifiedName,
255        /// the alias in between
256        alias: QualifiedName,
257        /// where it was searched
258        within: QualifiedName,
259    },
260}
261
262/// Result type of any evaluation.
263pub type EvalResult<T> = std::result::Result<T, EvalError>;