src/compiler/NameBinding.cpp
author David Anderson <dvander@alliedmods.net>
Mon Dec 24 16:43:22 2012 -0800 (2012-12-24)
changeset 237 c77540a61905
parent 233 bbb498ccb4ac
child 241 18f3010a358c
permissions -rw-r--r--
Don't allow declaring void variables.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of SourcePawn.
     6  *
     7  * SourcePawn is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * SourcePawn. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #include "../Strings.h"
    20 #include "../Zone.h"
    21 #include "../TypeManager.h"
    22 #include "NameBinding.h"
    23 #include "Scopes.h"
    24 #include "ConstantEvaluator.h"
    25 #include "../Spaces-inl.h"
    26 #include "../Heap-inl.h"
    27 
    28 using namespace ke;
    29 
    30 // Create symbol tables and symbols for every scope and declaration. For type
    31 // declarations and methods, we also pre-allocate a Type object, so that
    32 // circular dependencies between types will work.
    33 class NamePopulator : public AstVisitor
    34 {
    35   private:
    36     // This class is analagous to a Scope, however, it allows us to create
    37     // scopes lazily. If a scope is requested, and the current environment
    38     // has no scope, then a scope is created. If no scope is ever requested,
    39     // a scope does not need to be created.
    40     class SymbolEnv
    41     {
    42       public:
    43         SymbolEnv(SymbolEnv **prevp, Scope *scope = NULL)
    44           : envp_(prevp),
    45             prev_(*prevp),
    46             scope_(scope)
    47         {
    48             *envp_ = this;
    49         }
    50         ~SymbolEnv() {
    51             *envp_ = prev_;
    52         }
    53 
    54         Scope *scope() {
    55             return scope_;
    56         }
    57         void setScope(Scope *scope) {
    58             assert(!scope_);
    59             scope_ = scope;
    60         }
    61         SymbolEnv *prev() const {
    62             return prev_;
    63         }
    64 
    65       private:
    66         SymbolEnv **envp_;
    67         SymbolEnv *prev_;
    68         Scope *scope_;
    69     };
    70 
    71     enum ReturnStatus {
    72         NoReturn,
    73         VoidReturn,
    74         ValueReturn
    75     };
    76 
    77     class FunctionScope
    78     {
    79       public:
    80         FunctionScope(FunctionScope **prevp)
    81           : prevp_(prevp),
    82             prev_(*prevp),
    83             status_(NoReturn)
    84         {
    85             *prevp_ = this;
    86         }
    87         ~FunctionScope() {
    88             *prevp_ = prev_;
    89         }
    90         ReturnStatus returns() const {
    91             return status_;
    92         }
    93         void returns(ReturnStatus status) {
    94             if (status > status_)
    95                 status_ = status;
    96         }
    97       private:
    98         FunctionScope **prevp_;
    99         FunctionScope *prev_;
   100         ReturnStatus status_;
   101     };
   102 
   103   public:
   104     NamePopulator(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   105       : zone_(zone),
   106         pool_(zone->pool()),
   107         cc_(cc),
   108         unit_(unit),
   109         env_(NULL),
   110         fun_(NULL)
   111     {
   112     }
   113 
   114     bool analyze() {
   115         ImportScope *importScope = ImportScope::New(pool_);
   116         if (!importScope)
   117             return false;
   118 
   119         // At the import level, we declare system types.
   120         if (!declareSystemTypes(importScope))
   121             return false;
   122 
   123         GlobalScope *globalScope = GlobalScope::New(pool_, importScope);
   124         if (!globalScope)
   125             return false;
   126 
   127         unit_->setImportScope(importScope);
   128         unit_->setGlobalScope(globalScope);
   129 
   130         SymbolEnv env(&env_, globalScope);
   131 
   132         for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
   133             Statement *stmt = unit_->tree()->statements()->at(i);
   134             stmt->accept(this);
   135         }
   136 
   137         return true;
   138     }
   139 
   140     bool declareSystemType(ImportScope *scope, const char *name, Handle<Type> type) {
   141         Local<String> tag(zone_, zone_->makeSymbol(name));
   142         if (!tag)
   143             return false;
   144 
   145         TypeSymbol *sym = new (pool_) TypeSymbol(scope, tag, type);
   146         return scope->addSymbol(sym);
   147     }
   148 
   149     bool declareSystemType(ImportScope *scope, const char *name, PrimitiveType prim) {
   150         Local<Type> primitive(zone_, zone_->types()->getPrimitive(prim));
   151         assert(primitive);
   152         return declareSystemType(scope, name, primitive);
   153     }
   154 
   155     bool declareSystemTypes(ImportScope *scope) {
   156         if (!declareSystemType(scope, "float", PrimitiveType_Float))
   157             return false;
   158         if (!declareSystemType(scope, "_", PrimitiveType_Int32))
   159             return false;
   160         if (!declareSystemType(scope, "int", PrimitiveType_Int32))
   161             return false;
   162         if (!declareSystemType(scope, "bool", PrimitiveType_Bool))
   163             return false;
   164         if (!declareSystemType(scope, "char", PrimitiveType_Char))
   165             return false;
   166 
   167         Local<Type> voidType(zone_, zone_->types()->getVoid());
   168         if (!declareSystemType(scope, "void", voidType))
   169             return false;
   170 
   171         return true;
   172     }
   173 
   174     void visitVariableDeclaration(VariableDeclaration *node) {
   175         Scope *scope = env_->scope();
   176         if (!scope || scope->kind() != Scope::GLOBAL) {
   177             if ((scope = getOrCreateBlockScope()) == NULL)
   178                 return;
   179         }
   180 
   181         if (scope->kind() == Scope::GLOBAL) {
   182             // The symbol must be added now, since it could be an export.
   183             VariableSymbol *sym = new (pool_) VariableSymbol(scope, node->name(), node->pos());
   184             node->setSymbol(sym);
   185 
   186             if (!registerName(scope, sym))
   187                 return;
   188         } else {
   189             // We ensure the scope will exist at the name binding phase, but
   190             // we don't actually register the variable symbol yet. Otherwise,
   191             // when binding the initializer, we could encounter:
   192             //    new x = x;
   193             //
   194             // And we don't necessarily want this to bind.
   195         }
   196 
   197         if (node->initialization())
   198             node->initialization()->accept(this);
   199     }
   200     void visitEnumStatement(EnumStatement *node) {
   201         Local<String> name(zone_, node->name());
   202         Local<Type> type(zone_);
   203         if (name)
   204             type = zone_->types()->newEnum(name);
   205         else
   206             type = zone_->types()->getPrimitive(PrimitiveType_Int32);
   207 
   208         if (!type)
   209             return;
   210 
   211         Scope *scope = getGlobalOrCreateBlockScope();
   212         if (!scope)
   213             return;
   214 
   215         if (name) {
   216             TypeSymbol *sym = new (pool_) TypeSymbol(scope, name, type);
   217             if (!registerName(scope, sym))
   218                 return;
   219         }
   220 
   221         int value = 0;
   222         for (size_t i = 0; i < node->entries()->length(); i++) {
   223             EnumStatement::Entry &entry = node->entries()->at(i);
   224             BoxedPrimitive box = BoxedPrimitive::Int(value);
   225             if (entry.expr) {
   226                 if (!EvaluateForConstant(entry.expr, &box) || box.type() != PrimitiveType_Int32) {
   227                     cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
   228                     return;
   229                 }
   230 
   231                 assert(box.type() == PrimitiveType_Int32);
   232                 value = box.toInt();
   233             }
   234             
   235             ConstantSymbol *sym = new (pool_) ConstantSymbol(scope, entry.name, entry.pos, type, box);
   236             if (!registerName(scope, sym))
   237                 return;
   238 
   239             value++;
   240         }
   241     }
   242     void visitFunctionStatement(FunctionStatement *node) {
   243         // We create function types ahead of time, not for any particular
   244         // reason. It makes things consistent with FunctionTypeStatement,
   245         // which actually does produce a type.
   246         Local<FunctionType> type(zone_, FunctionType::New(zone_, node->name(), node->token()));
   247         if (!type)
   248             return;
   249 
   250         assert(env_->scope());
   251 
   252         // Function statements are always named, so add the name to the outer scope.
   253         FunctionSymbol *sym = new (pool_) FunctionSymbol(env_->scope(), node->name(), node->pos(), type);
   254         if (!registerName(env_->scope(), sym))
   255             return;
   256 
   257         if (node->token() == TOK_PUBLIC ||
   258             node->token() == TOK_FORWARD ||
   259             node->token() == TOK_NATIVE)
   260         {
   261             // We're in the global scope, for sure.
   262             assert(env_->scope()->kind() == Scope::GLOBAL);
   263             GlobalScope *globals = (GlobalScope *)env_->scope();
   264             if (!globals->addPublic(sym))
   265                 return;
   266         }
   267 
   268         node->setSymbol(sym);
   269 
   270         // Scope for the function's arguments.
   271         SymbolEnv argEnv(&env_);
   272         if (!registerArguments(node->signature()))
   273             return;
   274 
   275         // Scope for function body.
   276         SymbolEnv localEnv(&env_);
   277         FunctionScope fun(&fun_);
   278         if (node->body())
   279             node->body()->accept(this);
   280 
   281         // Function statements have quirky semantics around their return
   282         // type. For reasonable compatibility with SP1, we use the following
   283         // heuristics for when no explicit type is declared.
   284         if (!node->signature().returnType()) {
   285             Local<Type> type(zone_);
   286             if (node->token() == TOK_FORWARD || node->token() == TOK_NATIVE) {
   287                 // If the function type is a native or forward, we always
   288                 // assume it returns an int32.
   289                 type = zone_->types()->getPrimitive(PrimitiveType_Int32);
   290             } else if (fun.returns() != ValueReturn) {
   291                 // This function never returns a value, so mark it as
   292                 // returning void.
   293                 type = zone_->types()->getVoid();
   294             }
   295             // No need to NULL check here, we'll catch OOM later.
   296             node->sym()->type()->setReturnType(type);
   297         }
   298 
   299         node->setScopes(argEnv.scope(), localEnv.scope());
   300     }
   301     void visitStructureStatement(StructureStatement *node) {
   302         assert(false);
   303     }
   304     void visiFunctionTypeStatementt(FunctionTypeStatement *node) {
   305         assert(false);
   306     }
   307 
   308     void visitNameProxy(NameProxy *name) {
   309     }
   310     void visitAssignment(Assignment *node) {
   311         node->lvalue()->accept(this);
   312         node->expression()->accept(this);
   313     }
   314     void visitBinaryExpression(BinaryExpression *node) {
   315         node->left()->accept(this);
   316         node->right()->accept(this);
   317     }
   318     void visitReturnStatement(ReturnStatement *node) {
   319         if (node->expression())
   320             fun_->returns(ValueReturn);
   321         else
   322             fun_->returns(VoidReturn);
   323     }
   324     void visitForStatement(ForStatement *node) {
   325         SymbolEnv env(&env_);
   326 
   327         if (node->initialization())
   328             node->initialization()->accept(this);
   329         if (node->condition())
   330             node->condition()->accept(this);
   331         if (node->update())
   332             node->update()->accept(this);
   333         node->body()->accept(this);
   334 
   335         node->setScope(env.scope());
   336     }
   337     void visitBlockStatement(BlockStatement *node) {
   338         SymbolEnv env(&env_);
   339 
   340         for (size_t i = 0; i < node->statements()->length(); i++)
   341             node->statements()->at(i)->accept(this);
   342 
   343         node->setScope(env.scope());
   344     }
   345     void visitIntegerLiteral(IntegerLiteral *node) {
   346     }
   347     void visitExpressionStatement(ExpressionStatement *node) {
   348         node->expression()->accept(this);
   349     }
   350     void visitCallExpression(CallExpression *node) {
   351         node->callee()->accept(this);
   352         for (size_t i = 0; i < node->arguments()->length(); i++)
   353             node->arguments()->at(i)->accept(this);
   354     }
   355     void visitIfStatement(IfStatement *node) {
   356         node->ifTrue()->accept(this);
   357         if (node->ifFalse())
   358             node->ifFalse()->accept(this);
   359     }
   360     void visitIndexExpression(IndexExpression *node) {
   361         node->left()->accept(this);
   362         node->right()->accept(this);
   363     }
   364     void visitFloatLiteral(FloatLiteral *node) {
   365     }
   366     void visitWhileStatement(WhileStatement *node) {
   367         node->condition()->accept(this);
   368         node->body()->accept(this);
   369     }
   370     void visitBreakStatement(BreakStatement *node) {
   371     }
   372     void visitContinueStatement(ContinueStatement *node) {
   373     }
   374     void visitStringLiteral(StringLiteral *node) {
   375     }
   376     void visitIncDecExpression(IncDecExpression *node) {
   377         node->expression()->accept(this);
   378     }
   379     void visitUnaryExpression(UnaryExpression *node) {
   380         assert(false);
   381     }
   382     void visitTernaryExpression(TernaryExpression *node) {
   383         assert(false);
   384     }
   385     void visitBooleanLiteral(BooleanLiteral *node) {
   386     }
   387     void visitFieldExpression(FieldExpression *node) {
   388     }
   389     void visitSwitchStatement(SwitchStatement *node) {
   390         if (node->defaultCase())
   391             node->defaultCase()->accept(this);
   392 
   393         for (size_t i = 0; i < node->cases()->length(); i++)
   394             node->cases()->at(i)->statement()->accept(this);
   395     }
   396     void visitArrayLiteral(ArrayLiteral *node) {
   397     }
   398     void visitImportStatement(ImportStatement *node) {
   399     }
   400 
   401   private:
   402     Scope *getGlobalOrCreateBlockScope() {
   403         if (env_->scope()) {
   404             assert(env_->scope()->kind() == Scope::BLOCK ||
   405                    env_->scope()->kind() == Scope::GLOBAL);
   406             return env_->scope();
   407         }
   408         return getOrCreateBlockScope();
   409     }
   410     Scope *getOrCreateBlockScope() {
   411         if (env_->scope()) {
   412             assert(env_->scope()->kind() == Scope::BLOCK);
   413             return env_->scope();
   414         }
   415         
   416         LocalScope *scope = LocalScope::New(pool_);
   417         if (!scope)
   418             return NULL;
   419 
   420         env_->setScope(scope);
   421         return scope;
   422     }
   423 
   424     bool registerName(Scope *scope, Symbol *sym) {
   425         if (!scope)
   426             return false;
   427 
   428         if (Symbol *other = scope->localLookup(sym->name())) {
   429             // Report, but allow errors to continue.
   430             cc_.reportError(sym->pos(), Message_RedeclaredName,
   431                             sym->name()->chars(),
   432                             other->pos().line,
   433                             other->pos().col);
   434             return true;
   435         }
   436 
   437         return scope->addSymbol(sym);
   438     }
   439 
   440     bool registerArguments(const FunctionSignature &sig) {
   441         if (!sig.parameters()->length())
   442             return true;
   443 
   444         ArgumentScope *argScope = ArgumentScope::New(pool_);
   445         if (!argScope)
   446             return false;
   447         env_->setScope(argScope);
   448 
   449         for (size_t i = 0; i < sig.parameters()->length(); i++) {
   450             Parameter *param = sig.parameters()->at(i);
   451             VariableSymbol *sym = new (pool_) VariableSymbol(argScope, param->name(), param->pos());
   452             if (!registerName(env_->scope(), sym))
   453                 return false;
   454             param->setSymbol(sym);
   455         }
   456 
   457         return true;
   458     }
   459 
   460   private:
   461     Zone *zone_;
   462     PoolAllocator &pool_;
   463     CompileContext &cc_;
   464     TranslationUnit *unit_;
   465     SymbolEnv *env_;
   466     FunctionScope *fun_;
   467 };
   468 
   469 bool
   470 ke::PopulateNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   471 {
   472     NamePopulator populator(zone, cc, unit);
   473     return populator.analyze();
   474 }
   475 
   476 static const int INFER_ARRAY_SIZE = 0;
   477 static const int EVAL_ARRAY_SIZE = -1;
   478 static const int DYNAMIC_ARRAY_SIZE = -2;
   479 
   480 class NameBinder : public AstVisitor
   481 {
   482   public:
   483     class AutoLinkScope
   484     {
   485       public:
   486         AutoLinkScope(AutoLinkScope **prevp, Scope *scope)
   487           : prevp_(prevp),
   488             prev_(*prevp),
   489             scope_(scope)
   490         {
   491             if (scope_) {
   492                 *prevp_ = this;
   493                 if (prev_)
   494                     scope_->setParent(prev_->scope());
   495             }
   496         }
   497         ~AutoLinkScope() {
   498             if (scope_) {
   499                 assert(*prevp_ == this);
   500                 *prevp_ = prev_;
   501             }
   502         }
   503         Scope *scope() const {
   504             return scope_;
   505         }
   506 
   507       private:
   508         AutoLinkScope **prevp_;
   509         AutoLinkScope *prev_;
   510         Scope *scope_;
   511     };
   512 
   513   public:
   514     NameBinder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   515       : zone_(zone),
   516         pool_(zone->pool()),
   517         cc_(cc),
   518         unit_(unit),
   519         link_(NULL)
   520     {
   521     }
   522 
   523     bool bind() {
   524         // Start with the import scope, and collect all imported names.
   525         AutoLinkScope importScope(&link_, unit_->importScope());
   526 
   527         for (size_t i = 0; i < unit_->tree()->imports()->length(); i++)
   528             unit_->tree()->imports()->at(i)->accept(this);
   529 
   530         // Next, enter the global scope and walk all statements.
   531         AutoLinkScope globalScope(&link_, unit_->globalScope());
   532         for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
   533             Statement *stmt = unit_->tree()->statements()->at(i);
   534             stmt->accept(this);
   535         }
   536 
   537         return true;
   538     }
   539 
   540     void visitVariableDeclaration(VariableDeclaration *node) {
   541         // Bind the initializer before registering the declaration, so that we
   542         // can error on bogus initializers (new x = x).
   543         if (node->initialization())
   544             node->initialization()->accept(this);
   545 
   546         Local<Type> type(zone_, bindType(node->type()));
   547         if (!type)
   548             return;
   549 
   550         if (node->dims() || type->isArray()) {
   551             int dims[MAX_ARRAY_DEPTH];
   552             int levels = evaluateDimensions(node->pos(), type, node->dims(), dims);
   553             if (levels < 0)
   554                 return;
   555 
   556             // Do some extra inference based on the initializer, if present.
   557             Expression *init = node->initialization();
   558             if (init &&
   559                 init->isArrayLiteral() &&
   560                 init->toArrayLiteral()->isFixed())
   561             {
   562                 Local<Type> contained(zone_, type->isArray()
   563                                              ? ArrayType::cast(type)->contained()
   564                                              : type);
   565                 if (!inferFixedArrayDimensions(init->toArrayLiteral(), contained, dims, levels))
   566                     return;
   567             }
   568 
   569             // If we got extra dimensions, we need to build a new type.
   570             if (node->dims()) {
   571                 if ((type = buildArrayType(type, dims, node->dims()->length())) == NULL)
   572                     return;
   573             }
   574         }
   575 
   576         // If the node already has a symbol (meaning it was a global), then
   577         // we don't have to do anything more.
   578         if (node->sym()) {
   579             assert(node->sym()->scope()->kind() == Scope::GLOBAL);
   580             node->sym()->setType(type);
   581             return;
   582         }
   583 
   584         VariableSymbol *sym = new (pool_) VariableSymbol(link_->scope(), node->name(), node->pos(), type);
   585         node->setSymbol(sym);
   586        
   587         if (Symbol *other = link_->scope()->localLookup(sym->name())) {
   588             // Report, but allow errors to continue.
   589             cc_.reportError(sym->pos(), Message_RedeclaredName,
   590                             sym->name()->chars(),
   591                             other->pos().line,
   592                             other->pos().col);
   593             return;
   594         }
   595         
   596         link_->scope()->addSymbol(sym);
   597     }
   598     void visitEnumStatement(EnumStatement *node) {
   599     }
   600     void visitFunctionStatement(FunctionStatement *node) {
   601         AutoLinkScope argScope(&link_, node->argScope());
   602         AutoLinkScope varScope(&link_, node->varScope());
   603 
   604         Local<FunctionType> type(zone_, node->sym()->type());
   605         if (!fillFunctionType(type, node->signature()))
   606             return;
   607 
   608         if (node->body())
   609             node->body()->accept(this);
   610     }
   611     void visitStructureStatement(StructureStatement *node) {
   612         assert(false);
   613     }
   614     void visitFunctionTypeStatement(FunctionTypeStatement *node) {
   615         assert(false);
   616     }
   617 
   618     void visitNameProxy(NameProxy *proxy) {
   619         Scope *scope = link_->scope();
   620         Symbol *sym = scope->lookup(proxy->name());
   621         if (!sym)
   622             cc_.reportError(proxy->pos(), Message_IdentifierNotFound, proxy->name()->chars());
   623         proxy->bind(sym);
   624     }
   625     void visitAssignment(Assignment *node) {
   626         node->lvalue()->accept(this);
   627         node->expression()->accept(this);
   628     }
   629     void visitBinaryExpression(BinaryExpression *node) {
   630         node->left()->accept(this);
   631         node->right()->accept(this);
   632     }
   633     void visitReturnStatement(ReturnStatement *node) {
   634         node->expression()->accept(this);
   635     }
   636     void visitForStatement(ForStatement *node) {
   637         AutoLinkScope scope(&link_, node->scope());
   638 
   639         if (node->initialization())
   640             node->initialization()->accept(this);
   641         if (node->condition())
   642             node->condition()->accept(this);
   643         if (node->update())
   644             node->update()->accept(this);
   645         node->body()->accept(this);
   646     }
   647     void visitBlockStatement(BlockStatement *node) {
   648         AutoLinkScope scope(&link_, node->scope());
   649         for (size_t i = 0; i < node->statements()->length(); i++)
   650             node->statements()->at(i)->accept(this);
   651     }
   652     void visitIntegerLiteral(IntegerLiteral *node) {
   653     }
   654     void visitExpressionStatement(ExpressionStatement *node) {
   655         node->expression()->accept(this);
   656     }
   657     void visitCallExpression(CallExpression *node) {
   658         node->callee()->accept(this);
   659         for (size_t i = 0; i < node->arguments()->length(); i++)
   660             node->arguments()->at(i)->accept(this);
   661     }
   662     void visitIfStatement(IfStatement *node) {
   663         node->condition()->accept(this);
   664         node->ifTrue()->accept(this);
   665         if (node->ifFalse())
   666             node->ifFalse()->accept(this);
   667     }
   668     void visitIndexExpression(IndexExpression *node) {
   669         node->left()->accept(this);
   670         node->right()->accept(this);
   671     }
   672     void visitFloatLiteral(FloatLiteral *node) {
   673     }
   674     void visitWhileStatement(WhileStatement *node) {
   675         node->condition()->accept(this);
   676         node->body()->accept(this);
   677     }
   678     void visitBreakStatement(BreakStatement *node) {
   679     }
   680     void visitContinueStatement(ContinueStatement *node) {
   681     }
   682     void visitStringLiteral(StringLiteral *node) {
   683     }
   684     void visitIncDecExpression(IncDecExpression *node) {
   685         node->expression()->accept(this);
   686     }
   687     void visitUnaryExpression(UnaryExpression *node) {
   688         if (node->tag())
   689             node->tag()->accept(this);
   690         node->expression()->accept(this);
   691     }
   692     void visitTernaryExpression(TernaryExpression *node) {
   693         node->condition()->accept(this);
   694         node->left()->accept(this);
   695         node->right()->accept(this);
   696     }
   697     void visitBooleanLiteral(BooleanLiteral *node) {
   698     }
   699     void visitFieldExpression(FieldExpression *node) {
   700         node->left()->accept(this);
   701     }
   702     void visitSwitchStatement(SwitchStatement *node) {
   703         node->expression()->accept(this);
   704         node->defaultCase()->accept(this);
   705         for (size_t i = 0; i < node->cases()->length(); i++) {
   706             // We don't test case expressions because they are literals.
   707             Case *c = node->cases()->at(i);
   708             c->statement()->accept(this);
   709         }
   710     }
   711     void visitArrayLiteral(ArrayLiteral *node) {
   712         for (size_t i = 0; i < node->expressions()->length(); i++)
   713             node->expressions()->at(i)->accept(this);
   714     }
   715     void visitImportStatement(ImportStatement *node) {
   716         if (node->suffix() == TOK_STAR) {
   717             // Import every name.
   718             assert(false);
   719         } else {
   720             GlobalScope *other = node->source()->globalScope();
   721             Symbol *sym = other->findPublic(node->name());
   722             if (!sym) {
   723                 cc_.reportError(node->pos(), Message_CannotResolveImport, node->name()->chars());
   724                 return;
   725             }
   726             link_->scope()->addSymbol(sym);
   727         }
   728     }
   729 
   730   private:
   731     int evaluateDimensions(const SourcePosition &pos, Handle<Type> typeArg, ExpressionList *exprs, int dims[MAX_ARRAY_DEPTH]) {
   732         unsigned level = 0;
   733         Local<Type> type(zone_, typeArg);
   734         while (type->isArray()) {
   735             ArrayType *atype = ArrayType::cast(type);
   736             dims[level] = atype->isFixedLength()
   737                           ? atype->fixedLength()
   738                           : DYNAMIC_ARRAY_SIZE;
   739             type = atype->contained();
   740             level++;
   741         }
   742 
   743         if (!exprs)
   744             return level;
   745 
   746         if (level + exprs->length() > MAX_ARRAY_DEPTH) {
   747             cc_.reportError(pos, Message_MaximumArrayDepth);
   748             return -1;
   749         }
   750 
   751         bool hadEmptySize = false;
   752         for (size_t i = 0; i < exprs->length(); i++) {
   753             Expression *expr = exprs->at(i);
   754             if (!expr) {
   755                 dims[i] = INFER_ARRAY_SIZE;
   756                 hadEmptySize = true;
   757                 continue;
   758             }
   759 
   760             BoxedPrimitive box;
   761             if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
   762                 int size = box.toInt();
   763                 if (size <= 0) {
   764                     cc_.reportError(expr->pos(), Message_BadArraySize);
   765                     return false;
   766                 }
   767 
   768                 dims[i] = size;
   769                 continue;
   770             }
   771 
   772             if (hadEmptySize) {
   773                 cc_.reportError(expr->pos(), Message_BadDynamicInitializer);
   774                 return false;
   775             }
   776 
   777             dims[i] = EVAL_ARRAY_SIZE;
   778         }
   779 
   780         return level + exprs->length();
   781     }
   782 
   783     // This function computes missing dimension sizes based on a literal
   784     // initializer. We don't really handle any size rules here; we just
   785     // do a really dumb inference.
   786     bool inferFixedArrayDimensions(ArrayLiteral *lit, Handle<Type> contained, int dims[MAX_ARRAY_DEPTH], int levels) {
   787         for (int i = 0; i < levels; i++) {
   788             if (dims[i] == EVAL_ARRAY_SIZE || dims[i] == DYNAMIC_ARRAY_SIZE) {
   789                 // The following are invalid:
   790                 //   new x[<expr>] = {...}
   791                 //   new Type:x = {...}  // where Type is a non-fixed array type
   792                 cc_.reportError(lit->pos(), Message_CannotInitializeEvalArray);
   793                 return false;
   794             }
   795 
   796             if (dims[i] == INFER_ARRAY_SIZE) {
   797                 // Character arrays are always dynamic when inferred from string literals.
   798                 if (i == levels - 1 && contained->isChar())
   799                     dims[i] = DYNAMIC_ARRAY_SIZE;
   800                 else
   801                     dims[i] = lit->expressions()->length();
   802             }
   803 
   804             if (i != levels - 1) {
   805                 // Fixed array literals are guaranteed to have at least one expression.
   806                 Expression *next = lit->expressions()->at(0);
   807                 if (!next->isArrayLiteral()) {
   808                     // Whelp... this array is just malformed. Not the best error message
   809                     // but whatever.
   810                     cc_.reportError(next->pos(), Message_ArraySizeCannotBeDetermined);
   811                     return false;
   812                 }
   813                 lit = next->toArrayLiteral();
   814             }
   815         }
   816 
   817         return true;
   818     }
   819 
   820     ArrayType *buildArrayType(Handle<Type> contained, int dims[MAX_ARRAY_DEPTH], size_t postlevels) {
   821         Local<Type> type(zone_, contained);
   822         for (size_t i = postlevels - 1; i < postlevels; i--) {
   823             int size = dims[i] > 0
   824                        ? dims[i]
   825                        : ArrayType::DYNAMIC_ARRAY_SIZE;
   826             
   827             type = zone_->types()->newArray(contained, size);
   828             if (!type)
   829                 return NULL;
   830         }
   831         return ArrayType::cast(type);
   832     }
   833 
   834     bool fillFunctionType(Handle<FunctionType> fun, const FunctionSignature &sig) {
   835         Local<Type> type(zone_);
   836         if (!fun->returnType()) {
   837             if ((type = bindType(sig.returnType())) == NULL)
   838                 return false;
   839             fun->setReturnType(type);
   840         }
   841 
   842         Local<FixedArray> params(zone_, FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old));
   843         if (!params)
   844             return false;
   845 
   846         for (size_t i = 0; i < sig.parameters()->length(); i++) {
   847             Parameter *param = sig.parameters()->at(i);
   848             if ((type = bindType(param->type())) == NULL)
   849                 return false;
   850 
   851             if (type->isArray() || param->dims()) {
   852                 int dims[MAX_ARRAY_DEPTH];
   853                 int levels = evaluateDimensions(param->pos(), type, param->dims(), dims);
   854                 if (levels < 0)
   855                     return false;
   856 
   857                 // If we got extra dimensions, we need to build a new type.
   858                 // Unlike variables, we do not infer anything about array
   859                 // sizes from its default initializer.
   860                 if (param->dims()) {
   861                     if ((type = buildArrayType(type, dims, param->dims()->length())) == NULL)
   862                         return false;
   863                 }
   864 
   865                 if (ArrayType::cast(type)->innermost()->isVoid()) {
   866                     cc_.reportError(param->type()->pos(), Message_CannotDeclareVoid);
   867                     return false;
   868                 }
   869             }
   870 
   871             if (param->reference()) {
   872                 if (!type->isPod()) {
   873                     cc_.reportError(param->pos(), Message_ArrayCantBeReference);
   874                     return false;
   875                 }
   876                 if ((type = zone_->types()->getReference(type, false)) == NULL)
   877                     return false;
   878             }
   879 
   880             if (type->isVoid()) {
   881                 cc_.reportError(param->type()->pos(), Message_CannotDeclareVoid);
   882                 return false;
   883             }
   884 
   885             params->set(zone_, i, type);
   886             param->sym()->setType(type);
   887         }
   888 
   889         fun->setParameterTypes(params);
   890 
   891         return true;
   892     }
   893 
   894     Type *bindType(Expression *expr) {
   895         if (!expr) {
   896             // If no type was declared, we return int32.
   897             return zone_->types()->getPrimitive(PrimitiveType_Int32);
   898         }
   899         
   900         expr->accept(this);
   901 
   902         NameProxy *proxy = expr->asNameProxy();
   903         assert(proxy);
   904 
   905         Symbol *sym = proxy->sym();
   906         if (!sym)
   907             return NULL;
   908 
   909         if (!sym->isType()) {
   910             cc_.reportError(expr->pos(), Message_IdentifierIsNotAType, sym->name()->chars());
   911             return NULL;
   912         }
   913 
   914         return sym->type();
   915     }
   916 
   917   private:
   918     Zone *zone_;
   919     PoolAllocator &pool_;
   920     CompileContext &cc_;
   921     TranslationUnit *unit_;
   922     AutoLinkScope *link_;
   923 };
   924 
   925 bool
   926 ke::BindNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   927 {
   928     NameBinder binder(zone, cc, unit);
   929     return binder.bind();
   930 }