Parcourir la source

remove `bind_constructor`

blueloveTH il y a 1 an
Parent
commit
425fffec74

+ 1 - 1
3rd/lua_bridge/src/lua_bridge.cpp

@@ -80,7 +80,7 @@ struct PyLuaTable: PyLuaObject{
             return true;
         };
 
-        vm->bind_constructor<1>(type, [](VM* vm, ArgsView args){
+        vm->bind_func(type, __new__, 1, [](VM* vm, ArgsView args){
             lua_newtable(_L);    // push an empty table onto the stack
             PyObject* obj = vm->heap.gcnew<PyLuaTable>(PK_OBJ_GET(Type, args[0]));
             return obj;

+ 1 - 1
include/pocketpy/bindings.h

@@ -156,7 +156,7 @@ void _bind(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...)){
 #define PY_STRUCT_LIKE(wT)   \
         static_assert(std::is_trivially_copyable<wT>::value);                       \
         type->attr().set("__struct__", vm->True);                                   \
-        vm->bind_func<1>(type, "fromstruct", [](VM* vm, ArgsView args){             \
+        vm->bind_func(type, "fromstruct", 1, [](VM* vm, ArgsView args){             \
             Struct& s = CAST(Struct&, args[0]);                                     \
             if(s.size != sizeof(wT)) vm->ValueError("size mismatch");               \
             PyObject* obj = vm->new_user_object<wT>();                              \

+ 0 - 6
include/pocketpy/vm.h

@@ -310,12 +310,6 @@ public:
     template<typename T, typename F, bool ReadOnly=false>
     PyObject* bind_field(PyObject*, const char*, F T::*);
 
-    template<int ARGC, typename __T>
-    PyObject* bind_constructor(__T&& type, NativeFuncC fn) {
-        static_assert(ARGC==-1 || ARGC>=1);
-        return bind_func<ARGC>(std::forward<__T>(type), __new__, fn);
-    }
-
     template<typename T, typename __T>
     PyObject* bind_notimplemented_constructor(__T&& type) {
         return bind_func<-1>(std::forward<__T>(type), __new__, [](VM* vm, ArgsView args){

+ 2 - 2
src/base64.cpp

@@ -169,7 +169,7 @@ void add_module_base64(VM* vm){
     PyObject* mod = vm->new_module("base64");
 
     // b64encode
-    vm->bind_func<1>(mod, "b64encode", [](VM* vm, ArgsView args){
+    vm->bind_func(mod, "b64encode", 1, [](VM* vm, ArgsView args){
         Bytes& b = CAST(Bytes&, args[0]);
 		unsigned char* p = new unsigned char[b.size() * 2];
         int size = base64_encode((const unsigned char*)b.data(), b.size(), (char*)p);
@@ -177,7 +177,7 @@ void add_module_base64(VM* vm){
     });
 
     // b64decode
-    vm->bind_func<1>(mod, "b64decode", [](VM* vm, ArgsView args){
+    vm->bind_func(mod, "b64decode", 1, [](VM* vm, ArgsView args){
         Bytes& b = CAST(Bytes&, args[0]);
         unsigned char* p = new unsigned char[b.size()];
         int size = base64_decode((const char*)b.data(), b.size(), p);

+ 8 - 8
src/cffi.cpp

@@ -3,7 +3,7 @@
 namespace pkpy{
 
     void VoidP::_register(VM* vm, PyObject* mod, PyObject* type){
-        vm->bind_func<2>(type, __new__, [](VM* vm, ArgsView args){
+        vm->bind_func(type, __new__, 2, [](VM* vm, ArgsView args){
             Type cls = PK_OBJ_GET(Type, args[0]);
             i64 addr = CAST(i64, args[1]);
             return vm->heap.gcnew<VoidP>(cls, reinterpret_cast<void*>(addr));
@@ -38,7 +38,7 @@ namespace pkpy{
 
 
     void Struct::_register(VM* vm, PyObject* mod, PyObject* type){
-        vm->bind_constructor<2>(type, [](VM* vm, ArgsView args){
+        vm->bind_func(type, __new__, 2, [](VM* vm, ArgsView args){
             Type cls = PK_OBJ_GET(Type, args[0]);
             int size = CAST(int, args[1]);
             return vm->heap.gcnew<Struct>(cls, size);
@@ -52,7 +52,7 @@ namespace pkpy{
         });
 
         // @staticmethod
-        vm->bind_func<1>(type, "fromhex", [](VM* vm, ArgsView args){
+        vm->bind_func(type, "fromhex", 1, [](VM* vm, ArgsView args){
             const Str& s = CAST(Str&, args[0]);
             if(s.size<2 || s.size%2!=0) vm->ValueError("invalid hex string");
             Struct buffer(s.size/2, false);
@@ -136,24 +136,24 @@ namespace pkpy{
 void add_module_c(VM* vm){
     PyObject* mod = vm->new_module("c");
     
-    vm->bind_func<1>(mod, "malloc", [](VM* vm, ArgsView args){
+    vm->bind_func(mod, "malloc", 1, [](VM* vm, ArgsView args){
         i64 size = CAST(i64, args[0]);
         return VAR(malloc(size));
     });
 
-    vm->bind_func<1>(mod, "free", [](VM* vm, ArgsView args){
+    vm->bind_func(mod, "free", 1, [](VM* vm, ArgsView args){
         void* p = CAST(void*, args[0]);
         free(p);
         return vm->None;
     });
 
-    vm->bind_func<3>(mod, "memset", [](VM* vm, ArgsView args){
+    vm->bind_func(mod, "memset", 3, [](VM* vm, ArgsView args){
         void* p = CAST(void*, args[0]);
         memset(p, CAST(int, args[1]), CAST(size_t, args[2]));
         return vm->None;
     });
 
-    vm->bind_func<3>(mod, "memcpy", [](VM* vm, ArgsView args){
+    vm->bind_func(mod, "memcpy", 3, [](VM* vm, ArgsView args){
         void* dst = CAST(void*, args[0]);
         void* src = CAST(void*, args[1]);
         i64 size = CAST(i64, args[2]);
@@ -191,7 +191,7 @@ void add_module_c(VM* vm){
     Type type_t = -1;
 
 #define BIND_PRIMITIVE(T, CNAME) \
-    vm->bind_func<1>(mod, CNAME "_", [](VM* vm, ArgsView args){         \
+    vm->bind_func(mod, CNAME "_", 1, [](VM* vm, ArgsView args){         \
         T val = CAST(T, args[0]);                                       \
         return vm->new_user_object<Struct>(&val, sizeof(T));                       \
     });                                                                 \

+ 2 - 2
src/dataclasses.cpp

@@ -80,7 +80,7 @@ static void patch__eq__(VM* vm, Type cls){
 void add_module_dataclasses(VM* vm){
     PyObject* mod = vm->new_module("dataclasses");
 
-    vm->bind_func<1>(mod, "dataclass", [](VM* vm, ArgsView args){
+    vm->bind_func(mod, "dataclass", 1, [](VM* vm, ArgsView args){
         vm->check_type(args[0], VM::tp_type);
         Type cls = PK_OBJ_GET(Type, args[0]);
         NameDict& cls_d = args[0]->attr();
@@ -103,7 +103,7 @@ void add_module_dataclasses(VM* vm){
         return args[0];
     });
 
-    vm->bind_func<1>(mod, "asdict", [](VM* vm, ArgsView args){
+    vm->bind_func(mod, "asdict", 1, [](VM* vm, ArgsView args){
         const auto& fields = vm->_inst_type_info(args[0])->annotated_fields;
         const NameDict& obj_d = args[0]->attr();
         Dict d(vm);

+ 1 - 1
src/easing.cpp

@@ -209,7 +209,7 @@ void add_module_easing(VM* vm){
     PyObject* mod = vm->new_module("easing");
 
 #define EASE(name)  \
-    vm->bind_func<1>(mod, #name, [](VM* vm, ArgsView args){  \
+    vm->bind_func(mod, #name, 1, [](VM* vm, ArgsView args){  \
         f64 t = CAST(f64, args[0]); \
         return VAR(ease##name(t));   \
     });

+ 13 - 13
src/io.cpp

@@ -55,7 +55,7 @@ unsigned char* _default_import_handler(const char* name_p, int name_size, int* o
 };
 
 void FileIO::_register(VM* vm, PyObject* mod, PyObject* type){
-    vm->bind_constructor<3>(type, [](VM* vm, ArgsView args){
+    vm->bind_func(type, __new__, 3, [](VM* vm, ArgsView args){
         Type cls = PK_OBJ_GET(Type, args[0]);
         return vm->heap.gcnew<FileIO>(cls, vm,
                     py_cast<Str&>(vm, args[1]),
@@ -159,17 +159,17 @@ void add_module_os(VM* vm){
     mod->attr().set("path", path_obj);
     
     // Working directory is shared by all VMs!!
-    vm->bind_func<0>(mod, "getcwd", [](VM* vm, ArgsView args){
+    vm->bind_func(mod, "getcwd", 0, [](VM* vm, ArgsView args){
         return VAR(std::filesystem::current_path().string());
     });
 
-    vm->bind_func<1>(mod, "chdir", [](VM* vm, ArgsView args){
+    vm->bind_func(mod, "chdir", 1, [](VM* vm, ArgsView args){
         std::filesystem::path path(CAST(Str&, args[0]).sv());
         std::filesystem::current_path(path);
         return vm->None;
     });
 
-    vm->bind_func<1>(mod, "listdir", [](VM* vm, ArgsView args){
+    vm->bind_func(mod, "listdir", 1, [](VM* vm, ArgsView args){
         std::filesystem::path path(CAST(Str&, args[0]).sv());
         std::filesystem::directory_iterator di;
         try{
@@ -182,28 +182,28 @@ void add_module_os(VM* vm){
         return VAR(ret);
     });
 
-    vm->bind_func<1>(mod, "remove", [](VM* vm, ArgsView args){
+    vm->bind_func(mod, "remove", 1, [](VM* vm, ArgsView args){
         std::filesystem::path path(CAST(Str&, args[0]).sv());
         bool ok = std::filesystem::remove(path);
         if(!ok) vm->IOError("operation failed");
         return vm->None;
     });
 
-    vm->bind_func<1>(mod, "mkdir", [](VM* vm, ArgsView args){
+    vm->bind_func(mod, "mkdir", 1, [](VM* vm, ArgsView args){
         std::filesystem::path path(CAST(Str&, args[0]).sv());
         bool ok = std::filesystem::create_directory(path);
         if(!ok) vm->IOError("operation failed");
         return vm->None;
     });
 
-    vm->bind_func<1>(mod, "rmdir", [](VM* vm, ArgsView args){
+    vm->bind_func(mod, "rmdir", 1, [](VM* vm, ArgsView args){
         std::filesystem::path path(CAST(Str&, args[0]).sv());
         bool ok = std::filesystem::remove(path);
         if(!ok) vm->IOError("operation failed");
         return vm->None;
     });
 
-    vm->bind_func<-1>(path_obj, "join", [](VM* vm, ArgsView args){
+    vm->bind_func(path_obj, "join", -1, [](VM* vm, ArgsView args){
         std::filesystem::path path;
         for(int i=0; i<args.size(); i++){
             path /= CAST(Str&, args[i]).sv();
@@ -211,30 +211,30 @@ void add_module_os(VM* vm){
         return VAR(path.string());
     });
 
-    vm->bind_func<1>(path_obj, "exists", [](VM* vm, ArgsView args){
+    vm->bind_func(path_obj, "exists", 1, [](VM* vm, ArgsView args){
         std::filesystem::path path(CAST(Str&, args[0]).sv());
         bool exists = std::filesystem::exists(path);
         return VAR(exists);
     });
 
-    vm->bind_func<1>(path_obj, "basename", [](VM* vm, ArgsView args){
+    vm->bind_func(path_obj, "basename", 1, [](VM* vm, ArgsView args){
         std::filesystem::path path(CAST(Str&, args[0]).sv());
         return VAR(path.filename().string());
     });
 
-    vm->bind_func<1>(path_obj, "isdir", [](VM* vm, ArgsView args){
+    vm->bind_func(path_obj, "isdir", 1, [](VM* vm, ArgsView args){
         std::filesystem::path path(CAST(Str&, args[0]).sv());
         bool isdir = std::filesystem::is_directory(path);
         return VAR(isdir);
     });
 
-    vm->bind_func<1>(path_obj, "isfile", [](VM* vm, ArgsView args){
+    vm->bind_func(path_obj, "isfile", 1, [](VM* vm, ArgsView args){
         std::filesystem::path path(CAST(Str&, args[0]).sv());
         bool isfile = std::filesystem::is_regular_file(path);
         return VAR(isfile);
     });
 
-    vm->bind_func<1>(path_obj, "abspath", [](VM* vm, ArgsView args){
+    vm->bind_func(path_obj, "abspath", 1, [](VM* vm, ArgsView args){
         std::filesystem::path path(CAST(Str&, args[0]).sv());
         return VAR(std::filesystem::absolute(path).string());
     });

+ 7 - 7
src/linalg.cpp

@@ -117,10 +117,10 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
     void Vec2::_register(VM* vm, PyObject* mod, PyObject* type){
         PY_STRUCT_LIKE(Vec2)
 
-        vm->bind_constructor<3>(type, [](VM* vm, ArgsView args){
+        vm->bind_func(type, __new__, 3, [](VM* vm, ArgsView args){
             float x = CAST_F(args[1]);
             float y = CAST_F(args[2]);
-            return vm->heap.gcnew<Vec2>(PK_OBJ_GET(Type, args[0]), Vec2(x, y));
+            return vm->heap.gcnew<Vec2>(PK_OBJ_GET(Type, args[0]), x, y);
         });
 
         // @staticmethod
@@ -187,11 +187,11 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
     void Vec3::_register(VM* vm, PyObject* mod, PyObject* type){
         PY_STRUCT_LIKE(Vec3)
 
-        vm->bind_constructor<4>(type, [](VM* vm, ArgsView args){
+        vm->bind_func(type, __new__, 4, [](VM* vm, ArgsView args){
             float x = CAST_F(args[1]);
             float y = CAST_F(args[2]);
             float z = CAST_F(args[3]);
-            return vm->heap.gcnew<Vec3>(PK_OBJ_GET(Type, args[0]), Vec3(x, y, z));
+            return vm->heap.gcnew<Vec3>(PK_OBJ_GET(Type, args[0]), x, y, z);
         });
 
         vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
@@ -222,12 +222,12 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
     void Vec4::_register(VM* vm, PyObject* mod, PyObject* type){
         PY_STRUCT_LIKE(Vec4)
 
-        vm->bind_constructor<1+4>(type, [](VM* vm, ArgsView args){
+        vm->bind_func(type, __new__, 5, [](VM* vm, ArgsView args){
             float x = CAST_F(args[1]);
             float y = CAST_F(args[2]);
             float z = CAST_F(args[3]);
             float w = CAST_F(args[4]);
-            return vm->heap.gcnew<Vec4>(PK_OBJ_GET(Type, args[0]), Vec4(x, y, z, w));
+            return vm->heap.gcnew<Vec4>(PK_OBJ_GET(Type, args[0]), x, y, z, w);
         });
 
         vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
@@ -264,7 +264,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
     void Mat3x3::_register(VM* vm, PyObject* mod, PyObject* type){
         PY_STRUCT_LIKE(Mat3x3)
 
-        vm->bind_func<-1>(type, __new__, [](VM* vm, ArgsView args){
+        vm->bind_func(type, __new__, -1, [](VM* vm, ArgsView args){
             if(args.size() == 1+0) return vm->heap.gcnew<Mat3x3>(PK_OBJ_GET(Type, args[0]), Mat3x3::zeros());
             if(args.size() == 1+1){
                 const List& list = CAST(List&, args[1]);

+ 39 - 40
src/modules.cpp

@@ -44,12 +44,12 @@ void add_module_time(VM* vm){
     PyObject* mod = vm->new_module("time");
     vm->register_user_class<PyStructTime>(mod, "struct_time");
 
-    vm->bind_func<0>(mod, "time", [](VM* vm, ArgsView args) {
+    vm->bind_func(mod, "time", 0, [](VM* vm, ArgsView args) {
         auto now = std::chrono::system_clock::now();
         return VAR(std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count() / 1000.0);
     });
 
-    vm->bind_func<1>(mod, "sleep", [](VM* vm, ArgsView args) {
+    vm->bind_func(mod, "sleep", 1, [](VM* vm, ArgsView args) {
         f64 seconds = CAST_F(args[0]);
         auto begin = std::chrono::system_clock::now();
         while(true){
@@ -60,7 +60,7 @@ void add_module_time(VM* vm){
         return vm->None;
     });
 
-    vm->bind_func<0>(mod, "localtime", [](VM* vm, ArgsView args) {
+    vm->bind_func(mod, "localtime", 0, [](VM* vm, ArgsView args) {
         auto now = std::chrono::system_clock::now();
         std::time_t t = std::chrono::system_clock::to_time_t(now);
         return vm->new_user_object<PyStructTime>(t);
@@ -77,13 +77,13 @@ void add_module_sys(VM* vm){
     vm->setattr(mod, "stdout", stdout_);
     vm->setattr(mod, "stderr", stderr_);
 
-    vm->bind_func<1>(stdout_, "write", [](VM* vm, ArgsView args) {
+    vm->bind_func(stdout_, "write", 1, [](VM* vm, ArgsView args) {
         Str& s = CAST(Str&, args[0]);
         vm->stdout_write(s);
         return vm->None;
     });
 
-    vm->bind_func<1>(stderr_, "write", [](VM* vm, ArgsView args) {
+    vm->bind_func(stderr_, "write", 1, [](VM* vm, ArgsView args) {
         Str& s = CAST(Str&, args[0]);
         vm->_stderr(s.data, s.size);
         return vm->None;
@@ -92,7 +92,7 @@ void add_module_sys(VM* vm){
 
 void add_module_json(VM* vm){
     PyObject* mod = vm->new_module("json");
-    vm->bind_func<1>(mod, "loads", [](VM* vm, ArgsView args) {
+    vm->bind_func(mod, "loads", 1, [](VM* vm, ArgsView args) {
         std::string_view sv;
         if(is_type(args[0], vm->tp_bytes)){
             sv = PK_OBJ_GET(Bytes, args[0]).sv();
@@ -103,7 +103,7 @@ void add_module_json(VM* vm){
         return vm->_exec(code, vm->callstack.top()._module);
     });
 
-    vm->bind_func<1>(mod, "dumps", [](VM* vm, ArgsView args) {
+    vm->bind_func(mod, "dumps", 1, [](VM* vm, ArgsView args) {
         return vm->py_json(args[0]);
     });
 }
@@ -116,10 +116,10 @@ void add_module_math(VM* vm){
     mod->attr().set("inf", VAR(std::numeric_limits<double>::infinity()));
     mod->attr().set("nan", VAR(std::numeric_limits<double>::quiet_NaN()));
 
-    vm->bind_func<1>(mod, "ceil", PK_LAMBDA(VAR((i64)std::ceil(CAST_F(args[0])))));
-    vm->bind_func<1>(mod, "fabs", PK_LAMBDA(VAR(std::fabs(CAST_F(args[0])))));
-    vm->bind_func<1>(mod, "floor", PK_LAMBDA(VAR((i64)std::floor(CAST_F(args[0])))));
-    vm->bind_func<1>(mod, "fsum", [](VM* vm, ArgsView args) {
+    vm->bind_func(mod, "ceil", 1, PK_LAMBDA(VAR((i64)std::ceil(CAST_F(args[0])))));
+    vm->bind_func(mod, "fabs", 1, PK_LAMBDA(VAR(std::fabs(CAST_F(args[0])))));
+    vm->bind_func(mod, "floor", 1, PK_LAMBDA(VAR((i64)std::floor(CAST_F(args[0])))));
+    vm->bind_func(mod, "fsum", 1, [](VM* vm, ArgsView args) {
         List& list = CAST(List&, args[0]);
         double sum = 0;
         double c = 0;
@@ -132,7 +132,7 @@ void add_module_math(VM* vm){
         }
         return VAR(sum);
     });
-    vm->bind_func<2>(mod, "gcd", [](VM* vm, ArgsView args) {
+    vm->bind_func(mod, "gcd", 2, [](VM* vm, ArgsView args) {
         i64 a = CAST(i64, args[0]);
         i64 b = CAST(i64, args[1]);
         if(a < 0) a = -a;
@@ -145,18 +145,17 @@ void add_module_math(VM* vm){
         return VAR(a);
     });
 
-    vm->bind_func<1>(mod, "isfinite", PK_LAMBDA(VAR(std::isfinite(CAST_F(args[0])))));
-    vm->bind_func<1>(mod, "isinf", PK_LAMBDA(VAR(std::isinf(CAST_F(args[0])))));
-    vm->bind_func<1>(mod, "isnan", PK_LAMBDA(VAR(std::isnan(CAST_F(args[0])))));
+    vm->bind_func(mod, "isfinite", 1, PK_LAMBDA(VAR(std::isfinite(CAST_F(args[0])))));
+    vm->bind_func(mod, "isinf", 1, PK_LAMBDA(VAR(std::isinf(CAST_F(args[0])))));
+    vm->bind_func(mod, "isnan", 1, PK_LAMBDA(VAR(std::isnan(CAST_F(args[0])))));
 
-    vm->bind_func<2>(mod, "isclose", [](VM* vm, ArgsView args) {
+    vm->bind_func(mod, "isclose", 2, [](VM* vm, ArgsView args) {
         f64 a = CAST_F(args[0]);
         f64 b = CAST_F(args[1]);
         return VAR(std::fabs(a - b) < 1e-9);
     });
 
-    vm->bind_func<1>(mod, "exp", PK_LAMBDA(VAR(std::exp(CAST_F(args[0])))));
-    // vm->bind_func<1>(mod, "log", PK_LAMBDA(VAR(std::log(CAST_F(args[0])))));
+    vm->bind_func(mod, "exp", 1, PK_LAMBDA(VAR(std::exp(CAST_F(args[0])))));
 
     vm->bind(mod, "log(x, base=2.718281828459045)", [](VM* vm, ArgsView args){
         f64 x = CAST_F(args[0]);
@@ -164,31 +163,31 @@ void add_module_math(VM* vm){
         return VAR(std::log(x) / std::log(base));
     });
 
-    vm->bind_func<1>(mod, "log2", PK_LAMBDA(VAR(std::log2(CAST_F(args[0])))));
-    vm->bind_func<1>(mod, "log10", PK_LAMBDA(VAR(std::log10(CAST_F(args[0])))));
+    vm->bind_func(mod, "log2", 1, PK_LAMBDA(VAR(std::log2(CAST_F(args[0])))));
+    vm->bind_func(mod, "log10", 1, PK_LAMBDA(VAR(std::log10(CAST_F(args[0])))));
 
-    vm->bind_func<2>(mod, "pow", PK_LAMBDA(VAR(std::pow(CAST_F(args[0]), CAST_F(args[1])))));
-    vm->bind_func<1>(mod, "sqrt", PK_LAMBDA(VAR(std::sqrt(CAST_F(args[0])))));
+    vm->bind_func(mod, "pow", 2, PK_LAMBDA(VAR(std::pow(CAST_F(args[0]), CAST_F(args[1])))));
+    vm->bind_func(mod, "sqrt", 1, PK_LAMBDA(VAR(std::sqrt(CAST_F(args[0])))));
 
-    vm->bind_func<1>(mod, "acos", PK_LAMBDA(VAR(std::acos(CAST_F(args[0])))));
-    vm->bind_func<1>(mod, "asin", PK_LAMBDA(VAR(std::asin(CAST_F(args[0])))));
-    vm->bind_func<1>(mod, "atan", PK_LAMBDA(VAR(std::atan(CAST_F(args[0])))));
-    vm->bind_func<2>(mod, "atan2", PK_LAMBDA(VAR(std::atan2(CAST_F(args[0]), CAST_F(args[1])))));
+    vm->bind_func(mod, "acos", 1, PK_LAMBDA(VAR(std::acos(CAST_F(args[0])))));
+    vm->bind_func(mod, "asin", 1, PK_LAMBDA(VAR(std::asin(CAST_F(args[0])))));
+    vm->bind_func(mod, "atan", 1, PK_LAMBDA(VAR(std::atan(CAST_F(args[0])))));
+    vm->bind_func(mod, "atan2", 2, PK_LAMBDA(VAR(std::atan2(CAST_F(args[0]), CAST_F(args[1])))));
 
-    vm->bind_func<1>(mod, "cos", PK_LAMBDA(VAR(std::cos(CAST_F(args[0])))));
-    vm->bind_func<1>(mod, "sin", PK_LAMBDA(VAR(std::sin(CAST_F(args[0])))));
-    vm->bind_func<1>(mod, "tan", PK_LAMBDA(VAR(std::tan(CAST_F(args[0])))));
+    vm->bind_func(mod, "cos", 1, PK_LAMBDA(VAR(std::cos(CAST_F(args[0])))));
+    vm->bind_func(mod, "sin", 1, PK_LAMBDA(VAR(std::sin(CAST_F(args[0])))));
+    vm->bind_func(mod, "tan", 1, PK_LAMBDA(VAR(std::tan(CAST_F(args[0])))));
     
-    vm->bind_func<1>(mod, "degrees", PK_LAMBDA(VAR(CAST_F(args[0]) * 180 / 3.1415926535897932384)));
-    vm->bind_func<1>(mod, "radians", PK_LAMBDA(VAR(CAST_F(args[0]) * 3.1415926535897932384 / 180)));
+    vm->bind_func(mod, "degrees", 1, PK_LAMBDA(VAR(CAST_F(args[0]) * 180 / 3.1415926535897932384)));
+    vm->bind_func(mod, "radians", 1, PK_LAMBDA(VAR(CAST_F(args[0]) * 3.1415926535897932384 / 180)));
 
-    vm->bind_func<1>(mod, "modf", [](VM* vm, ArgsView args) {
+    vm->bind_func(mod, "modf", 1, [](VM* vm, ArgsView args) {
         f64 i;
         f64 f = std::modf(CAST_F(args[0]), &i);
         return VAR(Tuple(VAR(f), VAR(i)));
     });
 
-    vm->bind_func<1>(mod, "factorial", [](VM* vm, ArgsView args) {
+    vm->bind_func(mod, "factorial", 1, [](VM* vm, ArgsView args) {
         i64 n = CAST(i64, args[0]);
         if(n < 0) vm->ValueError("factorial() not defined for negative values");
         i64 r = 1;
@@ -199,14 +198,14 @@ void add_module_math(VM* vm){
 
 void add_module_traceback(VM* vm){
     PyObject* mod = vm->new_module("traceback");
-    vm->bind_func<0>(mod, "print_exc", [](VM* vm, ArgsView args) {
+    vm->bind_func(mod, "print_exc", 0, [](VM* vm, ArgsView args) {
         if(vm->__last_exception==nullptr) vm->ValueError("no exception");
         Exception& e = _CAST(Exception&, vm->__last_exception);
         vm->stdout_write(e.summary());
         return vm->None;
     });
 
-    vm->bind_func<0>(mod, "format_exc", [](VM* vm, ArgsView args) {
+    vm->bind_func(mod, "format_exc", 0, [](VM* vm, ArgsView args) {
         if(vm->__last_exception==nullptr) vm->ValueError("no exception");
         Exception& e = _CAST(Exception&, vm->__last_exception);
         return VAR(e.summary());
@@ -216,7 +215,7 @@ void add_module_traceback(VM* vm){
 void add_module_dis(VM* vm){
     PyObject* mod = vm->new_module("dis");
 
-    vm->bind_func<1>(mod, "dis", [](VM* vm, ArgsView args) {
+    vm->bind_func(mod, "dis", 1, [](VM* vm, ArgsView args) {
         CodeObject_ code;
         PyObject* obj = args[0];
         if(is_type(obj, vm->tp_str)){
@@ -233,7 +232,7 @@ void add_module_dis(VM* vm){
 
 void add_module_gc(VM* vm){
     PyObject* mod = vm->new_module("gc");
-    vm->bind_func<0>(mod, "collect", PK_LAMBDA(VAR(vm->heap.collect())));
+    vm->bind_func(mod, "collect", 0, PK_LAMBDA(VAR(vm->heap.collect())));
 }
 
 void add_module_enum(VM* vm){
@@ -257,11 +256,11 @@ void add_module_enum(VM* vm){
 void add_module___builtins(VM* vm){
     PyObject* mod = vm->new_module("__builtins");
 
-    vm->bind_func<1>(mod, "next", [](VM* vm, ArgsView args){
+    vm->bind_func(mod, "next", 1, [](VM* vm, ArgsView args){
         return vm->py_next(args[0]);
     });
 
-    vm->bind_func<1>(mod, "_enable_instance_dict", [](VM* vm, ArgsView args){
+    vm->bind_func(mod, "_enable_instance_dict", 1, [](VM* vm, ArgsView args){
         PyObject* self = args[0];
         if(is_tagged(self)) vm->TypeError("object: tagged object cannot enable instance dict");
         if(self->is_attr_valid()) vm->RuntimeError("object: instance dict is already enabled");
@@ -287,7 +286,7 @@ struct LineProfilerW{
     LineProfiler profiler;
 
     static void _register(VM* vm, PyObject* mod, PyObject* type){
-        vm->bind_func<1>(type, __new__, [](VM* vm, ArgsView args){
+        vm->bind_func(type, __new__, 1, [](VM* vm, ArgsView args){
             Type cls = PK_OBJ_GET(Type, args[0]);
             return vm->heap.gcnew<LineProfilerW>(cls);
         });

+ 40 - 40
src/pocketpy.cpp

@@ -72,14 +72,14 @@ void init_builtins(VM* _vm) {
 #undef BIND_NUM_LOGICAL_OPT
 
     // builtin functions
-    _vm->bind_func<0>(_vm->builtins, "breakpoint", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "breakpoint", 0, [](VM* vm, ArgsView args) {
 #if PK_ENABLE_PROFILER
         vm->_next_breakpoint = NextBreakpoint(vm->callstack.size(), vm->callstack.top().curr_lineno(), false);
 #endif
         return vm->None;
     });
 
-    _vm->bind_func<-1>(_vm->builtins, "super", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "super", -1, [](VM* vm, ArgsView args) {
         PyObject* class_arg = nullptr;
         PyObject* self_arg = nullptr;
         if(args.size() == 2){
@@ -107,19 +107,19 @@ void init_builtins(VM* _vm) {
         return vm->heap.gcnew<Super>(vm->tp_super, self_arg, vm->_all_types[type].base);
     });
 
-    _vm->bind_func<1>(_vm->builtins, "staticmethod", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "staticmethod", 1, [](VM* vm, ArgsView args) {
         PyObject* func = args[0];
         vm->check_type(func, vm->tp_function);
         return vm->heap.gcnew<StaticMethod>(vm->tp_staticmethod, args[0]);
     });
 
-    _vm->bind_func<1>(_vm->builtins, "classmethod", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "classmethod", 1, [](VM* vm, ArgsView args) {
         PyObject* func = args[0];
         vm->check_type(func, vm->tp_function);
         return vm->heap.gcnew<ClassMethod>(vm->tp_classmethod, args[0]);
     });
 
-    _vm->bind_func<2>(_vm->builtins, "isinstance", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "isinstance", 2, [](VM* vm, ArgsView args) {
         if(is_type(args[1], vm->tp_tuple)){
             Tuple& types = _CAST(Tuple&, args[1]);
             for(PyObject* type : types){
@@ -133,13 +133,13 @@ void init_builtins(VM* _vm) {
         return VAR(vm->isinstance(args[0], type));
     });
 
-    _vm->bind_func<2>(_vm->builtins, "issubclass", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "issubclass", 2, [](VM* vm, ArgsView args) {
         vm->check_type(args[0], vm->tp_type);
         vm->check_type(args[1], vm->tp_type);
         return VAR(vm->issubclass(PK_OBJ_GET(Type, args[0]), PK_OBJ_GET(Type, args[1])));
     });
 
-    _vm->bind_func<0>(_vm->builtins, "globals", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "globals", 0, [](VM* vm, ArgsView args) {
         PyObject* mod = vm->callstack.top()._module;
         return VAR(MappingProxy(mod));
     });
@@ -155,7 +155,7 @@ void init_builtins(VM* _vm) {
         return VAR((i64)(x * std::pow(10, ndigits) + offset) / std::pow(10, ndigits));
     });
 
-    _vm->bind_func<1>(_vm->builtins, "abs", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "abs", 1, [](VM* vm, ArgsView args) {
         if(is_int(args[0])) return VAR(std::abs(_CAST(i64, args[0])));
         if(is_float(args[0])) return VAR(std::abs(_CAST(f64, args[0])));
         vm->TypeError("bad operand type for abs()");
@@ -170,22 +170,22 @@ void init_builtins(VM* _vm) {
         return vm->__minmax_reduce(&VM::py_lt, args[0], args[1]);
     });
 
-    _vm->bind_func<1>(_vm->builtins, "id", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "id", 1, [](VM* vm, ArgsView args) {
         PyObject* obj = args[0];
         if(is_tagged(obj)) return vm->None;
         return VAR(PK_BITS(obj));
     });
 
-    _vm->bind_func<1>(_vm->builtins, "callable", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "callable", 1, [](VM* vm, ArgsView args) {
         return VAR(vm->py_callable(args[0]));
     });
 
-    _vm->bind_func<1>(_vm->builtins, "__import__", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "__import__", 1, [](VM* vm, ArgsView args) {
         const Str& name = CAST(Str&, args[0]);
         return vm->py_import(name);
     });
 
-    _vm->bind_func<2>(_vm->builtins, "divmod", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "divmod", 2, [](VM* vm, ArgsView args) {
         if(is_int(args[0])){
             i64 lhs = _CAST(i64, args[0]);
             i64 rhs = CAST(i64, args[1]);
@@ -244,43 +244,43 @@ void init_builtins(VM* _vm) {
         return vm->None;
     });
 
-    _vm->bind_func<1>(_vm->builtins, "repr", [](VM* vm, ArgsView args){
+    _vm->bind_func(_vm->builtins, "repr", 1, [](VM* vm, ArgsView args){
         return vm->py_repr(args[0]);
     });
 
-    _vm->bind_func<1>(_vm->builtins, "len", [](VM* vm, ArgsView args){
+    _vm->bind_func(_vm->builtins, "len", 1, [](VM* vm, ArgsView args){
         const PyTypeInfo* ti = vm->_inst_type_info(args[0]);
         if(ti->m__len__) return VAR(ti->m__len__(vm, args[0]));
         return vm->call_method(args[0], __len__);
     });
 
-    _vm->bind_func<1>(_vm->builtins, "hash", [](VM* vm, ArgsView args){
+    _vm->bind_func(_vm->builtins, "hash", 1, [](VM* vm, ArgsView args){
         i64 value = vm->py_hash(args[0]);
         return VAR(value);
     });
 
-    _vm->bind_func<1>(_vm->builtins, "chr", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "chr", 1, [](VM* vm, ArgsView args) {
         i64 i = CAST(i64, args[0]);
         if (i < 0 || i >= 128) vm->ValueError("chr() arg not in [0, 128)");
         return VAR(std::string(1, (char)i));
     });
 
-    _vm->bind_func<1>(_vm->builtins, "ord", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "ord", 1, [](VM* vm, ArgsView args) {
         const Str& s = CAST(Str&, args[0]);
         if (s.length()!=1) vm->TypeError("ord() expected an ASCII character");
         return VAR((i64)(s[0]));
     });
 
-    _vm->bind_func<2>(_vm->builtins, "hasattr", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "hasattr", 2, [](VM* vm, ArgsView args) {
         return VAR(vm->getattr(args[0], CAST(Str&, args[1]), false) != nullptr);
     });
 
-    _vm->bind_func<3>(_vm->builtins, "setattr", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "setattr", 3, [](VM* vm, ArgsView args) {
         vm->setattr(args[0], CAST(Str&, args[1]), args[2]);
         return vm->None;
     });
 
-    _vm->bind_func<-1>(_vm->builtins, "getattr", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "getattr", -1, [](VM* vm, ArgsView args) {
         if(args.size()!=2 && args.size()!=3) vm->TypeError("getattr() takes 2 or 3 arguments");
         StrName name = CAST(Str&, args[1]);
         PyObject* val = vm->getattr(args[0], name, false);
@@ -291,28 +291,28 @@ void init_builtins(VM* _vm) {
         return val;
     });
 
-    _vm->bind_func<2>(_vm->builtins, "delattr", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "delattr", 2, [](VM* vm, ArgsView args) {
         vm->delattr(args[0], CAST(Str&, args[1]));
         return vm->None;
     });
 
-    _vm->bind_func<1>(_vm->builtins, "hex", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "hex", 1, [](VM* vm, ArgsView args) {
         SStream ss;
         ss.write_hex(CAST(i64, args[0]));
         return VAR(ss.str());
     });
 
-    _vm->bind_func<1>(_vm->builtins, "iter", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "iter", 1, [](VM* vm, ArgsView args) {
         return vm->py_iter(args[0]);
     });
 
-    _vm->bind_func<1>(_vm->builtins, "next", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "next", 1, [](VM* vm, ArgsView args) {
         PyObject* retval = vm->py_next(args[0]);
         if(retval == vm->StopIteration) vm->_error(vm->call(vm->StopIteration));
         return retval;
     });
 
-    _vm->bind_func<1>(_vm->builtins, "bin", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "bin", 1, [](VM* vm, ArgsView args) {
         SStream ss;
         i64 x = CAST(i64, args[0]);
         if(x < 0){ ss << "-"; x = -x; }
@@ -328,7 +328,7 @@ void init_builtins(VM* _vm) {
         return VAR(ss.str());
     });
 
-    _vm->bind_func<1>(_vm->builtins, "dir", [](VM* vm, ArgsView args) {
+    _vm->bind_func(_vm->builtins, "dir", 1, [](VM* vm, ArgsView args) {
         std::set<StrName> names;
         if(!is_tagged(args[0]) && args[0]->is_attr_valid()){
             auto keys = args[0]->attr().keys();
@@ -356,17 +356,17 @@ void init_builtins(VM* _vm) {
         return VAR(_0 == _1); 
     });
 
-    _vm->__cached_object_new = _vm->bind_constructor<1>(_vm->_t(VM::tp_object), [](VM* vm, ArgsView args) {
+    _vm->__cached_object_new = _vm->bind_func(VM::tp_object, __new__, 1, [](VM* vm, ArgsView args) {
         vm->check_type(args[0], vm->tp_type);
         Type t = PK_OBJ_GET(Type, args[0]);
         return vm->heap.gcnew<DummyInstance>(t);
     });
 
     // tp_type
-    _vm->bind_constructor<2>(_vm->_t(VM::tp_type), PK_LAMBDA(vm->_t(args[1])));
+    _vm->bind_func(VM::tp_type, __new__, 2, PK_LAMBDA(vm->_t(args[1])));
 
     // tp_range
-    _vm->bind_constructor<-1>(_vm->_t(VM::tp_range), [](VM* vm, ArgsView args) {
+    _vm->bind_func(VM::tp_range, __new__, -1, [](VM* vm, ArgsView args) {
         args._begin += 1;   // skip cls
         Range r;
         switch (args.size()) {
@@ -418,7 +418,7 @@ void init_builtins(VM* _vm) {
     _vm->bind__pow__(VM::tp_int, py_number_pow);
     _vm->bind__pow__(VM::tp_float, py_number_pow);
 
-    _vm->bind_constructor<-1>(_vm->_t(VM::tp_int), [](VM* vm, ArgsView args) {
+    _vm->bind_func(VM::tp_int, __new__, -1, [](VM* vm, ArgsView args) {
         if(args.size() == 1+0) return VAR(0);
         // 1 arg
         if(args.size() == 1+1){
@@ -493,7 +493,7 @@ void init_builtins(VM* _vm) {
 
 #undef INT_BITWISE_OP
 
-    _vm->bind_constructor<-1>(_vm->_t(VM::tp_float), [](VM* vm, ArgsView args) {
+    _vm->bind_func(VM::tp_float, __new__, -1, [](VM* vm, ArgsView args) {
         if(args.size() == 1+0) return VAR(0.0);
         if(args.size() > 1+1) vm->TypeError("float() takes at most 1 argument");
         // 1 arg
@@ -540,7 +540,7 @@ void init_builtins(VM* _vm) {
     });
 
     // tp_str
-    _vm->bind_constructor<-1>(_vm->_t(VM::tp_str), [](VM* vm, ArgsView args) {
+    _vm->bind_func(VM::tp_str, __new__, -1, [](VM* vm, ArgsView args) {
         if(args.size() == 1) return VAR(Str());
         if(args.size() > 2) vm->TypeError("str() takes at most 1 argument");
         return vm->py_str(args[1]);
@@ -831,7 +831,7 @@ void init_builtins(VM* _vm) {
         return VAR(ss.str());
     });
 
-    _vm->bind_constructor<-1>(_vm->_t(VM::tp_list), [](VM* vm, ArgsView args) {
+    _vm->bind_func(VM::tp_list, __new__, -1, [](VM* vm, ArgsView args) {
         if(args.size() == 1+0) return VAR(List());
         if(args.size() == 1+1) return vm->py_list(args[1]);
         vm->TypeError("list() takes 0 or 1 arguments");
@@ -1017,7 +1017,7 @@ void init_builtins(VM* _vm) {
         self.erase(i);
     });
 
-    _vm->bind_constructor<-1>(_vm->_t(VM::tp_tuple), [](VM* vm, ArgsView args) {
+    _vm->bind_func(VM::tp_tuple, __new__, -1, [](VM* vm, ArgsView args) {
         if(args.size() == 1+0) return VAR(Tuple(0));
         if(args.size() == 1+1){
             List list(CAST(List, vm->py_list(args[1])));
@@ -1071,7 +1071,7 @@ void init_builtins(VM* _vm) {
     });
 
     // tp_bool
-    _vm->bind_constructor<2>(_vm->_t(VM::tp_bool), PK_LAMBDA(VAR(vm->py_bool(args[1]))));
+    _vm->bind_func(VM::tp_bool, __new__, 2, PK_LAMBDA(VAR(vm->py_bool(args[1]))));
     _vm->bind__hash__(VM::tp_bool, [](VM* vm, PyObject* _0) {
         return (i64)_CAST(bool, _0);
     });
@@ -1104,7 +1104,7 @@ void init_builtins(VM* _vm) {
     });
 
     // tp_bytes
-    _vm->bind_constructor<2>(_vm->_t(VM::tp_bytes), [](VM* vm, ArgsView args){
+    _vm->bind_func(VM::tp_bytes, __new__, 2, [](VM* vm, ArgsView args){
         List& list = CAST(List&, args[1]);
         unsigned char* buffer = new unsigned char[list.size()];
         for(int i=0; i<list.size(); i++){
@@ -1175,7 +1175,7 @@ void init_builtins(VM* _vm) {
     });
     
     // tp_slice
-    _vm->bind_constructor<4>(_vm->_t(VM::tp_slice), [](VM* vm, ArgsView args) {
+    _vm->bind_func(VM::tp_slice, __new__, 4, [](VM* vm, ArgsView args) {
         return VAR(Slice(args[1], args[2], args[3]));
     });
 
@@ -1275,7 +1275,7 @@ void init_builtins(VM* _vm) {
     });
 
     // tp_dict
-    _vm->bind_constructor<-1>(_vm->_t(VM::tp_dict), [](VM* vm, ArgsView args){
+    _vm->bind_func(VM::tp_dict, __new__, -1, [](VM* vm, ArgsView args){
         Type cls_t = PK_OBJ_GET(Type, args[0]);
         return vm->heap.gcnew<Dict>(cls_t, vm);
     });
@@ -1450,7 +1450,7 @@ void init_builtins(VM* _vm) {
     });
 
     // tp_property
-    _vm->bind_constructor<-1>(_vm->_t(VM::tp_property), [](VM* vm, ArgsView args) {
+    _vm->bind_func(VM::tp_property, __new__, -1, [](VM* vm, ArgsView args) {
         if(args.size() == 1+1){
             return VAR(Property(args[1], vm->None));
         }else if(args.size() == 1+2){
@@ -1474,7 +1474,7 @@ void init_builtins(VM* _vm) {
     });
 
     // tp_exception
-    _vm->bind_constructor<-1>(_vm->_t(VM::tp_exception), [](VM* vm, ArgsView args){
+    _vm->bind_func(VM::tp_exception, __new__, -1, [](VM* vm, ArgsView args){
         Type cls = PK_OBJ_GET(Type, args[0]);
         StrName cls_name = _type_name(vm, cls);
         PyObject* e_obj = vm->heap.gcnew<Exception>(cls, cls_name);

+ 1 - 1
src/random.cpp

@@ -134,7 +134,7 @@ struct Random{
     }
 
     static void _register(VM* vm, PyObject* mod, PyObject* type){
-        vm->bind_func<1>(type, __new__, [](VM* vm, ArgsView args){
+        vm->bind_func(type, __new__, 1, [](VM* vm, ArgsView args){
             Type cls = PK_OBJ_GET(Type, args[0]);
             return vm->heap.gcnew<Random>(cls);
         });

+ 0 - 5
tests/99_builtin_func.py

@@ -301,11 +301,6 @@ assert type(repr(bytes([0x41, 0x42, 0x43]))) is str
 
 
 # /************ slice ************/
-# 未完全测试准确性-----------------------------------------------
-#       116:  953:    _vm->bind_constructor<4>("slice", [](VM* vm, ArgsView args) {
-#     #####:  954:        return VAR(Slice(args[1], args[2], args[3]));
-#         -:  955:    });
-# test slice:
 assert type(slice(0.1, 0.2, 0.3)) is slice