mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-15 17:02:53 +08:00
support __eq__ for tuple & list & dict
This commit is contained in:
parent
edd320c9d3
commit
f882ff153b
23
examples/builtins/eq.py
Normal file
23
examples/builtins/eq.py
Normal file
@ -0,0 +1,23 @@
|
||||
assert [1, 2, 3] == [1, 2, 3]
|
||||
assert [1, 2, 3] != [1, 2, 4]
|
||||
|
||||
assert (1, 2, 3) == (1, 2, 3)
|
||||
assert (1, 2, 3) != (1, 2, 4)
|
||||
|
||||
assert (1, 2, 3) != [1, 2, 3]
|
||||
assert [1, 2, 3] != (1, 2, 3)
|
||||
assert [1, 2, 3] != 1
|
||||
|
||||
assert 1 != (1, 2, 3)
|
||||
|
||||
assert ('a', 'b', 'c') == ('a', 'b', 'c')
|
||||
assert ('a', 'b', 'c') != ('a', 'b', 'd')
|
||||
|
||||
dict1 = {'a': 1, 'b': 2, 'c': 3}
|
||||
dict2 = {'a': 1, 'b': 2, 'c': 3}
|
||||
dict3 = {'a': 1, 'b': 2, 'c': 4}
|
||||
|
||||
assert dict1 == dict2
|
||||
assert dict1 != dict3
|
||||
|
||||
print("PASS")
|
@ -27,6 +27,9 @@ class Tuple:
|
||||
def __contains__(self, val: any) -> int:
|
||||
""" support val in list """
|
||||
|
||||
def __eq__(self, other: any) -> int:
|
||||
""" support list == list """
|
||||
|
||||
|
||||
class List(Tuple):
|
||||
def __init__(self): ...
|
||||
@ -90,6 +93,9 @@ class Dict:
|
||||
|
||||
def update(self, other: Dict):
|
||||
""" update dict """
|
||||
|
||||
def __eq__(self, other: any) -> int:
|
||||
""" support dict == dict """
|
||||
|
||||
|
||||
class dict_keys:
|
||||
|
@ -293,3 +293,28 @@ void PikaStdData_Dict_update(PikaObj* self, PikaObj* other) {
|
||||
pikaVM_runByteCode(context, (uint8_t*)bytes);
|
||||
obj_deinit(context);
|
||||
}
|
||||
|
||||
int PikaStdData_Dict___eq__(PikaObj* self, Arg* other) {
|
||||
if (!arg_isObject(other)) {
|
||||
return 0;
|
||||
}
|
||||
PikaObj* oOther = arg_getObj(other);
|
||||
if (self->constructor != oOther->constructor) {
|
||||
return 0;
|
||||
}
|
||||
if (obj_getSize(self) != obj_getSize(oOther)) {
|
||||
return 0;
|
||||
}
|
||||
for (size_t i = 0; i < obj_getSize(self); i++) {
|
||||
Arg* key = args_getArgByIndex(_OBJ2KEYS(self), i);
|
||||
Arg* val = args_getArgByIndex(_OBJ2DICT(self), i);
|
||||
Arg* oVal = pikaDict_get(oOther, arg_getStr(key));
|
||||
if (NULL == oVal) {
|
||||
return 0;
|
||||
}
|
||||
if (!arg_isEqual(val, oVal)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -106,3 +106,24 @@ int PikaStdData_Tuple___contains__(PikaObj* self, Arg* val) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PikaStdData_Tuple___eq__(PikaObj* self, Arg* other) {
|
||||
if (!arg_isObject(other)) {
|
||||
return 0;
|
||||
}
|
||||
PikaObj* oOther = arg_getObj(other);
|
||||
if (self->constructor != oOther->constructor) {
|
||||
return 0;
|
||||
}
|
||||
if (obj_getSize(self) != obj_getSize(oOther)) {
|
||||
return 0;
|
||||
}
|
||||
for (size_t i = 0; i < pikaList_getSize(self); i++) {
|
||||
Arg* arg = pikaList_get(self, i);
|
||||
Arg* otherArg = pikaList_get(oOther, i);
|
||||
if (!arg_isEqual(arg, otherArg)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
2
port/linux/.vscode/launch.json
vendored
2
port/linux/.vscode/launch.json
vendored
@ -12,7 +12,7 @@
|
||||
// "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
|
||||
"args": [
|
||||
// "--gtest_filter=vm.keyword_2"
|
||||
"--gtest_filter=struct.unpack"
|
||||
"--gtest_filter=builtin.eq"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
|
@ -27,6 +27,9 @@ class Tuple:
|
||||
def __contains__(self, val: any) -> int:
|
||||
""" support val in list """
|
||||
|
||||
def __eq__(self, other: any) -> int:
|
||||
""" support list == list """
|
||||
|
||||
|
||||
class List(Tuple):
|
||||
def __init__(self): ...
|
||||
@ -90,6 +93,9 @@ class Dict:
|
||||
|
||||
def update(self, other: Dict):
|
||||
""" update dict """
|
||||
|
||||
def __eq__(self, other: any) -> int:
|
||||
""" support dict == dict """
|
||||
|
||||
|
||||
class dict_keys:
|
||||
|
@ -293,3 +293,28 @@ void PikaStdData_Dict_update(PikaObj* self, PikaObj* other) {
|
||||
pikaVM_runByteCode(context, (uint8_t*)bytes);
|
||||
obj_deinit(context);
|
||||
}
|
||||
|
||||
int PikaStdData_Dict___eq__(PikaObj* self, Arg* other) {
|
||||
if (!arg_isObject(other)) {
|
||||
return 0;
|
||||
}
|
||||
PikaObj* oOther = arg_getObj(other);
|
||||
if (self->constructor != oOther->constructor) {
|
||||
return 0;
|
||||
}
|
||||
if (obj_getSize(self) != obj_getSize(oOther)) {
|
||||
return 0;
|
||||
}
|
||||
for (size_t i = 0; i < obj_getSize(self); i++) {
|
||||
Arg* key = args_getArgByIndex(_OBJ2KEYS(self), i);
|
||||
Arg* val = args_getArgByIndex(_OBJ2DICT(self), i);
|
||||
Arg* oVal = pikaDict_get(oOther, arg_getStr(key));
|
||||
if (NULL == oVal) {
|
||||
return 0;
|
||||
}
|
||||
if (!arg_isEqual(val, oVal)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -106,3 +106,24 @@ int PikaStdData_Tuple___contains__(PikaObj* self, Arg* val) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PikaStdData_Tuple___eq__(PikaObj* self, Arg* other) {
|
||||
if (!arg_isObject(other)) {
|
||||
return 0;
|
||||
}
|
||||
PikaObj* oOther = arg_getObj(other);
|
||||
if (self->constructor != oOther->constructor) {
|
||||
return 0;
|
||||
}
|
||||
if (obj_getSize(self) != obj_getSize(oOther)) {
|
||||
return 0;
|
||||
}
|
||||
for (size_t i = 0; i < pikaList_getSize(self); i++) {
|
||||
Arg* arg = pikaList_get(self, i);
|
||||
Arg* otherArg = pikaList_get(oOther, i);
|
||||
if (!arg_isEqual(arg, otherArg)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -594,6 +594,12 @@ TEST(compiler, __add__) {
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
TEST(compiler, __eq__) {
|
||||
char* lines = "@res_eq = __eq__(__others)";
|
||||
pika_lines2Array(lines);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
TEST(compiler, __iter__) {
|
||||
char* lines = "@res_iter = __iter__()";
|
||||
pika_lines2Array(lines);
|
||||
|
23
port/linux/test/python/builtins/eq.py
Normal file
23
port/linux/test/python/builtins/eq.py
Normal file
@ -0,0 +1,23 @@
|
||||
assert [1, 2, 3] == [1, 2, 3]
|
||||
assert [1, 2, 3] != [1, 2, 4]
|
||||
|
||||
assert (1, 2, 3) == (1, 2, 3)
|
||||
assert (1, 2, 3) != (1, 2, 4)
|
||||
|
||||
assert (1, 2, 3) != [1, 2, 3]
|
||||
assert [1, 2, 3] != (1, 2, 3)
|
||||
assert [1, 2, 3] != 1
|
||||
|
||||
assert 1 != (1, 2, 3)
|
||||
|
||||
assert ('a', 'b', 'c') == ('a', 'b', 'c')
|
||||
assert ('a', 'b', 'c') != ('a', 'b', 'd')
|
||||
|
||||
dict1 = {'a': 1, 'b': 2, 'c': 3}
|
||||
dict2 = {'a': 1, 'b': 2, 'c': 3}
|
||||
dict3 = {'a': 1, 'b': 2, 'c': 4}
|
||||
|
||||
assert dict1 == dict2
|
||||
assert dict1 != dict3
|
||||
|
||||
print("PASS")
|
28
src/PikaVM.c
28
src/PikaVM.c
@ -2697,6 +2697,34 @@ static void _OPT_EQU(OperatorInfo* op) {
|
||||
}
|
||||
if (argType_isObject(op->t1) && argType_isObject(op->t2)) {
|
||||
is_equ = (arg_getPtr(op->a1) == arg_getPtr(op->a2));
|
||||
if (is_equ) {
|
||||
goto __exit;
|
||||
}
|
||||
Arg* __eq__ =
|
||||
obj_getMethodArgWithFullPath(arg_getPtr(op->a1), "__eq__");
|
||||
if (NULL != __eq__) {
|
||||
arg_deinit(__eq__);
|
||||
PikaObj* oThis = arg_getObj(op->a1);
|
||||
obj_setArg(oThis, "__others", op->a2);
|
||||
/* clang-format off */
|
||||
PIKA_PYTHON(
|
||||
@res_eq = __eq__(__others)
|
||||
)
|
||||
/* clang-format on */
|
||||
const uint8_t bytes[] = {
|
||||
0x0c, 0x00, 0x00, 0x00, /* instruct array size */
|
||||
0x10, 0x81, 0x01, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x04,
|
||||
0x11, 0x00,
|
||||
/* instruct array */
|
||||
0x19, 0x00, 0x00, 0x00, /* const pool size */
|
||||
0x00, 0x5f, 0x5f, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73, 0x00,
|
||||
0x5f, 0x5f, 0x65, 0x71, 0x5f, 0x5f, 0x00, 0x40, 0x72, 0x65,
|
||||
0x73, 0x5f, 0x65, 0x71, 0x00,
|
||||
/* const pool */
|
||||
};
|
||||
pikaVM_runByteCode(oThis, (uint8_t*)bytes);
|
||||
is_equ = obj_getInt(oThis, "@res_eq");
|
||||
}
|
||||
goto __exit;
|
||||
}
|
||||
/* default: int bool, and float */
|
||||
|
@ -2,4 +2,4 @@
|
||||
#define PIKA_VERSION_MINOR 12
|
||||
#define PIKA_VERSION_MICRO 5
|
||||
|
||||
#define PIKA_EDIT_TIME "2023/08/17 22:02:10"
|
||||
#define PIKA_EDIT_TIME "2023/08/17 23:33:21"
|
||||
|
Loading…
x
Reference in New Issue
Block a user