hyperledger-solang / solang

Solidity Compiler for Solana and Polkadot
https://solang.readthedocs.io/
Apache License 2.0
1.27k stars 215 forks source link

Support rational constants #284

Closed seanyoung closed 3 years ago

seanyoung commented 4 years ago

In Solidity, rationals are supported as long as they are compile-time constants. e.g. this is supported:

uint x = .5 * 8;

Also, fractions can be written with scientific notation: 1e-2 or 0.001e2.

Fractions can be added/subtracted at compiler time, but fractions cannot be added to integers, like:

uint x = 1;
uint y = x + 0.1;

This change requires:

seanyoung commented 3 years ago

I've left a review. Looks very good so far. Please let me know if you need any help

janus commented 3 years ago

@seanyoung Please review my code before. I changed coerce_integer to coerce_number

seanyoung commented 3 years ago

And then it will be complete. Thanks.

janus commented 3 years ago
* fn coerce_number() should return Type::Rational if either l or r is a rational

* there needs to be a funcion like fn eval_const_number() for rational expressions (something like eval_const_rational)

* fn cast() should check if it can cast from Type::Rational to Type::Uint(n) or Type::Int()

  * it should eval the rational expression using eval_const_rational and see if it is whole number, and not negative for Type::Uint(n)

* in src/codegen/expression.rs fn expression, if a rational expression is found, eval_const_should be called

And then it will be complete. Thanks. Thanks

janus commented 3 years ago
* coerce_number

This is what I have already inside coerce_number function:

        (Type::Rational, Type::Int(_)) => {
            return Ok(Type::Rational);
        }
        (Type::Rational, Type::Uint(_)) => {
            return Ok(Type::Rational);
        }
        (Type::Uint(_), Type::Rational) => {
            return Ok(Type::Rational);
        }
        (Type::Int(_), Type::Rational) => {
            return Ok(Type::Rational);
        }

Is it not complete?

seanyoung commented 3 years ago

I guess so, you also need to check for both l and r being rational.

What I forgot to mention is that you need a simple test case that shows that "uint x = 2.5 + 3.5 - 1;" works

janus commented 3 years ago

@seanyoung I would like to write test for the parser to verify my code, like we have for lexer. Is there something like that?

seanyoung commented 3 years ago

I would suggest adding a test like this one: https://github.com/hyperledger-labs/solang/blob/main/tests/solana_tests/simple.rs#L94-L142

janus commented 3 years ago

@seanyoung I got the below to pass: uint x = .5 * 8; uint x = 1; uint y = x + 0.1;

However, these are failing: 1e-2 0.001e2

I will debug my code. Please go through my code ( and tests) and comment.

This link is broken, https://solang.readthedocs.io/en/latest/installing.html#installing-llvm-on-linux .

seanyoung commented 3 years ago

I've fixed the link. Thank you for mentioning that.

Your code looks good. See my comment on the pull request. You do need to fold the work into one commit, and make sure you have your full name in the Signed-off-by line.

janus commented 3 years ago

@seanyoung I have added your comments to the code. Please review.

NB I have learnt so much and wont mine doing more tasks in the future.

janus commented 3 years ago

@seanyoung I need help. I don't know how to get Visual Code Extension test to pass. I need step by step instruction.

seanyoung commented 3 years ago

Change https://github.com/hyperledger-labs/solang/blob/main/vscode/src/test/suite/extension.test.ts#L35 from:

unrecognised token `}', expected "!", "(", "+", "++", "-", "--", "[", "address", "bool", "bytes", "delete", "false", "function", "mapping", "new", "payable", "string", "this", "true", "~", Bytes, Int, Uint, address, hexnumber, hexstring, identifier, number, string

to

unrecognised token `}', expected "!", "(", "+", "++", "-", "--", "[", "address", "bool", "bytes", "delete", "false", "function", "mapping", "new", "payable", "string", "this", "true", "~", Bytes, Int, Uint, address, hexnumber, hexstring, identifier, number, rational, string

Please also note the review I've left. Should not take long to fix

janus commented 3 years ago

@seanyoung

I get error message if I remove Int/Uint/Value.

test.sol:4:26-28: error: expected ‘uint256’, found rational
Line 4:
    uint x = .5 * 8;
    ---------^^
thread 'solana_tests::simple::returns' panicked at 'called `Option::unwrap()` on a `None` value', src/emit/mod.rs:4348:54

There may be something wrong with my cast then.

janus commented 3 years ago

@seanyoung Thanks so much. Ready for final review.

seanyoung commented 3 years ago

There have been no changes the PR since the last review

seanyoung commented 3 years ago

Please merge all the changes into one commit and push so they are visible at https://github.com/hyperledger-labs/solang/pull/384

janus commented 3 years ago

Please merge all the changes into one commit and push so they are visible at #384

@seanyoung Done.

seanyoung commented 3 years ago

@Web3Foundation the work has been completed, see https://github.com/hyperledger-labs/solang/pull/384

Thanks

gitcoinbot commented 3 years ago

Issue Status: 1. Open 2. Started 3. Submitted 4. Done


Work for 400.0 DAI (400.0 USD @ $1.0/DAI) has been submitted by:


seanyoung commented 2 years ago

@Web3Foundation a reminder, this work has been completed and merged. Thanks