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

View File

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

View File

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

View File

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