From 2fac9bad7178bd5f9576a54c5aa8b73a4ce06dc2 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Thu, 10 Oct 2019 00:52:49 +0900 Subject: [PATCH] Refactor sequence item comparison --- vm/src/obj/objsequence.rs | 88 ++++++++++----------------------------- vm/src/obj/objslice.rs | 42 +++++++------------ vm/src/vm.rs | 22 +++++++--- 3 files changed, 52 insertions(+), 100 deletions(-) diff --git a/vm/src/obj/objsequence.rs b/vm/src/obj/objsequence.rs index f7f7c7d56f..accb284c20 100644 --- a/vm/src/obj/objsequence.rs +++ b/vm/src/obj/objsequence.rs @@ -10,7 +10,6 @@ use crate::vm::VirtualMachine; use num_bigint::{BigInt, ToBigInt}; use num_traits::{One, Signed, ToPrimitive, Zero}; -use super::objbool; use super::objint::{PyInt, PyIntRef}; use super::objlist::PyList; use super::objslice::{PySlice, PySliceRef}; @@ -285,15 +284,14 @@ pub fn seq_equal( vm: &VirtualMachine, zelf: &dyn SimpleSeq, other: &dyn SimpleSeq, -) -> Result { +) -> PyResult { if zelf.len() == other.len() { for (a, b) in Iterator::zip(zelf.iter(), other.iter()) { - if !a.is(b) { - let eq = vm._eq(a.clone(), b.clone())?; - let value = objbool::boolval(vm, eq)?; - if !value { - return Ok(false); - } + if a.is(b) { + continue; + } + if !vm.bool_eq(a.clone(), b.clone())? { + return Ok(false); } } Ok(true) @@ -302,84 +300,42 @@ pub fn seq_equal( } } -pub fn seq_lt( - vm: &VirtualMachine, - zelf: &dyn SimpleSeq, - other: &dyn SimpleSeq, -) -> Result { +pub fn seq_lt(vm: &VirtualMachine, zelf: &dyn SimpleSeq, other: &dyn SimpleSeq) -> PyResult { for (a, b) in Iterator::zip(zelf.iter(), other.iter()) { - if vm.bool_lt(a.clone(), b.clone())? { - return Ok(true); - } else if !vm.bool_eq(a.clone(), b.clone())? { - return Ok(false); + if let Some(v) = vm.bool_seq_lt(a.clone(), b.clone())? { + return Ok(v); } } - - if zelf.len() == other.len() { - Ok(false) - } else { - Ok(zelf.len() < other.len()) - } + Ok(zelf.len() < other.len()) } -pub fn seq_gt( - vm: &VirtualMachine, - zelf: &dyn SimpleSeq, - other: &dyn SimpleSeq, -) -> Result { +pub fn seq_gt(vm: &VirtualMachine, zelf: &dyn SimpleSeq, other: &dyn SimpleSeq) -> PyResult { for (a, b) in Iterator::zip(zelf.iter(), other.iter()) { - if vm.bool_gt(a.clone(), b.clone())? { - return Ok(true); - } else if !vm.bool_eq(a.clone(), b.clone())? { - return Ok(false); + if let Some(v) = vm.bool_seq_gt(a.clone(), b.clone())? { + return Ok(v); } } - - if zelf.len() == other.len() { - Ok(false) - } else { - Ok(zelf.len() > other.len()) - } + Ok(zelf.len() > other.len()) } -pub fn seq_ge( - vm: &VirtualMachine, - zelf: &dyn SimpleSeq, - other: &dyn SimpleSeq, -) -> Result { +pub fn seq_ge(vm: &VirtualMachine, zelf: &dyn SimpleSeq, other: &dyn SimpleSeq) -> PyResult { for (a, b) in Iterator::zip(zelf.iter(), other.iter()) { - if vm.bool_gt(a.clone(), b.clone())? { - return Ok(true); - } else if !vm.bool_eq(a.clone(), b.clone())? { - return Ok(false); + if let Some(v) = vm.bool_seq_gt(a.clone(), b.clone())? { + return Ok(v); } } - if zelf.len() == other.len() { - Ok(true) - } else { - Ok(zelf.len() > other.len()) - } + Ok(zelf.len() >= other.len()) } -pub fn seq_le( - vm: &VirtualMachine, - zelf: &dyn SimpleSeq, - other: &dyn SimpleSeq, -) -> Result { +pub fn seq_le(vm: &VirtualMachine, zelf: &dyn SimpleSeq, other: &dyn SimpleSeq) -> PyResult { for (a, b) in Iterator::zip(zelf.iter(), other.iter()) { - if vm.bool_lt(a.clone(), b.clone())? { - return Ok(true); - } else if !vm.bool_eq(a.clone(), b.clone())? { - return Ok(false); + if let Some(v) = vm.bool_seq_lt(a.clone(), b.clone())? { + return Ok(v); } } - if zelf.len() == other.len() { - Ok(true) - } else { - Ok(zelf.len() < other.len()) - } + Ok(zelf.len() <= other.len()) } pub struct SeqMul<'a> { diff --git a/vm/src/obj/objslice.rs b/vm/src/obj/objslice.rs index e1f2064698..c292cc93d2 100644 --- a/vm/src/obj/objslice.rs +++ b/vm/src/obj/objslice.rs @@ -129,44 +129,30 @@ impl PySlice { Ok(true) } + #[inline] fn inner_lte(&self, other: &PySlice, eq: bool, vm: &VirtualMachine) -> PyResult { - if vm.bool_lt(self.start(vm), other.start(vm))? { - return Ok(true); - } else if !vm.bool_eq(self.start(vm), other.start(vm))? { - return Ok(false); + if let Some(v) = vm.bool_seq_lt(self.start(vm), other.start(vm))? { + return Ok(v); } - - if vm.bool_lt(self.stop(vm), other.stop(vm))? { - return Ok(true); - } else if !vm.bool_eq(self.stop(vm), other.stop(vm))? { - return Ok(false); + if let Some(v) = vm.bool_seq_lt(self.stop(vm), other.stop(vm))? { + return Ok(v); } - - if vm.bool_lt(self.step(vm), other.step(vm))? { - return Ok(true); - } else if !vm.bool_eq(self.step(vm), other.step(vm))? { - return Ok(false); + if let Some(v) = vm.bool_seq_lt(self.step(vm), other.step(vm))? { + return Ok(v); } Ok(eq) } + #[inline] fn inner_gte(&self, other: &PySlice, eq: bool, vm: &VirtualMachine) -> PyResult { - if vm.bool_gt(self.start(vm), other.start(vm))? { - return Ok(true); - } else if !vm.bool_eq(self.start(vm), other.start(vm))? { - return Ok(false); + if let Some(v) = vm.bool_seq_gt(self.start(vm), other.start(vm))? { + return Ok(v); } - - if vm.bool_gt(self.stop(vm), other.stop(vm))? { - return Ok(true); - } else if !vm.bool_eq(self.stop(vm), other.stop(vm))? { - return Ok(false); + if let Some(v) = vm.bool_seq_gt(self.stop(vm), other.stop(vm))? { + return Ok(v); } - - if vm.bool_gt(self.step(vm), other.step(vm))? { - return Ok(true); - } else if !vm.bool_eq(self.step(vm), other.step(vm))? { - return Ok(false); + if let Some(v) = vm.bool_seq_gt(self.step(vm), other.step(vm))? { + return Ok(v); } Ok(eq) } diff --git a/vm/src/vm.rs b/vm/src/vm.rs index ba854e8c6c..852a883b92 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -1272,15 +1272,25 @@ impl VirtualMachine { Ok(value) } - pub fn bool_lt(&self, a: PyObjectRef, b: PyObjectRef) -> PyResult { - let lt = self._lt(a.clone(), b.clone())?; - let value = objbool::boolval(self, lt)?; + pub fn bool_seq_lt(&self, a: PyObjectRef, b: PyObjectRef) -> PyResult> { + let value = if objbool::boolval(self, self._lt(a.clone(), b.clone())?)? { + Some(true) + } else if !objbool::boolval(self, self._eq(a.clone(), b.clone())?)? { + Some(false) + } else { + None + }; Ok(value) } - pub fn bool_gt(&self, a: PyObjectRef, b: PyObjectRef) -> PyResult { - let gt = self._gt(a.clone(), b.clone())?; - let value = objbool::boolval(self, gt)?; + pub fn bool_seq_gt(&self, a: PyObjectRef, b: PyObjectRef) -> PyResult> { + let value = if objbool::boolval(self, self._gt(a.clone(), b.clone())?)? { + Some(true) + } else if !objbool::boolval(self, self._eq(a.clone(), b.clone())?)? { + Some(false) + } else { + None + }; Ok(value) } }