This commit is contained in:
blueloveTH 2023-02-27 23:45:16 +08:00
parent 6a82644f9a
commit b0e2c6e489
5 changed files with 42 additions and 50 deletions

View File

@ -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<bool>(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<bool>(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<bool>(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<Exception>(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);

View File

@ -89,13 +89,13 @@ struct Pointer{
vm->bind_method<1>(type, "__eq__", [](VM* vm, Args& args) {
Pointer& self = vm->_cast<Pointer>(args[0]);
Pointer& other = vm->_cast<Pointer>(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<Pointer>(args[0]);
Pointer& other = vm->_cast<Pointer>(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<int>());
case C_TYPE("float_"): return py_object(vm, ref<float>());
case C_TYPE("double_"): return py_object(vm, ref<double>());
case C_TYPE("bool_"): return vm->PyBool(ref<bool>());
case C_TYPE("bool_"): return py_object(vm, ref<bool>());
case C_TYPE("void_"): vm->ValueError("cannot get void*"); break;
case C_TYPE("int8_"): return py_object(vm, ref<int8_t>());
case C_TYPE("int16_"): return py_object(vm, ref<int16_t>());
@ -168,7 +168,7 @@ struct Pointer{
case C_TYPE("int_"): ref<int>() = py_cast_v<i64>(vm, val); break;
case C_TYPE("float_"): ref<float>() = py_cast_v<f64>(vm, val); break;
case C_TYPE("double_"): ref<double>() = py_cast_v<f64>(vm, val); break;
case C_TYPE("bool_"): ref<bool>() = vm->PyBool_AS_C(val); break;
case C_TYPE("bool_"): ref<bool>() = py_cast_v<bool>(vm, val); break;
case C_TYPE("void_"): vm->ValueError("cannot set void*"); break;
case C_TYPE("int8_"): ref<int8_t>() = py_cast_v<i64>(vm, val); break;
case C_TYPE("int16_"): ref<int16_t>() = py_cast_v<i64>(vm, val); break;

View File

@ -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;

View File

@ -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<i64>(vm, args[0]) op _py_cast_v<i64>(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<i64>(vm, args[0]) op _py_cast_v<i64>(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<Str>(vm, args[1]), false) != nullptr);
return py_object(vm, vm->getattr(args[0], py_cast<Str>(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<f64>(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<bool>(vm, args[0]) ? 1 : 0);
if (is_type(args[0], vm->tp_str)) {
const Str& s = py_cast<Str>(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<i64>(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<bool>(vm, args[0]) ? 1.0 : 0.0);
if (is_type(args[0], vm->tp_str)) {
const Str& s = py_cast<Str>(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<Str>(vm, args[0]);
const Str& other = py_cast<Str>(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<Str>(vm, args[0]) == py_cast<Str>(vm, args[1]));
return vm->PyBool(args[0] == args[1]);
return py_object(vm, py_cast<Str>(vm, args[0]) == py_cast<Str>(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<Str>(vm, args[0]) != py_cast<Str>(vm, args[1]));
return vm->PyBool(args[0] != args[1]);
return py_object(vm, py_cast<Str>(vm, args[0]) != py_cast<Str>(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<Str>(vm, args[0]));
const Str& obj (py_cast<Str>(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<Str>(vm, args[0]));
const Str& obj (py_cast<Str>(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<Str>(vm, args[0]);
const Str& _prefix = py_cast<Str>(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<Str>(vm, args[0]);
const Str& _suffix = py_cast<Str>(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<bool>(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<bool>(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<bool>(vm, args[0]);
bool other = py_cast_v<bool>(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;

View File

@ -247,14 +247,6 @@ public:
return static_cast<BaseIter*>(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<f64>(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<bool>(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<i64>(this, obj) != 0);
if(is_type(obj, tp_float)) return PyBool(py_cast_v<f64>(this, obj) != 0.0);
if(is_type(obj, tp_int)) return py_object(this, py_cast_v<i64>(this, obj) != 0);
if(is_type(obj, tp_float)) return py_object(this, py_cast_v<f64>(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<i64>(this, ret) > 0);
return py_object(this, py_cast_v<i64>(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<bool>(this, obj) ? 1 : 0;
if (is_float(obj)){
f64 val = py_cast_v<f64>(this, obj);
return (i64)std::hash<f64>()(val);