Skip to content

Commit fc84fe8

Browse files
Convert range to new args style
1 parent 84d47d2 commit fc84fe8

File tree

1 file changed

+82
-120
lines changed

1 file changed

+82
-120
lines changed

vm/src/obj/objrange.rs

Lines changed: 82 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::ops::Mul;
33

44
use num_bigint::{BigInt, Sign};
55
use num_integer::Integer;
6-
use num_traits::{One, Signed, ToPrimitive, Zero};
6+
use num_traits::{One, Signed, Zero};
77

88
use crate::function::{OptionalArg, PyFuncArgs};
99
use crate::pyobject::{
@@ -31,26 +31,6 @@ impl PyValue for PyRange {
3131
}
3232

3333
impl PyRange {
34-
#[inline]
35-
pub fn try_len(&self) -> Option<usize> {
36-
match self.step.sign() {
37-
Sign::Plus if self.start < self.stop => ((&self.stop - &self.start - 1usize)
38-
/ &self.step)
39-
.to_usize()
40-
.map(|sz| sz + 1),
41-
Sign::Minus if self.start > self.stop => ((&self.start - &self.stop - 1usize)
42-
/ (-&self.step))
43-
.to_usize()
44-
.map(|sz| sz + 1),
45-
_ => Some(0),
46-
}
47-
}
48-
49-
#[inline]
50-
pub fn len(&self) -> usize {
51-
self.try_len().unwrap()
52-
}
53-
5434
#[inline]
5535
fn offset(&self, value: &BigInt) -> Option<BigInt> {
5636
match self.step.sign() {
@@ -113,40 +93,6 @@ impl PyRange {
11393
None
11494
}
11595
}
116-
117-
#[inline]
118-
pub fn reversed(&self) -> Self {
119-
// compute the last element that is actually contained within the range
120-
// this is the new start
121-
let remainder = ((&self.stop - &self.start) % &self.step).abs();
122-
let start = if remainder.is_zero() {
123-
&self.stop - &self.step
124-
} else {
125-
&self.stop - &remainder
126-
};
127-
128-
match self.step.sign() {
129-
Sign::Plus => PyRange {
130-
start,
131-
stop: &self.start - 1,
132-
step: -&self.step,
133-
},
134-
Sign::Minus => PyRange {
135-
start,
136-
stop: &self.start + 1,
137-
step: -&self.step,
138-
},
139-
Sign::NoSign => unreachable!(),
140-
}
141-
}
142-
143-
pub fn repr(&self) -> String {
144-
if self.step == BigInt::one() {
145-
format!("range({}, {})", self.start, self.stop)
146-
} else {
147-
format!("range({}, {}, {})", self.start, self.stop, self.step)
148-
}
149-
}
15096
}
15197

15298
pub fn get_value(obj: &PyObjectRef) -> PyRange {
@@ -165,20 +111,20 @@ pub fn init(context: &PyContext) {
165111
When step is given, it specifies the increment (or decrement).";
166112

167113
extend_class!(context, range_type, {
168-
"__bool__" => context.new_rustfunc(range_bool),
114+
"__bool__" => context.new_rustfunc(PyRangeRef::bool),
169115
"__contains__" => context.new_rustfunc(range_contains),
170116
"__doc__" => context.new_str(range_doc.to_string()),
171117
"__getitem__" => context.new_rustfunc(PyRangeRef::getitem),
172-
"__iter__" => context.new_rustfunc(range_iter),
173-
"__len__" => context.new_rustfunc(range_len),
118+
"__iter__" => context.new_rustfunc(PyRangeRef::iter),
119+
"__len__" => context.new_rustfunc(PyRangeRef::len),
174120
"__new__" => context.new_rustfunc(range_new),
175-
"__repr__" => context.new_rustfunc(range_repr),
176-
"__reversed__" => context.new_rustfunc(range_reversed),
121+
"__repr__" => context.new_rustfunc(PyRangeRef::repr),
122+
"__reversed__" => context.new_rustfunc(PyRangeRef::reversed),
177123
"count" => context.new_rustfunc(range_count),
178124
"index" => context.new_rustfunc(range_index),
179-
"start" => context.new_property(range_start),
180-
"step" => context.new_property(range_step),
181-
"stop" => context.new_property(range_stop)
125+
"start" => context.new_property(PyRangeRef::start),
126+
"stop" => context.new_property(PyRangeRef::stop),
127+
"step" => context.new_property(PyRangeRef::step),
182128
});
183129
}
184130

@@ -212,6 +158,79 @@ impl PyRangeRef {
212158
.into_ref_with_type(vm, cls)
213159
}
214160

161+
fn start(self, _vm: &VirtualMachine) -> BigInt {
162+
self.start.clone()
163+
}
164+
165+
fn stop(self, _vm: &VirtualMachine) -> BigInt {
166+
self.stop.clone()
167+
}
168+
169+
fn step(self, _vm: &VirtualMachine) -> BigInt {
170+
self.step.clone()
171+
}
172+
173+
fn iter(self: PyRangeRef, _vm: &VirtualMachine) -> PyIteratorValue {
174+
PyIteratorValue {
175+
position: Cell::new(0),
176+
iterated_obj: self.into_object(),
177+
}
178+
}
179+
180+
fn reversed(self: PyRangeRef, vm: &VirtualMachine) -> PyIteratorValue {
181+
// compute the last element that is actually contained within the range
182+
// this is the new start
183+
let remainder = ((&self.stop - &self.start) % &self.step).abs();
184+
let start = if remainder.is_zero() {
185+
&self.stop - &self.step
186+
} else {
187+
&self.stop - &remainder
188+
};
189+
190+
let reversed = match self.step.sign() {
191+
Sign::Plus => PyRange {
192+
start,
193+
stop: &self.start - 1,
194+
step: -&self.step,
195+
},
196+
Sign::Minus => PyRange {
197+
start,
198+
stop: &self.start + 1,
199+
step: -&self.step,
200+
},
201+
Sign::NoSign => unreachable!(),
202+
};
203+
PyIteratorValue {
204+
position: Cell::new(0),
205+
iterated_obj: reversed.into_ref(vm).into_object(),
206+
}
207+
}
208+
209+
fn len(self, _vm: &VirtualMachine) -> PyInt {
210+
match self.step.sign() {
211+
Sign::Plus if self.start < self.stop => {
212+
PyInt::new((&self.stop - &self.start - 1usize) / &self.step + 1)
213+
}
214+
Sign::Minus if self.start > self.stop => {
215+
PyInt::new((&self.start - &self.stop - 1usize) / (-&self.step) + 1)
216+
}
217+
Sign::Plus | Sign::Minus => PyInt::new(0),
218+
Sign::NoSign => unreachable!(),
219+
}
220+
}
221+
222+
fn repr(self, _vm: &VirtualMachine) -> String {
223+
if self.step.is_one() {
224+
format!("range({}, {})", self.start, self.stop)
225+
} else {
226+
format!("range({}, {}, {})", self.start, self.stop, self.step)
227+
}
228+
}
229+
230+
fn bool(self, _vm: &VirtualMachine) -> bool {
231+
self.stop != self.start
232+
}
233+
215234
fn getitem(self, subscript: Either<PyIntRef, PySliceRef>, vm: &VirtualMachine) -> PyResult {
216235
match subscript {
217236
Either::A(index) => {
@@ -272,48 +291,6 @@ fn range_new(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
272291
Ok(range.into_object())
273292
}
274293

275-
fn range_iter(range: PyRangeRef, _vm: &VirtualMachine) -> PyIteratorValue {
276-
PyIteratorValue {
277-
position: Cell::new(0),
278-
iterated_obj: range.into_object(),
279-
}
280-
}
281-
282-
fn range_reversed(zelf: PyRangeRef, vm: &VirtualMachine) -> PyIteratorValue {
283-
let range = zelf.reversed();
284-
285-
PyIteratorValue {
286-
position: Cell::new(0),
287-
iterated_obj: range.into_ref(vm).into_object(),
288-
}
289-
}
290-
291-
fn range_len(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
292-
arg_check!(vm, args, required = [(zelf, Some(vm.ctx.range_type()))]);
293-
294-
if let Some(len) = get_value(zelf).try_len() {
295-
Ok(vm.ctx.new_int(len))
296-
} else {
297-
Err(vm.new_overflow_error("Python int too large to convert to Rust usize".to_string()))
298-
}
299-
}
300-
301-
fn range_repr(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
302-
arg_check!(vm, args, required = [(zelf, Some(vm.ctx.range_type()))]);
303-
304-
let repr = get_value(zelf).repr();
305-
306-
Ok(vm.ctx.new_str(repr))
307-
}
308-
309-
fn range_bool(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
310-
arg_check!(vm, args, required = [(zelf, Some(vm.ctx.range_type()))]);
311-
312-
let len = get_value(zelf).len();
313-
314-
Ok(vm.ctx.new_bool(len > 0))
315-
}
316-
317294
fn range_contains(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
318295
arg_check!(
319296
vm,
@@ -368,18 +345,3 @@ fn range_count(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
368345
Ok(vm.ctx.new_int(0))
369346
}
370347
}
371-
372-
fn range_start(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
373-
arg_check!(vm, args, required = [(zelf, Some(vm.ctx.range_type()))]);
374-
Ok(vm.ctx.new_int(get_value(zelf).start))
375-
}
376-
377-
fn range_stop(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
378-
arg_check!(vm, args, required = [(zelf, Some(vm.ctx.range_type()))]);
379-
Ok(vm.ctx.new_int(get_value(zelf).stop))
380-
}
381-
382-
fn range_step(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
383-
arg_check!(vm, args, required = [(zelf, Some(vm.ctx.range_type()))]);
384-
Ok(vm.ctx.new_int(get_value(zelf).step))
385-
}

0 commit comments

Comments
 (0)