Refactor list slicing out to separate function
@@ -9,17 +9,9 @@ fn get_pos(l: &Vec<PyObjectRef>, p: i32) -> usize {
}
}
-pub fn get_item(vm: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -> PyResult {
- match &(b.borrow()).kind {
- PyObjectKind::Integer { value } => {
- let pos_index = 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()))
- }
- }
+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 } => {
let start = match start {
&Some(start) => get_pos(l, start),
@@ -29,10 +21,7 @@ pub fn get_item(vm: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -
&Some(stop) => get_pos(l, stop),
&None => l.len() as usize,
};
- // TODO: we could potentially avoid this copy and use slice
- Ok(PyObject::new(
- PyObjectKind::List {
- elements: match step {
+ match step {
&None | &Some(1) => l[start..stop].to_vec(),
&Some(num) => {
if num < 0 {
@@ -44,11 +33,33 @@ pub fn get_item(vm: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -
.cloned()
.collect()
}
- },
+ }
+ }
+ kind => panic!("get_slice_items called with non-slice: {:?}", kind),
+ }
+}
+
+pub fn get_item(vm: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -> PyResult {
+ match &(b.borrow()).kind {
+ PyObjectKind::Integer { value } => {
+ let pos_index = 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: get_slice_items(l, &b),
},
vm.get_type(),
- ))
- }
+ )),
_ => Err(vm.new_exception(format!(
"TypeError: indexing type {:?} with index {:?} is not supported (yet?)",
l, b
