mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
Merge pull request #48 from OddBloke/slice
Complete unification of tuple and list implementations
This commit is contained in:
@@ -8,6 +8,7 @@ assert squares == squares[:]
|
||||
assert [1, 9, 25] == squares[::2]
|
||||
assert [4, 16] == squares[1::2]
|
||||
assert [4] == squares[1:2:2]
|
||||
assert [25] == squares[4:100]
|
||||
|
||||
squares_tuple = (1, 4, 9, 16, 25)
|
||||
|
||||
@@ -19,3 +20,4 @@ assert squares_tuple == squares_tuple[:]
|
||||
assert (1, 9, 25) == squares_tuple[::2]
|
||||
assert (4, 16) == squares_tuple[1::2]
|
||||
assert (4,) == squares_tuple[1:2:2]
|
||||
assert (25,) == squares_tuple[4:100]
|
||||
|
||||
@@ -16,7 +16,6 @@ mod objint;
|
||||
mod objlist;
|
||||
mod objsequence;
|
||||
mod objstr;
|
||||
mod objtuple;
|
||||
mod objtype;
|
||||
mod objbool;
|
||||
pub mod pyobject;
|
||||
|
||||
@@ -1,34 +1,6 @@
|
||||
use super::pyobject::{PyObject, PyObjectKind, PyObjectRef, PyResult};
|
||||
use super::vm::VirtualMachine;
|
||||
|
||||
pub fn get_item(vm: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -> PyResult {
|
||||
match &(b.borrow()).kind {
|
||||
PyObjectKind::Integer { value } => {
|
||||
let pos_index = super::objsequence::get_pos(l, *value);
|
||||
if pos_index < l.len() {
|
||||
let obj = l[pos_index].clone();
|
||||
Ok(obj)
|
||||
} else {
|
||||
Err(vm.new_exception("Index out of bounds!".to_string()))
|
||||
}
|
||||
}
|
||||
PyObjectKind::Slice {
|
||||
start: _,
|
||||
stop: _,
|
||||
step: _,
|
||||
} => Ok(PyObject::new(
|
||||
PyObjectKind::List {
|
||||
elements: super::objsequence::get_slice_items(l, &b),
|
||||
},
|
||||
vm.get_type(),
|
||||
)),
|
||||
_ => Err(vm.new_exception(format!(
|
||||
"TypeError: indexing type {:?} with index {:?} is not supported (yet?)",
|
||||
l, b
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
// set_item:
|
||||
pub fn set_item(
|
||||
vm: &mut VirtualMachine,
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
use super::pyobject::{PyObject, PyObjectKind, PyObjectRef, PyResult};
|
||||
use super::vm::VirtualMachine;
|
||||
|
||||
pub fn get_pos(l: &Vec<PyObjectRef>, p: i32) -> usize {
|
||||
if p < 0 {
|
||||
l.len() - ((-p) as usize)
|
||||
} else if p as usize > l.len() {
|
||||
// This is for the slicing case where the end element is greater than the length of the
|
||||
// sequence
|
||||
l.len()
|
||||
} else {
|
||||
p as usize
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_slice_items(l: &Vec<PyObjectRef>, slice: &PyObjectRef) -> Vec<PyObjectRef> {
|
||||
fn get_slice_items(l: &Vec<PyObjectRef>, slice: &PyObjectRef) -> Vec<PyObjectRef> {
|
||||
// TODO: we could potentially avoid this copy and use slice
|
||||
match &(slice.borrow()).kind {
|
||||
PyObjectKind::Slice { start, stop, step } => {
|
||||
@@ -37,3 +42,42 @@ pub fn get_slice_items(l: &Vec<PyObjectRef>, slice: &PyObjectRef) -> Vec<PyObjec
|
||||
kind => panic!("get_slice_items called with non-slice: {:?}", kind),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_item(
|
||||
vm: &mut VirtualMachine,
|
||||
sequence: &PyObjectRef,
|
||||
elements: &Vec<PyObjectRef>,
|
||||
subscript: PyObjectRef,
|
||||
) -> PyResult {
|
||||
match &(subscript.borrow()).kind {
|
||||
PyObjectKind::Integer { value } => {
|
||||
let pos_index = get_pos(elements, *value);
|
||||
if pos_index < elements.len() {
|
||||
let obj = elements[pos_index].clone();
|
||||
Ok(obj)
|
||||
} else {
|
||||
Err(vm.new_exception("Index out of bounds!".to_string()))
|
||||
}
|
||||
}
|
||||
PyObjectKind::Slice {
|
||||
start: _,
|
||||
stop: _,
|
||||
step: _,
|
||||
} => Ok(PyObject::new(
|
||||
match &(sequence.borrow()).kind {
|
||||
PyObjectKind::Tuple { elements: _ } => PyObjectKind::Tuple {
|
||||
elements: get_slice_items(elements, &subscript),
|
||||
},
|
||||
PyObjectKind::List { elements: _ } => PyObjectKind::List {
|
||||
elements: get_slice_items(elements, &subscript),
|
||||
},
|
||||
ref kind => panic!("sequence get_item called for non-sequence: {:?}", kind),
|
||||
},
|
||||
vm.get_type(),
|
||||
)),
|
||||
_ => Err(vm.new_exception(format!(
|
||||
"TypeError: indexing type {:?} with index {:?} is not supported (yet?)",
|
||||
sequence, subscript
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ fn str_pos(s: &String, p: i32) -> usize {
|
||||
if p < 0 {
|
||||
s.len() - ((-p) as usize)
|
||||
} else if p as usize > s.len() {
|
||||
// This is for the slicing case where the end element is greater than the length of the
|
||||
// string
|
||||
s.len()
|
||||
} else {
|
||||
p as usize
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
use super::pyobject::{PyObject, PyObjectKind, PyObjectRef, PyResult};
|
||||
use super::vm::VirtualMachine;
|
||||
|
||||
pub fn get_item(vm: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -> PyResult {
|
||||
match &(b.borrow()).kind {
|
||||
PyObjectKind::Integer { value } => {
|
||||
let pos_index = super::objsequence::get_pos(l, *value);
|
||||
if pos_index < l.len() {
|
||||
let obj = l[pos_index].clone();
|
||||
Ok(obj)
|
||||
} else {
|
||||
Err(vm.new_exception("Index out of bounds!".to_string()))
|
||||
}
|
||||
}
|
||||
PyObjectKind::Slice {
|
||||
start: _,
|
||||
stop: _,
|
||||
step: _,
|
||||
} => Ok(PyObject::new(
|
||||
PyObjectKind::Tuple {
|
||||
elements: super::objsequence::get_slice_items(l, &b),
|
||||
},
|
||||
vm.get_type(),
|
||||
)),
|
||||
_ => Err(vm.new_exception(format!(
|
||||
"TypeError: indexing type {:?} with index {:?} is not supported (yet?)",
|
||||
l, b
|
||||
))),
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,6 @@ use super::frame::{Block, Frame, copy_code};
|
||||
use super::import::import;
|
||||
use super::objlist;
|
||||
use super::objstr;
|
||||
use super::objtuple;
|
||||
use super::pyobject::{
|
||||
DictProtocol, IdProtocol, ParentProtocol, PyContext, PyFuncArgs, PyObject, PyObjectKind,
|
||||
PyObjectRef, PyResult,
|
||||
@@ -238,8 +237,9 @@ impl VirtualMachine {
|
||||
let a2 = &*a.borrow();
|
||||
match &a2.kind {
|
||||
PyObjectKind::String { ref value } => objstr::subscript(self, value, b),
|
||||
PyObjectKind::List { ref elements } => objlist::get_item(self, elements, b),
|
||||
PyObjectKind::Tuple { ref elements } => objtuple::get_item(self, elements, b),
|
||||
PyObjectKind::List { ref elements } | PyObjectKind::Tuple { ref elements } => {
|
||||
super::objsequence::get_item(self, &a, elements, b)
|
||||
}
|
||||
_ => Err(self.new_exception(format!(
|
||||
"TypeError: indexing type {:?} with index {:?} is not supported (yet?)",
|
||||
a, b
|
||||
|
||||
Reference in New Issue
Block a user