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

Side by Side Diff: src/parser.cc

Issue 9496003: AST extensions and parsing for import & export declarations. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/prettyprinter.cc » ('j') | test/mjsunit/harmony/module-parsing.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698