This commit is contained in:
blueloveTH 2023-06-16 21:35:28 +08:00
parent 94bdfaa949
commit 715c8670d1
7 changed files with 137 additions and 127 deletions

View File

@ -307,8 +307,8 @@ class long:
def __cmp__(self, other): def __cmp__(self, other):
if type(other) is int: if type(other) is int:
other = long(other) other = long(other)
else: elif type(other) is not long:
assert type(other) is long return NotImplemented
if self.sign > other.sign: if self.sign > other.sign:
return 1 return 1
elif self.sign < other.sign: elif self.sign < other.sign:

View File

@ -337,6 +337,7 @@ __NEXT_STEP:;
_2 = get_unbound_method(_1, func, &self, false); \ _2 = get_unbound_method(_1, func, &self, false); \
if(_2 != nullptr) TOP() = call_method(self, _2, _0); \ if(_2 != nullptr) TOP() = call_method(self, _2, _0); \
else BinaryOptError(op); \ else BinaryOptError(op); \
if(TOP() == NotImplemented) BinaryOptError(op); \
} }
TARGET(BINARY_TRUEDIV) TARGET(BINARY_TRUEDIV)
@ -373,11 +374,11 @@ __NEXT_STEP:;
DISPATCH() DISPATCH()
TARGET(COMPARE_LT) TARGET(COMPARE_LT)
BINARY_OP_SPECIAL(__lt__); BINARY_OP_SPECIAL(__lt__);
if(TOP() == NotImplemented) BinaryOptError("<"); BINARY_OP_RSPECIAL("<", __gt__);
DISPATCH() DISPATCH()
TARGET(COMPARE_LE) TARGET(COMPARE_LE)
BINARY_OP_SPECIAL(__le__); BINARY_OP_SPECIAL(__le__);
if(TOP() == NotImplemented) BinaryOptError("<="); BINARY_OP_RSPECIAL("<=", __ge__);
DISPATCH() DISPATCH()
TARGET(COMPARE_EQ) TARGET(COMPARE_EQ)
_1 = POPX(); _1 = POPX();
@ -391,11 +392,11 @@ __NEXT_STEP:;
DISPATCH() DISPATCH()
TARGET(COMPARE_GT) TARGET(COMPARE_GT)
BINARY_OP_SPECIAL(__gt__); BINARY_OP_SPECIAL(__gt__);
if(TOP() == NotImplemented) BinaryOptError(">"); BINARY_OP_RSPECIAL(">", __lt__);
DISPATCH() DISPATCH()
TARGET(COMPARE_GE) TARGET(COMPARE_GE)
BINARY_OP_SPECIAL(__ge__); BINARY_OP_SPECIAL(__ge__);
if(TOP() == NotImplemented) BinaryOptError(">="); BINARY_OP_RSPECIAL(">=", __le__);
DISPATCH() DISPATCH()
TARGET(BITWISE_LSHIFT) TARGET(BITWISE_LSHIFT)
PREDICT_INT_OP(<<); PREDICT_INT_OP(<<);

View File

@ -45,6 +45,11 @@ struct VoidP{
bool operator!=(const VoidP& other) const { bool operator!=(const VoidP& other) const {
return ptr != other.ptr || base_offset != other.base_offset; return ptr != other.ptr || base_offset != other.base_offset;
} }
bool operator<(const VoidP& other) const { return ptr < other.ptr; }
bool operator<=(const VoidP& other) const { return ptr <= other.ptr; }
bool operator>(const VoidP& other) const { return ptr > other.ptr; }
bool operator>=(const VoidP& other) const { return ptr >= other.ptr; }
Str hex() const{ Str hex() const{
std::stringstream ss; std::stringstream ss;
@ -76,23 +81,20 @@ struct VoidP{
return VAR(ss.str()); return VAR(ss.str());
}); });
vm->bind__eq__(OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){ #define BIND_CMP(name, op) \
if(!is_non_tagged_type(rhs, VoidP::_type(vm))) return false; vm->bind##name(OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){ \
return _CAST(VoidP&, lhs) == _CAST(VoidP&, rhs); if(!is_non_tagged_type(rhs, VoidP::_type(vm))) return vm->NotImplemented; \
}); return VAR(_CAST(VoidP&, lhs) op _CAST(VoidP&, rhs)); \
vm->bind__gt__(OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
return _CAST(VoidP&, lhs).ptr > CAST(VoidP&, rhs).ptr;
});
vm->bind__lt__(OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
return _CAST(VoidP&, lhs).ptr < CAST(VoidP&, rhs).ptr;
});
vm->bind__ge__(OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
return _CAST(VoidP&, lhs).ptr >= CAST(VoidP&, rhs).ptr;
});
vm->bind__le__(OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
return _CAST(VoidP&, lhs).ptr <= CAST(VoidP&, rhs).ptr;
}); });
BIND_CMP(__eq__, ==)
BIND_CMP(__lt__, <)
BIND_CMP(__le__, <=)
BIND_CMP(__gt__, >)
BIND_CMP(__ge__, >=)
#undef BIND_CMP
vm->bind__hash__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ vm->bind__hash__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
VoidP& self = _CAST(VoidP&, obj); VoidP& self = _CAST(VoidP&, obj);
return reinterpret_cast<i64>(self.ptr); return reinterpret_cast<i64>(self.ptr);
@ -243,9 +245,10 @@ struct C99Struct{
vm->bind__eq__(OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){ vm->bind__eq__(OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
C99Struct& self = _CAST(C99Struct&, lhs); C99Struct& self = _CAST(C99Struct&, lhs);
if(!is_non_tagged_type(rhs, C99Struct::_type(vm))) return false; if(!is_non_tagged_type(rhs, C99Struct::_type(vm))) return vm->NotImplemented;
C99Struct& other = _CAST(C99Struct&, rhs); C99Struct& other = _CAST(C99Struct&, rhs);
return self.size == other.size && memcmp(self.p, other.p, self.size) == 0; bool ok = self.size == other.size && memcmp(self.p, other.p, self.size) == 0;
return VAR(ok);
}); });
// patch VoidP // patch VoidP

View File

@ -20,7 +20,7 @@
#include <variant> #include <variant>
#include <type_traits> #include <type_traits>
#define PK_VERSION "1.0.3" #define PK_VERSION "1.0.4"
#include "config.h" #include "config.h"

View File

