add tuple.__lt__

This commit is contained in:
blueloveTH 2024-09-29 13:06:07 +08:00
parent 7967852eb9
commit 95d5e3e437
4 changed files with 83 additions and 6 deletions

View File

@ -1040,6 +1040,33 @@ FrameResult VM__run_top_frame(VM* self) {
return RES_RETURN;
}
const static char* op2str(py_Name op) {
switch(op) {
case __eq__: return "==";
case __ne__: return "!=";
case __lt__: return "<";
case __le__: return "<=";
case __gt__: return ">";
case __ge__: return ">=";
case __add__: return "+";
case __sub__: return "-";
case __mul__: return "*";
case __truediv__: return "/";
case __floordiv__: return "//";
case __mod__: return "%";
case __pow__: return "**";
case __lshift__: return "<<";
case __rshift__: return ">>";
case __and__: return "&";
case __or__: return "|";
case __xor__: return "^";
case __neg__: return "-";
case __invert__: return "~";
case __matmul__: return "@";
default: return py_name2str(op);
}
}
bool pk_stack_binaryop(VM* self, py_Name op, py_Name rop) {
// [a, b]
py_Ref magic = py_tpfindmagic(SECOND()->type, op);
@ -1071,7 +1098,7 @@ bool pk_stack_binaryop(VM* self, py_Name op, py_Name rop) {
py_newbool(py_retval(), !res);
return true;
}
return TypeError("unsupported operand type(s) for '%n'", op);
return TypeError("unsupported operand type(s) for '%s'", op2str(op));
}
bool py_binaryop(py_Ref lhs, py_Ref rhs, py_Name op, py_Name rop) {

View File

@ -110,6 +110,37 @@ static bool tuple__ne__(int argc, py_Ref argv) {
return true;
}
static bool tuple__lt__(int argc, py_Ref argv) {
PY_CHECK_ARGC(2);
if(!py_istype(py_arg(1), tp_tuple)) {
py_newnotimplemented(py_retval());
return true;
}
py_TValue *p0, *p1;
int lhs_length = py_tuple_len(py_arg(0));
int rhs_length = py_tuple_len(py_arg(1));
p0 = py_tuple_data(py_arg(0));
p1 = py_tuple_data(py_arg(1));
int length = lhs_length < rhs_length ? lhs_length : rhs_length;
for(int i = 0; i < length; i++) {
int res_lt = py_less(p0 + i, p1 + i);
if(res_lt == -1) return false;
if(res_lt) {
py_newbool(py_retval(), true);
return true;
} else {
int res_eq = py_equal(p0 + i, p1 + i);
if(res_eq == -1) return false;
if(!res_eq) {
py_newbool(py_retval(), false);
return true;
}
}
}
py_newbool(py_retval(), lhs_length < rhs_length);
return true;
}
static bool tuple__iter__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
return pk_arrayiter(argv);
@ -144,6 +175,7 @@ py_Type pk_tuple__register() {
py_bindmagic(type, __getitem__, tuple__getitem__);
py_bindmagic(type, __eq__, tuple__eq__);
py_bindmagic(type, __ne__, tuple__ne__);
py_bindmagic(type, __lt__, tuple__lt__);
py_bindmagic(type, __iter__, tuple__iter__);
py_bindmagic(type, __contains__, tuple__contains__);
py_bindmagic(type, __hash__, tuple__hash__);

View File

@ -35,3 +35,20 @@ assert repr(tuple()) == '()'
# test in and not in
assert 1 in (1, 2, 3)
assert 4 not in (1, 2, 3)
# test < and == and !=
assert (1,2) == (1,2)
assert (2,1) == (2,1)
assert (1,) == (1,)
assert (1,2) != (1,3)
assert (1,2) != (1,2,3)
assert (1,2) != (1,)
assert (1,2) < (1,3)
assert (1,2) < (2,1)
assert (1,2) < (2,2)
assert (1,2) < (1,2,3)
assert (1,2) < (1,2,1)
assert (1,2) < (1,2,2)

View File

@ -574,11 +574,12 @@ assert max(1, 2, 3) == 3
assert max([1, 2]) == 2
assert max([1, 2, 3], key=lambda x: -x) == 1
# assert min([
# (1, 2),
# (1, 3),
# (1, 4),
# ]) == (1, 2)
assert min([
(3, 1),
(1, 2),
(1, 3),
(1, 4),
]) == (1, 2)
assert min(1, 2) == 1
assert max(1, 2) == 2