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 }, 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 Error for AnalyzerError {}
impl Display for AnalyzerError { impl Display for AnalyzerError {

View File

@ -22,30 +22,10 @@ impl<'src> DustError<'src> {
VmError::AnaylyzerError(_) => "Analyzer error", VmError::AnaylyzerError(_) => "Analyzer error",
VmError::ParseError(_) => "Parse error", VmError::ParseError(_) => "Parse error",
VmError::ValueError { .. } => "Value error", VmError::ValueError { .. } => "Value error",
VmError::BuiltInFunctionCallError(_) => "Runtime error", VmError::BuiltInFunctionError { .. } => "Runtime error",
_ => "Analysis Failure", _ => "Analysis Failure",
}; };
let span = match &self.vm_error { let span = self.vm_error.position();
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 label = self.vm_error.to_string(); let label = self.vm_error.to_string();
let message = Level::Error.title(title).snippet( let message = Level::Error.title(title).snippet(
Snippet::source(self.source).annotation(Level::Info.span(span.0..span.1).label(&label)), 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)? self.lex_number(source)?
} else if "-Infinity" == self.peek_chars(source, 9) { } else if "-Infinity" == self.peek_chars(source, 9) {
self.position += 9; self.position += 9;
( (
Token::Float(f64::NEG_INFINITY), Token::Float(f64::NEG_INFINITY),
(self.position - 9, self.position), (self.position - 9, self.position),
) )
} else { } else {
self.position += 1; self.position += 1;
(Token::Minus, (self.position - 1, self.position)) (Token::Minus, (self.position - 1, self.position))
} }
} }
@ -122,41 +124,54 @@ impl Lexer {
'\'' => self.lex_string('\'', source)?, '\'' => self.lex_string('\'', source)?,
'+' => { '+' => {
self.position += 1; self.position += 1;
(Token::Plus, (self.position - 1, self.position)) (Token::Plus, (self.position - 1, self.position))
} }
'*' => { '*' => {
self.position += 1; self.position += 1;
(Token::Star, (self.position - 1, self.position)) (Token::Star, (self.position - 1, self.position))
} }
'(' => { '(' => {
self.position += 1; self.position += 1;
(Token::LeftParenthesis, (self.position - 1, self.position)) (Token::LeftParenthesis, (self.position - 1, self.position))
} }
')' => { ')' => {
self.position += 1; self.position += 1;
(Token::RightParenthesis, (self.position - 1, self.position)) (Token::RightParenthesis, (self.position - 1, self.position))
} }
'=' => { '=' => {
self.position += 1; self.position += 1;
(Token::Equal, (self.position - 1, self.position)) (Token::Equal, (self.position - 1, self.position))
} }
'[' => { '[' => {
self.position += 1; self.position += 1;
(Token::LeftSquareBrace, (self.position - 1, self.position)) (Token::LeftSquareBrace, (self.position - 1, self.position))
} }
']' => { ']' => {
self.position += 1; self.position += 1;
(Token::RightSquareBrace, (self.position - 1, self.position)) (Token::RightSquareBrace, (self.position - 1, self.position))
} }
',' => { ',' => {
self.position += 1; self.position += 1;
(Token::Comma, (self.position - 1, self.position)) (Token::Comma, (self.position - 1, self.position))
} }
'.' => { '.' => {
self.position += 1; self.position += 1;
(Token::Dot, (self.position - 1, self.position)) (Token::Dot, (self.position - 1, self.position))
} }
_ => return Err(LexError::UnexpectedCharacter(c)), _ => {
self.position += 1;
return Err(LexError::UnexpectedCharacter(c));
}
} }
} else { } else {
(Token::Eof, (self.position, self.position)) (Token::Eof, (self.position, self.position))

View File

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

View File

@ -122,7 +122,13 @@ impl Vm {
} else { } else {
None 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) 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); return Ok(function_call_return);
} }
@ -319,7 +330,10 @@ pub enum VmError {
// Anaylsis Failures // Anaylsis Failures
// These should be prevented by running the analyzer before the VM // These should be prevented by running the analyzer before the VM
BuiltInFunctionCallError(BuiltInFunctionError), BuiltInFunctionError {
error: BuiltInFunctionError,
position: Span,
},
ExpectedIdentifier { ExpectedIdentifier {
position: Span, position: Span,
}, },
@ -345,9 +359,21 @@ pub enum VmError {
}, },
} }
impl From<BuiltInFunctionError> for VmError { impl VmError {
fn from(v: BuiltInFunctionError) -> Self { pub fn position(&self) -> Span {
Self::BuiltInFunctionCallError(v) 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::AnaylyzerError(analyzer_error) => Some(analyzer_error),
Self::ParseError(parse_error) => Some(parse_error), Self::ParseError(parse_error) => Some(parse_error),
Self::ValueError { error, .. } => Some(error), Self::ValueError { error, .. } => Some(error),
Self::BuiltInFunctionCallError(built_in_function_error) => { Self::BuiltInFunctionError { error, .. } => Some(error),
Some(built_in_function_error)
}
_ => None, _ => None,
} }
} }
@ -383,8 +407,8 @@ impl Display for VmError {
Self::AnaylyzerError(analyzer_error) => write!(f, "{}", analyzer_error), Self::AnaylyzerError(analyzer_error) => write!(f, "{}", analyzer_error),
Self::ParseError(parse_error) => write!(f, "{}", parse_error), Self::ParseError(parse_error) => write!(f, "{}", parse_error),
Self::ValueError { error, .. } => write!(f, "{}", error), Self::ValueError { error, .. } => write!(f, "{}", error),
Self::BuiltInFunctionCallError(built_in_function_error) => { Self::BuiltInFunctionError { error, .. } => {
write!(f, "{}", built_in_function_error) write!(f, "{}", error)
} }
Self::ExpectedFunction { actual, position } => { Self::ExpectedFunction { actual, position } => {
write!( write!(