diff --git a/RELEASES.md b/RELEASES.md index 89d2fd3b..9e80f364 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -32,6 +32,8 @@ Enhancements ------------ * Functions resolution cache is used in more cases, making repeated function calls faster. +* Added `atan(x, y)` and `hypot(x, y)` to `BasicMathPackage`. +* Added standard arithmetic operators between `FLOAT` and `INT`. Version 0.19.11 diff --git a/src/fn_call.rs b/src/fn_call.rs index bb928bb0..31c726de 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -1325,8 +1325,6 @@ pub fn run_builtin_binary_op( x: &Dynamic, y: &Dynamic, ) -> Result, Box> { - use crate::packages::arithmetic::arith_basic::INT::functions::*; - let args_type = x.type_id(); let second_type = y.type_id(); @@ -1358,6 +1356,8 @@ pub fn run_builtin_binary_op( let y = y.clone().cast::(); if cfg!(not(feature = "unchecked")) { + use crate::packages::arithmetic::arith_basic::INT::functions::*; + match op { "+" => return add(x, y).map(Some), "-" => return subtract(x, y).map(Some), @@ -1465,6 +1465,44 @@ pub fn run_builtin_binary_op( } } + #[cfg(feature = "decimal")] + if args_type == TypeId::of::() { + let x = x.clone().cast::(); + let y = y.clone().cast::(); + + if cfg!(not(feature = "unchecked")) { + use crate::packages::arithmetic::decimal_functions::*; + + match op { + "+" => return add(x, y).map(Some), + "-" => return subtract(x, y).map(Some), + "*" => return multiply(x, y).map(Some), + "/" => return divide(x, y).map(Some), + "%" => return modulo(x, y).map(Some), + _ => (), + } + } else { + match op { + "+" => return Ok(Some((x + y).into())), + "-" => return Ok(Some((x - y).into())), + "*" => return Ok(Some((x * y).into())), + "/" => return Ok(Some((x / y).into())), + "%" => return Ok(Some((x % y).into())), + _ => (), + } + } + + match op { + "==" => return Ok(Some((x == y).into())), + "!=" => return Ok(Some((x != y).into())), + ">" => return Ok(Some((x > y).into())), + ">=" => return Ok(Some((x >= y).into())), + "<" => return Ok(Some((x < y).into())), + "<=" => return Ok(Some((x <= y).into())), + _ => (), + } + } + Ok(None) } @@ -1474,8 +1512,6 @@ pub fn run_builtin_op_assignment( x: &mut Dynamic, y: &Dynamic, ) -> Result, Box> { - use crate::packages::arithmetic::arith_basic::INT::functions::*; - let args_type = x.type_id(); let second_type = y.type_id(); @@ -1498,13 +1534,15 @@ pub fn run_builtin_op_assignment( let mut x = x.write_lock::().unwrap(); if cfg!(not(feature = "unchecked")) { + use crate::packages::arithmetic::arith_basic::INT::functions::*; + match op { "+=" => return Ok(Some(*x = add(*x, y)?.as_int().unwrap())), "-=" => return Ok(Some(*x = subtract(*x, y)?.as_int().unwrap())), "*=" => return Ok(Some(*x = multiply(*x, y)?.as_int().unwrap())), "/=" => return Ok(Some(*x = divide(*x, y)?.as_int().unwrap())), "%=" => return Ok(Some(*x = modulo(*x, y)?.as_int().unwrap())), - "~=" => return Ok(Some(*x = power(*x, y)?.as_int().unwrap())), + "**=" => return Ok(Some(*x = power(*x, y)?.as_int().unwrap())), ">>=" => return Ok(Some(*x = shift_right(*x, y)?.as_int().unwrap())), "<<=" => return Ok(Some(*x = shift_left(*x, y)?.as_int().unwrap())), _ => (), @@ -1516,7 +1554,7 @@ pub fn run_builtin_op_assignment( "*=" => return Ok(Some(*x *= y)), "/=" => return Ok(Some(*x /= y)), "%=" => return Ok(Some(*x %= y)), - "~=" => return Ok(Some(*x = x.pow(y as u32))), + "**=" => return Ok(Some(*x = x.pow(y as u32))), ">>=" => return Ok(Some(*x = *x >> y)), "<<=" => return Ok(Some(*x = *x << y)), _ => (), @@ -1567,10 +1605,38 @@ pub fn run_builtin_op_assignment( "*=" => return Ok(Some(*x *= y)), "/=" => return Ok(Some(*x /= y)), "%=" => return Ok(Some(*x %= y)), - "~=" => return Ok(Some(*x = x.powf(y))), + "**=" => return Ok(Some(*x = x.powf(y))), _ => (), } } + #[cfg(feature = "decimal")] + if args_type == TypeId::of::() { + let y = y.clone().cast::(); + let mut x = x.write_lock::().unwrap(); + + if cfg!(not(feature = "unchecked")) { + use crate::packages::arithmetic::decimal_functions::*; + + match op { + "+=" => return Ok(Some(*x = add(*x, y)?.as_decimal().unwrap())), + "-=" => return Ok(Some(*x = subtract(*x, y)?.as_decimal().unwrap())), + "*=" => return Ok(Some(*x = multiply(*x, y)?.as_decimal().unwrap())), + "/=" => return Ok(Some(*x = divide(*x, y)?.as_decimal().unwrap())), + "%=" => return Ok(Some(*x = modulo(*x, y)?.as_decimal().unwrap())), + _ => (), + } + } else { + match op { + "+=" => return Ok(Some(*x += y)), + "-=" => return Ok(Some(*x -= y)), + "*=" => return Ok(Some(*x *= y)), + "/=" => return Ok(Some(*x /= y)), + "%=" => return Ok(Some(*x %= y)), + _ => (), + } + } + } + Ok(None) } diff --git a/src/packages/arithmetic.rs b/src/packages/arithmetic.rs index bfca6937..c86c61cc 100644 --- a/src/packages/arithmetic.rs +++ b/src/packages/arithmetic.rs @@ -250,11 +250,53 @@ mod f32_functions { pub fn modulo(x: f32, y: f32) -> f32 { x % y } - #[rhai_fn(name = "**", return_raw)] - pub fn pow_f_f(x: f32, y: f32) -> Result> { - Ok(Dynamic::from(x.powf(y))) + #[rhai_fn(name = "**")] + pub fn pow_f_f(x: f32, y: f32) -> f32 { + x.powf(y) } } + + #[rhai_fn(name = "+")] + pub fn add_if(x: INT, y: f32) -> f32 { + (x as f32) + (y as f32) + } + #[rhai_fn(name = "+")] + pub fn add_fi(x: f32, y: INT) -> f32 { + (x as f32) + (y as f32) + } + #[rhai_fn(name = "-")] + pub fn subtract_if(x: INT, y: f32) -> f32 { + (x as f32) - (y as f32) + } + #[rhai_fn(name = "-")] + pub fn subtract_fi(x: f32, y: INT) -> f32 { + (x as f32) - (y as f32) + } + #[rhai_fn(name = "*")] + pub fn multiply_if(x: INT, y: f32) -> f32 { + (x as f32) * (y as f32) + } + #[rhai_fn(name = "*")] + pub fn multiply_fi(x: f32, y: INT) -> f32 { + (x as f32) * (y as f32) + } + #[rhai_fn(name = "/")] + pub fn divide_if(x: INT, y: f32) -> f32 { + (x as f32) / (y as f32) + } + #[rhai_fn(name = "/")] + pub fn divide_fi(x: f32, y: INT) -> f32 { + (x as f32) / (y as f32) + } + #[rhai_fn(name = "%")] + pub fn modulo_if(x: INT, y: f32) -> f32 { + (x as f32) % (y as f32) + } + #[rhai_fn(name = "%")] + pub fn modulo_fi(x: f32, y: INT) -> f32 { + (x as f32) % (y as f32) + } + #[rhai_fn(name = "-")] pub fn neg(x: f32) -> f32 { -x @@ -313,11 +355,53 @@ mod f64_functions { pub fn modulo(x: f64, y: f64) -> f64 { x % y } - #[rhai_fn(name = "**", return_raw)] - pub fn pow_f_f(x: f64, y: f64) -> Result> { - Ok(Dynamic::from(x.powf(y))) + #[rhai_fn(name = "**")] + pub fn pow_f_f(x: f64, y: f64) -> f64 { + x.powf(y) } } + + #[rhai_fn(name = "+")] + pub fn add_if(x: INT, y: f64) -> f64 { + (x as f64) + (y as f64) + } + #[rhai_fn(name = "+")] + pub fn add_fi(x: f64, y: INT) -> f64 { + (x as f64) + (y as f64) + } + #[rhai_fn(name = "-")] + pub fn subtract_if(x: INT, y: f64) -> f64 { + (x as f64) - (y as f64) + } + #[rhai_fn(name = "-")] + pub fn subtract_fi(x: f64, y: INT) -> f64 { + (x as f64) - (y as f64) + } + #[rhai_fn(name = "*")] + pub fn multiply_if(x: INT, y: f64) -> f64 { + (x as f64) * (y as f64) + } + #[rhai_fn(name = "*")] + pub fn multiply_fi(x: f64, y: INT) -> f64 { + (x as f64) * (y as f64) + } + #[rhai_fn(name = "/")] + pub fn divide_if(x: INT, y: f64) -> f64 { + (x as f64) / (y as f64) + } + #[rhai_fn(name = "/")] + pub fn divide_fi(x: f64, y: INT) -> f64 { + (x as f64) / (y as f64) + } + #[rhai_fn(name = "%")] + pub fn modulo_if(x: INT, y: f64) -> f64 { + (x as f64) % (y as f64) + } + #[rhai_fn(name = "%")] + pub fn modulo_fi(x: f64, y: INT) -> f64 { + (x as f64) % (y as f64) + } + #[rhai_fn(name = "-")] pub fn neg(x: f64) -> f64 { -x @@ -357,7 +441,7 @@ mod decimal_functions { use rust_decimal::{prelude::Zero, Decimal}; #[rhai_fn(name = "+", return_raw)] - pub fn add_dd(x: Decimal, y: Decimal) -> Result> { + pub fn add(x: Decimal, y: Decimal) -> Result> { if cfg!(not(feature = "unchecked")) { x.checked_add(y) .ok_or_else(|| make_err(format!("Addition overflow: {} + {}", x, y))) @@ -368,14 +452,14 @@ mod decimal_functions { } #[rhai_fn(name = "+", return_raw)] pub fn add_id(x: INT, y: Decimal) -> Result> { - add_dd(x.into(), y) + add(x.into(), y) } #[rhai_fn(name = "+", return_raw)] pub fn add_di(x: Decimal, y: INT) -> Result> { - add_dd(x, y.into()) + add(x, y.into()) } #[rhai_fn(name = "-", return_raw)] - pub fn subtract_dd(x: Decimal, y: Decimal) -> Result> { + pub fn subtract(x: Decimal, y: Decimal) -> Result> { if cfg!(not(feature = "unchecked")) { x.checked_sub(y) .ok_or_else(|| make_err(format!("Subtraction overflow: {} - {}", x, y))) @@ -386,14 +470,14 @@ mod decimal_functions { } #[rhai_fn(name = "-", return_raw)] pub fn subtract_id(x: INT, y: Decimal) -> Result> { - subtract_dd(x.into(), y) + subtract(x.into(), y) } #[rhai_fn(name = "-", return_raw)] pub fn subtract_di(x: Decimal, y: INT) -> Result> { - subtract_dd(x, y.into()) + subtract(x, y.into()) } #[rhai_fn(name = "*", return_raw)] - pub fn multiply_dd(x: Decimal, y: Decimal) -> Result> { + pub fn multiply(x: Decimal, y: Decimal) -> Result> { if cfg!(not(feature = "unchecked")) { x.checked_mul(y) .ok_or_else(|| make_err(format!("Multiplication overflow: {} * {}", x, y))) @@ -404,14 +488,14 @@ mod decimal_functions { } #[rhai_fn(name = "*", return_raw)] pub fn multiply_id(x: INT, y: Decimal) -> Result> { - multiply_dd(x.into(), y) + multiply(x.into(), y) } #[rhai_fn(name = "*", return_raw)] pub fn multiply_di(x: Decimal, y: INT) -> Result> { - multiply_dd(x, y.into()) + multiply(x, y.into()) } #[rhai_fn(name = "/", return_raw)] - pub fn divide_dd(x: Decimal, y: Decimal) -> Result> { + pub fn divide(x: Decimal, y: Decimal) -> Result> { if cfg!(not(feature = "unchecked")) { // Detect division by zero if y == Decimal::zero() { @@ -427,14 +511,14 @@ mod decimal_functions { } #[rhai_fn(name = "/", return_raw)] pub fn divide_id(x: INT, y: Decimal) -> Result> { - divide_dd(x.into(), y) + divide(x.into(), y) } #[rhai_fn(name = "/", return_raw)] pub fn divide_di(x: Decimal, y: INT) -> Result> { - divide_dd(x, y.into()) + divide(x, y.into()) } #[rhai_fn(name = "%", return_raw)] - pub fn modulo_dd(x: Decimal, y: Decimal) -> Result> { + pub fn modulo(x: Decimal, y: Decimal) -> Result> { if cfg!(not(feature = "unchecked")) { x.checked_rem(y) .ok_or_else(|| { @@ -450,11 +534,11 @@ mod decimal_functions { } #[rhai_fn(name = "%", return_raw)] pub fn modulo_id(x: INT, y: Decimal) -> Result> { - modulo_dd(x.into(), y) + modulo(x.into(), y) } #[rhai_fn(name = "%", return_raw)] pub fn modulo_di(x: Decimal, y: INT) -> Result> { - modulo_dd(x, y.into()) + modulo(x, y.into()) } #[rhai_fn(name = "-")] pub fn neg(x: Decimal) -> Decimal { diff --git a/src/packages/math_basic.rs b/src/packages/math_basic.rs index 661afd26..5b8bc8dd 100644 --- a/src/packages/math_basic.rs +++ b/src/packages/math_basic.rs @@ -170,6 +170,10 @@ mod trig_functions { pub fn atan(x: FLOAT) -> FLOAT { x.atan() } + #[rhai_fn(name = "atan")] + pub fn atan2(x: FLOAT, y: FLOAT) -> FLOAT { + x.atan2(y) + } pub fn asinh(x: FLOAT) -> FLOAT { x.asinh() } @@ -179,6 +183,9 @@ mod trig_functions { pub fn atanh(x: FLOAT) -> FLOAT { x.atanh() } + pub fn hypot(x: FLOAT, y: FLOAT) -> FLOAT { + x.hypot(y) + } } #[cfg(not(feature = "no_float"))]