Make error messages a bit more consistent

This commit is contained in:
Laurenz 2023-04-04 14:33:43 +02:00
parent 4aa5e0a4a3
commit e77abf842d
2 changed files with 32 additions and 31 deletions

View File

@ -99,28 +99,22 @@ pub fn pow(
bail!(span, "exponent is too large") bail!(span, "exponent is too large")
} }
Num::Float(f) if !f.is_normal() && f != 0.0 => { Num::Float(f) if !f.is_normal() && f != 0.0 => {
bail!(span, "exponent may not be NaN, infinite, or subnormal") bail!(span, "exponent may not be infinite, subnormal, or NaN")
} }
_ => {} _ => {}
}; };
let return_value = match (base, exp) { let result = match (base, exp) {
(Num::Int(a), Num::Int(b)) if b >= 0 => Value::Int(a.pow(b as u32)), (Num::Int(a), Num::Int(b)) if b >= 0 => Num::Int(a.pow(b as u32)),
(a, Num::Int(b)) => Value::Float(a.float().powi(b as i32)), (a, Num::Int(b)) => Num::Float(a.float().powi(b as i32)),
(a, b) => Value::Float(a.float().powf(b.float())), (a, b) => Num::Float(a.float().powf(b.float())),
}; };
let is_nan = match return_value { if result.float().is_nan() {
Value::Float(f) => f.is_nan(), bail!(span, "the result is not a real number")
Value::Int(i) => (i as f64).is_nan(),
_ => false,
};
if is_nan {
bail!(span, "the return value is not a real number")
} }
return_value result.value()
} }
/// Calculate the square root of a number. /// Calculate the square root of a number.
@ -243,7 +237,7 @@ pub fn asin(
) -> Value { ) -> Value {
let val = value.v.float(); let val = value.v.float();
if val < -1.0 || val > 1.0 { if val < -1.0 || val > 1.0 {
bail!(value.span, "arcsin must be between -1 and 1"); bail!(value.span, "value must be between -1 and 1");
} }
Value::Angle(Angle::rad(val.asin())) Value::Angle(Angle::rad(val.asin()))
} }
@ -266,7 +260,7 @@ pub fn acos(
) -> Value { ) -> Value {
let val = value.v.float(); let val = value.v.float();
if val < -1.0 || val > 1.0 { if val < -1.0 || val > 1.0 {
bail!(value.span, "arccos must be between -1 and 1"); bail!(value.span, "value must be between -1 and 1");
} }
Value::Angle(Angle::rad(val.acos())) Value::Angle(Angle::rad(val.acos()))
} }
@ -379,23 +373,23 @@ pub fn tanh(
/// Returns: float /// Returns: float
#[func] #[func]
pub fn log( pub fn log(
/// The number whose logarithm to calculate. It must be strictly positive. /// The number whose logarithm to calculate. Must be strictly positive.
value: Spanned<Num>, value: Spanned<Num>,
/// The base of the logarithm. It can't be null. /// The base of the logarithm. Defaults to `{10}` and may not be zero.
#[named] #[named]
#[default(10.0)] #[default(10.0)]
base: f64, base: f64,
) -> Value { ) -> Value {
let number = value.v.float(); let number = value.v.float();
if number <= 0.0 {
if number <= 0 as f64 { bail!(value.span, "value must be strictly positive")
bail!(value.span, "a logarithm parameter must be strictly positive")
} }
if !base.is_normal() { if !base.is_normal() {
bail!(value.span, "a logarithm base should be normal (not NaN, not infinite, non-null, not subnormal)") bail!(value.span, "base may not be zero, NaN, infinite, or subnormal")
} }
let return_value = if base == 2.0 { let result = if base == 2.0 {
number.log2() number.log2()
} else if base == 10.0 { } else if base == 10.0 {
number.log10() number.log10()
@ -403,11 +397,11 @@ pub fn log(
number.log(base) number.log(base)
}; };
if return_value.is_infinite() || return_value.is_nan() { if result.is_infinite() || result.is_nan() {
bail!(value.span, "this logarithm doesn't return a real value") bail!(value.span, "the result is not a real number")
} }
Value::Float(return_value) Value::Float(result)
} }
/// Round a number down to the nearest integer. /// Round a number down to the nearest integer.
@ -695,6 +689,13 @@ impl Num {
Self::Float(v) => v, Self::Float(v) => v,
} }
} }
fn value(self) -> Value {
match self {
Self::Int(v) => Value::Int(v),
Self::Float(v) => Value::Float(v),
}
}
} }
cast_from_value! { cast_from_value! {

View File

@ -90,11 +90,11 @@
#calc.pow(2, 10000000000000000) #calc.pow(2, 10000000000000000)
--- ---
// Error: 14-36 exponent may not be NaN, infinite, or subnormal // Error: 14-36 exponent may not be infinite, subnormal, or NaN
#calc.pow(2, calc.pow(2.0, 10000.0)) #calc.pow(2, calc.pow(2.0, 10000.0))
--- ---
// Error: 15-18 the return value is not a real number // Error: 15-18 the result is not a real number
#calc.pow(-1, 0.5) #calc.pow(-1, 0.5)
--- ---
@ -102,15 +102,15 @@
#calc.sqrt(-1) #calc.sqrt(-1)
--- ---
// Error: 11-13 a logarithm parameter must be strictly positive // Error: 11-13 value must be strictly positive
#calc.log(-1) #calc.log(-1)
--- ---
// Error: 11-12 a logarithm base should be normal (not NaN, not infinite, non-null, not subnormal) // Error: 11-12 base may not be zero, NaN, infinite, or subnormal
#calc.log(1, base: 0) #calc.log(1, base: 0)
--- ---
// Error: 11-13 this logarithm doesn't return a real value // Error: 11-13 the result is not a real number
#calc.log(10, base: -1) #calc.log(10, base: -1)
--- ---