LLL: implement WITH keyword

This commit is contained in:
Alex Beregszaszi 2017-07-04 22:53:05 +02:00
parent dcfa5f4ea0
commit 7c051f1e32
2 changed files with 42 additions and 0 deletions

View File

@ -285,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"(