Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(644)

Unified Diff: src/parser.cc

Issue 13179002: Add parser support for generators. (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: added additional syntax tests Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index cdc0adb561831ee012fdd3434d9c210828a67cca..3b4ee7e86516e47e0504ccc3b730db35f4258d97 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -680,7 +680,8 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::ANONYMOUS_EXPRESSION,
FunctionLiteral::kGlobalOrEval,
- FunctionLiteral::kNotParenthesized);
+ FunctionLiteral::kNotParenthesized,
+ FunctionLiteral::kNotGenerator);
result->set_ast_properties(factory()->visitor()->ast_properties());
} else if (stack_overflow_) {
isolate()->StackOverflow();
@@ -768,6 +769,7 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source,
bool ok = true;
result = ParseFunctionLiteral(name,
false, // Strict mode name already checked.
+ shared_info->is_generator(),
RelocInfo::kNoPosition,
type,
&ok);
@@ -1132,6 +1134,7 @@ Statement* Parser::ParseModuleElement(ZoneStringList* labels,
// ModuleDeclaration
// ImportDeclaration
// ExportDeclaration
+ // GeneratorDeclaration
switch (peek()) {
case Token::FUNCTION:
@@ -1430,6 +1433,7 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
// 'export' Identifier (',' Identifier)* ';'
// 'export' VariableDeclaration
// 'export' FunctionDeclaration
+ // 'export' GeneratorDeclaration
// 'export' ModuleDeclaration
//
// TODO(ES6): implement structuring ExportSpecifiers
@@ -1509,6 +1513,7 @@ Statement* Parser::ParseBlockElement(ZoneStringList* labels,
// BlockElement (aka SourceElement):
// LetDeclaration
// ConstDeclaration
+ // GeneratorDeclaration
switch (peek()) {
case Token::FUNCTION:
@@ -1628,6 +1633,10 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
// FunctionDeclaration
// Common language extension is to allow function declaration in place
// of any statement. This language extension is disabled in strict mode.
+ //
+ // In Harmony mode, this case also handles the extension:
+ // Statement:
+ // GeneratorDeclaration
if (!top_scope_->is_classic_mode()) {
ReportMessageAt(scanner().peek_location(), "strict_function",
Vector<const char*>::empty());
@@ -1892,11 +1901,13 @@ Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) {
// 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
Expect(Token::FUNCTION, CHECK_OK);
int function_token_position = scanner().location().beg_pos;
+ bool is_generator = FLAG_harmony_generators && Check(Token::MUL);
bool is_strict_reserved = false;
Handle<String> name = ParseIdentifierOrStrictReservedWord(
&is_strict_reserved, CHECK_OK);
FunctionLiteral* fun = ParseFunctionLiteral(name,
is_strict_reserved,
+ is_generator,
function_token_position,
FunctionLiteral::DECLARATION,
CHECK_OK);
@@ -3004,8 +3015,13 @@ Expression* Parser::ParseExpression(bool accept_IN, bool* ok) {
Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
// AssignmentExpression ::
// ConditionalExpression
+ // YieldExpression
// LeftHandSideExpression AssignmentOperator AssignmentExpression
+ if (peek() == Token::YIELD && inside_generator()) {
+ return ParseYieldExpression(ok);
+ }
+
if (fni_ != NULL) fni_->Enter();
Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK);
@@ -3074,6 +3090,17 @@ Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
}
+Expression* Parser::ParseYieldExpression(bool* ok) {
+ // YieldExpression ::
+ // 'yield' '*'? AssignmentExpression
+ int position = scanner().peek_location().beg_pos;
+ Expect(Token::YIELD, CHECK_OK);
+ bool is_yield_star = Check(Token::MUL);
+ Expression* expression = ParseAssignmentExpression(false, CHECK_OK);
+ return factory()->NewYield(expression, is_yield_star, position);
+}
+
+
// Precedence = 3
Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
// ConditionalExpression ::
@@ -3450,6 +3477,7 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
if (peek() == Token::FUNCTION) {
Expect(Token::FUNCTION, CHECK_OK);
int function_token_position = scanner().location().beg_pos;
+ bool is_generator = FLAG_harmony_generators && Check(Token::MUL);
Handle<String> name;
bool is_strict_reserved_name = false;
if (peek_any_identifier()) {
@@ -3461,6 +3489,7 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
: FunctionLiteral::NAMED_EXPRESSION;
result = ParseFunctionLiteral(name,
is_strict_reserved_name,
+ is_generator,
function_token_position,
type,
CHECK_OK);
@@ -3604,6 +3633,7 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) {
break;
case Token::IDENTIFIER:
+ case Token::YIELD:
case Token::FUTURE_STRICT_RESERVED_WORD: {
Handle<String> name = ParseIdentifier(CHECK_OK);
if (fni_ != NULL) fni_->PushVariableName(name);
@@ -4009,6 +4039,7 @@ ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
FunctionLiteral* value =
ParseFunctionLiteral(name,
false, // reserved words are allowed here
+ false, // not a generator
RelocInfo::kNoPosition,
FunctionLiteral::ANONYMOUS_EXPRESSION,
CHECK_OK);
@@ -4310,6 +4341,7 @@ class SingletonLogger : public ParserRecorder {
FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
bool name_is_strict_reserved,
+ bool is_generator,
int function_token_position,
FunctionLiteral::Type type,
bool* ok) {
@@ -4333,6 +4365,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
Scope* scope = (type == FunctionLiteral::DECLARATION && !is_extended_mode())
? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE)
: NewScope(top_scope_, FUNCTION_SCOPE);
+ scope->set_inside_generator(is_generator);
ZoneList<Statement*>* body = NULL;
int materialized_literal_count = -1;
int expected_property_count = -1;
@@ -4344,6 +4377,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
? FunctionLiteral::kIsParenthesized
: FunctionLiteral::kNotParenthesized;
+ FunctionLiteral::IsGeneratorFlag generator = is_generator
+ ? FunctionLiteral::kIsGenerator
+ : FunctionLiteral::kNotGenerator;
AstProperties ast_properties;
// Parse function body.
{ FunctionState function_state(this, scope, isolate());
@@ -4584,7 +4620,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
duplicate_parameters,
type,
FunctionLiteral::kIsFunction,
- parenthesized);
+ parenthesized,
+ generator);
function_literal->set_function_token_position(function_token_position);
function_literal->set_ast_properties(&ast_properties);
@@ -4610,6 +4647,7 @@ preparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral(
}
preparser::PreParser::PreParseResult result =
reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(),
+ top_scope_->inside_generator(),
logger);
return result;
}
@@ -4672,7 +4710,8 @@ bool Parser::peek_any_identifier() {
Token::Value next = peek();
return next == Token::IDENTIFIER ||
next == Token::FUTURE_RESERVED_WORD ||
- next == Token::FUTURE_STRICT_RESERVED_WORD;
+ next == Token::FUTURE_STRICT_RESERVED_WORD ||
+ next == Token::YIELD;
}
@@ -4744,13 +4783,17 @@ Literal* Parser::GetLiteralTheHole() {
// Parses an identifier that is valid for the current scope, in particular it
// fails on strict mode future reserved keywords in a strict scope.
Handle<String> Parser::ParseIdentifier(bool* ok) {
- if (!top_scope_->is_classic_mode()) {
- Expect(Token::IDENTIFIER, ok);
- } else if (!Check(Token::IDENTIFIER)) {
- Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
+ Token::Value next = Next();
+ if (next == Token::IDENTIFIER ||
+ (top_scope_->is_classic_mode() &&
+ (next == Token::FUTURE_STRICT_RESERVED_WORD ||
+ (next == Token::YIELD && !inside_generator())))) {
+ return GetSymbol(ok);
+ } else {
+ ReportUnexpectedToken(next);
+ *ok = false;
+ return Handle<String>();
}
- if (!*ok) return Handle<String>();
- return GetSymbol(ok);
}
@@ -4758,12 +4801,17 @@ Handle<String> Parser::ParseIdentifier(bool* ok) {
// whether it is strict mode future reserved.
Handle<String> Parser::ParseIdentifierOrStrictReservedWord(
bool* is_strict_reserved, bool* ok) {
- *is_strict_reserved = false;
- if (!Check(Token::IDENTIFIER)) {
- Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
+ Token::Value next = Next();
+ if (next == Token::IDENTIFIER) {
+ *is_strict_reserved = false;
+ } else if (next == Token::FUTURE_STRICT_RESERVED_WORD ||
+ (next == Token::YIELD && !inside_generator())) {
*is_strict_reserved = true;
+ } else {
+ ReportUnexpectedToken(next);
+ *ok = false;
+ return Handle<String>();
}
- if (!*ok) return Handle<String>();
return GetSymbol(ok);
}
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698