Refactor errors and clean up read_line
This commit is contained in:
parent
9766777a47
commit
c1b71ffccc
@ -92,7 +92,7 @@ impl BuiltInFunction {
|
||||
|
||||
stdin().read_line(&mut input)?;
|
||||
|
||||
Ok(Some(Value::string(input)))
|
||||
Ok(Some(Value::string(input.trim_end_matches('\n'))))
|
||||
} else {
|
||||
Err(BuiltInFunctionError::WrongNumberOfValueArguments)
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ impl<'src> DustError<'src> {
|
||||
AnalyzerError::ExpectedIntegerFloatOrString { position, .. } => position,
|
||||
AnalyzerError::UnexpectedIdentifier { position, .. } => position,
|
||||
},
|
||||
VmError::ParseError(_) => todo!(),
|
||||
VmError::ParseError(parse_error) => &parse_error.position(),
|
||||
VmError::ValueError { position, .. } => position,
|
||||
VmError::BuiltInFunctionCallError(_) => todo!(),
|
||||
VmError::ExpectedIdentifier { position } => position,
|
||||
@ -44,6 +44,7 @@ impl<'src> DustError<'src> {
|
||||
VmError::ExpectedFunction { position, .. } => position,
|
||||
VmError::ExpectedList { position } => position,
|
||||
VmError::ExpectedValue { position } => position,
|
||||
VmError::UndefinedIdentifier { position, .. } => position,
|
||||
};
|
||||
let label = self.vm_error.to_string();
|
||||
let message = Level::Error.title(title).snippet(
|
||||
|
@ -128,7 +128,13 @@ impl<'src> Parser<'src> {
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
@ -341,7 +347,10 @@ impl<'src> Parser<'src> {
|
||||
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)]
|
||||
pub enum ParseError {
|
||||
LexError(LexError),
|
||||
LexError { error: LexError, position: Span },
|
||||
|
||||
ExpectedClosingParenthesis { actual: TokenOwned, position: Span },
|
||||
ExpectedClosingSquareBrace { 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 {
|
||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
match self {
|
||||
Self::LexError(error) => Some(error),
|
||||
Self::LexError { error, .. } => Some(error),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -379,7 +400,7 @@ impl Error for ParseError {
|
||||
impl Display for ParseError {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Self::LexError(error) => write!(f, "{}", error),
|
||||
Self::LexError { error, .. } => write!(f, "{}", error),
|
||||
Self::ExpectedClosingParenthesis { actual, .. } => {
|
||||
write!(f, "Expected closing parenthesis, found {actual}",)
|
||||
}
|
||||
@ -389,17 +410,11 @@ impl Display for ParseError {
|
||||
Self::ExpectedOpeningParenthesis { 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)]
|
||||
mod tests {
|
||||
use crate::Identifier;
|
||||
|
@ -131,6 +131,9 @@ impl Value {
|
||||
(ValueInner::Integer(left), ValueInner::Integer(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())),
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +171,16 @@ impl Vm {
|
||||
|
||||
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) => {
|
||||
let values = nodes
|
||||
.into_iter()
|
||||
@ -303,17 +312,37 @@ impl Vm {
|
||||
pub enum VmError {
|
||||
AnaylyzerError(AnalyzerError),
|
||||
ParseError(ParseError),
|
||||
ValueError { error: ValueError, position: Span },
|
||||
ValueError {
|
||||
error: ValueError,
|
||||
position: Span,
|
||||
},
|
||||
|
||||
// Anaylsis Failures
|
||||
// These should be prevented by running the analyzer before the VM
|
||||
BuiltInFunctionCallError(BuiltInFunctionError),
|
||||
ExpectedIdentifier { position: Span },
|
||||
ExpectedIdentifierOrInteger { position: Span },
|
||||
ExpectedInteger { position: Span },
|
||||
ExpectedFunction { actual: Value, position: Span },
|
||||
ExpectedList { position: Span },
|
||||
ExpectedValue { position: Span },
|
||||
ExpectedIdentifier {
|
||||
position: Span,
|
||||
},
|
||||
ExpectedIdentifierOrInteger {
|
||||
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 {
|
||||
@ -383,6 +412,16 @@ impl Display for VmError {
|
||||
Self::ExpectedValue { position } => {
|
||||
write!(f, "Expected a value at position: {:?}", position)
|
||||
}
|
||||
Self::UndefinedIdentifier {
|
||||
identifier,
|
||||
position,
|
||||
} => {
|
||||
write!(
|
||||
f,
|
||||
"Undefined identifier: {} at position: {:?}",
|
||||
identifier, position
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user