diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index a21e3a9c4..7c76975e4 100644 --- a/port/linux/.vscode/launch.json +++ b/port/linux/.vscode/launch.json @@ -20,7 +20,7 @@ // "--gtest_filter=eventloop.test1" // "--gtest_filter=parser.tuple_single" // "--gtest_filter=parser.*" - "--gtest_filter=parser.default_tuple" + "--gtest_filter=VM.is" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/src/PikaParser.c b/src/PikaParser.c index d17d79f18..7168caa47 100644 --- a/src/PikaParser.c +++ b/src/PikaParser.c @@ -1591,32 +1591,36 @@ static void _AST_parse_slice(AST* ast, Args* buffs, char* stmt) { } } -char* Suger_not_in(Args* out_buffs, char* line) { -#if PIKA_NANO_ENABLE - return line; -#endif +#include +#include "pikaScript.h" + +char* _Suger_process(Args* out_buffs, + char* line, + char* token1, + char* token2, + char* format) { char* ret = line; char* stmt1 = ""; char* stmt2 = ""; - PIKA_BOOL got_not_in = PIKA_FALSE; + PIKA_BOOL got_tokens = PIKA_FALSE; PIKA_BOOL skip = PIKA_FALSE; Args buffs = {0}; - if (1 != Cursor_count(line, TOKEN_operator, " not ")) { + + if (1 != Cursor_count(line, TOKEN_operator, token1)) { ret = line; goto __exit; } - if (1 != Cursor_count(line, TOKEN_operator, " in ")) { + if (1 != Cursor_count(line, TOKEN_operator, token2)) { ret = line; goto __exit; } - /* stmt1 not in stmt2 => not stmt1 in stmt2 */ Cursor_forEach(cs, line) { Cursor_iterStart(&cs); - if (!got_not_in) { - if (strEqu(cs.token1.pyload, " not ") && - strEqu(cs.token2.pyload, " in ")) { - got_not_in = PIKA_TRUE; + if (!got_tokens) { + if (strEqu(cs.token1.pyload, token1) && + strEqu(cs.token2.pyload, token2)) { + got_tokens = PIKA_TRUE; Cursor_iterEnd(&cs); continue; } @@ -1632,18 +1636,29 @@ char* Suger_not_in(Args* out_buffs, char* line) { Cursor_iterEnd(&cs); } Cursor_deinit(&cs); - if (!got_not_in) { + + if (!got_tokens) { ret = line; goto __exit; } - ret = strsFormat(out_buffs, strGetSize(line) + 3, " not %s in %s", stmt1, - stmt2); - goto __exit; + + ret = strsFormat(out_buffs, + strGetSize(line) + strlen(token1) + strlen(token2), format, + stmt1, stmt2); + __exit: strsDeinit(&buffs); return ret; } +char* Suger_not_in(Args* out_buffs, char* line) { + return _Suger_process(out_buffs, line, " not ", " in ", " not %s in %s"); +} + +char* Suger_is_not(Args* out_buffs, char* line) { + return _Suger_process(out_buffs, line, " is ", " not ", " not %s is %s"); +} + AST* AST_parseStmt(AST* ast, char* stmt) { Args buffs = {0}; char* assignment = Cursor_splitCollect(&buffs, stmt, "(", 0); @@ -1713,6 +1728,7 @@ AST* AST_parseStmt(AST* ast, char* stmt) { /* solve operator stmt */ if (STMT_operator == stmtType) { right = Suger_not_in(&buffs, right); + right = Suger_is_not(&buffs, right); char* rightWithoutSubStmt = _remove_sub_stmt(&buffs, right); char* operator= Lexer_getOperator(&buffs, rightWithoutSubStmt); if (NULL == operator) { diff --git a/src/PikaVM.c b/src/PikaVM.c index 1fd74c9cc..6d8a4180f 100644 --- a/src/PikaVM.c +++ b/src/PikaVM.c @@ -2826,6 +2826,11 @@ static Arg* VM_instruction_handler_OPT(PikaObj* self, } goto exit; } + if ((op.t1 != op.t2) && (op.t1 != ARG_TYPE_NONE) && + (op.t2 != ARG_TYPE_NONE)) { + op.res = arg_setInt(op.res, "", 0); + goto exit; + } #endif op.opt = "=="; _OPT_EQU(&op); diff --git a/test/VM-test.cpp b/test/VM-test.cpp index 8701f10d3..a3ddeffff 100644 --- a/test/VM-test.cpp +++ b/test/VM-test.cpp @@ -2848,6 +2848,8 @@ TEST_RUN_SINGLE_FILE_PASS(datastruct, TEST_RUN_LINES_EXCEPT_OUTPUT(vm, single_tuple, "(1,)", "(1,)\r\n") TEST_RUN_LINES_EXCEPT_OUTPUT(vm, single_tuple_str, "('test',)", "('test',)\r\n") +TEST_RUN_SINGLE_FILE_PASS(vm, is_not, "test/python/builtin/is_not.py") + #endif TEST_END \ No newline at end of file diff --git a/test/parse-test.cpp b/test/parse-test.cpp index c1d2be18a..ce692e307 100644 --- a/test/parse-test.cpp +++ b/test/parse-test.cpp @@ -5614,6 +5614,15 @@ TEST_LINES2ASM(default_tuple, "0 RET \n" "B0\n") +TEST_LINES2ASM(is_not, + "A is not None", + "B0\n" + "2 REF A\n" + "2 REF None\n" + "1 OPT is \n" + "0 OPT not \n" + "B0\n") + #endif TEST_END \ No newline at end of file diff --git a/test/python/builtin/is_not.py b/test/python/builtin/is_not.py new file mode 100644 index 000000000..f6ee818cc --- /dev/null +++ b/test/python/builtin/is_not.py @@ -0,0 +1,10 @@ + +assert (1 is not 1) == False +assert (1 is not 2) == True +assert (1 is not None) == True +assert (None is not None) == False +assert (None is not 1) == True +assert (1 is not 1.0) == True +assert (1.0 is not 1) == True +assert (1.0 is not 1.0) == False +print("PASS")