diff --git a/src/base/error.rs b/src/base/error.rs index 6e46584..0d71f36 100644 --- a/src/base/error.rs +++ b/src/base/error.rs @@ -1,20 +1,20 @@ /// An error that occurred during compilation. #[allow(missing_docs)] -#[derive(Debug, thiserror::Error)] +#[derive(Debug, thiserror::Error, Clone, PartialEq, Eq)] pub enum Error { #[error("An error occurred while working with Input/Output: {0}")] IoError(String), #[error(transparent)] Utf8Error(#[from] std::str::Utf8Error), - #[error("An error occurred while lexing the source code.")] + #[error("An error occurred while lexing the source code: {0}")] LexicalError(#[from] crate::lexical::Error), - #[error("An error occured while tokenizing the source code.")] + #[error("An error occured while tokenizing the source code: {0}")] TokenizeError(#[from] crate::lexical::token::TokenizeError), #[error(transparent)] ParseError(#[from] crate::syntax::error::Error), #[error(transparent)] TranspileError(#[from] crate::transpile::TranspileError), - #[error("An error occurred")] + #[error("An error occurred: {0}")] Other(&'static str), } diff --git a/src/transpile/error.rs b/src/transpile/error.rs index b0c9fc9..d003250 100644 --- a/src/transpile/error.rs +++ b/src/transpile/error.rs @@ -17,16 +17,16 @@ use super::transpiler::FunctionData; /// Errors that can occur during transpilation. #[allow(clippy::module_name_repetitions, missing_docs)] -#[derive(Debug, thiserror::Error, Clone)] +#[derive(Debug, thiserror::Error, Clone, PartialEq, Eq)] pub enum TranspileError { #[error(transparent)] MissingFunctionDeclaration(#[from] MissingFunctionDeclaration), - #[error("Unexpected expression: {}", .0.span().str())] - UnexpectedExpression(Expression), + #[error(transparent)] + UnexpectedExpression(#[from] UnexpectedExpression), #[error("Lua code evaluation is disabled.")] LuaDisabled, - #[error("Lua runtime error: {}", .0)] - LuaRuntimeError(String), + #[error(transparent)] + LuaRuntimeError(#[from] LuaRuntimeError), } /// The result of a transpilation operation. @@ -101,3 +101,51 @@ impl Display for MissingFunctionDeclaration { } impl std::error::Error for MissingFunctionDeclaration {} + +/// An error that occurs when a function declaration is missing. +#[allow(clippy::module_name_repetitions)] +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct LuaRuntimeError { + pub code_block: Span, + pub error_message: String, +} + +impl Display for LuaRuntimeError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let message = format!( + r#"error during lua code execution: "{}""#, + self.error_message + ); + write!(f, "{}", Message::new(Severity::Error, message))?; + + write!( + f, + "\n{}", + SourceCodeDisplay::new(&self.code_block, Option::::None) + ) + } +} + +impl std::error::Error for LuaRuntimeError {} + +/// An error that occurs when a function declaration is missing. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct UnexpectedExpression(pub Expression); + +impl Display for UnexpectedExpression { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + Message::new(Severity::Error, "encountered unexpected expression") + )?; + + write!( + f, + "\n{}", + SourceCodeDisplay::new(&self.0.span(), Option::::None) + ) + } +} + +impl std::error::Error for UnexpectedExpression {} diff --git a/src/transpile/lua.rs b/src/transpile/lua.rs index 3c2e786..5567cf8 100644 --- a/src/transpile/lua.rs +++ b/src/transpile/lua.rs @@ -7,7 +7,7 @@ mod enabled { use crate::{ base::{self, source_file::SourceElement, Handler}, syntax::syntax_tree::expression::LuaCode, - transpile::error::{TranspileError, TranspileResult}, + transpile::error::{LuaRuntimeError, TranspileError, TranspileResult}, }; impl LuaCode { @@ -48,26 +48,21 @@ mod enabled { .set_name(name) .eval::() .map_err(|err| { - let err = TranspileError::from(err); - handler.receive(err.clone()); + let err_string = err.to_string(); + let err = TranspileError::from(LuaRuntimeError { + error_message: err_string + .strip_prefix("runtime error: ") + .unwrap_or(&err_string) + .to_string(), + code_block: self.span(), + }); + handler.receive(crate::Error::from(err.clone())); err })?; Ok(lua_result) } } - - impl From for TranspileError { - fn from(value: mlua::Error) -> Self { - let string = value.to_string(); - Self::LuaRuntimeError( - string - .strip_prefix("runtime error: ") - .unwrap_or(&string) - .to_string(), - ) - } - } } #[cfg(not(feature = "lua"))] diff --git a/src/transpile/transpiler.rs b/src/transpile/transpiler.rs index 923fa83..64033a7 100644 --- a/src/transpile/transpiler.rs +++ b/src/transpile/transpiler.rs @@ -23,7 +23,7 @@ use crate::{ transpile::error::MissingFunctionDeclaration, }; -use super::error::{TranspileError, TranspileResult}; +use super::error::{TranspileError, TranspileResult, UnexpectedExpression}; /// A transpiler for `ShulkerScript`. #[derive(Debug)] @@ -396,7 +396,9 @@ impl Transpiler { self.transpile_function_call(func, handler).map(Some) } unexpected => { - let error = TranspileError::UnexpectedExpression(unexpected.clone()); + let error = TranspileError::UnexpectedExpression(UnexpectedExpression( + unexpected.clone(), + )); handler.receive(error.clone()); Err(error) }