@@ -320,62 +320,70 @@ 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 { -BigInt :: one ( ) } else { BigInt :: zero ( ) } ;
339
+ let upper_bound = if negative_step { & lower_bound + range_length } else { range_length. clone ( ) } ;
340
+
341
+ let substart = if let Some ( slice_start) = slice. start_index ( vm) ? {
342
+ if slice_start. is_negative ( ) {
343
+ let tmp = slice_start + range_length;
344
+ if tmp < lower_bound {
345
+ lower_bound. clone ( )
353
346
} else {
354
- self . stop . clone ( )
347
+ tmp . clone ( )
355
348
}
356
- } else if start < int {
357
- self . start . clone ( )
358
349
} else {
359
- self . stop . clone ( )
350
+ if slice_start > upper_bound {
351
+ upper_bound. clone ( )
352
+ } else {
353
+ slice_start. clone ( )
354
+ }
360
355
}
361
356
} else {
362
- self . stop . clone ( )
357
+ if negative_step { upper_bound . clone ( ) } else { lower_bound . clone ( ) }
363
358
} ;
364
359
365
- let new_step = if let Some ( int) = slice. step_index ( vm) ? {
366
- if int. is_zero ( ) {
367
- return Err ( vm. new_value_error ( "slice step cannot be zero" . to_string ( ) ) ) ;
360
+ let substop = if let Some ( slice_stop) = slice. stop_index ( vm) ? {
361
+ if slice_stop. is_negative ( ) {
362
+ let tmp = slice_stop + range_length;
363
+ if tmp < lower_bound {
364
+ lower_bound. clone ( )
365
+ } else {
366
+ tmp. clone ( )
367
+ }
368
368
} else {
369
- PyInt :: new ( int * self . step . as_bigint ( ) ) . into_ref ( vm)
369
+ if slice_stop > upper_bound {
370
+ upper_bound. clone ( )
371
+ } else {
372
+ slice_stop. clone ( )
373
+ }
370
374
}
371
375
} else {
372
- self . step . clone ( )
376
+ if negative_step { lower_bound . clone ( ) } else { upper_bound . clone ( ) }
373
377
} ;
374
378
379
+ let step = range_step * & substep;
380
+ let start = range_start + ( & substart * range_step) ;
381
+ let stop = range_start + ( & substop * range_step) ;
382
+
375
383
Ok ( PyRange {
376
- start : new_start ,
377
- stop : new_end ,
378
- step : new_step ,
384
+ start : PyInt :: new ( start ) . into_ref ( vm ) ,
385
+ stop : PyInt :: new ( stop ) . into_ref ( vm ) ,
386
+ step : PyInt :: new ( step ) . into_ref ( vm ) ,
379
387
}
380
388
. into_ref ( vm)
381
389
. into_object ( ) )
0 commit comments