8000 Implemented list.__reversed__ · rmliddle/RustPython@b7c035f · GitHub
[go: up one dir, main page]

Skip to content

Commit b7c035f

Browse files
author
Adolfo Gonzalez III
committed
Implemented list.__reversed__
1 parent 19e783d commit b7c035f

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

vm/src/obj/objlist.rs

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,14 @@ impl PyListRef {
167167
fn reverse(self, _vm: &VirtualMachine) {
168168
self.elements.borrow_mut().reverse();
169169
}
170+
171+
fn reversed(self, _vm: &VirtualMachine) -> PyListReverseIterator {
172+
let final_position = self.elements.borrow().len();
173+
PyListReverseIterator {
174+
position: Cell::new(final_position),
175+
list: self,
176+
}
177+
}
170178

171179
fn getitem(self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {
172180
get_item(
@@ -397,15 +405,15 @@ impl PyListRef {
397405
.collect();
398406
vm.ctx.new_list(new_elements)
399407
}
400-
408+
401409
fn imul(self, counter: isize, _vm: &VirtualMachine) -> Self {
402410
let new_elements = seq_mul(&self.elements.borrow().as_slice(), counter)
403411
.cloned()
404412
.collect();
405413
self.elements.replace(new_elements);
406414
self
407415
}
408-
416+
409417
fn count(self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult<usize> {
410418
let mut count: usize = 0;
411419
for element in self.elements.borrow().iter() {
@@ -813,6 +821,39 @@ impl PyListIterator {
813821
}
814822
}
815823

824+
#[pyclass]
825+
#[derive(Debug)]
826+
pub struct PyListReverseIterator {
827+
pub position: Cell<usize>,
828+
pub list: PyListRef,
829+
}
830+
831+
impl PyValue for PyListReverseIterator {
832+
fn class(vm: &VirtualMachine) -> PyClassRef {
833+
vm.ctx.listreverseiterator_type()
834+
}
835+
}
836+
837+
#[pyimpl]
838+
impl PyListReverseIterator {
839+
#[pymethod(name = "__next__")]
840+
fn next(&self, vm: &VirtualMachine) -> PyResult {
841+
if self.position.get() > 0 {
842+
let position: usize = self.position.get() - 1;
843+
let ret = self.list.elements.borrow()[position].clone();
844+
self.position.set(position);
845+
Ok(ret)
846+
} else {
847+
Err(objiter::new_stop_iteration(vm))
848+
}
849+
}
850+
851+
#[pymethod(name = "__iter__")]
852+
fn iter(zelf: PyRef<Self>, _vm: &VirtualMachine) -> PyRef<Self> {
853+
zelf
854+
}
855+
}
856+
816857
#[rustfmt::skip] // to avoid line splitting
817858
pub fn init(context: &PyContext) {
818859
let list_type = &context.list_type;
@@ -835,6 +876,7 @@ pub fn init(context: &PyContext) {
835876
"__getitem__" => context.new_rustfunc(PyListRef::getitem),
836877
"__iter__" => context.new_rustfunc(PyListRef::iter),
837878
"__setitem__" => context.new_rustfunc(PyListRef::setitem),
879+
"__reversed__" => context.new_rustfunc(PyListRef::reversed),
838880
"__mul__" => context.new_rustfunc(PyListRef::mul),
839881
"__imul__" => context.new_rustfunc(PyListRef::imul),
840882
"__len__" => context.new_rustfunc(PyListRef::len),
@@ -856,4 +898,5 @@ pub fn init(context: &PyContext) {
856898
});
857899

858900
PyListIterator::extend_class(context, &context.listiterator_type);
901+
PyListReverseIterator::extend_class(context, &context.listreverseiterator_type);
859902
}

vm/src/pyobject.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ pub struct PyContext {
134134
pub false_value: PyIntRef,
135135
pub list_type: PyClassRef,
136136
pub listiterator_type: PyClassRef,
137+
pub listreverseiterator_type: PyClassRef,
137138
pub dictkeyiterator_type: PyClassRef,
138139
pub dictvalueiterator_type: PyClassRef,
139140
pub dictitemiterator_type: PyClassRef,
@@ -271,6 +272,7 @@ impl PyContext {
271272
let str_type = create_type("str", &type_type, &object_type);
272273
let list_type = create_type("list", &type_type, &object_type);
273274
let listiterator_type = create_type("list_iterator", &type_type, &object_type);
275+
let listreverseiterator_type = create_type("list_reverseiterator", &type_type, &object_type);
274276
let dictkeys_type = create_type("dict_keys", &type_type, &object_type);
275277
let dictvalues_type = create_type("dict_values", &type_type, &object_type);
276278
let dictitems_type = create_type("dict_items", &type_type, &object_type);
@@ -337,6 +339,7 @@ impl PyContext {
337339
staticmethod_type,
338340
list_type,
339341
listiterator_type,
342+
listreverseiterator_type,
340343
dictkeys_type,
341344
dictvalues_type,
342345
dictitems_type,
@@ -467,6 +470,10 @@ impl PyContext {
467470
pub fn listiterator_type(&self) -> PyClassRef {
468471
self.listiterator_type.clone()
469472
}
473+
474+
pub fn listreverseiterator_type(&self) -> PyClassRef {
475+
self.listreverseiterator_type.clone()
476+
}
470477

471478
pub fn module_type(&self) -> PyClassRef {
472479
self.module_type.clone()

0 commit comments

Comments
 (0)
0