diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index 2ffdfe7d..e3d2ad55 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -353,11 +353,6 @@ public: }); } - template - PyObject* bind_builtin_func(Str name, NativeFuncC fn) { - return bind_func(builtins, name, fn); - } - int normalized_index(int index, int size); PyObject* py_next(PyObject* obj); diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index fce1ad77..d32097d2 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -48,7 +48,7 @@ void init_builtins(VM* _vm) { #undef BIND_NUM_ARITH_OPT #undef BIND_NUM_LOGICAL_OPT - _vm->bind_builtin_func<-1>("super", [](VM* vm, ArgsView args) { + _vm->bind_func<-1>(_vm->builtins, "super", [](VM* vm, ArgsView args) { PyObject* class_arg = nullptr; PyObject* self_arg = nullptr; if(args.size() == 2){ @@ -76,19 +76,19 @@ void init_builtins(VM* _vm) { return vm->heap.gcnew(vm->tp_super, self_arg, vm->_all_types[type].base); }); - _vm->bind_builtin_func<1>("staticmethod", [](VM* vm, ArgsView args) { + _vm->bind_func<1>(_vm->builtins, "staticmethod", [](VM* vm, ArgsView args) { PyObject* func = args[0]; vm->check_non_tagged_type(func, vm->tp_function); return vm->heap.gcnew(vm->tp_staticmethod, args[0]); }); - _vm->bind_builtin_func<1>("classmethod", [](VM* vm, ArgsView args) { + _vm->bind_func<1>(_vm->builtins, "classmethod", [](VM* vm, ArgsView args) { PyObject* func = args[0]; vm->check_non_tagged_type(func, vm->tp_function); return vm->heap.gcnew(vm->tp_classmethod, args[0]); }); - _vm->bind_builtin_func<2>("isinstance", [](VM* vm, ArgsView args) { + _vm->bind_func<2>(_vm->builtins, "isinstance", [](VM* vm, ArgsView args) { if(is_non_tagged_type(args[1], vm->tp_tuple)){ Tuple& types = _CAST(Tuple&, args[1]); for(PyObject* type : types){ @@ -102,13 +102,13 @@ void init_builtins(VM* _vm) { return VAR(vm->isinstance(args[0], type)); }); - _vm->bind_builtin_func<2>("issubclass", [](VM* vm, ArgsView args) { + _vm->bind_func<2>(_vm->builtins, "issubclass", [](VM* vm, ArgsView args) { vm->check_non_tagged_type(args[0], vm->tp_type); vm->check_non_tagged_type(args[1], vm->tp_type); return VAR(vm->issubclass(PK_OBJ_GET(Type, args[0]), PK_OBJ_GET(Type, args[1]))); }); - _vm->bind_builtin_func<0>("globals", [](VM* vm, ArgsView args) { + _vm->bind_func<0>(_vm->builtins, "globals", [](VM* vm, ArgsView args) { PyObject* mod = vm->top_frame()->_module; return VAR(MappingProxy(mod)); }); @@ -127,20 +127,20 @@ void init_builtins(VM* _vm) { } }); - _vm->bind_builtin_func<1>("abs", [](VM* vm, ArgsView args) { + _vm->bind_func<1>(_vm->builtins, "abs", [](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()"); return vm->None; }); - _vm->bind_builtin_func<1>("id", [](VM* vm, ArgsView args) { + _vm->bind_func<1>(_vm->builtins, "id", [](VM* vm, ArgsView args) { PyObject* obj = args[0]; if(is_tagged(obj)) return vm->None; return VAR(PK_BITS(obj)); }); - _vm->bind_builtin_func<1>("callable", [](VM* vm, ArgsView args) { + _vm->bind_func<1>(_vm->builtins, "callable", [](VM* vm, ArgsView args) { PyObject* cls = vm->_t(args[0]); switch(PK_OBJ_GET(Type, cls).index){ case VM::tp_function.index: return vm->True; @@ -152,12 +152,12 @@ void init_builtins(VM* _vm) { return VAR(ok); }); - _vm->bind_builtin_func<1>("__import__", [](VM* vm, ArgsView args) { + _vm->bind_func<1>(_vm->builtins, "__import__", [](VM* vm, ArgsView args) { const Str& name = CAST(Str&, args[0]); return vm->py_import(name); }); - _vm->bind_builtin_func<2>("divmod", [](VM* vm, ArgsView args) { + _vm->bind_func<2>(_vm->builtins, "divmod", [](VM* vm, ArgsView args) { if(is_int(args[0])){ i64 lhs = _CAST(i64, args[0]); i64 rhs = CAST(i64, args[1]); @@ -195,48 +195,48 @@ void init_builtins(VM* _vm) { return vm->None; }); - _vm->bind_builtin_func<-1>("exit", [](VM* vm, ArgsView args) { + _vm->bind_func<-1>(_vm->builtins, "exit", [](VM* vm, ArgsView args) { if(args.size() == 0) std::exit(0); else if(args.size() == 1) std::exit(CAST(int, args[0])); else vm->TypeError("exit() takes at most 1 argument"); return vm->None; }); - _vm->bind_builtin_func<1>("repr", PK_LAMBDA(vm->py_repr(args[0]))); + _vm->bind_func<1>(_vm->builtins, "repr", PK_LAMBDA(vm->py_repr(args[0]))); - _vm->bind_builtin_func<1>("len", [](VM* vm, ArgsView args){ + _vm->bind_func<1>(_vm->builtins, "len", [](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_builtin_func<1>("hash", [](VM* vm, ArgsView args){ + _vm->bind_func<1>(_vm->builtins, "hash", [](VM* vm, ArgsView args){ i64 value = vm->py_hash(args[0]); return VAR(value); }); - _vm->bind_builtin_func<1>("chr", [](VM* vm, ArgsView args) { + _vm->bind_func<1>(_vm->builtins, "chr", [](VM* vm, ArgsView args) { i64 i = CAST(i64, args[0]); if (i < 0 || i > 128) vm->ValueError("chr() arg not in range(128)"); return VAR(std::string(1, (char)i)); }); - _vm->bind_builtin_func<1>("ord", [](VM* vm, ArgsView args) { + _vm->bind_func<1>(_vm->builtins, "ord", [](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_builtin_func<2>("hasattr", [](VM* vm, ArgsView args) { + _vm->bind_func<2>(_vm->builtins, "hasattr", [](VM* vm, ArgsView args) { return VAR(vm->getattr(args[0], CAST(Str&, args[1]), false) != nullptr); }); - _vm->bind_builtin_func<3>("setattr", [](VM* vm, ArgsView args) { + _vm->bind_func<3>(_vm->builtins, "setattr", [](VM* vm, ArgsView args) { vm->setattr(args[0], CAST(Str&, args[1]), args[2]); return vm->None; }); - _vm->bind_builtin_func<-1>("getattr", [](VM* vm, ArgsView args) { + _vm->bind_func<-1>(_vm->builtins, "getattr", [](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); @@ -247,26 +247,26 @@ void init_builtins(VM* _vm) { return val; }); - _vm->bind_builtin_func<2>("delattr", [](VM* vm, ArgsView args) { + _vm->bind_func<2>(_vm->builtins, "delattr", [](VM* vm, ArgsView args) { vm->delattr(args[0], CAST(Str&, args[1])); return vm->None; }); - _vm->bind_builtin_func<1>("hex", [](VM* vm, ArgsView args) { + _vm->bind_func<1>(_vm->builtins, "hex", [](VM* vm, ArgsView args) { std::stringstream ss; // hex ss << std::hex << CAST(i64, args[0]); return VAR("0x" + ss.str()); }); - _vm->bind_builtin_func<1>("iter", [](VM* vm, ArgsView args) { + _vm->bind_func<1>(_vm->builtins, "iter", [](VM* vm, ArgsView args) { return vm->py_iter(args[0]); }); - _vm->bind_builtin_func<1>("next", [](VM* vm, ArgsView args) { + _vm->bind_func<1>(_vm->builtins, "next", [](VM* vm, ArgsView args) { return vm->py_next(args[0]); }); - _vm->bind_builtin_func<1>("bin", [](VM* vm, ArgsView args) { + _vm->bind_func<1>(_vm->builtins, "bin", [](VM* vm, ArgsView args) { SStream ss; i64 x = CAST(i64, args[0]); if(x < 0){ ss << "-"; x = -x; } @@ -282,7 +282,7 @@ void init_builtins(VM* _vm) { return VAR(ss.str()); }); - _vm->bind_builtin_func<1>("dir", [](VM* vm, ArgsView args) { + _vm->bind_func<1>(_vm->builtins, "dir", [](VM* vm, ArgsView args) { std::set names; if(!is_tagged(args[0]) && args[0]->is_attr_valid()){ std::vector keys = args[0]->attr().keys(); diff --git a/tests/99_builtin_func.py b/tests/99_builtin_func.py index cb6c6d1a..ebce2a56 100644 --- a/tests/99_builtin_func.py +++ b/tests/99_builtin_func.py @@ -95,29 +95,6 @@ try: except: pass -# 无法测试 ----------------------------------------------- -# 248: 192: _vm->bind_builtin_func<1>("__import__", [](VM* vm, ArgsView args) { -# 67: 193: const Str& name = CAST(Str&, args[0]); -# 67: 194: auto dot = name.sv().find_last_of("."); -# 67: 195: if(dot != std::string_view::npos){ -# #####: 196: auto ext = name.sv().substr(dot); -# #####: 197: if(ext == ".so" || ext == ".dll" || ext == ".dylib"){ -# #####: 198: dylib_entry_t entry = load_dylib(name.c_str()); -# #####: 199: if(!entry){ -# #####: 200: vm->_error("ImportError", "cannot load dynamic library: " + name.escape()); -# #####: 201: } -# #####: 202: vm->_c.s_view.push(ArgsView(vm->s_data.end(), vm->s_data.end())); -# #####: 203: const char* name = entry(vm, PK_VERSION); -# #####: 204: vm->_c.s_view.pop(); -# #####: 205: if(name == nullptr){ -# #####: 206: vm->_error("ImportError", "module initialization failed: " + Str(name).escape()); -# #####: 207: } -# #####: 208: return vm->_modules[name]; -# #####: 209: } -# #####: 210: } -# 67: 211: return vm->py_import(name); -# 67: 212: }); - # test hash: # 测试整数类型的输入 assert hash(0) == 0 @@ -168,38 +145,14 @@ try: except: pass - -# ----------------------------------------------- -# 114: 259: _vm->bind_builtin_func<1>("chr", [](VM* vm, ArgsView args) { -# #####: 260: i64 i = CAST(i64, args[0]); -# #####: 261: if (i < 0 || i > 128) vm->ValueError("chr() arg not in range(128)"); -# #####: 262: return VAR(std::string(1, (char)i)); -# #####: 263: }); # test chr l = [] for i in range(128): l.append(f'{i} {chr(i)}') assert l == ['0 \x00', '1 \x01', '2 \x02', '3 \x03', '4 \x04', '5 \x05', '6 \x06', '7 \x07', '8 \x08', '9 \t', '10 \n', '11 \x0b', '12 \x0c', '13 \r', '14 \x0e', '15 \x0f', '16 \x10', '17 \x11', '18 \x12', '19 \x13', '20 \x14', '21 \x15', '22 \x16', '23 \x17', '24 \x18', '25 \x19', '26 \x1a', '27 \x1b', '28 \x1c', '29 \x1d', '30 \x1e', '31 \x1f', '32 ', '33 !', '34 "', '35 #', '36 $', '37 %', '38 &', "39 '", '40 (', '41 )', '42 *', '43 +', '44 ,', '45 -', '46 .', '47 /', '48 0', '49 1', '50 2', '51 3', '52 4', '53 5', '54 6', '55 7', '56 8', '57 9', '58 :', '59 ;', '60 <', '61 =', '62 >', '63 ?', '64 @', '65 A', '66 B', '67 C', '68 D', '69 E', '70 F', '71 G', '72 H', '73 I', '74 J', '75 K', '76 L', '77 M', '78 N', '79 O', '80 P', '81 Q', '82 R', '83 S', '84 T', '85 U', '86 V', '87 W', '88 X', '89 Y', '90 Z', '91 [', '92 \\', '93 ]', '94 ^', '95 _', '96 `', '97 a', '98 b', '99 c', '100 d', '101 e', '102 f', '103 g', '104 h', '105 i', '106 j', '107 k', '108 l', '109 m', '110 n', '111 o', '112 p', '113 q', '114 r', '115 s', '116 t', '117 u', '118 v', '119 w', '120 x', '121 y', '122 z', '123 {', '124 |', '125 }', '126 ~', '127 \x7f'] - assert type(bin(1234)) is str -# 无法测试, 不能覆盖----------------------------------------------- -# 136: 285: _vm->bind_builtin_func<1>("dir", [](VM* vm, ArgsView args) { -# 10: 286: std::set names; -# 10: 287: if(!is_tagged(args[0]) && args[0]->is_attr_valid()){ -# #####: 288: std::vector keys = args[0]->attr().keys(); -# #####: 289: names.insert(keys.begin(), keys.end()); -# #####: 290: } -# 10: 291: const NameDict& t_attr = vm->_t(args[0])->attr(); -# 10: 292: std::vector keys = t_attr.keys(); -# 10: 293: names.insert(keys.begin(), keys.end()); -# 10: 294: List ret; -# 305: 295: for (StrName name : names) ret.push_back(VAR(name.sv())); -# 10: 296: return VAR(std::move(ret)); -# 10: 297: }); -# test dir: - # test __repr__: class A(): def __init__(self):