Refactor errors and clean up read_line

This commit is contained in:
Jeff 2024-08-09 00:49:17 -04:00
parent 9766777a47
commit c1b71ffccc
5 changed files with 81 additions and 23 deletions

View File

@ -92,7 +92,7 @@ impl BuiltInFunction {
stdin().read_line(&mut input)?; stdin().read_line(&mut input)?;
Ok(Some(Value::string(input))) Ok(Some(Value::string(input.trim_end_matches('\n'))))
} else { } else {
Err(BuiltInFunctionError::WrongNumberOfValueArguments) Err(BuiltInFunctionError::WrongNumberOfValueArguments)
} }

View File

@ -35,7 +35,7 @@ impl<'src> DustError<'src> {
AnalyzerError::ExpectedIntegerFloatOrString { position, .. } => position, AnalyzerError::ExpectedIntegerFloatOrString { position, .. } => position,
AnalyzerError::UnexpectedIdentifier { position, .. } => position, AnalyzerError::UnexpectedIdentifier { position, .. } => position,
}, },
VmError::ParseError(_) => todo!(), VmError::ParseError(parse_error) => &parse_error.position(),
VmError::ValueError { position, .. } => position, VmError::ValueError { position, .. } => position,
VmError::BuiltInFunctionCallError(_) => todo!(), VmError::BuiltInFunctionCallError(_) => todo!(),
VmError::ExpectedIdentifier { position } => position, VmError::ExpectedIdentifier { position } => position,
@ -44,6 +44,7 @@ impl<'src> DustError<'src> {
VmError::ExpectedFunction { position, .. } => position, VmError::ExpectedFunction { position, .. } => position,
VmError::ExpectedList { position } => position, VmError::ExpectedList { position } => position,
VmError::ExpectedValue { 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(

View File

@ -128,7 +128,13 @@ impl<'src> Parser<'src> {
} }
fn next_token(&mut self) -> Result<(), ParseError> { fn next_token(&mut self) -> Result<(), ParseError> {
self.current = self.lexer.next_token(self.source)?; self.current =
self.lexer
.next_token(self.source)
.map_err(|lex_error| ParseError::LexError {
error: lex_error,
position: self.current.1,
})?;
Ok(()) Ok(())
} }
@ -341,7 +347,10 @@ impl<'src> Parser<'src> {
left_span, left_span,
)) ))
} }
_ => Err(ParseError::UnexpectedToken(self.current.0.to_owned())), _ => Err(ParseError::UnexpectedToken {
actual: self.current.0.to_owned(),
position: self.current.1,
}),
} }
} }
@ -359,18 +368,30 @@ impl<'src> Parser<'src> {
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum ParseError { pub enum ParseError {
LexError(LexError), LexError { error: LexError, position: Span },
ExpectedClosingParenthesis { actual: TokenOwned, position: Span }, ExpectedClosingParenthesis { actual: TokenOwned, position: Span },
ExpectedClosingSquareBrace { actual: TokenOwned, position: Span }, ExpectedClosingSquareBrace { actual: TokenOwned, position: Span },
ExpectedOpeningParenthesis { actual: TokenOwned, position: Span }, ExpectedOpeningParenthesis { actual: TokenOwned, position: Span },
UnexpectedToken(TokenOwned), UnexpectedToken { actual: TokenOwned, position: Span },
}
impl ParseError {
pub fn position(&self) -> Span {
match self {
Self::LexError { position, .. } => *position,
Self::ExpectedClosingParenthesis { position, .. } => *position,
Self::ExpectedClosingSquareBrace { position, .. } => *position,
Self::ExpectedOpeningParenthesis { position, .. } => *position,
Self::UnexpectedToken { position, .. } => *position,
}
}
} }
impl Error for ParseError { impl Error for ParseError {
fn source(&self) -> Option<&(dyn Error + 'static)> { fn source(&self) -> Option<&(dyn Error + 'static)> {
match self { match self {
Self::LexError(error) => Some(error), Self::LexError { error, .. } => Some(error),
_ => None, _ => None,
} }
} }
@ -379,7 +400,7 @@ impl Error for ParseError {
impl Display for ParseError { impl Display for ParseError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result { fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self { match self {
Self::LexError(error) => write!(f, "{}", error), Self::LexError { error, .. } => write!(f, "{}", error),
Self::ExpectedClosingParenthesis { actual, .. } => { Self::ExpectedClosingParenthesis { actual, .. } => {
write!(f, "Expected closing parenthesis, found {actual}",) write!(f, "Expected closing parenthesis, found {actual}",)
} }
@ -389,17 +410,11 @@ impl Display for ParseError {
Self::ExpectedOpeningParenthesis { actual, .. } => { Self::ExpectedOpeningParenthesis { actual, .. } => {
write!(f, "Expected opening parenthesis, found {actual}",) write!(f, "Expected opening parenthesis, found {actual}",)
} }
Self::UnexpectedToken(actual) => write!(f, "Unexpected token {actual}"), Self::UnexpectedToken { actual, .. } => write!(f, "Unexpected token {actual}"),
} }
} }
} }
impl From<LexError> for ParseError {
fn from(v: LexError) -> Self {
Self::LexError(v)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::Identifier; use crate::Identifier;

View File

@ -131,6 +131,9 @@ impl Value {
(ValueInner::Integer(left), ValueInner::Integer(right)) => { (ValueInner::Integer(left), ValueInner::Integer(right)) => {
Ok(Value::integer(left.saturating_add(*right))) Ok(Value::integer(left.saturating_add(*right)))
} }
(ValueInner::String(left), ValueInner::String(right)) => {
Ok(Value::string(left.to_string() + right))
}
_ => Err(ValueError::CannotAdd(self.clone(), other.clone())), _ => Err(ValueError::CannotAdd(self.clone(), other.clone())),
} }
} }

View File

@ -171,7 +171,16 @@ impl Vm {
Ok(function.clone().call(None, value_parameters, variables)?) Ok(function.clone().call(None, value_parameters, variables)?)
} }
Statement::Identifier(_) => Ok(None), Statement::Identifier(identifier) => {
if let Some(value) = variables.get(&identifier) {
Ok(Some(value.clone()))
} else {
Err(VmError::UndefinedIdentifier {
identifier,
position: node.position,
})
}
}
Statement::List(nodes) => { Statement::List(nodes) => {
let values = nodes let values = nodes
.into_iter() .into_iter()
@ -303,17 +312,37 @@ impl Vm {
pub enum VmError { pub enum VmError {
AnaylyzerError(AnalyzerError), AnaylyzerError(AnalyzerError),
ParseError(ParseError), ParseError(ParseError),
ValueError { error: ValueError, position: Span }, ValueError {
error: ValueError,
position: Span,
},
// 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), BuiltInFunctionCallError(BuiltInFunctionError),
ExpectedIdentifier { position: Span }, ExpectedIdentifier {
ExpectedIdentifierOrInteger { position: Span }, position: Span,
ExpectedInteger { position: Span }, },
ExpectedFunction { actual: Value, position: Span }, ExpectedIdentifierOrInteger {
ExpectedList { position: Span }, position: Span,
ExpectedValue { position: Span }, },
ExpectedInteger {
position: Span,
},
ExpectedFunction {
actual: Value,
position: Span,
},
ExpectedList {
position: Span,
},
ExpectedValue {
position: Span,
},
UndefinedIdentifier {
identifier: Identifier,
position: Span,
},
} }
impl From<BuiltInFunctionError> for VmError { impl From<BuiltInFunctionError> for VmError {
@ -383,6 +412,16 @@ impl Display for VmError {
Self::ExpectedValue { position } => { Self::ExpectedValue { position } => {
write!(f, "Expected a value at position: {:?}", position) write!(f, "Expected a value at position: {:?}", position)
} }
Self::UndefinedIdentifier {
identifier,
position,
} => {
write!(
f,
"Undefined identifier: {} at position: {:?}",
identifier, position
)
}
} }
} }
} }