From a2219639febeeac1807c670071aded337d7a4d7c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 11 Jun 2014 19:25:21 +0100 Subject: [PATCH] LLL supports get/set/ref. Logging changes. --- CodeFragment.cpp | 81 ++++++++++++++++++++++++++++++++--------------- CompilerState.cpp | 4 +++ CompilerState.h | 5 ++- 3 files changed, 63 insertions(+), 27 deletions(-) diff --git a/CodeFragment.cpp b/CodeFragment.cpp index 448d3ef2f..804504f07 100644 --- a/CodeFragment.cpp +++ b/CodeFragment.cpp @@ -79,9 +79,10 @@ CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowAS if (it == _s.vars.end()) { bool ok; - tie(it, ok) = _s.vars.insert(make_pair(s, _s.vars.size() * 32)); + tie(it, ok) = _s.vars.insert(make_pair(s, make_pair(_s.stackSize, 32))); + _s.stackSize += 32; } - m_asm.append((u256)it->second); + m_asm.append((u256)it->second.first); } else error(); @@ -137,6 +138,36 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s) default:; } + auto firstAsString = [&]() + { + auto i = *++_t.begin(); + if (i.tag()) + error(); + if (i.which() == sp::utree_type::string_type) + { + auto sr = i.get, sp::utree_type::string_type>>(); + return string(sr.begin(), sr.end()); + } + else if (i.which() == sp::utree_type::symbol_type) + { + auto sr = i.get, sp::utree_type::symbol_type>>(); + return _s.getDef(string(sr.begin(), sr.end())).m_asm.backString(); + } + return string(); + }; + + auto varAddress = [&](string const& n) + { + auto it = _s.vars.find(n); + if (it == _s.vars.end()) + { + bool ok; + tie(it, ok) = _s.vars.insert(make_pair(n, make_pair(_s.stackSize, 32))); + _s.stackSize += 32; + } + return it->second.first; + }; + // Operations who args are not standard stack-pushers. bool nonStandard = true; if (us == "ASM") @@ -150,22 +181,28 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s) { if (_t.size() != 2) error(); - string n; - auto i = *++_t.begin(); - if (i.tag()) - error(); - if (i.which() == sp::utree_type::string_type) - { - auto sr = i.get, sp::utree_type::string_type>>(); - n = string(sr.begin(), sr.end()); - } - else if (i.which() == sp::utree_type::symbol_type) - { - auto sr = i.get, sp::utree_type::symbol_type>>(); - n = _s.getDef(string(sr.begin(), sr.end())).m_asm.backString(); - } - m_asm.append(CodeFragment::compile(asString(contents(n)), _s).m_asm); + m_asm.append(CodeFragment::compile(asString(contents(firstAsString())), _s).m_asm); } + else if (us == "SET") + { + if (_t.size() != 3) + error(); + int c = 0; + for (auto const& i: _t) + if (c++ == 2) + m_asm.append(CodeFragment(i, _s, false).m_asm); + m_asm.append((u256)varAddress(firstAsString())); + m_asm.append(Instruction::MSTORE); + } + else if (us == "GET") + { + if (_t.size() != 2) + error(); + m_asm.append((u256)varAddress(firstAsString())); + m_asm.append(Instruction::MLOAD); + } + else if (us == "REF") + m_asm.append((u256)varAddress(firstAsString())); else if (us == "DEF") { string n; @@ -497,15 +534,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s) m_asm.popTo(1); } else if (us.find_first_of("1234567890") != 0 && us.find_first_not_of("QWERTYUIOPASDFGHJKLZXCVBNM1234567890_") == string::npos) - { - auto it = _s.vars.find(s); - if (it == _s.vars.end()) - { - bool ok; - tie(it, ok) = _s.vars.insert(make_pair(s, _s.vars.size() * 32)); - } - m_asm.append((u256)it->second); - } + m_asm.append((u256)varAddress(s)); else error(); } diff --git a/CompilerState.cpp b/CompilerState.cpp index 74e5062f7..490e92672 100644 --- a/CompilerState.cpp +++ b/CompilerState.cpp @@ -25,6 +25,10 @@ using namespace std; using namespace eth; +CompilerState::CompilerState() +{ +} + CodeFragment const& CompilerState::getDef(std::string const& _s) { if (defs.count(_s)) diff --git a/CompilerState.h b/CompilerState.h index b7581e0bc..f8f7ce815 100644 --- a/CompilerState.h +++ b/CompilerState.h @@ -36,10 +36,13 @@ struct Macro struct CompilerState { + CompilerState(); + CodeFragment const& getDef(std::string const& _s); void populateStandard(); - std::map vars; + unsigned stackSize = 64; + std::map> vars; ///< maps name to stack offset & size. std::map defs; std::map args; std::map outers;