mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
7 files changed
+118
-176
No files matched your search
+21
-22
@@ -4,18 +4,20 @@ use std::ops::AddAssign;
|
||||
use num_bigint::BigInt;
|
||||
use num_traits::Zero;
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::function::{OptionalArg, PyFuncArgs};
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objint;
|
||||
use super::objint::PyIntRef;
|
||||
use super::objiter;
|
||||
use super::objtype::PyClassRef;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PyEnumerate {
|
||||
counter: RefCell<BigInt>,
|
||||
iterator: PyObjectRef,
|
||||
}
|
||||
type PyEnumerateRef = PyRef<PyEnumerate>;
|
||||
|
||||
impl PyValue for PyEnumerate {
|
||||
fn class(vm: &mut VirtualMachine) -> PyObjectRef {
|
||||
@@ -23,26 +25,23 @@ impl PyValue for PyEnumerate {
|
||||
}
|
||||
}
|
||||
|
||||
fn enumerate_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [(cls, Some(vm.ctx.type_type())), (iterable, None)],
|
||||
optional = [(start, Some(vm.ctx.int_type()))]
|
||||
);
|
||||
let counter = if let Some(x) = start {
|
||||
objint::get_value(x).clone()
|
||||
} else {
|
||||
BigInt::zero()
|
||||
fn enumerate_new(
|
||||
cls: PyClassRef,
|
||||
iterable: PyObjectRef,
|
||||
start: OptionalArg<PyIntRef>,
|
||||
vm: &mut VirtualMachine,
|
||||
) -> PyResult<PyEnumerateRef> {
|
||||
let counter = match start {
|
||||
OptionalArg::Present(start) => start.value.clone(),
|
||||
OptionalArg::Missing => BigInt::zero(),
|
||||
};
|
||||
let iterator = objiter::get_iter(vm, iterable)?;
|
||||
Ok(PyObject::new(
|
||||
PyEnumerate {
|
||||
counter: RefCell::new(counter),
|
||||
iterator,
|
||||
},
|
||||
cls.clone(),
|
||||
))
|
||||
|
||||
let iterator = objiter::get_iter(vm, &iterable)?;
|
||||
PyEnumerate {
|
||||
counter: RefCell::new(counter.clone()),
|
||||
iterator,
|
||||
}
|
||||
.into_ref_with_type(vm, cls)
|
||||
}
|
||||
|
||||
fn enumerate_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
|
||||
use crate::frame::{ExecutionResult, Frame};
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PyGenerator {
|
||||
frame: PyObjectRef,
|
||||
}
|
||||
type PyGeneratorRef = PyRef<PyGenerator>;
|
||||
|
||||
impl PyValue for PyGenerator {
|
||||
fn class(vm: &mut VirtualMachine) -> PyObjectRef {
|
||||
@@ -37,11 +38,8 @@ pub fn init(context: &PyContext) {
|
||||
);
|
||||
}
|
||||
|
||||
pub fn new_generator(vm: &mut VirtualMachine, frame: PyObjectRef) -> PyResult {
|
||||
Ok(PyObject::new(
|
||||
PyGenerator { frame },
|
||||
vm.ctx.generator_type.clone(),
|
||||
))
|
||||
pub fn new_generator(frame: PyObjectRef, vm: &mut VirtualMachine) -> PyGeneratorRef {
|
||||
PyGenerator { frame }.into_ref(vm)
|
||||
}
|
||||
|
||||
fn generator_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
@@ -119,14 +119,11 @@ impl PyListRef {
|
||||
)
|
||||
}
|
||||
|
||||
fn iter(self, vm: &mut VirtualMachine) -> PyObjectRef {
|
||||
PyObject::new(
|
||||
PyIteratorValue {
|
||||
position: Cell::new(0),
|
||||
iterated_obj: self.into_object(),
|
||||
},
|
||||
vm.ctx.iter_type(),
|
||||
)
|
||||
fn iter(self, _vm: &mut VirtualMachine) -> PyIteratorValue {
|
||||
PyIteratorValue {
|
||||
position: Cell::new(0),
|
||||
iterated_obj: self.into_object(),
|
||||
}
|
||||
}
|
||||
|
||||
fn setitem(self, key: PyObjectRef, value: PyObjectRef, vm: &mut VirtualMachine) -> PyResult {
|
||||
|
||||
+18
-21
@@ -1,14 +1,16 @@
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::function::{Args, PyFuncArgs};
|
||||
use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use super::objiter;
|
||||
use super::objtype::PyClassRef;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PyMap {
|
||||
mapper: PyObjectRef,
|
||||
iterators: Vec<PyObjectRef>,
|
||||
}
|
||||
type PyMapRef = PyRef<PyMap>;
|
||||
|
||||
impl PyValue for PyMap {
|
||||
fn class(vm: &mut VirtualMachine) -> PyObjectRef {
|
||||
@@ -16,26 +18,21 @@ impl PyValue for PyMap {
|
||||
}
|
||||
}
|
||||
|
||||
fn map_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
no_kwargs!(vm, args);
|
||||
let cls = &args.args[0];
|
||||
if args.args.len() < 3 {
|
||||
Err(vm.new_type_error("map() must have at least two arguments.".to_owned()))
|
||||
} else {
|
||||
let function = &args.args[1];
|
||||
let iterables = &args.args[2..];
|
||||
let iterators = iterables
|
||||
.iter()
|
||||
.map(|iterable| objiter::get_iter(vm, iterable))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
Ok(PyObject::new(
|
||||
PyMap {
|
||||
mapper: function.clone(),
|
||||
iterators,
|
||||
},
|
||||
cls.clone(),
|
||||
))
|
||||
fn map_new(
|
||||
cls: PyClassRef,
|
||||
function: PyObjectRef,
|
||||
iterables: Args,
|
||||
vm: &mut VirtualMachine,
|
||||
) -> PyResult<PyMapRef> {
|
||||
let iterators = iterables
|
||||
.into_iter()
|
||||
.map(|iterable| objiter::get_iter(vm, &iterable))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
PyMap {
|
||||
mapper: function.clone(),
|
||||
iterators,
|
||||
}
|
||||
.into_ref_with_type(vm, cls.clone())
|
||||
}
|
||||
|
||||
fn map_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
+59
-105
@@ -7,21 +7,22 @@ use std::collections::{hash_map::DefaultHasher, HashMap};
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::function::{OptionalArg, PyFuncArgs};
|
||||
use crate::pyobject::{
|
||||
PyContext, PyIteratorValue, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
|
||||
PyContext, PyIteratorValue, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::vm::{ReprGuard, VirtualMachine};
|
||||
|
||||
use super::objbool;
|
||||
use super::objint;
|
||||
use super::objiter;
|
||||
use super::objtype;
|
||||
use super::objtype::{self, PyClassRef};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PySet {
|
||||
elements: RefCell<HashMap<u64, PyObjectRef>>,
|
||||
}
|
||||
pub type PySetRef = PyRef<PySet>;
|
||||
|
||||
impl fmt::Debug for PySet {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
@@ -151,23 +152,20 @@ fn set_clear(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
|
||||
/* Create a new object of sub-type of set */
|
||||
fn set_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [(cls, None)],
|
||||
optional = [(iterable, None)]
|
||||
);
|
||||
|
||||
if !objtype::issubclass(cls, &vm.ctx.set_type()) {
|
||||
fn set_new(
|
||||
cls: PyClassRef,
|
||||
iterable: OptionalArg<PyObjectRef>,
|
||||
vm: &mut VirtualMachine,
|
||||
) -> PyResult<PySetRef> {
|
||||
if !objtype::issubclass(cls.as_object(), &vm.ctx.set_type()) {
|
||||
return Err(vm.new_type_error(format!("{} is not a subtype of set", cls)));
|
||||
}
|
||||
|
||||
let elements: HashMap<u64, PyObjectRef> = match iterable {
|
||||
None => HashMap::new(),
|
||||
Some(iterable) => {
|
||||
OptionalArg::Missing => HashMap::new(),
|
||||
OptionalArg::Present(iterable) => {
|
||||
let mut elements = HashMap::new();
|
||||
let iterator = objiter::get_iter(vm, iterable)?;
|
||||
let iterator = objiter::get_iter(vm, &iterable)?;
|
||||
while let Ok(v) = vm.call_method(&iterator, "__next__", vec![]) {
|
||||
insert_into_set(vm, &mut elements, &v)?;
|
||||
}
|
||||
@@ -175,12 +173,10 @@ fn set_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
};
|
||||
|
||||
Ok(PyObject::new(
|
||||
PySet {
|
||||
elements: RefCell::new(elements),
|
||||
},
|
||||
cls.clone(),
|
||||
))
|
||||
PySet {
|
||||
elements: RefCell::new(elements),
|
||||
}
|
||||
.into_ref_with_type(vm, cls)
|
||||
}
|
||||
|
||||
fn set_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
@@ -190,16 +186,12 @@ fn set_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Ok(vm.context().new_int(elements.len()))
|
||||
}
|
||||
|
||||
fn set_copy(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
trace!("set.copy called with: {:?}", args);
|
||||
arg_check!(vm, args, required = [(s, Some(vm.ctx.set_type()))]);
|
||||
let elements = get_elements(s);
|
||||
Ok(PyObject::new(
|
||||
PySet {
|
||||
elements: RefCell::new(elements),
|
||||
},
|
||||
vm.ctx.set_type(),
|
||||
))
|
||||
fn set_copy(obj: PySetRef, _vm: &mut VirtualMachine) -> PySet {
|
||||
trace!("set.copy called with: {:?}", obj);
|
||||
let elements = obj.elements.borrow().clone();
|
||||
PySet {
|
||||
elements: RefCell::new(elements),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
@@ -335,67 +327,47 @@ fn set_compare_inner(
|
||||
Ok(vm.new_bool(true))
|
||||
}
|
||||
|
||||
fn set_union(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [
|
||||
(zelf, Some(vm.ctx.set_type())),
|
||||
(other, Some(vm.ctx.set_type()))
|
||||
]
|
||||
);
|
||||
fn set_union(zelf: PySetRef, other: PySetRef, _vm: &mut VirtualMachine) -> PySet {
|
||||
let mut elements = zelf.elements.borrow().clone();
|
||||
elements.extend(other.elements.borrow().clone());
|
||||
|
||||
let mut elements = get_elements(zelf).clone();
|
||||
elements.extend(get_elements(other).clone());
|
||||
|
||||
Ok(PyObject::new(
|
||||
PySet {
|
||||
elements: RefCell::new(elements),
|
||||
},
|
||||
vm.ctx.set_type(),
|
||||
))
|
||||
PySet {
|
||||
elements: RefCell::new(elements),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_intersection(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
set_combine_inner(vm, args, SetCombineOperation::Intersection)
|
||||
fn set_intersection(zelf: PySetRef, other: PySetRef, vm: &mut VirtualMachine) -> PyResult<PySet> {
|
||||
set_combine_inner(zelf, other, vm, SetCombineOperation::Intersection)
|
||||
}
|
||||
|
||||
fn set_difference(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
set_combine_inner(vm, args, SetCombineOperation::Difference)
|
||||
fn set_difference(zelf: PySetRef, other: PySetRef, vm: &mut VirtualMachine) -> PyResult<PySet> {
|
||||
set_combine_inner(zelf, other, vm, SetCombineOperation::Difference)
|
||||
}
|
||||
|
||||
fn set_symmetric_difference(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [
|
||||
(zelf, Some(vm.ctx.set_type())),
|
||||
(other, Some(vm.ctx.set_type()))
|
||||
]
|
||||
);
|
||||
|
||||
fn set_symmetric_difference(
|
||||
zelf: PySetRef,
|
||||
other: PySetRef,
|
||||
vm: &mut VirtualMachine,
|
||||
) -> PyResult<PySet> {
|
||||
let mut elements = HashMap::new();
|
||||
|
||||
for element in get_elements(zelf).iter() {
|
||||
let value = vm.call_method(other, "__contains__", vec![element.1.clone()])?;
|
||||
for element in zelf.elements.borrow().iter() {
|
||||
let value = vm.call_method(other.as_object(), "__contains__", vec![element.1.clone()])?;
|
||||
if !objbool::get_value(&value) {
|
||||
elements.insert(element.0.clone(), element.1.clone());
|
||||
}
|
||||
}
|
||||
|
||||
for element in get_elements(other).iter() {
|
||||
let value = vm.call_method(zelf, "__contains__", vec![element.1.clone()])?;
|
||||
for element in other.elements.borrow().iter() {
|
||||
let value = vm.call_method(zelf.as_object(), "__contains__", vec![element.1.clone()])?;
|
||||
if !objbool::get_value(&value) {
|
||||
elements.insert(element.0.clone(), element.1.clone());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(PyObject::new(
|
||||
PySet {
|
||||
elements: RefCell::new(elements),
|
||||
},
|
||||
vm.ctx.set_type(),
|
||||
))
|
||||
Ok(PySet {
|
||||
elements: RefCell::new(elements),
|
||||
})
|
||||
}
|
||||
|
||||
enum SetCombineOperation {
|
||||
@@ -404,23 +376,15 @@ enum SetCombineOperation {
|
||||
}
|
||||
|
||||
fn set_combine_inner(
|
||||
zelf: PySetRef,
|
||||
other: PySetRef,
|
||||
vm: &mut VirtualMachine,
|
||||
args: PyFuncArgs,
|
||||
op: SetCombineOperation,
|
||||
) -> PyResult {
|
||||
arg_check!(
|
||||
vm,
|
||||
args,
|
||||
required = [
|
||||
(zelf, Some(vm.ctx.set_type())),
|
||||
(other, Some(vm.ctx.set_type()))
|
||||
]
|
||||
);
|
||||
|
||||
) -> PyResult<PySet> {
|
||||
let mut elements = HashMap::new();
|
||||
|
||||
for element in get_elements(zelf).iter() {
|
||||
let value = vm.call_method(other, "__contains__", vec![element.1.clone()])?;
|
||||
for element in zelf.elements.borrow().iter() {
|
||||
let value = vm.call_method(other.as_object(), "__contains__", vec![element.1.clone()])?;
|
||||
let should_add = match op {
|
||||
SetCombineOperation::Intersection => objbool::get_value(&value),
|
||||
SetCombineOperation::Difference => !objbool::get_value(&value),
|
||||
@@ -430,12 +394,9 @@ fn set_combine_inner(
|
||||
}
|
||||
}
|
||||
|
||||
Ok(PyObject::new(
|
||||
PySet {
|
||||
elements: RefCell::new(elements),
|
||||
},
|
||||
vm.ctx.set_type(),
|
||||
))
|
||||
Ok(PySet {
|
||||
elements: RefCell::new(elements),
|
||||
})
|
||||
}
|
||||
|
||||
fn set_pop(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
@@ -557,20 +518,13 @@ fn set_ixor(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
Ok(zelf.clone())
|
||||
}
|
||||
|
||||
fn set_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(zelf, Some(vm.ctx.set_type()))]);
|
||||
|
||||
let items = get_elements(zelf).values().cloned().collect();
|
||||
fn set_iter(zelf: PySetRef, vm: &mut VirtualMachine) -> PyIteratorValue {
|
||||
let items = zelf.elements.borrow().values().cloned().collect();
|
||||
let set_list = vm.ctx.new_list(items);
|
||||
let iter_obj = PyObject::new(
|
||||
PyIteratorValue {
|
||||
position: Cell::new(0),
|
||||
iterated_obj: set_list,
|
||||
},
|
||||
vm.ctx.iter_type(),
|
||||
);
|
||||
|
||||
Ok(iter_obj)
|
||||
PyIteratorValue {
|
||||
position: Cell::new(0),
|
||||
iterated_obj: set_list,
|
||||
}
|
||||
}
|
||||
|
||||
fn frozenset_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
+10
-13
@@ -4,7 +4,7 @@ use std::hash::{Hash, Hasher};
|
||||
|
||||
use crate::function::OptionalArg;
|
||||
use crate::pyobject::{
|
||||
IdProtocol, PyContext, PyIteratorValue, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
IdProtocol, PyContext, PyIteratorValue, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
};
|
||||
use crate::vm::{ReprGuard, VirtualMachine};
|
||||
|
||||
@@ -13,7 +13,7 @@ use super::objint;
|
||||
use super::objsequence::{
|
||||
get_elements, get_item, seq_equal, seq_ge, seq_gt, seq_le, seq_lt, seq_mul,
|
||||
};
|
||||
use super::objtype;
|
||||
use super::objtype::{self, PyClassRef};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PyTuple {
|
||||
@@ -132,14 +132,11 @@ impl PyTupleRef {
|
||||
Ok(hasher.finish())
|
||||
}
|
||||
|
||||
fn iter(self, vm: &mut VirtualMachine) -> PyObjectRef {
|
||||
PyObject::new(
|
||||
PyIteratorValue {
|
||||
position: Cell::new(0),
|
||||
iterated_obj: self.into_object(),
|
||||
},
|
||||
vm.ctx.iter_type(),
|
||||
)
|
||||
fn iter(self, _vm: &mut VirtualMachine) -> PyIteratorValue {
|
||||
PyIteratorValue {
|
||||
position: Cell::new(0),
|
||||
iterated_obj: self.into_object(),
|
||||
}
|
||||
}
|
||||
|
||||
fn len(self, _vm: &mut VirtualMachine) -> usize {
|
||||
@@ -207,10 +204,10 @@ impl PyTupleRef {
|
||||
}
|
||||
|
||||
fn tuple_new(
|
||||
cls: PyRef<objtype::PyClass>,
|
||||
cls: PyClassRef,
|
||||
iterable: OptionalArg<PyObjectRef>,
|
||||
vm: &mut VirtualMachine,
|
||||
) -> PyResult {
|
||||
) -> PyResult<PyTupleRef> {
|
||||
if !objtype::issubclass(cls.as_object(), &vm.ctx.tuple_type()) {
|
||||
return Err(vm.new_type_error(format!("{} is not a subtype of tuple", cls)));
|
||||
}
|
||||
@@ -221,7 +218,7 @@ fn tuple_new(
|
||||
vec![]
|
||||
};
|
||||
|
||||
Ok(PyObject::new(PyTuple::from(elements), cls.into_object()))
|
||||
PyTuple::from(elements).into_ref_with_type(vm, cls)
|
||||
}
|
||||
|
||||
#[rustfmt::skip] // to avoid line splitting
|
||||
|
||||
+1
-1
@@ -353,7 +353,7 @@ impl VirtualMachine {
|
||||
|
||||
// If we have a generator, create a new generator
|
||||
if code_object.is_generator {
|
||||
objgenerator::new_generator(self, frame)
|
||||
Ok(objgenerator::new_generator(frame, self).into_object())
|
||||
} else {
|
||||
self.run_frame_full(frame)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user