make for loop support compound pointer

Update pocketpy.h
This commit is contained in:
blueloveTH 2022-11-08 17:37:09 +08:00
parent d4d312fc36
commit 5761d0b69c
4 changed files with 20 additions and 16 deletions

View File

@ -628,17 +628,18 @@ public:
}
void compileForStatement() {
consume(TK("@id"));
int iterIndex = getCode()->addName(
parser->previous.str(),
codes.size()>1 ? NAME_LOCAL : NAME_GLOBAL
);
int size = 0;
do {
consume(TK("@id"));
exprName(); // push a name ptr into stack
size++;
} while (match(TK(",")));
if(size > 1) emitCode(OP_BUILD_SMART_TUPLE, size);
consume(TK("in"));
EXPR_TUPLE();
emitCode(OP_GET_ITER);
emitCode(OP_GET_ITER); // [ptr, list] -> iter
Loop& loop = enterLoop(true);
int patch = emitCode(OP_FOR_ITER);
emitCode(OP_STORE_NAME_PTR, iterIndex);
compileBlockBody();
emitCode(OP_JUMP_ABSOLUTE, loop.start); keepOpcodeLine();
patchJump(patch);

View File

@ -70,6 +70,9 @@ private:
public:
virtual PyVar next() = 0;
virtual bool hasNext() = 0;
_Pointer var;
_Iterator(PyVar _ref) : _ref(_ref) {}
};

View File

@ -101,9 +101,10 @@ void __initializeBuiltinFunctions(VM* _vm) {
return vm->PyStr(s);
});
_vm->bindMethod("type", "__new__", [](VM* vm, PyVarList args) {
return args.at(1)->attribs["__class__"];
});
// a little buggy... e.g. dict() call this instead of obj.__new__
// _vm->bindMethod("type", "__new__", [](VM* vm, PyVarList args) {
// return args.at(1)->attribs["__class__"];
// });
_vm->bindMethod("range", "__new__", [](VM* vm, PyVarList args) {
_Range r;

View File

@ -336,19 +336,18 @@ public:
PyVarOrNull iter_fn = getAttr(obj, __iter__, false);
if(iter_fn != nullptr){
PyVar tmp = call(iter_fn, {obj});
if(tmp->isType(_tp_native_iterator)){
frame->push(tmp);
break;
}
PyIter_AS_C(tmp)->var = PyPointer_AS_C(frame->__pop());
frame->push(tmp);
}else{
_error("TypeError", "'" + obj->getTypeName() + "' object is not iterable");
}
_error("TypeError", "'" + obj->getTypeName() + "' object is not iterable");
} break;
case OP_FOR_ITER:
{
const PyVar& iter = frame->topValue(this);
auto& it = PyIter_AS_C(iter);
if(it->hasNext()){
frame->push(it->next());
it->var->set(this, frame.get(), it->next());
}
else{
frame->popValue(this);