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:";
@ -214,7 +215,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
int c = 0;
for (auto const& i: _t)
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")
{
@ -223,10 +224,10 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
string fileName = firstAsString();
if (fileName.empty())
error<InvalidName>("Empty file name provided");
string contents = contentsString(fileName);
string contents = m_readFile(fileName);
if (contents.empty())
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")
{
@ -235,7 +236,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
int c = 0;
for (auto const& i: _t)
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(Instruction::MSTORE);
}
@ -276,7 +277,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
if (_t.size() == 3)
{
/// 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;
}
else
@ -317,7 +318,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
}
else if (ii == 1)
{
pos = CodeFragment(i, _s);
pos = CodeFragment(i, _s, m_readFile);
if (pos.m_asm.deposit() != 1)
error<InvalidDeposit>(toString(i));
}
@ -396,9 +397,9 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
if (c++)
{
if (us == "LLL" && c == 1)
code.push_back(CodeFragment(i, ns));
code.push_back(CodeFragment(i, ns, m_readFile));
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 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);
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)
_s.defs[i.first] = i.second;
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;
sp::utree o;
parseTreeLLL(_src, o);
if (!o.empty())
ret = CodeFragment(o, _s);
ret = CodeFragment(o, _s, _readFile);
_s.treesToKill.push_back(o);
return ret;
}

View File

@ -39,10 +39,12 @@ struct CompilerState;
class CodeFragment
{
public:
CodeFragment() {}
CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM = false);
using ReadCallback = std::function<std::string(std::string const&)>;
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.
Assembly& assembly(CompilerState const& _cs) { finalise(_cs); return m_asm; }
@ -60,6 +62,7 @@ private:
bool m_finalised = false;
Assembly m_asm;
ReadCallback m_readFile;
};
static const CodeFragment NullCodeFragment;

View File

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

View File

@ -30,9 +30,11 @@ namespace dev
namespace eth
{
using ReadCallback = std::function<std::string(std::string const&)>;
std::string parseLLL(std::string const& _src);
std::string compileLLLToAsm(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);
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, ReadCallback const& _readFile = ReadCallback());
}
}

View File

@ -82,5 +82,5 @@ void CompilerState::populateStandard()
"(def 'shl (val shift) (mul 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)
{
auto bs = compileLLL(src, optimise ? true : false, &errors);
auto bs = compileLLL(src, optimise ? true : false, &errors, contentsString);
if (mode == Hex)
cout << toHex(bs) << endl;
else if (mode == Binary)
@ -147,7 +147,7 @@ int main(int argc, char** argv)
else if (mode == ParseTree)
cout << parseLLL(src) << endl;
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)
cerr << i << endl;
if ( errors.size() )