diff -r 2b8512340180 -r bbb498ccb4ac src/compiler/NameBinding.cpp --- a/src/compiler/NameBinding.cpp Sat Dec 22 19:48:43 2012 -0800 +++ b/src/compiler/NameBinding.cpp Sat Dec 22 23:18:57 2012 -0800 @@ -198,13 +198,52 @@ node->initialization()->accept(this); } void visitEnumStatement(EnumStatement *node) { - assert(false); + Local name(zone_, node->name()); + Local type(zone_); + if (name) + type = zone_->types()->newEnum(name); + else + type = zone_->types()->getPrimitive(PrimitiveType_Int32); + + if (!type) + return; + + Scope *scope = getGlobalOrCreateBlockScope(); + if (!scope) + return; + + if (name) { + TypeSymbol *sym = new (pool_) TypeSymbol(scope, name, type); + if (!registerName(scope, sym)) + return; + } + + int value = 0; + for (size_t i = 0; i < node->entries()->length(); i++) { + EnumStatement::Entry &entry = node->entries()->at(i); + BoxedPrimitive box = BoxedPrimitive::Int(value); + if (entry.expr) { + if (!EvaluateForConstant(entry.expr, &box) || box.type() != PrimitiveType_Int32) { + cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant); + return; + } + + assert(box.type() == PrimitiveType_Int32); + value = box.toInt(); + } + + ConstantSymbol *sym = new (pool_) ConstantSymbol(scope, entry.name, entry.pos, type, box); + if (!registerName(scope, sym)) + return; + + value++; + } } void visitFunctionStatement(FunctionStatement *node) { // We create function types ahead of time, not for any particular // reason. It makes things consistent with FunctionTypeStatement, // which actually does produce a type. - Local type(zone_, FunctionType::New(zone_, node->token())); + Local type(zone_, FunctionType::New(zone_, node->name(), node->token())); if (!type) return; @@ -360,6 +399,14 @@ } private: + Scope *getGlobalOrCreateBlockScope() { + if (env_->scope()) { + assert(env_->scope()->kind() == Scope::BLOCK || + env_->scope()->kind() == Scope::GLOBAL); + return env_->scope(); + } + return getOrCreateBlockScope(); + } Scope *getOrCreateBlockScope() { if (env_->scope()) { assert(env_->scope()->kind() == Scope::BLOCK); @@ -546,11 +593,9 @@ return; } - if (link_->scope()->addSymbol(sym)) - return; + link_->scope()->addSymbol(sym); } void visitEnumStatement(EnumStatement *node) { - assert(false); } void visitFunctionStatement(FunctionStatement *node) { AutoLinkScope argScope(&link_, node->argScope());