changed names for Rational Constants and categories

This commit is contained in:
VoR0220 2016-03-29 15:08:51 -05:00
parent 4d283b2b30
commit 4b749fc333
6 changed files with 53 additions and 49 deletions

View File

@ -773,8 +773,8 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
// Infer type from value. // Infer type from value.
solAssert(!var.typeName(), ""); solAssert(!var.typeName(), "");
if ( if (
valueComponentType->category() == Type::Category::NumberConstant && valueComponentType->category() == Type::Category::RationalNumber &&
!dynamic_pointer_cast<ConstantNumberType const>(valueComponentType)->integerType() !dynamic_pointer_cast<RationalNumberType const>(valueComponentType)->integerType()
) )
fatalTypeError(_statement.initialValue()->location(), "Invalid integer constant " + valueComponentType->toString() + "."); fatalTypeError(_statement.initialValue()->location(), "Invalid integer constant " + valueComponentType->toString() + ".");
var.annotation().type = valueComponentType->mobileType(); var.annotation().type = valueComponentType->mobileType();
@ -799,8 +799,8 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
void TypeChecker::endVisit(ExpressionStatement const& _statement) void TypeChecker::endVisit(ExpressionStatement const& _statement)
{ {
if (type(_statement.expression())->category() == Type::Category::NumberConstant) if (type(_statement.expression())->category() == Type::Category::RationalNumber)
if (!dynamic_pointer_cast<ConstantNumberType const>(type(_statement.expression()))->integerType()) if (!dynamic_pointer_cast<RationalNumberType const>(type(_statement.expression()))->integerType())
typeError(_statement.expression().location(), "Invalid integer constant."); typeError(_statement.expression().location(), "Invalid integer constant.");
} }
@ -1106,7 +1106,7 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
auto const& argType = type(*arguments[i]); auto const& argType = type(*arguments[i]);
if (functionType->takesArbitraryParameters()) if (functionType->takesArbitraryParameters())
{ {
if (auto t = dynamic_cast<ConstantNumberType const*>(argType.get())) if (auto t = dynamic_cast<RationalNumberType const*>(argType.get()))
if (!t->integerType()) if (!t->integerType())
typeError(arguments[i]->location(), "Integer constant too large."); typeError(arguments[i]->location(), "Integer constant too large.");
} }
@ -1341,7 +1341,7 @@ bool TypeChecker::visit(IndexAccess const& _access)
else else
{ {
expectType(*index, IntegerType(256)); expectType(*index, IntegerType(256));
if (auto numberType = dynamic_cast<ConstantNumberType const*>(type(*index).get())) if (auto numberType = dynamic_cast<RationalNumberType const*>(type(*index).get()))
{ {
if (numberType->denominator() != 1) if (numberType->denominator() != 1)
typeError(_access.location(), "Invalid type for array access."); typeError(_access.location(), "Invalid type for array access.");
@ -1372,7 +1372,7 @@ bool TypeChecker::visit(IndexAccess const& _access)
else else
{ {
index->accept(*this); index->accept(*this);
if (auto length = dynamic_cast<ConstantNumberType const*>(type(*index).get())) if (auto length = dynamic_cast<RationalNumberType const*>(type(*index).get()))
resultType = make_shared<TypeType>(make_shared<ArrayType>( resultType = make_shared<TypeType>(make_shared<ArrayType>(
DataLocation::Memory, DataLocation::Memory,
typeType.actualType(), typeType.actualType(),
@ -1391,7 +1391,7 @@ bool TypeChecker::visit(IndexAccess const& _access)
else else
{ {
expectType(*index, IntegerType(256)); expectType(*index, IntegerType(256));
if (auto integerType = dynamic_cast<ConstantNumberType const*>(type(*index).get())) if (auto integerType = dynamic_cast<RationalNumberType const*>(type(*index).get()))
if (bytesType.numBytes() <= integerType->literalValue(nullptr)) if (bytesType.numBytes() <= integerType->literalValue(nullptr))
typeError(_access.location(), "Out of bounds array access."); typeError(_access.location(), "Out of bounds array access.");
} }

View File

@ -181,8 +181,8 @@ TypePointer Type::forLiteral(Literal const& _literal)
case Token::FalseLiteral: case Token::FalseLiteral:
return make_shared<BoolType>(); return make_shared<BoolType>();
case Token::Number: case Token::Number:
if (ConstantNumberType::isValidLiteral(_literal)) if (RationalNumberType::isValidLiteral(_literal))
return make_shared<ConstantNumberType>(_literal); return make_shared<RationalNumberType>(_literal);
else else
return TypePointer(); return TypePointer();
case Token::StringLiteral: case Token::StringLiteral:
@ -326,7 +326,7 @@ string IntegerType::toString(bool) const
TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
{ {
if (_other->category() != Category::NumberConstant && _other->category() != category()) if (_other->category() != Category::RationalNumber && _other->category() != category())
return TypePointer(); return TypePointer();
auto commonType = dynamic_pointer_cast<IntegerType const>(Type::commonType(shared_from_this(), _other)); auto commonType = dynamic_pointer_cast<IntegerType const>(Type::commonType(shared_from_this(), _other));
@ -441,7 +441,7 @@ string FixedPointType::toString(bool) const
TypePointer FixedPointType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const TypePointer FixedPointType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
{ {
if (_other->category() != Category::NumberConstant if (_other->category() != Category::RationalNumber
&& _other->category() != category() && _other->category() != category()
&& _other->category() != Category::Integer && _other->category() != Category::Integer
) )
@ -459,7 +459,7 @@ TypePointer FixedPointType::binaryOperatorResult(Token::Value _operator, TypePoi
return commonType; return commonType;
} }
bool ConstantNumberType::isValidLiteral(Literal const& _literal) bool RationalNumberType::isValidLiteral(Literal const& _literal)
{ {
try try
{ {
@ -495,7 +495,7 @@ bool ConstantNumberType::isValidLiteral(Literal const& _literal)
return true; return true;
} }
ConstantNumberType::ConstantNumberType(Literal const& _literal) RationalNumberType::RationalNumberType(Literal const& _literal)
{ {
rational numerator; rational numerator;
rational denominator = bigint(1); rational denominator = bigint(1);
@ -554,7 +554,7 @@ ConstantNumberType::ConstantNumberType(Literal const& _literal)
} }
} }
bool ConstantNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const bool RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const
{ {
if (_convertTo.category() == Category::Integer) if (_convertTo.category() == Category::Integer)
{ {
@ -593,7 +593,7 @@ bool ConstantNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const
return false; return false;
} }
bool ConstantNumberType::isExplicitlyConvertibleTo(Type const& _convertTo) const bool RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{ {
if (m_value.denominator() == 1) if (m_value.denominator() == 1)
{ {
@ -605,7 +605,7 @@ bool ConstantNumberType::isExplicitlyConvertibleTo(Type const& _convertTo) const
return fixType && fixType->isExplicitlyConvertibleTo(_convertTo); return fixType && fixType->isExplicitlyConvertibleTo(_convertTo);
} }
TypePointer ConstantNumberType::unaryOperatorResult(Token::Value _operator) const TypePointer RationalNumberType::unaryOperatorResult(Token::Value _operator) const
{ {
rational value; rational value;
switch (_operator) switch (_operator)
@ -626,10 +626,10 @@ TypePointer ConstantNumberType::unaryOperatorResult(Token::Value _operator) cons
default: default:
return TypePointer(); return TypePointer();
} }
return make_shared<ConstantNumberType>(value); return make_shared<RationalNumberType>(value);
} }
TypePointer ConstantNumberType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const TypePointer RationalNumberType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
{ {
if (_other->category() == Category::Integer) if (_other->category() == Category::Integer)
{ {
@ -649,7 +649,7 @@ TypePointer ConstantNumberType::binaryOperatorResult(Token::Value _operator, Typ
else if (_other->category() != category()) else if (_other->category() != category())
return TypePointer(); return TypePointer();
ConstantNumberType const& other = dynamic_cast<ConstantNumberType const&>(*_other); RationalNumberType const& other = dynamic_cast<RationalNumberType const&>(*_other);
if (Token::isCompareOp(_operator)) if (Token::isCompareOp(_operator))
{ {
if (m_value.denominator() == 1) if (m_value.denominator() == 1)
@ -746,26 +746,26 @@ TypePointer ConstantNumberType::binaryOperatorResult(Token::Value _operator, Typ
default: default:
return TypePointer(); return TypePointer();
} }
return make_shared<ConstantNumberType>(value); return make_shared<RationalNumberType>(value);
} }
} }
bool ConstantNumberType::operator==(Type const& _other) const bool RationalNumberType::operator==(Type const& _other) const
{ {
if (_other.category() != category()) if (_other.category() != category())
return false; return false;
ConstantNumberType const& other = dynamic_cast<ConstantNumberType const&>(_other); RationalNumberType const& other = dynamic_cast<RationalNumberType const&>(_other);
return m_value == other.m_value; return m_value == other.m_value;
} }
string ConstantNumberType::toString(bool) const string RationalNumberType::toString(bool) const
{ {
if (m_value.denominator() == 1) if (m_value.denominator() == 1)
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();
} }
u256 ConstantNumberType::literalValue(Literal const*) const u256 RationalNumberType::literalValue(Literal const*) const
{ {
u256 value; u256 value;
// we ignore the literal and hope that the type was correctly determined // we ignore the literal and hope that the type was correctly determined
@ -780,7 +780,7 @@ u256 ConstantNumberType::literalValue(Literal const*) const
return value; return value;
} }
TypePointer ConstantNumberType::mobileType() const TypePointer RationalNumberType::mobileType() const
{ {
if (m_value.denominator() == 1) if (m_value.denominator() == 1)
{ {
@ -793,7 +793,7 @@ TypePointer ConstantNumberType::mobileType() const
return fixType; return fixType;
} }
shared_ptr<IntegerType const> ConstantNumberType::integerType() const shared_ptr<IntegerType const> RationalNumberType::integerType() const
{ {
bigint value = wholeNumbers(); bigint value = wholeNumbers();
bool negative = (value < 0); bool negative = (value < 0);
@ -808,7 +808,7 @@ shared_ptr<IntegerType const> ConstantNumberType::integerType() const
); );
} }
shared_ptr<FixedPointType const> ConstantNumberType::fixedPointType() const shared_ptr<FixedPointType const> RationalNumberType::fixedPointType() const
{ {
//do calculations up here //do calculations up here
bigint integers = wholeNumbers(); bigint integers = wholeNumbers();
@ -844,10 +844,14 @@ shared_ptr<FixedPointType const> ConstantNumberType::fixedPointType() const
} }
//todo: change name of function //todo: change name of function
bigint ConstantNumberType::fractionalBitsNeeded() const bigint RationalNumberType::findFractionNumberAndBits(bool getWholeNumber = false) const
{ {
auto value = m_value - wholeNumbers(); rational value;
for (unsigned fractionalBits = 0; value < boost::multiprecision::pow(bigint(2), 256); fractionalBits += 8, value *= 10) if (getWholeNumber)
value = m_value;
else
value = m_value - wholeNumbers();
for (unsigned fractionalBits = 0; value < boost::multiprecision::pow(bigint(2), 256); fractionalBits += 8, value *= 256)
{ {
if (value.denominator() == 1) if (value.denominator() == 1)
return value.numerator()/value.denominator(); return value.numerator()/value.denominator();

View File

@ -135,7 +135,7 @@ class Type: private boost::noncopyable, public std::enable_shared_from_this<Type
public: public:
enum class Category enum class Category
{ {
Integer, NumberConstant, StringLiteral, Bool, FixedPoint, Array, Integer, RationalNumber, StringLiteral, Bool, FixedPoint, Array,
FixedBytes, Contract, Struct, Function, Enum, Tuple, FixedBytes, Contract, Struct, Function, Enum, Tuple,
Mapping, TypeType, Modifier, Magic, Module Mapping, TypeType, Modifier, Magic, Module
}; };
@ -356,17 +356,17 @@ private:
* Example expressions: 2, 3.14, 2+10.2, ~10. * Example expressions: 2, 3.14, 2+10.2, ~10.
* There is one distinct type per value. * There is one distinct type per value.
*/ */
class ConstantNumberType: public Type class RationalNumberType: public Type
{ {
public: public:
virtual Category category() const override { return Category::NumberConstant; } virtual Category category() const override { return Category::RationalNumber; }
/// @returns true if the literal is a valid integer. /// @returns true if the literal is a valid integer.
static bool isValidLiteral(Literal const& _literal); static bool isValidLiteral(Literal const& _literal);
explicit ConstantNumberType(Literal const& _literal); explicit RationalNumberType(Literal const& _literal);
explicit ConstantNumberType(rational _value): explicit RationalNumberType(rational _value):
m_value(_value) m_value(_value)
{} {}
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;

View File

@ -345,11 +345,11 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
break; break;
case Type::Category::Integer: case Type::Category::Integer:
case Type::Category::Contract: case Type::Category::Contract:
case Type::Category::NumberConstant: case Type::Category::RationalNumber
case Type::Category::FixedPoint: case Type::Category::FixedPoint:
if (targetTypeCategory == Type::Category::FixedBytes) if (targetTypeCategory == Type::Category::FixedBytes)
{ {
solAssert(stackTypeCategory == Type::Category::Integer || stackTypeCategory == Type::Category::NumberConstant, solAssert(stackTypeCategory == Type::Category::Integer || stackTypeCategory == Type::Category::RationalNumber,
"Invalid conversion to FixedBytesType requested."); "Invalid conversion to FixedBytesType requested.");
// conversion from bytes to string. no need to clean the high bit // conversion from bytes to string. no need to clean the high bit
// only to shift left because of opposite alignment // only to shift left because of opposite alignment
@ -366,7 +366,7 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
{ {
solAssert( solAssert(
stackTypeCategory == Type::Category::Integer || stackTypeCategory == Type::Category::Integer ||
stackTypeCategory == Type::Category::NumberConstant || stackTypeCategory == Type::Category::RationalNumber ||
stackTypeCategory == Type::Category::FixedPoint, stackTypeCategory == Type::Category::FixedPoint,
"Invalid conversion to FixedMxNType requested." "Invalid conversion to FixedMxNType requested."
); );
@ -384,9 +384,9 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
IntegerType addressType(0, IntegerType::Modifier::Address); IntegerType addressType(0, IntegerType::Modifier::Address);
IntegerType const& targetType = targetTypeCategory == Type::Category::Integer IntegerType const& targetType = targetTypeCategory == Type::Category::Integer
? dynamic_cast<IntegerType const&>(_targetType) : addressType; ? dynamic_cast<IntegerType const&>(_targetType) : addressType;
if (stackTypeCategory == Type::Category::NumberConstant) if (stackTypeCategory == Type::Category::RationalNumber)
{ {
ConstantNumberType const& constType = dynamic_cast<ConstantNumberType const&>(_typeOnStack); RationalNumberType const& constType = dynamic_cast<RationalNumberType const&>(_typeOnStack);
// We know that the stack is clean, we only have to clean for a narrowing conversion // We know that the stack is clean, we only have to clean for a narrowing conversion
// where cleanup is forced. // where cleanup is forced.
if (targetType.numBits() < constType.integerType()->numBits() && _cleanupNeeded) if (targetType.numBits() < constType.integerType()->numBits() && _cleanupNeeded)

View File

@ -285,7 +285,7 @@ bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation)
// the operator should know how to convert itself and to which types it applies, so // the operator should know how to convert itself and to which types it applies, so
// put this code together with "Type::acceptsBinary/UnaryOperator" into a class that // put this code together with "Type::acceptsBinary/UnaryOperator" into a class that
// represents the operator // represents the operator
if (_unaryOperation.annotation().type->category() == Type::Category::NumberConstant) if (_unaryOperation.annotation().type->category() == Type::Category::RationalNumber)
{ {
m_context << _unaryOperation.annotation().type->literalValue(nullptr); m_context << _unaryOperation.annotation().type->literalValue(nullptr);
return false; return false;
@ -360,7 +360,7 @@ bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)
if (c_op == Token::And || c_op == Token::Or) // special case: short-circuiting if (c_op == Token::And || c_op == Token::Or) // special case: short-circuiting
appendAndOrOperatorCode(_binaryOperation); appendAndOrOperatorCode(_binaryOperation);
else if (commonType.category() == Type::Category::NumberConstant) else if (commonType.category() == Type::Category::RationalNumber)
m_context << commonType.literalValue(nullptr); m_context << commonType.literalValue(nullptr);
else else
{ {
@ -370,7 +370,7 @@ bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)
// for commutative operators, push the literal as late as possible to allow improved optimization // for commutative operators, push the literal as late as possible to allow improved optimization
auto isLiteral = [](Expression const& _e) auto isLiteral = [](Expression const& _e)
{ {
return dynamic_cast<Literal const*>(&_e) || _e.annotation().type->category() == Type::Category::NumberConstant; return dynamic_cast<Literal const*>(&_e) || _e.annotation().type->category() == Type::Category::RationalNumber;
}; };
bool swap = m_optimize && Token::isCommutativeOp(c_op) && isLiteral(rightExpression) && !isLiteral(leftExpression); bool swap = m_optimize && Token::isCommutativeOp(c_op) && isLiteral(rightExpression) && !isLiteral(leftExpression);
if (swap) if (swap)
@ -1225,7 +1225,7 @@ void ExpressionCompiler::endVisit(Literal const& _literal)
switch (type->category()) switch (type->category())
{ {
case Type::Category::NumberConstant: case Type::Category::RationalNumber:
case Type::Category::Bool: case Type::Category::Bool:
m_context << type->literalValue(&_literal); m_context << type->literalValue(&_literal);
break; break;

View File

@ -428,9 +428,9 @@ bool Why3Translator::visit(BinaryOperation const& _binaryOperation)
Type const& commonType = *_binaryOperation.annotation().commonType; Type const& commonType = *_binaryOperation.annotation().commonType;
Token::Value const c_op = _binaryOperation.getOperator(); Token::Value const c_op = _binaryOperation.getOperator();
if (commonType.category() == Type::Category::NumberConstant) if (commonType.category() == Type::Category::RationalNumber)
{ {
auto const& constantNumber = dynamic_cast<ConstantNumberType const&>(commonType); auto const& constantNumber = dynamic_cast<RationalNumberType const&>(commonType);
if (constantNumber.denominator() != bigint(1)) if (constantNumber.denominator() != bigint(1))
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)) + ")");
@ -592,9 +592,9 @@ bool Why3Translator::visit(Literal const& _literal)
else else
add("true"); add("true");
break; break;
case Type::Category::NumberConstant: case Type::Category::RationalNumber:
{ {
auto const& constantNumber = dynamic_cast<ConstantNumberType const&>(*type); auto const& constantNumber = dynamic_cast<RationalNumberType const&>(*type);
if (constantNumber.denominator() != 1) if (constantNumber.denominator() != 1)
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)) + ")");