This commit is contained in:
blueloveTH 2024-07-01 00:57:14 +08:00
parent c5ab28d75b
commit 5847586121
3 changed files with 121 additions and 5 deletions

View File

@ -149,6 +149,23 @@ bool py_getitem(const py_Ref self, const py_Ref key, py_Ref out);
bool py_setitem(py_Ref self, const py_Ref key, const py_Ref val);
bool py_delitem(py_Ref self, const py_Ref key);
bool py_binaryop(const py_Ref lhs, const py_Ref rhs, py_Name op, py_Name rop);
#define py_binaryadd(lhs, rhs) py_binaryop(lhs, rhs, __add__, __radd__)
#define py_binarysub(lhs, rhs) py_binaryop(lhs, rhs, __sub__, __rsub__)
#define py_binarymul(lhs, rhs) py_binaryop(lhs, rhs, __mul__, __rmul__)
#define py_binarytruediv(lhs, rhs) py_binaryop(lhs, rhs, __truediv__, __rtruediv__)
#define py_binaryfloordiv(lhs, rhs) py_binaryop(lhs, rhs, __floordiv__, __rfloordiv__)
#define py_binarymod(lhs, rhs) py_binaryop(lhs, rhs, __mod__, __rmod__)
#define py_binarypow(lhs, rhs) py_binaryop(lhs, rhs, __pow__, __rpow__)
#define py_binarylshift(lhs, rhs) py_binaryop(lhs, rhs, __lshift__, 0)
#define py_binaryrshift(lhs, rhs) py_binaryop(lhs, rhs, __rshift__, 0)
#define py_binaryand(lhs, rhs) py_binaryop(lhs, rhs, __and__, 0)
#define py_binaryor(lhs, rhs) py_binaryop(lhs, rhs, __or__, 0)
#define py_binaryxor(lhs, rhs) py_binaryop(lhs, rhs, __xor__, 0)
#define py_binarymatmul(lhs, rhs) py_binaryop(lhs, rhs, __matmul__, 0)
/// Equivalent to `*dst = *src`.
void py_assign(py_Ref dst, const py_Ref src);
@ -187,8 +204,14 @@ void py_Error__print(py_Error*);
/************* Operators *************/
bool py_bool(const py_Ref);
int py_eq(const py_Ref, const py_Ref);
int py_ne(const py_Ref, const py_Ref);
int py_le(const py_Ref, const py_Ref);
int py_lt(const py_Ref, const py_Ref);
int py_ge(const py_Ref, const py_Ref);
int py_gt(const py_Ref, const py_Ref);
bool py_hash(const py_Ref, int64_t* out);
/// Compare two objects without using magic methods.

View File

@ -666,3 +666,64 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
return RES_RETURN;
}
bool py_binaryop(const py_Ref lhs, const py_Ref rhs, py_Name op, py_Name rop) {
pk_VM* self = pk_current_vm;
PUSH(lhs);
PUSH(rhs);
// [a, b]
py_Ref _0 = py_tpfindmagic(SECOND()->type, op);
py_Ref _1;
if(_0) {
if(_0->type == tp_nativefunc) {
bool ok = _0->_cfunc(2, SECOND(), &self->last_retval);
if(!ok) return false;
if(self->last_retval.type != tp_not_implemented_type) {
STACK_SHRINK(2);
return true;
}
} else {
// standard call
bool ok = py_call(_0, 2, SECOND());
if(!ok) return false;
if(self->last_retval.type != tp_not_implemented_type) {
STACK_SHRINK(2);
return true;
}
}
}
// try reverse operation
if(rop) {
// [a, b] -> [b, a]
py_TValue tmp = *TOP();
*TOP() = *SECOND();
*SECOND() = tmp;
_1 = py_tpfindmagic(SECOND()->type, rop);
if(_1) {
if(_1->type == tp_nativefunc) {
bool ok = _1->_cfunc(2, SECOND(), &self->last_retval);
if(!ok) return false;
if(tmp.type != tp_not_implemented_type) {
STACK_SHRINK(2);
return true;
}
} else {
// standard call
bool ok = py_call(_1, 2, SECOND());
if(!ok) return false;
if(self->last_retval.type != tp_not_implemented_type) {
STACK_SHRINK(2);
return true;
}
}
}
}
// eq/ne op never fails
if(op == __eq__ || op == __ne__) {
STACK_SHRINK(2);
self->last_retval = (op == __eq__) ? self->False : self->True;
return true;
}
BinaryOptError(byte.arg);
return false;
}

View File

@ -1,10 +1,6 @@
#include "pocketpy/interpreter/vm.h"
#include "pocketpy/pocketpy.h"
int py_eq(const py_Ref lhs, const py_Ref rhs) { return 0; }
int py_le(const py_Ref lhs, const py_Ref rhs) { return 0; }
bool py_isidentical(const py_Ref lhs, const py_Ref rhs){
if(lhs->is_ptr && rhs->is_ptr){
return lhs->_obj == rhs->_obj;
@ -26,4 +22,40 @@ bool py_getitem(const py_Ref self, const py_Ref key, py_Ref out) { return -1; }
bool py_setitem(py_Ref self, const py_Ref key, const py_Ref val) { return -1; }
bool py_delitem(py_Ref self, const py_Ref key) { return -1; }
bool py_delitem(py_Ref self, const py_Ref key) { return -1; }
int py_eq(const py_Ref lhs, const py_Ref rhs) {
bool ok = py_binaryop(lhs, rhs, __eq__, __eq__);
if(!ok) return -1;
return py_tobool(py_lastretval());
}
int py_ne(const py_Ref lhs, const py_Ref rhs) {
bool ok = py_binaryop(lhs, rhs, __ne__, __ne__);
if(!ok) return -1;
return py_tobool(py_lastretval());
}
int py_lt(const py_Ref lhs, const py_Ref rhs) {
bool ok = py_binaryop(lhs, rhs, __lt__, __gt__);
if(!ok) return -1;
return py_tobool(py_lastretval());
}
int py_gt(const py_Ref lhs, const py_Ref rhs) {
bool ok = py_binaryop(lhs, rhs, __gt__, __lt__);
if(!ok) return -1;
return py_tobool(py_lastretval());
}
int py_ge(const py_Ref lhs, const py_Ref rhs) {
bool ok = py_binaryop(lhs, rhs, __ge__, __le__);
if(!ok) return -1;
return py_tobool(py_lastretval());
}
int py_le(const py_Ref lhs, const py_Ref rhs) {
bool ok = py_binaryop(lhs, rhs, __le__, __ge__);
if(!ok) return -1;
return py_tobool(py_lastretval());
}