# HG changeset patch # User David Anderson # Date 1356247137 28800 # Node ID bbb498ccb4acf444f6451adac526f4b7d5dc239d # Parent 2b8512340180409535b6e7b2c745bd6693bafc2d Re-add enum support. diff -r 2b8512340180 -r bbb498ccb4ac src/Handles.h --- a/src/Handles.h Sat Dec 22 19:48:43 2012 -0800 +++ b/src/Handles.h Sat Dec 22 23:18:57 2012 -0800 @@ -85,6 +85,10 @@ return (!thingp_ && !other.thingp_) || *thingp_ == *other.thingp_; } + bool operator !=(const Handle &other) const { + return (!thingp_ != !other.thingp_) || + *thingp_ != *other.thingp_; + } private: template diff -r 2b8512340180 -r bbb498ccb4ac src/Messages.tbl --- a/src/Messages.tbl Sat Dec 22 19:48:43 2012 -0800 +++ b/src/Messages.tbl Sat Dec 22 23:18:57 2012 -0800 @@ -33,8 +33,6 @@ MSG(ArraySizeCannotBeDetermined, SyntaxError, "array size cannot be determined from initializer") MSG(ArrayAssignmentTooBig, SyntaxError, "destination array is too small") MSG(CannotDeclareStringCell, SyntaxError, "cannot declare a String cell") -MSG(BinaryTypeError, SyntaxError, "operator '%s' does not support types '%s' and '%s'") -MSG(UnaryTypeError, SyntaxError, "operator '%s' does not support type '%s'") MSG(CantOpenFile, SyntaxError, "cannot open file") MSG(ErrorSeekingFile, SyntaxError, "error seeking file") MSG(ErrorReadingFile, SyntaxError, "error reading file") @@ -80,4 +78,5 @@ MSG(SizeofNeedsArray, TypeError, "sizeof requires an array") MSG(ImportsMustBeFirst, SyntaxError, "import statements must come before other statements") MSG(ImportedNameAlreadyBound, TypeError, "imported name has already been bound") -MSG(CannotResolveImport, TypeError, "cannot resolve import %s") \ No newline at end of file +MSG(CannotResolveImport, TypeError, "cannot resolve import %s") +MSG(InvalidCoercion, TypeError, "cannot coerce type '%s' to type '%s'") \ No newline at end of file diff -r 2b8512340180 -r bbb498ccb4ac src/ObjectVisitor.h --- a/src/ObjectVisitor.h Sat Dec 22 19:48:43 2012 -0800 +++ b/src/ObjectVisitor.h Sat Dec 22 23:18:57 2012 -0800 @@ -46,10 +46,14 @@ } size_t iterateType(Object *obj) { - visitField(obj, Type::offsetOfName()); return sizeof(Type); } + size_t iterateEnumType(Object *obj) { + visitField(obj, EnumType::offsetOfName()); + return sizeof(EnumType); + } + size_t iterateReferenceType(Object *obj) { iterateType(obj); visitField(obj, ReferenceType::offsetOfContained()); @@ -67,6 +71,7 @@ iterateType(obj); visitField(obj, StructType::offsetOfFields()); visitField(obj, StructType::offsetOfNewMap()); + visitField(obj, StructType::offsetOfName()); return sizeof(StructType); } @@ -75,6 +80,7 @@ visitField(obj, FunctionType::offsetOfReturnType()); visitField(obj, FunctionType::offsetOfParameters()); visitField(obj, FunctionType::offsetOfDefaults()); + visitField(obj, FunctionType::offsetOfName()); return sizeof(FunctionType); } @@ -207,6 +213,9 @@ case MapKind_ArrayType: return iterateArrayType(obj); + case MapKind_EnumType: + return iterateEnumType(obj); + case MapKind_FunctionType: return iterateFunctionType(obj); @@ -293,6 +302,9 @@ case MapKind_ArrayType: return sizeof(ArrayType); + case MapKind_EnumType: + return sizeof(EnumType); + case MapKind_FunctionType: return sizeof(FunctionType); diff -r 2b8512340180 -r bbb498ccb4ac src/Objects.h --- a/src/Objects.h Sat Dec 22 19:48:43 2012 -0800 +++ b/src/Objects.h Sat Dec 22 23:18:57 2012 -0800 @@ -39,6 +39,7 @@ MapKind_StructType, MapKind_ArrayType, MapKind_ReferenceType, + MapKind_EnumType, // Represents basic data structures. When adding to this, don't forget // to update Zone::initialize(), or you'll get a NULL crash trying to diff -r 2b8512340180 -r bbb498ccb4ac src/Opcodes.cpp --- a/src/Opcodes.cpp Sat Dec 22 19:48:43 2012 -0800 +++ b/src/Opcodes.cpp Sat Dec 22 23:18:57 2012 -0800 @@ -256,7 +256,7 @@ { Heap::Tenure tenure = (Heap::Tenure)pc[1]; StructMap *map = StructMap::cast(code->map(READ_UINT32(pc + 1))); - fprintf(fp, "%s", map->type()->name()->chars()); + fprintf(fp, "%s", StructType::cast(map->type())->name()->chars()); if (tenure == Heap::Tenure_Stack) fprintf(fp, " ; lifo"); else if (tenure == Heap::Tenure_Old) diff -r 2b8512340180 -r bbb498ccb4ac src/Platform-Windows.cpp --- a/src/Platform-Windows.cpp Sat Dec 22 19:48:43 2012 -0800 +++ b/src/Platform-Windows.cpp Sat Dec 22 23:18:57 2012 -0800 @@ -2,19 +2,19 @@ * * Copyright (C) 2012 David Anderson * - * This file is part of JITCraft. + * This file is part of SourcePawn. * - * JITCraft is free software: you can redistribute it and/or modify it under + * SourcePawn is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) * any later version. * - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with - * JITCraft. If not, see http://www.gnu.org/licenses/. + * SourcePawn. If not, see http://www.gnu.org/licenses/. */ // :TODO: move into utility-style include diff -r 2b8512340180 -r bbb498ccb4ac src/TypeManager.cpp --- a/src/TypeManager.cpp Sat Dec 22 19:48:43 2012 -0800 +++ b/src/TypeManager.cpp Sat Dec 22 23:18:57 2012 -0800 @@ -64,20 +64,20 @@ return true; } -Type * +ArrayType * TypeManager::newArray(Handle contained, int elements) { // :TODO: cache this. return ArrayType::New(zone_, contained, elements); } -Type * +ArrayType * TypeManager::newExternalArray(Handle contained) { return ArrayType::NewExternal(zone_, contained); } -Type * +ReferenceType * TypeManager::getReference(Handle type, bool isConst) { if (!isConst && type->isPrimitive()) @@ -87,10 +87,10 @@ return ReferenceType::New(zone_, type); } -Type * +EnumType * TypeManager::newEnum(Handle name) { - return Type::NewEnum(zone_, name); + return EnumType::New(zone_, name); } void diff -r 2b8512340180 -r bbb498ccb4ac src/TypeManager.h --- a/src/TypeManager.h Sat Dec 22 19:48:43 2012 -0800 +++ b/src/TypeManager.h Sat Dec 22 23:18:57 2012 -0800 @@ -35,7 +35,7 @@ Unbarriered voidType_; Unbarriered uncheckedType_; Unbarriered primitiveTypes_[PrimitiveTypes_Total]; - Unbarriered referenceTypes_[PrimitiveTypes_Total]; + Unbarriered referenceTypes_[PrimitiveTypes_Total]; public: TypeManager(Zone *zone); @@ -52,10 +52,10 @@ Type *getUnchecked() { return uncheckedType_; } - Type *getReference(Handle type, bool isConst); - Type *newArray(Handle contained, int elements); - Type *newExternalArray(Handle contained); - Type *newEnum(Handle name); + ReferenceType *getReference(Handle type, bool isConst); + ArrayType *newArray(Handle contained, int elements); + ArrayType *newExternalArray(Handle contained); + EnumType *newEnum(Handle name); void accept(VirtualObjectVisitor *visitor); }; diff -r 2b8512340180 -r bbb498ccb4ac src/Types.cpp --- a/src/Types.cpp Sat Dec 22 19:48:43 2012 -0800 +++ b/src/Types.cpp Sat Dec 22 23:18:57 2012 -0800 @@ -55,8 +55,7 @@ return NULL; type->kind_ = PRIMITIVE; - type->name_ = NULL; - type->primitive_ = prim; + type->primitive_ = prim; return type; } @@ -75,7 +74,6 @@ return NULL; type->kind_ = ARRAY; - type->name_ = NULL; type->contained_ = contained; type->elements_ = elements; if (!contained->isArray()) @@ -95,7 +93,6 @@ assert(contained->isPrimitive()); type->kind_ = EXTERNAL_ARRAY; - type->name_ = NULL; type->contained_ = contained; type->elements_ = DYNAMIC_ARRAY_SIZE; type->levels_ = 1; @@ -110,16 +107,15 @@ return NULL; type->kind_ = REFERENCE; - type->name_ = NULL; type->const_ = false; type->contained_ = contained; return type; } -Type * -Type::NewEnum(Zone *zone, Handle name) +EnumType * +EnumType::New(Zone *zone, Handle name) { - Local type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old))); + Local type(zone, EnumType::cast(zone->allocate(MapKind_EnumType, sizeof(EnumType), Heap::Tenure_Old))); if (!type) return NULL; @@ -138,7 +134,6 @@ return NULL; type->kind_ = NATIVE; - type->name_ = NULL; type->contained_ = NULL; type->fields_ = NULL; type->newMap_ = NULL; @@ -217,9 +212,9 @@ return NULL; type->kind_ = STRUCT; - type->name_ = name; type->newMap_ = NULL; type->fields_ = fields; + type->name_ = name; // Fill in field offsets. StructureBufferBuilder builder; @@ -259,17 +254,17 @@ } FunctionType * -FunctionType::New(Zone *zone, TokenKind token) +FunctionType::New(Zone *zone, Handle name, TokenKind token) { Local type(zone, FunctionType::cast(zone->allocate(MapKind_FunctionType, sizeof(FunctionType), Heap::Tenure_Old))); if (!type) return NULL; type->kind_ = FUNCTION; - type->name_ = NULL; type->parameters_ = NULL; type->defaults_ = NULL; type->returnType_ = NULL; + type->name_ = name; type->token_ = token; return type; } @@ -284,8 +279,10 @@ return "function"; if (type->isVoid()) return "void"; - if (type->isEnum() || type->isStruct()) - return type->name()->chars(); + if (type->isEnum()) + return EnumType::cast(type)->name()->chars(); + if (type->isStruct()) + return StructType::cast(type)->name()->chars(); if (type->isReference()) type = ReferenceType::cast(type)->contained(); switch (type->primitive()) { diff -r 2b8512340180 -r bbb498ccb4ac src/Types.h --- a/src/Types.h Sat Dec 22 19:48:43 2012 -0800 +++ b/src/Types.h Sat Dec 22 23:18:57 2012 -0800 @@ -104,7 +104,6 @@ static Type *NewVoid(Zone *zone); static Type *NewUnchecked(Zone *zone); static Type *NewPrimitive(Zone *zone, PrimitiveType type); - static Type *NewEnum(Zone *zone, Handle name); static bool Compare(Type *left, Type *right); @@ -114,7 +113,8 @@ obj->is(MapKind_FunctionType) || obj->is(MapKind_StructType) || obj->is(MapKind_ArrayType) || - obj->is(MapKind_ReferenceType)); + obj->is(MapKind_ReferenceType) || + obj->is(MapKind_EnumType)); return (Type *)obj; } @@ -185,25 +185,35 @@ return kind() == ENUM; } - String *name() { - assert(isEnum() || isStruct()); - return name_; - } - - // GC Descriptor. - static inline size_t offsetOfName() { - return OFFSETOF(Type, name_); - } - // End GC Descriptor. - protected: Kind kind_; PrimitiveType primitive_; // Primitives, arrays, and references. bool const_; +}; - // Enums and structs only. +class EnumType : public Type +{ + public: + static EnumType *New(Zone *Zone, Handle name); + + String *name() { + return name_; + } + + // GC Descriptor. + static inline size_t offsetOfName() { + return OFFSETOF(EnumType, name_); + } + // End GC Descriptor. + + static EnumType *cast(Object *obj) { + assert(!obj || obj->is(MapKind_EnumType)); + return (EnumType *)obj; + } + + private: Barriered name_; }; @@ -325,6 +335,10 @@ newMap_ = map; } + String *name() { + return name_; + } + // GC Descriptor. static inline size_t offsetOfFields() { return OFFSETOF(StructType, fields_); @@ -332,6 +346,9 @@ static inline size_t offsetOfNewMap() { return OFFSETOF(StructType, newMap_); } + static inline size_t offsetOfName() { + return OFFSETOF(StructType, name_); + } // End GC Descriptor. static StructType *cast(Object *obj) { @@ -343,12 +360,13 @@ // Structs only. Barriered fields_; Barriered newMap_; + Barriered name_; }; class FunctionType : public Type { public: - static FunctionType *New(Zone *zone, TokenKind kind); + static FunctionType *New(Zone *zone, Handle name, TokenKind kind); Type *parameterAt(size_t i) { return Type::cast(parameters()->at(i)); @@ -386,6 +404,9 @@ TokenKind token() { return token_; } + String *name() { + return name_; + } // GC Descriptor. static inline size_t offsetOfReturnType() { @@ -397,6 +418,9 @@ static inline size_t offsetOfDefaults() { return OFFSETOF(FunctionType, defaults_); } + static inline size_t offsetOfName() { + return OFFSETOF(FunctionType, name_); + } // End GC Descriptor. static FunctionType *cast(Object *obj) { @@ -409,6 +433,7 @@ Barriered returnType_; Barriered parameters_; Barriered defaults_; + Barriered name_; TokenKind token_; bool variadicNative_; }; diff -r 2b8512340180 -r bbb498ccb4ac src/Zone.cpp --- a/src/Zone.cpp Sat Dec 22 19:48:43 2012 -0800 +++ b/src/Zone.cpp Sat Dec 22 23:18:57 2012 -0800 @@ -81,6 +81,7 @@ MapKind_FunctionType, MapKind_StructType, MapKind_ReferenceType, + MapKind_EnumType, MapKind_FixedArray, MapKind_ByteArray, MapKind_Code, diff -r 2b8512340180 -r bbb498ccb4ac src/compiler/AST.h --- a/src/compiler/AST.h Sat Dec 22 19:48:43 2012 -0800 +++ b/src/compiler/AST.h Sat Dec 22 23:18:57 2012 -0800 @@ -883,10 +883,12 @@ struct Entry { ScopedRoot name; Expression *expr; + SourcePosition pos; - Entry(Handle name, Expression *expr) + Entry(Handle name, Expression *expr, const SourcePosition &pos) : name(name), - expr(expr) + expr(expr), + pos(pos) { } }; 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()); diff -r 2b8512340180 -r bbb498ccb4ac src/compiler/Parser.cpp --- a/src/compiler/Parser.cpp Sat Dec 22 19:48:43 2012 -0800 +++ b/src/compiler/Parser.cpp Sat Dec 22 23:18:57 2012 -0800 @@ -1180,6 +1180,7 @@ if (scanner_.peek() == TOK_RBRACE) break; + SourcePosition &pos = scanner_.begin(); Local name(zone_, expectName()); if (!name) return NULL; @@ -1190,7 +1191,7 @@ return NULL; } - if (!entries->append(EnumStatement::Entry(name, expr))) + if (!entries->append(EnumStatement::Entry(name, expr, pos))) return NULL; } while (match(TOK_COMMA)); if (!expect(TOK_RBRACE)) diff -r 2b8512340180 -r bbb498ccb4ac src/compiler/SemanticAnalysis.cpp --- a/src/compiler/SemanticAnalysis.cpp Sat Dec 22 19:48:43 2012 -0800 +++ b/src/compiler/SemanticAnalysis.cpp Sat Dec 22 23:18:57 2012 -0800 @@ -214,6 +214,11 @@ } void +SemanticAnalysis::visitEnumStatement(EnumStatement *node) +{ +} + +void SemanticAnalysis::visitExpressionStatement(ExpressionStatement *node) { // While building HIR, we enter new pool and root scopes, since HIR @@ -545,24 +550,51 @@ SemanticAnalysis::visitNameProxy(NameProxy *proxy) { Symbol *sym = proxy->sym(); - VariableSymbol *var = sym->asVariable(); - Scope *in = sym->scope(); - switch (in->kind()) { - case Scope::GLOBAL: - hir_ = new (pool_) HGlobal(proxy, sym); - return; + switch (sym->kind()) { + case Symbol::kConstant: + { + ConstantSymbol *val = sym->toConstant(); + hir_ = new (pool_) HInteger(proxy, sym->type(), val->value().toInt()); + break; + } + + // This is kind of screwy. Symbol::kFunction is like a constant we can't + // evaluate yet. Maybe we should extract the GLOBAL case and say that + // kFunction is only used for global functions (and use const vars for + // local functions). + case Symbol::kFunction: + case Symbol::kVariable: + { + Scope *in = sym->scope(); + switch (in->kind()) { + case Scope::GLOBAL: + hir_ = new (pool_) HGlobal(proxy, sym); + break; - case Scope::FUNCTION: - assert(var->storage() == VariableSymbol::Arg); - hir_ = new (pool_) HLocal(proxy, var); - return; + case Scope::FUNCTION: + { + VariableSymbol *var = sym->toVariable(); + assert(var->storage() == VariableSymbol::Arg); + hir_ = new (pool_) HLocal(proxy, var); + break; + } + + default: + { + VariableSymbol *var = sym->toVariable(); + assert(in->kind() == Scope::BLOCK); + assert(var->storage() == VariableSymbol::Local); + hir_ = new (pool_) HLocal(proxy, var); + break; + } + } + break; + } default: - assert(in->kind() == Scope::BLOCK); - assert(var->storage() == VariableSymbol::Local); - hir_ = new (pool_) HLocal(proxy, var); - return; + // :TODO: + assert(false); } } @@ -854,6 +886,15 @@ } HIR * +SemanticAnalysis::typeFailure(const SourcePosition &pos, Handle from, Handle to) +{ + cc_.reportError(pos, Message_InvalidCoercion, + GetTypeName(from), + GetTypeName(to)); + return NULL; +} + +HIR * SemanticAnalysis::coerce(HIR *hir, Handle to, CoercionKind kind) { Handle from = hir->type(); @@ -862,6 +903,9 @@ return new (pool_) HConvert(hir->node(), to, OP_CVT_I2F, hir); if (from->isInt32() && to->isBool()) return new (pool_) HConvert(hir->node(), to, OP_CVT_I2B, hir); + + if (to->isEnum() && from != to) + return typeFailure(hir->node()->pos(), from, to); if (to->isArray()) { if (!typeCheckArray(SourcePosition(), from, to, kind)) diff -r 2b8512340180 -r bbb498ccb4ac src/compiler/SemanticAnalysis.h --- a/src/compiler/SemanticAnalysis.h Sat Dec 22 19:48:43 2012 -0800 +++ b/src/compiler/SemanticAnalysis.h Sat Dec 22 23:18:57 2012 -0800 @@ -48,6 +48,7 @@ void visitBlockStatement(BlockStatement *node); void visitExpressionStatement(ExpressionStatement *node); void visitReturnStatement(ReturnStatement *node); + void visitEnumStatement(EnumStatement *node); void visitCallExpression(CallExpression *node); void visitNameProxy(NameProxy *name); @@ -66,7 +67,6 @@ #if 0 void visitFunctionTypeStatement(FunctionTypeStatement *node); void visitImportStatement(ImportStatement *node); - void visitEnumStatement(EnumStatement *node); void visitStructureStatement(StructureStatement *node); void visitSwitchStatement(SwitchStatement *node); @@ -178,6 +178,7 @@ Type *coercionType(TokenKind token, HIR *left, HIR *right); HLValue *lvalue(Expression *expr); void discharge(HIR *hir); + HIR *typeFailure(const SourcePosition &pos, Handle from, Handle to); bool typeCheckArray(const SourcePosition &pos, Handle argGiven, diff -r 2b8512340180 -r bbb498ccb4ac src/compiler/Symbols.h --- a/src/compiler/Symbols.h Sat Dec 22 19:48:43 2012 -0800 +++ b/src/compiler/Symbols.h Sat Dec 22 23:18:57 2012 -0800 @@ -186,6 +186,28 @@ } }; +class ConstantSymbol : public Symbol +{ + public: + ConstantSymbol(Scope *scope, Handle name, const SourcePosition &pos, Handle type, + const BoxedPrimitive &prim) + : Symbol(scope, name, pos), + value_(prim) + { + type_ = type; + } + + Kind kind() const { + return kConstant; + } + const BoxedPrimitive &value() const { + return value_; + } + + private: + BoxedPrimitive value_; +}; + } #endif // _include_sp2_symbol_h_ diff -r 2b8512340180 -r bbb498ccb4ac tests/basic/enum-bad.err --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/basic/enum-bad.err Sat Dec 22 23:18:57 2012 -0800 @@ -0,0 +1,1 @@ + line 6, col 13: cannot coerce type 'int' to type 'X' diff -r 2b8512340180 -r bbb498ccb4ac tests/basic/enum-bad.sp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/basic/enum-bad.sp Sat Dec 22 23:18:57 2012 -0800 @@ -0,0 +1,7 @@ +enum X { +}; + +public main() +{ + new X:x = 5; +} diff -r 2b8512340180 -r bbb498ccb4ac tests/basic/enum-redecl.err --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/basic/enum-redecl.err Sat Dec 22 23:18:57 2012 -0800 @@ -0,0 +1,1 @@ + line 4, col 4: name 'Y' was redeclared (previous at line 2, col 4) diff -r 2b8512340180 -r bbb498ccb4ac tests/basic/enum-redecl.sp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/basic/enum-redecl.sp Sat Dec 22 23:18:57 2012 -0800 @@ -0,0 +1,6 @@ +enum X { + Y, + Z, + Y +}; + diff -r 2b8512340180 -r bbb498ccb4ac tests/basic/enum-use.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/basic/enum-use.out Sat Dec 22 23:18:57 2012 -0800 @@ -0,0 +1,1 @@ +01570157 diff -r 2b8512340180 -r bbb498ccb4ac tests/basic/enum-use.sp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/basic/enum-use.sp Sat Dec 22 23:18:57 2012 -0800 @@ -0,0 +1,28 @@ +native PrintNum(num); + +enum Crab { + CrabOne, + CrabTwo, + CrabThree=5, + CrabFour=7 +}; + +enum { + CrabFive, + CrabSix, + CrabSeven=5, + CrabEight=7 +}; + +public main() +{ + PrintNum(CrabOne); + PrintNum(CrabTwo); + PrintNum(CrabThree); + PrintNum(CrabFour); + PrintNum(CrabFive); + PrintNum(CrabSix); + PrintNum(CrabSeven); + PrintNum(CrabEight); +} +