Make 'module' a context-sensitive keyword.
authorrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 24 Feb 2012 15:53:09 +0000 (15:53 +0000)
committerrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 24 Feb 2012 15:53:09 +0000 (15:53 +0000)
Baseline: http://codereview.chromium.org/9401008/

R=lrn@chromium.org,mstarzinger@chromium.org
BUG=v8:1957
TEST=mjsunit/harmony/module-parsing

Review URL: https://chromiumcodereview.appspot.com/9422001

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10832 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/heap.h
src/parser.cc
src/scanner.cc
src/token.h
test/mjsunit/harmony/module-parsing.js

index 3a3c8f4695ef43225f30cbf21dcea5a1eac7cdfe..70c3146be204d1389a0adf635f0764f8ca7f314a 100644 (file)
@@ -177,6 +177,7 @@ namespace internal {
   V(eval_symbol, "eval")                                                 \
   V(function_symbol, "function")                                         \
   V(length_symbol, "length")                                             \
+  V(module_symbol, "module")                                             \
   V(name_symbol, "name")                                                 \
   V(native_symbol, "native")                                             \
   V(null_symbol, "null")                                                 \
index 3dfab294c8b4610c98c3db3edeac3469c8d767ba..f0556cb35531f2e3feea74bf7a708356ccea6d73 100644 (file)
@@ -1188,14 +1188,28 @@ Statement* Parser::ParseModuleElement(ZoneStringList* labels,
     case Token::LET:
     case Token::CONST:
       return ParseVariableStatement(kModuleElement, ok);
-    case Token::MODULE:
-      return ParseModuleDeclaration(ok);
     case Token::IMPORT:
       return ParseImportDeclaration(ok);
     case Token::EXPORT:
       return ParseExportDeclaration(ok);
-    default:
-      return ParseStatement(labels, ok);
+    default: {
+      Statement* stmt = ParseStatement(labels, CHECK_OK);
+      // Handle 'module' as a context-sensitive keyword.
+      if (FLAG_harmony_modules &&
+          peek() == Token::IDENTIFIER &&
+          !scanner().HasAnyLineTerminatorBeforeNext() &&
+          stmt != NULL) {
+        ExpressionStatement* estmt = stmt->AsExpressionStatement();
+        if (estmt != NULL &&
+            estmt->expression()->AsVariableProxy() != NULL &&
+            estmt->expression()->AsVariableProxy()->name()->Equals(
+                isolate()->heap()->module_symbol()) &&
+            !scanner().literal_contains_escapes()) {
+          return ParseModuleDeclaration(ok);
+        }
+      }
+      return stmt;
+    }
   }
 }
 
@@ -1206,7 +1220,6 @@ Block* Parser::ParseModuleDeclaration(bool* ok) {
 
   // Create new block with one expected declaration.
   Block* block = factory()->NewBlock(NULL, 1, true);
-  Expect(Token::MODULE, CHECK_OK);
   Handle<String> name = ParseIdentifier(CHECK_OK);
   // top_scope_->AddDeclaration(
   //     factory()->NewModuleDeclaration(proxy, module, top_scope_));
@@ -2172,8 +2185,17 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
     return ParseNativeDeclaration(ok);
   }
 
-  // Parsed expression statement.
-  ExpectSemicolon(CHECK_OK);
+  // Parsed expression statement, or the context-sensitive 'module' keyword.
+  // Only expect semicolon in the former case.
+  if (!FLAG_harmony_modules ||
+      peek() != Token::IDENTIFIER ||
+      scanner().HasAnyLineTerminatorBeforeNext() ||
+      expr->AsVariableProxy() == NULL ||
+      !expr->AsVariableProxy()->name()->Equals(
+          isolate()->heap()->module_symbol()) ||
+      scanner().literal_contains_escapes()) {
+    ExpectSemicolon(CHECK_OK);
+  }
   return factory()->NewExpressionStatement(expr);
 }
 
index 42a1c2bc31e93cd0cd859d1fc461bb03b9732585..72768b381b4b085e5a0281093b44b76b92a38b31 100755 (executable)
@@ -850,9 +850,6 @@ uc32 Scanner::ScanIdentifierUnicodeEscape() {
   KEYWORD_GROUP('l')                                                \
   KEYWORD("let", harmony_scoping                                    \
                  ? Token::LET : Token::FUTURE_STRICT_RESERVED_WORD) \
-  KEYWORD_GROUP('m')                                                \
-  KEYWORD("module", harmony_modules                                 \
-                    ? Token::MODULE : Token::IDENTIFIER)            \
   KEYWORD_GROUP('n')                                                \
   KEYWORD("new", Token::NEW)                                        \
   KEYWORD("null", Token::NULL_LITERAL)                              \
index b305c88a30fd3a852d8452468910b4495249dc47..1eeb60d876607173885bed61a64e279fd08a6a93 100644 (file)
@@ -173,7 +173,6 @@ namespace internal {
   K(EXPORT, "export", 0)                                                \
   K(IMPORT, "import", 0)                                                \
   K(LET, "let", 0)                                                      \
-  K(MODULE, "module", 0)                                                \
                                                                         \
   /* Illegal token - not able to scan. */                               \
   T(ILLEGAL, "ILLEGAL", 0)                                              \
index ac398636da852a2f1daaedf7187c892ee5eac38a..5a5e82fdb17f34d4a0d18882a4002b58c1b0a862 100644 (file)
@@ -63,18 +63,28 @@ module E3 = E1.F
 
 // Check that ASI does not interfere.
 
-module
-X
+module X
 {
 let x
 }
 
-module
-Y
+module Y
 =
 X
 
-module
-Z
+module Z
 at
 "file://local"
+
+
+// Check that 'module' still works as an identifier.
+
+var module
+module = {}
+module["a"] = 6
+function module() {}
+function f(module) { return module }
+try {} catch (module) {}
+
+module
+v = 20