aboutsummaryrefslogtreecommitdiffstats
path: root/liblll
diff options
context:
space:
mode:
authorAlex Beregszaszi <alex@rtfs.hu>2017-07-05 04:53:05 +0800
committerAlex Beregszaszi <alex@rtfs.hu>2018-11-21 23:50:45 +0800
commit7c051f1e321a406c1a57870f75106151ad70047b (patch)
tree3991f67a382b2b8b0fa1349108a01e6cac840087 /liblll
parentdcfa5f4ea02f785a0354f145a78f039da25ca485 (diff)
downloaddexon-solidity-7c051f1e321a406c1a57870f75106151ad70047b.tar.gz
dexon-solidity-7c051f1e321a406c1a57870f75106151ad70047b.tar.zst
dexon-solidity-7c051f1e321a406c1a57870f75106151ad70047b.zip
LLL: implement WITH keyword
Diffstat (limited to 'liblll')
-rw-r--r--liblll/CodeFragment.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/liblll/CodeFragment.cpp b/liblll/CodeFragment.cpp
index c6ab86f5..b32f14e9 100644
--- a/liblll/CodeFragment.cpp
+++ b/liblll/CodeFragment.cpp
@@ -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")