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

Side by Side Diff: src/parser.cc

Issue 9401008: Parsing of basic module declarations (no imports/exports yet). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed Lasse's comments. Created 8 years, 10 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
« no previous file with comments | « src/parser.h ('k') | src/prettyprinter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 647
648 // Make sure the target stack is empty. 648 // Make sure the target stack is empty.
649 ASSERT(target_stack_ == NULL); 649 ASSERT(target_stack_ == NULL);
650 650
651 // If there was a syntax error we have to get rid of the AST 651 // If there was a syntax error we have to get rid of the AST
652 // and it is not safe to do so before the scope has been deleted. 652 // and it is not safe to do so before the scope has been deleted.
653 if (result == NULL) zone_scope->DeleteOnExit(); 653 if (result == NULL) zone_scope->DeleteOnExit();
654 return result; 654 return result;
655 } 655 }
656 656
657
657 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) { 658 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
658 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT); 659 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
659 HistogramTimerScope timer(isolate()->counters()->parse_lazy()); 660 HistogramTimerScope timer(isolate()->counters()->parse_lazy());
660 Handle<String> source(String::cast(script_->source())); 661 Handle<String> source(String::cast(script_->source()));
661 isolate()->counters()->total_parse_size()->Increment(source->length()); 662 isolate()->counters()->total_parse_size()->Increment(source->length());
662 663
663 Handle<SharedFunctionInfo> shared_info = info->shared_info(); 664 Handle<SharedFunctionInfo> shared_info = info->shared_info();
664 // Initialize parser state. 665 // Initialize parser state.
665 source->TryFlatten(); 666 source->TryFlatten();
666 if (source->IsExternalTwoByteString()) { 667 if (source->IsExternalTwoByteString()) {
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 } 1081 }
1081 1082
1082 Isolate* isolate_; 1083 Isolate* isolate_;
1083 bool only_simple_this_property_assignments_; 1084 bool only_simple_this_property_assignments_;
1084 ZoneStringList names_; 1085 ZoneStringList names_;
1085 ZoneList<int> assigned_arguments_; 1086 ZoneList<int> assigned_arguments_;
1086 ZoneObjectList assigned_constants_; 1087 ZoneObjectList assigned_constants_;
1087 }; 1088 };
1088 1089
1089 1090
1090 Statement* Parser::ParseSourceElement(ZoneStringList* labels,
1091 bool* ok) {
1092 // (Ecma 262 5th Edition, clause 14):
1093 // SourceElement:
1094 // Statement
1095 // FunctionDeclaration
1096 //
1097 // In harmony mode we allow additionally the following productions
1098 // SourceElement:
1099 // LetDeclaration
1100 // ConstDeclaration
1101
1102 if (peek() == Token::FUNCTION) {
1103 return ParseFunctionDeclaration(ok);
1104 } else if (peek() == Token::LET || peek() == Token::CONST) {
1105 return ParseVariableStatement(kSourceElement, ok);
1106 }
1107 return ParseStatement(labels, ok);
1108 }
1109
1110
1111 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, 1091 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
1112 int end_token, 1092 int end_token,
1113 bool* ok) { 1093 bool* ok) {
1114 // SourceElements :: 1094 // SourceElements ::
1115 // (SourceElement)* <end_token> 1095 // (ModuleElement)* <end_token>
1116 1096
1117 // Allocate a target stack to use for this set of source 1097 // Allocate a target stack to use for this set of source
1118 // elements. This way, all scripts and functions get their own 1098 // elements. This way, all scripts and functions get their own
1119 // target stack thus avoiding illegal breaks and continues across 1099 // target stack thus avoiding illegal breaks and continues across
1120 // functions. 1100 // functions.
1121 TargetScope scope(&this->target_stack_); 1101 TargetScope scope(&this->target_stack_);
1122 1102
1123 ASSERT(processor != NULL); 1103 ASSERT(processor != NULL);
1124 InitializationBlockFinder block_finder(top_scope_, target_stack_); 1104 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1125 ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate()); 1105 ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate());
1126 bool directive_prologue = true; // Parsing directive prologue. 1106 bool directive_prologue = true; // Parsing directive prologue.
1127 1107
1128 while (peek() != end_token) { 1108 while (peek() != end_token) {
1129 if (directive_prologue && peek() != Token::STRING) { 1109 if (directive_prologue && peek() != Token::STRING) {
1130 directive_prologue = false; 1110 directive_prologue = false;
1131 } 1111 }
1132 1112
1133 Scanner::Location token_loc = scanner().peek_location(); 1113 Scanner::Location token_loc = scanner().peek_location();
1134 Statement* stat = ParseSourceElement(NULL, CHECK_OK); 1114 Statement* stat = ParseModuleElement(NULL, CHECK_OK);
1135 if (stat == NULL || stat->IsEmpty()) { 1115 if (stat == NULL || stat->IsEmpty()) {
1136 directive_prologue = false; // End of directive prologue. 1116 directive_prologue = false; // End of directive prologue.
1137 continue; 1117 continue;
1138 } 1118 }
1139 1119
1140 if (directive_prologue) { 1120 if (directive_prologue) {
1141 // A shot at a directive. 1121 // A shot at a directive.
1142 ExpressionStatement* e_stat; 1122 ExpressionStatement* e_stat;
1143 Literal* literal; 1123 Literal* literal;
1144 // Still processing directive prologue? 1124 // Still processing directive prologue?
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1180 if (only_simple_this_property_assignments) { 1160 if (only_simple_this_property_assignments) {
1181 current_function_state_->SetThisPropertyAssignmentInfo( 1161 current_function_state_->SetThisPropertyAssignmentInfo(
1182 only_simple_this_property_assignments, 1162 only_simple_this_property_assignments,
1183 this_property_assignment_finder.GetThisPropertyAssignments()); 1163 this_property_assignment_finder.GetThisPropertyAssignments());
1184 } 1164 }
1185 } 1165 }
1186 return 0; 1166 return 0;
1187 } 1167 }
1188 1168
1189 1169
1170 Statement* Parser::ParseModuleElement(ZoneStringList* labels,
1171 bool* ok) {
1172 // (Ecma 262 5th Edition, clause 14):
1173 // SourceElement:
1174 // Statement
1175 // FunctionDeclaration
1176 //
1177 // In harmony mode we allow additionally the following productions
1178 // ModuleElement:
1179 // LetDeclaration
1180 // ConstDeclaration
1181 // ModuleDeclaration
1182 // ImportDeclaration
1183 // ExportDeclaration
1184
1185 switch (peek()) {
1186 case Token::FUNCTION:
1187 return ParseFunctionDeclaration(ok);
1188 case Token::LET:
1189 case Token::CONST:
1190 return ParseVariableStatement(kModuleElement, ok);
1191 case Token::MODULE:
1192 return ParseModuleDeclaration(ok);
1193 case Token::IMPORT:
1194 return ParseImportDeclaration(ok);
1195 case Token::EXPORT:
1196 return ParseExportDeclaration(ok);
1197 default:
1198 return ParseStatement(labels, ok);
1199 }
1200 }
1201
1202
1203 Block* Parser::ParseModuleDeclaration(bool* ok) {
1204 // ModuleDeclaration:
1205 // 'module' Identifier Module
1206
1207 // Create new block with one expected declaration.
1208 Block* block = factory()->NewBlock(NULL, 1, true);
1209 Expect(Token::MODULE, CHECK_OK);
1210 Handle<String> name = ParseIdentifier(CHECK_OK);
1211 // top_scope_->AddDeclaration(
1212 // factory()->NewModuleDeclaration(proxy, module, top_scope_));
1213 VariableProxy* proxy = Declare(name, LET, NULL, true, CHECK_OK);
1214 Module* module = ParseModule(ok);
1215 // TODO(rossberg): Add initialization statement to block.
1216 USE(proxy);
1217 USE(module);
1218 return block;
1219 }
1220
1221
1222 Module* Parser::ParseModule(bool* ok) {
1223 // Module:
1224 // '{' ModuleElement '}'
1225 // '=' ModulePath
1226 // 'at' String
1227
1228 switch (peek()) {
1229 case Token::LBRACE:
1230 return ParseModuleLiteral(ok);
1231
1232 case Token::ASSIGN:
1233 Expect(Token::ASSIGN, CHECK_OK);
1234 return ParseModulePath(ok);
1235
1236 default:
1237 return ParseModuleUrl(ok);
1238 }
1239 }
1240
1241
1242 Module* Parser::ParseModuleLiteral(bool* ok) {
1243 // Module:
1244 // '{' ModuleElement '}'
1245
1246 // Construct block expecting 16 statements.
1247 Block* body = factory()->NewBlock(NULL, 16, false);
1248 Scope* scope = NewScope(top_scope_, MODULE_SCOPE);
1249
1250 Expect(Token::LBRACE, CHECK_OK);
1251 scope->set_start_position(scanner().location().beg_pos);
1252 scope->SetLanguageMode(EXTENDED_MODE);
1253
1254 {
1255 BlockState block_state(this, scope);
1256 TargetCollector collector;
1257 Target target(&this->target_stack_, &collector);
1258 Target target_body(&this->target_stack_, body);
1259 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1260
1261 while (peek() != Token::RBRACE) {
1262 Statement* stat = ParseModuleElement(NULL, CHECK_OK);
1263 if (stat && !stat->IsEmpty()) {
1264 body->AddStatement(stat);
1265 block_finder.Update(stat);
1266 }
1267 }
1268 }
1269
1270 Expect(Token::RBRACE, CHECK_OK);
1271 scope->set_end_position(scanner().location().end_pos);
1272 body->set_block_scope(scope);
1273 return factory()->NewModuleLiteral(body);
1274 }
1275
1276
1277 Module* Parser::ParseModulePath(bool* ok) {
1278 // ModulePath:
1279 // Identifier
1280 // ModulePath '.' Identifier
1281
1282 Module* result = ParseModuleVariable(CHECK_OK);
1283
1284 while (Check(Token::PERIOD)) {
1285 Handle<String> name = ParseIdentifierName(CHECK_OK);
1286 result = factory()->NewModulePath(result, name);
1287 }
1288
1289 return result;
1290 }
1291
1292
1293 Module* Parser::ParseModuleVariable(bool* ok) {
1294 // ModulePath:
1295 // Identifier
1296
1297 Handle<String> name = ParseIdentifier(CHECK_OK);
1298 VariableProxy* proxy = top_scope_->NewUnresolved(
1299 factory(), name, scanner().location().beg_pos);
1300 return factory()->NewModuleVariable(proxy);
1301 }
1302
1303
1304 Module* Parser::ParseModuleUrl(bool* ok) {
1305 // Module:
1306 // 'at' String
1307
1308 Expect(Token::IDENTIFIER, CHECK_OK);
1309 Handle<String> symbol = GetSymbol(CHECK_OK);
1310 if (!symbol->IsEqualTo(CStrVector("at"))) {
1311 *ok = false;
1312 ReportUnexpectedToken(scanner().current_token());
1313 return NULL;
1314 }
1315 Expect(Token::STRING, CHECK_OK);
1316 symbol = GetSymbol(CHECK_OK);
Lasse Reichstein Nielsen 2012/02/21 13:46:02 Great! :)
1317
1318 return factory()->NewModuleUrl(symbol);
1319 }
1320
1321
1322 Block* Parser::ParseImportDeclaration(bool* ok) {
1323 // TODO(rossberg)
1324 return NULL;
1325 }
1326
1327
1328 Block* Parser::ParseExportDeclaration(bool* ok) {
1329 // TODO(rossberg)
1330 return NULL;
1331 }
1332
1333
1334 Statement* Parser::ParseBlockElement(ZoneStringList* labels,
1335 bool* ok) {
1336 // (Ecma 262 5th Edition, clause 14):
1337 // SourceElement:
1338 // Statement
1339 // FunctionDeclaration
1340 //
1341 // In harmony mode we allow additionally the following productions
1342 // BlockElement (aka SourceElement):
1343 // LetDeclaration
1344 // ConstDeclaration
1345
1346 switch (peek()) {
1347 case Token::FUNCTION:
1348 return ParseFunctionDeclaration(ok);
1349 case Token::LET:
1350 case Token::CONST:
1351 return ParseVariableStatement(kModuleElement, ok);
1352 default:
1353 return ParseStatement(labels, ok);
1354 }
1355 }
1356
1357
1190 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { 1358 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
1191 // Statement :: 1359 // Statement ::
1192 // Block 1360 // Block
1193 // VariableStatement 1361 // VariableStatement
1194 // EmptyStatement 1362 // EmptyStatement
1195 // ExpressionStatement 1363 // ExpressionStatement
1196 // IfStatement 1364 // IfStatement
1197 // IterationStatement 1365 // IterationStatement
1198 // ContinueStatement 1366 // ContinueStatement
1199 // BreakStatement 1367 // BreakStatement
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 // will be added to the scope so that the declaration can be added 1505 // will be added to the scope so that the declaration can be added
1338 // to the corresponding activation frame at runtime if necessary. 1506 // to the corresponding activation frame at runtime if necessary.
1339 // For instance declarations inside an eval scope need to be added 1507 // For instance declarations inside an eval scope need to be added
1340 // to the calling function context. 1508 // to the calling function context.
1341 // Similarly, strict mode eval scope does not leak variable declarations to 1509 // Similarly, strict mode eval scope does not leak variable declarations to
1342 // the caller's scope so we declare all locals, too. 1510 // the caller's scope so we declare all locals, too.
1343 // Also for block scoped let/const bindings the variable can be 1511 // Also for block scoped let/const bindings the variable can be
1344 // statically declared. 1512 // statically declared.
1345 if (declaration_scope->is_function_scope() || 1513 if (declaration_scope->is_function_scope() ||
1346 declaration_scope->is_strict_or_extended_eval_scope() || 1514 declaration_scope->is_strict_or_extended_eval_scope() ||
1347 declaration_scope->is_block_scope()) { 1515 declaration_scope->is_block_scope() ||
1516 declaration_scope->is_module_scope()) {
1348 // Declare the variable in the function scope. 1517 // Declare the variable in the function scope.
1349 var = declaration_scope->LocalLookup(name); 1518 var = declaration_scope->LocalLookup(name);
1350 if (var == NULL) { 1519 if (var == NULL) {
1351 // Declare the name. 1520 // Declare the name.
1352 var = declaration_scope->DeclareLocal(name, mode, init_flag); 1521 var = declaration_scope->DeclareLocal(name, mode, init_flag);
1353 } else { 1522 } else {
1354 // The name was declared in this scope before; check for conflicting 1523 // The name was declared in this scope before; check for conflicting
1355 // re-declarations. We have a conflict if either of the declarations is 1524 // re-declarations. We have a conflict if either of the declarations is
1356 // not a var. There is similar code in runtime.cc in the Declare 1525 // not a var. There is similar code in runtime.cc in the Declare
1357 // functions. The function CheckNonConflictingScope checks for conflicting 1526 // functions. The function CheckNonConflictingScope checks for conflicting
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1567 result->AddStatement(stat); 1736 result->AddStatement(stat);
1568 block_finder.Update(stat); 1737 block_finder.Update(stat);
1569 } 1738 }
1570 } 1739 }
1571 Expect(Token::RBRACE, CHECK_OK); 1740 Expect(Token::RBRACE, CHECK_OK);
1572 return result; 1741 return result;
1573 } 1742 }
1574 1743
1575 1744
1576 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { 1745 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
1577 // The harmony mode uses source elements instead of statements. 1746 // The harmony mode uses block elements instead of statements.
1578 // 1747 //
1579 // Block :: 1748 // Block ::
1580 // '{' SourceElement* '}' 1749 // '{' BlockElement* '}'
1581 1750
1582 // Construct block expecting 16 statements. 1751 // Construct block expecting 16 statements.
1583 Block* body = factory()->NewBlock(labels, 16, false); 1752 Block* body = factory()->NewBlock(labels, 16, false);
1584 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); 1753 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE);
1585 1754
1586 // Parse the statements and collect escaping labels. 1755 // Parse the statements and collect escaping labels.
1587 Expect(Token::LBRACE, CHECK_OK); 1756 Expect(Token::LBRACE, CHECK_OK);
1588 block_scope->set_start_position(scanner().location().beg_pos); 1757 block_scope->set_start_position(scanner().location().beg_pos);
1589 { BlockState block_state(this, block_scope); 1758 { BlockState block_state(this, block_scope);
1590 TargetCollector collector; 1759 TargetCollector collector;
1591 Target target(&this->target_stack_, &collector); 1760 Target target(&this->target_stack_, &collector);
1592 Target target_body(&this->target_stack_, body); 1761 Target target_body(&this->target_stack_, body);
1593 InitializationBlockFinder block_finder(top_scope_, target_stack_); 1762 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1594 1763
1595 while (peek() != Token::RBRACE) { 1764 while (peek() != Token::RBRACE) {
1596 Statement* stat = ParseSourceElement(NULL, CHECK_OK); 1765 Statement* stat = ParseBlockElement(NULL, CHECK_OK);
1597 if (stat && !stat->IsEmpty()) { 1766 if (stat && !stat->IsEmpty()) {
1598 body->AddStatement(stat); 1767 body->AddStatement(stat);
1599 block_finder.Update(stat); 1768 block_finder.Update(stat);
1600 } 1769 }
1601 } 1770 }
1602 } 1771 }
1603 Expect(Token::RBRACE, CHECK_OK); 1772 Expect(Token::RBRACE, CHECK_OK);
1604 block_scope->set_end_position(scanner().location().end_pos); 1773 block_scope->set_end_position(scanner().location().end_pos);
1605 block_scope = block_scope->FinalizeBlockScope(); 1774 block_scope = block_scope->FinalizeBlockScope();
1606 body->set_block_scope(block_scope); 1775 body->set_block_scope(block_scope);
1607 return body; 1776 return body;
1608 } 1777 }
1609 1778
1610 1779
1611 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, 1780 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
1612 bool* ok) { 1781 bool* ok) {
1613 // VariableStatement :: 1782 // VariableStatement ::
1614 // VariableDeclarations ';' 1783 // VariableDeclarations ';'
1615 1784
1616 Handle<String> ignore; 1785 Handle<String> ignore;
1617 Block* result = ParseVariableDeclarations(var_context, 1786 Block* result =
1618 NULL, 1787 ParseVariableDeclarations(var_context, NULL, &ignore, CHECK_OK);
1619 &ignore,
1620 CHECK_OK);
1621 ExpectSemicolon(CHECK_OK); 1788 ExpectSemicolon(CHECK_OK);
1622 return result; 1789 return result;
1623 } 1790 }
1624 1791
1625 1792
1626 bool Parser::IsEvalOrArguments(Handle<String> string) { 1793 bool Parser::IsEvalOrArguments(Handle<String> string) {
1627 return string.is_identical_to(isolate()->factory()->eval_symbol()) || 1794 return string.is_identical_to(isolate()->factory()->eval_symbol()) ||
1628 string.is_identical_to(isolate()->factory()->arguments_symbol()); 1795 string.is_identical_to(isolate()->factory()->arguments_symbol());
1629 } 1796 }
1630 1797
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1677 switch (top_scope_->language_mode()) { 1844 switch (top_scope_->language_mode()) {
1678 case CLASSIC_MODE: 1845 case CLASSIC_MODE:
1679 mode = CONST; 1846 mode = CONST;
1680 init_op = Token::INIT_CONST; 1847 init_op = Token::INIT_CONST;
1681 break; 1848 break;
1682 case STRICT_MODE: 1849 case STRICT_MODE:
1683 ReportMessage("strict_const", Vector<const char*>::empty()); 1850 ReportMessage("strict_const", Vector<const char*>::empty());
1684 *ok = false; 1851 *ok = false;
1685 return NULL; 1852 return NULL;
1686 case EXTENDED_MODE: 1853 case EXTENDED_MODE:
1687 if (var_context != kSourceElement && 1854 if (var_context == kStatement) {
1688 var_context != kForStatement) {
1689 // In extended mode 'const' declarations are only allowed in source 1855 // In extended mode 'const' declarations are only allowed in source
1690 // element positions. 1856 // element positions.
1691 ReportMessage("unprotected_const", Vector<const char*>::empty()); 1857 ReportMessage("unprotected_const", Vector<const char*>::empty());
1692 *ok = false; 1858 *ok = false;
1693 return NULL; 1859 return NULL;
1694 } 1860 }
1695 mode = CONST_HARMONY; 1861 mode = CONST_HARMONY;
1696 init_op = Token::INIT_CONST_HARMONY; 1862 init_op = Token::INIT_CONST_HARMONY;
1697 } 1863 }
1698 is_const = true; 1864 is_const = true;
1699 needs_init = true; 1865 needs_init = true;
1700 } else if (peek() == Token::LET) { 1866 } else if (peek() == Token::LET) {
1701 // ES6 Draft Rev4 section 12.2.1: 1867 // ES6 Draft Rev4 section 12.2.1:
1702 // 1868 //
1703 // LetDeclaration : let LetBindingList ; 1869 // LetDeclaration : let LetBindingList ;
1704 // 1870 //
1705 // * It is a Syntax Error if the code that matches this production is not 1871 // * It is a Syntax Error if the code that matches this production is not
1706 // contained in extended code. 1872 // contained in extended code.
1707 if (!is_extended_mode()) { 1873 if (!is_extended_mode()) {
1708 ReportMessage("illegal_let", Vector<const char*>::empty()); 1874 ReportMessage("illegal_let", Vector<const char*>::empty());
1709 *ok = false; 1875 *ok = false;
1710 return NULL; 1876 return NULL;
1711 } 1877 }
1712 Consume(Token::LET); 1878 Consume(Token::LET);
1713 if (var_context != kSourceElement && 1879 if (var_context == kStatement) {
1714 var_context != kForStatement) {
1715 // Let declarations are only allowed in source element positions. 1880 // Let declarations are only allowed in source element positions.
1716 ASSERT(var_context == kStatement);
1717 ReportMessage("unprotected_let", Vector<const char*>::empty()); 1881 ReportMessage("unprotected_let", Vector<const char*>::empty());
1718 *ok = false; 1882 *ok = false;
1719 return NULL; 1883 return NULL;
1720 } 1884 }
1721 mode = LET; 1885 mode = LET;
1722 needs_init = true; 1886 needs_init = true;
1723 init_op = Token::INIT_LET; 1887 init_op = Token::INIT_LET;
1724 } else { 1888 } else {
1725 UNREACHABLE(); // by current callers 1889 UNREACHABLE(); // by current callers
1726 } 1890 }
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after
2446 ASSERT(for_scope == NULL); 2610 ASSERT(for_scope == NULL);
2447 // Parsed for-in loop w/ variable/const declaration. 2611 // Parsed for-in loop w/ variable/const declaration.
2448 return result; 2612 return result;
2449 } else { 2613 } else {
2450 init = variable_statement; 2614 init = variable_statement;
2451 } 2615 }
2452 } else if (peek() == Token::LET) { 2616 } else if (peek() == Token::LET) {
2453 Handle<String> name; 2617 Handle<String> name;
2454 VariableDeclarationProperties decl_props = kHasNoInitializers; 2618 VariableDeclarationProperties decl_props = kHasNoInitializers;
2455 Block* variable_statement = 2619 Block* variable_statement =
2456 ParseVariableDeclarations(kForStatement, 2620 ParseVariableDeclarations(kForStatement, &decl_props, &name, CHECK_OK);
2457 &decl_props,
2458 &name,
2459 CHECK_OK);
2460 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; 2621 bool accept_IN = !name.is_null() && decl_props != kHasInitializers;
2461 if (peek() == Token::IN && accept_IN) { 2622 if (peek() == Token::IN && accept_IN) {
2462 // Rewrite a for-in statement of the form 2623 // Rewrite a for-in statement of the form
2463 // 2624 //
2464 // for (let x in e) b 2625 // for (let x in e) b
2465 // 2626 //
2466 // into 2627 // into
2467 // 2628 //
2468 // <let x' be a temporary variable> 2629 // <let x' be a temporary variable>
2469 // for (x' in e) { 2630 // for (x' in e) {
(...skipping 3149 matching lines...) Expand 10 before | Expand all | Expand 10 after
5619 ASSERT(info->isolate()->has_pending_exception()); 5780 ASSERT(info->isolate()->has_pending_exception());
5620 } else { 5781 } else {
5621 result = parser.ParseProgram(info); 5782 result = parser.ParseProgram(info);
5622 } 5783 }
5623 } 5784 }
5624 info->SetFunction(result); 5785 info->SetFunction(result);
5625 return (result != NULL); 5786 return (result != NULL);
5626 } 5787 }
5627 5788
5628 } } // namespace v8::internal 5789 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/prettyprinter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698