@ -52,27 +52,23 @@ inline void init_builtins(VM* _vm) {
#undef BIND_NUM_ARITH_OPT #undef BIND_NUM_ARITH_OPT
#define BIND_NUM_LOGICAL_OPT(name, op, is_eq) \ #define BIND_NUM_LOGICAL_OPT(name, op) \
_vm->bind##name(_vm->tp_int, [](VM* vm, PyObject* lhs, PyObject* rhs) { \ _vm->bind##name(_vm->tp_int, [](VM* vm, PyObject* lhs, PyObject* rhs) { \
if(is_int(rhs)) return _CAST(i64, lhs) op _CAST(i64, rhs); \ if(is_int(rhs)) return VAR(_CAST(i64, lhs) op _CAST(i64, rhs)); \
if(is_float(rhs)) return _CAST(i64, lhs) op _CAST(f64, rhs); \ if(is_float(rhs)) return VAR(_CAST(i64, lhs) op _CAST(f64, rhs)); \
if constexpr(is_eq) return lhs op rhs; \ return vm->NotImplemented; \
vm->TypeError("unsupported operand type(s) for " #op ); \
return false; \
}); \ }); \
_vm->bind##name(_vm->tp_float, [](VM* vm, PyObject* lhs, PyObject* rhs) { \ _vm->bind##name(_vm->tp_float, [](VM* vm, PyObject* lhs, PyObject* rhs) { \
if(is_int(rhs)) return _CAST(f64, lhs) op _CAST(i64, rhs); \ if(is_int(rhs)) return VAR(_CAST(f64, lhs) op _CAST(i64, rhs)); \
if(is_float(rhs)) return _CAST(f64, lhs) op _CAST(f64, rhs); \ if(is_float(rhs)) return VAR(_CAST(f64, lhs) op _CAST(f64, rhs)); \
if constexpr(is_eq) return lhs op rhs; \ return vm->NotImplemented; \
vm->TypeError("unsupported operand type(s) for " #op ); \
return false; \
}); });
BIND_NUM_LOGICAL_OPT(__lt__, <, false) BIND_NUM_LOGICAL_OPT(__eq__, ==)
BIND_NUM_LOGICAL_OPT(__le__, <=, false) BIND_NUM_LOGICAL_OPT(__lt__, <)
BIND_NUM_LOGICAL_OPT(__gt__, >, false) BIND_NUM_LOGICAL_OPT(__le__, <=)
BIND_NUM_LOGICAL_OPT(__ge__, >=, false) BIND_NUM_LOGICAL_OPT(__gt__, >)
BIND_NUM_LOGICAL_OPT(__eq__, ==, true) BIND_NUM_LOGICAL_OPT(__ge__, >=)
#undef BIND_NUM_ARITH_OPT #undef BIND_NUM_ARITH_OPT
#undef BIND_NUM_LOGICAL_OPT #undef BIND_NUM_LOGICAL_OPT
@ -263,7 +259,7 @@ inline void init_builtins(VM* _vm) {
return VAR(ss.str()); return VAR(ss.str());
}); });
_vm->bind__eq__(_vm->tp_object, [](VM* vm, PyObject* lhs, PyObject* rhs) { return lhs == rhs; }); _vm->bind__eq__(_vm->tp_object, [](VM* vm, PyObject* lhs, PyObject* rhs) { return VAR(lhs == rhs); });
_vm->bind__hash__(_vm->tp_object, [](VM* vm, PyObject* obj) { return BITS(obj); }); _vm->bind__hash__(_vm->tp_object, [](VM* vm, PyObject* obj) { return BITS(obj); });
_vm->cached_object__new__ = _vm->bind_constructor<1>("object", [](VM* vm, ArgsView args) { _vm->cached_object__new__ = _vm->bind_constructor<1>("object", [](VM* vm, ArgsView args) {
@ -449,8 +445,7 @@ inline void init_builtins(VM* _vm) {
}); });
_vm->bind__contains__(_vm->tp_str, [](VM* vm, PyObject* lhs, PyObject* rhs) { _vm->bind__contains__(_vm->tp_str, [](VM* vm, PyObject* lhs, PyObject* rhs) {
const Str& self = _CAST(Str&, lhs); const Str& self = _CAST(Str&, lhs);
const Str& other = CAST(Str&, rhs); return VAR(self.index(CAST(Str&, rhs)) != -1);
return self.index(other) != -1;
}); });
_vm->bind__str__(_vm->tp_str, [](VM* vm, PyObject* obj) { return obj; }); _vm->bind__str__(_vm->tp_str, [](VM* vm, PyObject* obj) { return obj; });
_vm->bind__iter__(_vm->tp_str, [](VM* vm, PyObject* obj) { return VAR_T(StringIter, obj); }); _vm->bind__iter__(_vm->tp_str, [](VM* vm, PyObject* obj) { return VAR_T(StringIter, obj); });
@ -462,23 +457,20 @@ inline void init_builtins(VM* _vm) {
const Str& self = _CAST(Str&, obj); const Str& self = _CAST(Str&, obj);
return VAR(self.escape(false)); return VAR(self.escape(false));
}); });
_vm->bind__eq__(_vm->tp_str, [](VM* vm, PyObject* lhs, PyObject* rhs) {
if(!is_non_tagged_type(rhs, vm->tp_str)) return false; #define BIND_CMP_STR(name, op) \
return _CAST(Str&, lhs) == _CAST(Str&, rhs); _vm->bind##name(_vm->tp_str, [](VM* vm, PyObject* lhs, PyObject* rhs) { \
}); if(!is_non_tagged_type(rhs, vm->tp_str)) return vm->NotImplemented; \
_vm->bind__gt__(_vm->tp_str, [](VM* vm, PyObject* lhs, PyObject* rhs) { return VAR(_CAST(Str&, lhs) op _CAST(Str&, rhs)); \
return _CAST(Str&, lhs) > CAST(Str&, rhs);
});
_vm->bind__lt__(_vm->tp_str, [](VM* vm, PyObject* lhs, PyObject* rhs) {
return _CAST(Str&, lhs) < CAST(Str&, rhs);
});
_vm->bind__ge__(_vm->tp_str, [](VM* vm, PyObject* lhs, PyObject* rhs) {
return _CAST(Str&, lhs) >= CAST(Str&, rhs);
});
_vm->bind__le__(_vm->tp_str, [](VM* vm, PyObject* lhs, PyObject* rhs) {
return _CAST(Str&, lhs) <= CAST(Str&, rhs);
}); });
BIND_CMP_STR(__eq__, ==)
BIND_CMP_STR(__lt__, <)
BIND_CMP_STR(__le__, <=)
BIND_CMP_STR(__gt__, >)
BIND_CMP_STR(__ge__, >=)
#undef BIND_CMP_STR
_vm->bind__getitem__(_vm->tp_str, [](VM* vm, PyObject* obj, PyObject* index) { _vm->bind__getitem__(_vm->tp_str, [](VM* vm, PyObject* obj, PyObject* index) {
const Str& self = _CAST(Str&, obj); const Str& self = _CAST(Str&, obj);
if(is_non_tagged_type(index, vm->tp_slice)){ if(is_non_tagged_type(index, vm->tp_slice)){
@ -572,8 +564,8 @@ inline void init_builtins(VM* _vm) {
_vm->bind__contains__(_vm->tp_list, [](VM* vm, PyObject* obj, PyObject* item) { _vm->bind__contains__(_vm->tp_list, [](VM* vm, PyObject* obj, PyObject* item) {
List& self = _CAST(List&, obj); List& self = _CAST(List&, obj);
for(PyObject* i: self) if(vm->py_equals(i, item)) return true; for(PyObject* i: self) if(vm->py_equals(i, item)) return vm->True;
return false; return vm->False;
}); });
_vm->bind_method<1>("list", "count", [](VM* vm, ArgsView args) { _vm->bind_method<1>("list", "count", [](VM* vm, ArgsView args) {
@ -585,12 +577,13 @@ inline void init_builtins(VM* _vm) {
_vm->bind__eq__(_vm->tp_list, [](VM* vm, PyObject* lhs, PyObject* rhs) { _vm->bind__eq__(_vm->tp_list, [](VM* vm, PyObject* lhs, PyObject* rhs) {
List& a = _CAST(List&, lhs); List& a = _CAST(List&, lhs);
if(!is_non_tagged_type(rhs, vm->tp_list)) return vm->NotImplemented;
List& b = _CAST(List&, rhs); List& b = _CAST(List&, rhs);
if(a.size() != b.size()) return false; if(a.size() != b.size()) return vm->False;
for(int i=0; i<a.size(); i++){ for(int i=0; i<a.size(); i++){
if(!vm->py_equals(a[i], b[i])) return false; if(!vm->py_equals(a[i], b[i])) return vm->False;
} }
return true; return vm->True;
}); });
_vm->bind_method<1>("list", "index", [](VM* vm, ArgsView args) { _vm->bind_method<1>("list", "index", [](VM* vm, ArgsView args) {
@ -725,8 +718,8 @@ inline void init_builtins(VM* _vm) {
_vm->bind__contains__(_vm->tp_tuple, [](VM* vm, PyObject* obj, PyObject* item) { _vm->bind__contains__(_vm->tp_tuple, [](VM* vm, PyObject* obj, PyObject* item) {
Tuple& self = _CAST(Tuple&, obj); Tuple& self = _CAST(Tuple&, obj);
for(PyObject* i: self) if(vm->py_equals(i, item)) return true; for(PyObject* i: self) if(vm->py_equals(i, item)) return vm->True;
return false; return vm->False;
}); });
_vm->bind_method<1>("tuple", "count", [](VM* vm, ArgsView args) { _vm->bind_method<1>("tuple", "count", [](VM* vm, ArgsView args) {
@ -738,12 +731,13 @@ inline void init_builtins(VM* _vm) {
_vm->bind__eq__(_vm->tp_tuple, [](VM* vm, PyObject* lhs, PyObject* rhs) { _vm->bind__eq__(_vm->tp_tuple, [](VM* vm, PyObject* lhs, PyObject* rhs) {
const Tuple& self = _CAST(Tuple&, lhs); const Tuple& self = _CAST(Tuple&, lhs);
const Tuple& other = CAST(Tuple&, rhs); if(!is_non_tagged_type(rhs, vm->tp_tuple)) return vm->NotImplemented;
if(self.size() != other.size()) return false; const Tuple& other = _CAST(Tuple&, rhs);
if(self.size() != other.size()) return vm->False;
for(int i = 0; i < self.size(); i++) { for(int i = 0; i < self.size(); i++) {
if(!vm->py_equals(self[i], other[i])) return false; if(!vm->py_equals(self[i], other[i])) return vm->False;
} }
return true; return vm->True;
}); });
_vm->bind__hash__(_vm->tp_tuple, [](VM* vm, PyObject* obj) { _vm->bind__hash__(_vm->tp_tuple, [](VM* vm, PyObject* obj) {
@ -790,10 +784,15 @@ inline void init_builtins(VM* _vm) {
return VAR(_CAST(bool, lhs) != CAST(bool, rhs)); return VAR(_CAST(bool, lhs) != CAST(bool, rhs));
}); });
_vm->bind__eq__(_vm->tp_bool, [](VM* vm, PyObject* lhs, PyObject* rhs) { _vm->bind__eq__(_vm->tp_bool, [](VM* vm, PyObject* lhs, PyObject* rhs) {
return _CAST(bool, lhs) == CAST(bool, rhs); if(is_non_tagged_type(rhs, vm->tp_bool)) return VAR(lhs == rhs);
if(is_int(rhs)) return VAR(_CAST(bool, lhs) == (bool)CAST(i64, rhs));
return vm->NotImplemented;
}); });
_vm->bind__repr__(_vm->_type("ellipsis"), [](VM* vm, PyObject* self) { _vm->bind__repr__(_vm->_type("ellipsis"), [](VM* vm, PyObject* self) {
return VAR("Ellipsis"); return VAR("...");
});
_vm->bind__repr__(_vm->_type("NotImplementedType"), [](VM* vm, PyObject* self) {
return VAR("NotImplemented");
}); });
/************ bytes ************/ /************ bytes ************/
@ -856,7 +855,8 @@ inline void init_builtins(VM* _vm) {
}); });
_vm->bind__eq__(_vm->tp_bytes, [](VM* vm, PyObject* lhs, PyObject* rhs) { _vm->bind__eq__(_vm->tp_bytes, [](VM* vm, PyObject* lhs, PyObject* rhs) {
return _CAST(Bytes&, lhs) == _CAST(Bytes&, rhs); if(!is_non_tagged_type(rhs, vm->tp_bytes)) return vm->NotImplemented;
return VAR(_CAST(Bytes&, lhs) == _CAST(Bytes&, rhs));
}); });
/************ slice ************/ /************ slice ************/
_vm->bind_constructor<4>("slice", [](VM* vm, ArgsView args) { _vm->bind_constructor<4>("slice", [](VM* vm, ArgsView args) {
@ -926,7 +926,7 @@ inline void init_builtins(VM* _vm) {
_vm->bind__contains__(_vm->tp_mappingproxy, [](VM* vm, PyObject* obj, PyObject* key) { _vm->bind__contains__(_vm->tp_mappingproxy, [](VM* vm, PyObject* obj, PyObject* key) {
MappingProxy& self = _CAST(MappingProxy&, obj); MappingProxy& self = _CAST(MappingProxy&, obj);
return self.attr().contains(CAST(Str&, key)); return VAR(self.attr().contains(CAST(Str&, key)));
}); });
/************ dict ************/ /************ dict ************/
@ -986,7 +986,7 @@ inline void init_builtins(VM* _vm) {
_vm->bind__contains__(_vm->tp_dict, [](VM* vm, PyObject* obj, PyObject* key) { _vm->bind__contains__(_vm->tp_dict, [](VM* vm, PyObject* obj, PyObject* key) {
Dict& self = _CAST(Dict&, obj); Dict& self = _CAST(Dict&, obj);
return self.contains(key); return VAR(self.contains(key));
}); });
_vm->bind_method<-1>("dict", "get", [](VM* vm, ArgsView args) { _vm->bind_method<-1>("dict", "get", [](VM* vm, ArgsView args) {
@ -1080,15 +1080,15 @@ inline void init_builtins(VM* _vm) {
_vm->bind__eq__(_vm->tp_dict, [](VM* vm, PyObject* a, PyObject* b) { _vm->bind__eq__(_vm->tp_dict, [](VM* vm, PyObject* a, PyObject* b) {
Dict& self = _CAST(Dict&, a); Dict& self = _CAST(Dict&, a);
if(!is_non_tagged_type(b, vm->tp_dict)) return false; if(!is_non_tagged_type(b, vm->tp_dict)) return vm->NotImplemented;
Dict& other = _CAST(Dict&, b); Dict& other = _CAST(Dict&, b);
if(self.size() != other.size()) return false; if(self.size() != other.size()) return vm->False;
for(auto& item : self.items()){ for(auto& item : self.items()){
PyObject* value = other.try_get(item.first); PyObject* value = other.try_get(item.first);
if(value == nullptr) return false; if(value == nullptr) return vm->False;
if(!vm->py_equals(item.second, value)) return false; if(!vm->py_equals(item.second, value)) return vm->False;
} }
return true; return vm->True;
}); });
/************ property ************/ /************ property ************/
_vm->bind_constructor<-1>("property", [](VM* vm, ArgsView args) { _vm->bind_constructor<-1>("property", [](VM* vm, ArgsView args) {
@ -1370,8 +1370,8 @@ inline void VM::post_init(){
})); }));
bind__eq__(tp_bound_method, [](VM* vm, PyObject* lhs, PyObject* rhs){ bind__eq__(tp_bound_method, [](VM* vm, PyObject* lhs, PyObject* rhs){
if(!is_non_tagged_type(rhs, vm->tp_bound_method)) return false; if(!is_non_tagged_type(rhs, vm->tp_bound_method)) return vm->NotImplemented;
return _CAST(BoundMethod&, lhs) == _CAST(BoundMethod&, rhs); return VAR(_CAST(BoundMethod&, lhs) == _CAST(BoundMethod&, rhs));
}); });
_t(tp_slice)->attr().set("start", property([](VM* vm, ArgsView args){ _t(tp_slice)->attr().set("start", property([](VM* vm, ArgsView args){
return CAST(Slice&, args[0]).start; return CAST(Slice&, args[0]).start;

View File

@ -44,6 +44,8 @@ namespace pkpy{
inline PyObject* py_var(VM* vm, ctype&& value) { return vm->heap.gcnew(vm->ptype, std::move(value));} inline PyObject* py_var(VM* vm, ctype&& value) { return vm->heap.gcnew(vm->ptype, std::move(value));}
typedef PyObject* (*BinaryFuncC)(VM*, PyObject*, PyObject*);
struct PyTypeInfo{ struct PyTypeInfo{
PyObject* obj; PyObject* obj;
Type base; Type base;
@ -62,28 +64,28 @@ struct PyTypeInfo{
PyObject* (*m__neg__)(VM* vm, PyObject*) = nullptr; PyObject* (*m__neg__)(VM* vm, PyObject*) = nullptr;
PyObject* (*m__bool__)(VM* vm, PyObject*) = nullptr; PyObject* (*m__bool__)(VM* vm, PyObject*) = nullptr;
bool (*m__eq__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__eq__ = nullptr;
bool (*m__lt__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__lt__ = nullptr;
bool (*m__le__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__le__ = nullptr;
bool (*m__gt__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__gt__ = nullptr;
bool (*m__ge__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__ge__ = nullptr;
bool (*m__contains__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__contains__ = nullptr;
// binary operators // binary operators
PyObject* (*m__add__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__add__ = nullptr;
PyObject* (*m__sub__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__sub__ = nullptr;
PyObject* (*m__mul__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__mul__ = nullptr;
PyObject* (*m__truediv__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__truediv__ = nullptr;
PyObject* (*m__floordiv__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__floordiv__ = nullptr;
PyObject* (*m__mod__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__mod__ = nullptr;
PyObject* (*m__pow__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__pow__ = nullptr;
PyObject* (*m__matmul__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__matmul__ = nullptr;
PyObject* (*m__lshift__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__lshift__ = nullptr;
PyObject* (*m__rshift__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__rshift__ = nullptr;
PyObject* (*m__and__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__and__ = nullptr;
PyObject* (*m__or__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__or__ = nullptr;
PyObject* (*m__xor__)(VM* vm, PyObject*, PyObject*) = nullptr; BinaryFuncC m__xor__ = nullptr;
// indexer // indexer
PyObject* (*m__getitem__)(VM* vm, PyObject*, PyObject*) = nullptr; PyObject* (*m__getitem__)(VM* vm, PyObject*, PyObject*) = nullptr;
@ -358,37 +360,23 @@ public:
#undef BIND_UNARY_SPECIAL #undef BIND_UNARY_SPECIAL
#define BIND_LOGICAL_SPECIAL(name) \
void bind##name(Type type, bool (*f)(VM*, PyObject*, PyObject*)){ \
PyObject* obj = _t(type); \
_all_types[type].m##name = f; \
PyObject* nf = bind_method<1>(obj, #name, [](VM* vm, ArgsView args){ \
bool ok = lambda_get_userdata<bool(*)(VM*, PyObject*, PyObject*)>(args.begin())(vm, args[0], args[1]); \
return ok ? vm->True : vm->False; \
}); \
OBJ_GET(NativeFunc, nf).set_userdata(f); \
}
BIND_LOGICAL_SPECIAL(__eq__)
BIND_LOGICAL_SPECIAL(__lt__)
BIND_LOGICAL_SPECIAL(__le__)
BIND_LOGICAL_SPECIAL(__gt__)
BIND_LOGICAL_SPECIAL(__ge__)
BIND_LOGICAL_SPECIAL(__contains__)
#undef BIND_LOGICAL_SPECIAL
#define BIND_BINARY_SPECIAL(name) \ #define BIND_BINARY_SPECIAL(name) \
void bind##name(Type type, PyObject* (*f)(VM*, PyObject*, PyObject*)){ \ void bind##name(Type type, BinaryFuncC f){ \
PyObject* obj = _t(type); \ PyObject* obj = _t(type); \
_all_types[type].m##name = f; \ _all_types[type].m##name = f; \
PyObject* nf = bind_method<1>(obj, #name, [](VM* vm, ArgsView args){ \ PyObject* nf = bind_method<1>(obj, #name, [](VM* vm, ArgsView args){ \
return lambda_get_userdata<PyObject*(*)(VM*, PyObject*, PyObject*)>(args.begin())(vm, args[0], args[1]); \ return lambda_get_userdata<BinaryFuncC>(args.begin())(vm, args[0], args[1]); \
}); \ }); \
OBJ_GET(NativeFunc, nf).set_userdata(f); \ OBJ_GET(NativeFunc, nf).set_userdata(f); \
} }
BIND_BINARY_SPECIAL(__eq__)
BIND_BINARY_SPECIAL(__lt__)
BIND_BINARY_SPECIAL(__le__)
BIND_BINARY_SPECIAL(__gt__)
BIND_BINARY_SPECIAL(__ge__)
BIND_BINARY_SPECIAL(__contains__)
BIND_BINARY_SPECIAL(__add__) BIND_BINARY_SPECIAL(__add__)
BIND_BINARY_SPECIAL(__sub__) BIND_BINARY_SPECIAL(__sub__)
BIND_BINARY_SPECIAL(__mul__) BIND_BINARY_SPECIAL(__mul__)
@ -438,8 +426,22 @@ public:
bool py_equals(PyObject* lhs, PyObject* rhs){ bool py_equals(PyObject* lhs, PyObject* rhs){
if(lhs == rhs) return true; if(lhs == rhs) return true;
const PyTypeInfo* ti = _inst_type_info(lhs); const PyTypeInfo* ti = _inst_type_info(lhs);
if(ti->m__eq__) return ti->m__eq__(this, lhs, rhs); PyObject* res;
return call_method(lhs, __eq__, rhs) == True; if(ti->m__eq__){
res = ti->m__eq__(this, lhs, rhs);
if(res != vm->NotImplemented) return res == vm->True;
}
res = call_method(lhs, __eq__, rhs);
if(res != vm->NotImplemented) return res == vm->True;
ti = _inst_type_info(rhs);
if(ti->m__eq__){
res = ti->m__eq__(this, rhs, lhs);
if(res != vm->NotImplemented) return res == vm->True;
}
res = call_method(rhs, __eq__, lhs);
if(res != vm->NotImplemented) return res == vm->True;
return false;
} }
template<int ARGC> template<int ARGC>

View File

@ -1,4 +1,4 @@
assert long(123) == long('123') == 123L == 123 assert long(123) == long('123') == 123 == 123L
a = long(2) a = long(2)
assert a ** 0 == 1 assert a ** 0 == 1
@ -32,3 +32,7 @@ while a != 0:
s.append(r) s.append(r)
assert s == [4, 6, 7, 2, 3] assert s == [4, 6, 7, 2, 3]
assert 1 < 2L < 3 < 6.6
assert 1L < 2 < 9.6 >= 7 > 2L
assert 1L < 2 < 3 < 6.6