brooks_lib/mel/interpreter/
error.rs1use std::{error::Error, fmt::Display};
21
22use crate::{
23 common::TextLocation,
24 mel::{ast::BinaryInfixOperator, interpreter::interpret::MelInterpContext, types::Type},
25};
26
27#[derive(Debug, Clone)]
28pub enum InterpAssertion {
29 TypeMismatch(Type, Type),
30 SuccessWithoutValue(String, String),
31 UnexpectedOperator(BinaryInfixOperator),
32}
33
34impl Display for InterpAssertion {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 match self {
37 InterpAssertion::SuccessWithoutValue(what, whre) => write!(
38 f,
39 "Successful evaluation of subexpression {what} did not yield a value in {whre}"
40 ),
41 InterpAssertion::UnexpectedOperator(oper) => write!(
42 f,
43 "Unexpected binary infix operator during evaluation: {oper}",
44 ),
45 InterpAssertion::TypeMismatch(expected, actual) => {
46 write!(f, "Expected type {expected}, have type {actual}",)
47 }
48 }
49 }
50}
51
52#[derive(Debug, Clone)]
53pub enum MelInterpPreconditions {}
54
55impl Display for MelInterpPreconditions {
56 fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 Ok(())
58 }
59}
60
61#[derive(Debug, Clone)]
62pub enum InterpError {
63 Assertion(Box<InterpAssertion>),
64 ValueError(Box<TypedValueError>),
65 UnknownIdentifier(String),
66 UnknownField(String),
67 MistypedField(String, Type, Type),
68 BuiltinError(Box<BuiltinInterpError>),
69}
70
71impl Display for InterpError {
72 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73 write!(f, "Mel interpreter error: ")?;
74 match self {
75 InterpError::ValueError(mel_value_error) => {
76 write!(f, "value failure: {}", mel_value_error)
77 }
78 InterpError::Assertion(mel_interp_assertion) => {
79 write!(f, "assertion failure: {}", mel_interp_assertion)
80 }
81 InterpError::UnknownIdentifier(id) => {
82 write!(f, "unknown identifier: {}", id)
83 }
84 InterpError::UnknownField(field) => {
85 write!(f, "unknown field: {}", field)
86 }
87 InterpError::BuiltinError(bi) => {
88 write!(f, "error executing builtin function: {}", bi)
89 }
90 InterpError::MistypedField(field, expected, actual) => {
91 write!(
92 f,
93 "error adding field to struct: field {field} has wrong type (expected: {expected}, actual: {actual})",
94 )
95 }
96 }
97 }
98}
99
100impl Error for InterpError {}
101
102#[derive(Debug, Clone)]
103pub enum BuiltinInterpError {
104 ArgumentMiscount(usize, usize),
105 ArgumentMismatch(usize, Type, Type),
106 RuntimeError(String),
107 ArgumentsInvalid,
108}
109
110impl Display for BuiltinInterpError {
111 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112 match self {
113 BuiltinInterpError::ArgumentMiscount(expected, actual) => {
114 write!(f, "Expected {expected} arguments but got {actual}")
115 }
116 BuiltinInterpError::ArgumentMismatch(which, expected, actual) => write!(
117 f,
118 "Expected argument {which} to have type {expected} but it has {actual}",
119 ),
120 BuiltinInterpError::ArgumentsInvalid => write!(f, "Invalid arguments"),
121 BuiltinInterpError::RuntimeError(e) => write!(f, "Runtime error: {e}"),
122 }
123 }
124}
125
126#[derive(Debug, Clone)]
127pub enum TypedValueError {
128 ConversionError(String),
129}
130
131impl Display for TypedValueError {
132 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133 match self {
134 TypedValueError::ConversionError(ce) => write!(f, "Conversion error: {ce}"),
135 }
136 }
137}
138#[derive(Debug)]
139pub struct InterpLocatableError {
140 pub error: Box<InterpError>,
141 pub location: TextLocation,
142 pub context: MelInterpContext,
143}
144
145impl Display for InterpLocatableError {
146 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
147 write!(f, "{} ({})", self.error, self.location)
148 }
149}
150
151impl std::error::Error for InterpLocatableError {}