src/compiler/NameBinding.cpp
changeset 195 c1ba166f3fc4
parent 170 5e4570966ece
child 208 7c5be05296e3
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/compiler/NameBinding.cpp	Sat Nov 17 18:41:01 2012 -0800
     1.3 @@ -0,0 +1,710 @@
     1.4 +/* vim: set ts=4 sw=4 tw=99 et:
     1.5 + *
     1.6 + * Copyright (C) 2012 David Anderson
     1.7 + *
     1.8 + * This file is part of SourcePawn.
     1.9 + *
    1.10 + * SourcePawn is free software: you can redistribute it and/or modify it under
    1.11 + * the terms of the GNU General Public License as published by the Free
    1.12 + * Software Foundation, either version 3 of the License, or (at your option)
    1.13 + * any later version.
    1.14 + * 
    1.15 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    1.16 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    1.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    1.18 + *
    1.19 + * You should have received a copy of the GNU General Public License along with
    1.20 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
    1.21 + */
    1.22 +#include "../Strings.h"
    1.23 +#include "../Zone.h"
    1.24 +#include "../TypeManager.h"
    1.25 +#include "NameBinding.h"
    1.26 +#include "Scopes.h"
    1.27 +#include "../Spaces-inl.h"
    1.28 +#include "../Heap-inl.h"
    1.29 +
    1.30 +using namespace ke;
    1.31 +
    1.32 +// Create symbol tables and symbols for every scope and declaration. For type
    1.33 +// declarations and methods, we also pre-allocate a Type object, so that
    1.34 +// circular dependencies between types will work.
    1.35 +class NamePopulator : public AstVisitor
    1.36 +{
    1.37 +  private:
    1.38 +    // This class is analagous to a Scope, however, it allows us to create
    1.39 +    // scopes lazily. If a scope is requested, and the current environment
    1.40 +    // has no scope, then a scope is created. If no scope is ever requested,
    1.41 +    // a scope does not need to be created.
    1.42 +    class SymbolEnv
    1.43 +    {
    1.44 +      public:
    1.45 +        SymbolEnv(SymbolEnv **prevp, Scope *scope = NULL)
    1.46 +          : envp_(prevp),
    1.47 +            prev_(*prevp),
    1.48 +            scope_(scope)
    1.49 +        {
    1.50 +            *envp_ = this;
    1.51 +        }
    1.52 +        ~SymbolEnv() {
    1.53 +            *envp_ = prev_;
    1.54 +        }
    1.55 +
    1.56 +        Scope *scope() {
    1.57 +            return scope_;
    1.58 +        }
    1.59 +        void setScope(Scope *scope) {
    1.60 +            assert(!scope_);
    1.61 +            scope_ = scope;
    1.62 +        }
    1.63 +        SymbolEnv *prev() const {
    1.64 +            return prev_;
    1.65 +        }
    1.66 +
    1.67 +      private:
    1.68 +        SymbolEnv **envp_;
    1.69 +        SymbolEnv *prev_;
    1.70 +        Scope *scope_;
    1.71 +    };
    1.72 +
    1.73 +    enum ReturnStatus {
    1.74 +        NoReturn,
    1.75 +        VoidReturn,
    1.76 +        ValueReturn
    1.77 +    };
    1.78 +
    1.79 +    class FunctionScope
    1.80 +    {
    1.81 +      public:
    1.82 +        FunctionScope(FunctionScope **prevp)
    1.83 +          : prevp_(prevp),
    1.84 +            prev_(*prevp),
    1.85 +            status_(NoReturn)
    1.86 +        {
    1.87 +            *prevp_ = this;
    1.88 +        }
    1.89 +        ~FunctionScope() {
    1.90 +            *prevp_ = prev_;
    1.91 +        }
    1.92 +        ReturnStatus returns() const {
    1.93 +            return status_;
    1.94 +        }
    1.95 +        void returns(ReturnStatus status) {
    1.96 +            if (status > status_)
    1.97 +                status_ = status;
    1.98 +        }
    1.99 +      private:
   1.100 +        FunctionScope **prevp_;
   1.101 +        FunctionScope *prev_;
   1.102 +        ReturnStatus status_;
   1.103 +    };
   1.104 +
   1.105 +  public:
   1.106 +    NamePopulator(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   1.107 +      : zone_(zone),
   1.108 +        pool_(zone->pool()),
   1.109 +        cc_(cc),
   1.110 +        unit_(unit),
   1.111 +        env_(NULL),
   1.112 +        fun_(NULL)
   1.113 +    {
   1.114 +    }
   1.115 +
   1.116 +    bool analyze() {
   1.117 +        ImportScope *importScope = ImportScope::New(pool_);
   1.118 +        if (!importScope)
   1.119 +            return false;
   1.120 +
   1.121 +        // At the import level, we declare system types.
   1.122 +        if (!declareSystemTypes(importScope))
   1.123 +            return false;
   1.124 +
   1.125 +        GlobalScope *globalScope = GlobalScope::New(pool_, importScope);
   1.126 +        if (!globalScope)
   1.127 +            return false;
   1.128 +
   1.129 +        unit_->setImportScope(importScope);
   1.130 +        unit_->setGlobalScope(globalScope);
   1.131 +
   1.132 +        SymbolEnv env(&env_, globalScope);
   1.133 +
   1.134 +        for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
   1.135 +            Statement *stmt = unit_->tree()->statements()->at(i);
   1.136 +            stmt->accept(this);
   1.137 +        }
   1.138 +
   1.139 +        return true;
   1.140 +    }
   1.141 +
   1.142 +    bool declareSystemType(ImportScope *scope, const char *name, Handle<Type> type) {
   1.143 +        Local<String> tag(zone_, zone_->makeSymbol(name));
   1.144 +        if (!tag)
   1.145 +            return false;
   1.146 +
   1.147 +        TypeSymbol *sym = new (pool_) TypeSymbol(scope, tag, type);
   1.148 +        return scope->addSymbol(sym);
   1.149 +    }
   1.150 +
   1.151 +    bool declareSystemType(ImportScope *scope, const char *name, PrimitiveType prim) {
   1.152 +        Local<Type> primitive(zone_, zone_->types()->getPrimitive(prim));
   1.153 +        assert(primitive);
   1.154 +        return declareSystemType(scope, name, primitive);
   1.155 +    }
   1.156 +
   1.157 +    bool declareSystemTypes(ImportScope *scope) {
   1.158 +        if (!declareSystemType(scope, "float", PrimitiveType_Float))
   1.159 +            return false;
   1.160 +        if (!declareSystemType(scope, "_", PrimitiveType_Int32))
   1.161 +            return false;
   1.162 +        if (!declareSystemType(scope, "int", PrimitiveType_Int32))
   1.163 +            return false;
   1.164 +        if (!declareSystemType(scope, "bool", PrimitiveType_Bool))
   1.165 +            return false;
   1.166 +        if (!declareSystemType(scope, "char", PrimitiveType_Char))
   1.167 +            return false;
   1.168 +
   1.169 +        Local<Type> voidType(zone_, zone_->types()->getVoid());
   1.170 +        if (!declareSystemType(scope, "void", voidType))
   1.171 +            return false;
   1.172 +
   1.173 +        return true;
   1.174 +    }
   1.175 +
   1.176 +    void visitVariableDeclaration(VariableDeclaration *node) {
   1.177 +        Scope *scope = env_->scope();
   1.178 +        if (!scope || scope->kind() != Scope::GLOBAL) {
   1.179 +            if ((scope = getOrCreateBlockScope()) == NULL)
   1.180 +                return;
   1.181 +        }
   1.182 +
   1.183 +        if (scope->kind() == Scope::GLOBAL) {
   1.184 +            // The symbol must be added now, since it could be an export.
   1.185 +            VariableSymbol *sym = new (pool_) VariableSymbol(scope, node->name(), node->pos());
   1.186 +            node->setSymbol(sym);
   1.187 +
   1.188 +            if (!registerName(scope, sym))
   1.189 +                return;
   1.190 +        } else {
   1.191 +            // We ensure the scope will exist at the name binding phase, but
   1.192 +            // we don't actually register the variable symbol yet. Otherwise,
   1.193 +            // when binding the initializer, we could encounter:
   1.194 +            //    new x = x;
   1.195 +            //
   1.196 +            // And we don't necessarily want this to bind.
   1.197 +        }
   1.198 +
   1.199 +        node->initialization()->accept(this);
   1.200 +    }
   1.201 +    void visitEnumStatement(EnumStatement *node) {
   1.202 +        assert(false);
   1.203 +    }
   1.204 +    void visitFunctionStatement(FunctionStatement *node) {
   1.205 +        // We create function types ahead of time, not for any particular
   1.206 +        // reason. It makes things consistent with FunctionTypeStatement,
   1.207 +        // which actually does produce a type.
   1.208 +        Local<FunctionType> type(zone_, FunctionType::New(zone_, node->token()));
   1.209 +        if (!type)
   1.210 +            return;
   1.211 +
   1.212 +        assert(env_->scope());
   1.213 +
   1.214 +        // Function statements are always named, so add the name to the outer scope.
   1.215 +        FunctionSymbol *sym = new (pool_) FunctionSymbol(env_->scope(), node->name(), node->pos(), type);
   1.216 +        if (!registerName(env_->scope(), sym))
   1.217 +            return;
   1.218 +
   1.219 +        if (node->token() == TOK_PUBLIC ||
   1.220 +            node->token() == TOK_FORWARD ||
   1.221 +            node->token() == TOK_NATIVE)
   1.222 +        {
   1.223 +            // We're in the global scope, for sure.
   1.224 +            assert(env_->scope()->kind() == Scope::GLOBAL);
   1.225 +            GlobalScope *globals = (GlobalScope *)env_->scope();
   1.226 +            if (!globals->addPublic(sym))
   1.227 +                return;
   1.228 +        }
   1.229 +
   1.230 +        node->setSymbol(sym);
   1.231 +
   1.232 +        // Scope for the function's arguments.
   1.233 +        SymbolEnv argEnv(&env_);
   1.234 +        if (!registerArguments(node->signature()))
   1.235 +            return;
   1.236 +
   1.237 +        // Scope for function body.
   1.238 +        SymbolEnv localEnv(&env_);
   1.239 +        FunctionScope fun(&fun_);
   1.240 +        if (node->body())
   1.241 +            node->body()->accept(this);
   1.242 +
   1.243 +        // Function statements have quirky semantics around their return
   1.244 +        // type. For reasonable compatibility with SP1, we use the following
   1.245 +        // heuristics for when no explicit type is declared.
   1.246 +        if (!node->signature().returnType()) {
   1.247 +            Local<Type> type(zone_);
   1.248 +            if (node->token() == TOK_FORWARD || node->token() == TOK_NATIVE) {
   1.249 +                // If the function type is a native or forward, we always
   1.250 +                // assume it returns an int32.
   1.251 +                type = zone_->types()->getPrimitive(PrimitiveType_Int32);
   1.252 +            } else if (fun.returns() != ValueReturn) {
   1.253 +                // This function never returns a value, so mark it as
   1.254 +                // returning void.
   1.255 +                type = zone_->types()->getVoid();
   1.256 +            }
   1.257 +            // No need to NULL check here, we'll catch OOM later.
   1.258 +            node->sym()->type()->setReturnType(type);
   1.259 +        }
   1.260 +
   1.261 +        node->setScopes(argEnv.scope(), localEnv.scope());
   1.262 +    }
   1.263 +    void visitStructureStatement(StructureStatement *node) {
   1.264 +        assert(false);
   1.265 +    }
   1.266 +    void visiFunctionTypeStatementt(FunctionTypeStatement *node) {
   1.267 +        assert(false);
   1.268 +    }
   1.269 +
   1.270 +    void visitNameProxy(NameProxy *name) {
   1.271 +    }
   1.272 +    void visitAssignment(Assignment *node) {
   1.273 +        node->lvalue()->accept(this);
   1.274 +        node->expression()->accept(this);
   1.275 +    }
   1.276 +    void visitBinaryExpression(BinaryExpression *node) {
   1.277 +        node->left()->accept(this);
   1.278 +        node->right()->accept(this);
   1.279 +    }
   1.280 +    void visitReturnStatement(ReturnStatement *node) {
   1.281 +        if (node->expression())
   1.282 +            fun_->returns(ValueReturn);
   1.283 +        else
   1.284 +            fun_->returns(VoidReturn);
   1.285 +    }
   1.286 +    void visitForStatement(ForStatement *node) {
   1.287 +        SymbolEnv env(&env_);
   1.288 +
   1.289 +        if (node->initialization())
   1.290 +            node->initialization()->accept(this);
   1.291 +        if (node->condition())
   1.292 +            node->condition()->accept(this);
   1.293 +        if (node->update())
   1.294 +            node->update()->accept(this);
   1.295 +        node->body()->accept(this);
   1.296 +
   1.297 +        node->setScope(env.scope());
   1.298 +    }
   1.299 +    void visitBlockStatement(BlockStatement *node) {
   1.300 +        SymbolEnv env(&env_);
   1.301 +
   1.302 +        for (size_t i = 0; i < node->statements()->length(); i++)
   1.303 +            node->statements()->at(i)->accept(this);
   1.304 +
   1.305 +        node->setScope(env.scope());
   1.306 +    }
   1.307 +    void visitIntegerLiteral(IntegerLiteral *node) {
   1.308 +    }
   1.309 +    void visitExpressionStatement(ExpressionStatement *node) {
   1.310 +        node->expression()->accept(this);
   1.311 +    }
   1.312 +    void visitCallExpression(CallExpression *node) {
   1.313 +        node->callee()->accept(this);
   1.314 +        for (size_t i = 0; i < node->arguments()->length(); i++)
   1.315 +            node->arguments()->at(i)->accept(this);
   1.316 +    }
   1.317 +    void visitIfStatement(IfStatement *node) {
   1.318 +        node->ifTrue()->accept(this);
   1.319 +        if (node->ifFalse())
   1.320 +            node->ifFalse()->accept(this);
   1.321 +    }
   1.322 +    void visitIndexExpression(IndexExpression *node) {
   1.323 +        assert(false);
   1.324 +    }
   1.325 +    void visitFloatLiteral(FloatLiteral *node) {
   1.326 +    }
   1.327 +    void visitWhileStatement(WhileStatement *node) {
   1.328 +        node->condition()->accept(this);
   1.329 +        node->body()->accept(this);
   1.330 +    }
   1.331 +    void visitBreakStatement(BreakStatement *node) {
   1.332 +    }
   1.333 +    void visitContinueStatement(ContinueStatement *node) {
   1.334 +    }
   1.335 +    void visitStringLiteral(StringLiteral *node) {
   1.336 +    }
   1.337 +    void visitIncDecExpression(IncDecExpression *node) {
   1.338 +        assert(false);
   1.339 +    }
   1.340 +    void visitUnaryExpression(UnaryExpression *node) {
   1.341 +        assert(false);
   1.342 +    }
   1.343 +    void visitTernaryExpression(TernaryExpression *node) {
   1.344 +        assert(false);
   1.345 +    }
   1.346 +    void visitBooleanLiteral(BooleanLiteral *node) {
   1.347 +    }
   1.348 +    void visitFieldExpression(FieldExpression *node) {
   1.349 +    }
   1.350 +    void visitSwitchStatement(SwitchStatement *node) {
   1.351 +        if (node->defaultCase())
   1.352 +            node->defaultCase()->accept(this);
   1.353 +
   1.354 +        for (size_t i = 0; i < node->cases()->length(); i++)
   1.355 +            node->cases()->at(i)->statement()->accept(this);
   1.356 +    }
   1.357 +    void visitArrayLiteral(ArrayLiteral *node) {
   1.358 +    }
   1.359 +    void visitImportStatement(ImportStatement *node) {
   1.360 +    }
   1.361 +
   1.362 +  private:
   1.363 +    Scope *getOrCreateBlockScope() {
   1.364 +        if (env_->scope()) {
   1.365 +            assert(env_->scope()->kind() == Scope::BLOCK);
   1.366 +            return env_->scope();
   1.367 +        }
   1.368 +        
   1.369 +        LocalScope *scope = LocalScope::New(pool_);
   1.370 +        if (!scope)
   1.371 +            return NULL;
   1.372 +
   1.373 +        env_->setScope(scope);
   1.374 +        return scope;
   1.375 +    }
   1.376 +
   1.377 +    bool registerName(Scope *scope, Symbol *sym) {
   1.378 +        if (!scope)
   1.379 +            return false;
   1.380 +
   1.381 +        if (Symbol *other = scope->localLookup(sym->name())) {
   1.382 +            // Report, but allow errors to continue.
   1.383 +            cc_.reportError(sym->pos(), Message_RedeclaredName,
   1.384 +                            sym->name()->chars(),
   1.385 +                            other->pos().line,
   1.386 +                            other->pos().col);
   1.387 +            return true;
   1.388 +        }
   1.389 +
   1.390 +        return scope->addSymbol(sym);
   1.391 +    }
   1.392 +
   1.393 +    bool registerArguments(const FunctionSignature &sig) {
   1.394 +        if (!sig.parameters()->length())
   1.395 +            return true;
   1.396 +
   1.397 +        ArgumentScope *argScope = ArgumentScope::New(pool_);
   1.398 +        if (!argScope)
   1.399 +            return false;
   1.400 +        env_->setScope(argScope);
   1.401 +
   1.402 +        for (size_t i = 0; i < sig.parameters()->length(); i++) {
   1.403 +            Parameter *param = sig.parameters()->at(i);
   1.404 +            VariableSymbol *sym = new (pool_) VariableSymbol(argScope, param->name(), param->pos());
   1.405 +            if (!registerName(env_->scope(), sym))
   1.406 +                return false;
   1.407 +            param->setSymbol(sym);
   1.408 +        }
   1.409 +
   1.410 +        return true;
   1.411 +    }
   1.412 +
   1.413 +  private:
   1.414 +    Zone *zone_;
   1.415 +    PoolAllocator &pool_;
   1.416 +    CompileContext &cc_;
   1.417 +    TranslationUnit *unit_;
   1.418 +    SymbolEnv *env_;
   1.419 +    FunctionScope *fun_;
   1.420 +};
   1.421 +
   1.422 +bool
   1.423 +ke::PopulateNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   1.424 +{
   1.425 +    NamePopulator populator(zone, cc, unit);
   1.426 +    return populator.analyze();
   1.427 +}
   1.428 +
   1.429 +class NameBinder : public AstVisitor
   1.430 +{
   1.431 +  public:
   1.432 +    class AutoLinkScope
   1.433 +    {
   1.434 +      public:
   1.435 +        AutoLinkScope(AutoLinkScope **prevp, Scope *scope)
   1.436 +          : prevp_(prevp),
   1.437 +            prev_(*prevp),
   1.438 +            scope_(scope)
   1.439 +        {
   1.440 +            if (scope_) {
   1.441 +                *prevp_ = this;
   1.442 +                if (prev_)
   1.443 +                    scope_->setParent(prev_->scope());
   1.444 +            }
   1.445 +        }
   1.446 +        ~AutoLinkScope() {
   1.447 +            if (scope_) {
   1.448 +                assert(*prevp_ == this);
   1.449 +                *prevp_ = prev_;
   1.450 +            }
   1.451 +        }
   1.452 +        Scope *scope() const {
   1.453 +            return scope_;
   1.454 +        }
   1.455 +
   1.456 +      private:
   1.457 +        AutoLinkScope **prevp_;
   1.458 +        AutoLinkScope *prev_;
   1.459 +        Scope *scope_;
   1.460 +    };
   1.461 +
   1.462 +  public:
   1.463 +    NameBinder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   1.464 +      : zone_(zone),
   1.465 +        pool_(zone->pool()),
   1.466 +        cc_(cc),
   1.467 +        unit_(unit),
   1.468 +        link_(NULL)
   1.469 +    {
   1.470 +    }
   1.471 +
   1.472 +    bool bind() {
   1.473 +        // Start with the import scope, and collect all imported names.
   1.474 +        AutoLinkScope importScope(&link_, unit_->importScope());
   1.475 +
   1.476 +        for (size_t i = 0; i < unit_->tree()->imports()->length(); i++)
   1.477 +            unit_->tree()->imports()->at(i)->accept(this);
   1.478 +
   1.479 +        // Next, enter the global scope and walk all statements.
   1.480 +        AutoLinkScope globalScope(&link_, unit_->globalScope());
   1.481 +        for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
   1.482 +            Statement *stmt = unit_->tree()->statements()->at(i);
   1.483 +            stmt->accept(this);
   1.484 +        }
   1.485 +
   1.486 +        return true;
   1.487 +    }
   1.488 +
   1.489 +    void visitVariableDeclaration(VariableDeclaration *node) {
   1.490 +        // Bind the initializer before registering the declaration, so that we
   1.491 +        // can error on bogus initializers (new x = x).
   1.492 +        node->initialization()->accept(this);
   1.493 +
   1.494 +        Local<Type> type(zone_, bindType(node->type()));
   1.495 +        if (!type)
   1.496 +            return;
   1.497 +
   1.498 +        // If the node already has a symbol (meaning it was a global), then
   1.499 +        // we don't have to do anything more.
   1.500 +        if (node->sym()) {
   1.501 +            assert(node->sym()->scope()->kind() == Scope::GLOBAL);
   1.502 +            return;
   1.503 +        }
   1.504 +
   1.505 +        VariableSymbol *sym = new (pool_) VariableSymbol(link_->scope(), node->name(), node->pos(), type);
   1.506 +        node->setSymbol(sym);
   1.507 +       
   1.508 +        if (Symbol *other = link_->scope()->localLookup(sym->name())) {
   1.509 +            // Report, but allow errors to continue.
   1.510 +            cc_.reportError(sym->pos(), Message_RedeclaredName,
   1.511 +                            sym->name()->chars(),
   1.512 +                            other->pos().line,
   1.513 +                            other->pos().col);
   1.514 +            return;
   1.515 +        }
   1.516 +        
   1.517 +        if (link_->scope()->addSymbol(sym))
   1.518 +            return;
   1.519 +    }
   1.520 +    void visitEnumStatement(EnumStatement *node) {
   1.521 +        assert(false);
   1.522 +    }
   1.523 +    void visitFunctionStatement(FunctionStatement *node) {
   1.524 +        AutoLinkScope argScope(&link_, node->argScope());
   1.525 +        AutoLinkScope varScope(&link_, node->varScope());
   1.526 +
   1.527 +        Local<FunctionType> type(zone_, node->sym()->type());
   1.528 +        if (!fillFunctionType(type, node->signature()))
   1.529 +            return;
   1.530 +
   1.531 +        if (node->body())
   1.532 +            node->body()->accept(this);
   1.533 +    }
   1.534 +    void visitStructureStatement(StructureStatement *node) {
   1.535 +        assert(false);
   1.536 +    }
   1.537 +    void visitFunctionTypeStatement(FunctionTypeStatement *node) {
   1.538 +        assert(false);
   1.539 +    }
   1.540 +
   1.541 +    void visitNameProxy(NameProxy *proxy) {
   1.542 +        Scope *scope = link_->scope();
   1.543 +        Symbol *sym = scope->lookup(proxy->name());
   1.544 +        if (!sym)
   1.545 +            cc_.reportError(proxy->pos(), Message_IdentifierNotFound, proxy->name()->chars());
   1.546 +        proxy->bind(sym);
   1.547 +    }
   1.548 +    void visitAssignment(Assignment *node) {
   1.549 +        node->lvalue()->accept(this);
   1.550 +        node->expression()->accept(this);
   1.551 +    }
   1.552 +    void visitBinaryExpression(BinaryExpression *node) {
   1.553 +        node->left()->accept(this);
   1.554 +        node->right()->accept(this);
   1.555 +    }
   1.556 +    void visitReturnStatement(ReturnStatement *node) {
   1.557 +        node->expression()->accept(this);
   1.558 +    }
   1.559 +    void visitForStatement(ForStatement *node) {
   1.560 +        AutoLinkScope scope(&link_, node->scope());
   1.561 +
   1.562 +        if (node->initialization())
   1.563 +            node->initialization()->accept(this);
   1.564 +        if (node->condition())
   1.565 +            node->condition()->accept(this);
   1.566 +        if (node->update())
   1.567 +            node->update()->accept(this);
   1.568 +        node->body()->accept(this);
   1.569 +    }
   1.570 +    void visitBlockStatement(BlockStatement *node) {
   1.571 +        AutoLinkScope scope(&link_, node->scope());
   1.572 +        for (size_t i = 0; i < node->statements()->length(); i++)
   1.573 +            node->statements()->at(i)->accept(this);
   1.574 +    }
   1.575 +    void visitIntegerLiteral(IntegerLiteral *node) {
   1.576 +    }
   1.577 +    void visitExpressionStatement(ExpressionStatement *node) {
   1.578 +        node->expression()->accept(this);
   1.579 +    }
   1.580 +    void visitCallExpression(CallExpression *node) {
   1.581 +        node->callee()->accept(this);
   1.582 +        for (size_t i = 0; i < node->arguments()->length(); i++)
   1.583 +            node->arguments()->at(i)->accept(this);
   1.584 +    }
   1.585 +    void visitIfStatement(IfStatement *node) {
   1.586 +        node->condition()->accept(this);
   1.587 +        node->ifTrue()->accept(this);
   1.588 +        node->ifFalse()->accept(this);
   1.589 +    }
   1.590 +    void visitIndexExpression(IndexExpression *node) {
   1.591 +        node->left()->accept(this);
   1.592 +        node->right()->accept(this);
   1.593 +    }
   1.594 +    void visitFloatLiteral(FloatLiteral *node) {
   1.595 +    }
   1.596 +    void visitWhileStatement(WhileStatement *node) {
   1.597 +        node->condition()->accept(this);
   1.598 +        node->body()->accept(this);
   1.599 +    }
   1.600 +    void visitBreakStatement(BreakStatement *node) {
   1.601 +    }
   1.602 +    void visitContinueStatement(ContinueStatement *node) {
   1.603 +    }
   1.604 +    void visitStringLiteral(StringLiteral *node) {
   1.605 +    }
   1.606 +    void visitIncDecExpression(IncDecExpression *node) {
   1.607 +        node->expression()->accept(this);
   1.608 +    }
   1.609 +    void visitUnaryExpression(UnaryExpression *node) {
   1.610 +        if (node->tag())
   1.611 +            node->tag()->accept(this);
   1.612 +        node->expression()->accept(this);
   1.613 +    }
   1.614 +    void visitTernaryExpression(TernaryExpression *node) {
   1.615 +        node->condition()->accept(this);
   1.616 +        node->left()->accept(this);
   1.617 +        node->right()->accept(this);
   1.618 +    }
   1.619 +    void visitBooleanLiteral(BooleanLiteral *node) {
   1.620 +    }
   1.621 +    void visitFieldExpression(FieldExpression *node) {
   1.622 +        node->left()->accept(this);
   1.623 +    }
   1.624 +    void visitSwitchStatement(SwitchStatement *node) {
   1.625 +        node->expression()->accept(this);
   1.626 +        node->defaultCase()->accept(this);
   1.627 +        for (size_t i = 0; i < node->cases()->length(); i++) {
   1.628 +            // We don't test case expressions because they are literals.
   1.629 +            Case *c = node->cases()->at(i);
   1.630 +            c->statement()->accept(this);
   1.631 +        }
   1.632 +    }
   1.633 +    void visitArrayLiteral(ArrayLiteral *node) {
   1.634 +        for (size_t i = 0; i < node->expressions()->length(); i++)
   1.635 +            node->expressions()->at(i)->accept(this);
   1.636 +    }
   1.637 +    void visitImportStatement(ImportStatement *node) {
   1.638 +        if (node->suffix() == TOK_STAR) {
   1.639 +            // Import every name.
   1.640 +            assert(false);
   1.641 +        } else {
   1.642 +            GlobalScope *other = node->source()->globalScope();
   1.643 +            Symbol *sym = other->findPublic(node->name());
   1.644 +            if (!sym) {
   1.645 +                cc_.reportError(node->pos(), Message_CannotResolveImport, node->name()->chars());
   1.646 +                return;
   1.647 +            }
   1.648 +            link_->scope()->addSymbol(sym);
   1.649 +        }
   1.650 +    }
   1.651 +
   1.652 +  private:
   1.653 +    bool fillFunctionType(Handle<FunctionType> fun, const FunctionSignature &sig) {
   1.654 +        Local<Type> type(zone_);
   1.655 +        if (!fun->returnType()) {
   1.656 +            if ((type = bindType(sig.returnType())) == NULL)
   1.657 +                return false;
   1.658 +            fun->setReturnType(type);
   1.659 +        }
   1.660 +
   1.661 +        Local<FixedArray> params(zone_, FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old));
   1.662 +        if (!params)
   1.663 +            return false;
   1.664 +
   1.665 +        for (size_t i = 0; i < sig.parameters()->length(); i++) {
   1.666 +            Parameter *param = sig.parameters()->at(i);
   1.667 +            if ((type = bindType(param->type())) == NULL)
   1.668 +                return false;
   1.669 +            params->set(zone_, i, type);
   1.670 +        }
   1.671 +
   1.672 +        fun->setParameterTypes(params);
   1.673 +
   1.674 +        return true;
   1.675 +    }
   1.676 +
   1.677 +    Type *bindType(Expression *expr) {
   1.678 +        if (!expr) {
   1.679 +            // If no type was declared, we return int32.
   1.680 +            return zone_->types()->getPrimitive(PrimitiveType_Int32);
   1.681 +        }
   1.682 +        
   1.683 +        expr->accept(this);
   1.684 +
   1.685 +        NameProxy *proxy = expr->asNameProxy();
   1.686 +        assert(proxy);
   1.687 +
   1.688 +        Symbol *sym = proxy->sym();
   1.689 +        if (!sym)
   1.690 +            return NULL;
   1.691 +
   1.692 +        if (!sym->isType()) {
   1.693 +            cc_.reportError(expr->pos(), Message_IdentifierIsNotAType, sym->name()->chars());
   1.694 +            return NULL;
   1.695 +        }
   1.696 +
   1.697 +        return sym->type();
   1.698 +    }
   1.699 +
   1.700 +  private:
   1.701 +    Zone *zone_;
   1.702 +    PoolAllocator &pool_;
   1.703 +    CompileContext &cc_;
   1.704 +    TranslationUnit *unit_;
   1.705 +    AutoLinkScope *link_;
   1.706 +};
   1.707 +
   1.708 +bool
   1.709 +ke::BindNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   1.710 +{
   1.711 +    NameBinder binder(zone, cc, unit);
   1.712 +    return binder.bind();
   1.713 +}