mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
...
This commit is contained in:
parent
94bdfaa949
commit
715c8670d1
@ -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:
|
||||||
|
@ -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(<<);
|
||||||
|
37
src/cffi.h
37
src/cffi.h
@ -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
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
114
src/pocketpy.h
114
src/pocketpy.h
@ -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;
|
||||||
|
90
src/vm.h
90
src/vm.h
@ -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>
|
||||||
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user