From b2c19a964bbfca94be6733b1a8367aaeea83f2b5 Mon Sep 17 00:00:00 2001 From: HyeockJinKim Date: Sun, 6 Oct 2019 21:11:05 +0900 Subject: [PATCH] extend_class for PyTuple --- vm/src/obj/objtuple.rs | 124 ++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/vm/src/obj/objtuple.rs b/vm/src/obj/objtuple.rs index 9448ff3834..821871f295 100644 --- a/vm/src/obj/objtuple.rs +++ b/vm/src/obj/objtuple.rs @@ -15,6 +15,11 @@ use super::objsequence::{ }; use super::objtype::{self, PyClassRef}; +/// tuple() -> empty tuple +/// tuple(iterable) -> tuple initialized from iterable's items +/// +/// If the argument is a tuple, the return value is the same object. +#[pyclass] pub struct PyTuple { // TODO: shouldn't be public pub elements: Vec, @@ -72,8 +77,10 @@ pub fn get_value(obj: &PyObjectRef) -> Vec { obj.payload::().unwrap().elements.clone() } -impl PyTupleRef { - fn lt(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { +#[pyimpl] +impl PyTuple { + #[pymethod(name = "__lt__")] + fn lt(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { if objtype::isinstance(&other, &vm.ctx.tuple_type()) { let other = get_elements_tuple(&other); let res = seq_lt(vm, &self.elements.as_slice(), &other.as_slice())?; @@ -83,7 +90,8 @@ impl PyTupleRef { } } - fn gt(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { + #[pymethod(name = "__gt__")] + fn gt(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { if objtype::isinstance(&other, &vm.ctx.tuple_type()) { let other = get_elements_tuple(&other); let res = seq_gt(vm, &self.elements.as_slice(), &other.as_slice())?; @@ -93,7 +101,8 @@ impl PyTupleRef { } } - fn ge(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { + #[pymethod(name = "__ge__")] + fn ge(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { if objtype::isinstance(&other, &vm.ctx.tuple_type()) { let other = get_elements_tuple(&other); let res = seq_ge(vm, &self.elements.as_slice(), &other.as_slice())?; @@ -103,7 +112,8 @@ impl PyTupleRef { } } - fn le(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { + #[pymethod(name = "__le__")] + fn le(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { if objtype::isinstance(&other, &vm.ctx.tuple_type()) { let other = get_elements_tuple(&other); let res = seq_le(vm, &self.elements.as_slice(), &other.as_slice())?; @@ -113,7 +123,8 @@ impl PyTupleRef { } } - fn add(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { + #[pymethod(name = "__add__")] + fn add(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { if objtype::isinstance(&other, &vm.ctx.tuple_type()) { let e2 = get_elements_tuple(&other); let elements = self.elements.iter().chain(e2.iter()).cloned().collect(); @@ -123,11 +134,13 @@ impl PyTupleRef { } } - fn bool(self, _vm: &VirtualMachine) -> bool { + #[pymethod(name = "__bool__")] + fn bool(&self, _vm: &VirtualMachine) -> bool { !self.elements.is_empty() } - fn count(self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult { + #[pymethod(name = "count")] + fn count(&self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult { let mut count: usize = 0; for element in self.elements.iter() { if element.is(&needle) { @@ -142,7 +155,8 @@ impl PyTupleRef { Ok(count) } - fn eq(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { + #[pymethod(name = "__eq__")] + fn eq(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { if objtype::isinstance(&other, &vm.ctx.tuple_type()) { Ok(vm.new_bool(self.inner_eq(&other, vm)?)) } else { @@ -150,7 +164,8 @@ impl PyTupleRef { } } - fn ne(self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { + #[pymethod(name = "__ne__")] + fn ne(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult { if objtype::isinstance(&other, &vm.ctx.tuple_type()) { Ok(vm.new_bool(!self.inner_eq(&other, vm)?)) } else { @@ -163,25 +178,29 @@ impl PyTupleRef { seq_equal(vm, &self.elements.as_slice(), &other.as_slice()) } - fn hash(self, vm: &VirtualMachine) -> PyResult { + #[pymethod(name = "__hash__")] + fn hash(&self, vm: &VirtualMachine) -> PyResult { pyhash::hash_iter(self.elements.iter(), vm) } - fn iter(self, _vm: &VirtualMachine) -> PyTupleIterator { + #[pymethod(name = "__iter__")] + fn iter(zelf: PyRef, _vm: &VirtualMachine) -> PyTupleIterator { PyTupleIterator { position: Cell::new(0), - tuple: self, + tuple: zelf, } } - fn len(self, _vm: &VirtualMachine) -> usize { + #[pymethod(name = "__len__")] + fn len(&self, _vm: &VirtualMachine) -> usize { self.elements.len() } - fn repr(self, vm: &VirtualMachine) -> PyResult { - let s = if let Some(_guard) = ReprGuard::enter(self.as_object()) { - let mut str_parts = Vec::with_capacity(self.elements.len()); - for elem in self.elements.iter() { + #[pymethod(name = "__repr__")] + fn repr(zelf: PyRef, vm: &VirtualMachine) -> PyResult { + let s = if let Some(_guard) = ReprGuard::enter(zelf.as_object()) { + let mut str_parts = Vec::with_capacity(zelf.elements.len()); + for elem in zelf.elements.iter() { let s = vm.to_repr(elem)?; str_parts.push(s.as_str().to_owned()); } @@ -197,22 +216,26 @@ impl PyTupleRef { Ok(s) } - fn mul(self, counter: isize, vm: &VirtualMachine) -> PyObjectRef { + #[pymethod(name = "__mul__")] + fn mul(&self, counter: isize, vm: &VirtualMachine) -> PyObjectRef { let new_elements = seq_mul(&self.elements.as_slice(), counter) .cloned() .collect(); vm.ctx.new_tuple(new_elements) } - fn rmul(self, counter: isize, vm: &VirtualMachine) -> PyObjectRef { + #[pymethod(name = "__rmul__")] + fn rmul(&self, counter: isize, vm: &VirtualMachine) -> PyObjectRef { self.mul(counter, vm) } - fn getitem(self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult { - get_item(vm, self.as_object(), &self.elements, needle.clone()) + #[pymethod(name = "__getitem__")] + fn getitem(zelf: PyRef, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult { + get_item(vm, zelf.as_object(), &zelf.elements, needle.clone()) } - fn index(self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult { + #[pymethod(name = "index")] + fn index(&self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult { for (index, element) in self.elements.iter().enumerate() { if element.is(&needle) { return Ok(index); @@ -225,7 +248,8 @@ impl PyTupleRef { Err(vm.new_value_error("tuple.index(x): x not in tuple".to_string())) } - fn contains(self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult { + #[pymethod(name = "__contains__")] + fn contains(&self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult { for element in self.elements.iter() { if element.is(&needle) { return Ok(true); @@ -237,20 +261,21 @@ impl PyTupleRef { } Ok(false) } -} -fn tuple_new( - cls: PyClassRef, - iterable: OptionalArg, - vm: &VirtualMachine, -) -> PyResult { - let elements = if let OptionalArg::Present(iterable) = iterable { - vm.extract_elements(&iterable)? - } else { - vec![] - }; + #[pyslot(new)] + fn tuple_new( + cls: PyClassRef, + iterable: OptionalArg, + vm: &VirtualMachine, + ) -> PyResult { + let elements = if let OptionalArg::Present(iterable) = iterable { + vm.extract_elements(&iterable)? + } else { + vec![] + }; - PyTuple::from(elements).into_ref_with_type(vm, cls) + PyTuple::from(elements).into_ref_with_type(vm, cls) + } } #[pyclass] @@ -288,32 +313,7 @@ impl PyTupleIterator { #[rustfmt::skip] // to avoid line splitting pub fn init(context: &PyContext) { let tuple_type = &context.types.tuple_type; - let tuple_doc = "tuple() -> empty tuple -tuple(iterable) -> tuple initialized from iterable's items - -If the argument is a tuple, the return value is the same object."; - extend_class!(context, tuple_type, { - "__add__" => context.new_rustfunc(PyTupleRef::add), - "__bool__" => context.new_rustfunc(PyTupleRef::bool), - "__eq__" => context.new_rustfunc(PyTupleRef::eq), - "__ne__" => context.new_rustfunc(PyTupleRef::ne), - "__contains__" => context.new_rustfunc(PyTupleRef::contains), - "__getitem__" => context.new_rustfunc(PyTupleRef::getitem), - "__hash__" => context.new_rustfunc(PyTupleRef::hash), - "__iter__" => context.new_rustfunc(PyTupleRef::iter), - "__len__" => context.new_rustfunc(PyTupleRef::len), - (slot new) => tuple_new, - "__mul__" => context.new_rustfunc(PyTupleRef::mul), - "__rmul__" => context.new_rustfunc(PyTupleRef::rmul), - "__repr__" => context.new_rustfunc(PyTupleRef::repr), - "count" => context.new_rustfunc(PyTupleRef::count), - "__lt__" => context.new_rustfunc(PyTupleRef::lt), - "__le__" => context.new_rustfunc(PyTupleRef::le), - "__gt__" => context.new_rustfunc(PyTupleRef::gt), - "__ge__" => context.new_rustfunc(PyTupleRef::ge), - "__doc__" => context.new_str(tuple_doc.to_string()), - "index" => context.new_rustfunc(PyTupleRef::index) - }); + PyTuple::extend_class(context, tuple_type); PyTupleIterator::extend_class(context, &context.types.tupleiterator_type); }