diff options
author | chriseth <c@ethdev.com> | 2016-05-10 20:30:24 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2016-05-11 01:40:37 +0800 |
commit | 656405240e08e47fce40a2f62af93abc758bd2d2 (patch) | |
tree | ad1139d8209d5f98b41dee7eb82ebbd2d7d78495 /libsolidity | |
parent | cf226f0607386d1e6d9c75ebc7ce24e733ca4315 (diff) | |
download | dexon-solidity-656405240e08e47fce40a2f62af93abc758bd2d2.tar.gz dexon-solidity-656405240e08e47fce40a2f62af93abc758bd2d2.tar.zst dexon-solidity-656405240e08e47fce40a2f62af93abc758bd2d2.zip |
Simplify interface of RationalNumber.
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/analysis/ReferencesResolver.cpp | 2 | ||||
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 10 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 24 | ||||
-rw-r--r-- | libsolidity/ast/Types.h | 9 | ||||
-rw-r--r-- | libsolidity/formal/Why3Translator.cpp | 4 |
5 files changed, 25 insertions, 24 deletions
diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index 9f83971b..a7b9e8b8 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -104,7 +104,7 @@ void ReferencesResolver::endVisit(ArrayTypeName const& _typeName) if (!length->annotation().type) ConstantEvaluator e(*length); auto const* lengthType = dynamic_cast<RationalNumberType const*>(length->annotation().type.get()); - if (!lengthType || lengthType->denominator() != 1) + if (!lengthType || lengthType->isFractional()) fatalTypeError(length->location(), "Invalid array length, expected integer literal."); else _typeName.annotation().type = make_shared<ArrayType>(DataLocation::Storage, baseType, lengthType->literalValue(nullptr)); diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index f28e08ab..6df9aae0 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -792,7 +792,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) { if ( valueComponentType->category() == Type::Category::RationalNumber && - dynamic_cast<RationalNumberType const&>(*valueComponentType).denominator() != 1 && + dynamic_cast<RationalNumberType const&>(*valueComponentType).isFractional() && valueComponentType->mobileType() ) typeError( @@ -1366,9 +1366,9 @@ bool TypeChecker::visit(IndexAccess const& _access) expectType(*index, IntegerType(256)); if (auto numberType = dynamic_cast<RationalNumberType const*>(type(*index).get())) { - solAssert(!numberType->denominator() != 1 ,"Invalid type for array access."); - if (!actualType.isDynamicallySized() && actualType.length() <= numberType->literalValue(nullptr)) - typeError(_access.location(), "Out of bounds array access."); + if (!numberType->isFractional()) // error is reported above + if (!actualType.isDynamicallySized() && actualType.length() <= numberType->literalValue(nullptr)) + typeError(_access.location(), "Out of bounds array access."); } } resultType = actualType.baseType(); @@ -1522,7 +1522,7 @@ void TypeChecker::expectType(Expression const& _expression, Type const& _expecte { if ( type(_expression)->category() == Type::Category::RationalNumber && - dynamic_pointer_cast<RationalNumberType const>(type(_expression))->denominator() != 1 && + dynamic_pointer_cast<RationalNumberType const>(type(_expression))->isFractional() && type(_expression)->mobileType() ) typeError( diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 31248fb6..7995e7e3 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -534,15 +534,15 @@ bool RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const auto targetType = dynamic_cast<IntegerType const*>(&_convertTo); if (m_value == 0) return true; - if (m_value.denominator() != 1) + if (isFractional()) return false; int forSignBit = (targetType->isSigned() ? 1 : 0); if (m_value > 0) { - if (integerPart() <= (u256(-1) >> (256 - targetType->numBits() + forSignBit))) + if (m_value.numerator() <= (u256(-1) >> (256 - targetType->numBits() + forSignBit))) return true; } - else if (targetType->isSigned() && -integerPart() <= (u256(1) << (targetType->numBits() - forSignBit))) + else if (targetType->isSigned() && -m_value.numerator() <= (u256(1) << (targetType->numBits() - forSignBit))) return true; return false; } @@ -560,7 +560,7 @@ bool RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const else if (_convertTo.category() == Category::FixedBytes) { FixedBytesType const& fixedBytes = dynamic_cast<FixedBytesType const&>(_convertTo); - if (m_value.denominator() == 1) + if (!isFractional()) return fixedBytes.numBytes() * 8 >= integerType()->numBits(); else return false; @@ -580,7 +580,7 @@ TypePointer RationalNumberType::unaryOperatorResult(Token::Value _operator) cons switch (_operator) { case Token::BitNot: - if(m_value.denominator() != 1) + if (isFractional()) return TypePointer(); value = ~m_value.numerator(); break; @@ -625,7 +625,7 @@ TypePointer RationalNumberType::binaryOperatorResult(Token::Value _operator, Typ else { rational value; - bool fractional = (m_value.denominator() != 1 || other.m_value.denominator() != 1); + bool fractional = isFractional() || other.isFractional(); switch (_operator) { //bit operations will only be enabled for integers and fixed types that resemble integers @@ -673,7 +673,7 @@ TypePointer RationalNumberType::binaryOperatorResult(Token::Value _operator, Typ case Token::Exp: { using boost::multiprecision::pow; - if (other.m_value.denominator() != 1) + if (other.isFractional()) return TypePointer(); else if (abs(other.m_value) > numeric_limits<uint32_t>::max()) return TypePointer(); // This will need too much memory to represent. @@ -704,7 +704,7 @@ bool RationalNumberType::operator==(Type const& _other) const string RationalNumberType::toString(bool) const { - if (m_value.denominator() == 1) + if (!isFractional()) return "int_const " + m_value.numerator().str(); return "rational_const " + m_value.numerator().str() + '/' + m_value.denominator().str(); } @@ -717,7 +717,7 @@ u256 RationalNumberType::literalValue(Literal const*) const u256 value; bigint shiftedValue; - if (m_value.denominator() == 1) + if (!isFractional()) shiftedValue = m_value.numerator(); else { @@ -741,7 +741,7 @@ u256 RationalNumberType::literalValue(Literal const*) const TypePointer RationalNumberType::mobileType() const { - if (m_value.denominator() == 1) + if (!isFractional()) return integerType(); else return fixedPointType(); @@ -749,8 +749,8 @@ TypePointer RationalNumberType::mobileType() const shared_ptr<IntegerType const> RationalNumberType::integerType() const { - solAssert(m_value.denominator() == 1, "integerType() called for fractional number."); - bigint value = integerPart(); + solAssert(!isFractional(), "integerType() called for fractional number."); + bigint value = m_value.numerator(); bool negative = (value < 0); if (negative) // convert to positive number of same bit requirements value = ((0 - value) - 1) << 1; diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 441ab2ae..26c0f902 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -204,8 +204,9 @@ public: virtual bool isValueType() const { return false; } virtual unsigned sizeOnStack() const { return 1; } /// @returns the mobile (in contrast to static) type corresponding to the given type. - /// This returns the corresponding integer type for ConstantTypes and the pointer type - /// for storage reference types. Might return a null pointer if there is no fitting type. + /// This returns the corresponding IntegerType or FixedPointType for RationalNumberType + /// and the pointer type for storage reference types. + /// Might return a null pointer if there is no fitting type. virtual TypePointer mobileType() const { return shared_from_this(); } /// @returns true if this is a non-value type and the data of this type is stored at the /// given location. @@ -388,8 +389,8 @@ public: /// If the integer part does not fit, returns an empty pointer. std::shared_ptr<FixedPointType const> fixedPointType() const; - bigint denominator() const { return m_value.denominator(); } - bigint integerPart() const { return m_value.numerator() / m_value.denominator(); } + /// @returns true iff the value is not an integer. + bool isFractional() const { return m_value.denominator() != 1; } private: rational m_value; diff --git a/libsolidity/formal/Why3Translator.cpp b/libsolidity/formal/Why3Translator.cpp index 5921b9a4..c794cb24 100644 --- a/libsolidity/formal/Why3Translator.cpp +++ b/libsolidity/formal/Why3Translator.cpp @@ -431,7 +431,7 @@ bool Why3Translator::visit(BinaryOperation const& _binaryOperation) if (commonType.category() == Type::Category::RationalNumber) { auto const& constantNumber = dynamic_cast<RationalNumberType const&>(commonType); - if (constantNumber.denominator() != bigint(1)) + if (constantNumber.isFractional()) error(_binaryOperation, "Fractional numbers not supported."); add("(of_int " + toString(commonType.literalValue(nullptr)) + ")"); return false; @@ -595,7 +595,7 @@ bool Why3Translator::visit(Literal const& _literal) case Type::Category::RationalNumber: { auto const& constantNumber = dynamic_cast<RationalNumberType const&>(*type); - if (constantNumber.denominator() != 1) + if (constantNumber.isFractional()) error(_literal, "Fractional numbers not supported."); add("(of_int " + toString(type->literalValue(&_literal)) + ")"); break; |