diff --git a/3rd/lua_bridge/src/lua_bridge.cpp b/3rd/lua_bridge/src/lua_bridge.cpp index e7ee296d..1d51c5b3 100644 --- a/3rd/lua_bridge/src/lua_bridge.cpp +++ b/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(PK_OBJ_GET(Type, args[0])); return obj; diff --git a/include/pocketpy/bindings.h b/include/pocketpy/bindings.h index 84bae6d1..92ac5e0e 100644 --- a/include/pocketpy/bindings.h +++ b/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::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(); \ diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index 7d435c3b..e1ca2093 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -310,12 +310,6 @@ public: template PyObject* bind_field(PyObject*, const char*, F T::*); - template - PyObject* bind_constructor(__T&& type, NativeFuncC fn) { - static_assert(ARGC==-1 || ARGC>=1); - return bind_func(std::forward<__T>(type), __new__, fn); - } - template PyObject* bind_notimplemented_constructor(__T&& type) { return bind_func<-1>(std::forward<__T>(type), __new__, [](VM* vm, ArgsView args){ diff --git a/src/base64.cpp b/src/base64.cpp index 5dc83ca2..3016f54c 100644 --- a/src/base64.cpp +++ b/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); diff --git a/src/cffi.cpp b/src/cffi.cpp index 8730aea0..c96b183e 100644 --- a/src/cffi.cpp +++ b/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(cls, reinterpret_cast(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(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(&val, sizeof(T)); \ }); \ diff --git a/src/dataclasses.cpp b/src/dataclasses.cpp index 7b40a273..ec17bc17 100644 --- a/src/dataclasses.cpp +++ b/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); diff --git a/src/easing.cpp b/src/easing.cpp index 14e4fb92..615d434d 100644 --- a/src/easing.cpp +++ b/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)); \ }); diff --git a/src/io.cpp b/src/io.cpp index e6d7ff76..a35829ae 100644 --- a/src/io.cpp +++ b/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(cls, vm, py_cast(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; ibind_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()); }); diff --git a/src/linalg.cpp b/src/linalg.cpp index 09aae4a5..a7abeaa6 100644 --- a/src/linalg.cpp +++ b/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(PK_OBJ_GET(Type, args[0]), Vec2(x, y)); + return vm->heap.gcnew(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(PK_OBJ_GET(Type, args[0]), Vec3(x, y, z)); + return vm->heap.gcnew(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(PK_OBJ_GET(Type, args[0]), Vec4(x, y, z, w)); + return vm->heap.gcnew(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(PK_OBJ_GET(Type, args[0]), Mat3x3::zeros()); if(args.size() == 1+1){ const List& list = CAST(List&, args[1]); diff --git a/src/modules.cpp b/src/modules.cpp index 18985b80..667fbc0b 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -44,12 +44,12 @@ void add_module_time(VM* vm){ PyObject* mod = vm->new_module("time"); vm->register_user_class(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(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(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::infinity())); mod->attr().set("nan", VAR(std::numeric_limits::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(cls); }); diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index 134dce67..63d80d3b 100644 --- a/src/pocketpy.cpp +++ b/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(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(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(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 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(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; ibind_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(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(cls, cls_name); diff --git a/src/random.cpp b/src/random.cpp index d8f8a7f1..b8b9ba40 100644 --- a/src/random.cpp +++ b/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(cls); }); diff --git a/tests/99_builtin_func.py b/tests/99_builtin_func.py index fddfd44b..3f3e091a 100644 --- a/tests/99_builtin_func.py +++ b/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