@@ -4,27 +4,31 @@ use super::super::pyobject::{
44use super :: super :: vm:: VirtualMachine ;
55use super :: objint;
66use super :: objtype;
7- use num_bigint:: ToBigInt ;
8- use num_traits:: ToPrimitive ;
7+ use num_bigint:: { BigInt , ToBigInt } ;
8+ use num_traits:: { One , Signed , ToPrimitive , Zero } ;
99
10- #[ derive( Debug , Copy , Clone ) ]
10+ #[ derive( Debug , Clone ) ]
1111pub struct RangeType {
1212 // Unfortunately Rust's built in range type doesn't support things like indexing
1313 // or ranges where start > end so we need to roll our own.
14- pub start : i64 ,
15- pub end : i64 ,
16- pub step : i64 ,
14+ pub start : BigInt ,
15+ pub end : BigInt ,
16+ pub step : BigInt ,
1717}
1818
1919impl RangeType {
2020 #[ inline]
2121 pub fn len ( & self ) -> usize {
22- ( ( self . end - self . start ) / self . step ) . abs ( ) as usize
22+ ( ( self . end . clone ( ) - self . start . clone ( ) ) / self . step . clone ( ) )
23+ . abs ( )
24+ . to_usize ( )
25+ . unwrap ( )
2326 }
2427
2528 #[ inline]
2629 pub fn is_empty ( & self ) -> bool {
27- ( self . start <= self . end && self . step < 0 ) || ( self . start >= self . end && self . step > 0 )
30+ ( self . start <= self . end && self . step . is_negative ( ) )
31+ || ( self . start >= self . end && self . step . is_positive ( ) )
2832 }
2933
3034 #[ inline]
@@ -33,8 +37,8 @@ impl RangeType {
3337 }
3438
3539 #[ inline]
36- pub fn get ( & self , index : i64 ) -> Option < i64 > {
37- let result = self . start + self . step * index;
40+ pub fn get ( & self , index : BigInt ) -> Option < BigInt > {
41+ let result = self . start . clone ( ) + self . step . clone ( ) * index;
3842
3943 if self . forward ( ) && !self . is_empty ( ) && result < self . end {
4044 Some ( result)
@@ -70,24 +74,24 @@ fn range_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
7074 ) ;
7175
7276 let start = if let Some ( _) = second {
73- objint:: get_value ( first) . to_i64 ( ) . unwrap ( )
77+ objint:: get_value ( first)
7478 } else {
75- 0i64
79+ BigInt :: zero ( )
7680 } ;
7781
7882 let end = if let Some ( pyint) = second {
79- objint:: get_value ( pyint) . to_i64 ( ) . unwrap ( )
83+ objint:: get_value ( pyint)
8084 } else {
81- objint:: get_value ( first) . to_i64 ( ) . unwrap ( )
85+ objint:: get_value ( first)
8286 } ;
8387
8488 let step = if let Some ( pyint) = step {
85- objint:: get_value ( pyint) . to_i64 ( ) . unwrap ( )
89+ objint:: get_value ( pyint)
8690 } else {
87- 1i64
91+ BigInt :: one ( )
8892 } ;
8993
90- if step == 0 {
94+ if step. is_zero ( ) {
9195 Err ( vm. new_value_error ( "range with 0 step size" . to_string ( ) ) )
9296 } else {
9397 Ok ( PyObject :: new (
@@ -128,15 +132,15 @@ fn range_getitem(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
128132 args,
129133 required = [ ( zelf, Some ( vm. ctx. range_type( ) ) ) , ( subscript, None ) ]
130134 ) ;
131- let zrange = if let PyObjectPayload :: Range { range } = zelf. borrow ( ) . payload {
135+ let zrange = if let PyObjectPayload :: Range { ref range } = zelf. borrow ( ) . payload {
132136 range. clone ( )
133137 } else {
134138 unreachable ! ( )
135139 } ;
136140
137141 match subscript. borrow ( ) . payload {
138142 PyObjectPayload :: Integer { ref value } => {
139- if let Some ( int) = zrange. get ( value. to_i64 ( ) . unwrap ( ) ) {
143+ if let Some ( int) = zrange. get ( value. clone ( ) ) {
140144 Ok ( PyObject :: new (
141145 PyObjectPayload :: Integer {
142146 value : int. to_bigint ( ) . unwrap ( ) ,
@@ -150,17 +154,17 @@ fn range_getitem(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
150154 PyObjectPayload :: Slice { start, stop, step } => {
151155 let new_start = if let Some ( int) = start {
152156 if let Some ( i) = zrange. get ( int. into ( ) ) {
153- i as i64
157+ i
154158 } else {
155- zrange. start
159+ zrange. start . clone ( )
156160 }
157161 } else {
158- zrange. start
162+ zrange. start . clone ( )
159163 } ;
160164
161165 let new_end = if let Some ( int) = stop {
162166 if let Some ( i) = zrange. get ( int. into ( ) ) {
163- i as i64
167+ i
164168 } else {
165169 zrange. end
166170 }
0 commit comments