Chromium Code Reviews

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: Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | 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...)
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...)
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...)
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 (peek() == Token::PERIOD) {
1285 Consume(Token::PERIOD);
Lasse Reichstein Nielsen 2012/02/20 09:55:48 Can be shortened to while (Check(Token::PERIOD))
rossberg 2012/02/20 12:30:04 Done.
1286 Handle<String> name = ParseIdentifierName(CHECK_OK);
1287 result = factory()->NewModulePath(result, name);
1288 }
1289
1290 return result;
1291 }
1292
1293
1294 Module* Parser::ParseModuleVariable(bool* ok) {
1295 // ModulePath:
1296 // Identifier
1297
1298 Handle<String> name = ParseIdentifier(CHECK_OK);
1299 VariableProxy* proxy = top_scope_->NewUnresolved(
1300 factory(), name, scanner().location().beg_pos);
1301 return factory()->NewModuleVariable(proxy);
1302 }
1303
1304
1305 Module* Parser::ParseModuleUrl(bool* ok) {
1306 // Module:
1307 // 'at' String
1308
1309 Token::Value token = Next();
1310 Handle<String> symbol = GetSymbol(ok);
Lasse Reichstein Nielsen 2012/02/20 09:55:48 Should this continue after an error? I.e., shouldn
rossberg 2012/02/20 12:30:04 Right, I don't know what I was thinking. Much simp
1311
1312 if (*ok && token == Token::IDENTIFIER &&
1313 symbol->IsEqualTo(CStrVector("at"))) {
1314 token = Next();
1315 symbol = GetSymbol(ok);
1316 } else {
1317 *ok = false;
1318 }
1319
1320 if (!*ok || token != Token::STRING) {
1321 *ok = false;
1322 ReportUnexpectedToken(token);
1323 return NULL;
1324 }
1325
1326 return factory()->NewModuleUrl(symbol);
1327 }
1328
1329
1330 Block* Parser::ParseImportDeclaration(bool* ok) {
1331 // TODO(rossberg)
1332 return NULL;
1333 }
1334
1335
1336 Block* Parser::ParseExportDeclaration(bool* ok) {
1337 // TODO(rossberg)
1338 return NULL;
1339 }
1340
1341
1342 Statement* Parser::ParseBlockElement(ZoneStringList* labels,
1343 bool* ok) {
1344 // (Ecma 262 5th Edition, clause 14):
1345 // SourceElement:
1346 // Statement
1347 // FunctionDeclaration
1348 //
1349 // In harmony mode we allow additionally the following productions
1350 // BlockElement (aka SourceElement):
1351 // LetDeclaration
1352 // ConstDeclaration
1353
1354 switch (peek()) {
1355 case Token::FUNCTION:
1356 return ParseFunctionDeclaration(ok);
1357 case Token::LET:
1358 case Token::CONST:
1359 return ParseVariableStatement(kModuleElement, ok);
1360 default:
1361 return ParseStatement(labels, ok);
1362 }
1363 }
1364
1365
1190 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { 1366 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
1191 // Statement :: 1367 // Statement ::
1192 // Block 1368 // Block
1193 // VariableStatement 1369 // VariableStatement
1194 // EmptyStatement 1370 // EmptyStatement
1195 // ExpressionStatement 1371 // ExpressionStatement
1196 // IfStatement 1372 // IfStatement
1197 // IterationStatement 1373 // IterationStatement
1198 // ContinueStatement 1374 // ContinueStatement
1199 // BreakStatement 1375 // BreakStatement
(...skipping 137 matching lines...)
1337 // will be added to the scope so that the declaration can be added 1513 // will be added to the scope so that the declaration can be added
1338 // to the corresponding activation frame at runtime if necessary. 1514 // to the corresponding activation frame at runtime if necessary.
1339 // For instance declarations inside an eval scope need to be added 1515 // For instance declarations inside an eval scope need to be added
1340 // to the calling function context. 1516 // to the calling function context.
1341 // Similarly, strict mode eval scope does not leak variable declarations to 1517 // Similarly, strict mode eval scope does not leak variable declarations to
1342 // the caller's scope so we declare all locals, too. 1518 // the caller's scope so we declare all locals, too.
1343 // Also for block scoped let/const bindings the variable can be 1519 // Also for block scoped let/const bindings the variable can be
1344 // statically declared. 1520 // statically declared.
1345 if (declaration_scope->is_function_scope() || 1521 if (declaration_scope->is_function_scope() ||
1346 declaration_scope->is_strict_or_extended_eval_scope() || 1522 declaration_scope->is_strict_or_extended_eval_scope() ||
1347 declaration_scope->is_block_scope()) { 1523 declaration_scope->is_block_scope() ||
1524 declaration_scope->is_module_scope()) {
1348 // Declare the variable in the function scope. 1525 // Declare the variable in the function scope.
1349 var = declaration_scope->LocalLookup(name); 1526 var = declaration_scope->LocalLookup(name);
1350 if (var == NULL) { 1527 if (var == NULL) {
1351 // Declare the name. 1528 // Declare the name.
1352 var = declaration_scope->DeclareLocal(name, mode, init_flag); 1529 var = declaration_scope->DeclareLocal(name, mode, init_flag);
1353 } else { 1530 } else {
1354 // The name was declared in this scope before; check for conflicting 1531 // The name was declared in this scope before; check for conflicting
1355 // re-declarations. We have a conflict if either of the declarations is 1532 // 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 1533 // not a var. There is similar code in runtime.cc in the Declare
1357 // functions. The function CheckNonConflictingScope checks for conflicting 1534 // functions. The function CheckNonConflictingScope checks for conflicting
(...skipping 209 matching lines...)
1567 result->AddStatement(stat); 1744 result->AddStatement(stat);
1568 block_finder.Update(stat); 1745 block_finder.Update(stat);
1569 } 1746 }
1570 } 1747 }
1571 Expect(Token::RBRACE, CHECK_OK); 1748 Expect(Token::RBRACE, CHECK_OK);
1572 return result; 1749 return result;
1573 } 1750 }
1574 1751
1575 1752
1576 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { 1753 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
1577 // The harmony mode uses source elements instead of statements. 1754 // The harmony mode uses block elements instead of statements.
1578 // 1755 //
1579 // Block :: 1756 // Block ::
1580 // '{' SourceElement* '}' 1757 // '{' BlockElement* '}'
1581 1758
1582 // Construct block expecting 16 statements. 1759 // Construct block expecting 16 statements.
1583 Block* body = factory()->NewBlock(labels, 16, false); 1760 Block* body = factory()->NewBlock(labels, 16, false);
1584 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); 1761 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE);
1585 1762
1586 // Parse the statements and collect escaping labels. 1763 // Parse the statements and collect escaping labels.
1587 Expect(Token::LBRACE, CHECK_OK); 1764 Expect(Token::LBRACE, CHECK_OK);
1588 block_scope->set_start_position(scanner().location().beg_pos); 1765 block_scope->set_start_position(scanner().location().beg_pos);
1589 { BlockState block_state(this, block_scope); 1766 { BlockState block_state(this, block_scope);
1590 TargetCollector collector; 1767 TargetCollector collector;
1591 Target target(&this->target_stack_, &collector); 1768 Target target(&this->target_stack_, &collector);
1592 Target target_body(&this->target_stack_, body); 1769 Target target_body(&this->target_stack_, body);
1593 InitializationBlockFinder block_finder(top_scope_, target_stack_); 1770 InitializationBlockFinder block_finder(top_scope_, target_stack_);
1594 1771
1595 while (peek() != Token::RBRACE) { 1772 while (peek() != Token::RBRACE) {
1596 Statement* stat = ParseSourceElement(NULL, CHECK_OK); 1773 Statement* stat = ParseBlockElement(NULL, CHECK_OK);
1597 if (stat && !stat->IsEmpty()) { 1774 if (stat && !stat->IsEmpty()) {
1598 body->AddStatement(stat); 1775 body->AddStatement(stat);
1599 block_finder.Update(stat); 1776 block_finder.Update(stat);
1600 } 1777 }
1601 } 1778 }
1602 } 1779 }
1603 Expect(Token::RBRACE, CHECK_OK); 1780 Expect(Token::RBRACE, CHECK_OK);
1604 block_scope->set_end_position(scanner().location().end_pos); 1781 block_scope->set_end_position(scanner().location().end_pos);
1605 block_scope = block_scope->FinalizeBlockScope(); 1782 block_scope = block_scope->FinalizeBlockScope();
1606 body->set_block_scope(block_scope); 1783 body->set_block_scope(block_scope);
1607 return body; 1784 return body;
1608 } 1785 }
1609 1786
1610 1787
1611 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, 1788 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
1612 bool* ok) { 1789 bool* ok) {
1613 // VariableStatement :: 1790 // VariableStatement ::
1614 // VariableDeclarations ';' 1791 // VariableDeclarations ';'
1615 1792
1616 Handle<String> ignore; 1793 Handle<String> ignore;
1617 Block* result = ParseVariableDeclarations(var_context, 1794 Block* result =
1618 NULL, 1795 ParseVariableDeclarations(var_context, NULL, &ignore, CHECK_OK);
1619 &ignore,
1620 CHECK_OK);
1621 ExpectSemicolon(CHECK_OK); 1796 ExpectSemicolon(CHECK_OK);
1622 return result; 1797 return result;
1623 } 1798 }
1624 1799
1625 1800
1626 bool Parser::IsEvalOrArguments(Handle<String> string) { 1801 bool Parser::IsEvalOrArguments(Handle<String> string) {
1627 return string.is_identical_to(isolate()->factory()->eval_symbol()) || 1802 return string.is_identical_to(isolate()->factory()->eval_symbol()) ||
1628 string.is_identical_to(isolate()->factory()->arguments_symbol()); 1803 string.is_identical_to(isolate()->factory()->arguments_symbol());
1629 } 1804 }
1630 1805
(...skipping 46 matching lines...)
1677 switch (top_scope_->language_mode()) { 1852 switch (top_scope_->language_mode()) {
1678 case CLASSIC_MODE: 1853 case CLASSIC_MODE:
1679 mode = CONST; 1854 mode = CONST;
1680 init_op = Token::INIT_CONST; 1855 init_op = Token::INIT_CONST;
1681 break; 1856 break;
1682 case STRICT_MODE: 1857 case STRICT_MODE:
1683 ReportMessage("strict_const", Vector<const char*>::empty()); 1858 ReportMessage("strict_const", Vector<const char*>::empty());
1684 *ok = false; 1859 *ok = false;
1685 return NULL; 1860 return NULL;
1686 case EXTENDED_MODE: 1861 case EXTENDED_MODE:
1687 if (var_context != kSourceElement && 1862 if (var_context == kStatement) {
1688 var_context != kForStatement) {
1689 // In extended mode 'const' declarations are only allowed in source 1863 // In extended mode 'const' declarations are only allowed in source
1690 // element positions. 1864 // element positions.
1691 ReportMessage("unprotected_const", Vector<const char*>::empty()); 1865 ReportMessage("unprotected_const", Vector<const char*>::empty());
1692 *ok = false; 1866 *ok = false;
1693 return NULL; 1867 return NULL;
1694 } 1868 }
1695 mode = CONST_HARMONY; 1869 mode = CONST_HARMONY;
1696 init_op = Token::INIT_CONST_HARMONY; 1870 init_op = Token::INIT_CONST_HARMONY;
1697 } 1871 }
1698 is_const = true; 1872 is_const = true;
1699 needs_init = true; 1873 needs_init = true;
1700 } else if (peek() == Token::LET) { 1874 } else if (peek() == Token::LET) {
1701 // ES6 Draft Rev4 section 12.2.1: 1875 // ES6 Draft Rev4 section 12.2.1:
1702 // 1876 //
1703 // LetDeclaration : let LetBindingList ; 1877 // LetDeclaration : let LetBindingList ;
1704 // 1878 //
1705 // * It is a Syntax Error if the code that matches this production is not 1879 // * It is a Syntax Error if the code that matches this production is not
1706 // contained in extended code. 1880 // contained in extended code.
1707 if (!is_extended_mode()) { 1881 if (!is_extended_mode()) {
1708 ReportMessage("illegal_let", Vector<const char*>::empty()); 1882 ReportMessage("illegal_let", Vector<const char*>::empty());
1709 *ok = false; 1883 *ok = false;
1710 return NULL; 1884 return NULL;
1711 } 1885 }
1712 Consume(Token::LET); 1886 Consume(Token::LET);
1713 if (var_context != kSourceElement && 1887 if (var_context == kStatement) {
1714 var_context != kForStatement) {
1715 // Let declarations are only allowed in source element positions. 1888 // Let declarations are only allowed in source element positions.
1716 ASSERT(var_context == kStatement);
1717 ReportMessage("unprotected_let", Vector<const char*>::empty()); 1889 ReportMessage("unprotected_let", Vector<const char*>::empty());
1718 *ok = false; 1890 *ok = false;
1719 return NULL; 1891 return NULL;
1720 } 1892 }
1721 mode = LET; 1893 mode = LET;
1722 needs_init = true; 1894 needs_init = true;
1723 init_op = Token::INIT_LET; 1895 init_op = Token::INIT_LET;
1724 } else { 1896 } else {
1725 UNREACHABLE(); // by current callers 1897 UNREACHABLE(); // by current callers
1726 } 1898 }
(...skipping 719 matching lines...)
2446 ASSERT(for_scope == NULL); 2618 ASSERT(for_scope == NULL);
2447 // Parsed for-in loop w/ variable/const declaration. 2619 // Parsed for-in loop w/ variable/const declaration.
2448 return result; 2620 return result;
2449 } else { 2621 } else {
2450 init = variable_statement; 2622 init = variable_statement;
2451 } 2623 }
2452 } else if (peek() == Token::LET) { 2624 } else if (peek() == Token::LET) {
2453 Handle<String> name; 2625 Handle<String> name;
2454 VariableDeclarationProperties decl_props = kHasNoInitializers; 2626 VariableDeclarationProperties decl_props = kHasNoInitializers;
2455 Block* variable_statement = 2627 Block* variable_statement =
2456 ParseVariableDeclarations(kForStatement, 2628 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; 2629 bool accept_IN = !name.is_null() && decl_props != kHasInitializers;
2461 if (peek() == Token::IN && accept_IN) { 2630 if (peek() == Token::IN && accept_IN) {
2462 // Rewrite a for-in statement of the form 2631 // Rewrite a for-in statement of the form
2463 // 2632 //
2464 // for (let x in e) b 2633 // for (let x in e) b
2465 // 2634 //
2466 // into 2635 // into
2467 // 2636 //
2468 // <let x' be a temporary variable> 2637 // <let x' be a temporary variable>
2469 // for (x' in e) { 2638 // for (x' in e) {
(...skipping 3149 matching lines...)
5619 ASSERT(info->isolate()->has_pending_exception()); 5788 ASSERT(info->isolate()->has_pending_exception());
5620 } else { 5789 } else {
5621 result = parser.ParseProgram(info); 5790 result = parser.ParseProgram(info);
5622 } 5791 }
5623 } 5792 }
5624 info->SetFunction(result); 5793 info->SetFunction(result);
5625 return (result != NULL); 5794 return (result != NULL);
5626 } 5795 }
5627 5796
5628 } } // namespace v8::internal 5797 } } // 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