LLL: change (include) to use a callback

This commit is contained in:
Alex Beregszaszi 2017-10-02 13:17:52 +01:00
parent 91b20b4bd2
commit 26f3ea8cf7
6 changed files with 31 additions and 24 deletions

View File

@ -47,7 +47,8 @@ void CodeFragment::finalise(CompilerState const& _cs)
} }
} }
CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM) CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, ReadCallback const& _readFile, bool _allowASM):
m_readFile(_readFile)
{ {
/* /*
std::cout << "CodeFragment. Locals:"; std::cout << "CodeFragment. Locals:";
@ -214,7 +215,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
int c = 0; int c = 0;
for (auto const& i: _t) for (auto const& i: _t)
if (c++) if (c++)
m_asm.append(CodeFragment(i, _s, true).m_asm); m_asm.append(CodeFragment(i, _s, m_readFile, true).m_asm);
} }
else if (us == "INCLUDE") else if (us == "INCLUDE")
{ {
@ -223,10 +224,10 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
string fileName = firstAsString(); string fileName = firstAsString();
if (fileName.empty()) if (fileName.empty())
error<InvalidName>("Empty file name provided"); error<InvalidName>("Empty file name provided");
string contents = contentsString(fileName); string contents = m_readFile(fileName);
if (contents.empty()) if (contents.empty())
error<InvalidName>(std::string("File not found (or empty): ") + fileName); error<InvalidName>(std::string("File not found (or empty): ") + fileName);
m_asm.append(CodeFragment::compile(contents, _s).m_asm); m_asm.append(CodeFragment::compile(contents, _s, m_readFile).m_asm);
} }
else if (us == "SET") else if (us == "SET")
{ {
@ -235,7 +236,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
int c = 0; int c = 0;
for (auto const& i: _t) for (auto const& i: _t)
if (c++ == 2) if (c++ == 2)
m_asm.append(CodeFragment(i, _s, false).m_asm); m_asm.append(CodeFragment(i, _s, m_readFile, false).m_asm);
m_asm.append((u256)varAddress(firstAsString(), true)); m_asm.append((u256)varAddress(firstAsString(), true));
m_asm.append(Instruction::MSTORE); m_asm.append(Instruction::MSTORE);
} }
@ -276,7 +277,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
if (_t.size() == 3) if (_t.size() == 3)
{ {
/// NOTE: some compilers could do the assignment first if this is done in a single line /// NOTE: some compilers could do the assignment first if this is done in a single line
CodeFragment code = CodeFragment(i, _s); CodeFragment code = CodeFragment(i, _s, m_readFile);
_s.defs[n] = code; _s.defs[n] = code;
} }
else else
@ -317,7 +318,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
} }
else if (ii == 1) else if (ii == 1)
{ {
pos = CodeFragment(i, _s); pos = CodeFragment(i, _s, m_readFile);
if (pos.m_asm.deposit() != 1) if (pos.m_asm.deposit() != 1)
error<InvalidDeposit>(toString(i)); error<InvalidDeposit>(toString(i));
} }
@ -396,9 +397,9 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
if (c++) if (c++)
{ {
if (us == "LLL" && c == 1) if (us == "LLL" && c == 1)
code.push_back(CodeFragment(i, ns)); code.push_back(CodeFragment(i, ns, m_readFile));
else else
code.push_back(CodeFragment(i, _s)); code.push_back(CodeFragment(i, _s, m_readFile));
} }
auto requireSize = [&](unsigned s) { if (code.size() != s) error<IncorrectParameterCount>(us); }; auto requireSize = [&](unsigned s) { if (code.size() != s) error<IncorrectParameterCount>(us); };
auto requireMinSize = [&](unsigned s) { if (code.size() < s) error<IncorrectParameterCount>(us); }; auto requireMinSize = [&](unsigned s) { if (code.size() < s) error<IncorrectParameterCount>(us); };
@ -419,7 +420,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
//requireDeposit(i, 1); //requireDeposit(i, 1);
cs.args[m.args[i]] = code[i]; cs.args[m.args[i]] = code[i];
} }
m_asm.append(CodeFragment(m.code, cs).m_asm); m_asm.append(CodeFragment(m.code, cs, m_readFile).m_asm);
for (auto const& i: cs.defs) for (auto const& i: cs.defs)
_s.defs[i.first] = i.second; _s.defs[i.first] = i.second;
for (auto const& i: cs.macros) for (auto const& i: cs.macros)
@ -676,13 +677,13 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
} }
} }
CodeFragment CodeFragment::compile(string const& _src, CompilerState& _s) CodeFragment CodeFragment::compile(string const& _src, CompilerState& _s, ReadCallback const& _readFile)
{ {
CodeFragment ret; CodeFragment ret;
sp::utree o; sp::utree o;
parseTreeLLL(_src, o); parseTreeLLL(_src, o);
if (!o.empty()) if (!o.empty())
ret = CodeFragment(o, _s); ret = CodeFragment(o, _s, _readFile);
_s.treesToKill.push_back(o); _s.treesToKill.push_back(o);
return ret; return ret;
} }

View File

@ -39,10 +39,12 @@ struct CompilerState;
class CodeFragment class CodeFragment
{ {
public: public:
CodeFragment() {} using ReadCallback = std::function<std::string(std::string const&)>;
CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM = false);
static CodeFragment compile(std::string const& _src, CompilerState& _s); CodeFragment() {}
CodeFragment(sp::utree const& _t, CompilerState& _s, ReadCallback const& _readFile, bool _allowASM = false);
static CodeFragment compile(std::string const& _src, CompilerState& _s, ReadCallback const& _readFile);
/// Consolidates data and compiles code. /// Consolidates data and compiles code.
Assembly& assembly(CompilerState const& _cs) { finalise(_cs); return m_asm; } Assembly& assembly(CompilerState const& _cs) { finalise(_cs); return m_asm; }
@ -60,6 +62,7 @@ private:
bool m_finalised = false; bool m_finalised = false;
Assembly m_asm; Assembly m_asm;
ReadCallback m_readFile;
}; };
static const CodeFragment NullCodeFragment; static const CodeFragment NullCodeFragment;

View File

@ -28,13 +28,14 @@ using namespace std;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
bytes dev::eth::compileLLL(string const& _src, bool _opt, vector<string>* _errors)
bytes dev::eth::compileLLL(string const& _src, bool _opt, vector<string>* _errors, ReadCallback const& _readFile)
{ {
try try
{ {
CompilerState cs; CompilerState cs;
cs.populateStandard(); cs.populateStandard();
auto assembly = CodeFragment::compile(_src, cs).assembly(cs); auto assembly = CodeFragment::compile(_src, cs, _readFile).assembly(cs);
if (_opt) if (_opt)
assembly = assembly.optimise(true); assembly = assembly.optimise(true);
bytes ret = assembly.assemble().bytecode; bytes ret = assembly.assemble().bytecode;
@ -66,13 +67,13 @@ bytes dev::eth::compileLLL(string const& _src, bool _opt, vector<string>* _error
return bytes(); return bytes();
} }
std::string dev::eth::compileLLLToAsm(std::string const& _src, bool _opt, std::vector<std::string>* _errors) std::string dev::eth::compileLLLToAsm(std::string const& _src, bool _opt, std::vector<std::string>* _errors, ReadCallback const& _readFile)
{ {
try try
{ {
CompilerState cs; CompilerState cs;
cs.populateStandard(); cs.populateStandard();
auto assembly = CodeFragment::compile(_src, cs).assembly(cs); auto assembly = CodeFragment::compile(_src, cs, _readFile).assembly(cs);
if (_opt) if (_opt)
assembly = assembly.optimise(true); assembly = assembly.optimise(true);
string ret = assembly.assemblyString(); string ret = assembly.assemblyString();

View File

@ -30,9 +30,11 @@ namespace dev
namespace eth namespace eth
{ {
using ReadCallback = std::function<std::string(std::string const&)>;
std::string parseLLL(std::string const& _src); std::string parseLLL(std::string const& _src);
std::string compileLLLToAsm(std::string const& _src, bool _opt = true, std::vector<std::string>* _errors = nullptr); std::string compileLLLToAsm(std::string const& _src, bool _opt = true, std::vector<std::string>* _errors = nullptr, ReadCallback const& _readFile = ReadCallback());
bytes compileLLL(std::string const& _src, bool _opt = true, std::vector<std::string>* _errors = nullptr); bytes compileLLL(std::string const& _src, bool _opt = true, std::vector<std::string>* _errors = nullptr, ReadCallback const& _readFile = ReadCallback());
} }
} }

View File

@ -82,5 +82,5 @@ void CompilerState::populateStandard()
"(def 'shl (val shift) (mul val (exp 2 shift)))" "(def 'shl (val shift) (mul val (exp 2 shift)))"
"(def 'shr (val shift) (div val (exp 2 shift)))" "(def 'shr (val shift) (div val (exp 2 shift)))"
"}"; "}";
CodeFragment::compile(s, *this); CodeFragment::compile(s, *this, CodeFragment::ReadCallback());
} }

View File

@ -138,7 +138,7 @@ int main(int argc, char** argv)
} }
else if (mode == Binary || mode == Hex) else if (mode == Binary || mode == Hex)
{ {
auto bs = compileLLL(src, optimise ? true : false, &errors); auto bs = compileLLL(src, optimise ? true : false, &errors, contentsString);
if (mode == Hex) if (mode == Hex)
cout << toHex(bs) << endl; cout << toHex(bs) << endl;
else if (mode == Binary) else if (mode == Binary)
@ -147,7 +147,7 @@ int main(int argc, char** argv)
else if (mode == ParseTree) else if (mode == ParseTree)
cout << parseLLL(src) << endl; cout << parseLLL(src) << endl;
else if (mode == Assembly) else if (mode == Assembly)
cout << compileLLLToAsm(src, optimise ? true : false, &errors) << endl; cout << compileLLLToAsm(src, optimise ? true : false, &errors, contentsString) << endl;
for (auto const& i: errors) for (auto const& i: errors)
cerr << i << endl; cerr << i << endl;
if ( errors.size() ) if ( errors.size() )