Reviewers: Michael Starzinger,
Description:
Extend scanner with new Harmony module keywords (under flag).
[email protected]
BUG=
TEST=
Please review this at https://chromiumcodereview.appspot.com/9352013/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/flag-definitions.h
M src/parser.h
M src/parser.cc
M src/preparser.h
M src/scanner.h
M src/scanner.cc
M src/token.h
M test/cctest/test-parsing.cc
Index: src/flag-definitions.h
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index
9cdea067254f2edab1bdb6ce9cc34b8dc8d2e5a9..d087d1a491e6567c773d64ad6a20224010760239
100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -109,11 +109,13 @@ private:
// Flags for experimental language features.
DEFINE_bool(harmony_typeof, false, "enable harmony semantics for typeof")
DEFINE_bool(harmony_scoping, false, "enable harmony block scoping")
+DEFINE_bool(harmony_modules, false, "enable harmony modules")
DEFINE_bool(harmony_proxies, false, "enable harmony proxies")
DEFINE_bool(harmony_collections, false,
"enable harmony collections (sets, maps, and weak maps)")
DEFINE_bool(harmony, false, "enable all harmony features (except typeof)")
DEFINE_implication(harmony, harmony_scoping)
+DEFINE_implication(harmony, harmony_modules)
DEFINE_implication(harmony, harmony_proxies)
DEFINE_implication(harmony, harmony_collections)
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index
5be1a6dc2b98ae4874b9a762c8ca2ac8a98272aa..3615f2298794d12de8b3bc9d3a3ad3078fa8bf1a
100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -602,12 +602,16 @@ Parser::Parser(Handle<Script> script,
fni_(NULL),
allow_natives_syntax_((parser_flags & kAllowNativesSyntax) != 0),
allow_lazy_((parser_flags & kAllowLazy) != 0),
+ allow_modules_((parser_flags & kAllowModules) != 0),
stack_overflow_(false),
parenthesized_function_(false) {
AstNode::ResetIds();
if ((parser_flags & kLanguageModeMask) == EXTENDED_MODE) {
scanner().SetHarmonyScoping(true);
}
+ if ((parser_flags & kAllowModules) != 0) {
+ scanner().SetHarmonyModules(true);
+ }
}
@@ -4343,7 +4347,8 @@ preparser::PreParser::PreParseResult
Parser::LazyParseFunctionLiteral(
NULL,
stack_limit,
do_allow_lazy,
- allow_natives_syntax_);
+ allow_natives_syntax_,
+ allow_modules_);
}
preparser::PreParser::PreParseResult result =
reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(),
@@ -5665,6 +5670,9 @@ bool ParserApi::Parse(CompilationInfo* info, int
parsing_flags) {
// Harmony scoping is requested.
parsing_flags |= EXTENDED_MODE;
}
+ if (!info->is_native() && FLAG_harmony_modules) {
+ parsing_flags |= kAllowModules;
+ }
if (FLAG_allow_natives_syntax || info->is_native()) {
// We requre %identifier(..) syntax.
parsing_flags |= kAllowNativesSyntax;
Index: src/parser.h
diff --git a/src/parser.h b/src/parser.h
index
16c2eff6d3a45a62c11cba0a93a564cb5667f649..5dcb75a4f90dec7e33050c999112828001e4215e
100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -762,6 +762,7 @@ class Parser {
Mode mode_;
bool allow_natives_syntax_;
bool allow_lazy_;
+ bool allow_modules_;
bool stack_overflow_;
// If true, the next (and immediately following) function literal is
// preceded by a parenthesis.
Index: src/preparser.h
diff --git a/src/preparser.h b/src/preparser.h
index
f17bac2eac81ff399c3ac535040be7dee0a2f25c..886d81a9e600d069c7c913f7914f5c6360e5ba55
100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -115,7 +115,8 @@ class PreParser {
i::ParserRecorder* log,
uintptr_t stack_limit,
bool allow_lazy,
- bool allow_natives_syntax)
+ bool allow_natives_syntax,
+ bool allow_modules)
: scanner_(scanner),
log_(log),
scope_(NULL),
@@ -124,6 +125,7 @@ class PreParser {
strict_mode_violation_type_(NULL),
stack_overflow_(false),
allow_lazy_(allow_lazy),
+ allow_modules_(allow_modules),
allow_natives_syntax_(allow_natives_syntax),
parenthesized_function_(false),
harmony_scoping_(scanner->HarmonyScoping()) { }
@@ -140,8 +142,9 @@ class PreParser {
uintptr_t stack_limit) {
bool allow_lazy = (flags & i::kAllowLazy) != 0;
bool allow_natives_syntax = (flags & i::kAllowNativesSyntax) != 0;
- return PreParser(scanner, log, stack_limit,
- allow_lazy, allow_natives_syntax).PreParse();
+ bool allow_modules = (flags & i::kAllowModules) != 0;
+ return PreParser(scanner, log, stack_limit, allow_lazy,
+ allow_natives_syntax, allow_modules).PreParse();
}
// Parses a single function literal, from the opening parentheses before
@@ -647,6 +650,7 @@ class PreParser {
const char* strict_mode_violation_type_;
bool stack_overflow_;
bool allow_lazy_;
+ bool allow_modules_;
bool allow_natives_syntax_;
bool parenthesized_function_;
bool harmony_scoping_;
Index: src/scanner.cc
diff --git a/src/scanner.cc b/src/scanner.cc
index
01fe81c64646ccf1ac039ed9a9b4d2a47a1f4461..42a1c2bc31e93cd0cd859d1fc461bb03b9732585
100755
--- a/src/scanner.cc
+++ b/src/scanner.cc
@@ -41,7 +41,8 @@ namespace internal {
Scanner::Scanner(UnicodeCache* unicode_cache)
: unicode_cache_(unicode_cache),
octal_pos_(Location::invalid()),
- harmony_scoping_(false) { }
+ harmony_scoping_(false),
+ harmony_modules_(false) { }
void Scanner::Initialize(UC16CharacterStream* source) {
@@ -830,7 +831,8 @@ uc32 Scanner::ScanIdentifierUnicodeEscape() {
KEYWORD_GROUP('e') \
KEYWORD("else", Token::ELSE) \
KEYWORD("enum", Token::FUTURE_RESERVED_WORD) \
- KEYWORD("export", Token::FUTURE_RESERVED_WORD) \
+ KEYWORD("export", harmony_modules \
+ ? Token::EXPORT : Token::FUTURE_RESERVED_WORD) \
KEYWORD("extends", Token::FUTURE_RESERVED_WORD) \
KEYWORD_GROUP('f') \
KEYWORD("false", Token::FALSE_LITERAL) \
@@ -840,13 +842,17 @@ uc32 Scanner::ScanIdentifierUnicodeEscape() {
KEYWORD_GROUP('i') \
KEYWORD("if", Token::IF) \
KEYWORD("implements", Token::FUTURE_STRICT_RESERVED_WORD) \
- KEYWORD("import", Token::FUTURE_RESERVED_WORD) \
+ KEYWORD("import", harmony_modules \
+ ? Token::IMPORT : Token::FUTURE_RESERVED_WORD) \
KEYWORD("in", Token::IN) \
KEYWORD("instanceof", Token::INSTANCEOF) \
KEYWORD("interface", Token::FUTURE_STRICT_RESERVED_WORD) \
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) \
@@ -879,7 +885,8 @@ uc32 Scanner::ScanIdentifierUnicodeEscape() {
static Token::Value KeywordOrIdentifierToken(const char* input,
int input_length,
- bool harmony_scoping) {
+ bool harmony_scoping,
+ bool harmony_modules) {
ASSERT(input_length >= 1);
const int kMinLength = 2;
const int kMaxLength = 10;
@@ -955,7 +962,8 @@ Token::Value Scanner::ScanIdentifierOrKeyword() {
Vector<const char> chars = next_.literal_chars->ascii_literal();
return KeywordOrIdentifierToken(chars.start(),
chars.length(),
- harmony_scoping_);
+ harmony_scoping_,
+ harmony_modules_);
}
return Token::IDENTIFIER;
Index: src/scanner.h
diff --git a/src/scanner.h b/src/scanner.h
index
c512ec3fefb68c6ecc858b2351d62dfbd134e046..a1a377f653829e7a82d45235dd2bb741aaef612d
100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -52,7 +52,8 @@ enum ParsingFlags {
// EXTENDED_MODE,
kLanguageModeMask = 0x03,
kAllowLazy = 4,
- kAllowNativesSyntax = 8
+ kAllowNativesSyntax = 8,
+ kAllowModules = 16
};
STATIC_ASSERT((kLanguageModeMask & CLASSIC_MODE) == CLASSIC_MODE);
@@ -403,8 +404,14 @@ class Scanner {
bool HarmonyScoping() const {
return harmony_scoping_;
}
- void SetHarmonyScoping(bool block_scoping) {
- harmony_scoping_ = block_scoping;
+ void SetHarmonyScoping(bool scoping) {
+ harmony_scoping_ = scoping;
+ }
+ bool HarmonyModules() const {
+ return harmony_modules_;
+ }
+ void SetHarmonyModules(bool modules) {
+ harmony_modules_ = modules;
}
@@ -552,9 +559,10 @@ class Scanner {
// Whether there is a multi-line comment that contains a
// line-terminator after the current token, and before the next.
bool has_multiline_comment_before_next_;
- // Whether we scan 'let' as a keyword for harmony block scoped
- // let bindings.
+ // Whether we scan 'let' as a keyword for harmony block-scoped let
bindings.
bool harmony_scoping_;
+ // Whether we scan 'module', 'import', 'export', and 'from' as keywords.
+ bool harmony_modules_;
};
} } // namespace v8::internal
Index: src/token.h
diff --git a/src/token.h b/src/token.h
index
7a2156c950706a37085e728edd96dd3bc8012fca..b305c88a30fd3a852d8452468910b4495249dc47
100644
--- a/src/token.h
+++ b/src/token.h
@@ -170,7 +170,10 @@ namespace internal {
T(FUTURE_RESERVED_WORD, NULL, 0) \
T(FUTURE_STRICT_RESERVED_WORD, NULL, 0) \
K(CONST, "const", 0) \
+ 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: test/cctest/test-parsing.cc
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc
index
1b6e4ab9a15089a14edf578c2394af4e6728b866..cd8a6aff382934ae11c8ce45212e967f6c1fedd7
100755
--- a/test/cctest/test-parsing.cc
+++ b/test/cctest/test-parsing.cc
@@ -65,8 +65,9 @@ TEST(ScanKeywords) {
{
i::Utf8ToUC16CharacterStream stream(keyword, length);
i::Scanner scanner(&unicode_cache);
- // The scanner should parse 'let' as Token::LET for this test.
+ // The scanner should parse Harmony keywords for this test.
scanner.SetHarmonyScoping(true);
+ scanner.SetHarmonyModules(true);
scanner.Initialize(&stream);
CHECK_EQ(key_token.token, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next());
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev