mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
fix everything
This commit is contained in:
parent
e14d4e295a
commit
8edb46afb4
@ -242,7 +242,7 @@ public:
|
||||
List py_list(PyVar); // x -> list(x)
|
||||
bool py_callable(PyVar obj); // x -> callable(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);
|
||||
}
|
||||
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());
|
||||
}
|
||||
}
|
||||
return obj._bool;
|
||||
return (bool)obj.extra;
|
||||
} else if constexpr(is_integral_v<T>) {
|
||||
static_assert(!std::is_reference_v<__T>);
|
||||
// int
|
||||
|
@ -41,17 +41,18 @@ typedef struct PyVar{
|
||||
|
||||
static_assert(sizeof(PyVar) == 16, "sizeof(PyVar) != 16");
|
||||
|
||||
extern const pkpy_Type tp_object, tp_type;
|
||||
extern const pkpy_Type tp_int, tp_float, tp_bool, tp_str;
|
||||
extern const pkpy_Type tp_list, tp_tuple;
|
||||
extern const pkpy_Type tp_slice, tp_range, tp_module;
|
||||
extern const pkpy_Type tp_function, tp_native_func, tp_bound_method;
|
||||
extern const pkpy_Type tp_super, tp_exception, tp_bytes, tp_mappingproxy;
|
||||
extern const pkpy_Type tp_dict, tp_property, tp_star_wrapper;
|
||||
extern const pkpy_Type tp_staticmethod, tp_classmethod;
|
||||
extern const pkpy_Type tp_none_type, tp_not_implemented_type;
|
||||
extern const pkpy_Type tp_ellipsis;
|
||||
extern const pkpy_Type tp_op_call, tp_op_yield;
|
||||
/* predefined vars */
|
||||
static const pkpy_Type tp_object = 1, tp_type = 2;
|
||||
static const pkpy_Type tp_int = 3, tp_float = 4, tp_bool = 5, tp_str = 6;
|
||||
static const pkpy_Type tp_list = 7, tp_tuple = 8;
|
||||
static const pkpy_Type tp_slice = 9, tp_range = 10, tp_module = 11;
|
||||
static const pkpy_Type tp_function = 12, tp_native_func = 13, tp_bound_method = 14;
|
||||
static const pkpy_Type tp_super = 15, tp_exception = 16, tp_bytes = 17, tp_mappingproxy = 18;
|
||||
static const pkpy_Type tp_dict = 19, tp_property = 20, tp_star_wrapper = 21;
|
||||
static const pkpy_Type tp_staticmethod = 22, tp_classmethod = 23;
|
||||
static const pkpy_Type tp_none_type = 24, tp_not_implemented_type = 25;
|
||||
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 int64_t PyVar__hash(const PyVar* self) { return self->extra + self->_i64; }
|
||||
|
@ -67,25 +67,25 @@ void VM::__op_unpack_sequence(uint16_t arg) {
|
||||
bool VM::py_lt(PyVar _0, PyVar _1) {
|
||||
BINARY_F_COMPARE(__lt__, "<", __gt__);
|
||||
assert(ret.type == tp_bool);
|
||||
return ret._bool;
|
||||
return ret.extra;
|
||||
}
|
||||
|
||||
bool VM::py_le(PyVar _0, PyVar _1) {
|
||||
BINARY_F_COMPARE(__le__, "<=", __ge__);
|
||||
assert(ret.type == tp_bool);
|
||||
return ret._bool;
|
||||
return ret.extra;
|
||||
}
|
||||
|
||||
bool VM::py_gt(PyVar _0, PyVar _1) {
|
||||
BINARY_F_COMPARE(__gt__, ">", __lt__);
|
||||
assert(ret.type == tp_bool);
|
||||
return ret._bool;
|
||||
return ret.extra;
|
||||
}
|
||||
|
||||
bool VM::py_ge(PyVar _0, PyVar _1) {
|
||||
BINARY_F_COMPARE(__ge__, ">=", __le__);
|
||||
assert(ret.type == tp_bool);
|
||||
return ret._bool;
|
||||
return ret.extra;
|
||||
}
|
||||
|
||||
#undef BINARY_F_COMPARE
|
||||
|
@ -60,7 +60,7 @@ struct JsonSerializer {
|
||||
if(std::isinf(val) || std::isnan(val)) vm->ValueError("cannot jsonify 'nan' or 'inf'");
|
||||
ss << val;
|
||||
} else if(obj_t == vm->tp_bool) {
|
||||
ss << (obj._bool ? "true" : "false");
|
||||
ss << (obj.extra ? "true" : "false");
|
||||
} else if(obj_t == vm->tp_str) {
|
||||
ss << _CAST(Str&, obj).escape('"');
|
||||
} else if(obj_t == vm->tp_list) {
|
||||
@ -235,18 +235,18 @@ bool VM::py_eq(PyVar lhs, PyVar rhs) {
|
||||
PyVar res;
|
||||
if(ti->m__eq__) {
|
||||
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);
|
||||
if(!is_not_implemented(res)) return res._bool;
|
||||
if(!is_not_implemented(res)) return res.extra;
|
||||
|
||||
ti = _tp_info(rhs);
|
||||
if(ti->m__eq__) {
|
||||
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);
|
||||
if(!is_not_implemented(res)) return res._bool;
|
||||
if(!is_not_implemented(res)) return res.extra;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1,23 +1,5 @@
|
||||
#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_OP_CALL = {.type=tp_op_call, .is_ptr=false};
|
||||
PyVar pkpy_OP_YIELD = {.type=tp_op_yield, .is_ptr=false};
|
||||
|
@ -6,3 +6,16 @@ void PyVar__ctor3(PyVar* self, PyObject* existing){
|
||||
self->is_ptr = true;
|
||||
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};
|
@ -375,7 +375,9 @@ void __init_builtins(VM* _vm) {
|
||||
});
|
||||
|
||||
_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) {
|
||||
@ -462,7 +464,7 @@ void __init_builtins(VM* _vm) {
|
||||
switch(vm->_tp(args[1])) {
|
||||
case VM::tp_float: return VAR((i64)_CAST(f64, 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;
|
||||
default: vm->TypeError("invalid arguments for int()");
|
||||
}
|
||||
@ -543,7 +545,7 @@ void __init_builtins(VM* _vm) {
|
||||
switch(vm->_tp(args[1])) {
|
||||
case VM::tp_int: return VAR((f64)CAST(i64, 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;
|
||||
default: vm->TypeError("invalid arguments for float()");
|
||||
}
|
||||
@ -1151,7 +1153,7 @@ void __init_builtins(VM* _vm) {
|
||||
return VAR(_CAST(bool, _0) != CAST(bool, _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));
|
||||
return vm->NotImplemented;
|
||||
});
|
||||
|
@ -18,3 +18,8 @@ assert bool([]) == False
|
||||
assert bool("abc") == True
|
||||
assert bool([1,2]) == True
|
||||
assert bool('') == False
|
||||
|
||||
# extra compare for None
|
||||
assert None == None
|
||||
assert ... == ...
|
||||
assert NotImplemented == NotImplemented
|
||||
|
@ -42,9 +42,11 @@ if not inq:
|
||||
else:
|
||||
assert False
|
||||
|
||||
if inq is not 1:
|
||||
a = object()
|
||||
b = object()
|
||||
if a is not b:
|
||||
assert True
|
||||
if inq is not 0:
|
||||
if a is 0:
|
||||
assert False
|
||||
|
||||
def g(x):
|
||||
|
Loading…
x
Reference in New Issue
Block a user