use super::parser::Position; use std::fmt; use std::fmt::Display; use std::io; use std::num::ParseIntError; use super::vm::VariableType; #[derive(Debug)] pub enum GenericError { StdIOError(io::Error), } impl From for GenericError { fn from(error: io::Error) -> Self { Self::StdIOError(error) } } #[derive(Debug)] pub enum SyntaxError { #[allow(dead_code)] Fatal, ExpectedToken(Position, char), ExpectedExpression(Position, Option>), ExpectedIdent(Position), ExpectedStatement(Position, Option>), ExpectedPattern(Position), } impl SyntaxError { fn from_opt(from: &Option>) -> String { if let Some(err) = from { format!("\n {}", err) } else { String::new() } } } impl Display for SyntaxError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let text = match self { SyntaxError::Fatal => "Fatal error".to_string(), SyntaxError::ExpectedToken(pos, c) => format!("Expected token '{}' at {}", c, pos), SyntaxError::ExpectedExpression(pos, err) => format!( "Expected expression at {}{}", pos, SyntaxError::from_opt(err) ), SyntaxError::ExpectedIdent(pos) => format!("Expected ident at {}", pos), SyntaxError::ExpectedStatement(pos, err) => format!( "Expected statement at {}{}", pos, SyntaxError::from_opt(err) ), SyntaxError::ExpectedPattern(pos) => format!("Expected pattern at {}", pos), }; write!(f, "{}", text) } } #[derive(Debug)] pub enum CompilerError { #[allow(dead_code)] Fatal, VariableExists(Position, String), VariableNotExists(Position, String), InvalidScopeExit(Position), LetFailed(Position, Box), CanNotAssignVoidType, FunctionNotFound(Position, String, Vec), ParseIntError(ParseIntError), } 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) } CompilerError::CanNotAssignVoidType => format!("Can not assign void type here"), CompilerError::FunctionNotFound(pos, name, params) => format!( "Function with signature {}{} not found at {}", name, ParamList(params.clone()), pos ), CompilerError::ParseIntError(err) => format!("Failed to parse integer value: {}", err), }; write!(f, "{}", text) } } struct ParamList(Vec); 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 { #[allow(dead_code)] Fatal, InvalidCommandIdx(usize), ScopeStackUnderflow, StackUnderflow, StackOverflow, RegistryNotDefined, InvalidHeapAddress, ValueNotInitialized, InvalidTypeAssign, InvalidFuncAddress, }