Reid/src/errors.rs

211 lines
6.7 KiB
Rust
Raw Permalink Normal View History

2020-06-21 00:37:56 +02:00
use std::fmt;
use std::fmt::Display;
2020-06-21 00:21:24 +02:00
use std::io;
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
2020-06-24 23:39:18 +02:00
use std::num::ParseIntError;
2020-06-21 00:21:24 +02:00
2020-07-05 21:20:49 +02:00
#[cfg(feature = "compiler")]
use super::compiler::ArithmeticOp;
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
use super::vm::Position;
2020-06-24 20:58:16 +02:00
use super::vm::VariableType;
2020-06-21 00:21:24 +02:00
#[derive(Debug)]
pub enum GenericError {
StdIOError(io::Error),
CorruptedBytecode,
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
SyntaxError(SyntaxError),
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
CompilerError(CompilerError),
2020-06-21 00:21:24 +02:00
}
impl From<io::Error> for GenericError {
fn from(error: io::Error) -> Self {
Self::StdIOError(error)
}
}
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
impl From<SyntaxError> for GenericError {
fn from(error: SyntaxError) -> Self {
Self::SyntaxError(error)
}
}
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
impl From<CompilerError> for GenericError {
fn from(error: CompilerError) -> Self {
Self::CompilerError(error)
}
}
impl Display for GenericError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let text = match self {
GenericError::StdIOError(err) => format!("IO Error: {}", err),
GenericError::CorruptedBytecode => {
"Failed to read bytecode. Bytecode might be corrupted.".to_string()
}
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
GenericError::SyntaxError(err) => format!("Syntax Error: {}", err),
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
GenericError::CompilerError(err) => format!("Compiler Error: {}", err),
};
write!(f, "{}", text)
}
}
2020-06-21 00:21:24 +02:00
#[derive(Debug)]
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
2020-06-22 20:49:21 +02:00
pub enum SyntaxError {
2020-06-24 23:46:05 +02:00
#[allow(dead_code)]
2020-06-21 00:21:24 +02:00
Fatal,
ExpectedToken(Position, char),
2020-06-22 20:49:21 +02:00
ExpectedExpression(Position, Option<Box<SyntaxError>>),
2020-06-21 00:21:24 +02:00
ExpectedIdent(Position),
2020-06-22 20:49:21 +02:00
ExpectedStatement(Position, Option<Box<SyntaxError>>),
2020-06-21 00:21:24 +02:00
ExpectedPattern(Position),
}
2020-06-21 00:37:56 +02:00
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
2020-06-22 20:49:21 +02:00
impl SyntaxError {
fn from_opt(from: &Option<Box<SyntaxError>>) -> String {
2020-06-22 15:58:42 +02:00
if let Some(err) = from {
format!("\n {}", err)
} else {
String::new()
}
}
}
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
2020-06-22 20:49:21 +02:00
impl Display for SyntaxError {
2020-06-21 00:37:56 +02:00
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let text = match self {
2020-06-22 20:49:21 +02:00
SyntaxError::Fatal => "Fatal error".to_string(),
SyntaxError::ExpectedToken(pos, c) => format!("Expected token '{}' at {}", c, pos),
SyntaxError::ExpectedExpression(pos, err) => format!(
2020-06-22 15:58:42 +02:00
"Expected expression at {}{}",
pos,
2020-06-22 20:49:21 +02:00
SyntaxError::from_opt(err)
2020-06-22 15:58:42 +02:00
),
2020-06-22 20:49:21 +02:00
SyntaxError::ExpectedIdent(pos) => format!("Expected ident at {}", pos),
SyntaxError::ExpectedStatement(pos, err) => format!(
2020-06-22 15:58:42 +02:00
"Expected statement at {}{}",
pos,
2020-06-22 20:49:21 +02:00
SyntaxError::from_opt(err)
2020-06-22 15:58:42 +02:00
),
2020-06-22 20:49:21 +02:00
SyntaxError::ExpectedPattern(pos) => format!("Expected pattern at {}", pos),
2020-06-21 00:37:56 +02:00
};
write!(f, "{}", text)
}
}
2020-06-22 20:49:21 +02:00
#[derive(Debug)]
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
2020-06-22 20:49:21 +02:00
pub enum CompilerError {
2020-06-24 23:46:05 +02:00
#[allow(dead_code)]
2020-06-22 20:49:21 +02:00
Fatal,
VariableExists(Position, String),
VariableNotExists(Position, String),
InvalidScopeExit(Position),
LetFailed(Position, Box<CompilerError>),
CanNotAssignVoidType,
2020-06-24 20:58:16 +02:00
FunctionNotFound(Position, String, Vec<VariableType>),
2020-06-24 23:39:18 +02:00
ParseIntError(ParseIntError),
2020-07-05 21:20:49 +02:00
ArithmeticExpressionFailed(Position, Box<CompilerError>),
InvalidArithmeticOperation(ArithmeticOp),
2020-06-22 20:49:21 +02:00
}
2020-07-02 22:13:10 +02:00
#[cfg(feature = "compiler")]
impl Display for CompilerError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let text = match self {
CompilerError::Fatal => "Fatal error".to_string(),
CompilerError::VariableExists(pos, name) => {
format!("Variable '{}' already exists, re-assign at {}", pos, name)
}
CompilerError::VariableNotExists(pos, name) => {
format!("Variable '{}' does not exist, at {}", name, pos)
}
CompilerError::InvalidScopeExit(pos) => {
format!("Attempted to escape a scope invalidly at {}", pos)
}
CompilerError::LetFailed(pos, error) => {
format!("Let statement failed at {}:\n {}", pos, error)
}
2020-06-25 00:13:35 +02:00
CompilerError::CanNotAssignVoidType => "Can not assign void type here".to_string(),
2020-06-24 20:58:16 +02:00
CompilerError::FunctionNotFound(pos, name, params) => format!(
"Function with signature {}{} not found at {}",
name,
ParamList(params.clone()),
pos
),
2020-06-24 23:39:18 +02:00
CompilerError::ParseIntError(err) => format!("Failed to parse integer value: {}", err),
2020-07-05 21:20:49 +02:00
CompilerError::ArithmeticExpressionFailed(pos, err) => {
format!("Arithmetic expression failed at {}:\n {}", pos, err)
}
CompilerError::InvalidArithmeticOperation(op) => {
let text = match op {
ArithmeticOp::Add(t1, t2, _) => {
format!("{} + {}", t1.to_string(), t2.to_string())
}
ArithmeticOp::Subtract(t1, t2, _) => {
format!("{} - {}", t1.to_string(), t2.to_string())
}
ArithmeticOp::Mult(t1, t2, _) => {
format!("{} * {}", t1.to_string(), t2.to_string())
}
2020-07-06 11:42:38 +02:00
ArithmeticOp::Pow(t1, t2, _) => {
format!("{} ** {}", t1.to_string(), t2.to_string())
}
ArithmeticOp::Div(t1, t2, _) => {
format!("{} / {}", t1.to_string(), t2.to_string())
}
2020-07-07 14:06:10 +02:00
ArithmeticOp::Mod(t1, t2, _) => {
format!("{} % {}", t1.to_string(), t2.to_string())
}
2020-07-05 21:20:49 +02:00
};
format!("Invalid arithmetic operation: {}", text)
}
};
write!(f, "{}", text)
}
}
2020-06-24 20:58:16 +02:00
struct ParamList(Vec<VariableType>);
impl Display for ParamList {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut text = String::new();
text += "(";
for (idx, vtype) in self.0.iter().enumerate() {
if idx > 0 {
text += ", ";
}
text += &vtype.to_string();
}
text += ")";
write!(f, "{}", text)
}
}
#[derive(Debug)]
pub enum RuntimePanic {
2020-06-24 23:46:05 +02:00
#[allow(dead_code)]
Fatal,
InvalidCommandIdx(usize),
ScopeStackUnderflow,
StackUnderflow,
StackOverflow,
RegistryNotDefined,
InvalidHeapAddress,
ValueNotInitialized,
2020-06-24 16:37:53 +02:00
InvalidTypeAssign,
2020-06-24 20:58:16 +02:00
InvalidFuncAddress,
2020-07-05 21:20:49 +02:00
AttemptedInvalidArithmeticOperation,
}