void Parser::onFunction(Token &out, Token &ret, Token &ref, Token &name, Token ¶ms, Token &stmt) { FunctionStatementPtr func = peekFunc(); ASSERT(func); popFunc(); func->setLoc(popFuncLocation().get()); bool hasCallToGetArgs = m_hasCallToGetArgs.back(); m_hasCallToGetArgs.pop_back(); if (func->hasYield()) { string closureName = getClosureName(); func->setName(closureName); Token new_params; prepare_generator(this, stmt, new_params, func->getYieldCount()); StatementListStatementPtr body = stmt->getStmtList(); func->init(this, ref.num(), new_params->params(), body, hasCallToGetArgs); out.reset(); out->stmt() = func; create_generator(this, out, params, name, closureName, NULL, NULL); } else { StatementListStatementPtr body = stmt->getStmtList(); func->init(this, ref.num(), params->params(), body, hasCallToGetArgs); out.reset(); out->stmt() = func; } }
void Parser::onReturn(Token &out, Token *expr, bool checkYield /* = true */) { out.reset(); out->stmt() = NEW_STMT(Return, expr ? (*expr)->exp() : ExpressionPtr()); if (checkYield && haveFunc()) { FunctionStatementPtr func = peekFunc(); if (func->hasYield()) { raise_error("Cannot mix 'return' and 'yield' in the same function: %s", getMessage().c_str()); } func->setHasReturn(); } }