Browse Source

Include in LLL, sample include file.

cl-refactor
Gav Wood 11 years ago
parent
commit
f3112031e9
  1. 7
      include.lll
  2. 85
      libethereum/Instruction.cpp
  3. 2
      libethereum/Instruction.h

7
include.lll

@ -0,0 +1,7 @@
{
(def 'gav 0x8a40bfaa73256b60764c1bf40675a99083efb075)
(def 'send (to value) (call (- (gas) 21) to value 0 0 0 0))
(def 'makevar (name pos) { (def name (sload pos)) (def name (v) (sstore pos v)) } )
(def 'varcount 0)
(def 'var (name) { (makevar name varcount) (def 'varcount (+ varcount 1)) } )
}

85
libethereum/Instruction.cpp

@ -310,6 +310,7 @@ struct CompilerState
std::map<std::string, CodeFragment> args;
std::map<std::string, CodeFragment> outers;
std::map<std::string, Macro> macros;
std::vector<sp::utree> treesToKill;
};
}
@ -546,12 +547,30 @@ void CodeFragment::appendPushDataLocation(bytes const& _data)
std::string CodeFragment::asPushedString() const
{
string ret;
unsigned bc = m_code[0] - (byte)Instruction::PUSH1 + 1;
if (m_code.size() && m_code[0] >= (byte)Instruction::PUSH1 && m_code[0] <= (byte)Instruction::PUSH32)
for (unsigned s = 0; s < bc && m_code[1 + s]; ++s)
ret.push_back(m_code[1 + s]);
else
error<ExpectedLiteral>();
if (m_code.size())
{
unsigned bc = m_code[0] - (byte)Instruction::PUSH1 + 1;
if (m_code[0] >= (byte)Instruction::PUSH1 && m_code[0] <= (byte)Instruction::PUSH32)
{
for (unsigned s = 0; s < bc && m_code[1 + s]; ++s)
ret.push_back(m_code[1 + s]);
return ret;
}
}
error<ExpectedLiteral>();
return ret;
}
CodeFragment compileLLLFragment(string const& _src, CompilerState& _s)
{
CodeFragment ret;
sp::utree o;
parseLLL(_src, o);
debugOutAST(cerr, o);
cerr << endl;
if (!o.empty())
ret = CodeFragment(o, _s);
_s.treesToKill.push_back(o);
return ret;
}
@ -601,6 +620,26 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
if (c++)
appendFragment(CodeFragment(i, _s, true));
}
else if (us == "INCLUDE")
{
if (_t.size() != 2)
error<IncorrectParameterCount>();
string n;
auto i = *++_t.begin();
if (i.tag())
error<InvalidName>();
if (i.which() == sp::utree_type::string_type)
{
auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, 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::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
n = _s.getDef(string(sr.begin(), sr.end())).asPushedString();
}
appendFragment(compileLLLFragment(asString(contents(n)), _s));
}
else if (us == "DEF")
{
string n;
@ -934,33 +973,25 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
bytes eth::compileLLL(string const& _s, vector<string>* _errors)
{
bytes ret;
sp::utree o;
try
{
parseLLL(_s, o);
CompilerState cs;
bytes ret = compileLLLFragment(_s, cs).code();
for (auto i: cs.treesToKill)
killBigints(i);
return ret;
}
catch (...)
catch (Exception const& _e)
{
if (_errors)
_errors->push_back("Syntax error.");
return ret;
_errors->push_back(_e.description());
}
debugOutAST(cerr, o);
cerr << endl;
if (!o.empty())
try
{
CompilerState cs;
ret = CodeFragment(o, cs).code();
}
catch (CompilerException const& _e)
{
if (_errors)
_errors->push_back(_e.description());
}
killBigints(o);
return ret;
catch (std::exception)
{
if (_errors)
_errors->push_back("Parse error.");
}
return bytes();
}
string eth::disassemble(bytes const& _mem)

2
libethereum/Instruction.h

@ -217,6 +217,8 @@ public:
CodeLocation appendJump(CodeLocation _l) { auto ret = appendPushLocation(_l.m_pos); appendInstruction(Instruction::JUMP); return ret; }
CodeLocation appendJumpI(CodeLocation _l) { auto ret = appendPushLocation(_l.m_pos); appendInstruction(Instruction::JUMPI); return ret; }
void appendFile(std::string const& _fn);
std::string asPushedString() const;
void onePath() { assert(!m_totalDeposit && !m_baseDeposit); m_baseDeposit = m_deposit; m_totalDeposit = INT_MAX; }

Loading…
Cancel
Save