mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
...
This commit is contained in:
parent
a7ee33c2e3
commit
0912e88ac7
40
src/ceval.h
40
src/ceval.h
@ -408,22 +408,15 @@ __NEXT_STEP:;
|
||||
/*****************************************/
|
||||
TARGET(GET_ITER)
|
||||
TOP() = asIter(TOP());
|
||||
check_type(TOP(), tp_iterator);
|
||||
DISPATCH();
|
||||
TARGET(FOR_ITER) {
|
||||
#if DEBUG_EXTRA_CHECK
|
||||
BaseIter* it = PyIter_AS_C(TOP());
|
||||
#else
|
||||
BaseIter* it = _PyIter_AS_C(TOP());
|
||||
#endif
|
||||
PyObject* obj = it->next();
|
||||
if(obj != StopIteration){
|
||||
PUSH(obj);
|
||||
TARGET(FOR_ITER)
|
||||
_0 = PyIterNext(TOP());
|
||||
if(_0 != StopIteration){
|
||||
PUSH(_0);
|
||||
}else{
|
||||
int target = co_blocks[byte.block].end;
|
||||
frame->jump_abs_break(target);
|
||||
frame->jump_abs_break(co_blocks[byte.block].end);
|
||||
}
|
||||
} DISPATCH();
|
||||
DISPATCH();
|
||||
/*****************************************/
|
||||
TARGET(IMPORT_NAME) {
|
||||
StrName name(byte.arg);
|
||||
@ -459,12 +452,10 @@ __NEXT_STEP:;
|
||||
/*****************************************/
|
||||
TARGET(UNPACK_SEQUENCE)
|
||||
TARGET(UNPACK_EX) {
|
||||
// asIter or iter->next may run bytecode, accidential gc may happen
|
||||
auto _lock = heap.gc_scope_lock(); // lock the gc via RAII!!
|
||||
PyObject* obj = asIter(POPX());
|
||||
BaseIter* iter = PyIter_AS_C(obj);
|
||||
PyObject* iter = asIter(POPX());
|
||||
for(int i=0; i<byte.arg; i++){
|
||||
PyObject* item = iter->next();
|
||||
PyObject* item = PyIterNext(iter);
|
||||
if(item == StopIteration) ValueError("not enough values to unpack");
|
||||
PUSH(item);
|
||||
}
|
||||
@ -472,23 +463,22 @@ __NEXT_STEP:;
|
||||
if(byte.op == OP_UNPACK_EX){
|
||||
List extras;
|
||||
while(true){
|
||||
PyObject* item = iter->next();
|
||||
PyObject* item = PyIterNext(iter);
|
||||
if(item == StopIteration) break;
|
||||
extras.push_back(item);
|
||||
}
|
||||
PUSH(VAR(extras));
|
||||
}else{
|
||||
if(iter->next() != StopIteration) ValueError("too many values to unpack");
|
||||
if(PyIterNext(iter) != StopIteration) ValueError("too many values to unpack");
|
||||
}
|
||||
} DISPATCH();
|
||||
TARGET(UNPACK_UNLIMITED) {
|
||||
auto _lock = heap.gc_scope_lock(); // lock the gc via RAII!!
|
||||
PyObject* obj = asIter(POPX());
|
||||
BaseIter* iter = PyIter_AS_C(obj);
|
||||
obj = iter->next();
|
||||
while(obj != StopIteration){
|
||||
PUSH(obj);
|
||||
obj = iter->next();
|
||||
PyObject* iter = asIter(POPX());
|
||||
_0 = PyIterNext(iter);
|
||||
while(_0 != StopIteration){
|
||||
PUSH(_0);
|
||||
_0 = PyIterNext(iter);
|
||||
}
|
||||
} DISPATCH();
|
||||
/*****************************************/
|
||||
|
@ -166,8 +166,7 @@ inline void init_builtins(VM* _vm) {
|
||||
});
|
||||
|
||||
_vm->bind_builtin_func<1>("next", [](VM* vm, ArgsView args) {
|
||||
BaseIter* iter = vm->PyIter_AS_C(args[0]);
|
||||
return iter->next();
|
||||
return vm->PyIterNext(args[0]);
|
||||
});
|
||||
|
||||
_vm->bind_builtin_func<1>("dir", [](VM* vm, ArgsView args) {
|
||||
|
@ -383,6 +383,7 @@ const StrName __class__ = StrName::get("__class__");
|
||||
const StrName __base__ = StrName::get("__base__");
|
||||
const StrName __new__ = StrName::get("__new__");
|
||||
const StrName __iter__ = StrName::get("__iter__");
|
||||
const StrName __next__ = StrName::get("__next__");
|
||||
const StrName __str__ = StrName::get("__str__");
|
||||
const StrName __repr__ = StrName::get("__repr__");
|
||||
const StrName __getitem__ = StrName::get("__getitem__");
|
||||
|
15
src/vm.h
15
src/vm.h
@ -321,15 +321,12 @@ public:
|
||||
return heap.gcnew<P>(tp_iterator, std::forward<P>(value));
|
||||
}
|
||||
|
||||
BaseIter* PyIter_AS_C(PyObject* obj)
|
||||
{
|
||||
check_type(obj, tp_iterator);
|
||||
return static_cast<BaseIter*>(obj->value());
|
||||
}
|
||||
|
||||
BaseIter* _PyIter_AS_C(PyObject* obj)
|
||||
{
|
||||
return static_cast<BaseIter*>(obj->value());
|
||||
PyObject* PyIterNext(PyObject* obj){
|
||||
if(is_non_tagged_type(obj, tp_iterator)){
|
||||
BaseIter* iter = static_cast<BaseIter*>(obj->value());
|
||||
return iter->next();
|
||||
}
|
||||
return call_method(obj, __next__);
|
||||
}
|
||||
|
||||
/***** Error Reporter *****/
|
||||
|
@ -10,3 +10,29 @@ while True:
|
||||
total += obj
|
||||
|
||||
assert total == 6
|
||||
|
||||
class Task:
|
||||
def __init__(self, n):
|
||||
self.n = n
|
||||
|
||||
def __iter__(self):
|
||||
self.i = 0
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if self.i == self.n:
|
||||
return StopIteration
|
||||
self.i += 1
|
||||
return self.i
|
||||
|
||||
a = Task(3)
|
||||
assert sum(a) == 6
|
||||
|
||||
i = iter(Task(5))
|
||||
assert next(i) == 1
|
||||
assert next(i) == 2
|
||||
assert next(i) == 3
|
||||
assert next(i) == 4
|
||||
assert next(i) == 5
|
||||
assert next(i) == StopIteration
|
||||
assert next(i) == StopIteration
|
||||
|
Loading…
x
Reference in New Issue
Block a user