Re-add enum support.
Re-add enum support.
1.1 --- a/src/Handles.h Sat Dec 22 19:48:43 2012 -0800
1.2 +++ b/src/Handles.h Sat Dec 22 23:18:57 2012 -0800
1.3 @@ -85,6 +85,10 @@
1.4 return (!thingp_ && !other.thingp_) ||
1.5 *thingp_ == *other.thingp_;
1.6 }
1.7 + bool operator !=(const Handle<T> &other) const {
1.8 + return (!thingp_ != !other.thingp_) ||
1.9 + *thingp_ != *other.thingp_;
1.10 + }
1.11
1.12 private:
1.13 template <typename S>
2.1 --- a/src/Messages.tbl Sat Dec 22 19:48:43 2012 -0800
2.2 +++ b/src/Messages.tbl Sat Dec 22 23:18:57 2012 -0800
2.3 @@ -33,8 +33,6 @@
2.4 MSG(ArraySizeCannotBeDetermined, SyntaxError, "array size cannot be determined from initializer")
2.5 MSG(ArrayAssignmentTooBig, SyntaxError, "destination array is too small")
2.6 MSG(CannotDeclareStringCell, SyntaxError, "cannot declare a String cell")
2.7 -MSG(BinaryTypeError, SyntaxError, "operator '%s' does not support types '%s' and '%s'")
2.8 -MSG(UnaryTypeError, SyntaxError, "operator '%s' does not support type '%s'")
2.9 MSG(CantOpenFile, SyntaxError, "cannot open file")
2.10 MSG(ErrorSeekingFile, SyntaxError, "error seeking file")
2.11 MSG(ErrorReadingFile, SyntaxError, "error reading file")
2.12 @@ -80,4 +78,5 @@
2.13 MSG(SizeofNeedsArray, TypeError, "sizeof requires an array")
2.14 MSG(ImportsMustBeFirst, SyntaxError, "import statements must come before other statements")
2.15 MSG(ImportedNameAlreadyBound, TypeError, "imported name has already been bound")
2.16 -MSG(CannotResolveImport, TypeError, "cannot resolve import %s")
2.17 \ No newline at end of file
2.18 +MSG(CannotResolveImport, TypeError, "cannot resolve import %s")
2.19 +MSG(InvalidCoercion, TypeError, "cannot coerce type '%s' to type '%s'")
2.20 \ No newline at end of file
3.1 --- a/src/ObjectVisitor.h Sat Dec 22 19:48:43 2012 -0800
3.2 +++ b/src/ObjectVisitor.h Sat Dec 22 23:18:57 2012 -0800
3.3 @@ -46,10 +46,14 @@
3.4 }
3.5
3.6 size_t iterateType(Object *obj) {
3.7 - visitField(obj, Type::offsetOfName());
3.8 return sizeof(Type);
3.9 }
3.10
3.11 + size_t iterateEnumType(Object *obj) {
3.12 + visitField(obj, EnumType::offsetOfName());
3.13 + return sizeof(EnumType);
3.14 + }
3.15 +
3.16 size_t iterateReferenceType(Object *obj) {
3.17 iterateType(obj);
3.18 visitField(obj, ReferenceType::offsetOfContained());
3.19 @@ -67,6 +71,7 @@
3.20 iterateType(obj);
3.21 visitField(obj, StructType::offsetOfFields());
3.22 visitField(obj, StructType::offsetOfNewMap());
3.23 + visitField(obj, StructType::offsetOfName());
3.24 return sizeof(StructType);
3.25 }
3.26
3.27 @@ -75,6 +80,7 @@
3.28 visitField(obj, FunctionType::offsetOfReturnType());
3.29 visitField(obj, FunctionType::offsetOfParameters());
3.30 visitField(obj, FunctionType::offsetOfDefaults());
3.31 + visitField(obj, FunctionType::offsetOfName());
3.32 return sizeof(FunctionType);
3.33 }
3.34
3.35 @@ -207,6 +213,9 @@
3.36 case MapKind_ArrayType:
3.37 return iterateArrayType(obj);
3.38
3.39 + case MapKind_EnumType:
3.40 + return iterateEnumType(obj);
3.41 +
3.42 case MapKind_FunctionType:
3.43 return iterateFunctionType(obj);
3.44
3.45 @@ -293,6 +302,9 @@
3.46 case MapKind_ArrayType:
3.47 return sizeof(ArrayType);
3.48
3.49 + case MapKind_EnumType:
3.50 + return sizeof(EnumType);
3.51 +
3.52 case MapKind_FunctionType:
3.53 return sizeof(FunctionType);
3.54
4.1 --- a/src/Objects.h Sat Dec 22 19:48:43 2012 -0800
4.2 +++ b/src/Objects.h Sat Dec 22 23:18:57 2012 -0800
4.3 @@ -39,6 +39,7 @@
4.4 MapKind_StructType,
4.5 MapKind_ArrayType,
4.6 MapKind_ReferenceType,
4.7 + MapKind_EnumType,
4.8
4.9 // Represents basic data structures. When adding to this, don't forget
4.10 // to update Zone::initialize(), or you'll get a NULL crash trying to
5.1 --- a/src/Opcodes.cpp Sat Dec 22 19:48:43 2012 -0800
5.2 +++ b/src/Opcodes.cpp Sat Dec 22 23:18:57 2012 -0800
5.3 @@ -256,7 +256,7 @@
5.4 {
5.5 Heap::Tenure tenure = (Heap::Tenure)pc[1];
5.6 StructMap *map = StructMap::cast(code->map(READ_UINT32(pc + 1)));
5.7 - fprintf(fp, "%s", map->type()->name()->chars());
5.8 + fprintf(fp, "%s", StructType::cast(map->type())->name()->chars());
5.9 if (tenure == Heap::Tenure_Stack)
5.10 fprintf(fp, " ; lifo");
5.11 else if (tenure == Heap::Tenure_Old)
6.1 --- a/src/Platform-Windows.cpp Sat Dec 22 19:48:43 2012 -0800
6.2 +++ b/src/Platform-Windows.cpp Sat Dec 22 23:18:57 2012 -0800
6.3 @@ -2,19 +2,19 @@
6.4 *
6.5 * Copyright (C) 2012 David Anderson
6.6 *
6.7 - * This file is part of JITCraft.
6.8 + * This file is part of SourcePawn.
6.9 *
6.10 - * JITCraft is free software: you can redistribute it and/or modify it under
6.11 + * SourcePawn is free software: you can redistribute it and/or modify it under
6.12 * the terms of the GNU General Public License as published by the Free
6.13 * Software Foundation, either version 3 of the License, or (at your option)
6.14 * any later version.
6.15 *
6.16 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
6.17 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
6.18 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
6.19 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
6.20 *
6.21 * You should have received a copy of the GNU General Public License along with
6.22 - * JITCraft. If not, see http://www.gnu.org/licenses/.
6.23 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
6.24 */
6.25
6.26 // :TODO: move into utility-style include
7.1 --- a/src/TypeManager.cpp Sat Dec 22 19:48:43 2012 -0800
7.2 +++ b/src/TypeManager.cpp Sat Dec 22 23:18:57 2012 -0800
7.3 @@ -64,20 +64,20 @@
7.4 return true;
7.5 }
7.6
7.7 -Type *
7.8 +ArrayType *
7.9 TypeManager::newArray(Handle<Type> contained, int elements)
7.10 {
7.11 // :TODO: cache this.
7.12 return ArrayType::New(zone_, contained, elements);
7.13 }
7.14
7.15 -Type *
7.16 +ArrayType *
7.17 TypeManager::newExternalArray(Handle<Type> contained)
7.18 {
7.19 return ArrayType::NewExternal(zone_, contained);
7.20 }
7.21
7.22 -Type *
7.23 +ReferenceType *
7.24 TypeManager::getReference(Handle<Type> type, bool isConst)
7.25 {
7.26 if (!isConst && type->isPrimitive())
7.27 @@ -87,10 +87,10 @@
7.28 return ReferenceType::New(zone_, type);
7.29 }
7.30
7.31 -Type *
7.32 +EnumType *
7.33 TypeManager::newEnum(Handle<String> name)
7.34 {
7.35 - return Type::NewEnum(zone_, name);
7.36 + return EnumType::New(zone_, name);
7.37 }
7.38
7.39 void
8.1 --- a/src/TypeManager.h Sat Dec 22 19:48:43 2012 -0800
8.2 +++ b/src/TypeManager.h Sat Dec 22 23:18:57 2012 -0800
8.3 @@ -35,7 +35,7 @@
8.4 Unbarriered<Type> voidType_;
8.5 Unbarriered<Type> uncheckedType_;
8.6 Unbarriered<Type> primitiveTypes_[PrimitiveTypes_Total];
8.7 - Unbarriered<Type> referenceTypes_[PrimitiveTypes_Total];
8.8 + Unbarriered<ReferenceType> referenceTypes_[PrimitiveTypes_Total];
8.9
8.10 public:
8.11 TypeManager(Zone *zone);
8.12 @@ -52,10 +52,10 @@
8.13 Type *getUnchecked() {
8.14 return uncheckedType_;
8.15 }
8.16 - Type *getReference(Handle<Type> type, bool isConst);
8.17 - Type *newArray(Handle<Type> contained, int elements);
8.18 - Type *newExternalArray(Handle<Type> contained);
8.19 - Type *newEnum(Handle<String> name);
8.20 + ReferenceType *getReference(Handle<Type> type, bool isConst);
8.21 + ArrayType *newArray(Handle<Type> contained, int elements);
8.22 + ArrayType *newExternalArray(Handle<Type> contained);
8.23 + EnumType *newEnum(Handle<String> name);
8.24
8.25 void accept(VirtualObjectVisitor *visitor);
8.26 };
9.1 --- a/src/Types.cpp Sat Dec 22 19:48:43 2012 -0800
9.2 +++ b/src/Types.cpp Sat Dec 22 23:18:57 2012 -0800
9.3 @@ -55,8 +55,7 @@
9.4 return NULL;
9.5
9.6 type->kind_ = PRIMITIVE;
9.7 - type->name_ = NULL;
9.8 - type->primitive_ = prim;
9.9 + type->primitive_ = prim;
9.10 return type;
9.11 }
9.12
9.13 @@ -75,7 +74,6 @@
9.14 return NULL;
9.15
9.16 type->kind_ = ARRAY;
9.17 - type->name_ = NULL;
9.18 type->contained_ = contained;
9.19 type->elements_ = elements;
9.20 if (!contained->isArray())
9.21 @@ -95,7 +93,6 @@
9.22 assert(contained->isPrimitive());
9.23
9.24 type->kind_ = EXTERNAL_ARRAY;
9.25 - type->name_ = NULL;
9.26 type->contained_ = contained;
9.27 type->elements_ = DYNAMIC_ARRAY_SIZE;
9.28 type->levels_ = 1;
9.29 @@ -110,16 +107,15 @@
9.30 return NULL;
9.31
9.32 type->kind_ = REFERENCE;
9.33 - type->name_ = NULL;
9.34 type->const_ = false;
9.35 type->contained_ = contained;
9.36 return type;
9.37 }
9.38
9.39 -Type *
9.40 -Type::NewEnum(Zone *zone, Handle<String> name)
9.41 +EnumType *
9.42 +EnumType::New(Zone *zone, Handle<String> name)
9.43 {
9.44 - Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
9.45 + Local<EnumType> type(zone, EnumType::cast(zone->allocate(MapKind_EnumType, sizeof(EnumType), Heap::Tenure_Old)));
9.46 if (!type)
9.47 return NULL;
9.48
9.49 @@ -138,7 +134,6 @@
9.50 return NULL;
9.51
9.52 type->kind_ = NATIVE;
9.53 - type->name_ = NULL;
9.54 type->contained_ = NULL;
9.55 type->fields_ = NULL;
9.56 type->newMap_ = NULL;
9.57 @@ -217,9 +212,9 @@
9.58 return NULL;
9.59
9.60 type->kind_ = STRUCT;
9.61 - type->name_ = name;
9.62 type->newMap_ = NULL;
9.63 type->fields_ = fields;
9.64 + type->name_ = name;
9.65
9.66 // Fill in field offsets.
9.67 StructureBufferBuilder builder;
9.68 @@ -259,17 +254,17 @@
9.69 }
9.70
9.71 FunctionType *
9.72 -FunctionType::New(Zone *zone, TokenKind token)
9.73 +FunctionType::New(Zone *zone, Handle<String> name, TokenKind token)
9.74 {
9.75 Local<FunctionType> type(zone, FunctionType::cast(zone->allocate(MapKind_FunctionType, sizeof(FunctionType), Heap::Tenure_Old)));
9.76 if (!type)
9.77 return NULL;
9.78
9.79 type->kind_ = FUNCTION;
9.80 - type->name_ = NULL;
9.81 type->parameters_ = NULL;
9.82 type->defaults_ = NULL;
9.83 type->returnType_ = NULL;
9.84 + type->name_ = name;
9.85 type->token_ = token;
9.86 return type;
9.87 }
9.88 @@ -284,8 +279,10 @@
9.89 return "function";
9.90 if (type->isVoid())
9.91 return "void";
9.92 - if (type->isEnum() || type->isStruct())
9.93 - return type->name()->chars();
9.94 + if (type->isEnum())
9.95 + return EnumType::cast(type)->name()->chars();
9.96 + if (type->isStruct())
9.97 + return StructType::cast(type)->name()->chars();
9.98 if (type->isReference())
9.99 type = ReferenceType::cast(type)->contained();
9.100 switch (type->primitive()) {
10.1 --- a/src/Types.h Sat Dec 22 19:48:43 2012 -0800
10.2 +++ b/src/Types.h Sat Dec 22 23:18:57 2012 -0800
10.3 @@ -104,7 +104,6 @@
10.4 static Type *NewVoid(Zone *zone);
10.5 static Type *NewUnchecked(Zone *zone);
10.6 static Type *NewPrimitive(Zone *zone, PrimitiveType type);
10.7 - static Type *NewEnum(Zone *zone, Handle<String> name);
10.8
10.9 static bool Compare(Type *left, Type *right);
10.10
10.11 @@ -114,7 +113,8 @@
10.12 obj->is(MapKind_FunctionType) ||
10.13 obj->is(MapKind_StructType) ||
10.14 obj->is(MapKind_ArrayType) ||
10.15 - obj->is(MapKind_ReferenceType));
10.16 + obj->is(MapKind_ReferenceType) ||
10.17 + obj->is(MapKind_EnumType));
10.18 return (Type *)obj;
10.19 }
10.20
10.21 @@ -185,25 +185,35 @@
10.22 return kind() == ENUM;
10.23 }
10.24
10.25 - String *name() {
10.26 - assert(isEnum() || isStruct());
10.27 - return name_;
10.28 - }
10.29 -
10.30 - // GC Descriptor.
10.31 - static inline size_t offsetOfName() {
10.32 - return OFFSETOF(Type, name_);
10.33 - }
10.34 - // End GC Descriptor.
10.35 -
10.36 protected:
10.37 Kind kind_;
10.38 PrimitiveType primitive_;
10.39
10.40 // Primitives, arrays, and references.
10.41 bool const_;
10.42 +};
10.43
10.44 - // Enums and structs only.
10.45 +class EnumType : public Type
10.46 +{
10.47 + public:
10.48 + static EnumType *New(Zone *Zone, Handle<String> name);
10.49 +
10.50 + String *name() {
10.51 + return name_;
10.52 + }
10.53 +
10.54 + // GC Descriptor.
10.55 + static inline size_t offsetOfName() {
10.56 + return OFFSETOF(EnumType, name_);
10.57 + }
10.58 + // End GC Descriptor.
10.59 +
10.60 + static EnumType *cast(Object *obj) {
10.61 + assert(!obj || obj->is(MapKind_EnumType));
10.62 + return (EnumType *)obj;
10.63 + }
10.64 +
10.65 + private:
10.66 Barriered<String> name_;
10.67 };
10.68
10.69 @@ -325,6 +335,10 @@
10.70 newMap_ = map;
10.71 }
10.72
10.73 + String *name() {
10.74 + return name_;
10.75 + }
10.76 +
10.77 // GC Descriptor.
10.78 static inline size_t offsetOfFields() {
10.79 return OFFSETOF(StructType, fields_);
10.80 @@ -332,6 +346,9 @@
10.81 static inline size_t offsetOfNewMap() {
10.82 return OFFSETOF(StructType, newMap_);
10.83 }
10.84 + static inline size_t offsetOfName() {
10.85 + return OFFSETOF(StructType, name_);
10.86 + }
10.87 // End GC Descriptor.
10.88
10.89 static StructType *cast(Object *obj) {
10.90 @@ -343,12 +360,13 @@
10.91 // Structs only.
10.92 Barriered<FixedArray> fields_;
10.93 Barriered<StructMap> newMap_;
10.94 + Barriered<String> name_;
10.95 };
10.96
10.97 class FunctionType : public Type
10.98 {
10.99 public:
10.100 - static FunctionType *New(Zone *zone, TokenKind kind);
10.101 + static FunctionType *New(Zone *zone, Handle<String> name, TokenKind kind);
10.102
10.103 Type *parameterAt(size_t i) {
10.104 return Type::cast(parameters()->at(i));
10.105 @@ -386,6 +404,9 @@
10.106 TokenKind token() {
10.107 return token_;
10.108 }
10.109 + String *name() {
10.110 + return name_;
10.111 + }
10.112
10.113 // GC Descriptor.
10.114 static inline size_t offsetOfReturnType() {
10.115 @@ -397,6 +418,9 @@
10.116 static inline size_t offsetOfDefaults() {
10.117 return OFFSETOF(FunctionType, defaults_);
10.118 }
10.119 + static inline size_t offsetOfName() {
10.120 + return OFFSETOF(FunctionType, name_);
10.121 + }
10.122 // End GC Descriptor.
10.123
10.124 static FunctionType *cast(Object *obj) {
10.125 @@ -409,6 +433,7 @@
10.126 Barriered<Type> returnType_;
10.127 Barriered<FixedArray> parameters_;
10.128 Barriered<FixedArray> defaults_;
10.129 + Barriered<String> name_;
10.130 TokenKind token_;
10.131 bool variadicNative_;
10.132 };
11.1 --- a/src/Zone.cpp Sat Dec 22 19:48:43 2012 -0800
11.2 +++ b/src/Zone.cpp Sat Dec 22 23:18:57 2012 -0800
11.3 @@ -81,6 +81,7 @@
11.4 MapKind_FunctionType,
11.5 MapKind_StructType,
11.6 MapKind_ReferenceType,
11.7 + MapKind_EnumType,
11.8 MapKind_FixedArray,
11.9 MapKind_ByteArray,
11.10 MapKind_Code,
12.1 --- a/src/compiler/AST.h Sat Dec 22 19:48:43 2012 -0800
12.2 +++ b/src/compiler/AST.h Sat Dec 22 23:18:57 2012 -0800
12.3 @@ -883,10 +883,12 @@
12.4 struct Entry {
12.5 ScopedRoot<String> name;
12.6 Expression *expr;
12.7 + SourcePosition pos;
12.8
12.9 - Entry(Handle<String> name, Expression *expr)
12.10 + Entry(Handle<String> name, Expression *expr, const SourcePosition &pos)
12.11 : name(name),
12.12 - expr(expr)
12.13 + expr(expr),
12.14 + pos(pos)
12.15 {
12.16 }
12.17 };
13.1 --- a/src/compiler/NameBinding.cpp Sat Dec 22 19:48:43 2012 -0800
13.2 +++ b/src/compiler/NameBinding.cpp Sat Dec 22 23:18:57 2012 -0800
13.3 @@ -198,13 +198,52 @@
13.4 node->initialization()->accept(this);
13.5 }
13.6 void visitEnumStatement(EnumStatement *node) {
13.7 - assert(false);
13.8 + Local<String> name(zone_, node->name());
13.9 + Local<Type> type(zone_);
13.10 + if (name)
13.11 + type = zone_->types()->newEnum(name);
13.12 + else
13.13 + type = zone_->types()->getPrimitive(PrimitiveType_Int32);
13.14 +
13.15 + if (!type)
13.16 + return;
13.17 +
13.18 + Scope *scope = getGlobalOrCreateBlockScope();
13.19 + if (!scope)
13.20 + return;
13.21 +
13.22 + if (name) {
13.23 + TypeSymbol *sym = new (pool_) TypeSymbol(scope, name, type);
13.24 + if (!registerName(scope, sym))
13.25 + return;
13.26 + }
13.27 +
13.28 + int value = 0;
13.29 + for (size_t i = 0; i < node->entries()->length(); i++) {
13.30 + EnumStatement::Entry &entry = node->entries()->at(i);
13.31 + BoxedPrimitive box = BoxedPrimitive::Int(value);
13.32 + if (entry.expr) {
13.33 + if (!EvaluateForConstant(entry.expr, &box) || box.type() != PrimitiveType_Int32) {
13.34 + cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
13.35 + return;
13.36 + }
13.37 +
13.38 + assert(box.type() == PrimitiveType_Int32);
13.39 + value = box.toInt();
13.40 + }
13.41 +
13.42 + ConstantSymbol *sym = new (pool_) ConstantSymbol(scope, entry.name, entry.pos, type, box);
13.43 + if (!registerName(scope, sym))
13.44 + return;
13.45 +
13.46 + value++;
13.47 + }
13.48 }
13.49 void visitFunctionStatement(FunctionStatement *node) {
13.50 // We create function types ahead of time, not for any particular
13.51 // reason. It makes things consistent with FunctionTypeStatement,
13.52 // which actually does produce a type.
13.53 - Local<FunctionType> type(zone_, FunctionType::New(zone_, node->token()));
13.54 + Local<FunctionType> type(zone_, FunctionType::New(zone_, node->name(), node->token()));
13.55 if (!type)
13.56 return;
13.57
13.58 @@ -360,6 +399,14 @@
13.59 }
13.60
13.61 private:
13.62 + Scope *getGlobalOrCreateBlockScope() {
13.63 + if (env_->scope()) {
13.64 + assert(env_->scope()->kind() == Scope::BLOCK ||
13.65 + env_->scope()->kind() == Scope::GLOBAL);
13.66 + return env_->scope();
13.67 + }
13.68 + return getOrCreateBlockScope();
13.69 + }
13.70 Scope *getOrCreateBlockScope() {
13.71 if (env_->scope()) {
13.72 assert(env_->scope()->kind() == Scope::BLOCK);
13.73 @@ -546,11 +593,9 @@
13.74 return;
13.75 }
13.76
13.77 - if (link_->scope()->addSymbol(sym))
13.78 - return;
13.79 + link_->scope()->addSymbol(sym);
13.80 }
13.81 void visitEnumStatement(EnumStatement *node) {
13.82 - assert(false);
13.83 }
13.84 void visitFunctionStatement(FunctionStatement *node) {
13.85 AutoLinkScope argScope(&link_, node->argScope());
14.1 --- a/src/compiler/Parser.cpp Sat Dec 22 19:48:43 2012 -0800
14.2 +++ b/src/compiler/Parser.cpp Sat Dec 22 23:18:57 2012 -0800
14.3 @@ -1180,6 +1180,7 @@
14.4 if (scanner_.peek() == TOK_RBRACE)
14.5 break;
14.6
14.7 + SourcePosition &pos = scanner_.begin();
14.8 Local<String> name(zone_, expectName());
14.9 if (!name)
14.10 return NULL;
14.11 @@ -1190,7 +1191,7 @@
14.12 return NULL;
14.13 }
14.14
14.15 - if (!entries->append(EnumStatement::Entry(name, expr)))
14.16 + if (!entries->append(EnumStatement::Entry(name, expr, pos)))
14.17 return NULL;
14.18 } while (match(TOK_COMMA));
14.19 if (!expect(TOK_RBRACE))
15.1 --- a/src/compiler/SemanticAnalysis.cpp Sat Dec 22 19:48:43 2012 -0800
15.2 +++ b/src/compiler/SemanticAnalysis.cpp Sat Dec 22 23:18:57 2012 -0800
15.3 @@ -214,6 +214,11 @@
15.4 }
15.5
15.6 void
15.7 +SemanticAnalysis::visitEnumStatement(EnumStatement *node)
15.8 +{
15.9 +}
15.10 +
15.11 +void
15.12 SemanticAnalysis::visitExpressionStatement(ExpressionStatement *node)
15.13 {
15.14 // While building HIR, we enter new pool and root scopes, since HIR
15.15 @@ -545,24 +550,51 @@
15.16 SemanticAnalysis::visitNameProxy(NameProxy *proxy)
15.17 {
15.18 Symbol *sym = proxy->sym();
15.19 - VariableSymbol *var = sym->asVariable();
15.20
15.21 - Scope *in = sym->scope();
15.22 - switch (in->kind()) {
15.23 - case Scope::GLOBAL:
15.24 - hir_ = new (pool_) HGlobal(proxy, sym);
15.25 - return;
15.26 + switch (sym->kind()) {
15.27 + case Symbol::kConstant:
15.28 + {
15.29 + ConstantSymbol *val = sym->toConstant();
15.30 + hir_ = new (pool_) HInteger(proxy, sym->type(), val->value().toInt());
15.31 + break;
15.32 + }
15.33 +
15.34 + // This is kind of screwy. Symbol::kFunction is like a constant we can't
15.35 + // evaluate yet. Maybe we should extract the GLOBAL case and say that
15.36 + // kFunction is only used for global functions (and use const vars for
15.37 + // local functions).
15.38 + case Symbol::kFunction:
15.39 + case Symbol::kVariable:
15.40 + {
15.41 + Scope *in = sym->scope();
15.42 + switch (in->kind()) {
15.43 + case Scope::GLOBAL:
15.44 + hir_ = new (pool_) HGlobal(proxy, sym);
15.45 + break;
15.46
15.47 - case Scope::FUNCTION:
15.48 - assert(var->storage() == VariableSymbol::Arg);
15.49 - hir_ = new (pool_) HLocal(proxy, var);
15.50 - return;
15.51 + case Scope::FUNCTION:
15.52 + {
15.53 + VariableSymbol *var = sym->toVariable();
15.54 + assert(var->storage() == VariableSymbol::Arg);
15.55 + hir_ = new (pool_) HLocal(proxy, var);
15.56 + break;
15.57 + }
15.58 +
15.59 + default:
15.60 + {
15.61 + VariableSymbol *var = sym->toVariable();
15.62 + assert(in->kind() == Scope::BLOCK);
15.63 + assert(var->storage() == VariableSymbol::Local);
15.64 + hir_ = new (pool_) HLocal(proxy, var);
15.65 + break;
15.66 + }
15.67 + }
15.68 + break;
15.69 + }
15.70
15.71 default:
15.72 - assert(in->kind() == Scope::BLOCK);
15.73 - assert(var->storage() == VariableSymbol::Local);
15.74 - hir_ = new (pool_) HLocal(proxy, var);
15.75 - return;
15.76 + // :TODO:
15.77 + assert(false);
15.78 }
15.79 }
15.80
15.81 @@ -854,6 +886,15 @@
15.82 }
15.83
15.84 HIR *
15.85 +SemanticAnalysis::typeFailure(const SourcePosition &pos, Handle<Type> from, Handle<Type> to)
15.86 +{
15.87 + cc_.reportError(pos, Message_InvalidCoercion,
15.88 + GetTypeName(from),
15.89 + GetTypeName(to));
15.90 + return NULL;
15.91 +}
15.92 +
15.93 +HIR *
15.94 SemanticAnalysis::coerce(HIR *hir, Handle<Type> to, CoercionKind kind)
15.95 {
15.96 Handle<Type> from = hir->type();
15.97 @@ -862,6 +903,9 @@
15.98 return new (pool_) HConvert(hir->node(), to, OP_CVT_I2F, hir);
15.99 if (from->isInt32() && to->isBool())
15.100 return new (pool_) HConvert(hir->node(), to, OP_CVT_I2B, hir);
15.101 +
15.102 + if (to->isEnum() && from != to)
15.103 + return typeFailure(hir->node()->pos(), from, to);
15.104
15.105 if (to->isArray()) {
15.106 if (!typeCheckArray(SourcePosition(), from, to, kind))
16.1 --- a/src/compiler/SemanticAnalysis.h Sat Dec 22 19:48:43 2012 -0800
16.2 +++ b/src/compiler/SemanticAnalysis.h Sat Dec 22 23:18:57 2012 -0800
16.3 @@ -48,6 +48,7 @@
16.4 void visitBlockStatement(BlockStatement *node);
16.5 void visitExpressionStatement(ExpressionStatement *node);
16.6 void visitReturnStatement(ReturnStatement *node);
16.7 + void visitEnumStatement(EnumStatement *node);
16.8
16.9 void visitCallExpression(CallExpression *node);
16.10 void visitNameProxy(NameProxy *name);
16.11 @@ -66,7 +67,6 @@
16.12 #if 0
16.13 void visitFunctionTypeStatement(FunctionTypeStatement *node);
16.14 void visitImportStatement(ImportStatement *node);
16.15 - void visitEnumStatement(EnumStatement *node);
16.16 void visitStructureStatement(StructureStatement *node);
16.17 void visitSwitchStatement(SwitchStatement *node);
16.18
16.19 @@ -178,6 +178,7 @@
16.20 Type *coercionType(TokenKind token, HIR *left, HIR *right);
16.21 HLValue *lvalue(Expression *expr);
16.22 void discharge(HIR *hir);
16.23 + HIR *typeFailure(const SourcePosition &pos, Handle<Type> from, Handle<Type> to);
16.24
16.25 bool typeCheckArray(const SourcePosition &pos,
16.26 Handle<Type> argGiven,
17.1 --- a/src/compiler/Symbols.h Sat Dec 22 19:48:43 2012 -0800
17.2 +++ b/src/compiler/Symbols.h Sat Dec 22 23:18:57 2012 -0800
17.3 @@ -186,6 +186,28 @@
17.4 }
17.5 };
17.6
17.7 +class ConstantSymbol : public Symbol
17.8 +{
17.9 + public:
17.10 + ConstantSymbol(Scope *scope, Handle<String> name, const SourcePosition &pos, Handle<Type> type,
17.11 + const BoxedPrimitive &prim)
17.12 + : Symbol(scope, name, pos),
17.13 + value_(prim)
17.14 + {
17.15 + type_ = type;
17.16 + }
17.17 +
17.18 + Kind kind() const {
17.19 + return kConstant;
17.20 + }
17.21 + const BoxedPrimitive &value() const {
17.22 + return value_;
17.23 + }
17.24 +
17.25 + private:
17.26 + BoxedPrimitive value_;
17.27 +};
17.28 +
17.29 }
17.30
17.31 #endif // _include_sp2_symbol_h_
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/tests/basic/enum-bad.err Sat Dec 22 23:18:57 2012 -0800
18.3 @@ -0,0 +1,1 @@
18.4 + line 6, col 13: cannot coerce type 'int' to type 'X'
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/tests/basic/enum-bad.sp Sat Dec 22 23:18:57 2012 -0800
19.3 @@ -0,0 +1,7 @@
19.4 +enum X {
19.5 +};
19.6 +
19.7 +public main()
19.8 +{
19.9 + new X:x = 5;
19.10 +}
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/tests/basic/enum-redecl.err Sat Dec 22 23:18:57 2012 -0800
20.3 @@ -0,0 +1,1 @@
20.4 + line 4, col 4: name 'Y' was redeclared (previous at line 2, col 4)
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/tests/basic/enum-redecl.sp Sat Dec 22 23:18:57 2012 -0800
21.3 @@ -0,0 +1,6 @@
21.4 +enum X {
21.5 + Y,
21.6 + Z,
21.7 + Y
21.8 +};
21.9 +
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/tests/basic/enum-use.out Sat Dec 22 23:18:57 2012 -0800
22.3 @@ -0,0 +1,1 @@
22.4 +01570157
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/tests/basic/enum-use.sp Sat Dec 22 23:18:57 2012 -0800
23.3 @@ -0,0 +1,28 @@
23.4 +native PrintNum(num);
23.5 +
23.6 +enum Crab {
23.7 + CrabOne,
23.8 + CrabTwo,
23.9 + CrabThree=5,
23.10 + CrabFour=7
23.11 +};
23.12 +
23.13 +enum {
23.14 + CrabFive,
23.15 + CrabSix,
23.16 + CrabSeven=5,
23.17 + CrabEight=7
23.18 +};
23.19 +
23.20 +public main()
23.21 +{
23.22 + PrintNum(CrabOne);
23.23 + PrintNum(CrabTwo);
23.24 + PrintNum(CrabThree);
23.25 + PrintNum(CrabFour);
23.26 + PrintNum(CrabFive);
23.27 + PrintNum(CrabSix);
23.28 + PrintNum(CrabSeven);
23.29 + PrintNum(CrabEight);
23.30 +}
23.31 +