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 +}