Simplify error handling code.
This commit is contained in:
parent
ef9b90c3ef
commit
ee3781e86e
@ -15,6 +15,11 @@ use num_traits::float::Float;
|
|||||||
|
|
||||||
use crate::stdlib::format;
|
use crate::stdlib::format;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn make_err(msg: String) -> Box<EvalAltResult> {
|
||||||
|
EvalAltResult::ErrorArithmetic(msg, Position::none()).into()
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! gen_arithmetic_functions {
|
macro_rules! gen_arithmetic_functions {
|
||||||
($root:ident => $($arg_type:ident),+) => {
|
($root:ident => $($arg_type:ident),+) => {
|
||||||
pub mod $root { $(pub mod $arg_type {
|
pub mod $root { $(pub mod $arg_type {
|
||||||
@ -26,13 +31,7 @@ macro_rules! gen_arithmetic_functions {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn add(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
|
pub fn add(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
if cfg!(not(feature = "unchecked")) {
|
if cfg!(not(feature = "unchecked")) {
|
||||||
x.checked_add(y).ok_or_else(|| {
|
x.checked_add(y).ok_or_else(|| make_err(format!("Addition overflow: {} + {}", x, y))).map(Dynamic::from)
|
||||||
EvalAltResult::ErrorArithmetic(
|
|
||||||
format!("Addition overflow: {} + {}", x, y),
|
|
||||||
Position::none(),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}).map(Dynamic::from)
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Dynamic::from(x + y))
|
Ok(Dynamic::from(x + y))
|
||||||
}
|
}
|
||||||
@ -41,13 +40,7 @@ macro_rules! gen_arithmetic_functions {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn subtract(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
|
pub fn subtract(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
if cfg!(not(feature = "unchecked")) {
|
if cfg!(not(feature = "unchecked")) {
|
||||||
x.checked_sub(y).ok_or_else(|| {
|
x.checked_sub(y).ok_or_else(|| make_err(format!("Subtraction overflow: {} - {}", x, y))).map(Dynamic::from)
|
||||||
EvalAltResult::ErrorArithmetic(
|
|
||||||
format!("Subtraction overflow: {} - {}", x, y),
|
|
||||||
Position::none(),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}).map(Dynamic::from)
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Dynamic::from(x - y))
|
Ok(Dynamic::from(x - y))
|
||||||
}
|
}
|
||||||
@ -56,13 +49,7 @@ macro_rules! gen_arithmetic_functions {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn multiply(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
|
pub fn multiply(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
if cfg!(not(feature = "unchecked")) {
|
if cfg!(not(feature = "unchecked")) {
|
||||||
x.checked_mul(y).ok_or_else(|| {
|
x.checked_mul(y).ok_or_else(|| make_err(format!("Multiplication overflow: {} * {}", x, y))).map(Dynamic::from)
|
||||||
EvalAltResult::ErrorArithmetic(
|
|
||||||
format!("Multiplication overflow: {} * {}", x, y),
|
|
||||||
Position::none(),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}).map(Dynamic::from)
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Dynamic::from(x * y))
|
Ok(Dynamic::from(x * y))
|
||||||
}
|
}
|
||||||
@ -73,19 +60,9 @@ macro_rules! gen_arithmetic_functions {
|
|||||||
if cfg!(not(feature = "unchecked")) {
|
if cfg!(not(feature = "unchecked")) {
|
||||||
// Detect division by zero
|
// Detect division by zero
|
||||||
if y == 0 {
|
if y == 0 {
|
||||||
EvalAltResult::ErrorArithmetic(
|
Err(make_err(format!("Division by zero: {} / {}", x, y)))
|
||||||
format!("Division by zero: {} / {}", x, y),
|
|
||||||
Position::none(),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
} else {
|
} else {
|
||||||
x.checked_div(y).ok_or_else(|| {
|
x.checked_div(y).ok_or_else(|| make_err(format!("Division overflow: {} / {}", x, y))).map(Dynamic::from)
|
||||||
EvalAltResult::ErrorArithmetic(
|
|
||||||
format!("Division overflow: {} / {}", x, y),
|
|
||||||
Position::none(),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}).map(Dynamic::from)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(Dynamic::from(x / y))
|
Ok(Dynamic::from(x / y))
|
||||||
@ -95,13 +72,7 @@ macro_rules! gen_arithmetic_functions {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn modulo(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
|
pub fn modulo(x: $arg_type, y: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
if cfg!(not(feature = "unchecked")) {
|
if cfg!(not(feature = "unchecked")) {
|
||||||
x.checked_rem(y).ok_or_else(|| {
|
x.checked_rem(y).ok_or_else(|| make_err(format!("Modulo division by zero or overflow: {} % {}", x, y))).map(Dynamic::from)
|
||||||
EvalAltResult::ErrorArithmetic(
|
|
||||||
format!("Modulo division by zero or overflow: {} % {}", x, y),
|
|
||||||
Position::none(),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}).map(Dynamic::from)
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Dynamic::from(x % y))
|
Ok(Dynamic::from(x % y))
|
||||||
}
|
}
|
||||||
@ -111,25 +82,11 @@ macro_rules! gen_arithmetic_functions {
|
|||||||
pub fn power(x: INT, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
pub fn power(x: INT, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
if cfg!(not(feature = "unchecked")) {
|
if cfg!(not(feature = "unchecked")) {
|
||||||
if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) {
|
if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) {
|
||||||
EvalAltResult::ErrorArithmetic(
|
Err(make_err(format!("Integer raised to too large an index: {} ~ {}", x, y)))
|
||||||
format!("Integer raised to too large an index: {} ~ {}", x, y),
|
|
||||||
Position::none(),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
} else if y < 0 {
|
} else if y < 0 {
|
||||||
EvalAltResult::ErrorArithmetic(
|
Err(make_err(format!("Integer raised to a negative index: {} ~ {}", x, y)))
|
||||||
format!("Integer raised to a negative index: {} ~ {}", x, y),
|
|
||||||
Position::none(),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
} else {
|
} else {
|
||||||
x.checked_pow(y as u32).ok_or_else(|| {
|
x.checked_pow(y as u32).ok_or_else(|| make_err(format!("Power overflow: {} ~ {}", x, y))).map(Dynamic::from)
|
||||||
EvalAltResult::ErrorArithmetic(
|
|
||||||
format!("Power overflow: {} ~ {}", x, y),
|
|
||||||
Position::none(),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}).map(Dynamic::from)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(Dynamic::from(x.pow(y as u32)))
|
Ok(Dynamic::from(x.pow(y as u32)))
|
||||||
@ -141,25 +98,11 @@ macro_rules! gen_arithmetic_functions {
|
|||||||
pub fn shift_left(x: $arg_type, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
pub fn shift_left(x: $arg_type, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
if cfg!(not(feature = "unchecked")) {
|
if cfg!(not(feature = "unchecked")) {
|
||||||
if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) {
|
if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) {
|
||||||
EvalAltResult::ErrorArithmetic(
|
Err(make_err(format!("Left-shift by too many bits: {} << {}", x, y)))
|
||||||
format!("Left-shift by too many bits: {} << {}", x, y),
|
|
||||||
Position::none(),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
} else if y < 0 {
|
} else if y < 0 {
|
||||||
EvalAltResult::ErrorArithmetic(
|
Err(make_err(format!("Left-shift by a negative number: {} << {}", x, y)))
|
||||||
format!("Left-shift by a negative number: {} << {}", x, y),
|
|
||||||
Position::none(),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
} else {
|
} else {
|
||||||
x.checked_shl(y as u32).ok_or_else(|| {
|
x.checked_shl(y as u32).ok_or_else(|| make_err(format!("Left-shift by too many bits: {} << {}", x, y))).map(Dynamic::from)
|
||||||
EvalAltResult::ErrorArithmetic(
|
|
||||||
format!("Left-shift by too many bits: {} << {}", x, y),
|
|
||||||
Position::none(),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}).map(Dynamic::from)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(Dynamic::from(x << y))
|
Ok(Dynamic::from(x << y))
|
||||||
@ -170,25 +113,11 @@ macro_rules! gen_arithmetic_functions {
|
|||||||
pub fn shift_right(x: $arg_type, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
pub fn shift_right(x: $arg_type, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
if cfg!(not(feature = "unchecked")) {
|
if cfg!(not(feature = "unchecked")) {
|
||||||
if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) {
|
if cfg!(not(feature = "only_i32")) && y > (u32::MAX as INT) {
|
||||||
EvalAltResult::ErrorArithmetic(
|
Err(make_err(format!("Right-shift by too many bits: {} >> {}", x, y)))
|
||||||
format!("Right-shift by too many bits: {} >> {}", x, y),
|
|
||||||
Position::none(),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
} else if y < 0 {
|
} else if y < 0 {
|
||||||
EvalAltResult::ErrorArithmetic(
|
Err(make_err(format!("Right-shift by a negative number: {} >> {}", x, y)))
|
||||||
format!("Right-shift by a negative number: {} >> {}", x, y),
|
|
||||||
Position::none(),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
} else {
|
} else {
|
||||||
x.checked_shr(y as u32).ok_or_else(|| {
|
x.checked_shr(y as u32).ok_or_else(|| make_err(format!("Right-shift by too many bits: {} >> {}", x, y))).map(Dynamic::from)
|
||||||
EvalAltResult::ErrorArithmetic(
|
|
||||||
format!("Right-shift by too many bits: {} >> {}", x, y),
|
|
||||||
Position::none(),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}).map(Dynamic::from)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(Dynamic::from(x >> y))
|
Ok(Dynamic::from(x >> y))
|
||||||
@ -225,10 +154,7 @@ macro_rules! gen_signed_functions {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn neg(x: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
|
pub fn neg(x: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
if cfg!(not(feature = "unchecked")) {
|
if cfg!(not(feature = "unchecked")) {
|
||||||
x.checked_neg().ok_or_else(|| {
|
x.checked_neg().ok_or_else(|| make_err(format!("Negation overflow: -{}", x))).map(Dynamic::from)
|
||||||
EvalAltResult::ErrorArithmetic(format!("Negation overflow: -{}", x), Position::none())
|
|
||||||
.into()
|
|
||||||
}).map(Dynamic::from)
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Dynamic::from(-x))
|
Ok(Dynamic::from(-x))
|
||||||
}
|
}
|
||||||
@ -237,10 +163,7 @@ macro_rules! gen_signed_functions {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn abs(x: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
|
pub fn abs(x: $arg_type) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
if cfg!(not(feature = "unchecked")) {
|
if cfg!(not(feature = "unchecked")) {
|
||||||
x.checked_abs().ok_or_else(|| {
|
x.checked_abs().ok_or_else(|| make_err(format!("Negation overflow: -{}", x))).map(Dynamic::from)
|
||||||
EvalAltResult::ErrorArithmetic(format!("Negation overflow: -{}", x), Position::none())
|
|
||||||
.into()
|
|
||||||
}).map(Dynamic::from)
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Dynamic::from(x.abs()))
|
Ok(Dynamic::from(x.abs()))
|
||||||
}
|
}
|
||||||
@ -368,11 +291,10 @@ mod f32_functions {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn pow_f_i(x: f32, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
pub fn pow_f_i(x: f32, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
if cfg!(not(feature = "unchecked")) && y > (i32::MAX as INT) {
|
if cfg!(not(feature = "unchecked")) && y > (i32::MAX as INT) {
|
||||||
EvalAltResult::ErrorArithmetic(
|
Err(make_err(format!(
|
||||||
format!("Number raised to too large an index: {} ~ {}", x, y),
|
"Number raised to too large an index: {} ~ {}",
|
||||||
Position::none(),
|
x, y
|
||||||
)
|
)))
|
||||||
.into()
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Dynamic::from(x.powi(y as i32)))
|
Ok(Dynamic::from(x.powi(y as i32)))
|
||||||
}
|
}
|
||||||
@ -405,11 +327,10 @@ mod f64_functions {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn pow_f_i(x: FLOAT, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
pub fn pow_f_i(x: FLOAT, y: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
if cfg!(not(feature = "unchecked")) && y > (i32::MAX as INT) {
|
if cfg!(not(feature = "unchecked")) && y > (i32::MAX as INT) {
|
||||||
EvalAltResult::ErrorArithmetic(
|
Err(make_err(format!(
|
||||||
format!("Number raised to too large an index: {} ~ {}", x, y),
|
"Number raised to too large an index: {} ~ {}",
|
||||||
Position::none(),
|
x, y
|
||||||
)
|
)))
|
||||||
.into()
|
|
||||||
} else {
|
} else {
|
||||||
Ok(x.powi(y as i32).into())
|
Ok(x.powi(y as i32).into())
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
#![cfg(not(feature = "no_std"))]
|
#![cfg(not(feature = "no_std"))]
|
||||||
|
|
||||||
#[cfg(feature = "no_float")]
|
#[cfg(feature = "no_float")]
|
||||||
#[cfg(not(feature = "unchecked"))]
|
use super::{arithmetic::make_err, math_basic::MAX_INT};
|
||||||
use super::math_basic::MAX_INT;
|
|
||||||
|
|
||||||
use crate::def_package;
|
use crate::def_package;
|
||||||
use crate::plugin::*;
|
use crate::plugin::*;
|
||||||
@ -14,10 +13,6 @@ use crate::parser::FLOAT;
|
|||||||
#[cfg(feature = "no_float")]
|
#[cfg(feature = "no_float")]
|
||||||
use crate::parser::INT;
|
use crate::parser::INT;
|
||||||
|
|
||||||
#[cfg(feature = "no_float")]
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
|
||||||
use crate::token::Position;
|
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
use crate::stdlib::time::Instant;
|
use crate::stdlib::time::Instant;
|
||||||
|
|
||||||
@ -46,18 +41,16 @@ mod time_functions {
|
|||||||
{
|
{
|
||||||
let seconds = timestamp.elapsed().as_secs();
|
let seconds = timestamp.elapsed().as_secs();
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
if cfg!(not(feature = "unchecked")) && seconds > (MAX_INT as u64) {
|
||||||
if seconds > (MAX_INT as u64) {
|
Err(make_err(format!(
|
||||||
return EvalAltResult::ErrorArithmetic(
|
"Integer overflow for timestamp.elapsed: {}",
|
||||||
format!("Integer overflow for timestamp.elapsed: {}", seconds),
|
seconds
|
||||||
Position::none(),
|
)))
|
||||||
)
|
} else {
|
||||||
.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok((seconds as INT).into())
|
Ok((seconds as INT).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[rhai_fn(get = "elapsed", return_raw)]
|
#[rhai_fn(get = "elapsed", return_raw)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -81,31 +74,27 @@ mod time_functions {
|
|||||||
if ts2 > ts1 {
|
if ts2 > ts1 {
|
||||||
let seconds = (ts2 - ts1).as_secs();
|
let seconds = (ts2 - ts1).as_secs();
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
if cfg!(not(feature = "unchecked")) && seconds > (MAX_INT as u64) {
|
||||||
if seconds > (MAX_INT as u64) {
|
Err(make_err(format!(
|
||||||
return EvalAltResult::ErrorArithmetic(
|
"Integer overflow for timestamp duration: -{}",
|
||||||
format!("Integer overflow for timestamp duration: -{}", seconds),
|
seconds
|
||||||
Position::none(),
|
)))
|
||||||
)
|
} else {
|
||||||
.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Dynamic::from(-(seconds as INT)))
|
Ok(Dynamic::from(-(seconds as INT)))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let seconds = (ts1 - ts2).as_secs();
|
let seconds = (ts1 - ts2).as_secs();
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
if cfg!(not(feature = "unchecked")) && seconds > (MAX_INT as u64) {
|
||||||
if seconds > (MAX_INT as u64) {
|
Err(make_err(format!(
|
||||||
return EvalAltResult::ErrorArithmetic(
|
"Integer overflow for timestamp duration: {}",
|
||||||
format!("Integer overflow for timestamp duration: {}", seconds),
|
seconds
|
||||||
Position::none(),
|
)))
|
||||||
)
|
} else {
|
||||||
.into();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok((seconds as INT).into())
|
Ok((seconds as INT).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[rhai_fn(name = "==")]
|
#[rhai_fn(name = "==")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
Loading…
Reference in New Issue
Block a user