Browse Source

Other operators.

cl-refactor
Gav Wood 11 years ago
parent
commit
3744b2dab3
  1. 70
      libethereum/Instruction.cpp

70
libethereum/Instruction.cpp

@ -1165,7 +1165,7 @@ class CodeFragment
friend class CodeLocation;
public:
CodeFragment(sp::utree const& _t, CompileState const& _s = CompileState(), bool _allowASM = false);
CodeFragment(sp::utree const& _t, CompileState& _s, bool _allowASM = false);
bytes const& code() const { return m_code; }
@ -1193,7 +1193,7 @@ protected:
private:
template <class T> void error() { throw T(); }
void constructOperation(sp::utree const& _t, CompileState const& _s);
void constructOperation(sp::utree const& _t, CompileState& _s);
void donePath() { if (m_totalDeposit != INT_MAX && m_totalDeposit != m_deposit) error<InvalidDeposit>(); }
@ -1312,7 +1312,7 @@ void debugOutAST(ostream& _out, sp::utree const& _this)
}
}
CodeFragment::CodeFragment(sp::utree const& _t, CompileState const& _s, bool _allowASM)
CodeFragment::CodeFragment(sp::utree const& _t, CompileState& _s, bool _allowASM)
{
switch (_t.which())
{
@ -1363,7 +1363,7 @@ CodeFragment::CodeFragment(sp::utree const& _t, CompileState const& _s, bool _al
}
}
void CodeFragment::constructOperation(sp::utree const& _t, CompileState const& _s)
void CodeFragment::constructOperation(sp::utree const& _t, CompileState& _s)
{
if (_t.empty())
error<EmptyList>();
@ -1388,10 +1388,11 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompileState const& _
std::map<std::string, Instruction> const c_unary = { { "!", Instruction::NOT } };
vector<CodeFragment> code;
CompileState ns;
int c = 0;
for (auto const& i: _t)
if (c++)
code.push_back(CodeFragment(i, (s == "LLL" && c == 1) ? CompileState() : _s));
code.push_back(CodeFragment(i, (s == "LLL" && c == 1) ? ns : _s));
auto requireSize = [&](unsigned s) { if (code.size() != s) error<IncorrectParameterCount>(); };
auto requireMinSize = [&](unsigned s) { if (code.size() < s) error<IncorrectParameterCount>(); };
auto requireMaxSize = [&](unsigned s) { if (code.size() > s) error<IncorrectParameterCount>(); };
@ -1406,10 +1407,42 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompileState const& _
else
requireMinSize(-ea);
for (int i = code.size(); i; --i)
for (unsigned i = code.size(); i; --i)
appendFragment(code[i - 1], 1);
appendInstruction(it->second);
}
else if (c_arith.count(s))
{
auto it = c_arith.find(s);
requireMinSize(1);
for (unsigned i = 0; i < code.size(); ++i)
{
requireDeposit(i, 1);
appendFragment(code[i], 1);
}
for (unsigned i = 1; i < code.size(); ++i)
appendInstruction(it->second);
}
else if (c_binary.count(s))
{
auto it = c_binary.find(s);
requireSize(2);
requireDeposit(0, 1);
requireDeposit(1, 1);
appendFragment(code[1], 1);
appendFragment(code[0], 1);
appendInstruction(it->second.first);
if (it->second.second)
appendInstruction(Instruction::NOT);
}
else if (c_unary.count(s))
{
auto it = c_unary.find(s);
requireSize(1);
requireDeposit(0, 1);
appendFragment(code[0], 1);
appendInstruction(it->second);
}
else if (s == "IF")
{
requireSize(3);
@ -1536,13 +1569,33 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompileState const& _
for (auto& i: ends)
i.anchor();
}
else if (s == "~")
{
requireSize(1);
requireDeposit(0, 1);
appendFragment(code[0], 1);
appendPush(1);
appendPush(0);
appendInstruction(Instruction::SUB);
appendInstruction(Instruction::SUB);
}
else if (s == "SEQ")
{
for (auto const& i: code)
appendFragment(i, 0);
}
else
error<InvalidOpCode>();
{
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));
}
appendPush(it->second);
}
// else
// error<InvalidOpCode>();
}
}
@ -1555,7 +1608,8 @@ bytes eth::compileLLL(string const& _s, vector<string>* _errors)
if (!o.empty())
try
{
ret = CodeFragment(o).code();
CompileState cs;
ret = CodeFragment(o, cs).code();
}
catch (CompilerException const& _e)
{

Loading…
Cancel
Save