blueloveTH 2 rokov pred
rodič
commit
b3b6f8c87c
5 zmenil súbory, kde vykonal 21 pridanie a 7 odobranie
  1. 1 1
      src/common.h
  2. 8 1
      src/compiler.h
  3. 7 3
      src/expr.h
  4. 1 1
      src/vm.h
  5. 4 1
      tests/99_bugs.py

+ 1 - 1
src/common.h

@@ -20,7 +20,7 @@
 #include <variant>
 #include <type_traits>
 
-#define PK_VERSION				"1.0.4"
+#define PK_VERSION				"1.0.5"
 
 #include "config.h"
 

+ 8 - 1
src/compiler.h

@@ -679,7 +679,7 @@ __SUBSCR_END:
             case TK("<<="): case TK(">>="): case TK("&="): case TK("|="): case TK("^="): {
                 Expr* lhs_p = ctx()->s_expr.top().get();
                 if(lhs_p->is_starred()) SyntaxError();
-                if(ctx()->is_compiling_class) SyntaxError();
+                if(ctx()->is_compiling_class) SyntaxError("can't use inplace operator in class definition");
                 advance();
                 auto e = make_expr<BinaryExpr>();
                 e->op = prev().type - 1; // -1 to remove =
@@ -695,8 +695,15 @@ __SUBSCR_END:
                 int n = 0;
                 while(match(TK("="))){
                     EXPR_TUPLE();
+                    Expr* _tp = ctx()->s_expr.top().get();
+                    if(ctx()->is_compiling_class && _tp->is_tuple()){
+                        SyntaxError("can't use unpack tuple in class definition");
+                    }
                     n += 1;
                 }
+                if(ctx()->is_compiling_class && n>1){
+                    SyntaxError("can't assign to multiple targets in class definition");
+                }
                 // stack size is n+1
                 Expr_ val = ctx()->s_expr.popx();
                 val->emit(ctx());

+ 7 - 3
src/expr.h

@@ -61,12 +61,16 @@ struct CodeEmitContext{
     }
 
     void exit_block(){
-        if(co->blocks[curr_block_i].type == FOR_LOOP) for_loop_depth--;
+        auto curr_type = co->blocks[curr_block_i].type;
+        if(curr_type == FOR_LOOP) for_loop_depth--;
         co->blocks[curr_block_i].end = co->codes.size();
         curr_block_i = co->blocks[curr_block_i].parent;
         if(curr_block_i < 0) FATAL_ERROR();
-        // add a no op here to make block check work
-        emit(OP_NO_OP, BC_NOARG, BC_KEEPLINE);
+
+        if(curr_type == FOR_LOOP){
+            // add a no op here to make block check work
+            emit(OP_NO_OP, BC_NOARG, BC_KEEPLINE);
+        }
     }
 
     // clear the expression stack and generate bytecode

+ 1 - 1
src/vm.h

@@ -995,7 +995,7 @@ inline std::string _opcode_argstr(VM* vm, Bytecode byte, const CodeObject* co){
         case OP_LOAD_NAME: case OP_LOAD_GLOBAL: case OP_LOAD_NONLOCAL: case OP_STORE_GLOBAL:
         case OP_LOAD_ATTR: case OP_LOAD_METHOD: case OP_STORE_ATTR: case OP_DELETE_ATTR:
         case OP_IMPORT_NAME: case OP_BEGIN_CLASS: case OP_RAISE:
-        case OP_DELETE_GLOBAL: case OP_INC_GLOBAL: case OP_DEC_GLOBAL:
+        case OP_DELETE_GLOBAL: case OP_INC_GLOBAL: case OP_DEC_GLOBAL: case OP_STORE_CLASS_ATTR:
             argStr += fmt(" (", StrName(byte.arg).sv(), ")");
             break;
         case OP_LOAD_FAST: case OP_STORE_FAST: case OP_DELETE_FAST: case OP_INC_FAST: case OP_DEC_FAST:

+ 4 - 1
tests/99_bugs.py

@@ -53,4 +53,7 @@ def f():
     for i in range(4):
         _ = 0
     while i: --i
-f()
+f()
+
+# class A: a=b=1
+# class A: a, b = 1, 2