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());