blueloveTH 2 лет назад
Родитель
Сommit
e4bf6288ad
2 измененных файлов с 71 добавлено и 0 удалено
  1. 70 0
      src/cffi.h
  2. 1 0
      src/pocketpy.h

+ 70 - 0
src/cffi.h

@@ -483,4 +483,74 @@ inline void add_module_c(VM* vm){
     add_refl_type("void_p", sizeof(void*), {});
 }
 
+struct Int32Flags{
+    PY_CLASS(Int32Flags, builtins, int32flags)
+
+    uint32_t value;
+    Int32Flags(uint32_t value) : value(value) {}
+
+    static void _register(VM* vm, PyObject* mod, PyObject* type){
+        vm->bind_constructor<-1>(type, [](VM* vm, ArgsView args){
+            vm->check_args_size(args.size(), 1+0, 1+1);
+            uint32_t value = CAST_DEFAULT(uint32_t, 1, 0);
+            return VAR_T(Int32Flags, value);
+        });
+
+        vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* self){
+            uint32_t value = _CAST(Int32Flags&, self).value;
+            std::string str;
+            for(int i=0; i<32; ++i) str += (value & (1<<i)) ? '1' : '0';
+            std::reverse(str.begin(), str.end());
+            return VAR(str);
+        });
+
+        vm->bind__and__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
+            uint32_t value = _CAST(Int32Flags&, lhs).value;
+            if(!is_non_tagged_type(rhs, Int32Flags::_type(vm))) return vm->NotImplemented;
+            return VAR_T(Int32Flags, value & _CAST(Int32Flags&, rhs).value);
+        });
+
+        vm->bind__or__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
+            uint32_t value = _CAST(Int32Flags&, lhs).value;
+            if(!is_non_tagged_type(rhs, Int32Flags::_type(vm))) return vm->NotImplemented;
+            return VAR_T(Int32Flags, value | _CAST(Int32Flags&, rhs).value);
+        });
+
+        vm->bind__xor__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
+            uint32_t value = _CAST(Int32Flags&, lhs).value;
+            if(!is_non_tagged_type(rhs, Int32Flags::_type(vm))) return vm->NotImplemented;
+            return VAR_T(Int32Flags, value ^ _CAST(Int32Flags&, rhs).value);
+        });
+
+        vm->bind__lshift__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
+            uint32_t value = _CAST(Int32Flags&, lhs).value;
+            if(!is_int(rhs)) return vm->NotImplemented;
+            return VAR_T(Int32Flags, value << _CAST(i64, rhs));
+        });
+
+        vm->bind__rshift__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
+            uint32_t value = _CAST(Int32Flags&, lhs).value;
+            if(!is_int(rhs)) return vm->NotImplemented;
+            return VAR_T(Int32Flags, value >> _CAST(i64, rhs));
+        });
+
+        vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* self, PyObject* i){
+            uint32_t value = _CAST(Int32Flags&, self).value;
+            int index = CAST(i64, i);
+            index = vm->normalized_index(index, 32);
+            int ok = value & (1 << index);
+            return VAR(ok);
+        });
+
+        vm->bind__setitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* self, PyObject* i, PyObject* v){
+            uint32_t& value = _CAST(Int32Flags&, self).value;
+            int index = CAST(i64, i);
+            index = vm->normalized_index(index, 32);
+            bool ok = CAST(i64, v) != 0;
+            if(ok) value |= (1 << index);
+            else value &= ~(1 << index);
+        });
+    }
+};
+
 }   // namespace pkpy

+ 1 - 0
src/pocketpy.h

@@ -1181,6 +1181,7 @@ inline void init_builtins(VM* _vm) {
     ArrayIter::register_class(_vm, _vm->builtins);
     StringIter::register_class(_vm, _vm->builtins);
     Generator::register_class(_vm, _vm->builtins);
+    Int32Flags::register_class(_vm, _vm->builtins);
 }
 
 inline void add_module_timeit(VM* vm){