diff --git a/src/ceval.h b/src/ceval.h index 6681479c..78841579 100644 --- a/src/ceval.h +++ b/src/ceval.h @@ -150,13 +150,13 @@ PyVar VM::run_frame(Frame* frame){ PyVar rhs = frame->pop_value(this); bool ret_c = rhs == frame->top_value(this); if(byte.arg == 1) ret_c = !ret_c; - frame->top() = PyBool(ret_c); + frame->top() = py_object(this, ret_c); } continue; case OP_CONTAINS_OP: { PyVar rhs = frame->pop_value(this); - bool ret_c = PyBool_AS_C(call(rhs, __contains__, one_arg(frame->pop_value(this)))); + bool ret_c = py_cast_v(this, call(rhs, __contains__, one_arg(frame->pop_value(this)))); if(byte.arg == 1) ret_c = !ret_c; - frame->push(PyBool(ret_c)); + frame->push(py_object(this, ret_c)); } continue; case OP_UNARY_NEGATIVE: frame->top() = num_negated(frame->top_value(this)); @@ -164,10 +164,10 @@ PyVar VM::run_frame(Frame* frame){ case OP_UNARY_NOT: { PyVar obj = frame->pop_value(this); const PyVar& obj_bool = asBool(obj); - frame->push(PyBool(!_PyBool_AS_C(obj_bool))); + frame->push(py_object(this, !_py_cast_v(this, obj_bool))); } continue; case OP_POP_JUMP_IF_FALSE: - if(!_PyBool_AS_C(asBool(frame->pop_value(this)))) frame->jump_abs(byte.arg); + if(!_py_cast_v(this, asBool(frame->pop_value(this)))) frame->jump_abs(byte.arg); continue; case OP_LOAD_NONE: frame->push(None); continue; case OP_LOAD_TRUE: frame->push(True); continue; @@ -182,7 +182,7 @@ PyVar VM::run_frame(Frame* frame){ case OP_EXCEPTION_MATCH: { const auto& e = py_cast(this, frame->top()); StrName name = frame->co->names[byte.arg].first; - frame->push(PyBool(e.match_type(name))); + frame->push(py_object(this, e.match_type(name))); } continue; case OP_RAISE: { PyVar obj = frame->pop_value(this); diff --git a/src/cffi.h b/src/cffi.h index 6d3ed055..7ba80a20 100644 --- a/src/cffi.h +++ b/src/cffi.h @@ -89,13 +89,13 @@ struct Pointer{ vm->bind_method<1>(type, "__eq__", [](VM* vm, Args& args) { Pointer& self = vm->_cast(args[0]); Pointer& other = vm->_cast(args[1]); - return vm->PyBool(self.ptr == other.ptr); + return py_object(vm, self.ptr == other.ptr); }); vm->bind_method<1>(type, "__ne__", [](VM* vm, Args& args) { Pointer& self = vm->_cast(args[0]); Pointer& other = vm->_cast(args[1]); - return vm->PyBool(self.ptr != other.ptr); + return py_object(vm, self.ptr != other.ptr); }); // https://docs.python.org/zh-cn/3/library/ctypes.html @@ -145,7 +145,7 @@ struct Pointer{ case C_TYPE("int_"): return py_object(vm, ref()); case C_TYPE("float_"): return py_object(vm, ref()); case C_TYPE("double_"): return py_object(vm, ref()); - case C_TYPE("bool_"): return vm->PyBool(ref()); + case C_TYPE("bool_"): return py_object(vm, ref()); case C_TYPE("void_"): vm->ValueError("cannot get void*"); break; case C_TYPE("int8_"): return py_object(vm, ref()); case C_TYPE("int16_"): return py_object(vm, ref()); @@ -168,7 +168,7 @@ struct Pointer{ case C_TYPE("int_"): ref() = py_cast_v(vm, val); break; case C_TYPE("float_"): ref() = py_cast_v(vm, val); break; case C_TYPE("double_"): ref() = py_cast_v(vm, val); break; - case C_TYPE("bool_"): ref() = vm->PyBool_AS_C(val); break; + case C_TYPE("bool_"): ref() = py_cast_v(vm, val); break; case C_TYPE("void_"): vm->ValueError("cannot set void*"); break; case C_TYPE("int8_"): ref() = py_cast_v(vm, val); break; case C_TYPE("int16_"): ref() = py_cast_v(vm, val); break; diff --git a/src/compiler.h b/src/compiler.h index 6a8436c5..b8a3de7e 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -1101,8 +1101,8 @@ __LISTCOMP: } if(match(TK("@num"))) return parser->prev.value; if(match(TK("@str"))) return parser->prev.value; - if(match(TK("True"))) return vm->PyBool(true); - if(match(TK("False"))) return vm->PyBool(false); + if(match(TK("True"))) return py_object(vm, true); + if(match(TK("False"))) return py_object(vm, false); if(match(TK("None"))) return vm->None; if(match(TK("..."))) return vm->Ellipsis; return nullptr; diff --git a/src/pocketpy.h b/src/pocketpy.h index 021b1c58..c3d4282a 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -31,12 +31,12 @@ CodeObject_ VM::compile(Str source, Str filename, CompileMode mode) { #define BIND_NUM_LOGICAL_OPT(name, op, is_eq) \ _vm->_bind_methods<1>({"int","float"}, #name, [](VM* vm, Args& args){ \ if(!is_both_int_or_float(args[0], args[1])){ \ - if constexpr(is_eq) return vm->PyBool(args[0] op args[1]); \ + if constexpr(is_eq) return py_object(vm, args[0] op args[1]); \ vm->TypeError("unsupported operand type(s) for " #op ); \ } \ if(is_both_int(args[0], args[1])) \ - return vm->PyBool(_py_cast_v(vm, args[0]) op _py_cast_v(vm, args[1])); \ - return vm->PyBool(vm->num_to_float(args[0]) op vm->num_to_float(args[1])); \ + return py_object(vm, _py_cast_v(vm, args[0]) op _py_cast_v(vm, args[1])); \ + return py_object(vm, vm->num_to_float(args[0]) op vm->num_to_float(args[1])); \ }); @@ -117,7 +117,7 @@ void init_builtins(VM* _vm) { }); _vm->bind_builtin_func<2>("hasattr", [](VM* vm, Args& args) { - return vm->PyBool(vm->getattr(args[0], py_cast(vm, args[1]), false) != nullptr); + return py_object(vm, vm->getattr(args[0], py_cast(vm, args[1]), false) != nullptr); }); _vm->bind_builtin_func<3>("setattr", [](VM* vm, Args& args) { @@ -159,8 +159,8 @@ void init_builtins(VM* _vm) { return py_object(vm, s); }); - _vm->bind_method<1>("object", "__eq__", CPP_LAMBDA(vm->PyBool(args[0] == args[1]))); - _vm->bind_method<1>("object", "__ne__", CPP_LAMBDA(vm->PyBool(args[0] != args[1]))); + _vm->bind_method<1>("object", "__eq__", CPP_LAMBDA(py_object(vm, args[0] == args[1]))); + _vm->bind_method<1>("object", "__ne__", CPP_LAMBDA(py_object(vm, args[0] != args[1]))); _vm->bind_static_method<1>("type", "__new__", CPP_LAMBDA(vm->_t(args[0]))); @@ -211,7 +211,7 @@ void init_builtins(VM* _vm) { _vm->bind_static_method<1>("int", "__new__", [](VM* vm, Args& args) { if (is_type(args[0], vm->tp_int)) return args[0]; if (is_type(args[0], vm->tp_float)) return py_object(vm, (i64)py_cast_v(vm, args[0])); - if (is_type(args[0], vm->tp_bool)) return py_object(vm, vm->_PyBool_AS_C(args[0]) ? 1 : 0); + if (is_type(args[0], vm->tp_bool)) return py_object(vm, _py_cast_v(vm, args[0]) ? 1 : 0); if (is_type(args[0], vm->tp_str)) { const Str& s = py_cast(vm, args[0]); try{ @@ -257,7 +257,7 @@ void init_builtins(VM* _vm) { _vm->bind_static_method<1>("float", "__new__", [](VM* vm, Args& args) { if (is_type(args[0], vm->tp_int)) return py_object(vm, (f64)py_cast_v(vm, args[0])); if (is_type(args[0], vm->tp_float)) return args[0]; - if (is_type(args[0], vm->tp_bool)) return py_object(vm, vm->_PyBool_AS_C(args[0]) ? 1.0 : 0.0); + if (is_type(args[0], vm->tp_bool)) return py_object(vm, _py_cast_v(vm, args[0]) ? 1.0 : 0.0); if (is_type(args[0], vm->tp_str)) { const Str& s = py_cast(vm, args[0]); if(s == "inf") return py_object(vm, INFINITY); @@ -306,7 +306,7 @@ void init_builtins(VM* _vm) { _vm->bind_method<1>("str", "__contains__", [](VM* vm, Args& args) { const Str& self = py_cast(vm, args[0]); const Str& other = py_cast(vm, args[1]); - return vm->PyBool(self.find(other) != Str::npos); + return py_object(vm, self.find(other) != Str::npos); }); _vm->bind_method<0>("str", "__str__", CPP_LAMBDA(args[0])); @@ -324,14 +324,14 @@ void init_builtins(VM* _vm) { _vm->bind_method<1>("str", "__eq__", [](VM* vm, Args& args) { if(is_type(args[0], vm->tp_str) && is_type(args[1], vm->tp_str)) - return vm->PyBool(py_cast(vm, args[0]) == py_cast(vm, args[1])); - return vm->PyBool(args[0] == args[1]); + return py_object(vm, py_cast(vm, args[0]) == py_cast(vm, args[1])); + return py_object(vm, args[0] == args[1]); }); _vm->bind_method<1>("str", "__ne__", [](VM* vm, Args& args) { if(is_type(args[0], vm->tp_str) && is_type(args[1], vm->tp_str)) - return vm->PyBool(py_cast(vm, args[0]) != py_cast(vm, args[1])); - return vm->PyBool(args[0] != args[1]); + return py_object(vm, py_cast(vm, args[0]) != py_cast(vm, args[1])); + return py_object(vm, args[0] != args[1]); }); _vm->bind_method<1>("str", "__getitem__", [](VM* vm, Args& args) { @@ -351,13 +351,13 @@ void init_builtins(VM* _vm) { _vm->bind_method<1>("str", "__gt__", [](VM* vm, Args& args) { const Str& self (py_cast(vm, args[0])); const Str& obj (py_cast(vm, args[1])); - return vm->PyBool(self > obj); + return py_object(vm, self > obj); }); _vm->bind_method<1>("str", "__lt__", [](VM* vm, Args& args) { const Str& self (py_cast(vm, args[0])); const Str& obj (py_cast(vm, args[1])); - return vm->PyBool(self < obj); + return py_object(vm, self < obj); }); _vm->bind_method<2>("str", "replace", [](VM* vm, Args& args) { @@ -377,13 +377,13 @@ void init_builtins(VM* _vm) { _vm->bind_method<1>("str", "startswith", [](VM* vm, Args& args) { const Str& _self = py_cast(vm, args[0]); const Str& _prefix = py_cast(vm, args[1]); - return vm->PyBool(_self.find(_prefix) == 0); + return py_object(vm, _self.find(_prefix) == 0); }); _vm->bind_method<1>("str", "endswith", [](VM* vm, Args& args) { const Str& _self = py_cast(vm, args[0]); const Str& _suffix = py_cast(vm, args[1]); - return vm->PyBool(_self.rfind(_suffix) == _self.length() - _suffix.length()); + return py_object(vm, _self.rfind(_suffix) == _self.length() - _suffix.length()); }); _vm->bind_method<1>("str", "join", [](VM* vm, Args& args) { @@ -521,19 +521,19 @@ void init_builtins(VM* _vm) { _vm->bind_static_method<1>("bool", "__new__", CPP_LAMBDA(vm->asBool(args[0]))); _vm->bind_method<0>("bool", "__repr__", [](VM* vm, Args& args) { - bool val = vm->PyBool_AS_C(args[0]); + bool val = py_cast_v(vm, args[0]); return py_object(vm, val ? "True" : "False"); }); _vm->bind_method<0>("bool", "__json__", [](VM* vm, Args& args) { - bool val = vm->PyBool_AS_C(args[0]); + bool val = py_cast_v(vm, args[0]); return py_object(vm, val ? "true" : "false"); }); _vm->bind_method<1>("bool", "__xor__", [](VM* vm, Args& args) { - bool self = vm->PyBool_AS_C(args[0]); - bool other = vm->PyBool_AS_C(args[1]); - return vm->PyBool(self ^ other); + bool self = py_cast_v(vm, args[0]); + bool other = py_cast_v(vm, args[1]); + return py_object(vm, self ^ other); }); _vm->bind_method<0>("ellipsis", "__repr__", CPP_LAMBDA(py_object(vm, "Ellipsis"))); @@ -596,8 +596,8 @@ void add_module_math(VM* vm){ vm->bind_func<1>(mod, "sin", CPP_LAMBDA(py_object(vm, std::sin(vm->num_to_float(args[0]))))); vm->bind_func<1>(mod, "cos", CPP_LAMBDA(py_object(vm, std::cos(vm->num_to_float(args[0]))))); vm->bind_func<1>(mod, "tan", CPP_LAMBDA(py_object(vm, std::tan(vm->num_to_float(args[0]))))); - vm->bind_func<1>(mod, "isnan", CPP_LAMBDA(vm->PyBool(std::isnan(vm->num_to_float(args[0]))))); - vm->bind_func<1>(mod, "isinf", CPP_LAMBDA(vm->PyBool(std::isinf(vm->num_to_float(args[0]))))); + vm->bind_func<1>(mod, "isnan", CPP_LAMBDA(py_object(vm, std::isnan(vm->num_to_float(args[0]))))); + vm->bind_func<1>(mod, "isinf", CPP_LAMBDA(py_object(vm, std::isinf(vm->num_to_float(args[0]))))); vm->bind_func<1>(mod, "fabs", CPP_LAMBDA(py_object(vm, std::fabs(vm->num_to_float(args[0]))))); vm->bind_func<1>(mod, "floor", CPP_LAMBDA(py_object(vm, (i64)std::floor(vm->num_to_float(args[0]))))); vm->bind_func<1>(mod, "ceil", CPP_LAMBDA(py_object(vm, (i64)std::ceil(vm->num_to_float(args[0]))))); @@ -977,7 +977,7 @@ extern "C" { switch(ret_code){ case 'i': return py_object(vm, f_int(packet)); case 'f': return py_object(vm, f_float(packet)); - case 'b': return vm->PyBool(f_bool(packet)); + case 'b': return py_object(vm, f_bool(packet)); case 's': { char* p = f_str(packet); if(p == nullptr) return vm->None; diff --git a/src/vm.h b/src/vm.h index 0399e19e..5aba9055 100644 --- a/src/vm.h +++ b/src/vm.h @@ -247,14 +247,6 @@ public: return static_cast(obj->value()); } - // there is only one True/False, so no need to copy them! - inline bool PyBool_AS_C(const PyVar& obj){ - check_type(obj, tp_bool); - return obj == True; - } - inline bool _PyBool_AS_C(const PyVar& obj){ return obj == True; } - inline const PyVar& PyBool(bool value){return value ? True : False;} - /***** Error Reporter *****/ void _error(StrName name, const Str& msg){ _error(Exception(name, msg)); @@ -433,7 +425,7 @@ template<> f64 _py_cast_v(VM* vm, const PyVar& obj){ return __8B(bits)._float; } -PyVar py_object(VM* vm, bool val){ +const PyVar& py_object(VM* vm, bool val){ return val ? vm->True : vm->False; } template<> bool py_cast_v(VM* vm, const PyVar& obj){ @@ -471,12 +463,12 @@ f64 VM::num_to_float(const PyVar& obj){ const PyVar& VM::asBool(const PyVar& obj){ if(is_type(obj, tp_bool)) return obj; if(obj == None) return False; - if(is_type(obj, tp_int)) return PyBool(py_cast_v(this, obj) != 0); - if(is_type(obj, tp_float)) return PyBool(py_cast_v(this, obj) != 0.0); + if(is_type(obj, tp_int)) return py_object(this, py_cast_v(this, obj) != 0); + if(is_type(obj, tp_float)) return py_object(this, py_cast_v(this, obj) != 0.0); PyVarOrNull len_fn = getattr(obj, __len__, false); if(len_fn != nullptr){ PyVar ret = call(len_fn); - return PyBool(py_cast_v(this, ret) > 0); + return py_object(this, py_cast_v(this, ret) > 0); } return True; } @@ -494,7 +486,7 @@ i64 VM::hash(const PyVar& obj){ return x; } if (is_type(obj, tp_type)) return obj.bits; - if (is_type(obj, tp_bool)) return _PyBool_AS_C(obj) ? 1 : 0; + if (is_type(obj, tp_bool)) return _py_cast_v(this, obj) ? 1 : 0; if (is_float(obj)){ f64 val = py_cast_v(this, obj); return (i64)std::hash()(val);