diff options
author | Christian <c@ethdev.com> | 2015-01-07 02:08:24 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2015-01-09 22:09:10 +0800 |
commit | be1e89da42e0ed9828dd2fb5939fd7bd48140be7 (patch) | |
tree | 977979fe84ea56786984dafe99be7952eb111c2a | |
parent | dcda38cf3806c1d4205136c55d17f1e73eda48c1 (diff) | |
download | dexon-solidity-be1e89da42e0ed9828dd2fb5939fd7bd48140be7.tar dexon-solidity-be1e89da42e0ed9828dd2fb5939fd7bd48140be7.tar.gz dexon-solidity-be1e89da42e0ed9828dd2fb5939fd7bd48140be7.tar.bz2 dexon-solidity-be1e89da42e0ed9828dd2fb5939fd7bd48140be7.tar.lz dexon-solidity-be1e89da42e0ed9828dd2fb5939fd7bd48140be7.tar.xz dexon-solidity-be1e89da42e0ed9828dd2fb5939fd7bd48140be7.tar.zst dexon-solidity-be1e89da42e0ed9828dd2fb5939fd7bd48140be7.zip |
Possibility for unary operators to change type.
-rw-r--r-- | AST.cpp | 4 | ||||
-rw-r--r-- | Types.cpp | 28 | ||||
-rw-r--r-- | Types.h | 16 |
3 files changed, 31 insertions, 17 deletions
@@ -228,8 +228,8 @@ void UnaryOperation::checkTypeRequirements() m_subExpression->checkTypeRequirements(); if (m_operator == Token::Value::INC || m_operator == Token::Value::DEC || m_operator == Token::Value::DELETE) m_subExpression->requireLValue(); - m_type = m_subExpression->getType(); - if (!m_type->acceptsUnaryOperator(m_operator)) + m_type = m_subExpression->getType()->unaryOperatorResult(m_operator); + if (!m_type) BOOST_THROW_EXCEPTION(createTypeError("Unary operator not compatible with type.")); } @@ -156,18 +156,26 @@ bool IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const return _convertTo.getCategory() == getCategory() || _convertTo.getCategory() == Category::CONTRACT; } -bool IntegerType::acceptsUnaryOperator(Token::Value _operator) const +TypePointer IntegerType::unaryOperatorResult(Token::Value _operator) const { + // "delete" is ok for all integer types if (_operator == Token::DELETE) - return true; - if (isAddress()) - return false; - if (_operator == Token::BIT_NOT) - return true; - if (isHash()) - return false; - return _operator == Token::ADD || _operator == Token::SUB || - _operator == Token::INC || _operator == Token::DEC; + return shared_from_this(); + // no further unary operators for addresses + else if (isAddress()) + return TypePointer(); + // "~" is ok for all other types + else if (_operator == Token::BIT_NOT) + return shared_from_this(); + // nothing else for hashes + else if (isHash()) + return TypePointer(); + // for non-hash integers, we allow +, -, ++ and -- + else if (_operator == Token::ADD || _operator == Token::SUB || + _operator == Token::INC || _operator == Token::DEC) + return shared_from_this(); + else + return TypePointer(); } bool IntegerType::operator==(Type const& _other) const @@ -99,7 +99,10 @@ public: { return isImplicitlyConvertibleTo(_convertTo); } - virtual bool acceptsUnaryOperator(Token::Value) const { return false; } + /// @returns the resulting type of applying the given unary operator or an empty pointer if + /// this is not possible. + /// The default implementation does not allow any unary operator. + virtual TypePointer unaryOperatorResult(Token::Value) const { return TypePointer(); } /// @returns the resulting type of applying the given binary operator or an empty pointer if /// this is not possible. /// The default implementation allows comparison operators if a common type exists @@ -163,7 +166,7 @@ public: virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; - virtual bool acceptsUnaryOperator(Token::Value _operator) const override; + virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override; virtual bool operator==(Type const& _other) const override; @@ -225,9 +228,9 @@ public: BoolType() {} virtual Category getCategory() const { return Category::BOOL; } virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; - virtual bool acceptsUnaryOperator(Token::Value _operator) const override + virtual TypePointer unaryOperatorResult(Token::Value _operator) const override { - return _operator == Token::NOT || _operator == Token::DELETE; + return (_operator == Token::NOT || _operator == Token::DELETE) ? shared_from_this() : TypePointer(); } virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override; @@ -277,7 +280,10 @@ class StructType: public Type public: virtual Category getCategory() const override { return Category::STRUCT; } StructType(StructDefinition const& _struct): m_struct(_struct) {} - virtual bool acceptsUnaryOperator(Token::Value _operator) const override { return _operator == Token::DELETE; } + virtual TypePointer unaryOperatorResult(Token::Value _operator) const override + { + return _operator == Token::DELETE ? shared_from_this() : TypePointer(); + } virtual bool operator==(Type const& _other) const override; virtual u256 getStorageSize() const override; |