Skip to content

Commit

Permalink
Merge pull request #569 from rben01/boxed-errors
Browse files Browse the repository at this point in the history
Boxed errors
  • Loading branch information
sharkdp authored Sep 24, 2024
2 parents 582860b + 1681261 commit 4361530
Show file tree
Hide file tree
Showing 13 changed files with 228 additions and 209 deletions.
4 changes: 2 additions & 2 deletions numbat-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ impl Cli {
Err(_) => Err(()),
};

let control_flow = match interpretation_result {
let control_flow = match interpretation_result.map_err(|b| *b) {
Ok((statements, interpreter_result)) => {
if interactive || pretty_print {
println!();
Expand Down Expand Up @@ -550,7 +550,7 @@ impl Cli {
ControlFlow::Continue(())
}
Err(NumbatError::ResolverError(e)) => {
self.print_diagnostic(e.clone());
self.print_diagnostic(e);
execution_mode.exit_status_in_case_of_error()
}
Err(NumbatError::NameResolutionError(
Expand Down
1 change: 1 addition & 0 deletions numbat-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ impl Numbat {
match self
.ctx
.interpret_with_settings(&mut settings, code, CodeSource::Text)
.map_err(|b| *b)
{
Ok((statements, result)) => {
// Pretty print
Expand Down
4 changes: 2 additions & 2 deletions numbat/src/interpreter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ impl InterpreterResult {
}
}

pub type Result<T> = std::result::Result<T, RuntimeError>;
pub type Result<T> = std::result::Result<T, Box<RuntimeError>>;

pub type PrintFunction = dyn FnMut(&Markup) + Send;

Expand Down Expand Up @@ -237,7 +237,7 @@ mod tests {
#[track_caller]
fn assert_runtime_error(input: &str, err_expected: RuntimeError) {
if let Err(err_actual) = get_interpreter_result(input) {
assert_eq!(err_actual, err_expected);
assert_eq!(*err_actual, err_expected);
} else {
panic!();
}
Expand Down
10 changes: 5 additions & 5 deletions numbat/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ pub enum NumbatError {
RuntimeError(RuntimeError),
}

type Result<T> = std::result::Result<T, NumbatError>;
type Result<T> = std::result::Result<T, Box<NumbatError>>;

#[derive(Clone)]
pub struct Context {
Expand Down Expand Up @@ -585,7 +585,7 @@ impl Context {
let result = self
.typechecker
.check(transformed_statements)
.map_err(NumbatError::TypeCheckError);
.map_err(|err| NumbatError::TypeCheckError(*err));

if result.is_err() {
// Reset the state of the prefix transformer to what we had before. This is necessary
Expand Down Expand Up @@ -771,9 +771,9 @@ impl Context {
let erc = ExchangeRatesCache::fetch();

if erc.is_none() {
return Err(NumbatError::RuntimeError(
return Err(Box::new(NumbatError::RuntimeError(
RuntimeError::CouldNotLoadExchangeRates,
));
)));
}
}

Expand Down Expand Up @@ -822,7 +822,7 @@ impl Context {
self.interpreter = interpreter_old;
}

let result = result.map_err(NumbatError::RuntimeError)?;
let result = result.map_err(|err| NumbatError::RuntimeError(*err))?;

Ok((typed_statements, result))
}
Expand Down
97 changes: 36 additions & 61 deletions numbat/src/typechecker/const_evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,21 @@ fn to_rational_exponent(exponent_f64: f64) -> Option<Exponent> {
/// support type checking of expressions like `(2 * meter)^(2*3 - 4)` where we
/// need to know not just the *type* but also the *value* of the exponent.
pub fn evaluate_const_expr(expr: &typed_ast::Expression) -> Result<Exponent> {
match expr {
let name = match expr {
typed_ast::Expression::Scalar(span, n, _type) => {
Ok(to_rational_exponent(n.to_f64())
return Ok(to_rational_exponent(n.to_f64())
.ok_or(TypeCheckError::NonRationalExponent(*span))?)
}
typed_ast::Expression::UnaryOperator(_, ast::UnaryOperator::Negate, ref expr, _) => {
Ok(-evaluate_const_expr(expr)?)
return Ok(-evaluate_const_expr(expr)?)
}
e @ typed_ast::Expression::UnaryOperator(_, ast::UnaryOperator::Factorial, _, _) => Err(
TypeCheckError::UnsupportedConstEvalExpression(e.full_span(), "factorial"),
),
e @ typed_ast::Expression::UnaryOperator(_, ast::UnaryOperator::LogicalNeg, _, _) => Err(
TypeCheckError::UnsupportedConstEvalExpression(e.full_span(), "logical"),
),
typed_ast::Expression::UnaryOperator(_, ast::UnaryOperator::Factorial, _, _) => "factorial",
typed_ast::Expression::UnaryOperator(_, ast::UnaryOperator::LogicalNeg, _, _) => "logical",

e @ typed_ast::Expression::BinaryOperator(_span_op, op, lhs_expr, rhs_expr, _) => {
let lhs = evaluate_const_expr(lhs_expr)?;
let rhs = evaluate_const_expr(rhs_expr)?;
match op {
return match op {
typed_ast::BinaryOperator::Add => Ok(lhs
.checked_add(&rhs)
.ok_or_else(|| TypeCheckError::OverflowInConstExpr(expr.full_span()))?),
Expand All @@ -42,8 +39,8 @@ pub fn evaluate_const_expr(expr: &typed_ast::Expression) -> Result<Exponent> {
.ok_or_else(|| TypeCheckError::OverflowInConstExpr(expr.full_span()))?),
typed_ast::BinaryOperator::Div => {
if rhs == Rational::zero() {
Err(TypeCheckError::DivisionByZeroInConstEvalExpression(
e.full_span(),
Err(Box::new(
TypeCheckError::DivisionByZeroInConstEvalExpression(e.full_span()),
))
} else {
Ok(lhs
Expand All @@ -61,69 +58,47 @@ pub fn evaluate_const_expr(expr: &typed_ast::Expression) -> Result<Exponent> {
)
.ok_or_else(|| TypeCheckError::OverflowInConstExpr(expr.full_span()))?)
} else {
Err(TypeCheckError::UnsupportedConstEvalExpression(
Err(Box::new(TypeCheckError::UnsupportedConstEvalExpression(
e.full_span(),
"exponentiation with non-integer exponent",
))
)))
}
}
typed_ast::BinaryOperator::ConvertTo => Err(
typed_ast::BinaryOperator::ConvertTo => Err(Box::new(
TypeCheckError::UnsupportedConstEvalExpression(e.full_span(), "conversion"),
),
)),
typed_ast::BinaryOperator::LessThan
| typed_ast::BinaryOperator::GreaterThan
| typed_ast::BinaryOperator::LessOrEqual
| typed_ast::BinaryOperator::GreaterOrEqual
| typed_ast::BinaryOperator::Equal
| typed_ast::BinaryOperator::NotEqual => Err(
| typed_ast::BinaryOperator::NotEqual => Err(Box::new(
TypeCheckError::UnsupportedConstEvalExpression(e.full_span(), "comparison"),
),
)),
typed_ast::BinaryOperator::LogicalAnd | typed_ast::BinaryOperator::LogicalOr => {
Err(TypeCheckError::UnsupportedConstEvalExpression(
Err(Box::new(TypeCheckError::UnsupportedConstEvalExpression(
e.full_span(),
"logical",
))
)))
}
}
};
}
e @ typed_ast::Expression::Identifier(..) => Err(
TypeCheckError::UnsupportedConstEvalExpression(e.full_span(), "variable"),
),
e @ typed_ast::Expression::UnitIdentifier(..) => Err(
TypeCheckError::UnsupportedConstEvalExpression(e.full_span(), "unit identifier"),
),
e @ typed_ast::Expression::FunctionCall(_, _, _, _, _) => Err(
TypeCheckError::UnsupportedConstEvalExpression(e.full_span(), "function call"),
),
e @ &typed_ast::Expression::CallableCall(_, _, _, _) => Err(
TypeCheckError::UnsupportedConstEvalExpression(e.full_span(), "function call"),
),
e @ typed_ast::Expression::Boolean(_, _) => Err(
TypeCheckError::UnsupportedConstEvalExpression(e.full_span(), "Boolean value"),
),
e @ typed_ast::Expression::String(_, _) => Err(
TypeCheckError::UnsupportedConstEvalExpression(e.full_span(), "String"),
),
e @ typed_ast::Expression::Condition(..) => Err(
TypeCheckError::UnsupportedConstEvalExpression(e.full_span(), "Conditional"),
),
e @ typed_ast::Expression::BinaryOperatorForDate(..) => {
Err(TypeCheckError::UnsupportedConstEvalExpression(
e.full_span(),
"binary operator for datetimes",
))
}
e @ typed_ast::Expression::InstantiateStruct(_, _, _) => Err(
TypeCheckError::UnsupportedConstEvalExpression(e.full_span(), "instantiate struct"),
),
e @ typed_ast::Expression::AccessField(_, _, _, _, _, _) => Err(
TypeCheckError::UnsupportedConstEvalExpression(e.full_span(), "access field of struct"),
),
e @ typed_ast::Expression::List(_, _, _) => Err(
TypeCheckError::UnsupportedConstEvalExpression(e.full_span(), "lists"),
),
e @ typed_ast::Expression::TypedHole(_, _) => Err(
TypeCheckError::UnsupportedConstEvalExpression(e.full_span(), "typed hole"),
),
}
typed_ast::Expression::Identifier(..) => "variable",
typed_ast::Expression::UnitIdentifier(..) => "unit identifier",
typed_ast::Expression::FunctionCall(_, _, _, _, _) => "function call",
typed_ast::Expression::CallableCall(_, _, _, _) => "function call",
typed_ast::Expression::Boolean(_, _) => "Boolean value",
typed_ast::Expression::String(_, _) => "String",
typed_ast::Expression::Condition(..) => "Conditional",
typed_ast::Expression::BinaryOperatorForDate(..) => "binary operator for datetimes",
typed_ast::Expression::InstantiateStruct(_, _, _) => "instantiate struct",
typed_ast::Expression::AccessField(_, _, _, _, _, _) => "access field of struct",
typed_ast::Expression::List(_, _, _) => "lists",
typed_ast::Expression::TypedHole(_, _) => "typed hole",
};

Err(Box::new(TypeCheckError::UnsupportedConstEvalExpression(
expr.full_span(),
name,
)))
}
2 changes: 1 addition & 1 deletion numbat/src/typechecker/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,4 @@ pub enum TypeCheckError {
MultipleTypedHoles(Span),
}

pub type Result<T> = std::result::Result<T, TypeCheckError>;
pub type Result<T> = std::result::Result<T, Box<TypeCheckError>>;
Loading

0 comments on commit 4361530

Please sign in to comment.