Chromium Code Reviews| Index: src/preparser.cc |
| diff --git a/src/preparser.cc b/src/preparser.cc |
| index c741b4655a0556d4450c94608a69ad6316d4e9fa..d285de960c5e13905e5080d7bb2d5dce5a6bb36e 100644 |
| --- a/src/preparser.cc |
| +++ b/src/preparser.cc |
| @@ -30,6 +30,7 @@ |
| #include "globals.h" |
| #include "checks.h" |
| #include "allocation.h" |
| +#include "flags.h" |
| #include "utils.h" |
| #include "list.h" |
| @@ -84,6 +85,8 @@ void PreParser::ReportUnexpectedToken(i::Token::Value token) { |
| case i::Token::FUTURE_RESERVED_WORD: |
| return ReportMessageAt(source_location.beg_pos, source_location.end_pos, |
| "unexpected_reserved", NULL); |
| + case i::Token::LET: |
| + // fallthrough |
|
Lasse Reichstein
2011/08/12 08:08:33
No need to write "fallthrough" if the two case lab
Steven
2011/08/16 09:05:32
The scanner is now producing the correct token bas
|
| case i::Token::FUTURE_STRICT_RESERVED_WORD: |
| return ReportMessageAt(source_location.beg_pos, source_location.end_pos, |
| "unexpected_strict_reserved", NULL); |
| @@ -114,6 +117,18 @@ void PreParser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| #undef DUMMY |
| +PreParser::Statement PreParser::ParseSourceElement(bool* ok) { |
| + switch (peek()) { |
| + case i::Token::LET: |
| + if (i::FLAG_harmony_block_scoping) { |
| + return ParseVariableStatement(true, ok); |
| + } |
|
Lasse Reichstein
2011/08/12 08:08:33
Need fallthrough here. Or drop the switch and just
Steven
2011/08/16 09:05:32
Done.
|
| + default: |
| + return ParseStatement(ok); |
| + } |
| +} |
| + |
| + |
| PreParser::SourceElements PreParser::ParseSourceElements(int end_token, |
| bool* ok) { |
| // SourceElements :: |
| @@ -121,7 +136,7 @@ PreParser::SourceElements PreParser::ParseSourceElements(int end_token, |
| bool allow_directive_prologue = true; |
| while (peek() != end_token) { |
| - Statement statement = ParseStatement(CHECK_OK); |
| + Statement statement = ParseSourceElement(CHECK_OK); |
| if (allow_directive_prologue) { |
| if (statement.IsUseStrictLiteral()) { |
| set_strict_mode(); |
| @@ -174,7 +189,7 @@ PreParser::Statement PreParser::ParseStatement(bool* ok) { |
| case i::Token::CONST: |
| case i::Token::VAR: |
| - return ParseVariableStatement(ok); |
| + return ParseVariableStatement(false, ok); |
| case i::Token::SEMICOLON: |
| Next(); |
| @@ -260,7 +275,7 @@ PreParser::Statement PreParser::ParseBlock(bool* ok) { |
| Expect(i::Token::LBRACE, CHECK_OK); |
| while (peek() != i::Token::RBRACE) { |
| i::Scanner::Location start_location = scanner_->peek_location(); |
| - Statement statement = ParseStatement(CHECK_OK); |
| + Statement statement = ParseSourceElement(CHECK_OK); |
| i::Scanner::Location end_location = scanner_->location(); |
| if (strict_mode() && statement.IsFunctionDeclaration()) { |
| ReportMessageAt(start_location.beg_pos, end_location.end_pos, |
| @@ -274,11 +289,15 @@ PreParser::Statement PreParser::ParseBlock(bool* ok) { |
| } |
| -PreParser::Statement PreParser::ParseVariableStatement(bool* ok) { |
| +PreParser::Statement PreParser::ParseVariableStatement(bool accept_LET, |
| + bool* ok) { |
| // VariableStatement :: |
| // VariableDeclarations ';' |
| - Statement result = ParseVariableDeclarations(true, NULL, CHECK_OK); |
| + Statement result = ParseVariableDeclarations(accept_LET, |
| + true, |
| + NULL, |
| + CHECK_OK); |
| ExpectSemicolon(CHECK_OK); |
| return result; |
| } |
| @@ -289,7 +308,8 @@ PreParser::Statement PreParser::ParseVariableStatement(bool* ok) { |
| // *var is untouched; in particular, it is the caller's responsibility |
| // to initialize it properly. This mechanism is also used for the parsing |
| // of 'for-in' loops. |
| -PreParser::Statement PreParser::ParseVariableDeclarations(bool accept_IN, |
| +PreParser::Statement PreParser::ParseVariableDeclarations(bool accept_LET, |
| + bool accept_IN, |
| int* num_decl, |
| bool* ok) { |
| // VariableDeclarations :: |
| @@ -306,6 +326,15 @@ PreParser::Statement PreParser::ParseVariableDeclarations(bool accept_IN, |
| return Statement::Default(); |
| } |
| Consume(i::Token::CONST); |
| + } else if (peek() == i::Token::LET) { |
| + if (!accept_LET) { |
| + i::Scanner::Location location = scanner_->peek_location(); |
| + ReportMessageAt(location.beg_pos, location.end_pos, |
| + "unprotected_let", NULL); |
| + *ok = false; |
| + return Statement::Default(); |
| + } |
| + Consume(i::Token::LET); |
| } else { |
| *ok = false; |
| return Statement::Default(); |
| @@ -537,9 +566,10 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) { |
| Expect(i::Token::FOR, CHECK_OK); |
| Expect(i::Token::LPAREN, CHECK_OK); |
| if (peek() != i::Token::SEMICOLON) { |
| - if (peek() == i::Token::VAR || peek() == i::Token::CONST) { |
| + if (peek() == i::Token::VAR || peek() == i::Token::CONST || |
| + peek() == i::Token::LET) { |
| int decl_count; |
| - ParseVariableDeclarations(false, &decl_count, CHECK_OK); |
| + ParseVariableDeclarations(true, false, &decl_count, CHECK_OK); |
| if (peek() == i::Token::IN && decl_count == 1) { |
| Expect(i::Token::IN, CHECK_OK); |
| ParseExpression(true, CHECK_OK); |
| @@ -995,6 +1025,16 @@ PreParser::Expression PreParser::ParsePrimaryExpression(bool* ok) { |
| return Expression::Default(); |
| } |
| + case i::Token::LET: |
| + if (i::FLAG_harmony_block_scoping) { |
| + Next(); |
| + i::Scanner::Location location = scanner_->location(); |
| + ReportMessageAt(location.beg_pos, location.end_pos, |
| + "unexpected_token", NULL); |
| + *ok = false; |
| + return Expression::Default(); |
| + } |
| + // FALLTHROUGH |
| case i::Token::FUTURE_STRICT_RESERVED_WORD: |
| if (strict_mode()) { |
| Next(); |
| @@ -1333,6 +1373,8 @@ PreParser::Identifier PreParser::GetIdentifierSymbol() { |
| } else if (scanner_->current_token() == |
| i::Token::FUTURE_STRICT_RESERVED_WORD) { |
| return Identifier::FutureStrictReserved(); |
| + } else if (scanner_->current_token() == i::Token::LET) { |
| + return Identifier::FutureStrictReserved(); |
| } |
| if (scanner_->is_literal_ascii()) { |
| // Detect strict-mode poison words. |
| @@ -1357,7 +1399,13 @@ PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { |
| ReportMessageAt(location.beg_pos, location.end_pos, |
| "reserved_word", NULL); |
| *ok = false; |
| + return GetIdentifierSymbol(); |
| } |
| + case i::Token::LET: |
| + if (i::FLAG_harmony_block_scoping) { |
| + *ok = false; |
| + return Identifier::Default(); |
| + } |
| // FALLTHROUGH |
| case i::Token::FUTURE_STRICT_RESERVED_WORD: |
| case i::Token::IDENTIFIER: |
| @@ -1430,7 +1478,8 @@ PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { |
| } |
| if (next == i::Token::IDENTIFIER || |
| next == i::Token::FUTURE_RESERVED_WORD || |
| - next == i::Token::FUTURE_STRICT_RESERVED_WORD) { |
| + next == i::Token::FUTURE_STRICT_RESERVED_WORD || |
| + next == i::Token::LET) { |
| return GetIdentifierSymbol(); |
| } |
| *ok = false; |
| @@ -1460,6 +1509,7 @@ bool PreParser::peek_any_identifier() { |
| i::Token::Value next = peek(); |
| return next == i::Token::IDENTIFIER || |
| next == i::Token::FUTURE_RESERVED_WORD || |
| - next == i::Token::FUTURE_STRICT_RESERVED_WORD; |
| + next == i::Token::FUTURE_STRICT_RESERVED_WORD || |
| + next == i::Token::LET; |
| } |
| } } // v8::preparser |