src/compiler/Parser.cpp
changeset 258 241d082d6d89
parent 257 9db4cc815ebc
child 261 219b49bf4a03
     1.1 --- a/src/compiler/Parser.cpp	Sun Jan 06 13:56:56 2013 -0800
     1.2 +++ b/src/compiler/Parser.cpp	Sat Jan 12 16:13:46 2013 -0800
     1.3 @@ -1240,13 +1240,19 @@
     1.4  }
     1.5  
     1.6  ImportStatement *
     1.7 -Parser::import()
     1.8 +Parser::import(TokenKind kind)
     1.9  {
    1.10      SourcePosition pos = scanner_.begin();
    1.11  
    1.12 -    // import       ::= import_path
    1.13 -    // import_path  ::= name |
    1.14 -    //                  name "." import_path
    1.15 +    // import       ::= "from" import_path "import" import_names
    1.16 +    //                | "import" import_path
    1.17 +    //                | "import" import_path ".*"
    1.18 +    // import_path  ::= name
    1.19 +    //                | name "." import_path
    1.20 +    // import_names ::= "*"
    1.21 +    //                | import_name_list
    1.22 +    // import_name_list ::= name
    1.23 +    //                    | name "," import_name_list
    1.24  
    1.25      Local<String> name(zone_, expectName());
    1.26      if (!name)
    1.27 @@ -1255,7 +1261,16 @@
    1.28      PathComponent *root = new (pool_) PathComponent(NewScopedRoot<String>(pool_, name), NULL);
    1.29      PathComponent *current = root;
    1.30  
    1.31 +    // NULL namelist means that we do not import any names. An empty namelist
    1.32 +    // means we import all names.
    1.33 +    NameList *names = NULL;
    1.34 +
    1.35      while (match(TOK_DOT)) {
    1.36 +        if (kind == TOK_IMPORT && match(TOK_STAR)) {
    1.37 +            names = new (pool_) NameList();
    1.38 +            break;
    1.39 +        }
    1.40 +
    1.41          if ((name = expectName()) == NULL)
    1.42              return NULL;
    1.43  
    1.44 @@ -1263,7 +1278,31 @@
    1.45          current = current->next;
    1.46      }
    1.47  
    1.48 -    return new (pool_) ImportStatement(pos, root);
    1.49 +    if (kind == TOK_FROM) {
    1.50 +        if (!expect(TOK_IMPORT))
    1.51 +            return NULL;
    1.52 +
    1.53 +        names = new (pool_) NameList();
    1.54 +
    1.55 +        if (!match(TOK_STAR)) {
    1.56 +            if (!matchName(name.address())) {
    1.57 +                cc_.reportError(scanner_.begin(), Message_BadImportFrom);
    1.58 +                return NULL;
    1.59 +            }
    1.60 +
    1.61 +            if (!name || !names->append(NewScopedRoot<String>(pool_, name)))
    1.62 +                return NULL;
    1.63 +
    1.64 +            while (match(TOK_COMMA)) {
    1.65 +                if ((name = expectName()) == NULL)
    1.66 +                    return NULL;
    1.67 +                if (!names->append(NewScopedRoot<String>(pool_, name)))
    1.68 +                    return NULL;
    1.69 +            }
    1.70 +        }
    1.71 +    }
    1.72 +
    1.73 +    return new (pool_) ImportStatement(pos, root, names);
    1.74  }
    1.75  
    1.76  Statement *
    1.77 @@ -1391,12 +1430,13 @@
    1.78                  return NULL;
    1.79              break;
    1.80  
    1.81 +          case TOK_FROM:
    1.82            case TOK_IMPORT:
    1.83            {
    1.84              scanner_.scan();
    1.85              if (statements->length())
    1.86                  cc_.reportError(scanner_.begin(), Message_ImportsMustBeFirst);
    1.87 -            ImportStatement *stmt = import();
    1.88 +            ImportStatement *stmt = import(kind);
    1.89              if (!stmt)
    1.90                  return NULL;
    1.91              if (!imports_->append(stmt))