Variables can be declared constant which allows:
keccak256, ecrecover, sha256, ripemd160, addmod, mulmod, new (for creating objects only, such as arrays)Currently whenever a constant expression is used, the entire expression is placed into the output. This is of course reduced/optimised, but that is mostly restricted to operations on literals and some edge cases.
We should consider one or more of the following:
constant into two, constant which only allows literals and constexpr which allows more complex expressionsecrecover, sha256, ripemd160)constant or constexpr in a VM during compilation time and use the result only (this VM could be a subset of the EVM, since many features are not required)Obviously 2 and 3 contradict eachother. I would opt for 2. unless 4. is implemented and then 3. could be allowed.
Somewhat relevant is #715.
I, by the way, vote for finally starting with this at least soonish...
Should we consider C++-style literals and use them in expressions, such as "stringtobehashed"_keccak256 instead of the built in function?
Going forward I'd very much like for this to work even for user-defined pure functions, e.g.
function weirdStuff(uint256 x, uint256 y) public pure returns(uint256) { return 2**4 - 3 * x / y; }
uint256[weirdStuff(1,2)] x;
Or even stuff like
function weirdStuff(bytes memory x) public pure returns(uint256 s) { for (uint256 i = 0; i < x.length; ++i) s += x[i]; }
uint256[weirdStuff(hex"12345678")] x;
Not in a first step for sure, but eventually...
So given that, I'd personally not see much need to distinguish that much between compile time constant string literal things and function calls.
Is it in any way possible to compile this via yul and run it through an interpreter? Then we would at least not have to re-implement everything.
Why not?
We should definitely allow compile-time evaluation of user-defined pure functions.