Allow negative range step.
This commit is contained in:
parent
082111074e
commit
66b557692b
10
CHANGELOG.md
10
CHANGELOG.md
@ -9,6 +9,16 @@ Bug fixes
|
||||
|
||||
* Errors in native Rust functions now contain the correct function call positions.
|
||||
|
||||
Breaking changes
|
||||
----------------
|
||||
|
||||
* Zero step in the `range` function now raises an error instead of creating an infinite stream.
|
||||
|
||||
Enhancements
|
||||
------------
|
||||
|
||||
* `range` function now supports negative step and decreasing streams (i.e. to < from).
|
||||
|
||||
|
||||
Version 0.19.13
|
||||
===============
|
||||
|
@ -3,7 +3,7 @@ use crate::stdlib::{
|
||||
boxed::Box,
|
||||
ops::{Add, Range},
|
||||
};
|
||||
use crate::{def_package, EvalAltResult, INT};
|
||||
use crate::{def_package, EvalAltResult, Position, INT};
|
||||
|
||||
fn get_range<T: Variant + Clone>(from: T, to: T) -> Result<Range<T>, Box<EvalAltResult>> {
|
||||
Ok(from..to)
|
||||
@ -16,6 +16,23 @@ where
|
||||
for<'a> &'a T: Add<&'a T, Output = T>,
|
||||
T: Variant + Clone + PartialOrd;
|
||||
|
||||
impl<T> StepRange<T>
|
||||
where
|
||||
for<'a> &'a T: Add<&'a T, Output = T>,
|
||||
T: Variant + Clone + PartialOrd,
|
||||
{
|
||||
pub fn new(from: T, to: T, step: T) -> Result<Self, Box<EvalAltResult>> {
|
||||
if &from + &step == from {
|
||||
Err(Box::new(EvalAltResult::ErrorArithmetic(
|
||||
"invalid step value".to_string(),
|
||||
Position::NONE,
|
||||
)))
|
||||
} else {
|
||||
Ok(Self(from, to, step))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Iterator for StepRange<T>
|
||||
where
|
||||
for<'a> &'a T: Add<&'a T, Output = T>,
|
||||
@ -24,12 +41,18 @@ where
|
||||
type Item = T;
|
||||
|
||||
fn next(&mut self) -> Option<T> {
|
||||
if self.0 < self.1 {
|
||||
if self.0 == self.1 {
|
||||
None
|
||||
} else if self.0 < self.1 {
|
||||
let v = self.0.clone();
|
||||
self.0 = self.0.add(&self.2);
|
||||
let n = self.0.add(&self.2);
|
||||
self.0 = if n >= self.1 { self.1.clone() } else { n };
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
let v = self.0.clone();
|
||||
let n = self.0.add(&self.2);
|
||||
self.0 = if n <= self.1 { self.1.clone() } else { n };
|
||||
Some(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -39,7 +62,7 @@ where
|
||||
for<'a> &'a T: Add<&'a T, Output = T>,
|
||||
T: Variant + Clone + PartialOrd,
|
||||
{
|
||||
Ok(StepRange::<T>(from, to, step))
|
||||
StepRange::<T>::new(from, to, step)
|
||||
}
|
||||
|
||||
macro_rules! reg_range {
|
||||
|
Loading…
Reference in New Issue
Block a user