blueloveTH 3 years ago
parent
commit
8008f131fb
4 changed files with 30 additions and 22 deletions
  1. 11 14
      src/pocketpy.h
  2. 0 1
      src/safestl.h
  3. 3 7
      src/vm.h
  4. 16 0
      tests/_reflection.py

+ 11 - 14
src/pocketpy.h

@@ -88,22 +88,19 @@ void __initializeBuiltinFunctions(VM* _vm) {
         return vm->PyInt((i64)s[0]);
     });
 
-    _vm->bindBuiltinFunc<0>("globals", [](VM* vm, const pkpy::ArgList& args) {
-        const auto& d = vm->top_frame()->f_globals();
-        PyVar obj = vm->call(vm->builtins->attribs["dict"]);
-        for (const auto& [k, v] : d) {
-            vm->call(obj, __setitem__, pkpy::twoArgs(vm->PyStr(k), v));
-        }
-        return obj;
+    _vm->bindBuiltinFunc<2>("hasattr", [](VM* vm, const pkpy::ArgList& args) {
+        return vm->PyBool(vm->getattr(args[0], vm->PyStr_AS_C(args[1]), false) != nullptr);
     });
 
-    _vm->bindBuiltinFunc<0>("locals", [](VM* vm, const pkpy::ArgList& args) {
-        const auto& d = vm->top_frame()->f_locals();
-        PyVar obj = vm->call(vm->builtins->attribs["dict"]);
-        for (const auto& [k, v] : d) {
-            vm->call(obj, __setitem__, pkpy::twoArgs(vm->PyStr(k), v));
-        }
-        return obj;
+    _vm->bindBuiltinFunc<3>("setattr", [](VM* vm, const pkpy::ArgList& args) {
+        PyVar obj = args[0];
+        vm->setattr(obj, vm->PyStr_AS_C(args[1]), args[2]);
+        return vm->None;
+    });
+
+    _vm->bindBuiltinFunc<2>("getattr", [](VM* vm, const pkpy::ArgList& args) {
+        _Str name = vm->PyStr_AS_C(args[1]);
+        return vm->getattr(args[0], name);
     });
 
     _vm->bindBuiltinFunc<1>("hex", [](VM* vm, const pkpy::ArgList& args) {

+ 0 - 1
src/safestl.h

@@ -98,7 +98,6 @@ namespace pkpy {
         PyVar& operator[](uint8_t i){ return _args[i]; }
         const PyVar& operator[](uint8_t i) const { return _args[i]; }
 
-        // overload = for &&
         ArgList& operator=(ArgList&& other) noexcept {
             if(this != &other){
                 __tryRelease();

+ 3 - 7
src/vm.h

@@ -644,15 +644,11 @@ public:
         return nullptr;
     }
 
-    template<typename T>
-    void setattr(PyObject* obj, const _Str& name, T&& value) {
-        while(obj->is_type(_tp_super)) obj = ((Py_<PyVar>*)obj)->_valueT.get();
-        obj->attribs[name] = value;
-    }
-
     template<typename T>
     inline void setattr(PyVar& obj, const _Str& name, T&& value) {
-        setattr(obj.get(), name, value);
+        PyObject* p = obj.get();
+        while(p->is_type(_tp_super)) p = ((Py_<PyVar>*)p)->_valueT.get();
+        p->attribs[name] = std::forward<T>(value);
     }
 
     template<int ARGC>

+ 16 - 0
tests/_reflection.py

@@ -0,0 +1,16 @@
+assert type(1) is int
+assert type(1.0) is float
+assert type(object) is type
+assert type(type) is type
+
+assert hasattr(object, '__base__')
+assert hasattr(1, '__add__')
+assert hasattr(int, '__add__')
+
+assert type(1).__add__(1, 2) == 3
+assert getattr(1, '__add__')(2) == 3
+
+a = {}
+setattr(a, 'b', 1)
+assert a.b == 1
+assert getattr(a, 'b') == 1