got exponents up and working with their inverse, changed a few of the tests....something is working that likely shouldn't be

slight changes to how to flip the rational negative around...still trying to figure it out

tests added

updated tests

odd differences in trying soltest from solc binary, let me know if you can replicate

test not working for odd reason

fixed test problem with fixed literals...still need a way to log this error

broken up the tests, added some, changed some things in types and began compiler work

moar tests and prepping for rebuilding much of the types.cpp file

further fixing

infinite loop still happening but it's somewhere in the fixedPoint methodd

fractional bits needed algo improved! Eliminated 2 errors

Corrected problems with the previous commit. No infinite loops. Actually appear to have corrected an error
This commit is contained in:
RJ Catalano 2016-03-18 15:03:26 -05:00 committed by VoR0220
parent a1a2eac5fd
commit 93295ae8f8
5 changed files with 354 additions and 263 deletions

View File

@ -362,6 +362,7 @@ MemberList::MemberMap IntegerType::nativeMembers(ContractDefinition const*) cons
FixedPointType::FixedPointType(int _integerBits, int _fractionalBits, FixedPointType::Modifier _modifier):
m_integerBits(_integerBits), m_fractionalBits(_fractionalBits), m_modifier(_modifier)
{
cout << "FIXED POINT CONSTRUCTOR: " << _integerBits << "x" << _fractionalBits << endl;
solAssert(
m_integerBits + m_fractionalBits > 0 &&
m_integerBits + m_fractionalBits <= 256 &&
@ -469,7 +470,6 @@ bool ConstantNumberType::isValidLiteral(Literal const& _literal)
{
//problem here. If the first digit is a 0 in the string, it won't
//turn it into a integer...Using find if not to count the leading 0s.
auto leadingZeroes = find_if_not(
radixPoint + 1,
_literal.value().end(),
@ -516,18 +516,17 @@ ConstantNumberType::ConstantNumberType(Literal const& _literal)
distance(radixPoint + 1, _literal.value().end())
);
numerator = bigint(string(_literal.value().begin(), radixPoint));
m_value = numerator + denominator;
}
else
m_value = bigint(_literal.value());
switch (_literal.subDenomination())
{
case Literal::SubDenomination::None:
case Literal::SubDenomination::Wei:
case Literal::SubDenomination::Second:
break;
}
case Literal::SubDenomination::Szabo:
m_value *= bigint("1000000000000");
break;
@ -573,24 +572,6 @@ bool ConstantNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const
return false;
}
else if (_convertTo.category() == Category::FixedPoint)
{
auto targetType = dynamic_cast<FixedPointType const*>(&_convertTo);
if (m_value == 0)
return true;
int forSignBit = (targetType->isSigned() ? 1 : 0);
if (m_value > 0)
{
bool properlyScaledBits = m_scalingFactor <= targetType->fractionalBits() ?
true : m_scalingFactor == 1 && targetType->fractionalBits() == 0 ? true : false;
if (m_value <= (u256(-1) >> (256 - targetType->numBits() + forSignBit)) && properlyScaledBits)
return true;
else if (targetType->isSigned() && -m_value <= (u256(1) << (targetType->numBits() - forSignBit)) && properlyScaledBits)
return true;
return false;
}
}
else if (_convertTo.category() == Category::FixedPoint)
{
cout << "IMPLICIT CONVERSION" << endl;
if (fixedPointType() && fixedPointType()->isImplicitlyConvertibleTo(_convertTo))
@ -598,6 +579,12 @@ bool ConstantNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const
return false;
}
else if (_convertTo.category() == Category::FixedPoint)
{
if (fixedPointType() && fixedPointType()->isImplicitlyConvertibleTo(_convertTo))
return true;
return false;
}
else if (_convertTo.category() == Category::FixedBytes)
{
FixedBytesType const& fixedBytes = dynamic_cast<FixedBytesType const&>(_convertTo);
@ -613,6 +600,7 @@ bool ConstantNumberType::isExplicitlyConvertibleTo(Type const& _convertTo) const
TypePointer intType = integerType();
return intType && intType->isExplicitlyConvertibleTo(_convertTo);
}
cout << "EXPLICIT CONVERSION" << endl;
TypePointer fixType = fixedPointType();
return fixType && fixType->isExplicitlyConvertibleTo(_convertTo);
}
@ -628,10 +616,10 @@ TypePointer ConstantNumberType::unaryOperatorResult(Token::Value _operator) cons
value = ~m_value.numerator();
break;
case Token::Add:
value = m_value;
value = +(m_value);
break;
case Token::Sub:
value = -m_value;
value = -(m_value);
break;
case Token::After:
return shared_from_this();
@ -711,7 +699,6 @@ TypePointer ConstantNumberType::binaryOperatorResult(Token::Value _operator, Typ
value = m_value - other.m_value;
break;
case Token::Mul:
scale = m_scalingFactor - other.m_scalingFactor;
value = m_value * other.m_value;
break;
case Token::Div:
@ -734,6 +721,7 @@ TypePointer ConstantNumberType::binaryOperatorResult(Token::Value _operator, Typ
break;
case Token::Exp:
{
cout << "Is this the source of the problem" << endl;
bigint newDenominator;
bigint newNumerator;
if (other.m_value.denominator() != 1)
@ -781,7 +769,7 @@ u256 ConstantNumberType::literalValue(Literal const*) const
{
u256 value;
// we ignore the literal and hope that the type was correctly determined
solAssert(m_value <= u256(-1), "Number constant too large.");
solAssert(m_value >= -(bigint(1) << 255), "Number constant too small.");
if (m_value >= 0)
@ -807,7 +795,7 @@ TypePointer ConstantNumberType::mobileType() const
shared_ptr<IntegerType const> ConstantNumberType::integerType() const
{
bigint value = m_value.numerator() / m_value.denominator();
bigint value = wholeNumbers();
bool negative = (value < 0);
if (negative) // convert to positive number of same bit requirements
value = ((0 - value) - 1) << 1;
@ -822,28 +810,51 @@ shared_ptr<IntegerType const> ConstantNumberType::integerType() const
shared_ptr<FixedPointType const> ConstantNumberType::fixedPointType() const
{
rational value = m_value;
cout << "Original value: " << value << endl;
bool negative = (value < 0);
if (negative) // convert to absolute value
value = abs(value);
if (value > u256(-1))
//do calculations up here
bigint integers = wholeNumbers();
//bigint _remainder = abs(m_value.numerator() % m_value.denominator());
bool fractionalSignBit = integers == 0; //sign the fractional side or the integer side
bool negative = (m_value < 0);
//todo: change name
bigint fractionalBits = fractionalBitsNeeded();
if (negative && !fractionalSignBit) // convert to positive number of same bit requirements
{
integers = ((0 - integers) - 1) << 1;
fractionalBits = ((0 - fractionalBits) - 1) << 1;
}
else if (negative && fractionalSignBit)
fractionalBits = ((0 - fractionalBits) - 1) << 1;
if (fractionalBits > u256(-1))
return shared_ptr<FixedPointType const>();
else
{
// need to fix this because these aren't the proper M and N
bigint integerBits = m_value.numerator() / m_value.denominator();
bigint remains = m_value.numerator() % m_value.denominator();
cout << "Integer: " << integerBits.str() << endl;
cout << "Remains: " << remains.str() << endl << endl;
bigint fractionalBits;
unsigned totalBytesRequired = bytesRequired(fractionalBits) * 8;
unsigned integerBytesRequired = bytesRequired(integers) * 8;
return make_shared<FixedPointType>(
max(bytesRequired(integerBits), 1u) * 8, max(bytesRequired(fractionalBits), 1u) * 8,
integerBytesRequired, totalBytesRequired - integerBytesRequired,
negative ? FixedPointType::Modifier::Signed : FixedPointType::Modifier::Unsigned
);
}
}
//todo: change name of function
bigint ConstantNumberType::fractionalBitsNeeded() const
{
auto value = m_value;
for (unsigned fractionalBits = 0; value < boost::multiprecision::pow(bigint(2), 256); fractionalBits += 8, value *= 10)
{
if (value.denominator() == 1)
return value.numerator()/value.denominator();
for ( ; value.denominator() != 1 && value < boost::multiprecision::pow(bigint(2), fractionalBits); value *= 10)
if (value.denominator() == 1)
return value.numerator()/value.denominator();
}
cout << "too big :(" << endl;
return value.numerator()/value.denominator();
}
StringLiteralType::StringLiteralType(Literal const& _literal):

View File

@ -387,8 +387,11 @@ public:
std::shared_ptr<IntegerType const> integerType() const;
/// @returns the smallest fixed type that can hold the value or an empty pointer
std::shared_ptr<FixedPointType const> fixedPointType() const;
bigint fractionalBitsNeeded() const;
bigint denominator() const { return m_value.denominator(); }
bigint wholeNumbers() const { return m_value.numerator() / m_value.denominator(); }
private:
rational m_value;
};

View File

@ -436,19 +436,6 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
);
break;
}
/*case Type::Category::Fixed:
{
if (targetTypeCategory == Type::Category::Integer)
{
//need some guidance here
}
else if (targetTypeCategory == Type::Category::FixedBytes)
{
//need some guidance here
}
else
//need some guidance here
}*/
case Type::Category::Array:
{
solAssert(targetTypeCategory == stackTypeCategory, "");

View File

@ -153,9 +153,9 @@ tuple<Token::Value, unsigned int, unsigned int> Token::fromIdentifierOrKeyword(s
positionM < positionX &&
positionX < _literal.end() &&
*positionX == 'x' &&
all_of(++positionX, _literal.end(), ::isdigit)
all_of(positionX + 1, _literal.end(), ::isdigit)
) {
int n = parseSize(positionX, _literal.end());
int n = parseSize(positionX + 1, _literal.end());
if (
0 <= m && m <= 256 &&
0 <= n && n <= 256 &&

View File

@ -3354,6 +3354,303 @@ BOOST_AUTO_TEST_CASE(fixed_type_literal_expression)
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(fixed_type_invalid_size_conversion)
{
char const* text = R"(
contract test {
function f() {
fixed a = 1/3;
ufixed248x8 b = a + 2.5;
}
}
)";
BOOST_CHECK(!success(text));
}
BOOST_AUTO_TEST_CASE(fixed_type_valid_size_conversion)
{
char const* text = R"(
contract test {
function f() {
fixed a = 1/3;
ufixed248x8 b = ufixed248x8(a) + 2.5;
}
}
)";
BOOST_CHECK(!success(text));
}
BOOST_AUTO_TEST_CASE(uint_array_declaration_with_fixed_type)
{
char const* text = R"(
contract test {
function f() {
uint[fixed(3.56)] a;
}
}
)";
BOOST_CHECK(!success(text));
}
BOOST_AUTO_TEST_CASE(array_declaration_with_fixed_literal)
{
char const* text = R"(
contract test {
function f() {
uint[3.56] a;
}
}
)";
BOOST_CHECK(!success(text));
}
BOOST_AUTO_TEST_CASE(mapping_with_fixed_literal)
{
char const* text = R"(
contract test {
mapping(fixed => string) fixedString;
function f() {
fixedString[3.14] = "Pi";
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(inline_array_fixed_type)
{
char const* text = R"(
contract test {
function f() {
fixed[3] memory a = [fixed(3.5), fixed(4.1234), fixed(967.32)];
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(inline_array_fixed_rationals)
{
char const* text = R"(
contract test {
function f() {
ufixed8x16[3] memory a = [3.5, 4.1234, 2.5];
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(size_capabilities_of_fixed_point_types)
{
char const* text = R"(
contract test {
function f() {
ufixed0x64 a = 0.12345678;
ufixed8x0 b = 12345678.0;
ufixed0x64 c = 0.00000009;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(var_capable_of_holding_constant_rationals)
{
char const* text = R"(
contract test {
function f() {
var a = 0.12345678;
var b = 12345678.0;
var c = 0.00000009;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(invalid_rational_exponent_usage)
{
char const* text = R"(
contract test {
function f() {
fixed8x8 a = 3 ** 1.5;
fixed24x24 b = 2 ** (1/2);
fixed40x40 c = 42 ** (-1/4);
fixed48x48 d = 16 ** -0.33;
}
}
)";
BOOST_CHECK(!success(text));
}
BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents)
{
char const* text = R"(
contract test {
function f() {
fixed a = 3 ** fixed(1.5);
fixed b = 2 ** fixed(1/2);
fixed c = 42 ** fixed(-1/4);
fixed d = 16 ** fixed(-0.33);
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(rational_unary_operation)
{
char const* text = R"(
contract test {
function f() {
fixed a = +3.5134;
fixed b = -2.5145;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(rational_bitnot_unary_operation)
{
char const* text = R"(
contract test {
function f() {
fixed a = ~3.56;
}
}
)";
BOOST_CHECK(!success(text));
}
BOOST_AUTO_TEST_CASE(rational_bitor_binary_operation)
{
char const* text = R"(
contract test {
function f() {
fixed a = 1.56 | 3;
}
}
)";
BOOST_CHECK(!success(text));
}
BOOST_AUTO_TEST_CASE(rational_bitxor_binary_operation)
{
char const* text = R"(
contract test {
function f() {
fixed a = 1.56 ^ 3;
}
}
)";
BOOST_CHECK(!success(text));
}
BOOST_AUTO_TEST_CASE(rational_bitand_binary_operation)
{
char const* text = R"(
contract test {
function f() {
fixed a = 1.56 & 3;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(valid_fraction_fixed_type)
{
char const* text = R"(
contract test {
function f(){
fixed8x8 a = (2**24)/127;
fixed0x8 b = 1/256;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(valid_fixed_types)
{
char const* text = R"(
contract test {
function f(){
fixed8x8 a = 87654321.12345678;
fixed16x16 b = a**2;
fixed24x24 c = b**3;
fixed32x32 d = b**2;
fixed40x40 e = a**5;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(fixed_type_int_conversion)
{
char const* text = R"(
contract test {
function f() {
uint128 a = 3;
int128 b = 4;
fixed c = b;
ufixed d = a;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(fixed_type_const_int_conversion)
{
char const* text = R"(
contract test {
function f() {
fixed c = 3;
ufixed d = 4;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(fixed_type_literal)
{
char const* text = R"(
contract test {
function f() {
fixed a = 3.14;
ufixed d = 2.555555;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(fixed_type_literal_expression)
{
char const* text = R"(
contract test {
function f() {
fixed a = 3.14 * 3;
ufixed b = 4 - 2.555555;
fixed c = 1.0 / 3.0;
ufixed d = 599 + .5367;
ufixed e = 35.245 % 12.9;
ufixed f = 1.2 % 2.00000;
fixed g = 2 ** -2;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(uint_array_declaration_with_fixed_type)
{
char const* text = R"(
@ -3367,7 +3664,7 @@ BOOST_AUTO_TEST_CASE(uint_array_declaration_with_fixed_type)
}
BOOST_AUTO_TEST_CASE(array_declaration_with_fixed_literal)
BOOST_AUTO_TEST_CASE(array_declaration_with_rational)
{
char const* text = R"(
contract test {
@ -3543,216 +3840,9 @@ BOOST_AUTO_TEST_CASE(rational_bitand_binary_operation)
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(invalid_non_mod_8_fixed_types)
{
char const* text = R"(
contract test {
function f(){
fixed8x10 a = 12345678.1234567890;
}
}
)";
BOOST_CHECK(!success(text));
}
BOOST_AUTO_TEST_CASE(valid_fixed_types)
{
char const* text = R"(
contract test {
function f(){
fixed8x8 a = 87654321.12345678;
fixed16x16 b = a**2;
fixed24x24 c = b**(1.5);
fixed32x32 d = b**2;
fixed40x40 e = a**5;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(fixed_type_int_conversion)
{
char const* text = R"(
contract test {
function f() {
uint128 a = 3;
int128 b = 4;
fixed c = b;
ufixed d = a;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(fixed_type_const_int_conversion)
{
char const* text = R"(
contract test {
function f() {
fixed c = 3;
ufixed d = 4;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(fixed_type_literal)
{
char const* text = R"(
contract test {
function f() {
fixed a = 3.14;
ufixed d = 2.555555;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(fixed_type_literal_expression)
{
char const* text = R"(
contract test {
function f() {
fixed a = 3.14 * 3;
ufixed b = 4 - 2.555555;
fixed c = 1.0 / 3.0;
ufixed d = 599 + .5367;
ufixed e = 35.245 % 12.9;
ufixed f = 1.2 % 2.00000;
//fixed g = 2 ** -1.5;
//fixed h = -3 ** -5.8;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(fixed_type_literal_seconds_and_wei)
{
char const* text = R"(
contract test {
function f() {
fixed a = 3.14 wei;
ufixed b = 4.5 seconds;
}
}
)";
BOOST_CHECK(!success(text));
}
BOOST_AUTO_TEST_CASE(uint_array_declaration_with_fixed_type)
{
char const* text = R"(
contract test {
function f() {
uint[fixed(3.56)] a;
}
}
)";
BOOST_CHECK(!success(text));
}
BOOST_AUTO_TEST_CASE(array_declaration_with_fixed_literal)
{
char const* text = R"(
contract test {
function f() {
uint[3.56] a;
}
}
)";
BOOST_CHECK(!success(text));
}
BOOST_AUTO_TEST_CASE(mapping_with_fixed_literal)
{
char const* text = R"(
contract test {
mapping(fixed => string) fixedString;
function f() {
fixedString[3.14] = "Pi";
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(inline_array_fixed_type)
{
char const* text = R"(
contract test {
function f() {
fixed[3] memory a = [fixed(3.5), fixed(4.1234), fixed(967.32)];
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(inline_array_fixed_literals)
{
char const* text = R"(
contract test {
function f() {
fixed[3] memory a = [3.5, 4.1234, 967.32];
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(zero_and_eight_variants_fixed)
{
char const* text = R"(
contract A {
fixed8x0 someInt = 4;
fixed0x8 half = 0.5;
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(size_capabilities_of_fixed_point_types)
{
char const* text = R"(
contract test {
function f() {
fixed0x8 a = 0.12345678;
fixed8x0 b = 12345678.0;
fixed0x8 c = 0.00000009;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(var_capable_of_holding_fixed_constants)
{
char const* text = R"(
contract test {
function f() {
var a = 0.12345678;
var b = 12345678.0;
var c = 0.00000009;
}
}
)";
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_SUITE_END()
}