mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Simplify interface of RationalNumber.
This commit is contained in:
parent
cf226f0607
commit
656405240e
@ -104,7 +104,7 @@ void ReferencesResolver::endVisit(ArrayTypeName const& _typeName)
|
|||||||
if (!length->annotation().type)
|
if (!length->annotation().type)
|
||||||
ConstantEvaluator e(*length);
|
ConstantEvaluator e(*length);
|
||||||
auto const* lengthType = dynamic_cast<RationalNumberType const*>(length->annotation().type.get());
|
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.");
|
fatalTypeError(length->location(), "Invalid array length, expected integer literal.");
|
||||||
else
|
else
|
||||||
_typeName.annotation().type = make_shared<ArrayType>(DataLocation::Storage, baseType, lengthType->literalValue(nullptr));
|
_typeName.annotation().type = make_shared<ArrayType>(DataLocation::Storage, baseType, lengthType->literalValue(nullptr));
|
||||||
|
@ -792,7 +792,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
|
|||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
valueComponentType->category() == Type::Category::RationalNumber &&
|
valueComponentType->category() == Type::Category::RationalNumber &&
|
||||||
dynamic_cast<RationalNumberType const&>(*valueComponentType).denominator() != 1 &&
|
dynamic_cast<RationalNumberType const&>(*valueComponentType).isFractional() &&
|
||||||
valueComponentType->mobileType()
|
valueComponentType->mobileType()
|
||||||
)
|
)
|
||||||
typeError(
|
typeError(
|
||||||
@ -1366,7 +1366,7 @@ bool TypeChecker::visit(IndexAccess const& _access)
|
|||||||
expectType(*index, IntegerType(256));
|
expectType(*index, IntegerType(256));
|
||||||
if (auto numberType = dynamic_cast<RationalNumberType const*>(type(*index).get()))
|
if (auto numberType = dynamic_cast<RationalNumberType const*>(type(*index).get()))
|
||||||
{
|
{
|
||||||
solAssert(!numberType->denominator() != 1 ,"Invalid type for array access.");
|
if (!numberType->isFractional()) // error is reported above
|
||||||
if (!actualType.isDynamicallySized() && actualType.length() <= numberType->literalValue(nullptr))
|
if (!actualType.isDynamicallySized() && actualType.length() <= numberType->literalValue(nullptr))
|
||||||
typeError(_access.location(), "Out of bounds array access.");
|
typeError(_access.location(), "Out of bounds array access.");
|
||||||
}
|
}
|
||||||
@ -1522,7 +1522,7 @@ void TypeChecker::expectType(Expression const& _expression, Type const& _expecte
|
|||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
type(_expression)->category() == Type::Category::RationalNumber &&
|
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()
|
type(_expression)->mobileType()
|
||||||
)
|
)
|
||||||
typeError(
|
typeError(
|
||||||
|
@ -534,15 +534,15 @@ bool RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
auto targetType = dynamic_cast<IntegerType const*>(&_convertTo);
|
auto targetType = dynamic_cast<IntegerType const*>(&_convertTo);
|
||||||
if (m_value == 0)
|
if (m_value == 0)
|
||||||
return true;
|
return true;
|
||||||
if (m_value.denominator() != 1)
|
if (isFractional())
|
||||||
return false;
|
return false;
|
||||||
int forSignBit = (targetType->isSigned() ? 1 : 0);
|
int forSignBit = (targetType->isSigned() ? 1 : 0);
|
||||||
if (m_value > 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;
|
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 true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -560,7 +560,7 @@ bool RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
else if (_convertTo.category() == Category::FixedBytes)
|
else if (_convertTo.category() == Category::FixedBytes)
|
||||||
{
|
{
|
||||||
FixedBytesType const& fixedBytes = dynamic_cast<FixedBytesType const&>(_convertTo);
|
FixedBytesType const& fixedBytes = dynamic_cast<FixedBytesType const&>(_convertTo);
|
||||||
if (m_value.denominator() == 1)
|
if (!isFractional())
|
||||||
return fixedBytes.numBytes() * 8 >= integerType()->numBits();
|
return fixedBytes.numBytes() * 8 >= integerType()->numBits();
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
@ -580,7 +580,7 @@ TypePointer RationalNumberType::unaryOperatorResult(Token::Value _operator) cons
|
|||||||
switch (_operator)
|
switch (_operator)
|
||||||
{
|
{
|
||||||
case Token::BitNot:
|
case Token::BitNot:
|
||||||
if(m_value.denominator() != 1)
|
if (isFractional())
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
value = ~m_value.numerator();
|
value = ~m_value.numerator();
|
||||||
break;
|
break;
|
||||||
@ -625,7 +625,7 @@ TypePointer RationalNumberType::binaryOperatorResult(Token::Value _operator, Typ
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
rational value;
|
rational value;
|
||||||
bool fractional = (m_value.denominator() != 1 || other.m_value.denominator() != 1);
|
bool fractional = isFractional() || other.isFractional();
|
||||||
switch (_operator)
|
switch (_operator)
|
||||||
{
|
{
|
||||||
//bit operations will only be enabled for integers and fixed types that resemble integers
|
//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:
|
case Token::Exp:
|
||||||
{
|
{
|
||||||
using boost::multiprecision::pow;
|
using boost::multiprecision::pow;
|
||||||
if (other.m_value.denominator() != 1)
|
if (other.isFractional())
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
else if (abs(other.m_value) > numeric_limits<uint32_t>::max())
|
else if (abs(other.m_value) > numeric_limits<uint32_t>::max())
|
||||||
return TypePointer(); // This will need too much memory to represent.
|
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
|
string RationalNumberType::toString(bool) const
|
||||||
{
|
{
|
||||||
if (m_value.denominator() == 1)
|
if (!isFractional())
|
||||||
return "int_const " + m_value.numerator().str();
|
return "int_const " + m_value.numerator().str();
|
||||||
return "rational_const " + m_value.numerator().str() + '/' + m_value.denominator().str();
|
return "rational_const " + m_value.numerator().str() + '/' + m_value.denominator().str();
|
||||||
}
|
}
|
||||||
@ -717,7 +717,7 @@ u256 RationalNumberType::literalValue(Literal const*) const
|
|||||||
u256 value;
|
u256 value;
|
||||||
bigint shiftedValue;
|
bigint shiftedValue;
|
||||||
|
|
||||||
if (m_value.denominator() == 1)
|
if (!isFractional())
|
||||||
shiftedValue = m_value.numerator();
|
shiftedValue = m_value.numerator();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -741,7 +741,7 @@ u256 RationalNumberType::literalValue(Literal const*) const
|
|||||||
|
|
||||||
TypePointer RationalNumberType::mobileType() const
|
TypePointer RationalNumberType::mobileType() const
|
||||||
{
|
{
|
||||||
if (m_value.denominator() == 1)
|
if (!isFractional())
|
||||||
return integerType();
|
return integerType();
|
||||||
else
|
else
|
||||||
return fixedPointType();
|
return fixedPointType();
|
||||||
@ -749,8 +749,8 @@ TypePointer RationalNumberType::mobileType() const
|
|||||||
|
|
||||||
shared_ptr<IntegerType const> RationalNumberType::integerType() const
|
shared_ptr<IntegerType const> RationalNumberType::integerType() const
|
||||||
{
|
{
|
||||||
solAssert(m_value.denominator() == 1, "integerType() called for fractional number.");
|
solAssert(!isFractional(), "integerType() called for fractional number.");
|
||||||
bigint value = integerPart();
|
bigint value = m_value.numerator();
|
||||||
bool negative = (value < 0);
|
bool negative = (value < 0);
|
||||||
if (negative) // convert to positive number of same bit requirements
|
if (negative) // convert to positive number of same bit requirements
|
||||||
value = ((0 - value) - 1) << 1;
|
value = ((0 - value) - 1) << 1;
|
||||||
|
@ -204,8 +204,9 @@ public:
|
|||||||
virtual bool isValueType() const { return false; }
|
virtual bool isValueType() const { return false; }
|
||||||
virtual unsigned sizeOnStack() const { return 1; }
|
virtual unsigned sizeOnStack() const { return 1; }
|
||||||
/// @returns the mobile (in contrast to static) type corresponding to the given type.
|
/// @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
|
/// This returns the corresponding IntegerType or FixedPointType for RationalNumberType
|
||||||
/// for storage reference types. Might return a null pointer if there is no fitting type.
|
/// 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(); }
|
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
|
/// @returns true if this is a non-value type and the data of this type is stored at the
|
||||||
/// given location.
|
/// given location.
|
||||||
@ -388,8 +389,8 @@ public:
|
|||||||
/// If the integer part does not fit, returns an empty pointer.
|
/// If the integer part does not fit, returns an empty pointer.
|
||||||
std::shared_ptr<FixedPointType const> fixedPointType() const;
|
std::shared_ptr<FixedPointType const> fixedPointType() const;
|
||||||
|
|
||||||
bigint denominator() const { return m_value.denominator(); }
|
/// @returns true iff the value is not an integer.
|
||||||
bigint integerPart() const { return m_value.numerator() / m_value.denominator(); }
|
bool isFractional() const { return m_value.denominator() != 1; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
rational m_value;
|
rational m_value;
|
||||||
|
@ -431,7 +431,7 @@ bool Why3Translator::visit(BinaryOperation const& _binaryOperation)
|
|||||||
if (commonType.category() == Type::Category::RationalNumber)
|
if (commonType.category() == Type::Category::RationalNumber)
|
||||||
{
|
{
|
||||||
auto const& constantNumber = dynamic_cast<RationalNumberType const&>(commonType);
|
auto const& constantNumber = dynamic_cast<RationalNumberType const&>(commonType);
|
||||||
if (constantNumber.denominator() != bigint(1))
|
if (constantNumber.isFractional())
|
||||||
error(_binaryOperation, "Fractional numbers not supported.");
|
error(_binaryOperation, "Fractional numbers not supported.");
|
||||||
add("(of_int " + toString(commonType.literalValue(nullptr)) + ")");
|
add("(of_int " + toString(commonType.literalValue(nullptr)) + ")");
|
||||||
return false;
|
return false;
|
||||||
@ -595,7 +595,7 @@ bool Why3Translator::visit(Literal const& _literal)
|
|||||||
case Type::Category::RationalNumber:
|
case Type::Category::RationalNumber:
|
||||||
{
|
{
|
||||||
auto const& constantNumber = dynamic_cast<RationalNumberType const&>(*type);
|
auto const& constantNumber = dynamic_cast<RationalNumberType const&>(*type);
|
||||||
if (constantNumber.denominator() != 1)
|
if (constantNumber.isFractional())
|
||||||
error(_literal, "Fractional numbers not supported.");
|
error(_literal, "Fractional numbers not supported.");
|
||||||
add("(of_int " + toString(type->literalValue(&_literal)) + ")");
|
add("(of_int " + toString(type->literalValue(&_literal)) + ")");
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user