aboutsummaryrefslogtreecommitdiffstats
path: root/Types.cpp
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2015-02-20 22:52:30 +0800
committerChristian <c@ethdev.com>2015-02-21 22:10:01 +0800
commit5e3208317922d20a5b3b760df872a589d87bf94d (patch)
tree982cb7d888c7ae395de3f533c8e8d1bdd27c5c27 /Types.cpp
parent75498a48d83277240605b43e27197be36c02ce23 (diff)
downloaddexon-solidity-5e3208317922d20a5b3b760df872a589d87bf94d.tar.gz
dexon-solidity-5e3208317922d20a5b3b760df872a589d87bf94d.tar.zst
dexon-solidity-5e3208317922d20a5b3b760df872a589d87bf94d.zip
Parsing of array types and basic implementation.
Diffstat (limited to 'Types.cpp')
-rw-r--r--Types.cpp64
1 files changed, 50 insertions, 14 deletions
diff --git a/Types.cpp b/Types.cpp
index 55dedd92..d0448ef7 100644
--- a/Types.cpp
+++ b/Types.cpp
@@ -58,7 +58,7 @@ TypePointer Type::fromElementaryTypeName(Token::Value _typeToken)
else if (Token::String0 <= _typeToken && _typeToken <= Token::String32)
return make_shared<StaticStringType>(int(_typeToken) - int(Token::String0));
else if (_typeToken == Token::Bytes)
- return make_shared<ByteArrayType>(ByteArrayType::Location::Storage);
+ return make_shared<ArrayType>(ArrayType::Location::Storage);
else
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to convert elementary typename " +
std::string(Token::toString(_typeToken)) + " to type."));
@@ -83,17 +83,35 @@ TypePointer Type::fromUserDefinedTypeName(UserDefinedTypeName const& _typeName)
return TypePointer();
}
-TypePointer Type::fromMapping(Mapping const& _typeName)
+TypePointer Type::fromMapping(ElementaryTypeName& _keyType, TypeName& _valueType)
{
- TypePointer keyType = _typeName.getKeyType().toType();
+ TypePointer keyType = _keyType.toType();
if (!keyType)
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Error resolving type name."));
- TypePointer valueType = _typeName.getValueType().toType();
+ TypePointer valueType = _valueType.toType();
if (!valueType)
- BOOST_THROW_EXCEPTION(_typeName.getValueType().createTypeError("Invalid type name"));
+ BOOST_THROW_EXCEPTION(_valueType.createTypeError("Invalid type name."));
return make_shared<MappingType>(keyType, valueType);
}
+TypePointer Type::fromArrayTypeName(TypeName& _baseTypeName, Expression* _length)
+{
+ TypePointer baseType = _baseTypeName.toType();
+ if (!baseType)
+ BOOST_THROW_EXCEPTION(_baseTypeName.createTypeError("Invalid type name."));
+ if (_length)
+ {
+ if (!_length->getType())
+ _length->checkTypeRequirements();
+ auto const* length = dynamic_cast<IntegerConstantType const*>(_length->getType().get());
+ if (!length)
+ BOOST_THROW_EXCEPTION(_length->createTypeError("Invalid array length."));
+ return make_shared<ArrayType>(ArrayType::Location::Storage, baseType, length->literalValue(nullptr));
+ }
+ else
+ return make_shared<ArrayType>(ArrayType::Location::Storage, baseType);
+}
+
TypePointer Type::forLiteral(Literal const& _literal)
{
switch (_literal.getToken())
@@ -517,27 +535,27 @@ TypePointer ContractType::unaryOperatorResult(Token::Value _operator) const
return _operator == Token::Delete ? make_shared<VoidType>() : TypePointer();
}
-bool ByteArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const
+bool ArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const
{
return _convertTo.getCategory() == getCategory();
}
-TypePointer ByteArrayType::unaryOperatorResult(Token::Value _operator) const
+TypePointer ArrayType::unaryOperatorResult(Token::Value _operator) const
{
if (_operator == Token::Delete)
return make_shared<VoidType>();
return TypePointer();
}
-bool ByteArrayType::operator==(Type const& _other) const
+bool ArrayType::operator==(Type const& _other) const
{
if (_other.getCategory() != getCategory())
return false;
- ByteArrayType const& other = dynamic_cast<ByteArrayType const&>(_other);
+ ArrayType const& other = dynamic_cast<ArrayType const&>(_other);
return other.m_location == m_location;
}
-unsigned ByteArrayType::getSizeOnStack() const
+unsigned ArrayType::getSizeOnStack() const
{
if (m_location == Location::CallData)
// offset, length (stack top)
@@ -547,12 +565,30 @@ unsigned ByteArrayType::getSizeOnStack() const
return 1;
}
-shared_ptr<ByteArrayType> ByteArrayType::copyForLocation(ByteArrayType::Location _location) const
+string ArrayType::toString() const
{
- return make_shared<ByteArrayType>(_location);
+ if (isByteArray())
+ return "bytes";
+ string ret = getBaseType()->toString() + "[";
+ if (!isDynamicallySized())
+ ret += getLength().str();
+ return ret + "]";
+}
+
+shared_ptr<ArrayType> ArrayType::copyForLocation(ArrayType::Location _location) const
+{
+ auto copy = make_shared<ArrayType>(_location);
+ copy->m_isByteArray = m_isByteArray;
+ if (m_baseType->getCategory() == Type::Category::Array)
+ copy->m_baseType = dynamic_cast<ArrayType const&>(*m_baseType).copyForLocation(_location);
+ else
+ copy->m_baseType = m_baseType;
+ copy->m_hasDynamicLength = m_hasDynamicLength;
+ copy->m_length = m_length;
+ return copy;
}
-const MemberList ByteArrayType::s_byteArrayMemberList = MemberList({{"length", make_shared<IntegerType>(256)}});
+const MemberList ArrayType::s_arrayTypeMemberList = MemberList({{"length", make_shared<IntegerType>(256)}});
bool ContractType::operator==(Type const& _other) const
{
@@ -1033,7 +1069,7 @@ MagicType::MagicType(MagicType::Kind _kind):
m_members = MemberList({{"sender", make_shared<IntegerType>(0, IntegerType::Modifier::Address)},
{"gas", make_shared<IntegerType>(256)},
{"value", make_shared<IntegerType>(256)},
- {"data", make_shared<ByteArrayType>(ByteArrayType::Location::CallData)}});
+ {"data", make_shared<ArrayType>(ArrayType::Location::CallData)}});
break;
case Kind::Transaction:
m_members = MemberList({{"origin", make_shared<IntegerType>(0, IntegerType::Modifier::Address)},