@@ -4,27 +4,31 @@ use super::super::pyobject::{
4
4
use super :: super :: vm:: VirtualMachine ;
5
5
use super :: objint;
6
6
use 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 } ;
9
9
10
- #[ derive( Debug , Copy , Clone ) ]
10
+ #[ derive( Debug , Clone ) ]
11
11
pub struct RangeType {
12
12
// Unfortunately Rust's built in range type doesn't support things like indexing
13
13
// 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 ,
17
17
}
18
18
19
19
impl RangeType {
20
20
#[ inline]
21
21
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 ( )
23
26
}
24
27
25
28
#[ inline]
26
29
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 ( ) )
28
32
}
29
33
30
34
#[ inline]
@@ -33,8 +37,8 @@ impl RangeType {
33
37
}
34
38
35
39
#[ 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;
38
42
39
43
if self . forward ( ) && !self . is_empty ( ) && result < self . end {
40
44
Some ( result)
@@ -70,24 +74,24 @@ fn range_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
70
74
) ;
71
75
72
76
let start = if let Some ( _) = second {
73
- objint:: get_value ( first) . to_i64 ( ) . unwrap ( )
77
+ objint:: get_value ( first)
74
78
} else {
75
- 0i64
79
+ BigInt :: zero ( )
76
80
} ;
77
81
78
82
let end = if let Some ( pyint) = second {
79
- objint:: get_value ( pyint) . to_i64 ( ) . unwrap ( )
83
+ objint:: get_value ( pyint)
80
84
} else {
81
- objint:: get_value ( first) . to_i64 ( ) . unwrap ( )
85
+ objint:: get_value ( first)
82
86
} ;
83
87
84
88
let step = if let Some ( pyint) = step {
85
- objint:: get_value ( pyint) . to_i64 ( ) . unwrap ( )
89
+ objint:: get_value ( pyint)
86
90
} else {
87
- 1i64
91
+ BigInt :: one ( )
88
92
} ;
89
93
90
- if step == 0 {
94
+ if step. is_zero ( ) {
91
95
Err ( vm. new_value_error ( "range with 0 step size" . to_string ( ) ) )
92
96
} else {
93
97
Ok ( PyObject :: new (
@@ -128,15 +132,15 @@ fn range_getitem(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
128
132
args,
129
133
required = [ ( zelf, Some ( vm. ctx. range_type( ) ) ) , ( subscript, None ) ]
130
134
) ;
131
- let zrange = if let PyObjectPayload :: Range { range } = zelf. borrow ( ) . payload {
135
+ let zrange = if let PyObjectPayload :: Range { ref range } = zelf. borrow ( ) . payload {
132
136
range. clone ( )
133
137
} else {
134
138
unreachable ! ( )
135
139
} ;
136
140
137
141
match subscript. borrow ( ) . payload {
138
142
PyObjectPayload :: Integer { ref value } => {
139
- if let Some ( int) = zrange. get ( value. to_i64 ( ) . unwrap ( ) ) {
143
+ if let Some ( int) = zrange. get ( value. clone ( ) ) {
140
144
Ok ( PyObject :: new (
141
145
PyObjectPayload :: Integer {
142
146
value : int. to_bigint ( ) . unwrap ( ) ,
@@ -150,17 +154,17 @@ fn range_getitem(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
150
154
PyObjectPayload :: Slice { start, stop, step } => {
151
155
let new_start = if let Some ( int) = start {
152
156
if let Some ( i) = zrange. get ( int. into ( ) ) {
153
- i as i64
157
+ i
154
158
} else {
155
- zrange. start
159
+ zrange. start . clone ( )
156
160
}
157
161
} else {
158
- zrange. start
162
+ zrange. start . clone ( )
159
163
} ;
160
164
161
165
let new_end = if let Some ( int) = stop {
162
166
if let Some ( i) = zrange. get ( int. into ( ) ) {
163
- i as i64
167
+ i
164
168
} else {
165
169
zrange. end
166
170
}
0 commit comments