Parcourir la source

make for loop support compound pointer

Update pocketpy.h
blueloveTH il y a 3 ans
Parent
commit
5761d0b69c
4 fichiers modifiés avec 20 ajouts et 16 suppressions
  1. 8 7
      src/compiler.h
  2. 3 0
      src/obj.h
  3. 4 3
      src/pocketpy.h
  4. 5 6
      src/vm.h

+ 8 - 7
src/compiler.h

@@ -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);

+ 3 - 0
src/obj.h

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

+ 4 - 3
src/pocketpy.h

@@ -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;

+ 5 - 6
src/vm.h

@@ -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);