aboutsummaryrefslogtreecommitdiffstats
path: root/liblll
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-11-22 01:43:37 +0800
committerGitHub <noreply@github.com>2018-11-22 01:43:37 +0800
commitd47707abaddfd6820d8ff1f9ec5ec0d2a61ee622 (patch)
treebcaaeebc62d127277057ec4cac8555870a9d881b /liblll
parent10a2e5d100e36b2c031faab35ddd956545d07536 (diff)
parent7c051f1e321a406c1a57870f75106151ad70047b (diff)
downloaddexon-solidity-d47707abaddfd6820d8ff1f9ec5ec0d2a61ee622.tar.gz
dexon-solidity-d47707abaddfd6820d8ff1f9ec5ec0d2a61ee622.tar.zst
dexon-solidity-d47707abaddfd6820d8ff1f9ec5ec0d2a61ee622.zip
Merge pull request #2520 from ethereum/lll-with
LLL: implement the UNSET and WITH keywords
Diffstat (limited to 'liblll')
-rw-r--r--liblll/CodeFragment.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/liblll/CodeFragment.cpp b/liblll/CodeFragment.cpp
index f37cb8b9..b32f14e9 100644
--- a/liblll/CodeFragment.cpp
+++ b/liblll/CodeFragment.cpp
@@ -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")