8000 Refactor list, tuple and collections.deque by youknowone · Pull Request #1655 · RustPython/RustPython · GitHub
[go: up one dir, main page]

Skip to content

Refactor list, tuple and collections.deque #1655

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jan 8, 2020
Prev Previous commit
Next Next commit
vm::sequence for SimpleSeq utilities
  • Loading branch information
youknowone committed Jan 7, 2020
commit 226ebfa0c65ac8db5e63e008d32481865eb61345
23 changes: 13 additions & 10 deletions vm/src/obj/objlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,15 @@ use super::objbool;
use super::objbyteinner;
use super::objint::PyIntRef;
use super::objiter;
use super::objsequence::{
get_item, seq_equal, seq_ge, seq_gt, seq_le, seq_lt, seq_mul, SequenceIndex, SimpleSeq,
};
use super::objsequence::{get_item, SequenceIndex};
use super::objslice::PySliceRef;
use super::objtype::PyClassRef;
use crate::function::OptionalArg;
use crate::pyobject::{
IdProtocol, PyArithmaticValue::*, PyClassImpl, PyComparisonValue, PyContext, PyIterable,
PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
};
use crate::sequence::{self, SimpleSeq};
use crate::vm::{ReprGuard, VirtualMachine};

/// Built-in mutable sequence.
Expand Down Expand Up @@ -469,7 +468,9 @@ impl PyList {

#[pymethod(name = "__mul__")]
fn mul(&self, counter: isize, vm: &VirtualMachine) -> PyObjectRef {
let new_elements = seq_mul(&self.borrow_sequence(), counter).cloned().collect();
let new_elements = sequence::seq_mul(&self.borrow_sequence(), counter)
.cloned()
.collect();
vm.ctx.new_list(new_elements)
}

Expand All @@ -480,7 +481,9 @@ impl PyList {

#[pymethod(name = "__imul__")]
fn imul(zelf: PyRef<Self>, counter: isize, _vm: &VirtualMachine) -> PyRef<Self> {
let new_elements = seq_mul(&zelf.borrow_sequence(), counter).cloned().collect();
let new_elements = sequence::seq_mul(&zelf.borrow_sequence(), counter)
.cloned()
.collect();
zelf.elements.replace(new_elements);
zelf
}
Expand Down Expand Up @@ -562,7 +565,7 @@ impl PyList {
let value = if zelf.as_object().is(&other) {
Implemented(true)
} else if let Some(other) = other.payload_if_subclass::<PyList>(vm) {
Implemented(seq_equal(
Implemented(sequence::eq(
vm,
&zelf.borrow_sequence(),
&other.borrow_sequence(),
Expand All @@ -585,7 +588,7 @@ impl PyList {
#[pymethod(name = "__lt__")]
fn lt(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if let Some(other) = other.payload_if_subclass::<PyList>(vm) {
let res = seq_lt(vm, &self.borrow_sequence(), &other.borrow_sequence())?;
let res = sequence::lt(vm, &self.borrow_sequence(), &other.borrow_sequence())?;
Ok(vm.new_bool(res))
} else {
Ok(vm.ctx.not_implemented())
Expand All @@ -595,7 +598,7 @@ impl PyList {
#[pymethod(name = "__gt__")]
fn gt(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if let Some(other) = other.payload_if_subclass::<PyList>(vm) {
let res = seq_gt(vm, &self.borrow_sequence(), &other.borrow_sequence())?;
let res = sequence::gt(vm, &self.borrow_sequence(), &other.borrow_sequence())?;
Ok(vm.new_bool(res))
} else {
Ok(vm.ctx.not_implemented())
Expand All @@ -605,7 +608,7 @@ impl PyList {
#[pymethod(name = "__ge__")]
fn ge(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if let Some(other) = other.payload_if_subclass::<PyList>(vm) {
let res = seq_ge(vm, &self.borrow_sequence(), &other.borrow_sequence())?;
let res = sequence::ge(vm, &self.borrow_sequence(), &other.borrow_sequence())?;
Ok(vm.new_bool(res))
} else {
Ok(vm.ctx.not_implemented())
Expand All @@ -615,7 +618,7 @@ impl PyList {
#[pymethod(name = "__le__")]
fn le(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if let Some(other) = other.payload_if_subclass::<PyList>(vm) {
let res = seq_le(vm, &self.borrow_sequence(), &other.borrow_sequence())?;
let res = sequence::le(vm, &self.borrow_sequence(), &other.borrow_sequence())?;
Ok(vm.new_bool(res))
} else {
Ok(vm.ctx.not_implemented())
Expand Down
164 changes: 2 additions & 162 deletions vm/src/obj/objsequence.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::marker::Sized;
use std::ops::{Deref, Range};
use std::ops::Range;

use num_bigint::{BigInt, ToBigInt};
use num_traits::{One, Signed, ToPrimitive, Zero};
Expand All @@ -10,7 +10,7 @@ use super::objnone::PyNone;
use super::objslice::{PySlice, PySliceRef};
use super::objtuple::PyTuple;
use crate::function::OptionalArg;
use crate::pyobject::{IdProtocol, PyObject, PyObjectRef, PyResult, TryFromObject, TypeProtocol};
use crate::pyobject::{PyObject, PyObjectRef, PyResult, TryFromObject, TypeProtocol};
use crate::vm::VirtualMachine;

pub trait PySliceableSequence {
Expand Down Expand Up @@ -246,166 +246,6 @@ pub fn get_item(
}
}

type DynPyIter<'a> = Box<dyn ExactSizeIterator<Item = &'a PyObjectRef> + 'a>;

#[allow(clippy::len_without_is_empty)]
pub trait SimpleSeq {
fn len(&self) -> usize;
fn iter(&self) -> DynPyIter;
}

// impl SimpleSeq for &[PyObjectRef] {
// fn len(&self) -> usize {
// (&**self).len()
// }
// fn iter(&self) -> DynPyIter {
// Box::new((&**self).iter())
// }
// }

impl SimpleSeq for Vec<PyObjectRef> {
fn len(&self) -> usize {
self.len()
}
fn iter(&self) -> DynPyIter {
Box::new(self.as_slice().iter())
}
}

impl SimpleSeq for std::collections::VecDeque<PyObjectRef> {
fn len(&self) -> usize {
self.len()
}
fn iter(&self) -> DynPyIter {
Box::new(self.iter())
}
}

impl<T> SimpleSeq for std::cell::Ref<'_, T> where T: SimpleSeq {
fn len(&self) -> usize {
self.deref().len()
}
fn iter(&self) -> DynPyIter {
self.deref().iter()
}
EDBE }

// impl<'a, I>

pub fn seq_equal(
vm: &VirtualMachine,
zelf: &impl SimpleSeq,
other: &impl SimpleSeq,
) -> PyResult<bool> {
if zelf.len() == other.len() {
for (a, b) in Iterator::zip(zelf.iter(), other.iter()) {
if a.is(b) {
continue;
}
if !vm.bool_eq(a.clone(), b.clone())? {
return Ok(false);
}
}
Ok(true)
} else {
Ok(false)
}
}

pub fn seq_lt(
vm: &VirtualMachine,
zelf: &impl SimpleSeq,
other: &impl SimpleSeq,
) -> PyResult<bool> {
for (a, b) in Iterator::zip(zelf.iter(), other.iter()) {
if let Some(v) = vm.bool_seq_lt(a.clone(), b.clone())? {
return Ok(v);
}
}
Ok(zelf.len() < other.len())
}

pub fn seq_gt(
vm: &VirtualMachine,
zelf: &impl SimpleSeq,
other: &impl SimpleSeq,
) -> PyResult<bool> {
for (a, b) in Iterator::zip(zelf.iter(), other.iter()) {
if let Some(v) = vm.bool_seq_gt(a.clone(), b.clone())? {
return Ok(v);
}
}
Ok(zelf.len() > other.len())
}

pub fn seq_ge(
vm: &VirtualMachine,
zelf: &impl SimpleSeq,
other: &impl SimpleSeq,
) -> PyResult<bool> {
for (a, b) in Iterator::zip(zelf.iter(), other.iter()) {
if let Some(v) = vm.bool_seq_gt(a.clone(), b.clone())? {
return Ok(v);
}
}

Ok(zelf.len() >= other.len())
}

pub fn seq_le(
vm: &VirtualMachine,
zelf: &impl SimpleSeq,
other: &impl SimpleSeq,
) -> PyResult<bool> {
for (a, b) in Iterator::zip(zelf.iter(), other.iter()) {
if let Some(v) = vm.bool_seq_lt(a.clone(), b.clone())? {
return Ok(v);
}
}

Ok(zelf.len() <= other.len())
}

pub struct SeqMul<'a> {
seq: &'a dyn SimpleSeq,
repetitions: usize,
iter: Option<DynPyIter<'a>>,
}
impl<'a> Iterator for SeqMul<'a> {
type Item = &'a PyObjectRef;
fn next(&mut self) -> Option<Self::Item> {
if self.seq.len() == 0 {
return None;
}
match self.iter.as_mut().and_then(Iterator::next) {
Some(item) => Some(item),
None => {
if self.repetitions == 0 {
None
} else {
self.repetitions -= 1;
self.iter = Some(self.seq.iter());
self.next()
}
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.iter.as_ref().map_or(0, ExactSizeIterator::len)
+ (self.repetitions * self.seq.len());
(size, Some(size))
}
}
impl ExactSizeIterator for SeqMul<'_> {}

pub fn seq_mul<'a>(seq: &'a impl SimpleSeq, repetitions: isize) -> SeqMul<'a> {
SeqMul {
seq,
repetitions: repetitions.max(0) as usize,
iter: None,
}
}

//Check if given arg could be used with PySliceableSequence.get_slice_range()
pub fn is_valid_slice_arg(
arg: OptionalArg<PyObjectRef>,
Expand Down
17 changes: 10 additions & 7 deletions vm/src/obj/objtuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ use std::cell::Cell;
use std::fmt;

use super::objiter;
use super::objsequence::{get_item, seq_equal, seq_ge, seq_gt, seq_le, seq_lt, seq_mul, SimpleSeq};
use super::objsequence::get_item;
use super::objtype::PyClassRef;
use crate::function::OptionalArg;
use crate::pyhash;
use crate::pyobject::{
IntoPyObject, PyArithmaticValue::*, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef,
PyRef, PyResult, PyValue,
};
use crate::sequence::{self, SimpleSeq};
use crate::vm::{ReprGuard, VirtualMachine};

/// tuple() -> empty tuple
Expand Down Expand Up @@ -95,22 +96,22 @@ impl PyTuple {

#[pymethod(name = "__lt__")]
fn lt(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyComparisonValue> {
self.cmp(other, |a, b| seq_lt(vm, a, b), vm)
self.cmp(other, |a, b| sequence::lt(vm, a, b), vm)
}

#[pymethod(name = "__gt__")]
fn gt(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyComparisonValue> {
self.cmp(other, |a, b| seq_gt(vm, a, b), vm)
self.cmp(other, |a, b| sequence::gt(vm, a, b), vm)
}

#[pymethod(name = "__ge__")]
fn ge(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyComparisonValue> {
self.cmp(other, |a, b| seq_ge(vm, a, b), vm)
self.cmp(other, |a, b| sequence::ge(vm, a, b), vm)
}

#[pymethod(name = "__le__")]
fn le(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyComparisonValue> {
self.cmp(other, |a, b| seq_le(vm, a, b), vm)
self.cmp(other, |a, b| sequence::le(vm, a, b), vm)
}

#[pymethod(name = "__add__")]
Expand Down Expand Up @@ -146,7 +147,7 @@ impl PyTuple {

#[pymethod(name = "__eq__")]
fn eq(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyComparisonValue> {
self.cmp(other, |a, b| seq_equal(vm, a, b), vm)
self.cmp(other, |a, b| sequence::eq(vm, a, b), vm)
}

#[pymethod(name = "__ne__")]
Expand Down Expand Up @@ -194,7 +195,9 @@ impl PyTuple {

#[pymethod(name = "__mul__")]
fn mul(&self, counter: isize, vm: &VirtualMachine) -> PyObjectRef {
let new_elements = seq_mul(&self.elements, counter).cloned().collect();
let new_elements = sequence::seq_mul(&self.elements, counter)
.cloned()
.collect();
vm.ctx.new_tuple(new_elements)
}

Expand Down
Loading
0