More fixes to tuple comparisons; port to lists
This commit is contained in:
parent
d6018001ba
commit
2d8de139b3
@ -791,6 +791,20 @@ extern KrkValue krk_operator_lt(KrkValue,KrkValue);
|
|||||||
*/
|
*/
|
||||||
extern KrkValue krk_operator_gt(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.
|
* @brief Set the maximum recursion call depth.
|
||||||
*/
|
*/
|
||||||
|
@ -475,6 +475,28 @@ KRK_Method(list,__iter__) {
|
|||||||
return OBJECT_VAL(output);
|
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
|
#undef CURRENT_CTYPE
|
||||||
|
|
||||||
struct ListIterator {
|
struct ListIterator {
|
||||||
@ -564,6 +586,10 @@ void _createAndBind_listClass(void) {
|
|||||||
BIND_METHOD(list,__iter__);
|
BIND_METHOD(list,__iter__);
|
||||||
BIND_METHOD(list,__mul__);
|
BIND_METHOD(list,__mul__);
|
||||||
BIND_METHOD(list,__add__);
|
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),
|
KRK_DOC(BIND_METHOD(list,append),
|
||||||
"@brief Add an item to the end of the list.\n"
|
"@brief Add an item to the end of the list.\n"
|
||||||
"@arguments item\n\n"
|
"@arguments item\n\n"
|
||||||
|
@ -124,71 +124,27 @@ KRK_Method(tuple,__eq__) {
|
|||||||
return BOOLEAN_VAL(1);
|
return BOOLEAN_VAL(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
KRK_Method(tuple,__lt__) {
|
#define MAKE_TUPLE_COMPARE(name,op) \
|
||||||
METHOD_TAKES_EXACTLY(1);
|
KRK_Method(tuple,__ ## name ## __) { \
|
||||||
if (!IS_tuple(argv[1])) return NOTIMPL_VAL();
|
METHOD_TAKES_EXACTLY(1); \
|
||||||
KrkTuple * them = AS_tuple(argv[1]);
|
if (!IS_tuple(argv[1])) return NOTIMPL_VAL(); \
|
||||||
size_t lesser = self->values.count < them->values.count ? self->values.count : them->values.count;
|
KrkTuple * them = AS_tuple(argv[1]); \
|
||||||
for (size_t i = 0; i < lesser; ++i) {
|
size_t lesser = self->values.count < them->values.count ? self->values.count : them->values.count; \
|
||||||
KrkValue a = self->values.values[i];
|
for (size_t i = 0; i < lesser; ++i) { \
|
||||||
KrkValue b = them->values.values[i];
|
KrkValue a = self->values.values[i]; \
|
||||||
KrkValue ltComp = krk_operator_lt(a,b);
|
KrkValue b = them->values.values[i]; \
|
||||||
if (IS_BOOLEAN(ltComp) && AS_BOOLEAN(ltComp)) return BOOLEAN_VAL(1);
|
if (krk_valuesSameOrEqual(a,b)) continue; \
|
||||||
KrkValue gtComp = krk_operator_gt(a,b);
|
KrkValue cmComp = krk_operator_ ## name(a,b); \
|
||||||
if (IS_BOOLEAN(gtComp) && AS_BOOLEAN(gtComp)) return BOOLEAN_VAL(0);
|
if (IS_BOOLEAN(cmComp) && AS_BOOLEAN(cmComp)) return BOOLEAN_VAL(1); \
|
||||||
/* continue on == */
|
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__) {
|
MAKE_TUPLE_COMPARE(gt,>)
|
||||||
METHOD_TAKES_EXACTLY(1);
|
MAKE_TUPLE_COMPARE(lt,<)
|
||||||
if (!IS_tuple(argv[1])) return NOTIMPL_VAL();
|
MAKE_TUPLE_COMPARE(ge,>=)
|
||||||
KrkTuple * them = AS_tuple(argv[1]);
|
MAKE_TUPLE_COMPARE(le,<=)
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
KRK_Method(tuple,__repr__) {
|
KRK_Method(tuple,__repr__) {
|
||||||
if (((KrkObj*)self)->flags & KRK_OBJ_FLAGS_IN_REPR) return OBJECT_VAL(S("(...)"));
|
if (((KrkObj*)self)->flags & KRK_OBJ_FLAGS_IN_REPR) return OBJECT_VAL(S("(...)"));
|
||||||
|
36
test/testSequenceCompare.krk
Normal file
36
test/testSequenceCompare.krk
Normal 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()
|
27
test/testSequenceCompare.krk.expect
Normal file
27
test/testSequenceCompare.krk.expect
Normal 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
|
Loading…
Reference in New Issue
Block a user