From 909d48caed7fe87ead72967950a34374d8412cf7 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Mon, 15 Feb 2021 17:42:33 +0800 Subject: [PATCH] Provide short-cuts to Decimal calculations. --- src/fn_call.rs | 80 ++++++++++++++++++++++++++++++++++---- src/packages/arithmetic.rs | 30 +++++++------- 2 files changed, 88 insertions(+), 22 deletions(-) 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..60837813 100644 --- a/src/packages/arithmetic.rs +++ b/src/packages/arithmetic.rs @@ -357,7 +357,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 +368,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 +386,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 +404,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 +427,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 +450,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 {