Merge pull request #2520 from ethereum/lll-with

LLL: implement the UNSET and WITH keywords
This commit is contained in:
chriseth 2018-11-21 18:43:37 +01:00 committed by GitHub
commit d47707abad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 0 deletions

View File

@ -259,6 +259,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
}
else if (us == "SET")
{
// TODO: move this to be a stack variable (and not a memory variable)
if (_t.size() != 3)
error<IncorrectParameterCount>(us);
int c = 0;
@ -268,6 +269,15 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
m_asm.append((u256)varAddress(firstAsString(), true));
m_asm.append(Instruction::MSTORE);
}
else if (us == "UNSET")
{
// TODO: this doesn't actually free up anything, since it is a memory variable (see "SET")
if (_t.size() != 2)
error<IncorrectParameterCount>();
auto it = _s.vars.find(firstAsString());
if (it != _s.vars.end())
_s.vars.erase(it);
}
else if (us == "GET")
{
if (_t.size() != 2)
@ -275,6 +285,35 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
m_asm.append((u256)varAddress(firstAsString()));
m_asm.append(Instruction::MLOAD);
}
else if (us == "WITH")
{
if (_t.size() != 4)
error<IncorrectParameterCount>();
string key = firstAsString();
if (_s.vars.find(key) != _s.vars.end())
error<InvalidName>(string("Symbol already used: ") + key);
// Create variable
// TODO: move this to be a stack variable (and not a memory variable)
size_t c = 0;
for (auto const& i: _t)
if (c++ == 2)
m_asm.append(CodeFragment(i, _s, m_readFile, false).m_asm);
m_asm.append((u256)varAddress(key, true));
m_asm.append(Instruction::MSTORE);
// Insert sub with variable access, but new state
CompilerState ns = _s;
c = 0;
for (auto const& i: _t)
if (c++ == 3)
m_asm.append(CodeFragment(i, _s, m_readFile, false).m_asm);
// Remove variable
auto it = _s.vars.find(key);
if (it != _s.vars.end())
_s.vars.erase(it);
}
else if (us == "REF")
m_asm.append((u256)varAddress(firstAsString()));
else if (us == "DEF")

View File

@ -109,6 +109,19 @@ BOOST_AUTO_TEST_CASE(variables)
BOOST_CHECK(callFallback() == encodeArgs(u256(488)));
}
BOOST_AUTO_TEST_CASE(with)
{
char const* sourceCode = R"(
(returnlll
(seq
(set 'x 11)
(with 'y 22 { [0]:(+ (get 'x) (get 'y)) })
(return 0 32)))
)";
compileAndRun(sourceCode);
BOOST_CHECK(callFallback() == toBigEndian(u256(33)));
}
BOOST_AUTO_TEST_CASE(when)
{
char const* sourceCode = R"(