src/compiler/NameBinding.cpp
changeset 233 bbb498ccb4ac
parent 224 321a652349a6
child 237 c77540a61905
     1.1 --- a/src/compiler/NameBinding.cpp	Sat Dec 22 19:48:43 2012 -0800
     1.2 +++ b/src/compiler/NameBinding.cpp	Sat Dec 22 23:18:57 2012 -0800
     1.3 @@ -198,13 +198,52 @@
     1.4              node->initialization()->accept(this);
     1.5      }
     1.6      void visitEnumStatement(EnumStatement *node) {
     1.7 -        assert(false);
     1.8 +        Local<String> name(zone_, node->name());
     1.9 +        Local<Type> type(zone_);
    1.10 +        if (name)
    1.11 +            type = zone_->types()->newEnum(name);
    1.12 +        else
    1.13 +            type = zone_->types()->getPrimitive(PrimitiveType_Int32);
    1.14 +
    1.15 +        if (!type)
    1.16 +            return;
    1.17 +
    1.18 +        Scope *scope = getGlobalOrCreateBlockScope();
    1.19 +        if (!scope)
    1.20 +            return;
    1.21 +
    1.22 +        if (name) {
    1.23 +            TypeSymbol *sym = new (pool_) TypeSymbol(scope, name, type);
    1.24 +            if (!registerName(scope, sym))
    1.25 +                return;
    1.26 +        }
    1.27 +
    1.28 +        int value = 0;
    1.29 +        for (size_t i = 0; i < node->entries()->length(); i++) {
    1.30 +            EnumStatement::Entry &entry = node->entries()->at(i);
    1.31 +            BoxedPrimitive box = BoxedPrimitive::Int(value);
    1.32 +            if (entry.expr) {
    1.33 +                if (!EvaluateForConstant(entry.expr, &box) || box.type() != PrimitiveType_Int32) {
    1.34 +                    cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
    1.35 +                    return;
    1.36 +                }
    1.37 +
    1.38 +                assert(box.type() == PrimitiveType_Int32);
    1.39 +                value = box.toInt();
    1.40 +            }
    1.41 +            
    1.42 +            ConstantSymbol *sym = new (pool_) ConstantSymbol(scope, entry.name, entry.pos, type, box);
    1.43 +            if (!registerName(scope, sym))
    1.44 +                return;
    1.45 +
    1.46 +            value++;
    1.47 +        }
    1.48      }
    1.49      void visitFunctionStatement(FunctionStatement *node) {
    1.50          // We create function types ahead of time, not for any particular
    1.51          // reason. It makes things consistent with FunctionTypeStatement,
    1.52          // which actually does produce a type.
    1.53 -        Local<FunctionType> type(zone_, FunctionType::New(zone_, node->token()));
    1.54 +        Local<FunctionType> type(zone_, FunctionType::New(zone_, node->name(), node->token()));
    1.55          if (!type)
    1.56              return;
    1.57  
    1.58 @@ -360,6 +399,14 @@
    1.59      }
    1.60  
    1.61    private:
    1.62 +    Scope *getGlobalOrCreateBlockScope() {
    1.63 +        if (env_->scope()) {
    1.64 +            assert(env_->scope()->kind() == Scope::BLOCK ||
    1.65 +                   env_->scope()->kind() == Scope::GLOBAL);
    1.66 +            return env_->scope();
    1.67 +        }
    1.68 +        return getOrCreateBlockScope();
    1.69 +    }
    1.70      Scope *getOrCreateBlockScope() {
    1.71          if (env_->scope()) {
    1.72              assert(env_->scope()->kind() == Scope::BLOCK);
    1.73 @@ -546,11 +593,9 @@
    1.74              return;
    1.75          }
    1.76          
    1.77 -        if (link_->scope()->addSymbol(sym))
    1.78 -            return;
    1.79 +        link_->scope()->addSymbol(sym);
    1.80      }
    1.81      void visitEnumStatement(EnumStatement *node) {
    1.82 -        assert(false);
    1.83      }
    1.84      void visitFunctionStatement(FunctionStatement *node) {
    1.85          AutoLinkScope argScope(&link_, node->argScope());