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 |