1.1 --- a/src/compiler/NameBinding.cpp Sun Jan 06 13:56:56 2013 -0800
1.2 +++ b/src/compiler/NameBinding.cpp Sat Jan 12 16:13:46 2013 -0800
1.3 @@ -217,6 +217,11 @@
1.4 TypeSymbol *sym = new (pool_) TypeSymbol(scope, name, type);
1.5 if (!registerName(scope, sym))
1.6 return;
1.7 +
1.8 + if (scope->kind() == Scope::GLOBAL) {
1.9 + if (!unit_->globalScope()->exported()->append(sym))
1.10 + return;
1.11 + }
1.12 }
1.13
1.14 int value = 0;
1.15 @@ -236,6 +241,10 @@
1.16 ConstantSymbol *sym = new (pool_) ConstantSymbol(scope, entry.name, entry.pos, type, box);
1.17 if (!registerName(scope, sym))
1.18 return;
1.19 + if (scope->kind() == Scope::GLOBAL) {
1.20 + if (!unit_->globalScope()->exported()->append(sym))
1.21 + return;
1.22 + }
1.23
1.24 value++;
1.25 }
1.26 @@ -262,6 +271,9 @@
1.27 {
1.28 // We're in the global scope, for sure.
1.29 assert(env_->scope()->kind() == Scope::GLOBAL);
1.30 +
1.31 + if (!unit_->globalScope()->exported()->append(sym))
1.32 + return;
1.33 }
1.34
1.35 node->setSymbol(sym);
1.36 @@ -504,7 +516,6 @@
1.37 {
1.38 }
1.39
1.40 -
1.41 protected:
1.42 Type *buildVariableType(VariableDeclaration *node) {
1.43 Local<Type> type(zone_, bindType(node->type(), node->quals()));
1.44 @@ -762,7 +773,8 @@
1.45 {
1.46 public:
1.47 GlobalBuilder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.48 - : NameBinderBase(zone, cc, unit)
1.49 + : NameBinderBase(zone, cc, unit),
1.50 + globalScope_(unit->globalScope())
1.51 {
1.52 }
1.53
1.54 @@ -796,9 +808,10 @@
1.55 }
1.56
1.57 void visitNameProxy(NameProxy *proxy) {
1.58 - // Don't report errors here, since we'll report them later.
1.59 Scope *scope = unit_->globalScope();
1.60 Symbol *sym = scope->lookup(proxy->name());
1.61 + if (!sym)
1.62 + cc_.reportError(proxy->pos(), Message_IdentifierNotFound, proxy->name()->chars());
1.63 proxy->bind(sym);
1.64 }
1.65
1.66 @@ -850,8 +863,7 @@
1.67 }
1.68
1.69 void visitImportStatement(ImportStatement *node) {
1.70 - // Eventually we'll handle |from| style imports as well.
1.71 - {
1.72 + if (!node->names()) {
1.73 PathComponent *path = node->path();
1.74 while (path->next)
1.75 path = path->next;
1.76 @@ -868,12 +880,48 @@
1.77 ImportSymbol *sym = new (pool_) ImportSymbol(unit_->importScope(), path->name, node->pos(), type, node->importIndex());
1.78 if (!unit_->importScope()->addSymbol(sym))
1.79 return;
1.80 + } else if (node->importAllNames()) {
1.81 + Local<Importable> importable(zone_, unit_->module()->getImportAt(node->importIndex()));
1.82 + if (importable->isPackage()) {
1.83 + assert(false);
1.84 + } else {
1.85 + Local<Module> module(zone_, Module::cast(importable));
1.86 + if (!module->globals())
1.87 + importAllFromTranslationUnit(node, module, module->translationUnit());
1.88 + else
1.89 + assert(false);
1.90 + }
1.91 + }
1.92 + }
1.93 +
1.94 + private:
1.95 + void importAllFromTranslationUnit(ImportStatement *node, Handle<Module> module, TranslationUnit *other) {
1.96 + assert(!other->failed());
1.97 +
1.98 + for (size_t i = 0; i < other->globalScope()->exported()->length(); i++) {
1.99 + Symbol *import = other->globalScope()->exported()->at(i);
1.100 + assert(import->type());
1.101 +
1.102 + // Check for duplicate import names.
1.103 + if (unit_->importScope()->localLookup(import->name())) {
1.104 + cc_.reportError(node->pos(), Message_DuplicateImport, import->name()->chars());
1.105 + return;
1.106 + }
1.107 +
1.108 + ImplicitSymbol *sym = new (pool_) ImplicitSymbol(unit_->importScope(),
1.109 + import->name(),
1.110 + node->pos(),
1.111 + import->type(),
1.112 + node->importIndex());
1.113 + if (!unit_->importScope()->addSymbol(sym))
1.114 + return;
1.115 }
1.116 }
1.117
1.118 private:
1.119 StructureBufferBuilder builder_;
1.120 Vector<ScopedRoot<Descriptor> *> descriptors_;
1.121 + GlobalScope *globalScope_;
1.122 };
1.123
1.124 class NameBinder : public NameBinderBase
1.125 @@ -1093,21 +1141,22 @@
1.126 };
1.127
1.128 void
1.129 -ke::BindNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.130 +ke::BindGlobals(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.131 {
1.132 AutoEnterCompileContext enter(cc, unit);
1.133
1.134 - // Because of the way globals work in Pawn, we need a precursor step to
1.135 - // actually enter global symbols into the global struct. They're already
1.136 - // in the global symbol table, so we know they won't clash. This process
1.137 - // also binds any remaining types on global variables.
1.138 GlobalBuilder builder(zone, cc, unit);
1.139 Local<Struct> globals(zone, builder.build());
1.140 if (!globals || unit->failed())
1.141 return;
1.142
1.143 unit->module()->setGlobals(globals);
1.144 +}
1.145
1.146 +void
1.147 +ke::BindNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.148 +{
1.149 + AutoEnterCompileContext enter(cc, unit);
1.150 NameBinder binder(zone, cc, unit);
1.151 binder.bind();
1.152 }