blueloveTH 3 лет назад
Родитель
Сommit
5b2e301fa7
4 измененных файлов с 31 добавлено и 3 удалено
  1. 2 1
      src/compiler.h
  2. 1 0
      src/opcodes.h
  3. 19 1
      src/pocketpy.h
  4. 9 1
      src/vm.h

+ 2 - 1
src/compiler.h

@@ -95,7 +95,7 @@ public:
         rules[TK(",")] =        { nullptr,               METHOD(exprComma),          PREC_COMMA };
         rules[TK("<<")] =       { nullptr,               METHOD(exprBinaryOp),       PREC_BITWISE_SHIFT };
         rules[TK(">>")] =       { nullptr,               METHOD(exprBinaryOp),       PREC_BITWISE_SHIFT };
-        rules[TK("&")] =        { nullptr,               METHOD(exprBinaryOp),       PREC_BITWISE_AND };
+        rules[TK("&")] =        { METHOD(exprUnaryOp),   METHOD(exprBinaryOp),       PREC_BITWISE_AND };
         rules[TK("|")] =        { nullptr,               METHOD(exprBinaryOp),       PREC_BITWISE_OR };
         rules[TK("^")] =        { nullptr,               METHOD(exprBinaryOp),       PREC_BITWISE_XOR };
 #undef METHOD
@@ -449,6 +449,7 @@ public:
         switch (op) {
             case TK("-"):     emitCode(OP_UNARY_NEGATIVE); break;
             case TK("not"):   emitCode(OP_UNARY_NOT);      break;
+            case TK("&"):     emitCode(OP_UNARY_REF);      break;
             default: UNREACHABLE();
         }
     }

+ 1 - 0
src/opcodes.h

@@ -59,5 +59,6 @@ OPCODE(BUILD_SMART_TUPLE)   // if all elements are pointers, build a compound po
 OPCODE(BUILD_STRING)        // arg is the expr count, build a string from the top of the stack
 
 OPCODE(GOTO)
+OPCODE(UNARY_REF)           // for &
 
 #endif

+ 19 - 1
src/pocketpy.h

@@ -56,6 +56,19 @@ void __initializeBuiltinFunctions(VM* _vm) {
         return vm->PyStr(tvm->readStdin());
     });
 
+    _vm->bindMethod("pointer", "set", [](VM* vm, const pkpy::ArgList& args) {
+        vm->__checkArgSize(args, 2, true);
+        _Pointer& p = std::get<_Pointer>(args[0]->_native);
+        p->set(vm, vm->topFrame(), args[1]);
+        return vm->None;
+    });
+
+    _vm->bindMethod("pointer", "get", [](VM* vm, const pkpy::ArgList& args) {
+        vm->__checkArgSize(args, 1, true);
+        _Pointer& p = std::get<_Pointer>(args[0]->_native);
+        return p->get(vm, vm->topFrame());
+    });
+
     _vm->bindBuiltinFunc("eval", [](VM* vm, const pkpy::ArgList& args) {
         vm->__checkArgSize(args, 1);
         const _Str& expr = vm->PyStr_AS_C(args[0]);
@@ -115,8 +128,13 @@ void __initializeBuiltinFunctions(VM* _vm) {
 
     _vm->bindBuiltinFunc("dir", [](VM* vm, const pkpy::ArgList& args) {
         vm->__checkArgSize(args, 1);
+        std::vector<_Str> names;
+        for (auto& [k, _] : args[0]->attribs) names.push_back(k);
+        for (auto& [k, _] : args[0]->_type->attribs) {
+            if (std::find(names.begin(), names.end(), k) == names.end()) names.push_back(k);
+        }
         PyVarList ret;
-        for (auto& [k, _] : args[0]->attribs) ret.push_back(vm->PyStr(k));
+        for (const auto& name : names) ret.push_back(vm->PyStr(name));
         return vm->PyList(ret);
     });
 

+ 9 - 1
src/vm.h

@@ -207,6 +207,12 @@ private:
                     const PyVar& obj_bool = asBool(obj);
                     frame->push(PyBool(!PyBool_AS_C(obj_bool)));
                 } break;
+            case OP_UNARY_REF:
+                {
+                    PyVar obj = frame->__pop();
+                    _Pointer p = PyPointer_AS_C(obj);
+                    frame->push(newObject(_tp_user_pointer, p));
+                } break;
             case OP_POP_JUMP_IF_FALSE:
                 if(!PyBool_AS_C(asBool(frame->popValue(this)))) frame->jump(byte.arg);
                 break;
@@ -659,12 +665,13 @@ public:
     PyVar _tp_list, _tp_tuple;
     PyVar _tp_function, _tp_native_function, _tp_native_iterator, _tp_bounded_method;
     PyVar _tp_slice, _tp_range, _tp_module, _tp_pointer;
+    PyVar _tp_user_pointer;
 
     __DEF_PY_POOL(Int, _Int, _tp_int, 256);
     __DEF_PY_AS_C(Int, _Int, _tp_int)
     __DEF_PY_POOL(Float, _Float, _tp_float, 256);
     __DEF_PY_AS_C(Float, _Float, _tp_float)
-    __DEF_PY_POOL(Pointer, _Pointer, _tp_pointer, 512)
+    __DEF_PY_POOL(Pointer, _Pointer, _tp_pointer, 256)
     __DEF_PY_AS_C(Pointer, _Pointer, _tp_pointer)
 
     DEF_NATIVE(Str, _Str, _tp_str)
@@ -698,6 +705,7 @@ public:
         _tp_range = newClassType("range");
         _tp_module = newClassType("module");
         _tp_pointer = newClassType("_pointer");
+        _tp_user_pointer = newClassType("pointer");
 
         newClassType("NoneType");
         newClassType("ellipsis");