Quellcode durchsuchen

add `a<b<c` support

blueloveTH vor 2 Jahren
Ursprung
Commit
caadfefc01
6 geänderte Dateien mit 28 neuen und 10 gelöschten Zeilen
  1. 1 1
      docs/features/differences.md
  2. 1 0
      src/ceval.h
  3. 2 2
      src/common.h
  4. 3 3
      src/expr.h
  5. 5 4
      src/vm.h
  6. 16 0
      tests/31_cmp.py

+ 1 - 1
docs/features/differences.md

@@ -42,4 +42,4 @@ The easiest way to test a feature is to [try it on your browser](https://pocketp
 6. `__ne__` is not required. Define `__eq__` is enough.
 7. Raw string cannot have boundary quotes in it, even escaped. See [#55](https://github.com/blueloveTH/pocketpy/issues/55).
 8. In a starred unpacked assignment, e.g. `a, b, *c = x`, the starred variable can only be presented in the last position. `a, *b, c = x` is not supported.
-9. `a < b < c` does not work as you expected. Use `a < b and b < c` instead.
+9. `a < b < c` does not work as you expected. Use `a < b and b < c` instead. **(available in main branch now)**

+ 1 - 0
src/ceval.h

@@ -420,6 +420,7 @@ __NEXT_STEP:;
             PUSH(vm->False);                // [False]
             frame->jump_abs(byte.arg);
         } else POP();                       // [b]
+        DISPATCH();
     TARGET(LOOP_CONTINUE)
         frame->jump_abs(co_blocks[byte.block].start);
         DISPATCH();

+ 2 - 2
src/common.h

@@ -178,9 +178,9 @@ inline PyObject* const PY_OP_CALL = (PyObject*)0b100011;
 inline PyObject* const PY_OP_YIELD = (PyObject*)0b110011;
 
 #ifdef _WIN32
-    char kPlatformSep = '\\';
+    inline const char kPlatformSep = '\\';
 #else
-    char kPlatformSep = '/';
+    inline const char kPlatformSep = '/';
 #endif
 
 } // namespace pkpy

+ 3 - 3
src/expr.h

@@ -716,13 +716,11 @@ struct BinaryExpr: Expr{
     }
 
     void emit(CodeEmitContext* ctx) override {
-        
+        std::vector<int> jmps;
         if(is_compare() && lhs->is_compare()){
             // (a < b) < c
-            std::vector<int> jmps;
             static_cast<BinaryExpr*>(lhs.get())->_emit_compare(ctx, jmps);
             // [b, RES]
-            for(int i: jmps) ctx->patch_jump(i);
         }else{
             // (1 + 2) < c
             lhs->emit(ctx);
@@ -759,6 +757,8 @@ struct BinaryExpr: Expr{
             case TK("@"):   ctx->emit(OP_BINARY_MATMUL, BC_NOARG, line);  break;
             default: FATAL_ERROR();
         }
+
+        for(int i: jmps) ctx->patch_jump(i);
     }
 };
 

+ 5 - 4
src/vm.h

@@ -1005,7 +1005,7 @@ inline Str VM::disassemble(CodeObject_ co){
 
     std::vector<int> jumpTargets;
     for(auto byte : co->codes){
-        if(byte.op == OP_JUMP_ABSOLUTE || byte.op == OP_POP_JUMP_IF_FALSE){
+        if(byte.op == OP_JUMP_ABSOLUTE || byte.op == OP_POP_JUMP_IF_FALSE || byte.op == OP_POP_JUMP_IF_FALSE || byte.op == OP_SHORTCUT_IF_FALSE_OR_POP){
             jumpTargets.push_back(byte.arg);
         }
     }
@@ -1027,11 +1027,12 @@ inline Str VM::disassemble(CodeObject_ co){
             pointer = "   ";
         }
         ss << pad(line, 8) << pointer << pad(std::to_string(i), 3);
-        ss << " " << pad(OP_NAMES[byte.op], 20) << " ";
+        ss << " " << pad(OP_NAMES[byte.op], 25) << " ";
         // ss << pad(byte.arg == -1 ? "" : std::to_string(byte.arg), 5);
         std::string argStr = _opcode_argstr(this, byte, co.get());
-        ss << pad(argStr, 40);      // may overflow
-        ss << co->blocks[byte.block].type;
+        ss << argStr;
+        // ss << pad(argStr, 40);      // may overflow
+        // ss << co->blocks[byte.block].type;
         if(i != co->codes.size() - 1) ss << '\n';
     }
 

+ 16 - 0
tests/31_cmp.py

@@ -0,0 +1,16 @@
+assert 1<2
+assert 1+1==2
+assert 2+1>=2
+
+assert 1<2<3
+assert 1<2<3<4
+assert 1<2<3<4<5
+
+assert 1<1+1<3
+assert 1<1+1<3<4
+assert 1<1+1<3<2+2<5
+
+a = [1,2,3]
+assert a[0] < a[1] < a[2]
+assert a[0]+1 == a[1] < a[2]
+assert a[0]+1 == a[1] < a[2]+1 < 5