@@ -82,15 +82,15 @@ impl PyRange {
82
82
return None ;
83
83
}
84
84
85
- let length = if start < stop {
85
+ let length: BigInt = if start < stop {
86
86
( stop - start - 1 ) / step + 1
87
87
} else {
88
88
( start - stop - 1 ) / ( -step) + 1
89
89
} ;
90
90
91
- let index = if index < BigInt :: zero ( ) {
92
- let new_index = & length + & index;
93
- if new_index < BigInt :: zero ( ) {
91
+ let index = if index. is_negative ( ) {
92
+ let new_index: BigInt = & length + & index;
93
+ if new_index. is_negative ( ) {
94
94
return None ;
95
95
}
96
96
length + index
@@ -320,73 +320,86 @@ impl PyRange {
320
320
fn getitem ( & self , subscript : RangeIndex , vm : & VirtualMachine ) -> PyResult {
321
321
match subscript {
322
322
RangeIndex :: Slice ( slice) => {
323
- let start = self . start . as_bigint ( ) ;
324
- let stop = self . stop . as_bigint ( ) ;
325
- let step = self . step . as_bigint ( ) ;
326
-
327
- let new_start = if let Some ( int) = slice. start_index ( vm) ? {
328
- let int = & int;
329
- if let Some ( i) = self . get ( int) {
330
- PyInt :: new ( i) . into_ref ( vm)
331
- } else if start < stop {
332
- if stop <= int {
333
- self . stop . clone ( )
334
- } else {
335
- self . start . clone ( )
336
- }
337
- } else if int < stop {
338
- self . stop . clone ( )
339
- } else {
340
- self . start . clone ( )
323
+ let range_start = self . start . as_bigint ( ) ;
324
+ let range_step = self . step . as_bigint ( ) ;
325
+ let _tmp_len = self . length ( ) ;
326
+ let range_length = _tmp_len. as_bigint ( ) ;
327
+
328
+ let substep = if let Some ( slice_step) = slice. step_index ( vm) ? {
329
+ if slice_step. is_zero ( ) {
330
+ return Err ( vm. new_value_error ( "slice step cannot be zero" . to_string ( ) ) ) ;
341
331
}
332
+ slice_step
342
333
} else {
343
- self . start . clone ( )
334
+ BigInt :: one ( )
344
335
} ;
345
336
346
- let new_end = if let Some ( int) = slice. stop_index ( vm) ? {
347
- let int = & int;
348
- if let Some ( i) = self . get ( int) {
349
- PyInt :: new ( i) . into_ref ( vm)
350
- } else if start < stop {
351
- if int < start {
352
- self . start . clone ( )
337
+ let negative_step = substep. is_negative ( ) ;
338
+ let lower_bound = if negative_step {
339
+ -BigInt :: one ( )
340
+ } else {
341
+ BigInt :: zero ( )
342
+ } ;
343
+ let upper_bound = if negative_step {
344
+ & lower_bound + range_length
345
+ } else {
346
+ range_length. clone ( )
347
+ } ;
348
+
349
+ let substart = if let Some ( slice_start) = slice. start_index ( vm) ? {
350
+ if slice_start. is_negative ( ) {
351
+ let tmp = slice_start + range_length;
352
+ if tmp < lower_bound {
353
+ lower_bound. clone ( )
353
354
} else {
354
- self . stop . clone ( )
355
+ tmp . clone ( )
355
356
}
356
- } else if start < int {
357
- self . start . clone ( )
357
+ } else if slice_start > upper_bound {
358
+ upper_bound . clone ( )
358
359
} else {
359
- self . stop . clone ( )
360
+ slice_start . clone ( )
360
361
}
362
+ } else if negative_step {
363
+ upper_bound. clone ( )
361
364
} else {
362
- self . stop . clone ( )
365
+ lower_bound . clone ( )
363
366
} ;
364
367
365
- let new_step = if let Some ( int) = slice. step_index ( vm) ? {
366
- if step. is_zero ( ) {
367
- return Err ( vm. new_value_error ( "slice step cannot be zero" . to_string ( ) ) ) ;
368
+ let substop = if let Some ( slice_stop) = slice. stop_index ( vm) ? {
369
+ if slice_stop. is_negative ( ) {
370
+ let tmp = slice_stop + range_length;
371
+ if tmp < lower_bound {
372
+ lower_bound. clone ( )
373
+ } else {
374
+ tmp. clone ( )
375
+ }
376
+ } else if slice_stop > upper_bound {
377
+ upper_bound. clone ( )
368
378
} else {
369
- PyInt :: new ( int * self . step . as_bigint ( ) ) . into_ref ( vm )
379
+ slice_stop . clone ( )
370
380
}
381
+ } else if negative_step {
382
+ lower_bound. clone ( )
371
383
} else {
372
- self . step . clone ( )
384
+ upper_bound . clone ( )
373
385
} ;
374
386
387
+ let step = range_step * & substep;
388
+ let start = range_start + ( & substart * range_step) ;
389
+ let stop = range_start + ( & substop * range_step) ;
390
+
375
391
Ok ( PyRange {
376
- start : new_start ,
377
- stop : new_end ,
378
- step : new_step ,
392
+ start : PyInt :: new ( start ) . into_ref ( vm ) ,
393
+ stop : PyInt :: new ( stop ) . into_ref ( vm ) ,
394
+ step : PyInt :: new ( step ) . into_ref ( vm ) ,
379
395
}
380
396
. into_ref ( vm)
381
397
. into_object ( ) )
382
398
}
383
- RangeIndex :: Int ( index) => {
384
- if let Some ( value) = self . get ( index. as_bigint ( ) ) {
385
- Ok ( PyInt :: new ( value) . into_ref ( vm) . into_object ( ) )
386
- } else {
387
- Err ( vm. new_index_error ( "range object index out of range" . to_string ( ) ) )
388
- }
389
- }
399
+ RangeIndex :: Int ( index) => match self . get ( index. as_bigint ( ) ) {
400
+ Some ( value) => Ok ( PyInt :: new ( value) . into_ref ( vm) . into_object ( ) ) ,
401
+ None => Err ( vm. new_index_error ( "range object index out of range" . to_string ( ) ) ) ,
402
+ } ,
390
403
}
391
404
}
392
405
0 commit comments