Kaynağa Gözat

fix `assert` message won't be evaluated on true cond

blueloveTH 2 yıl önce
ebeveyn
işleme
e26f389182
3 değiştirilmiş dosya ile 24 ekleme ve 17 silme
  1. 2 1
      include/pocketpy/opcodes.h
  2. 11 13
      src/ceval.cpp
  3. 11 3
      src/compiler.cpp

+ 2 - 1
include/pocketpy/opcodes.h

@@ -81,6 +81,7 @@ OPCODE(CONTAINS_OP)
 /**************************/
 OPCODE(JUMP_ABSOLUTE)
 OPCODE(POP_JUMP_IF_FALSE)
+OPCODE(POP_JUMP_IF_TRUE)
 OPCODE(JUMP_IF_TRUE_OR_POP)
 OPCODE(JUMP_IF_FALSE_OR_POP)
 OPCODE(SHORTCUT_IF_FALSE_OR_POP)
@@ -120,9 +121,9 @@ OPCODE(STORE_CLASS_ATTR)
 OPCODE(WITH_ENTER)
 OPCODE(WITH_EXIT)
 /**************************/
-OPCODE(ASSERT)
 OPCODE(EXCEPTION_MATCH)
 OPCODE(RAISE)
+OPCODE(RAISE_ASSERT)
 OPCODE(RE_RAISE)
 OPCODE(POP_EXCEPTION)
 /**************************/

+ 11 - 13
src/ceval.cpp

@@ -473,6 +473,9 @@ __NEXT_STEP:;
     TARGET(POP_JUMP_IF_FALSE)
         if(!py_bool(POPX())) frame->jump_abs(byte.arg);
         DISPATCH();
+    TARGET(POP_JUMP_IF_TRUE)
+        if(py_bool(POPX())) frame->jump_abs(byte.arg);
+        DISPATCH();
     TARGET(JUMP_IF_TRUE_OR_POP)
         if(py_bool(TOP()) == true) frame->jump_abs(byte.arg);
         else POP();
@@ -682,19 +685,6 @@ __NEXT_STEP:;
         call_method(POPX(), __exit__);
         DISPATCH();
     /*****************************************/
-    TARGET(ASSERT) {
-        _0 = TOP();
-        Str msg;
-        if(is_type(_0, tp_tuple)){
-            auto& t = CAST(Tuple&, _0);
-            if(t.size() != 2) ValueError("assert tuple must have 2 elements");
-            _0 = t[0];
-            msg = CAST(Str&, py_str(t[1]));
-        }
-        bool ok = py_bool(_0);
-        POP();
-        if(!ok) _error("AssertionError", msg);
-    } DISPATCH();
     TARGET(EXCEPTION_MATCH) {
         const auto& e = CAST(Exception&, TOP());
         _name = StrName(byte.arg);
@@ -705,6 +695,14 @@ __NEXT_STEP:;
         Str msg = _0 == None ? "" : CAST(Str, py_str(_0));
         _error(StrName(byte.arg), msg);
     } DISPATCH();
+    TARGET(RAISE_ASSERT)
+        if(byte.arg){
+            _0 = py_str(POPX());
+            _error("AssertionError", CAST(Str, _0));
+        }else{
+            _error("AssertionError", "");
+        }
+        DISPATCH();
     TARGET(RE_RAISE) _raise(true); DISPATCH();
     TARGET(POP_EXCEPTION) _last_exception = POPX(); DISPATCH();
     /*****************************************/

+ 11 - 3
src/compiler.cpp

@@ -802,11 +802,19 @@ __EAT_DOTS_END:
                 consume_end_stmt();
                 break;
             }
-            case TK("assert"):
-                EXPR_TUPLE(false);
-                ctx()->emit(OP_ASSERT, BC_NOARG, kw_line);
+            case TK("assert"):{
+                EXPR(false);    // condition
+                int index = ctx()->emit(OP_POP_JUMP_IF_TRUE, BC_NOARG, kw_line);
+                int has_msg = 0;
+                if(match(TK(","))){
+                    EXPR(false);    // message
+                    has_msg = 1;
+                }
+                ctx()->emit(OP_RAISE_ASSERT, has_msg, kw_line);
+                ctx()->patch_jump(index);
                 consume_end_stmt();
                 break;
+            }
             case TK("global"):
                 do {
                     consume(TK("@id"));