Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Convert iterator
  • Loading branch information
OddCoincidence committed Mar 9, 2019
commit 157d18d7a155dfaa740426a68f43b0face68c203
12 changes: 7 additions & 5 deletions vm/src/obj/objbytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use std::ops::Deref;
use super::objint;
use super::objtype;
use crate::pyobject::{
PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef, PyResult,
TypeProtocol,
PyContext, PyFuncArgs, PyIteratorValue, PyObject, PyObjectPayload, PyObjectPayload2,
PyObjectRef, PyResult, TypeProtocol,
};
use crate::vm::VirtualMachine;
use num_traits::ToPrimitive;
Expand Down Expand Up @@ -209,9 +209,11 @@ fn bytes_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(obj, Some(vm.ctx.bytes_type()))]);

let iter_obj = PyObject::new(
PyObjectPayload::Iterator {
position: Cell::new(0),
iterated_obj: obj.clone(),
PyObjectPayload::AnyRustValue {
value: Box::new(PyIteratorValue {
position: Cell::new(0),
iterated_obj: obj.clone(),
}),
},
vm.ctx.iter_type(),
);
Expand Down
28 changes: 17 additions & 11 deletions vm/src/obj/objdict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use super::objiter;
use super::objstr;
use super::objtype;
use crate::pyobject::{
PyAttributes, PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef,
PyResult, TypeProtocol,
PyAttributes, PyContext, PyFuncArgs, PyIteratorValue, PyObject, PyObjectPayload,
PyObjectPayload2, PyObjectRef, PyResult, TypeProtocol,
};
use crate::vm::{ReprGuard, VirtualMachine};

Expand Down Expand Up @@ -249,9 +249,11 @@ fn dict_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let key_list = vm.ctx.new_list(keys);

let iter_obj = PyObject::new(
PyObjectPayload::Iterator {
position: Cell::new(0),
iterated_obj: key_list,
PyObjectPayload::AnyRustValue {
value: Box::new(PyIteratorValue {
position: Cell::new(0),
iterated_obj: key_list,
}),
},
vm.ctx.iter_type(),
);
Expand All @@ -269,9 +271,11 @@ fn dict_values(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let values_list = vm.ctx.new_list(values);

let iter_obj = PyObject::new(
PyObjectPayload::Iterator {
position: Cell::new(0),
iterated_obj: values_list,
PyObjectPayload::AnyRustValue {
value: Box::new(PyIteratorValue {
position: Cell::new(0),
iterated_obj: values_list,
}),
},
vm.ctx.iter_type(),
);
Expand All @@ -289,9 +293,11 @@ fn dict_items(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let items_list = vm.ctx.new_list(items);

let iter_obj = PyObject::new(
PyObjectPayload::Iterator {
position: Cell::new(0),
iterated_obj: items_list,
PyObjectPayload::AnyRustValue {
value: Box::new(PyIteratorValue {
position: Cell::new(0),
iterated_obj: items_list,
}),
},
vm.ctx.iter_type(),
);
Expand Down
6 changes: 3 additions & 3 deletions vm/src/obj/objiter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/

use crate::pyobject::{
PyContext, PyFuncArgs, PyObjectPayload, PyObjectRef, PyResult, TypeProtocol,
PyContext, PyFuncArgs, PyIteratorValue, PyObjectRef, PyResult, TypeProtocol,
};
use crate::vm::VirtualMachine;

Expand Down Expand Up @@ -128,10 +128,10 @@ fn iter_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
fn iter_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(iter, Some(vm.ctx.iter_type()))]);

if let PyObjectPayload::Iterator {
if let Some(PyIteratorValue {
ref position,
iterated_obj: ref iterated_obj_ref,
} = iter.payload
}) = iter.payload()
{
if let Some(range) = iterated_obj_ref.payload::<PyRange>() {
if let Some(int) = range.get(position.get()) {
Expand Down
12 changes: 7 additions & 5 deletions vm/src/obj/objlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use super::objstr;
use super::objtype;
use crate::function::PyRef;
use crate::pyobject::{
IdProtocol, OptionalArg, PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2,
PyObjectRef, PyResult, TypeProtocol,
IdProtocol, OptionalArg, PyContext, PyFuncArgs, PyIteratorValue, PyObject, PyObjectPayload,
PyObjectPayload2, PyObjectRef, PyResult, TypeProtocol,
};
use crate::vm::{ReprGuard, VirtualMachine};
use num_traits::ToPrimitive;
Expand Down Expand Up @@ -112,9 +112,11 @@ impl PyListRef {

fn iter(self, vm: &mut VirtualMachine) -> PyObjectRef {
PyObject::new(
PyObjectPayload::Iterator {
position: Cell::new(0),
iterated_obj: self.into_object(),
PyObjectPayload::AnyRustValue {
value: Box::new(PyIteratorValue {
position: Cell::new(0),
iterated_obj: self.into_object(),
}),
},
vm.ctx.iter_type(),
)
Expand Down
30 changes: 17 additions & 13 deletions vm/src/obj/objrange.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use num_integer::Integer;
use num_traits::{One, Signed, ToPrimitive, Zero};

use crate::pyobject::{
PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef, PyResult,
TypeProtocol,
PyContext, PyFuncArgs, PyIteratorValue, PyObject, PyObjectPayload, PyObjectPayload2,
PyObjectRef, PyResult, TypeProtocol,
};
use crate::vm::VirtualMachine;

Expand Down Expand Up @@ -240,9 +240,11 @@ fn range_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(range, Some(vm.ctx.range_type()))]);

Ok(PyObject::new(
PyObjectPayload::Iterator {
position: Cell::new(0),
iterated_obj: range.clone(),
PyObjectPayload::AnyRustValue {
value: Box::new(PyIteratorValue {
position: Cell::new(0),
iterated_obj: range.clone(),
}),
},
vm.ctx.iter_type(),
))
Expand All @@ -254,14 +256,16 @@ fn range_reversed(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let range = get_value(zelf).reversed();

Ok(PyObject::new(
PyObjectPayload::Iterator {
position: Cell::new(0),
iterated_obj: PyObject::new(
PyObjectPayload::AnyRustValue {
value: Box::new(range),
},
vm.ctx.range_type(),
),
PyObjectPayload::AnyRustValue {
value: Box::new(PyIteratorValue {
position: Cell::new(0),
iterated_obj: PyObject::new(
PyObjectPayload::AnyRustValue {
value: Box::new(range),
},
vm.ctx.range_type(),
),
}),
},
vm.ctx.iter_type(),
))
Expand Down
12 changes: 7 additions & 5 deletions vm/src/obj/objset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use super::objiter;
use super::objstr;
use super::objtype;
use crate::pyobject::{
PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef, PyResult,
TypeProtocol,
PyContext, PyFuncArgs, PyIteratorValue, PyObject, PyObjectPayload, PyObjectPayload2,
PyObjectRef, PyResult, TypeProtocol,
};
use crate::vm::{ReprGuard, VirtualMachine};

Expand Down Expand Up @@ -566,9 +566,11 @@ fn set_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let items = get_elements(zelf).values().cloned().collect();
let set_list = vm.ctx.new_list(items);
let iter_obj = PyObject::new(
PyObjectPayload::Iterator {
position: Cell::new(0),
iterated_obj: set_list,
PyObjectPayload::AnyRustValue {
value: Box::new(PyIteratorValue {
position: Cell::new(0),
iterated_obj: set_list,
}),
},
vm.ctx.iter_type(),
);
Expand Down
12 changes: 7 additions & 5 deletions vm/src/obj/objtuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::hash::{Hash, Hasher};

use crate::function::PyRef;
use crate::pyobject::{
IdProtocol, OptionalArg, PyContext, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef,
PyResult,
IdProtocol, OptionalArg, PyContext, PyIteratorValue, PyObject, PyObjectPayload,
PyObjectPayload2, PyObjectRef, PyResult,
};
use crate::vm::{ReprGuard, VirtualMachine};

Expand Down Expand Up @@ -127,9 +127,11 @@ impl PyTupleRef {

fn iter(self, vm: &mut VirtualMachine) -> PyObjectRef {
PyObject::new(
PyObjectPayload::Iterator {
position: Cell::new(0),
iterated_obj: self.into_object(),
PyObjectPayload::AnyRustValue {
value: Box::new(PyIteratorValue {
position: Cell::new(0),
iterated_obj: self.into_object(),
}),
},
vm.ctx.iter_type(),
)
Expand Down
30 changes: 14 additions & 16 deletions vm/src/pyobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,6 @@ impl fmt::Display for PyObject {
}
}

/*
// Idea: implement the iterator trait upon PyObjectRef
impl Iterator for (VirtualMachine, PyObjectRef) {
type Item = char;

fn next(&mut self) -> Option<Self::Item> {
// call method ("_next__")
}
}
*/

#[derive(Debug)]
pub struct PyContext {
pub bytes_type: PyObjectRef,
Expand Down Expand Up @@ -1496,10 +1485,6 @@ into_py_native_func_tuple!((a, A), (b, B), (c, C), (d, D), (e, E));
/// of rust data for a particular python object. Determine the python type
/// by using for example the `.typ()` method on a python object.
pub enum PyObjectPayload {
Iterator {
position: Cell<usize>,
iterated_obj: PyObjectRef,
},
Slice {
start: Option<BigInt>,
stop: Option<BigInt>,
Expand All @@ -1524,12 +1509,25 @@ impl Default for PyObjectPayload {
}
}

// TODO: This is a workaround and shouldn't exist.
// Each iterable type should have its own distinct iterator type.
#[derive(Debug)]
pub struct PyIteratorValue {
pub position: Cell<usize>,
pub iterated_obj: PyObjectRef,
}

impl PyObjectPayload2 for PyIteratorValue {
fn required_type(ctx: &PyContext) -> PyObjectRef {
ctx.iter_type()
}
}

impl fmt::Debug for PyObjectPayload {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
PyObjectPayload::MemoryView { ref obj } => write!(f, "bytes/bytearray {:?}", obj),
PyObjectPayload::WeakRef { .. } => write!(f, "weakref"),
PyObjectPayload::Iterator { .. } => write!(f, "iterator"),
PyObjectPayload::Slice { .. } => write!(f, "slice"),
PyObjectPayload::AnyRustValue { value } => value.fmt(f),
}
Expand Down