From 0e3329a6b82873531f63fb1358f57852723fad05 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 11 Apr 2014 13:10:21 +0000 Subject: [PATCH] py, compiler: Allow lambda's to yield. --- py/compile.c | 15 ++++++++------- tests/bytecode/mp-tests/yield2.py | 3 +++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/py/compile.c b/py/compile.c index 661e587f2e..9f081ebbcf 100644 --- a/py/compile.c +++ b/py/compile.c @@ -2681,7 +2681,7 @@ void compile_argument(compiler_t *comp, mp_parse_node_struct_t *pns) { } void compile_yield_expr(compiler_t *comp, mp_parse_node_struct_t *pns) { - if (comp->scope_cur->kind != SCOPE_FUNCTION) { + if (comp->scope_cur->kind != SCOPE_FUNCTION && comp->scope_cur->kind != SCOPE_LAMBDA) { compile_syntax_error(comp, (mp_parse_node_t)pns, "'yield' outside function"); return; } @@ -2993,6 +2993,12 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { } compile_node(comp, pns->nodes[1]); // 1 is lambda body + + // if the lambda is a generator, then we return None, not the result of the expression of the lambda + if (scope->scope_flags & MP_SCOPE_FLAG_GENERATOR) { + EMIT(pop_top); + EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); + } EMIT(return_value); } else if (scope->kind == SCOPE_LIST_COMP || scope->kind == SCOPE_DICT_COMP || scope->kind == SCOPE_SET_COMP || scope->kind == SCOPE_GEN_EXPR) { // a bit of a hack at the moment @@ -3242,15 +3248,10 @@ void compile_scope_compute_things(compiler_t *comp, scope_t *scope) { #if MICROPY_EMIT_CPYTHON // these flags computed here are for CPython compatibility only - if (scope->kind == SCOPE_FUNCTION) { - scope->scope_flags |= MP_SCOPE_FLAG_NEWLOCALS; - } if (scope->kind == SCOPE_FUNCTION || scope->kind == SCOPE_LAMBDA || scope->kind == SCOPE_LIST_COMP || scope->kind == SCOPE_DICT_COMP || scope->kind == SCOPE_SET_COMP || scope->kind == SCOPE_GEN_EXPR) { assert(scope->parent != NULL); + scope->scope_flags |= MP_SCOPE_FLAG_NEWLOCALS; scope->scope_flags |= MP_SCOPE_FLAG_OPTIMISED; - - // TODO possibly other ways it can be nested - // Note that we don't actually use this information at the moment (for CPython compat only) if ((SCOPE_FUNCTION <= scope->parent->kind && scope->parent->kind <= SCOPE_SET_COMP) || (scope->parent->kind == SCOPE_CLASS && scope->parent->parent->kind == SCOPE_FUNCTION)) { scope->scope_flags |= MP_SCOPE_FLAG_NESTED; } diff --git a/tests/bytecode/mp-tests/yield2.py b/tests/bytecode/mp-tests/yield2.py index 140fe0795a..acc0ec8e99 100644 --- a/tests/bytecode/mp-tests/yield2.py +++ b/tests/bytecode/mp-tests/yield2.py @@ -2,3 +2,6 @@ def f(): yield from a yield from (a, b) yield from f(a) + +lambda:(yield) +lambda:(yield 1) + 2