More fixes to tuple comparisons; port to lists

This commit is contained in:
K. Lange 2022-07-06 21:25:59 +09:00
parent d6018001ba
commit 2d8de139b3
5 changed files with 122 additions and 63 deletions

View File

@ -791,6 +791,20 @@ extern KrkValue krk_operator_lt(KrkValue,KrkValue);
*/
extern KrkValue krk_operator_gt(KrkValue,KrkValue);
/**
* @brief Compare two values, returning @ref True if the left is less than or equal to the right.
*
* This is equivalent to the opcode instruction OP_LESS_EQUAL.
*/
extern KrkValue krk_operator_le(KrkValue,KrkValue);
/**
* @brief Compare to values, returning @ref True if the left is greater than or equal to the right.
*
* This is equivalent to the opcode instruction OP_GREATER_EQUAL.
*/
extern KrkValue krk_operator_ge(KrkValue,KrkValue);
/**
* @brief Set the maximum recursion call depth.
*/

View File

@ -475,6 +475,28 @@ KRK_Method(list,__iter__) {
return OBJECT_VAL(output);
}
#define MAKE_LIST_COMPARE(name,op) \
KRK_Method(list,__ ## name ## __) { \
METHOD_TAKES_EXACTLY(1); \
if (!IS_list(argv[1])) return NOTIMPL_VAL(); \
KrkList * them = AS_list(argv[1]); \
size_t lesser = self->values.count < them->values.count ? self->values.count : them->values.count; \
for (size_t i = 0; i < lesser; ++i) { \
KrkValue a = self->values.values[i]; \
KrkValue b = them->values.values[i]; \
if (krk_valuesSameOrEqual(a,b)) continue; \
KrkValue cmComp = krk_operator_ ## name(a,b); \
if (IS_BOOLEAN(cmComp) && AS_BOOLEAN(cmComp)) return BOOLEAN_VAL(1); \
return BOOLEAN_VAL(0); \
} \
return BOOLEAN_VAL((self->values.count op them->values.count)); \
}
MAKE_LIST_COMPARE(gt,>)
MAKE_LIST_COMPARE(lt,<)
MAKE_LIST_COMPARE(ge,>=)
MAKE_LIST_COMPARE(le,<=)
#undef CURRENT_CTYPE
struct ListIterator {
@ -564,6 +586,10 @@ void _createAndBind_listClass(void) {
BIND_METHOD(list,__iter__);
BIND_METHOD(list,__mul__);
BIND_METHOD(list,__add__);
BIND_METHOD(list,__lt__);
BIND_METHOD(list,__gt__);
BIND_METHOD(list,__le__);
BIND_METHOD(list,__ge__);
KRK_DOC(BIND_METHOD(list,append),
"@brief Add an item to the end of the list.\n"
"@arguments item\n\n"

View File

@ -124,71 +124,27 @@ KRK_Method(tuple,__eq__) {
return BOOLEAN_VAL(1);
}
KRK_Method(tuple,__lt__) {
METHOD_TAKES_EXACTLY(1);
if (!IS_tuple(argv[1])) return NOTIMPL_VAL();
KrkTuple * them = AS_tuple(argv[1]);
size_t lesser = self->values.count < them->values.count ? self->values.count : them->values.count;
for (size_t i = 0; i < lesser; ++i) {
KrkValue a = self->values.values[i];
KrkValue b = them->values.values[i];
KrkValue ltComp = krk_operator_lt(a,b);
if (IS_BOOLEAN(ltComp) && AS_BOOLEAN(ltComp)) return BOOLEAN_VAL(1);
KrkValue gtComp = krk_operator_gt(a,b);
if (IS_BOOLEAN(gtComp) && AS_BOOLEAN(gtComp)) return BOOLEAN_VAL(0);
/* continue on == */
#define MAKE_TUPLE_COMPARE(name,op) \
KRK_Method(tuple,__ ## name ## __) { \
METHOD_TAKES_EXACTLY(1); \
if (!IS_tuple(argv[1])) return NOTIMPL_VAL(); \
KrkTuple * them = AS_tuple(argv[1]); \
size_t lesser = self->values.count < them->values.count ? self->values.count : them->values.count; \
for (size_t i = 0; i < lesser; ++i) { \
KrkValue a = self->values.values[i]; \
KrkValue b = them->values.values[i]; \
if (krk_valuesSameOrEqual(a,b)) continue; \
KrkValue cmComp = krk_operator_ ## name(a,b); \
if (IS_BOOLEAN(cmComp) && AS_BOOLEAN(cmComp)) return BOOLEAN_VAL(1); \
return BOOLEAN_VAL(0); \
} \
return BOOLEAN_VAL((self->values.count op them->values.count)); \
}
return BOOLEAN_VAL((self->values.count < them->values.count));
}
KRK_Method(tuple,__gt__) {
METHOD_TAKES_EXACTLY(1);
if (!IS_tuple(argv[1])) return NOTIMPL_VAL();
KrkTuple * them = AS_tuple(argv[1]);
size_t lesser = self->values.count < them->values.count ? self->values.count : them->values.count;
for (size_t i = 0; i < lesser; ++i) {
KrkValue a = self->values.values[i];
KrkValue b = them->values.values[i];
KrkValue gtComp = krk_operator_gt(a,b);
if (IS_BOOLEAN(gtComp) && AS_BOOLEAN(gtComp)) return BOOLEAN_VAL(1);
KrkValue ltComp = krk_operator_lt(a,b);
if (IS_BOOLEAN(ltComp) && AS_BOOLEAN(ltComp)) return BOOLEAN_VAL(0);
}
return BOOLEAN_VAL((self->values.count > them->values.count));
}
KRK_Method(tuple,__le__) {
METHOD_TAKES_EXACTLY(1);
if (!IS_tuple(argv[1])) return NOTIMPL_VAL();
KrkTuple * them = AS_tuple(argv[1]);
size_t lesser = self->values.count < them->values.count ? self->values.count : them->values.count;
for (size_t i = 0; i < lesser; ++i) {
KrkValue a = self->values.values[i];
KrkValue b = them->values.values[i];
KrkValue ltComp = krk_operator_lt(a,b);
if (IS_BOOLEAN(ltComp) && AS_BOOLEAN(ltComp)) return BOOLEAN_VAL(1);
KrkValue gtComp = krk_operator_gt(a,b);
if (IS_BOOLEAN(gtComp) && AS_BOOLEAN(gtComp)) return BOOLEAN_VAL(0);
/* continue on == */
}
return BOOLEAN_VAL((self->values.count <= them->values.count));
}
KRK_Method(tuple,__ge__) {
METHOD_TAKES_EXACTLY(1);
if (!IS_tuple(argv[1])) return NOTIMPL_VAL();
KrkTuple * them = AS_tuple(argv[1]);
size_t lesser = self->values.count < them->values.count ? self->values.count : them->values.count;
for (size_t i = 0; i < lesser; ++i) {
KrkValue a = self->values.values[i];
KrkValue b = them->values.values[i];
KrkValue gtComp = krk_operator_gt(a,b);
if (IS_BOOLEAN(gtComp) && AS_BOOLEAN(gtComp)) return BOOLEAN_VAL(1);
KrkValue ltComp = krk_operator_lt(a,b);
if (IS_BOOLEAN(ltComp) && AS_BOOLEAN(ltComp)) return BOOLEAN_VAL(0);
}
return BOOLEAN_VAL((self->values.count >= them->values.count));
}
MAKE_TUPLE_COMPARE(gt,>)
MAKE_TUPLE_COMPARE(lt,<)
MAKE_TUPLE_COMPARE(ge,>=)
MAKE_TUPLE_COMPARE(le,<=)
KRK_Method(tuple,__repr__) {
if (((KrkObj*)self)->flags & KRK_OBJ_FLAGS_IN_REPR) return OBJECT_VAL(S("(...)"));

View File

@ -0,0 +1,36 @@
class Foo():
def __init__(self, v):
self.v = v
def __lt__(self, o):
print(self.v,'<',o.v)
return self.v < o.v
def __le__(self, o):
print(self.v,'<=',o.v)
return self.v <= o.v
def __gt__(self, o):
print(self.v,'>',o.v)
return self.v > o.v
def __ge__(self, o):
print(self.v,'>=',o.v)
return self.v >= o.v
def __eq__(self, o):
print(self.v,'==',o.v)
return self.v == o.v
import math
def foo(a=Foo(math.nan)):
print(a is a)
print(a.v is a.v)
print(a.v == a.v)
print((a,Foo(2),Foo(3)) < (a,Foo(5),Foo(6)))
print((a,Foo(2),Foo(3)) > (a,Foo(2),Foo(3.0)))
print((a,Foo(2),Foo(3)) <= (a,Foo(5),Foo(6)))
print((a,Foo(2),Foo(3)) >= (a,Foo(2),Foo(3.0)))
print([a,Foo(2),Foo(3)] < [a,Foo(5),Foo(6)])
print([a,Foo(2),Foo(3)] > [a,Foo(2),Foo(3.0)])
print([a,Foo(2),Foo(3)] <= [a,Foo(5),Foo(6)])
print([a,Foo(2),Foo(3)] >= [a,Foo(2),Foo(3.0)])
foo()

View File

@ -0,0 +1,27 @@
True
True
False
2 == 5
2 < 5
True
2 == 2
3 == 3.0
False
2 == 5
2 <= 5
True
2 == 2
3 == 3.0
True
2 == 5
2 < 5
True
2 == 2
3 == 3.0
False
2 == 5
2 <= 5
True
2 == 2
3 == 3.0
True