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)?;
|
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)
|
||||||
}
|
}
|
||||||
|
@ -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(
|
||||||
|
@ -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;
|
||||||
|
@ -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())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user