diff -r 9db4cc815ebc -r 241d082d6d89 src/compiler/Parser.cpp --- a/src/compiler/Parser.cpp Sun Jan 06 13:56:56 2013 -0800 +++ b/src/compiler/Parser.cpp Sat Jan 12 16:13:46 2013 -0800 @@ -1240,13 +1240,19 @@ } ImportStatement * -Parser::import() +Parser::import(TokenKind kind) { SourcePosition pos = scanner_.begin(); - // import ::= import_path - // import_path ::= name | - // name "." import_path + // import ::= "from" import_path "import" import_names + // | "import" import_path + // | "import" import_path ".*" + // import_path ::= name + // | name "." import_path + // import_names ::= "*" + // | import_name_list + // import_name_list ::= name + // | name "," import_name_list Local name(zone_, expectName()); if (!name) @@ -1255,7 +1261,16 @@ PathComponent *root = new (pool_) PathComponent(NewScopedRoot(pool_, name), NULL); PathComponent *current = root; + // NULL namelist means that we do not import any names. An empty namelist + // means we import all names. + NameList *names = NULL; + while (match(TOK_DOT)) { + if (kind == TOK_IMPORT && match(TOK_STAR)) { + names = new (pool_) NameList(); + break; + } + if ((name = expectName()) == NULL) return NULL; @@ -1263,7 +1278,31 @@ current = current->next; } - return new (pool_) ImportStatement(pos, root); + if (kind == TOK_FROM) { + if (!expect(TOK_IMPORT)) + return NULL; + + names = new (pool_) NameList(); + + if (!match(TOK_STAR)) { + if (!matchName(name.address())) { + cc_.reportError(scanner_.begin(), Message_BadImportFrom); + return NULL; + } + + if (!name || !names->append(NewScopedRoot(pool_, name))) + return NULL; + + while (match(TOK_COMMA)) { + if ((name = expectName()) == NULL) + return NULL; + if (!names->append(NewScopedRoot(pool_, name))) + return NULL; + } + } + } + + return new (pool_) ImportStatement(pos, root, names); } Statement * @@ -1391,12 +1430,13 @@ return NULL; break; + case TOK_FROM: case TOK_IMPORT: { scanner_.scan(); if (statements->length()) cc_.reportError(scanner_.begin(), Message_ImportsMustBeFirst); - ImportStatement *stmt = import(); + ImportStatement *stmt = import(kind); if (!stmt) return NULL; if (!imports_->append(stmt))