Fix decimal build.
This commit is contained in:
parent
c82a47ac26
commit
41d3709db1
@ -5,24 +5,20 @@ use std::ops::Range;
|
|||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
use num_traits::{CheckedAdd as Add, CheckedSub as Sub};
|
use num_traits::{CheckedAdd, CheckedSub};
|
||||||
|
|
||||||
#[cfg(feature = "unchecked")]
|
#[cfg(feature = "unchecked")]
|
||||||
use std::ops::{Add, Sub};
|
use std::ops::{Add, Sub};
|
||||||
|
|
||||||
fn get_range<T: Variant + Clone>(from: T, to: T) -> Result<Range<T>, Box<EvalAltResult>> {
|
|
||||||
Ok(from..to)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register range function with step
|
// Register range function with step
|
||||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
|
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
|
||||||
struct StepRange<T>(T, T, T)
|
struct StepRange<T>(T, T, T)
|
||||||
where
|
where
|
||||||
T: Variant + Copy + PartialOrd + Add<Output = T> + Sub<Output = T>;
|
T: Variant + Copy + PartialOrd + CheckedAdd<Output = T> + CheckedSub<Output = T>;
|
||||||
|
|
||||||
impl<T> StepRange<T>
|
impl<T> StepRange<T>
|
||||||
where
|
where
|
||||||
T: Variant + Copy + PartialOrd + Add<Output = T> + Sub<Output = T>,
|
T: Variant + Copy + PartialOrd + CheckedAdd<Output = T> + CheckedSub<Output = T>,
|
||||||
{
|
{
|
||||||
pub fn new(from: T, to: T, step: T) -> Result<Self, Box<EvalAltResult>> {
|
pub fn new(from: T, to: T, step: T) -> Result<Self, Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
@ -47,7 +43,7 @@ where
|
|||||||
|
|
||||||
impl<T> Iterator for StepRange<T>
|
impl<T> Iterator for StepRange<T>
|
||||||
where
|
where
|
||||||
T: Variant + Copy + PartialOrd + Add<Output = T> + Sub<Output = T>,
|
T: Variant + Copy + PartialOrd + CheckedAdd<Output = T> + CheckedSub<Output = T>,
|
||||||
{
|
{
|
||||||
type Item = T;
|
type Item = T;
|
||||||
|
|
||||||
@ -130,18 +126,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_step_range<T>(from: T, to: T, step: T) -> Result<StepRange<T>, Box<EvalAltResult>>
|
|
||||||
where
|
|
||||||
T: Variant + Copy + PartialOrd + Add<Output = T> + Sub<Output = T>,
|
|
||||||
{
|
|
||||||
StepRange::<T>::new(from, to, step)
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! reg_range {
|
macro_rules! reg_range {
|
||||||
($lib:ident | $x:expr => $( $y:ty ),*) => {
|
($lib:ident | $x:expr => $( $y:ty ),*) => {
|
||||||
$(
|
$(
|
||||||
$lib.set_iterator::<Range<$y>>();
|
$lib.set_iterator::<Range<$y>>();
|
||||||
let _hash = $lib.set_native_fn($x, get_range::<$y>);
|
let _hash = $lib.set_native_fn($x, |from: $y, to: $y| Ok(from..to));
|
||||||
|
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
$lib.update_fn_metadata(_hash, &[
|
$lib.update_fn_metadata(_hash, &[
|
||||||
@ -154,7 +143,7 @@ macro_rules! reg_range {
|
|||||||
($lib:ident | step $x:expr => $( $y:ty ),*) => {
|
($lib:ident | step $x:expr => $( $y:ty ),*) => {
|
||||||
$(
|
$(
|
||||||
$lib.set_iterator::<StepRange<$y>>();
|
$lib.set_iterator::<StepRange<$y>>();
|
||||||
let _hash = $lib.set_native_fn($x, get_step_range::<$y>);
|
let _hash = $lib.set_native_fn($x, |from: $y, to: $y, step: $y| StepRange::new(from, to, step));
|
||||||
|
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
$lib.update_fn_metadata(_hash, &[
|
$lib.update_fn_metadata(_hash, &[
|
||||||
@ -192,12 +181,72 @@ def_package!(crate:BasicIteratorPackage:"Basic range iterators.", lib, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
{
|
||||||
|
use crate::FLOAT;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
struct StepFloatRange(FLOAT, FLOAT, FLOAT);
|
||||||
|
|
||||||
|
impl StepFloatRange {
|
||||||
|
pub fn new(from: FLOAT, to: FLOAT, step: FLOAT) -> Result<Self, Box<EvalAltResult>> {
|
||||||
|
#[cfg(not(feature = "unchecked"))]
|
||||||
|
if step == 0.0 {
|
||||||
|
return EvalAltResult::ErrorInFunctionCall("range".to_string(), "".to_string(),
|
||||||
|
Box::new(EvalAltResult::ErrorArithmetic("step value cannot be zero".to_string(), crate::Position::NONE)),
|
||||||
|
crate::Position::NONE,
|
||||||
|
).into();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self(from, to, step))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for StepFloatRange {
|
||||||
|
type Item = FLOAT;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<FLOAT> {
|
||||||
|
if self.0 == self.1 {
|
||||||
|
None
|
||||||
|
} else if self.0 < self.1 {
|
||||||
|
#[cfg(not(feature = "unchecked"))]
|
||||||
|
if self.2 < 0.0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let v = self.0;
|
||||||
|
let n = self.0 + self.2;
|
||||||
|
|
||||||
|
self.0 = if n >= self.1 { self.1 } else { n };
|
||||||
|
Some(v)
|
||||||
|
} else {
|
||||||
|
#[cfg(not(feature = "unchecked"))]
|
||||||
|
if self.2 > 0.0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let v = self.0;
|
||||||
|
let n = self.0 + self.2;
|
||||||
|
|
||||||
|
self.0 = if n <= self.1 { self.1 } else { n };
|
||||||
|
Some(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::iter::FusedIterator for StepFloatRange {}
|
||||||
|
|
||||||
|
lib.set_iterator::<StepFloatRange>();
|
||||||
|
|
||||||
|
let _hash = lib.set_native_fn("range", |from, to, step| StepFloatRange::new(from, to, step));
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
lib.update_fn_metadata(_hash, &["from: FLOAT", "to: FLOAT", "step: FLOAT", "Iterator<Item=FLOAT>"]);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "decimal")]
|
#[cfg(feature = "decimal")]
|
||||||
{
|
{
|
||||||
use rust_decimal::{
|
use rust_decimal::Decimal;
|
||||||
prelude::{One, Zero},
|
use num_traits::Zero;
|
||||||
Decimal,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
|
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
|
||||||
struct StepDecimalRange(Decimal, Decimal, Decimal);
|
struct StepDecimalRange(Decimal, Decimal, Decimal);
|
||||||
@ -252,10 +301,6 @@ def_package!(crate:BasicIteratorPackage:"Basic range iterators.", lib, {
|
|||||||
|
|
||||||
lib.set_iterator::<StepDecimalRange>();
|
lib.set_iterator::<StepDecimalRange>();
|
||||||
|
|
||||||
let _hash = lib.set_native_fn("range", |from, to| StepDecimalRange::new(from, to, Decimal::one()));
|
|
||||||
#[cfg(feature = "metadata")]
|
|
||||||
lib.update_fn_metadata(_hash, &["from: Decimal", "to: Decimal", "Iterator<Item=Decimal>"]);
|
|
||||||
|
|
||||||
let _hash = lib.set_native_fn("range", |from, to, step| StepDecimalRange::new(from, to, step));
|
let _hash = lib.set_native_fn("range", |from, to, step| StepDecimalRange::new(from, to, step));
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
lib.update_fn_metadata(_hash, &["from: Decimal", "to: Decimal", "step: Decimal", "Iterator<Item=Decimal>"]);
|
lib.update_fn_metadata(_hash, &["from: Decimal", "to: Decimal", "step: Decimal", "Iterator<Item=Decimal>"]);
|
||||||
|
150
tests/for.rs
150
tests/for.rs
@ -1,31 +1,52 @@
|
|||||||
use rhai::{Engine, EvalAltResult, Module, INT};
|
use rhai::{Engine, EvalAltResult, Module, INT};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
use rhai::FLOAT;
|
||||||
|
|
||||||
|
#[cfg(feature = "decimal")]
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
use rust_decimal::Decimal;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_for() -> Result<(), Box<EvalAltResult>> {
|
fn test_for() -> Result<(), Box<EvalAltResult>> {
|
||||||
let engine = Engine::new();
|
let engine = Engine::new();
|
||||||
|
|
||||||
let script = "
|
#[cfg(not(feature = "no_index"))]
|
||||||
let sum1 = 0;
|
assert_eq!(
|
||||||
let sum2 = 0;
|
engine.eval::<INT>(
|
||||||
let inputs = [1, 2, 3, 4, 5];
|
"
|
||||||
|
let sum1 = 0;
|
||||||
|
let sum2 = 0;
|
||||||
|
let inputs = [1, 2, 3, 4, 5];
|
||||||
|
|
||||||
for x in inputs {
|
for x in inputs {
|
||||||
sum1 += x;
|
sum1 += x;
|
||||||
}
|
}
|
||||||
|
|
||||||
for x in range(1, 6) {
|
for x in range(1, 6) {
|
||||||
sum2 += x;
|
sum2 += x;
|
||||||
}
|
}
|
||||||
|
|
||||||
for x in range(1, 6, 3) {
|
for x in range(1, 6, 3) {
|
||||||
sum2 += x;
|
sum2 += x;
|
||||||
}
|
}
|
||||||
|
|
||||||
sum1 + sum2
|
sum1 + sum2
|
||||||
";
|
"
|
||||||
|
)?,
|
||||||
|
35
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(engine.eval::<INT>(script)?, 35);
|
assert_eq!(
|
||||||
|
engine.eval::<INT>(
|
||||||
|
"
|
||||||
|
let sum = 0;
|
||||||
|
for x in range(1, 10) { sum += x; }
|
||||||
|
sum
|
||||||
|
"
|
||||||
|
)?,
|
||||||
|
45
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
engine.eval::<INT>(
|
engine.eval::<INT>(
|
||||||
@ -71,6 +92,101 @@ fn test_for() -> Result<(), Box<EvalAltResult>> {
|
|||||||
30
|
30
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
{
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<FLOAT>(
|
||||||
|
"
|
||||||
|
let sum = 0.0;
|
||||||
|
for x in range(1.0, 10.0, 2.0) { sum += x; }
|
||||||
|
sum
|
||||||
|
"
|
||||||
|
)?,
|
||||||
|
25.0
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<FLOAT>(
|
||||||
|
"
|
||||||
|
let sum = 0.0;
|
||||||
|
for x in range(10.0, 1.0, 2.0) { sum += x; }
|
||||||
|
sum
|
||||||
|
"
|
||||||
|
)?,
|
||||||
|
0.0
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<FLOAT>(
|
||||||
|
"
|
||||||
|
let sum = 0.0;
|
||||||
|
for x in range(1.0, 10.0, -2.0) { sum += x; }
|
||||||
|
sum
|
||||||
|
"
|
||||||
|
)?,
|
||||||
|
0.0
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<FLOAT>(
|
||||||
|
"
|
||||||
|
let sum = 0.0;
|
||||||
|
for x in range(10.0, 1.0, -2.0) { sum += x; }
|
||||||
|
sum
|
||||||
|
"
|
||||||
|
)?,
|
||||||
|
30.0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
#[cfg(feature = "decimal")]
|
||||||
|
{
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<Decimal>(
|
||||||
|
"
|
||||||
|
let sum = to_decimal(0);
|
||||||
|
for x in range(to_decimal(1), to_decimal(10), to_decimal(2)) { sum += x; }
|
||||||
|
sum
|
||||||
|
"
|
||||||
|
)?,
|
||||||
|
Decimal::from(25)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<Decimal>(
|
||||||
|
"
|
||||||
|
let sum = to_decimal(0);
|
||||||
|
for x in range(to_decimal(10), to_decimal(1), to_decimal(2)) { sum += x; }
|
||||||
|
sum
|
||||||
|
"
|
||||||
|
)?,
|
||||||
|
Decimal::from(0)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<Decimal>(
|
||||||
|
"
|
||||||
|
let sum = to_decimal(0);
|
||||||
|
for x in range(to_decimal(1), to_decimal(10), to_decimal(-2)) { sum += x; }
|
||||||
|
sum
|
||||||
|
"
|
||||||
|
)?,
|
||||||
|
Decimal::from(0)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<Decimal>(
|
||||||
|
"
|
||||||
|
let sum = to_decimal(0);
|
||||||
|
for x in range(to_decimal(10), to_decimal(1), to_decimal(-2)) { sum += x; }
|
||||||
|
sum
|
||||||
|
"
|
||||||
|
)?,
|
||||||
|
Decimal::from(30)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user