impl yield from

This commit is contained in:
blueloveTH 2023-04-19 13:56:26 +08:00
parent 0f7dce130c
commit 839f766205
3 changed files with 29 additions and 1 deletions

View File

@ -730,6 +730,19 @@ __SUBSCR_END:
ctx()->emit(OP_YIELD_VALUE, BC_NOARG, kw_line); ctx()->emit(OP_YIELD_VALUE, BC_NOARG, kw_line);
consume_end_stmt(); consume_end_stmt();
break; break;
case TK("yield from"):
if (contexts.size() <= 1) SyntaxError("'yield from' outside function");
EXPR_TUPLE(false);
// if yield from present, mark the function as generator
ctx()->co->is_generator = true;
ctx()->emit(OP_GET_ITER, BC_NOARG, kw_line);
ctx()->enter_block(FOR_LOOP);
ctx()->emit(OP_FOR_ITER, BC_NOARG, BC_KEEPLINE);
ctx()->emit(OP_YIELD_VALUE, BC_NOARG, BC_KEEPLINE);
ctx()->emit(OP_LOOP_CONTINUE, BC_NOARG, BC_KEEPLINE);
ctx()->exit_block();
consume_end_stmt();
break;
case TK("return"): case TK("return"):
if (contexts.size() <= 1) SyntaxError("'return' outside function"); if (contexts.size() <= 1) SyntaxError("'return' outside function");
if(match_end_stmt()){ if(match_end_stmt()){

View File

@ -9,7 +9,7 @@ namespace pkpy{
typedef uint8_t TokenIndex; typedef uint8_t TokenIndex;
constexpr const char* kTokens[] = { constexpr const char* kTokens[] = {
"is not", "not in", "is not", "not in", "yield from",
"@eof", "@eol", "@sof", "@eof", "@eol", "@sof",
"@id", "@num", "@str", "@fstr", "@id", "@num", "@str", "@fstr",
"@indent", "@dedent", "@indent", "@dedent",
@ -231,6 +231,12 @@ struct Lexer {
add_token(TK("is not")); add_token(TK("is not"));
return 0; return 0;
} }
}else if(name == "yield"){
if(strncmp(curr_char, " from", 5) == 0){
curr_char += 5;
add_token(TK("yield from"));
return 0;
}
} }
add_token(kTokenKwMap.at(name)); add_token(kTokenKwMap.at(name));
} else { } else {

View File

@ -28,3 +28,12 @@ assert a[5] == (1,2)
assert a[6] == (2,0) assert a[6] == (2,0)
assert a[7] == (2,1) assert a[7] == (2,1)
assert a[8] == (2,2) assert a[8] == (2,2)
def g():
yield from [1, 2, 3]
def f():
yield from g()
a = [i for i in f()]
assert a == [1, 2, 3]