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

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: 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 if (allow_harmony_scoping() && strict_mode() == STRICT) {
marja 2014/07/09 14:24:45 Ditto
176 return ParseVariableStatement(kSourceElement, ok);
177 }
178 // Fall through.
173 default: 179 default:
174 return ParseStatement(ok); 180 return ParseStatement(ok);
175 } 181 }
176 } 182 }
177 183
178 184
179 PreParser::SourceElements PreParser::ParseSourceElements(int end_token, 185 PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
180 bool* ok) { 186 bool* ok) {
181 // SourceElements :: 187 // SourceElements ::
182 // (Statement)* <end_token> 188 // (Statement)* <end_token>
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 // iterations or 'switch' statements (i.e., BreakableStatements), 236 // iterations or 'switch' statements (i.e., BreakableStatements),
231 // labels can be simply ignored in all other cases; except for 237 // labels can be simply ignored in all other cases; except for
232 // trivial labeled break statements 'label: break label' which is 238 // trivial labeled break statements 'label: break label' which is
233 // parsed into an empty statement. 239 // parsed into an empty statement.
234 240
235 // Keep the source position of the statement 241 // Keep the source position of the statement
236 switch (peek()) { 242 switch (peek()) {
237 case Token::LBRACE: 243 case Token::LBRACE:
238 return ParseBlock(ok); 244 return ParseBlock(ok);
239 245
240 case Token::CONST:
241 case Token::LET:
242 case Token::VAR:
243 return ParseVariableStatement(kStatement, ok);
244
245 case Token::SEMICOLON: 246 case Token::SEMICOLON:
246 Next(); 247 Next();
247 return Statement::Default(); 248 return Statement::Default();
248 249
249 case Token::IF: 250 case Token::IF:
250 return ParseIfStatement(ok); 251 return ParseIfStatement(ok);
251 252
252 case Token::DO: 253 case Token::DO:
253 return ParseDoWhileStatement(ok); 254 return ParseDoWhileStatement(ok);
254 255
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 *ok = false; 291 *ok = false;
291 return Statement::Default(); 292 return Statement::Default();
292 } else { 293 } else {
293 return statement; 294 return statement;
294 } 295 }
295 } 296 }
296 297
297 case Token::DEBUGGER: 298 case Token::DEBUGGER:
298 return ParseDebuggerStatement(ok); 299 return ParseDebuggerStatement(ok);
299 300
301 case Token::VAR:
302 case Token::CONST:
303 return ParseVariableStatement(kStatement, ok);
304
305 case Token::LET:
306 if (allow_harmony_scoping() && strict_mode() == STRICT) {
marja 2014/07/09 14:24:45 Ditto
307 return ParseVariableStatement(kStatement, ok);
308 }
309 // Fall through.
300 default: 310 default:
301 return ParseExpressionOrLabelledStatement(ok); 311 return ParseExpressionOrLabelledStatement(ok);
302 } 312 }
303 } 313 }
304 314
305 315
306 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 316 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
307 // FunctionDeclaration :: 317 // FunctionDeclaration ::
308 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 318 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
309 // GeneratorDeclaration :: 319 // GeneratorDeclaration ::
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 return Statement::Default(); 418 return Statement::Default();
409 } 419 }
410 require_initializer = true; 420 require_initializer = true;
411 } else { 421 } else {
412 Scanner::Location location = scanner()->peek_location(); 422 Scanner::Location location = scanner()->peek_location();
413 ReportMessageAt(location, "strict_const"); 423 ReportMessageAt(location, "strict_const");
414 *ok = false; 424 *ok = false;
415 return Statement::Default(); 425 return Statement::Default();
416 } 426 }
417 } 427 }
418 } else if (peek() == Token::LET) { 428 } 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); 429 Consume(Token::LET);
433 if (var_context != kSourceElement && 430 if (var_context != kSourceElement && var_context != kForStatement) {
434 var_context != kForStatement) {
435 ReportMessageAt(scanner()->peek_location(), "unprotected_let"); 431 ReportMessageAt(scanner()->peek_location(), "unprotected_let");
436 *ok = false; 432 *ok = false;
437 return Statement::Default(); 433 return Statement::Default();
438 } 434 }
439 } else { 435 } else {
440 *ok = false; 436 *ok = false;
441 return Statement::Default(); 437 return Statement::Default();
442 } 438 }
443 439
444 // The scope of a var/const declared variable anywhere inside a function 440 // 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 658
663 659
664 PreParser::Statement PreParser::ParseForStatement(bool* ok) { 660 PreParser::Statement PreParser::ParseForStatement(bool* ok) {
665 // ForStatement :: 661 // ForStatement ::
666 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 662 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
667 663
668 Expect(Token::FOR, CHECK_OK); 664 Expect(Token::FOR, CHECK_OK);
669 Expect(Token::LPAREN, CHECK_OK); 665 Expect(Token::LPAREN, CHECK_OK);
670 if (peek() != Token::SEMICOLON) { 666 if (peek() != Token::SEMICOLON) {
671 if (peek() == Token::VAR || peek() == Token::CONST || 667 if (peek() == Token::VAR || peek() == Token::CONST ||
672 peek() == Token::LET) { 668 (peek() == Token::LET && strict_mode() == STRICT)) {
673 bool is_let = peek() == Token::LET; 669 bool is_let = peek() == Token::LET;
674 int decl_count; 670 int decl_count;
675 VariableDeclarationProperties decl_props = kHasNoInitializers; 671 VariableDeclarationProperties decl_props = kHasNoInitializers;
676 ParseVariableDeclarations( 672 ParseVariableDeclarations(
677 kForStatement, &decl_props, &decl_count, CHECK_OK); 673 kForStatement, &decl_props, &decl_count, CHECK_OK);
678 bool has_initializers = decl_props == kHasInitializers; 674 bool has_initializers = decl_props == kHasInitializers;
679 bool accept_IN = decl_count == 1 && !(is_let && has_initializers); 675 bool accept_IN = decl_count == 1 && !(is_let && has_initializers);
680 bool accept_OF = !has_initializers; 676 bool accept_OF = !has_initializers;
681 if (accept_IN && CheckInOrOf(accept_OF)) { 677 if (accept_IN && CheckInOrOf(accept_OF)) {
682 ParseExpression(true, CHECK_OK); 678 ParseExpression(true, CHECK_OK);
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 923 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
928 ParseArguments(ok); 924 ParseArguments(ok);
929 925
930 return Expression::Default(); 926 return Expression::Default();
931 } 927 }
932 928
933 #undef CHECK_OK 929 #undef CHECK_OK
934 930
935 931
936 } } // v8::internal 932 } } // 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