Add |from x import names| support.
Add |from x import names| support.
1.1 --- a/src/Messages.tbl Sat Jan 12 16:13:46 2013 -0800
1.2 +++ b/src/Messages.tbl Sat Jan 12 16:26:09 2013 -0800
1.3 @@ -91,4 +91,5 @@
1.4 MSG(PackageDoesNotHaveMember, TypeError, "package does not have member '%s' (check imports)")
1.5 MSG(ImportWasNeverImported, TypeError, "'%s' was never imported")
1.6 MSG(FieldNotFound, TypeError, "field '%s' not found")
1.7 -MSG(BadImportFrom, TypeError, "expected '*' or <name>")
1.8 \ No newline at end of file
1.9 +MSG(BadImportFrom, TypeError, "expected '*' or <name>")
1.10 +MSG(NotFoundInImportable, TypeError, "name '%s' was not found in import '%s'")
2.1 --- a/src/compiler/NameBinding.cpp Sat Jan 12 16:13:46 2013 -0800
2.2 +++ b/src/compiler/NameBinding.cpp Sat Jan 12 16:26:09 2013 -0800
2.3 @@ -887,7 +887,18 @@
2.4 } else {
2.5 Local<Module> module(zone_, Module::cast(importable));
2.6 if (!module->globals())
2.7 - importAllFromTranslationUnit(node, module, module->translationUnit());
2.8 + importAllFromTranslationUnit(node, module->translationUnit());
2.9 + else
2.10 + assert(false);
2.11 + }
2.12 + } else {
2.13 + Local<Importable> importable(zone_, unit_->module()->getImportAt(node->importIndex()));
2.14 + if (importable->isPackage()) {
2.15 + assert(false);
2.16 + } else {
2.17 + Local<Module> module(zone_, Module::cast(importable));
2.18 + if (!module->globals())
2.19 + importFromTranslationUnit(node, module->translationUnit());
2.20 else
2.21 assert(false);
2.22 }
2.23 @@ -895,25 +906,53 @@
2.24 }
2.25
2.26 private:
2.27 - void importAllFromTranslationUnit(ImportStatement *node, Handle<Module> module, TranslationUnit *other) {
2.28 + bool importFrom(ImportStatement *node, Symbol *import) {
2.29 + assert(import->type());
2.30 +
2.31 + // Check for duplicate import names.
2.32 + if (unit_->importScope()->localLookup(import->name())) {
2.33 + cc_.reportError(node->pos(), Message_DuplicateImport, import->name()->chars());
2.34 + return false;
2.35 + }
2.36 +
2.37 + ImplicitSymbol *sym = new (pool_) ImplicitSymbol(unit_->importScope(),
2.38 + import->name(),
2.39 + node->pos(),
2.40 + import->type(),
2.41 + node->importIndex());
2.42 + if (!unit_->importScope()->addSymbol(sym))
2.43 + return false;
2.44 +
2.45 + return true;
2.46 + }
2.47 +
2.48 + void importFromTranslationUnit(ImportStatement *node, TranslationUnit *other) {
2.49 + assert(!other->failed());
2.50 +
2.51 + for (size_t i = 0; i < node->names()->length(); i++) {
2.52 + Handle<String> name = *node->names()->at(i);
2.53 +
2.54 + // See if the name exists in the other translation unit.
2.55 + Symbol *import = other->globalScope()->findExported(name);
2.56 + if (!import) {
2.57 + FixedArray *path = unit_->module()->importPathAt(node->importIndex());
2.58 + cc_.reportError(node->pos(), Message_NotFoundInImportable,
2.59 + name->chars(),
2.60 + String::cast(path->at(path->length() - 1))->chars());
2.61 + return;
2.62 + }
2.63 +
2.64 + if (!importFrom(node, import))
2.65 + return;
2.66 + }
2.67 + }
2.68 +
2.69 + void importAllFromTranslationUnit(ImportStatement *node, TranslationUnit *other) {
2.70 assert(!other->failed());
2.71
2.72 for (size_t i = 0; i < other->globalScope()->exported()->length(); i++) {
2.73 Symbol *import = other->globalScope()->exported()->at(i);
2.74 - assert(import->type());
2.75 -
2.76 - // Check for duplicate import names.
2.77 - if (unit_->importScope()->localLookup(import->name())) {
2.78 - cc_.reportError(node->pos(), Message_DuplicateImport, import->name()->chars());
2.79 - return;
2.80 - }
2.81 -
2.82 - ImplicitSymbol *sym = new (pool_) ImplicitSymbol(unit_->importScope(),
2.83 - import->name(),
2.84 - node->pos(),
2.85 - import->type(),
2.86 - node->importIndex());
2.87 - if (!unit_->importScope()->addSymbol(sym))
2.88 + if (!importFrom(node, import))
2.89 return;
2.90 }
2.91 }
3.1 --- a/src/compiler/Scopes.cpp Sat Jan 12 16:13:46 2013 -0800
3.2 +++ b/src/compiler/Scopes.cpp Sat Jan 12 16:26:09 2013 -0800
3.3 @@ -168,6 +168,16 @@
3.4 return scope;
3.5 }
3.6
3.7 +Symbol *
3.8 +GlobalScope::findExported(Handle<String> name)
3.9 +{
3.10 + for (size_t i = 0; i < exported_.length(); i++) {
3.11 + if (exported_[i]->name() == name)
3.12 + return exported_[i];
3.13 + }
3.14 + return NULL;
3.15 +}
3.16 +
3.17 ImportScope::ImportScope(PoolAllocator &pool)
3.18 : Scope(pool, Scope::IMPORT, NULL)
3.19 {
4.1 --- a/src/compiler/Scopes.h Sat Jan 12 16:13:46 2013 -0800
4.2 +++ b/src/compiler/Scopes.h Sat Jan 12 16:26:09 2013 -0800
4.3 @@ -104,6 +104,7 @@
4.4 PoolList<Symbol *> *exported() {
4.5 return &exported_;
4.6 }
4.7 + Symbol *findExported(Handle<String> name);
4.8
4.9 private:
4.10 GlobalScope(PoolAllocator &pool, ImportScope *parent);
5.1 --- a/src/compiler/SemanticAnalysis.cpp Sat Jan 12 16:13:46 2013 -0800
5.2 +++ b/src/compiler/SemanticAnalysis.cpp Sat Jan 12 16:26:09 2013 -0800
5.3 @@ -717,7 +717,6 @@
5.4 } else {
5.5 Local<Type> actual(zone_, fun->parameterAt(i));
5.6
5.7 -
5.8 if (expression->isIndexExpression() && arg->isIndex()) {
5.9 // If the expression is the form x[y], and this produced a
5.10 // normal array indexing operation, then we apply some
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/tests/basic/import-sysroot-select.out Sat Jan 12 16:26:09 2013 -0800
6.3 @@ -0,0 +1,1 @@
6.4 +5 is 5.000000
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/tests/basic/import-sysroot-select.sp Sat Jan 12 16:26:09 2013 -0800
7.3 @@ -0,0 +1,9 @@
7.4 +from shell import PrintNum, PrintString, PrintFloat;
7.5 +
7.6 +public main()
7.7 +{
7.8 + PrintNum(5);
7.9 + PrintString(" is ");
7.10 + PrintFloat(5.0);
7.11 +}
7.12 +