Ver código fonte

support `yield` implicit None

blueloveTH 1 ano atrás
pai
commit
18fc4c02d3
3 arquivos alterados com 16 adições e 6 exclusões
  1. 8 4
      src/compiler/compiler.c
  2. 6 2
      src/interpreter/ceval.c
  3. 2 0
      tests/51_yield.py

+ 8 - 4
src/compiler/compiler.c

@@ -2498,10 +2498,14 @@ static Error* compile_stmt(Compiler* self) {
             break;
         case TK_YIELD:
             if(self->contexts.length <= 1) return SyntaxError(self, "'yield' outside function");
-            check(EXPR_TUPLE(self));
-            Ctx__s_emit_top(ctx());
-            Ctx__emit_(ctx(), OP_YIELD_VALUE, BC_NOARG, kw_line);
-            consume_end_stmt();
+            if(match_end_stmt(self)) {
+                Ctx__emit_(ctx(), OP_YIELD_VALUE, 1, kw_line);
+            } else {
+                check(EXPR_TUPLE(self));
+                Ctx__s_emit_top(ctx());
+                Ctx__emit_(ctx(), OP_YIELD_VALUE, BC_NOARG, kw_line);
+                consume_end_stmt();
+            }
             break;
         case TK_YIELD_FROM:
             check(compile_yield_from(self, kw_line));

+ 6 - 2
src/interpreter/ceval.c

@@ -715,8 +715,12 @@ FrameResult VM__run_top_frame(VM* self) {
                 DISPATCH();
             }
             case OP_YIELD_VALUE: {
-                py_assign(py_retval(), TOP());
-                POP();
+                if(byte.arg == 1) {
+                    py_newnone(py_retval());
+                } else {
+                    py_assign(py_retval(), TOP());
+                    POP();
+                }
                 return RES_YIELD;
             }
             /////////

+ 2 - 0
tests/51_yield.py

@@ -1,10 +1,12 @@
 def g():
     yield 1
     yield 2
+    yield
 
 a = g()
 assert next(a) == 1
 assert next(a, None) == 2
+assert next(a) == None
 
 try:
     next(a)