fix everything

This commit is contained in:
blueloveTH 2024-06-16 20:54:12 +08:00
parent e14d4e295a
commit 8edb46afb4
9 changed files with 52 additions and 47 deletions

View File

@ -242,7 +242,7 @@ public:
List py_list(PyVar); // x -> list(x) List py_list(PyVar); // x -> list(x)
bool py_callable(PyVar obj); // x -> callable(x) bool py_callable(PyVar obj); // x -> callable(x)
bool py_bool(PyVar obj){ // x -> bool(x) bool py_bool(PyVar obj){ // x -> bool(x)
if(obj.type == tp_bool) return obj._bool; if(obj.type == tp_bool) return (bool)obj.extra;
return __py_bool_non_trivial(obj); return __py_bool_non_trivial(obj);
} }
i64 py_hash(PyVar obj); // x -> hash(x) i64 py_hash(PyVar obj); // x -> hash(x)
@ -604,7 +604,7 @@ __T _py_cast__internal(VM* vm, PyVar obj) {
vm->TypeError("expected 'bool', got " + _type_name(vm, vm->_tp(obj)).escape()); vm->TypeError("expected 'bool', got " + _type_name(vm, vm->_tp(obj)).escape());
} }
} }
return obj._bool; return (bool)obj.extra;
} else if constexpr(is_integral_v<T>) { } else if constexpr(is_integral_v<T>) {
static_assert(!std::is_reference_v<__T>); static_assert(!std::is_reference_v<__T>);
// int // int

View File

@ -41,17 +41,18 @@ typedef struct PyVar{
static_assert(sizeof(PyVar) == 16, "sizeof(PyVar) != 16"); static_assert(sizeof(PyVar) == 16, "sizeof(PyVar) != 16");
extern const pkpy_Type tp_object, tp_type; /* predefined vars */
extern const pkpy_Type tp_int, tp_float, tp_bool, tp_str; static const pkpy_Type tp_object = 1, tp_type = 2;
extern const pkpy_Type tp_list, tp_tuple; static const pkpy_Type tp_int = 3, tp_float = 4, tp_bool = 5, tp_str = 6;
extern const pkpy_Type tp_slice, tp_range, tp_module; static const pkpy_Type tp_list = 7, tp_tuple = 8;
extern const pkpy_Type tp_function, tp_native_func, tp_bound_method; static const pkpy_Type tp_slice = 9, tp_range = 10, tp_module = 11;
extern const pkpy_Type tp_super, tp_exception, tp_bytes, tp_mappingproxy; static const pkpy_Type tp_function = 12, tp_native_func = 13, tp_bound_method = 14;
extern const pkpy_Type tp_dict, tp_property, tp_star_wrapper; static const pkpy_Type tp_super = 15, tp_exception = 16, tp_bytes = 17, tp_mappingproxy = 18;
extern const pkpy_Type tp_staticmethod, tp_classmethod; static const pkpy_Type tp_dict = 19, tp_property = 20, tp_star_wrapper = 21;
extern const pkpy_Type tp_none_type, tp_not_implemented_type; static const pkpy_Type tp_staticmethod = 22, tp_classmethod = 23;
extern const pkpy_Type tp_ellipsis; static const pkpy_Type tp_none_type = 24, tp_not_implemented_type = 25;
extern const pkpy_Type tp_op_call, tp_op_yield; static const pkpy_Type tp_ellipsis = 26;
static const pkpy_Type tp_op_call = 27, tp_op_yield = 28;
PK_INLINE bool PyVar__is_null(const PyVar* self) { return self->type == 0; } PK_INLINE bool PyVar__is_null(const PyVar* self) { return self->type == 0; }
PK_INLINE int64_t PyVar__hash(const PyVar* self) { return self->extra + self->_i64; } PK_INLINE int64_t PyVar__hash(const PyVar* self) { return self->extra + self->_i64; }

View File

@ -67,25 +67,25 @@ void VM::__op_unpack_sequence(uint16_t arg) {
bool VM::py_lt(PyVar _0, PyVar _1) { bool VM::py_lt(PyVar _0, PyVar _1) {
BINARY_F_COMPARE(__lt__, "<", __gt__); BINARY_F_COMPARE(__lt__, "<", __gt__);
assert(ret.type == tp_bool); assert(ret.type == tp_bool);
return ret._bool; return ret.extra;
} }
bool VM::py_le(PyVar _0, PyVar _1) { bool VM::py_le(PyVar _0, PyVar _1) {
BINARY_F_COMPARE(__le__, "<=", __ge__); BINARY_F_COMPARE(__le__, "<=", __ge__);
assert(ret.type == tp_bool); assert(ret.type == tp_bool);
return ret._bool; return ret.extra;
} }
bool VM::py_gt(PyVar _0, PyVar _1) { bool VM::py_gt(PyVar _0, PyVar _1) {
BINARY_F_COMPARE(__gt__, ">", __lt__); BINARY_F_COMPARE(__gt__, ">", __lt__);
assert(ret.type == tp_bool); assert(ret.type == tp_bool);
return ret._bool; return ret.extra;
} }
bool VM::py_ge(PyVar _0, PyVar _1) { bool VM::py_ge(PyVar _0, PyVar _1) {
BINARY_F_COMPARE(__ge__, ">=", __le__); BINARY_F_COMPARE(__ge__, ">=", __le__);
assert(ret.type == tp_bool); assert(ret.type == tp_bool);
return ret._bool; return ret.extra;
} }
#undef BINARY_F_COMPARE #undef BINARY_F_COMPARE

View File

@ -60,7 +60,7 @@ struct JsonSerializer {
if(std::isinf(val) || std::isnan(val)) vm->ValueError("cannot jsonify 'nan' or 'inf'"); if(std::isinf(val) || std::isnan(val)) vm->ValueError("cannot jsonify 'nan' or 'inf'");
ss << val; ss << val;
} else if(obj_t == vm->tp_bool) { } else if(obj_t == vm->tp_bool) {
ss << (obj._bool ? "true" : "false"); ss << (obj.extra ? "true" : "false");
} else if(obj_t == vm->tp_str) { } else if(obj_t == vm->tp_str) {
ss << _CAST(Str&, obj).escape('"'); ss << _CAST(Str&, obj).escape('"');
} else if(obj_t == vm->tp_list) { } else if(obj_t == vm->tp_list) {
@ -235,18 +235,18 @@ bool VM::py_eq(PyVar lhs, PyVar rhs) {
PyVar res; PyVar res;
if(ti->m__eq__) { if(ti->m__eq__) {
res = ti->m__eq__(this, lhs, rhs); res = ti->m__eq__(this, lhs, rhs);
if(!is_not_implemented(res)) return res._bool; if(!is_not_implemented(res)) return res.extra;
} }
res = call_method(lhs, __eq__, rhs); res = call_method(lhs, __eq__, rhs);
if(!is_not_implemented(res)) return res._bool; if(!is_not_implemented(res)) return res.extra;
ti = _tp_info(rhs); ti = _tp_info(rhs);
if(ti->m__eq__) { if(ti->m__eq__) {
res = ti->m__eq__(this, rhs, lhs); res = ti->m__eq__(this, rhs, lhs);
if(!is_not_implemented(res)) return res._bool; if(!is_not_implemented(res)) return res.extra;
} }
res = call_method(rhs, __eq__, lhs); res = call_method(rhs, __eq__, lhs);
if(!is_not_implemented(res)) return res._bool; if(!is_not_implemented(res)) return res.extra;
return false; return false;
} }

View File

@ -1,23 +1,5 @@
#include "pocketpy/objects/base.h" #include "pocketpy/objects/base.h"
/* predefined vars */
const pkpy_Type tp_object = 1, tp_type = 2;
const pkpy_Type tp_int = 3, tp_float = 4, tp_bool = 5, tp_str = 6;
const pkpy_Type tp_list = 7, tp_tuple = 8;
const pkpy_Type tp_slice = 9, tp_range = 10, tp_module = 11;
const pkpy_Type tp_function = 12, tp_native_func = 13, tp_bound_method = 14;
const pkpy_Type tp_super = 15, tp_exception = 16, tp_bytes = 17, tp_mappingproxy = 18;
const pkpy_Type tp_dict = 19, tp_property = 20, tp_star_wrapper = 21;
const pkpy_Type tp_staticmethod = 22, tp_classmethod = 23;
const pkpy_Type tp_none_type = 24, tp_not_implemented_type = 25;
const pkpy_Type tp_ellipsis = 26;
const pkpy_Type tp_op_call = 27, tp_op_yield = 28;
PyVar pkpy_True = {.type=tp_bool, .is_ptr=false, ._bool=true};
PyVar pkpy_False = {.type=tp_bool, .is_ptr=false, ._bool=false};
PyVar pkpy_None = {.type=tp_none_type, .is_ptr=false};
PyVar pkpy_NotImplemented = {.type=tp_not_implemented_type, .is_ptr=false};
PyVar pkpy_Ellipsis = {.type=tp_ellipsis, .is_ptr=false};
PyVar pkpy_NULL = {.type=0, .is_ptr=false}; PyVar pkpy_NULL = {.type=0, .is_ptr=false};
PyVar pkpy_OP_CALL = {.type=tp_op_call, .is_ptr=false}; PyVar pkpy_OP_CALL = {.type=tp_op_call, .is_ptr=false};
PyVar pkpy_OP_YIELD = {.type=tp_op_yield, .is_ptr=false}; PyVar pkpy_OP_YIELD = {.type=tp_op_yield, .is_ptr=false};

View File

@ -6,3 +6,16 @@ void PyVar__ctor3(PyVar* self, PyObject* existing){
self->is_ptr = true; self->is_ptr = true;
self->_obj = existing; self->_obj = existing;
} }
static PyObject __true_obj = {.type=tp_bool, .gc_is_large=false, .gc_marked=false, ._attr=NULL};
static PyObject __false_obj = {.type=tp_bool, .gc_is_large=false, .gc_marked=false, ._attr=NULL};
static PyObject __none_obj = {.type=tp_none_type, .gc_is_large=false, .gc_marked=false, ._attr=NULL};
static PyObject __not_implemented_obj = {.type=tp_not_implemented_type, .gc_is_large=false, .gc_marked=false, ._attr=NULL};
static PyObject __ellipsis_obj = {.type=tp_ellipsis, .gc_is_large=false, .gc_marked=false, ._attr=NULL};
/* Must be heap objects to support `==` and `is` and `is not` */
PyVar pkpy_True = {.type=tp_bool, .is_ptr=true, .extra=1, ._obj=&__true_obj};
PyVar pkpy_False = {.type=tp_bool, .is_ptr=true, .extra=0, ._obj=&__false_obj};
PyVar pkpy_None = {.type=tp_none_type, .is_ptr=true, ._obj=&__none_obj};
PyVar pkpy_NotImplemented = {.type=tp_not_implemented_type, .is_ptr=true, ._obj=&__not_implemented_obj};
PyVar pkpy_Ellipsis = {.type=tp_ellipsis, .is_ptr=true, ._obj=&__ellipsis_obj};

View File

@ -375,7 +375,9 @@ void __init_builtins(VM* _vm) {
}); });
_vm->bind__eq__(VM::tp_object, [](VM* vm, PyVar _0, PyVar _1) { _vm->bind__eq__(VM::tp_object, [](VM* vm, PyVar _0, PyVar _1) {
return PyVar__IS_OP(&_0, &_1) ? vm->True : vm->False; if(!_0.is_ptr) vm->TypeError("cannot compare tagged object: _0");
if(!_1.is_ptr) vm->TypeError("cannot compare tagged object: _1");
return _0._obj == _1._obj ? vm->True : vm->False;
}); });
_vm->__cached_object_new = _vm->bind_func(VM::tp_object, __new__, 1, [](VM* vm, ArgsView args) { _vm->__cached_object_new = _vm->bind_func(VM::tp_object, __new__, 1, [](VM* vm, ArgsView args) {
@ -462,7 +464,7 @@ void __init_builtins(VM* _vm) {
switch(vm->_tp(args[1])) { switch(vm->_tp(args[1])) {
case VM::tp_float: return VAR((i64)_CAST(f64, args[1])); case VM::tp_float: return VAR((i64)_CAST(f64, args[1]));
case VM::tp_int: return args[1]; case VM::tp_int: return args[1];
case VM::tp_bool: return VAR(args[1]._bool ? 1 : 0); case VM::tp_bool: return VAR(args[1].extra ? 1 : 0);
case VM::tp_str: break; case VM::tp_str: break;
default: vm->TypeError("invalid arguments for int()"); default: vm->TypeError("invalid arguments for int()");
} }
@ -543,7 +545,7 @@ void __init_builtins(VM* _vm) {
switch(vm->_tp(args[1])) { switch(vm->_tp(args[1])) {
case VM::tp_int: return VAR((f64)CAST(i64, args[1])); case VM::tp_int: return VAR((f64)CAST(i64, args[1]));
case VM::tp_float: return args[1]; case VM::tp_float: return args[1];
case VM::tp_bool: return VAR(args[1]._bool ? 1.0 : 0.0); case VM::tp_bool: return VAR(args[1].extra ? 1.0 : 0.0);
case VM::tp_str: break; case VM::tp_str: break;
default: vm->TypeError("invalid arguments for float()"); default: vm->TypeError("invalid arguments for float()");
} }
@ -1151,7 +1153,7 @@ void __init_builtins(VM* _vm) {
return VAR(_CAST(bool, _0) != CAST(bool, _1)); return VAR(_CAST(bool, _0) != CAST(bool, _1));
}); });
_vm->bind__eq__(VM::tp_bool, [](VM* vm, PyVar _0, PyVar _1) { _vm->bind__eq__(VM::tp_bool, [](VM* vm, PyVar _0, PyVar _1) {
if(is_type(_1, vm->tp_bool)) return VAR(_0._bool == _1._bool); if(is_type(_1, vm->tp_bool)) return VAR(_0.extra == _1.extra);
if(is_int(_1)) return VAR(_CAST(bool, _0) == (bool)CAST(i64, _1)); if(is_int(_1)) return VAR(_CAST(bool, _0) == (bool)CAST(i64, _1));
return vm->NotImplemented; return vm->NotImplemented;
}); });

View File

@ -18,3 +18,8 @@ assert bool([]) == False
assert bool("abc") == True assert bool("abc") == True
assert bool([1,2]) == True assert bool([1,2]) == True
assert bool('') == False assert bool('') == False
# extra compare for None
assert None == None
assert ... == ...
assert NotImplemented == NotImplemented

View File

@ -42,9 +42,11 @@ if not inq:
else: else:
assert False assert False
if inq is not 1: a = object()
b = object()
if a is not b:
assert True assert True
if inq is not 0: if a is 0:
assert False assert False
def g(x): def g(x):