OLD | NEW |
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 1166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1177 // In harmony mode we allow additionally the following productions | 1177 // In harmony mode we allow additionally the following productions |
1178 // ModuleElement: | 1178 // ModuleElement: |
1179 // LetDeclaration | 1179 // LetDeclaration |
1180 // ConstDeclaration | 1180 // ConstDeclaration |
1181 // ModuleDeclaration | 1181 // ModuleDeclaration |
1182 // ImportDeclaration | 1182 // ImportDeclaration |
1183 // ExportDeclaration | 1183 // ExportDeclaration |
1184 | 1184 |
1185 switch (peek()) { | 1185 switch (peek()) { |
1186 case Token::FUNCTION: | 1186 case Token::FUNCTION: |
1187 return ParseFunctionDeclaration(ok); | 1187 return ParseFunctionDeclaration(NULL, ok); |
1188 case Token::LET: | 1188 case Token::LET: |
1189 case Token::CONST: | 1189 case Token::CONST: |
1190 return ParseVariableStatement(kModuleElement, ok); | 1190 return ParseVariableStatement(kModuleElement, NULL, ok); |
1191 case Token::IMPORT: | 1191 case Token::IMPORT: |
1192 return ParseImportDeclaration(ok); | 1192 return ParseImportDeclaration(ok); |
1193 case Token::EXPORT: | 1193 case Token::EXPORT: |
1194 return ParseExportDeclaration(ok); | 1194 return ParseExportDeclaration(ok); |
1195 default: { | 1195 default: { |
1196 Statement* stmt = ParseStatement(labels, CHECK_OK); | 1196 Statement* stmt = ParseStatement(labels, CHECK_OK); |
1197 // Handle 'module' as a context-sensitive keyword. | 1197 // Handle 'module' as a context-sensitive keyword. |
1198 if (FLAG_harmony_modules && | 1198 if (FLAG_harmony_modules && |
1199 peek() == Token::IDENTIFIER && | 1199 peek() == Token::IDENTIFIER && |
1200 !scanner().HasAnyLineTerminatorBeforeNext() && | 1200 !scanner().HasAnyLineTerminatorBeforeNext() && |
1201 stmt != NULL) { | 1201 stmt != NULL) { |
1202 ExpressionStatement* estmt = stmt->AsExpressionStatement(); | 1202 ExpressionStatement* estmt = stmt->AsExpressionStatement(); |
1203 if (estmt != NULL && | 1203 if (estmt != NULL && |
1204 estmt->expression()->AsVariableProxy() != NULL && | 1204 estmt->expression()->AsVariableProxy() != NULL && |
1205 estmt->expression()->AsVariableProxy()->name()->Equals( | 1205 estmt->expression()->AsVariableProxy()->name()->Equals( |
1206 isolate()->heap()->module_symbol()) && | 1206 isolate()->heap()->module_symbol()) && |
1207 !scanner().literal_contains_escapes()) { | 1207 !scanner().literal_contains_escapes()) { |
1208 return ParseModuleDeclaration(ok); | 1208 return ParseModuleDeclaration(NULL, ok); |
1209 } | 1209 } |
1210 } | 1210 } |
1211 return stmt; | 1211 return stmt; |
1212 } | 1212 } |
1213 } | 1213 } |
1214 } | 1214 } |
1215 | 1215 |
1216 | 1216 |
1217 Block* Parser::ParseModuleDeclaration(bool* ok) { | 1217 Block* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { |
1218 // ModuleDeclaration: | 1218 // ModuleDeclaration: |
1219 // 'module' Identifier Module | 1219 // 'module' Identifier Module |
1220 | 1220 |
1221 // Create new block with one expected declaration. | 1221 // Create new block with one expected declaration. |
1222 Block* block = factory()->NewBlock(NULL, 1, true); | 1222 Block* block = factory()->NewBlock(NULL, 1, true); |
1223 Handle<String> name = ParseIdentifier(CHECK_OK); | 1223 Handle<String> name = ParseIdentifier(CHECK_OK); |
1224 Module* module = ParseModule(CHECK_OK); | 1224 Module* module = ParseModule(CHECK_OK); |
1225 VariableProxy* proxy = NewUnresolved(name, LET); | 1225 VariableProxy* proxy = NewUnresolved(name, LET); |
1226 Declaration* declaration = | 1226 Declaration* declaration = |
1227 factory()->NewModuleDeclaration(proxy, module, top_scope_); | 1227 factory()->NewModuleDeclaration(proxy, module, top_scope_); |
1228 Declare(declaration, true, CHECK_OK); | 1228 Declare(declaration, true, CHECK_OK); |
1229 | 1229 |
1230 // TODO(rossberg): Add initialization statement to block. | 1230 // TODO(rossberg): Add initialization statement to block. |
1231 | 1231 |
| 1232 if (names) names->Add(name); |
1232 return block; | 1233 return block; |
1233 } | 1234 } |
1234 | 1235 |
1235 | 1236 |
1236 Module* Parser::ParseModule(bool* ok) { | 1237 Module* Parser::ParseModule(bool* ok) { |
1237 // Module: | 1238 // Module: |
1238 // '{' ModuleElement '}' | 1239 // '{' ModuleElement '}' |
1239 // '=' ModulePath | 1240 // '=' ModulePath ';' |
1240 // 'at' String | 1241 // 'at' String ';' |
1241 | 1242 |
1242 switch (peek()) { | 1243 switch (peek()) { |
1243 case Token::LBRACE: | 1244 case Token::LBRACE: |
1244 return ParseModuleLiteral(ok); | 1245 return ParseModuleLiteral(ok); |
1245 | 1246 |
1246 case Token::ASSIGN: | 1247 case Token::ASSIGN: { |
1247 Expect(Token::ASSIGN, CHECK_OK); | 1248 Expect(Token::ASSIGN, CHECK_OK); |
1248 return ParseModulePath(ok); | 1249 Module* result = ParseModulePath(CHECK_OK); |
| 1250 ExpectSemicolon(CHECK_OK); |
| 1251 return result; |
| 1252 } |
1249 | 1253 |
1250 default: | 1254 default: { |
1251 return ParseModuleUrl(ok); | 1255 ExpectContextualKeyword("at", CHECK_OK); |
| 1256 Module* result = ParseModuleUrl(CHECK_OK); |
| 1257 ExpectSemicolon(CHECK_OK); |
| 1258 return result; |
| 1259 } |
1252 } | 1260 } |
1253 } | 1261 } |
1254 | 1262 |
1255 | 1263 |
1256 Module* Parser::ParseModuleLiteral(bool* ok) { | 1264 Module* Parser::ParseModuleLiteral(bool* ok) { |
1257 // Module: | 1265 // Module: |
1258 // '{' ModuleElement '}' | 1266 // '{' ModuleElement '}' |
1259 | 1267 |
1260 // Construct block expecting 16 statements. | 1268 // Construct block expecting 16 statements. |
1261 Block* body = factory()->NewBlock(NULL, 16, false); | 1269 Block* body = factory()->NewBlock(NULL, 16, false); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1310 | 1318 |
1311 Handle<String> name = ParseIdentifier(CHECK_OK); | 1319 Handle<String> name = ParseIdentifier(CHECK_OK); |
1312 VariableProxy* proxy = top_scope_->NewUnresolved( | 1320 VariableProxy* proxy = top_scope_->NewUnresolved( |
1313 factory(), name, scanner().location().beg_pos); | 1321 factory(), name, scanner().location().beg_pos); |
1314 return factory()->NewModuleVariable(proxy); | 1322 return factory()->NewModuleVariable(proxy); |
1315 } | 1323 } |
1316 | 1324 |
1317 | 1325 |
1318 Module* Parser::ParseModuleUrl(bool* ok) { | 1326 Module* Parser::ParseModuleUrl(bool* ok) { |
1319 // Module: | 1327 // Module: |
1320 // 'at' String | 1328 // String |
1321 | 1329 |
1322 Expect(Token::IDENTIFIER, CHECK_OK); | 1330 Expect(Token::STRING, CHECK_OK); |
1323 Handle<String> symbol = GetSymbol(CHECK_OK); | 1331 Handle<String> symbol = GetSymbol(CHECK_OK); |
1324 if (!symbol->IsEqualTo(CStrVector("at"))) { | |
1325 *ok = false; | |
1326 ReportUnexpectedToken(scanner().current_token()); | |
1327 return NULL; | |
1328 } | |
1329 Expect(Token::STRING, CHECK_OK); | |
1330 symbol = GetSymbol(CHECK_OK); | |
1331 | 1332 |
1332 return factory()->NewModuleUrl(symbol); | 1333 return factory()->NewModuleUrl(symbol); |
1333 } | 1334 } |
1334 | 1335 |
1335 | 1336 |
1336 Block* Parser::ParseImportDeclaration(bool* ok) { | 1337 Module* Parser::ParseModuleSpecifier(bool* ok) { |
1337 // TODO(rossberg) | 1338 // ModuleSpecifier: |
1338 return NULL; | 1339 // String |
| 1340 // ModulePath |
| 1341 |
| 1342 if (peek() == Token::STRING) { |
| 1343 return ParseModuleUrl(ok); |
| 1344 } else { |
| 1345 return ParseModulePath(ok); |
| 1346 } |
1339 } | 1347 } |
1340 | 1348 |
1341 | 1349 |
1342 Block* Parser::ParseExportDeclaration(bool* ok) { | 1350 Block* Parser::ParseImportDeclaration(bool* ok) { |
1343 // TODO(rossberg) | 1351 // ImportDeclaration: |
1344 return NULL; | 1352 // 'import' IdentifierName (',' IdentifierName)* 'from' ModuleSpecifier ';' |
| 1353 // |
| 1354 // TODO(ES6): implement destructuring ImportSpecifiers |
| 1355 |
| 1356 Expect(Token::IMPORT, CHECK_OK); |
| 1357 ZoneStringList names(1); |
| 1358 |
| 1359 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 1360 while (peek() == Token::COMMA) { |
| 1361 Consume(Token::COMMA); |
| 1362 name = ParseIdentifierName(CHECK_OK); |
| 1363 names.Add(name); |
| 1364 } |
| 1365 |
| 1366 ExpectContextualKeyword("from", CHECK_OK); |
| 1367 Module* module = ParseModuleSpecifier(CHECK_OK); |
| 1368 ExpectSemicolon(CHECK_OK); |
| 1369 |
| 1370 // Generate a separate declaration for each identifier. |
| 1371 // TODO(ES6): once we implement destructuring, make that one declaration. |
| 1372 Block* block = factory()->NewBlock(NULL, 1, true); |
| 1373 for (int i = 0; i < names.length(); ++i) { |
| 1374 VariableProxy* proxy = NewUnresolved(names[i], LET); |
| 1375 Declaration* declaration = |
| 1376 factory()->NewImportDeclaration(proxy, module, top_scope_); |
| 1377 Declare(declaration, true, CHECK_OK); |
| 1378 // TODO(rossberg): Add initialization statement to block. |
| 1379 } |
| 1380 |
| 1381 |
| 1382 return block; |
1345 } | 1383 } |
1346 | 1384 |
1347 | 1385 |
| 1386 Statement* Parser::ParseExportDeclaration(bool* ok) { |
| 1387 // ExportDeclaration: |
| 1388 // 'export' Identifier (',' Identifier)* ';' |
| 1389 // 'export' VariableDeclaration |
| 1390 // 'export' FunctionDeclaration |
| 1391 // 'export' ModuleDeclaration |
| 1392 // |
| 1393 // TODO(ES6): implement structuring ExportSpecifiers |
| 1394 |
| 1395 Expect(Token::EXPORT, CHECK_OK); |
| 1396 |
| 1397 Statement* result = NULL; |
| 1398 ZoneStringList names(1); |
| 1399 switch (peek()) { |
| 1400 case Token::IDENTIFIER: { |
| 1401 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1402 // Handle 'module' as a context-sensitive keyword. |
| 1403 if (!name->IsEqualTo(CStrVector("module"))) { |
| 1404 names.Add(name); |
| 1405 while (peek() == Token::COMMA) { |
| 1406 Consume(Token::COMMA); |
| 1407 name = ParseIdentifier(CHECK_OK); |
| 1408 names.Add(name); |
| 1409 } |
| 1410 ExpectSemicolon(CHECK_OK); |
| 1411 result = factory()->NewEmptyStatement(); |
| 1412 } else { |
| 1413 result = ParseModuleDeclaration(&names, CHECK_OK); |
| 1414 } |
| 1415 break; |
| 1416 } |
| 1417 |
| 1418 case Token::FUNCTION: |
| 1419 result = ParseFunctionDeclaration(&names, CHECK_OK); |
| 1420 break; |
| 1421 |
| 1422 case Token::VAR: |
| 1423 case Token::LET: |
| 1424 case Token::CONST: |
| 1425 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK); |
| 1426 break; |
| 1427 |
| 1428 default: |
| 1429 *ok = false; |
| 1430 ReportUnexpectedToken(scanner().current_token()); |
| 1431 return NULL; |
| 1432 } |
| 1433 |
| 1434 // Extract declared names into export declarations. |
| 1435 for (int i = 0; i < names.length(); ++i) { |
| 1436 VariableProxy* proxy = NewUnresolved(names[i], LET); |
| 1437 Declaration* declaration = |
| 1438 factory()->NewExportDeclaration(proxy, top_scope_); |
| 1439 top_scope_->AddDeclaration(declaration); |
| 1440 } |
| 1441 |
| 1442 ASSERT(result != NULL); |
| 1443 return result; |
| 1444 } |
| 1445 |
| 1446 |
1348 Statement* Parser::ParseBlockElement(ZoneStringList* labels, | 1447 Statement* Parser::ParseBlockElement(ZoneStringList* labels, |
1349 bool* ok) { | 1448 bool* ok) { |
1350 // (Ecma 262 5th Edition, clause 14): | 1449 // (Ecma 262 5th Edition, clause 14): |
1351 // SourceElement: | 1450 // SourceElement: |
1352 // Statement | 1451 // Statement |
1353 // FunctionDeclaration | 1452 // FunctionDeclaration |
1354 // | 1453 // |
1355 // In harmony mode we allow additionally the following productions | 1454 // In harmony mode we allow additionally the following productions |
1356 // BlockElement (aka SourceElement): | 1455 // BlockElement (aka SourceElement): |
1357 // LetDeclaration | 1456 // LetDeclaration |
1358 // ConstDeclaration | 1457 // ConstDeclaration |
1359 | 1458 |
1360 switch (peek()) { | 1459 switch (peek()) { |
1361 case Token::FUNCTION: | 1460 case Token::FUNCTION: |
1362 return ParseFunctionDeclaration(ok); | 1461 return ParseFunctionDeclaration(NULL, ok); |
1363 case Token::LET: | 1462 case Token::LET: |
1364 case Token::CONST: | 1463 case Token::CONST: |
1365 return ParseVariableStatement(kModuleElement, ok); | 1464 return ParseVariableStatement(kModuleElement, NULL, ok); |
1366 default: | 1465 default: |
1367 return ParseStatement(labels, ok); | 1466 return ParseStatement(labels, ok); |
1368 } | 1467 } |
1369 } | 1468 } |
1370 | 1469 |
1371 | 1470 |
1372 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { | 1471 Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
1373 // Statement :: | 1472 // Statement :: |
1374 // Block | 1473 // Block |
1375 // VariableStatement | 1474 // VariableStatement |
(...skipping 21 matching lines...) Expand all Loading... |
1397 // Keep the source position of the statement | 1496 // Keep the source position of the statement |
1398 int statement_pos = scanner().peek_location().beg_pos; | 1497 int statement_pos = scanner().peek_location().beg_pos; |
1399 Statement* stmt = NULL; | 1498 Statement* stmt = NULL; |
1400 switch (peek()) { | 1499 switch (peek()) { |
1401 case Token::LBRACE: | 1500 case Token::LBRACE: |
1402 return ParseBlock(labels, ok); | 1501 return ParseBlock(labels, ok); |
1403 | 1502 |
1404 case Token::CONST: // fall through | 1503 case Token::CONST: // fall through |
1405 case Token::LET: | 1504 case Token::LET: |
1406 case Token::VAR: | 1505 case Token::VAR: |
1407 stmt = ParseVariableStatement(kStatement, ok); | 1506 stmt = ParseVariableStatement(kStatement, NULL, ok); |
1408 break; | 1507 break; |
1409 | 1508 |
1410 case Token::SEMICOLON: | 1509 case Token::SEMICOLON: |
1411 Next(); | 1510 Next(); |
1412 return factory()->NewEmptyStatement(); | 1511 return factory()->NewEmptyStatement(); |
1413 | 1512 |
1414 case Token::IF: | 1513 case Token::IF: |
1415 stmt = ParseIfStatement(labels, ok); | 1514 stmt = ParseIfStatement(labels, ok); |
1416 break; | 1515 break; |
1417 | 1516 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1474 // Statement | 1573 // Statement |
1475 // FunctionDeclaration | 1574 // FunctionDeclaration |
1476 // Common language extension is to allow function declaration in place | 1575 // Common language extension is to allow function declaration in place |
1477 // of any statement. This language extension is disabled in strict mode. | 1576 // of any statement. This language extension is disabled in strict mode. |
1478 if (!top_scope_->is_classic_mode()) { | 1577 if (!top_scope_->is_classic_mode()) { |
1479 ReportMessageAt(scanner().peek_location(), "strict_function", | 1578 ReportMessageAt(scanner().peek_location(), "strict_function", |
1480 Vector<const char*>::empty()); | 1579 Vector<const char*>::empty()); |
1481 *ok = false; | 1580 *ok = false; |
1482 return NULL; | 1581 return NULL; |
1483 } | 1582 } |
1484 return ParseFunctionDeclaration(ok); | 1583 return ParseFunctionDeclaration(NULL, ok); |
1485 } | 1584 } |
1486 | 1585 |
1487 case Token::DEBUGGER: | 1586 case Token::DEBUGGER: |
1488 stmt = ParseDebuggerStatement(ok); | 1587 stmt = ParseDebuggerStatement(ok); |
1489 break; | 1588 break; |
1490 | 1589 |
1491 default: | 1590 default: |
1492 stmt = ParseExpressionOrLabelledStatement(labels, ok); | 1591 stmt = ParseExpressionOrLabelledStatement(labels, ok); |
1493 } | 1592 } |
1494 | 1593 |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1701 factory()->NewVariableDeclaration(proxy, VAR, top_scope_); | 1800 factory()->NewVariableDeclaration(proxy, VAR, top_scope_); |
1702 Declare(declaration, true, CHECK_OK); | 1801 Declare(declaration, true, CHECK_OK); |
1703 SharedFunctionInfoLiteral* lit = | 1802 SharedFunctionInfoLiteral* lit = |
1704 factory()->NewSharedFunctionInfoLiteral(shared); | 1803 factory()->NewSharedFunctionInfoLiteral(shared); |
1705 return factory()->NewExpressionStatement( | 1804 return factory()->NewExpressionStatement( |
1706 factory()->NewAssignment( | 1805 factory()->NewAssignment( |
1707 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition)); | 1806 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition)); |
1708 } | 1807 } |
1709 | 1808 |
1710 | 1809 |
1711 Statement* Parser::ParseFunctionDeclaration(bool* ok) { | 1810 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { |
1712 // FunctionDeclaration :: | 1811 // FunctionDeclaration :: |
1713 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1812 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
1714 Expect(Token::FUNCTION, CHECK_OK); | 1813 Expect(Token::FUNCTION, CHECK_OK); |
1715 int function_token_position = scanner().location().beg_pos; | 1814 int function_token_position = scanner().location().beg_pos; |
1716 bool is_strict_reserved = false; | 1815 bool is_strict_reserved = false; |
1717 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1816 Handle<String> name = ParseIdentifierOrStrictReservedWord( |
1718 &is_strict_reserved, CHECK_OK); | 1817 &is_strict_reserved, CHECK_OK); |
1719 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1818 FunctionLiteral* fun = ParseFunctionLiteral(name, |
1720 is_strict_reserved, | 1819 is_strict_reserved, |
1721 function_token_position, | 1820 function_token_position, |
1722 FunctionLiteral::DECLARATION, | 1821 FunctionLiteral::DECLARATION, |
1723 CHECK_OK); | 1822 CHECK_OK); |
1724 // Even if we're not at the top-level of the global or a function | 1823 // Even if we're not at the top-level of the global or a function |
1725 // scope, we treat is as such and introduce the function with it's | 1824 // scope, we treat is as such and introduce the function with it's |
1726 // initial value upon entering the corresponding scope. | 1825 // initial value upon entering the corresponding scope. |
1727 VariableMode mode = is_extended_mode() ? LET : VAR; | 1826 VariableMode mode = is_extended_mode() ? LET : VAR; |
1728 VariableProxy* proxy = NewUnresolved(name, mode); | 1827 VariableProxy* proxy = NewUnresolved(name, mode); |
1729 Declaration* declaration = | 1828 Declaration* declaration = |
1730 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_); | 1829 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_); |
1731 Declare(declaration, true, CHECK_OK); | 1830 Declare(declaration, true, CHECK_OK); |
| 1831 if (names) names->Add(name); |
1732 return factory()->NewEmptyStatement(); | 1832 return factory()->NewEmptyStatement(); |
1733 } | 1833 } |
1734 | 1834 |
1735 | 1835 |
1736 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1836 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
1737 if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); | 1837 if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); |
1738 | 1838 |
1739 // Block :: | 1839 // Block :: |
1740 // '{' Statement* '}' | 1840 // '{' Statement* '}' |
1741 | 1841 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1788 } | 1888 } |
1789 Expect(Token::RBRACE, CHECK_OK); | 1889 Expect(Token::RBRACE, CHECK_OK); |
1790 block_scope->set_end_position(scanner().location().end_pos); | 1890 block_scope->set_end_position(scanner().location().end_pos); |
1791 block_scope = block_scope->FinalizeBlockScope(); | 1891 block_scope = block_scope->FinalizeBlockScope(); |
1792 body->set_block_scope(block_scope); | 1892 body->set_block_scope(block_scope); |
1793 return body; | 1893 return body; |
1794 } | 1894 } |
1795 | 1895 |
1796 | 1896 |
1797 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 1897 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
| 1898 ZoneStringList* names, |
1798 bool* ok) { | 1899 bool* ok) { |
1799 // VariableStatement :: | 1900 // VariableStatement :: |
1800 // VariableDeclarations ';' | 1901 // VariableDeclarations ';' |
1801 | 1902 |
1802 Handle<String> ignore; | 1903 Handle<String> ignore; |
1803 Block* result = | 1904 Block* result = |
1804 ParseVariableDeclarations(var_context, NULL, &ignore, CHECK_OK); | 1905 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); |
1805 ExpectSemicolon(CHECK_OK); | 1906 ExpectSemicolon(CHECK_OK); |
1806 return result; | 1907 return result; |
1807 } | 1908 } |
1808 | 1909 |
1809 | 1910 |
1810 bool Parser::IsEvalOrArguments(Handle<String> string) { | 1911 bool Parser::IsEvalOrArguments(Handle<String> string) { |
1811 return string.is_identical_to(isolate()->factory()->eval_symbol()) || | 1912 return string.is_identical_to(isolate()->factory()->eval_symbol()) || |
1812 string.is_identical_to(isolate()->factory()->arguments_symbol()); | 1913 string.is_identical_to(isolate()->factory()->arguments_symbol()); |
1813 } | 1914 } |
1814 | 1915 |
1815 | 1916 |
1816 // If the variable declaration declares exactly one non-const | 1917 // If the variable declaration declares exactly one non-const |
1817 // variable, then *out is set to that variable. In all other cases, | 1918 // variable, then *out is set to that variable. In all other cases, |
1818 // *out is untouched; in particular, it is the caller's responsibility | 1919 // *out is untouched; in particular, it is the caller's responsibility |
1819 // to initialize it properly. This mechanism is used for the parsing | 1920 // to initialize it properly. This mechanism is used for the parsing |
1820 // of 'for-in' loops. | 1921 // of 'for-in' loops. |
1821 Block* Parser::ParseVariableDeclarations( | 1922 Block* Parser::ParseVariableDeclarations( |
1822 VariableDeclarationContext var_context, | 1923 VariableDeclarationContext var_context, |
1823 VariableDeclarationProperties* decl_props, | 1924 VariableDeclarationProperties* decl_props, |
| 1925 ZoneStringList* names, |
1824 Handle<String>* out, | 1926 Handle<String>* out, |
1825 bool* ok) { | 1927 bool* ok) { |
1826 // VariableDeclarations :: | 1928 // VariableDeclarations :: |
1827 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] | 1929 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] |
1828 // | 1930 // |
1829 // The ES6 Draft Rev3 specifies the following grammar for const declarations | 1931 // The ES6 Draft Rev3 specifies the following grammar for const declarations |
1830 // | 1932 // |
1831 // ConstDeclaration :: | 1933 // ConstDeclaration :: |
1832 // const ConstBinding (',' ConstBinding)* ';' | 1934 // const ConstBinding (',' ConstBinding)* ';' |
1833 // ConstBinding :: | 1935 // ConstBinding :: |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1958 Declaration* declaration = | 2060 Declaration* declaration = |
1959 factory()->NewVariableDeclaration(proxy, mode, top_scope_); | 2061 factory()->NewVariableDeclaration(proxy, mode, top_scope_); |
1960 Declare(declaration, mode != VAR, CHECK_OK); | 2062 Declare(declaration, mode != VAR, CHECK_OK); |
1961 nvars++; | 2063 nvars++; |
1962 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { | 2064 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { |
1963 ReportMessageAt(scanner().location(), "too_many_variables", | 2065 ReportMessageAt(scanner().location(), "too_many_variables", |
1964 Vector<const char*>::empty()); | 2066 Vector<const char*>::empty()); |
1965 *ok = false; | 2067 *ok = false; |
1966 return NULL; | 2068 return NULL; |
1967 } | 2069 } |
| 2070 if (names) names->Add(name); |
1968 | 2071 |
1969 // Parse initialization expression if present and/or needed. A | 2072 // Parse initialization expression if present and/or needed. A |
1970 // declaration of the form: | 2073 // declaration of the form: |
1971 // | 2074 // |
1972 // var v = x; | 2075 // var v = x; |
1973 // | 2076 // |
1974 // is syntactic sugar for: | 2077 // is syntactic sugar for: |
1975 // | 2078 // |
1976 // var v; v = x; | 2079 // var v; v = x; |
1977 // | 2080 // |
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2610 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); | 2713 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); |
2611 top_scope_ = for_scope; | 2714 top_scope_ = for_scope; |
2612 | 2715 |
2613 Expect(Token::FOR, CHECK_OK); | 2716 Expect(Token::FOR, CHECK_OK); |
2614 Expect(Token::LPAREN, CHECK_OK); | 2717 Expect(Token::LPAREN, CHECK_OK); |
2615 for_scope->set_start_position(scanner().location().beg_pos); | 2718 for_scope->set_start_position(scanner().location().beg_pos); |
2616 if (peek() != Token::SEMICOLON) { | 2719 if (peek() != Token::SEMICOLON) { |
2617 if (peek() == Token::VAR || peek() == Token::CONST) { | 2720 if (peek() == Token::VAR || peek() == Token::CONST) { |
2618 Handle<String> name; | 2721 Handle<String> name; |
2619 Block* variable_statement = | 2722 Block* variable_statement = |
2620 ParseVariableDeclarations(kForStatement, NULL, &name, CHECK_OK); | 2723 ParseVariableDeclarations(kForStatement, NULL, NULL, &name, CHECK_OK); |
2621 | 2724 |
2622 if (peek() == Token::IN && !name.is_null()) { | 2725 if (peek() == Token::IN && !name.is_null()) { |
2623 VariableProxy* each = top_scope_->NewUnresolved(factory(), name); | 2726 VariableProxy* each = top_scope_->NewUnresolved(factory(), name); |
2624 ForInStatement* loop = factory()->NewForInStatement(labels); | 2727 ForInStatement* loop = factory()->NewForInStatement(labels); |
2625 Target target(&this->target_stack_, loop); | 2728 Target target(&this->target_stack_, loop); |
2626 | 2729 |
2627 Expect(Token::IN, CHECK_OK); | 2730 Expect(Token::IN, CHECK_OK); |
2628 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2731 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2629 Expect(Token::RPAREN, CHECK_OK); | 2732 Expect(Token::RPAREN, CHECK_OK); |
2630 | 2733 |
2631 Statement* body = ParseStatement(NULL, CHECK_OK); | 2734 Statement* body = ParseStatement(NULL, CHECK_OK); |
2632 loop->Initialize(each, enumerable, body); | 2735 loop->Initialize(each, enumerable, body); |
2633 Block* result = factory()->NewBlock(NULL, 2, false); | 2736 Block* result = factory()->NewBlock(NULL, 2, false); |
2634 result->AddStatement(variable_statement); | 2737 result->AddStatement(variable_statement); |
2635 result->AddStatement(loop); | 2738 result->AddStatement(loop); |
2636 top_scope_ = saved_scope; | 2739 top_scope_ = saved_scope; |
2637 for_scope->set_end_position(scanner().location().end_pos); | 2740 for_scope->set_end_position(scanner().location().end_pos); |
2638 for_scope = for_scope->FinalizeBlockScope(); | 2741 for_scope = for_scope->FinalizeBlockScope(); |
2639 ASSERT(for_scope == NULL); | 2742 ASSERT(for_scope == NULL); |
2640 // Parsed for-in loop w/ variable/const declaration. | 2743 // Parsed for-in loop w/ variable/const declaration. |
2641 return result; | 2744 return result; |
2642 } else { | 2745 } else { |
2643 init = variable_statement; | 2746 init = variable_statement; |
2644 } | 2747 } |
2645 } else if (peek() == Token::LET) { | 2748 } else if (peek() == Token::LET) { |
2646 Handle<String> name; | 2749 Handle<String> name; |
2647 VariableDeclarationProperties decl_props = kHasNoInitializers; | 2750 VariableDeclarationProperties decl_props = kHasNoInitializers; |
2648 Block* variable_statement = | 2751 Block* variable_statement = |
2649 ParseVariableDeclarations(kForStatement, &decl_props, &name, CHECK_OK); | 2752 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
| 2753 CHECK_OK); |
2650 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; | 2754 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; |
2651 if (peek() == Token::IN && accept_IN) { | 2755 if (peek() == Token::IN && accept_IN) { |
2652 // Rewrite a for-in statement of the form | 2756 // Rewrite a for-in statement of the form |
2653 // | 2757 // |
2654 // for (let x in e) b | 2758 // for (let x in e) b |
2655 // | 2759 // |
2656 // into | 2760 // into |
2657 // | 2761 // |
2658 // <let x' be a temporary variable> | 2762 // <let x' be a temporary variable> |
2659 // for (x' in e) { | 2763 // for (x' in e) { |
(...skipping 1909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4569 } | 4673 } |
4570 if (scanner().HasAnyLineTerminatorBeforeNext() || | 4674 if (scanner().HasAnyLineTerminatorBeforeNext() || |
4571 tok == Token::RBRACE || | 4675 tok == Token::RBRACE || |
4572 tok == Token::EOS) { | 4676 tok == Token::EOS) { |
4573 return; | 4677 return; |
4574 } | 4678 } |
4575 Expect(Token::SEMICOLON, ok); | 4679 Expect(Token::SEMICOLON, ok); |
4576 } | 4680 } |
4577 | 4681 |
4578 | 4682 |
| 4683 void Parser::ExpectContextualKeyword(const char* keyword, bool* ok) { |
| 4684 Expect(Token::IDENTIFIER, ok); |
| 4685 if (!*ok) return; |
| 4686 Handle<String> symbol = GetSymbol(ok); |
| 4687 if (!*ok) return; |
| 4688 if (!symbol->IsEqualTo(CStrVector(keyword))) { |
| 4689 *ok = false; |
| 4690 ReportUnexpectedToken(scanner().current_token()); |
| 4691 } |
| 4692 } |
| 4693 |
| 4694 |
4579 Literal* Parser::GetLiteralUndefined() { | 4695 Literal* Parser::GetLiteralUndefined() { |
4580 return factory()->NewLiteral(isolate()->factory()->undefined_value()); | 4696 return factory()->NewLiteral(isolate()->factory()->undefined_value()); |
4581 } | 4697 } |
4582 | 4698 |
4583 | 4699 |
4584 Literal* Parser::GetLiteralTheHole() { | 4700 Literal* Parser::GetLiteralTheHole() { |
4585 return factory()->NewLiteral(isolate()->factory()->the_hole_value()); | 4701 return factory()->NewLiteral(isolate()->factory()->the_hole_value()); |
4586 } | 4702 } |
4587 | 4703 |
4588 | 4704 |
(...skipping 1220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5809 ASSERT(info->isolate()->has_pending_exception()); | 5925 ASSERT(info->isolate()->has_pending_exception()); |
5810 } else { | 5926 } else { |
5811 result = parser.ParseProgram(info); | 5927 result = parser.ParseProgram(info); |
5812 } | 5928 } |
5813 } | 5929 } |
5814 info->SetFunction(result); | 5930 info->SetFunction(result); |
5815 return (result != NULL); | 5931 return (result != NULL); |
5816 } | 5932 } |
5817 | 5933 |
5818 } } // namespace v8::internal | 5934 } } // namespace v8::internal |
OLD | NEW |