Improve error reports

This commit is contained in:
Jeff 2024-08-09 01:43:58 -04:00
parent c1b71ffccc
commit 83018ec5ec
5 changed files with 83 additions and 40 deletions

View File

@ -225,6 +225,20 @@ pub enum AnalyzerError {
UnexpectedIdentifier { identifier: Node, position: Span },
}
impl AnalyzerError {
pub fn position(&self) -> Span {
match self {
AnalyzerError::ExpectedBoolean { position, .. } => *position,
AnalyzerError::ExpectedFunction { position, .. } => *position,
AnalyzerError::ExpectedIdentifier { position, .. } => *position,
AnalyzerError::ExpectedIdentifierOrValue { position, .. } => *position,
AnalyzerError::ExpectedIntegerOrFloat { position, .. } => *position,
AnalyzerError::ExpectedIntegerFloatOrString { position, .. } => *position,
AnalyzerError::UnexpectedIdentifier { position, .. } => *position,
}
}
}
impl Error for AnalyzerError {}
impl Display for AnalyzerError {

View File

@ -22,30 +22,10 @@ impl<'src> DustError<'src> {
VmError::AnaylyzerError(_) => "Analyzer error",
VmError::ParseError(_) => "Parse error",
VmError::ValueError { .. } => "Value error",
VmError::BuiltInFunctionCallError(_) => "Runtime error",
VmError::BuiltInFunctionError { .. } => "Runtime error",
_ => "Analysis Failure",
};
let span = match &self.vm_error {
VmError::AnaylyzerError(analyzer_error) => match analyzer_error {
AnalyzerError::ExpectedBoolean { position, .. } => position,
AnalyzerError::ExpectedFunction { position, .. } => position,
AnalyzerError::ExpectedIdentifier { position, .. } => position,
AnalyzerError::ExpectedIdentifierOrValue { position, .. } => position,
AnalyzerError::ExpectedIntegerOrFloat { position, .. } => position,
AnalyzerError::ExpectedIntegerFloatOrString { position, .. } => position,
AnalyzerError::UnexpectedIdentifier { position, .. } => position,
},
VmError::ParseError(parse_error) => &parse_error.position(),
VmError::ValueError { position, .. } => position,
VmError::BuiltInFunctionCallError(_) => todo!(),
VmError::ExpectedIdentifier { position } => position,
VmError::ExpectedIdentifierOrInteger { position } => position,
VmError::ExpectedInteger { position } => position,
VmError::ExpectedFunction { position, .. } => position,
VmError::ExpectedList { position } => position,
VmError::ExpectedValue { position } => position,
VmError::UndefinedIdentifier { position, .. } => position,
};
let span = self.vm_error.position();
let label = self.vm_error.to_string();
let message = Level::Error.title(title).snippet(
Snippet::source(self.source).annotation(Level::Info.span(span.0..span.1).label(&label)),

View File

@ -108,12 +108,14 @@ impl Lexer {
self.lex_number(source)?
} else if "-Infinity" == self.peek_chars(source, 9) {
self.position += 9;
(
Token::Float(f64::NEG_INFINITY),
(self.position - 9, self.position),
)
} else {
self.position += 1;
(Token::Minus, (self.position - 1, self.position))
}
}
@ -122,41 +124,54 @@ impl Lexer {
'\'' => self.lex_string('\'', source)?,
'+' => {
self.position += 1;
(Token::Plus, (self.position - 1, self.position))
}
'*' => {
self.position += 1;
(Token::Star, (self.position - 1, self.position))
}
'(' => {
self.position += 1;
(Token::LeftParenthesis, (self.position - 1, self.position))
}
')' => {
self.position += 1;
(Token::RightParenthesis, (self.position - 1, self.position))
}
'=' => {
self.position += 1;
(Token::Equal, (self.position - 1, self.position))
}
'[' => {
self.position += 1;
(Token::LeftSquareBrace, (self.position - 1, self.position))
}
']' => {
self.position += 1;
(Token::RightSquareBrace, (self.position - 1, self.position))
}
',' => {
self.position += 1;
(Token::Comma, (self.position - 1, self.position))
}
'.' => {
self.position += 1;
(Token::Dot, (self.position - 1, self.position))
}
_ => return Err(LexError::UnexpectedCharacter(c)),
_ => {
self.position += 1;
return Err(LexError::UnexpectedCharacter(c));
}
}
} else {
(Token::Eof, (self.position, self.position))

View File

@ -128,13 +128,23 @@ impl<'src> Parser<'src> {
}
fn next_token(&mut self) -> Result<(), ParseError> {
self.current =
self.lexer
.next_token(self.source)
.map_err(|lex_error| ParseError::LexError {
let next = self.lexer.next_token(self.source);
self.current = match next {
Ok((token, position)) => (token, position),
Err(lex_error) => {
let position = {
self.next_token()?;
self.current.1
};
return Err(ParseError::LexError {
error: lex_error,
position: self.current.1,
})?;
position,
});
}
};
Ok(())
}

View File

@ -122,7 +122,13 @@ impl Vm {
} else {
None
};
let function_call_return = function.call(None, values)?;
let function_call_return =
function
.call(None, values)
.map_err(|built_in_function_error| VmError::BuiltInFunctionError {
error: built_in_function_error,
position: node.position,
})?;
Ok(function_call_return)
}
@ -269,7 +275,12 @@ impl Vm {
}
}
let function_call_return = function.call(None, Some(value_arguments))?;
let function_call_return = function.call(None, Some(value_arguments)).map_err(
|built_in_function_error| VmError::BuiltInFunctionError {
error: built_in_function_error,
position: right_span,
},
)?;
return Ok(function_call_return);
}
@ -319,7 +330,10 @@ pub enum VmError {
// Anaylsis Failures
// These should be prevented by running the analyzer before the VM
BuiltInFunctionCallError(BuiltInFunctionError),
BuiltInFunctionError {
error: BuiltInFunctionError,
position: Span,
},
ExpectedIdentifier {
position: Span,
},
@ -345,9 +359,21 @@ pub enum VmError {
},
}
impl From<BuiltInFunctionError> for VmError {
fn from(v: BuiltInFunctionError) -> Self {
Self::BuiltInFunctionCallError(v)
impl VmError {
pub fn position(&self) -> Span {
match self {
Self::AnaylyzerError(analyzer_error) => analyzer_error.position(),
Self::ParseError(parse_error) => parse_error.position(),
Self::ValueError { position, .. } => *position,
Self::BuiltInFunctionError { position, .. } => *position,
Self::ExpectedIdentifier { position } => *position,
Self::ExpectedIdentifierOrInteger { position } => *position,
Self::ExpectedInteger { position } => *position,
Self::ExpectedFunction { position, .. } => *position,
Self::ExpectedList { position } => *position,
Self::ExpectedValue { position } => *position,
Self::UndefinedIdentifier { position, .. } => *position,
}
}
}
@ -369,9 +395,7 @@ impl Error for VmError {
Self::AnaylyzerError(analyzer_error) => Some(analyzer_error),
Self::ParseError(parse_error) => Some(parse_error),
Self::ValueError { error, .. } => Some(error),
Self::BuiltInFunctionCallError(built_in_function_error) => {
Some(built_in_function_error)
}
Self::BuiltInFunctionError { error, .. } => Some(error),
_ => None,
}
}
@ -383,8 +407,8 @@ impl Display for VmError {
Self::AnaylyzerError(analyzer_error) => write!(f, "{}", analyzer_error),
Self::ParseError(parse_error) => write!(f, "{}", parse_error),
Self::ValueError { error, .. } => write!(f, "{}", error),
Self::BuiltInFunctionCallError(built_in_function_error) => {
write!(f, "{}", built_in_function_error)
Self::BuiltInFunctionError { error, .. } => {
write!(f, "{}", error)
}
Self::ExpectedFunction { actual, position } => {
write!(