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

Side by Side Diff: src/preparser.cc

Issue 378303003: Make `let` usable as an identifier in ES6 sloppy mode. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comments Created 6 years, 5 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <cmath> 5 #include <cmath>
6 6
7 #include "include/v8stdint.h" 7 #include "include/v8stdint.h"
8 8
9 #include "src/allocation.h" 9 #include "src/allocation.h"
10 #include "src/base/logging.h" 10 #include "src/base/logging.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 is_reference_error); 54 is_reference_error);
55 } 55 }
56 56
57 57
58 PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) { 58 PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
59 if (scanner->current_token() == Token::FUTURE_RESERVED_WORD) { 59 if (scanner->current_token() == Token::FUTURE_RESERVED_WORD) {
60 return PreParserIdentifier::FutureReserved(); 60 return PreParserIdentifier::FutureReserved();
61 } else if (scanner->current_token() == 61 } else if (scanner->current_token() ==
62 Token::FUTURE_STRICT_RESERVED_WORD) { 62 Token::FUTURE_STRICT_RESERVED_WORD) {
63 return PreParserIdentifier::FutureStrictReserved(); 63 return PreParserIdentifier::FutureStrictReserved();
64 } else if (scanner->current_token() == Token::LET) {
65 return PreParserIdentifier::Let();
64 } else if (scanner->current_token() == Token::YIELD) { 66 } else if (scanner->current_token() == Token::YIELD) {
65 return PreParserIdentifier::Yield(); 67 return PreParserIdentifier::Yield();
66 } 68 }
67 if (scanner->UnescapedLiteralMatches("eval", 4)) { 69 if (scanner->UnescapedLiteralMatches("eval", 4)) {
68 return PreParserIdentifier::Eval(); 70 return PreParserIdentifier::Eval();
69 } 71 }
70 if (scanner->UnescapedLiteralMatches("arguments", 9)) { 72 if (scanner->UnescapedLiteralMatches("arguments", 9)) {
71 return PreParserIdentifier::Arguments(); 73 return PreParserIdentifier::Arguments();
72 } 74 }
73 return PreParserIdentifier::Default(); 75 return PreParserIdentifier::Default();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 // 162 //
161 // In harmony mode we allow additionally the following productions 163 // In harmony mode we allow additionally the following productions
162 // SourceElement: 164 // SourceElement:
163 // LetDeclaration 165 // LetDeclaration
164 // ConstDeclaration 166 // ConstDeclaration
165 // GeneratorDeclaration 167 // GeneratorDeclaration
166 168
167 switch (peek()) { 169 switch (peek()) {
168 case Token::FUNCTION: 170 case Token::FUNCTION:
169 return ParseFunctionDeclaration(ok); 171 return ParseFunctionDeclaration(ok);
170 case Token::LET:
171 case Token::CONST: 172 case Token::CONST:
172 return ParseVariableStatement(kSourceElement, ok); 173 return ParseVariableStatement(kSourceElement, ok);
174 case Token::LET:
175 ASSERT(allow_harmony_scoping());
176 if (strict_mode() == STRICT) {
177 return ParseVariableStatement(kSourceElement, ok);
178 }
179 // Fall through.
173 default: 180 default:
174 return ParseStatement(ok); 181 return ParseStatement(ok);
175 } 182 }
176 } 183 }
177 184
178 185
179 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, 186 PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
180 bool* ok) { 187 bool* ok) {
181 // SourceElements :: 188 // SourceElements ::
182 // (Statement)* <end_token> 189 // (Statement)* <end_token>
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 // iterations or 'switch' statements (i.e., BreakableStatements), 237 // iterations or 'switch' statements (i.e., BreakableStatements),
231 // labels can be simply ignored in all other cases; except for 238 // labels can be simply ignored in all other cases; except for
232 // trivial labeled break statements 'label: break label' which is 239 // trivial labeled break statements 'label: break label' which is
233 // parsed into an empty statement. 240 // parsed into an empty statement.
234 241
235 // Keep the source position of the statement 242 // Keep the source position of the statement
236 switch (peek()) { 243 switch (peek()) {
237 case Token::LBRACE: 244 case Token::LBRACE:
238 return ParseBlock(ok); 245 return ParseBlock(ok);
239 246
240 case Token::CONST:
241 case Token::LET:
242 case Token::VAR:
243 return ParseVariableStatement(kStatement, ok);
244
245 case Token::SEMICOLON: 247 case Token::SEMICOLON:
246 Next(); 248 Next();
247 return Statement::Default(); 249 return Statement::Default();
248 250
249 case Token::IF: 251 case Token::IF:
250 return ParseIfStatement(ok); 252 return ParseIfStatement(ok);
251 253
252 case Token::DO: 254 case Token::DO:
253 return ParseDoWhileStatement(ok); 255 return ParseDoWhileStatement(ok);
254 256
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 *ok = false; 292 *ok = false;
291 return Statement::Default(); 293 return Statement::Default();
292 } else { 294 } else {
293 return statement; 295 return statement;
294 } 296 }
295 } 297 }
296 298
297 case Token::DEBUGGER: 299 case Token::DEBUGGER:
298 return ParseDebuggerStatement(ok); 300 return ParseDebuggerStatement(ok);
299 301
302 case Token::VAR:
303 case Token::CONST:
304 return ParseVariableStatement(kStatement, ok);
305
306 case Token::LET:
307 ASSERT(allow_harmony_scoping());
308 if (strict_mode() == STRICT) {
309 return ParseVariableStatement(kStatement, ok);
310 }
311 // Fall through.
300 default: 312 default:
301 return ParseExpressionOrLabelledStatement(ok); 313 return ParseExpressionOrLabelledStatement(ok);
302 } 314 }
303 } 315 }
304 316
305 317
306 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 318 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
307 // FunctionDeclaration :: 319 // FunctionDeclaration ::
308 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 320 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
309 // GeneratorDeclaration :: 321 // GeneratorDeclaration ::
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 return Statement::Default(); 420 return Statement::Default();
409 } 421 }
410 require_initializer = true; 422 require_initializer = true;
411 } else { 423 } else {
412 Scanner::Location location = scanner()->peek_location(); 424 Scanner::Location location = scanner()->peek_location();
413 ReportMessageAt(location, "strict_const"); 425 ReportMessageAt(location, "strict_const");
414 *ok = false; 426 *ok = false;
415 return Statement::Default(); 427 return Statement::Default();
416 } 428 }
417 } 429 }
418 } else if (peek() == Token::LET) { 430 } else if (peek() == Token::LET && strict_mode() == STRICT) {
419 // ES6 Draft Rev4 section 12.2.1:
420 //
421 // LetDeclaration : let LetBindingList ;
422 //
423 // * It is a Syntax Error if the code that matches this production is not
424 // contained in extended code.
425 //
426 // TODO(rossberg): make 'let' a legal identifier in sloppy mode.
427 if (!allow_harmony_scoping() || strict_mode() == SLOPPY) {
428 ReportMessageAt(scanner()->peek_location(), "illegal_let");
429 *ok = false;
430 return Statement::Default();
431 }
432 Consume(Token::LET); 431 Consume(Token::LET);
433 if (var_context != kSourceElement && 432 if (var_context != kSourceElement && var_context != kForStatement) {
434 var_context != kForStatement) {
435 ReportMessageAt(scanner()->peek_location(), "unprotected_let"); 433 ReportMessageAt(scanner()->peek_location(), "unprotected_let");
436 *ok = false; 434 *ok = false;
437 return Statement::Default(); 435 return Statement::Default();
438 } 436 }
439 } else { 437 } else {
440 *ok = false; 438 *ok = false;
441 return Statement::Default(); 439 return Statement::Default();
442 } 440 }
443 441
444 // The scope of a var/const declared variable anywhere inside a function 442 // The scope of a var/const declared variable anywhere inside a function
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 660
663 661
664 PreParser::Statement PreParser::ParseForStatement(bool* ok) { 662 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
665 // ForStatement :: 663 // ForStatement ::
666 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 664 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
667 665
668 Expect(Token::FOR, CHECK_OK); 666 Expect(Token::FOR, CHECK_OK);
669 Expect(Token::LPAREN, CHECK_OK); 667 Expect(Token::LPAREN, CHECK_OK);
670 if (peek() != Token::SEMICOLON) { 668 if (peek() != Token::SEMICOLON) {
671 if (peek() == Token::VAR || peek() == Token::CONST || 669 if (peek() == Token::VAR || peek() == Token::CONST ||
672 peek() == Token::LET) { 670 (peek() == Token::LET && strict_mode() == STRICT)) {
673 bool is_let = peek() == Token::LET; 671 bool is_let = peek() == Token::LET;
674 int decl_count; 672 int decl_count;
675 VariableDeclarationProperties decl_props = kHasNoInitializers; 673 VariableDeclarationProperties decl_props = kHasNoInitializers;
676 ParseVariableDeclarations( 674 ParseVariableDeclarations(
677 kForStatement, &decl_props, &decl_count, CHECK_OK); 675 kForStatement, &decl_props, &decl_count, CHECK_OK);
678 bool has_initializers = decl_props == kHasInitializers; 676 bool has_initializers = decl_props == kHasInitializers;
679 bool accept_IN = decl_count == 1 && !(is_let && has_initializers); 677 bool accept_IN = decl_count == 1 && !(is_let && has_initializers);
680 bool accept_OF = !has_initializers; 678 bool accept_OF = !has_initializers;
681 if (accept_IN && CheckInOrOf(accept_OF)) { 679 if (accept_IN && CheckInOrOf(accept_OF)) {
682 ParseExpression(true, CHECK_OK); 680 ParseExpression(true, CHECK_OK);
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 925 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
928 ParseArguments(ok); 926 ParseArguments(ok);
929 927
930 return Expression::Default(); 928 return Expression::Default();
931 } 929 }
932 930
933 #undef CHECK_OK 931 #undef CHECK_OK
934 932
935 933
936 } } // v8::internal 934 } } // v8::internal
OLDNEW
« src/parser.cc ('K') | « src/preparser.h ('k') | test/mjsunit/harmony/block-early-errors.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698