mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-29 17:22:56 +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:
|
def __contains__(self, val: any) -> int:
|
||||||
""" support val in list """
|
""" support val in list """
|
||||||
|
|
||||||
|
def __eq__(self, other: any) -> int:
|
||||||
|
""" support list == list """
|
||||||
|
|
||||||
|
|
||||||
class List(Tuple):
|
class List(Tuple):
|
||||||
def __init__(self): ...
|
def __init__(self): ...
|
||||||
@ -91,6 +94,9 @@ class Dict:
|
|||||||
def update(self, other: Dict):
|
def update(self, other: Dict):
|
||||||
""" update dict """
|
""" update dict """
|
||||||
|
|
||||||
|
def __eq__(self, other: any) -> int:
|
||||||
|
""" support dict == dict """
|
||||||
|
|
||||||
|
|
||||||
class dict_keys:
|
class dict_keys:
|
||||||
def __iter__(self) -> any: ...
|
def __iter__(self) -> any: ...
|
||||||
|
@ -293,3 +293,28 @@ void PikaStdData_Dict_update(PikaObj* self, PikaObj* other) {
|
|||||||
pikaVM_runByteCode(context, (uint8_t*)bytes);
|
pikaVM_runByteCode(context, (uint8_t*)bytes);
|
||||||
obj_deinit(context);
|
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;
|
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",
|
// "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
|
||||||
"args": [
|
"args": [
|
||||||
// "--gtest_filter=vm.keyword_2"
|
// "--gtest_filter=vm.keyword_2"
|
||||||
"--gtest_filter=struct.unpack"
|
"--gtest_filter=builtin.eq"
|
||||||
],
|
],
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
|
@ -27,6 +27,9 @@ class Tuple:
|
|||||||
def __contains__(self, val: any) -> int:
|
def __contains__(self, val: any) -> int:
|
||||||
""" support val in list """
|
""" support val in list """
|
||||||
|
|
||||||
|
def __eq__(self, other: any) -> int:
|
||||||
|
""" support list == list """
|
||||||
|
|
||||||
|
|
||||||
class List(Tuple):
|
class List(Tuple):
|
||||||
def __init__(self): ...
|
def __init__(self): ...
|
||||||
@ -91,6 +94,9 @@ class Dict:
|
|||||||
def update(self, other: Dict):
|
def update(self, other: Dict):
|
||||||
""" update dict """
|
""" update dict """
|
||||||
|
|
||||||
|
def __eq__(self, other: any) -> int:
|
||||||
|
""" support dict == dict """
|
||||||
|
|
||||||
|
|
||||||
class dict_keys:
|
class dict_keys:
|
||||||
def __iter__(self) -> any: ...
|
def __iter__(self) -> any: ...
|
||||||
|
@ -293,3 +293,28 @@ void PikaStdData_Dict_update(PikaObj* self, PikaObj* other) {
|
|||||||
pikaVM_runByteCode(context, (uint8_t*)bytes);
|
pikaVM_runByteCode(context, (uint8_t*)bytes);
|
||||||
obj_deinit(context);
|
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;
|
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);
|
EXPECT_EQ(pikaMemNow(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(compiler, __eq__) {
|
||||||
|
char* lines = "@res_eq = __eq__(__others)";
|
||||||
|
pika_lines2Array(lines);
|
||||||
|
EXPECT_EQ(pikaMemNow(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(compiler, __iter__) {
|
TEST(compiler, __iter__) {
|
||||||
char* lines = "@res_iter = __iter__()";
|
char* lines = "@res_iter = __iter__()";
|
||||||
pika_lines2Array(lines);
|
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)) {
|
if (argType_isObject(op->t1) && argType_isObject(op->t2)) {
|
||||||
is_equ = (arg_getPtr(op->a1) == arg_getPtr(op->a2));
|
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;
|
goto __exit;
|
||||||
}
|
}
|
||||||
/* default: int bool, and float */
|
/* default: int bool, and float */
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
#define PIKA_VERSION_MINOR 12
|
#define PIKA_VERSION_MINOR 12
|
||||||
#define PIKA_VERSION_MICRO 5
|
#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