OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |