# HG changeset patch # User David Anderson # Date 1358036769 28800 # Node ID 99ab8b19f0b9a0399ec2d35fc85c218ad12535c6 # Parent 241d082d6d894ac768718bd0e86ffe9fab451a4e Add |from x import names| support. diff -r 241d082d6d89 -r 99ab8b19f0b9 src/Messages.tbl --- a/src/Messages.tbl Sat Jan 12 16:13:46 2013 -0800 +++ b/src/Messages.tbl Sat Jan 12 16:26:09 2013 -0800 @@ -91,4 +91,5 @@ MSG(PackageDoesNotHaveMember, TypeError, "package does not have member '%s' (check imports)") MSG(ImportWasNeverImported, TypeError, "'%s' was never imported") MSG(FieldNotFound, TypeError, "field '%s' not found") -MSG(BadImportFrom, TypeError, "expected '*' or ") \ No newline at end of file +MSG(BadImportFrom, TypeError, "expected '*' or ") +MSG(NotFoundInImportable, TypeError, "name '%s' was not found in import '%s'") diff -r 241d082d6d89 -r 99ab8b19f0b9 src/compiler/NameBinding.cpp --- a/src/compiler/NameBinding.cpp Sat Jan 12 16:13:46 2013 -0800 +++ b/src/compiler/NameBinding.cpp Sat Jan 12 16:26:09 2013 -0800 @@ -887,7 +887,18 @@ } else { Local module(zone_, Module::cast(importable)); if (!module->globals()) - importAllFromTranslationUnit(node, module, module->translationUnit()); + importAllFromTranslationUnit(node, module->translationUnit()); + else + assert(false); + } + } else { + Local importable(zone_, unit_->module()->getImportAt(node->importIndex())); + if (importable->isPackage()) { + assert(false); + } else { + Local module(zone_, Module::cast(importable)); + if (!module->globals()) + importFromTranslationUnit(node, module->translationUnit()); else assert(false); } @@ -895,25 +906,53 @@ } private: - void importAllFromTranslationUnit(ImportStatement *node, Handle module, TranslationUnit *other) { + bool importFrom(ImportStatement *node, Symbol *import) { + assert(import->type()); + + // Check for duplicate import names. + if (unit_->importScope()->localLookup(import->name())) { + cc_.reportError(node->pos(), Message_DuplicateImport, import->name()->chars()); + return false; + } + + ImplicitSymbol *sym = new (pool_) ImplicitSymbol(unit_->importScope(), + import->name(), + node->pos(), + import->type(), + node->importIndex()); + if (!unit_->importScope()->addSymbol(sym)) + return false; + + return true; + } + + void importFromTranslationUnit(ImportStatement *node, TranslationUnit *other) { + assert(!other->failed()); + + for (size_t i = 0; i < node->names()->length(); i++) { + Handle name = *node->names()->at(i); + + // See if the name exists in the other translation unit. + Symbol *import = other->globalScope()->findExported(name); + if (!import) { + FixedArray *path = unit_->module()->importPathAt(node->importIndex()); + cc_.reportError(node->pos(), Message_NotFoundInImportable, + name->chars(), + String::cast(path->at(path->length() - 1))->chars()); + return; + } + + if (!importFrom(node, import)) + return; + } + } + + void importAllFromTranslationUnit(ImportStatement *node, TranslationUnit *other) { assert(!other->failed()); for (size_t i = 0; i < other->globalScope()->exported()->length(); i++) { Symbol *import = other->globalScope()->exported()->at(i); - assert(import->type()); - - // Check for duplicate import names. - if (unit_->importScope()->localLookup(import->name())) { - cc_.reportError(node->pos(), Message_DuplicateImport, import->name()->chars()); - return; - } - - ImplicitSymbol *sym = new (pool_) ImplicitSymbol(unit_->importScope(), - import->name(), - node->pos(), - import->type(), - node->importIndex()); - if (!unit_->importScope()->addSymbol(sym)) + if (!importFrom(node, import)) return; } } diff -r 241d082d6d89 -r 99ab8b19f0b9 src/compiler/Scopes.cpp --- a/src/compiler/Scopes.cpp Sat Jan 12 16:13:46 2013 -0800 +++ b/src/compiler/Scopes.cpp Sat Jan 12 16:26:09 2013 -0800 @@ -168,6 +168,16 @@ return scope; } +Symbol * +GlobalScope::findExported(Handle name) +{ + for (size_t i = 0; i < exported_.length(); i++) { + if (exported_[i]->name() == name) + return exported_[i]; + } + return NULL; +} + ImportScope::ImportScope(PoolAllocator &pool) : Scope(pool, Scope::IMPORT, NULL) { diff -r 241d082d6d89 -r 99ab8b19f0b9 src/compiler/Scopes.h --- a/src/compiler/Scopes.h Sat Jan 12 16:13:46 2013 -0800 +++ b/src/compiler/Scopes.h Sat Jan 12 16:26:09 2013 -0800 @@ -104,6 +104,7 @@ PoolList *exported() { return &exported_; } + Symbol *findExported(Handle name); private: GlobalScope(PoolAllocator &pool, ImportScope *parent); diff -r 241d082d6d89 -r 99ab8b19f0b9 src/compiler/SemanticAnalysis.cpp --- a/src/compiler/SemanticAnalysis.cpp Sat Jan 12 16:13:46 2013 -0800 +++ b/src/compiler/SemanticAnalysis.cpp Sat Jan 12 16:26:09 2013 -0800 @@ -717,7 +717,6 @@ } else { Local actual(zone_, fun->parameterAt(i)); - if (expression->isIndexExpression() && arg->isIndex()) { // If the expression is the form x[y], and this produced a // normal array indexing operation, then we apply some diff -r 241d082d6d89 -r 99ab8b19f0b9 tests/basic/import-sysroot-select.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/basic/import-sysroot-select.out Sat Jan 12 16:26:09 2013 -0800 @@ -0,0 +1,1 @@ +5 is 5.000000 diff -r 241d082d6d89 -r 99ab8b19f0b9 tests/basic/import-sysroot-select.sp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/basic/import-sysroot-select.sp Sat Jan 12 16:26:09 2013 -0800 @@ -0,0 +1,9 @@ +from shell import PrintNum, PrintString, PrintFloat; + +public main() +{ + PrintNum(5); + PrintString(" is "); + PrintFloat(5.0); +} +