Procházet zdrojové kódy

fix `if <str/bytes/object/list>` behavior

Lyon před 2 roky
rodič
revize
0249f2bf75

+ 39 - 0
examples/builtins/bool.py

@@ -38,4 +38,43 @@ if False:
 else:
     assert True
 
+# If statement with string
+
+
+def is_string_empty(s):
+    if s:
+        return False
+    else:
+        return True
+
+
+assert is_string_empty('Hello') == False
+assert is_string_empty('') == True
+
+# If statement with list
+
+
+def is_list_empty(lst):
+    if lst:
+        return False
+    else:
+        return True
+
+
+assert is_list_empty([1, 2, 3]) == False
+assert is_list_empty([]) == True
+
+# If statement with string comparison
+
+
+def compare_strings(s1, s2):
+    if s1 == s2:
+        return True
+    else:
+        return False
+
+
+assert compare_strings('abc', 'abc') == True
+assert compare_strings('abc', 'def') == False
+
 print("PASS")

+ 2 - 1
port/linux/.vscode/launch.json

@@ -14,8 +14,9 @@
                 // "--gtest_filter=builtin.write_fn"
                 // "--gtest_filter=builtin.base_type"
                 // "--gtest_filter=parser.comprehension"
-                "--gtest_filter=parser.*"
+                // "--gtest_filter=parser.*"
                 // "--gtest_filter=pikaMain.slice2"
+                "--gtest_filter=re.match"
             ],
             "stopAtEntry": false,
             "cwd": "${workspaceFolder}",

+ 39 - 0
port/linux/test/python/builtins/bool.py

@@ -38,4 +38,43 @@ if False:
 else:
     assert True
 
+# If statement with string
+
+
+def is_string_empty(s):
+    if s:
+        return False
+    else:
+        return True
+
+
+assert is_string_empty('Hello') == False
+assert is_string_empty('') == True
+
+# If statement with list
+
+
+def is_list_empty(lst):
+    if lst:
+        return False
+    else:
+        return True
+
+
+assert is_list_empty([1, 2, 3]) == False
+assert is_list_empty([]) == True
+
+# If statement with string comparison
+
+
+def compare_strings(s1, s2):
+    if s1 == s2:
+        return True
+    else:
+        return False
+
+
+assert compare_strings('abc', 'abc') == True
+assert compare_strings('abc', 'def') == False
+
 print("PASS")

+ 2 - 1
src/PikaObj.c

@@ -3013,7 +3013,8 @@ PIKA_RES _transeBool(Arg* arg, pika_bool* res) {
     if (arg_isObject(arg)) {
         int64_t len = obj_getSize(arg_getObj(arg));
         if (len < 0) {
-            return PIKA_RES_ERR_INVALID_PARAM;
+            *res = pika_true;
+            return PIKA_RES_OK;
         }
         if (len == 0) {
             *res = pika_false;

+ 1 - 0
src/PikaObj.h

@@ -775,6 +775,7 @@ int32_t objDict_forEach(PikaObj* self,
                                               void* context),
                         void* context);
 void pika_sleep_ms(uint32_t ms);
+PIKA_RES _transeBool(Arg* arg, pika_bool* res);
 
 #endif
 #ifdef __cplusplus

+ 22 - 16
src/PikaVM.c

@@ -2388,18 +2388,18 @@ static Arg* _VM_JEZ(PikaObj* self,
                     VMState* vm,
                     char* data,
                     Arg* arg_ret_reg,
-                    int pika_assert) {
+                    int bAssert) {
     int thisBlockDeepth = VMState_getBlockDeepthNow(vm);
     int jmp_expect = fast_atoi(data);
-    vm->ireg[thisBlockDeepth] = (pika_bool)!pika_assert;
+    vm->ireg[thisBlockDeepth] = (pika_bool)!bAssert;
 
-    if (0 == pika_assert) {
+    if (0 == bAssert) {
         /* jump */
         vm->jmp = jmp_expect;
     }
 
     /* restore loop deepth */
-    if (2 == jmp_expect && 0 == pika_assert) {
+    if (2 == jmp_expect && 0 == bAssert) {
         int block_deepth_now = VMState_getBlockDeepthNow(vm);
         vm->loop_deepth = block_deepth_now;
     }
@@ -2411,26 +2411,32 @@ static Arg* VM_instruction_handler_JEZ(PikaObj* self,
                                        VMState* vm,
                                        char* data,
                                        Arg* arg_ret_reg) {
-    Arg* pika_assertArg = stack_popArg(&(vm->stack), arg_ret_reg);
-    int pika_assert = 0;
-    if (NULL != pika_assertArg) {
-        pika_assert = arg_getInt(pika_assertArg);
-        arg_deinit(pika_assertArg);
+    Arg* aAssert = stack_popArg(&(vm->stack), arg_ret_reg);
+    pika_bool bAssert = 0;
+    if (NULL != aAssert) {
+        PIKA_RES res = _transeBool(aAssert, &bAssert);
+        if (PIKA_RES_OK != res) {
+            bAssert = 0;
+        }
+        arg_deinit(aAssert);
     }
-    return _VM_JEZ(self, vm, data, arg_ret_reg, pika_assert);
+    return _VM_JEZ(self, vm, data, arg_ret_reg, bAssert);
 }
 
 static Arg* VM_instruction_handler_JNZ(PikaObj* self,
                                        VMState* vm,
                                        char* data,
                                        Arg* arg_ret_reg) {
-    Arg* pika_assertArg = stack_popArg(&(vm->stack), arg_ret_reg);
-    int pika_assert = 0;
-    if (NULL != pika_assertArg) {
-        pika_assert = arg_getInt(pika_assertArg);
-        arg_deinit(pika_assertArg);
+    Arg* aAssert = stack_popArg(&(vm->stack), arg_ret_reg);
+    pika_bool bAssert = 0;
+    if (NULL != aAssert) {
+        PIKA_RES res = _transeBool(aAssert, &bAssert);
+        if (PIKA_RES_OK != res) {
+            bAssert = 0;
+        }
+        arg_deinit(aAssert);
     }
-    return _VM_JEZ(self, vm, data, arg_ret_reg, !pika_assert);
+    return _VM_JEZ(self, vm, data, arg_ret_reg, !bAssert);
 }
 
 static uint8_t VMState_getInputArgNum(VMState* vm) {