aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AST.cpp13
-rw-r--r--AST.h3
-rw-r--r--ExpressionCompiler.cpp12
-rw-r--r--Types.cpp5
-rw-r--r--Types.h2
5 files changed, 34 insertions, 1 deletions
diff --git a/AST.cpp b/AST.cpp
index 488bd4cd..7653952f 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -277,6 +277,19 @@ TypePointer EnumDefinition::getType(ContractDefinition const*) const
return make_shared<TypeType>(make_shared<EnumType>(*this));
}
+
+unsigned int EnumDefinition::getMemberValue(ASTString const& _member) const
+{
+ unsigned int index = 0;
+ for (ASTPointer<EnumDeclaration> const& decl: m_members)
+ {
+ if (decl->getName() == _member)
+ return index;
+ ++index;
+ }
+ BOOST_THROW_EXCEPTION(createTypeError("Requested unknown enum value ." + _member));
+}
+
TypePointer FunctionDefinition::getType(ContractDefinition const*) const
{
return make_shared<FunctionType>(*this);
diff --git a/AST.h b/AST.h
index 65c35026..fdbbcd5b 100644
--- a/AST.h
+++ b/AST.h
@@ -348,6 +348,9 @@ public:
virtual TypePointer getType(ContractDefinition const*) const override;
+ /// @returns the value that the string has in the Enum
+ unsigned int getMemberValue(ASTString const& _member) const;
+
/// Checks that the members do not include any duplicate names
void checkValidityOfMembers() const;
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 90f860a1..dd41b485 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -489,6 +489,12 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess)
m_currentLValue.retrieveValueIfLValueNotRequested(_memberAccess);
break;
}
+ case Type::Category::Enum:
+ {
+ EnumType const& type = dynamic_cast<EnumType const&>(*_memberAccess.getExpression().getType());
+ EnumDefinition const& enumDef = type.getEnumDefinition();
+ m_context << enumDef.getMemberValue(_memberAccess.getMemberName());
+ }
case Type::Category::TypeType:
{
TypeType const& type = dynamic_cast<TypeType const&>(*_memberAccess.getExpression().getType());
@@ -562,6 +568,10 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier)
{
// no-op
}
+ else if (dynamic_cast<EnumDefinition const*>(declaration))
+ {
+ // no-op
+ }
else
{
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Identifier type not expected in expression context."));
@@ -746,7 +756,7 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con
}
}
else if (stackTypeCategory == Type::Category::Integer || stackTypeCategory == Type::Category::Contract ||
- stackTypeCategory == Type::Category::IntegerConstant)
+ stackTypeCategory == Type::Category::IntegerConstant || stackTypeCategory == Type::Category::Enum)
{
if (targetTypeCategory == Type::Category::String && stackTypeCategory == Type::Category::Integer)
{
diff --git a/Types.cpp b/Types.cpp
index f2543160..df0b0f20 100644
--- a/Types.cpp
+++ b/Types.cpp
@@ -682,6 +682,11 @@ string EnumType::toString() const
return string("enum ") + m_enum.getName();
}
+bool EnumType::isExplicitlyConvertibleTo(Type const& _convertTo) const
+{
+ return _convertTo.getCategory() == getCategory() || _convertTo.getCategory() == Category::Integer;
+}
+
FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal):
m_location(_isInternal ? Location::Internal : Location::External),
m_isConstant(_function.isDeclaredConst()),
diff --git a/Types.h b/Types.h
index 0b576bd3..15bd86b1 100644
--- a/Types.h
+++ b/Types.h
@@ -381,6 +381,8 @@ public:
virtual std::string toString() const override;
virtual bool isValueType() const override { return true; }
+ virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
+
EnumDefinition const& getEnumDefinition() const { return m_enum; }
private: