Refactor shared list/tuple functions to objsequence.rs

This commit is contained in:
Daniel Watkins
2018-08-06 15:08:45 -04:00
parent 5dad8b2c54
commit da55a6addb
4 changed files with 45 additions and 43 deletions

View File

@@ -14,6 +14,7 @@ mod import;
mod objdict;
mod objint;
mod objlist;
mod objsequence;
mod objstr;
mod objtuple;
mod objtype;

View File

@@ -1,48 +1,10 @@
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 {
p as usize
}
}
pub 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),
&None => 0,
};
let stop = match stop {
&Some(stop) => get_pos(l, stop),
&None => l.len() as usize,
};
match step {
&None | &Some(1) => l[start..stop].to_vec(),
&Some(num) => {
if num < 0 {
unimplemented!("negative step indexing not yet supported")
};
l[start..stop]
.iter()
.step_by(num as usize)
.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);
let pos_index = super::objsequence::get_pos(l, *value);
if pos_index < l.len() {
let obj = l[pos_index].clone();
Ok(obj)
@@ -56,7 +18,7 @@ pub fn get_item(vm: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -
step: _,
} => Ok(PyObject::new(
PyObjectKind::List {
elements: get_slice_items(l, &b),
elements: super::objsequence::get_slice_items(l, &b),
},
vm.get_type(),
)),
@@ -76,7 +38,7 @@ pub fn set_item(
) -> PyResult {
match &(idx.borrow()).kind {
PyObjectKind::Integer { value } => {
let pos_index = get_pos(l, *value);
let pos_index = super::objsequence::get_pos(l, *value);
l[pos_index] = obj;
Ok(vm.get_none())
}

39
vm/src/objsequence.rs Normal file
View File

@@ -0,0 +1,39 @@
use super::pyobject::{PyObject, PyObjectKind, PyObjectRef, PyResult};
pub fn get_pos(l: &Vec<PyObjectRef>, p: i32) -> usize {
if p < 0 {
l.len() - ((-p) as usize)
} else {
p as usize
}
}
pub 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),
&None => 0,
};
let stop = match stop {
&Some(stop) => get_pos(l, stop),
&None => l.len() as usize,
};
match step {
&None | &Some(1) => l[start..stop].to_vec(),
&Some(num) => {
if num < 0 {
unimplemented!("negative step indexing not yet supported")
};
l[start..stop]
.iter()
.step_by(num as usize)
.cloned()
.collect()
}
}
}
kind => panic!("get_slice_items called with non-slice: {:?}", kind),
}
}

View File

@@ -4,7 +4,7 @@ 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::objlist::get_pos(l, *value);
let pos_index = super::objsequence::get_pos(l, *value);
if pos_index < l.len() {
let obj = l[pos_index].clone();
Ok(obj)
@@ -18,7 +18,7 @@ pub fn get_item(vm: &mut VirtualMachine, l: &Vec<PyObjectRef>, b: PyObjectRef) -
step: _,
} => Ok(PyObject::new(
PyObjectKind::Tuple {
elements: super::objlist::get_slice_items(l, &b),
elements: super::objsequence::get_slice_items(l, &b),
},
vm.get_type(),
)),