Browse Source

New language facilities.

cl-refactor
Gav Wood 11 years ago
parent
commit
b486033cbf
  1. 2
      alethzero/MainWin.cpp
  2. 120
      libethereum/Instruction.cpp

2
alethzero/MainWin.cpp

@ -537,7 +537,7 @@ void Main::on_data_textChanged()
string code = ui->data->toPlainText().toStdString();
m_init.clear();
m_data = compileLisp(code, true, m_init);
ui->code->setHtml((m_init.size() ? ("<h4>Init</h4><pre>" + QString::fromStdString(disassemble(m_init)) + "</pre>") : "") + "<h4>Body</h4><pre>" + QString::fromStdString(disassemble(m_data)) + "</pre>");
ui->code->setHtml((m_init.size() ? "<h4>Init</h4>" + QString::fromStdString(disassemble(m_init)).toHtmlEscaped() : "") + "<h4>Body</h4>" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped());
ui->gas->setMinimum((qint64)state().createGas(m_data.size() + m_init.size(), 0));
if (!ui->gas->isEnabled())
ui->gas->setValue(m_backupGas);

120
libethereum/Instruction.cpp

@ -339,7 +339,7 @@ static void appendCode(bytes& o_code, vector<unsigned>& o_locs, bytes _code, vec
o_code.push_back(i);
}
static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes& o_code, vector<unsigned>& o_locs)
static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes& o_code, vector<unsigned>& o_locs, map<string, unsigned>& _vars)
{
std::map<std::string, Instruction> const c_arith = { { "+", Instruction::ADD }, { "-", Instruction::SUB }, { "*", Instruction::MUL }, { "/", Instruction::DIV }, { "%", Instruction::MOD } };
std::map<std::string, pair<Instruction, bool>> const c_binary = { { "<", { Instruction::LT, false } }, { "<=", { Instruction::GT, true } }, { ">", { Instruction::GT, false } }, { ">=", { Instruction::LT, true } }, { "=", { Instruction::EQ, false } }, { "!=", { Instruction::EQ, true } } };
@ -352,7 +352,7 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes
while (d != e)
{
// skip to next token
for (; d != e && !isalnum(*d) && *d != '(' && *d != ')' && *d != '_' && *d != '"' && !c_allowed.count(*d) && *d != ';'; ++d) {}
for (; d != e && !isalnum(*d) && *d != '(' && *d != ')' && *d != '_' && *d != '"' && *d != '@' && *d != '[' && !c_allowed.count(*d) && *d != ';'; ++d) {}
if (d == e)
break;
@ -374,6 +374,59 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes
else
// unexpected - return false as we don't know what to do with it.
return -1;
case '@':
{
if (exec)
return -1;
bool store = false;
++d;
if (*d == '@')
{
++d;
store = true;
}
bytes codes;
vector<unsigned> locs;
if (compileLispFragment(d, e, _quiet, codes, locs, _vars) != 1)
return -1;
while (d != e && isspace(*d))
++d;
appendCode(o_code, o_locs, codes, locs);
o_code.push_back((byte)(store ? Instruction::SLOAD : Instruction::MLOAD));
return 1;
}
case '[':
{
if (exec)
return -1;
bool store = false;
++d;
if (*d == '[')
{
++d;
store = true;
}
bytes codes;
vector<unsigned> locs;
if (compileLispFragment(d, e, _quiet, codes, locs, _vars) != 1)
return -1;
while (d != e && isspace(*d))
++d;
if (*d != ']')
return -1;
++d;
if (store && *d != ']')
return -1;
++d;
if (compileLispFragment(d, e, _quiet, o_code, o_locs, _vars) != 1)
return -1;
appendCode(o_code, o_locs, codes, locs);
o_code.push_back((byte)(store ? Instruction::SSTORE: Instruction::MSTORE));
return 1;
}
default:
{
bool haveLiteral = false;
@ -414,10 +467,10 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes
{
bytes codes;
vector<unsigned> locs;
if (compileLispFragment(d, e, _quiet, codes, locs) != -1)
if (compileLispFragment(d, e, _quiet, codes, locs, _vars) != -1)
{
appendCode(o_code, o_locs, codes, locs);
while (compileLispFragment(d, e, _quiet, codes, locs) != -1)
while (compileLispFragment(d, e, _quiet, codes, locs, _vars) != -1)
if (!_quiet)
cwarn << "Additional items in bare store. Ignoring.";
bareLoad = false;
@ -437,13 +490,13 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes
vector<unsigned> locs[4];
for (int i = 0; i < 3; ++i)
{
int o = compileLispFragment(d, e, _quiet, codes[i], locs[i]);
int o = compileLispFragment(d, e, _quiet, codes[i], locs[i], _vars);
if (i == 1)
outs = o;
if ((i == 0 && o != 1) || o == -1 || (i == 2 && o != outs))
return -1;
}
if (compileLispFragment(d, e, _quiet, codes[3], locs[3]) != -1)
if (compileLispFragment(d, e, _quiet, codes[3], locs[3], _vars) != -1)
return false;
// First fragment - predicate
@ -481,14 +534,14 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes
vector<unsigned> locs[3];
for (int i = 0; i < 2; ++i)
{
int o = compileLispFragment(d, e, _quiet, codes[i], locs[i]);
int o = compileLispFragment(d, e, _quiet, codes[i], locs[i], _vars);
if (o == -1 || (i == 0 && o != 1))
return false;
if (i == 1)
for (int j = 0; j < o; ++j)
codes[i].push_back((byte)Instruction::POP); // pop additional items off stack for the previous item (final item's returns get left on).
}
if (compileLispFragment(d, e, _quiet, codes[2], locs[2]) != -1)
if (compileLispFragment(d, e, _quiet, codes[2], locs[2], _vars) != -1)
return false;
// First fragment - predicate
@ -518,14 +571,14 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes
vector<unsigned> locs[3];
for (int i = 0; i < 2; ++i)
{
int o = compileLispFragment(d, e, _quiet, codes[i], locs[i]);
int o = compileLispFragment(d, e, _quiet, codes[i], locs[i], _vars);
if (o == -1 || (i == 0 && o != 1))
return false;
if (i == 1)
for (int j = 0; j < o; ++j)
codes[i].push_back((byte)Instruction::POP); // pop additional items off stack for the previous item (final item's returns get left on).
}
if (compileLispFragment(d, e, _quiet, codes[2], locs[2]) != -1)
if (compileLispFragment(d, e, _quiet, codes[2], locs[2], _vars) != -1)
return false;
unsigned startLocation = (unsigned)o_code.size();
@ -561,7 +614,7 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes
vector<unsigned> locs;
outs = 0;
int o;
if ((o = compileLispFragment(d, e, _quiet, codes, locs)) > -1)
if ((o = compileLispFragment(d, e, _quiet, codes, locs, _vars)) > -1)
{
for (int i = 0; i < outs; ++i)
o_code.push_back((byte)Instruction::POP); // pop additional items off stack for the previous item (final item's returns get left on).
@ -580,7 +633,7 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes
int totalArgs = 0;
while (d != e)
{
int o = compileLispFragment(d, e, _quiet, codes.back().first, codes.back().second);
int o = compileLispFragment(d, e, _quiet, codes.back().first, codes.back().second, _vars);
if (o < 1)
break;
codes.push_back(pair<bytes, vector<unsigned>>());
@ -612,7 +665,7 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes
vector<unsigned> locs;
outs = 0;
int o;
if ((o = compileLispFragment(d, e, _quiet, codes, locs)) > -1)
if ((o = compileLispFragment(d, e, _quiet, codes, locs, _vars)) > -1)
{
outs += o;
appendCode(o_code, o_locs, codes, locs);
@ -630,11 +683,11 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes
codes.resize(codes.size() + 1);
locs.resize(locs.size() + 1);
{
int o = compileLispFragment(d, e, _quiet, codes.back(), locs.back());
int o = compileLispFragment(d, e, _quiet, codes.back(), locs.back(), _vars);
if (o != 1)
return false;
}
if (compileLispFragment(d, e, _quiet, codes.back(), locs.back()) != -1)
if (compileLispFragment(d, e, _quiet, codes.back(), locs.back(), _vars) != -1)
break;
}
@ -684,7 +737,7 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes
codes.resize(codes.size() + 1);
locs.resize(locs.size() + 1);
{
int o = compileLispFragment(d, e, _quiet, codes.back(), locs.back());
int o = compileLispFragment(d, e, _quiet, codes.back(), locs.back(), _vars);
if (o != 1)
return false;
}
@ -737,7 +790,7 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes
int totalArgs = 0;
while (d != e)
{
int o = compileLispFragment(d, e, _quiet, codes.back().first, codes.back().second);
int o = compileLispFragment(d, e, _quiet, codes.back().first, codes.back().second, _vars);
if (o < 1)
break;
codes.push_back(pair<bytes, vector<unsigned>>());
@ -770,7 +823,7 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes
int totalArgs = 0;
while (d != e)
{
int o = compileLispFragment(d, e, _quiet, codes.back().first, codes.back().second);
int o = compileLispFragment(d, e, _quiet, codes.back().first, codes.back().second, _vars);
if (o < 1)
break;
codes.push_back(pair<bytes, vector<unsigned>>());
@ -795,7 +848,7 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes
int totalArgs = 0;
while (d != e)
{
int o = compileLispFragment(d, e, _quiet, codes.back().first, codes.back().second);
int o = compileLispFragment(d, e, _quiet, codes.back().first, codes.back().second, _vars);
if (o < 1)
break;
codes.push_back(pair<bytes, vector<unsigned>>());
@ -823,7 +876,7 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes
int totalArgs = 0;
while (d != e)
{
int o = compileLispFragment(d, e, _quiet, codes.back().first, codes.back().second);
int o = compileLispFragment(d, e, _quiet, codes.back().first, codes.back().second, _vars);
if (o == -1)
break;
totalArgs += o;
@ -840,8 +893,16 @@ static int compileLispFragment(char const*& d, char const* e, bool _quiet, bytes
appendCode(o_code, o_locs, it->first, it->second);
o_code.push_back((byte)it->second);
}
else if (!_quiet)
cwarn << "Unknown assembler token" << t;
else
{
auto it = _vars.find(t);
if (it == _vars.end())
{
bool ok;
tie(it, ok) = _vars.insert(make_pair(t, _vars.size() * 32));
}
pushLiteral(o_code, it->second);
}
}
}
}
@ -860,12 +921,19 @@ bytes eth::compileLisp(std::string const& _code, bool _quiet, bytes& _init)
{
char const* d = _code.data();
char const* e = _code.data() + _code.size();
bytes ret;
bytes first;
bytes second;
vector<unsigned> locs;
compileLispFragment(d, e, _quiet, ret, locs);
map<string, unsigned> vars;
compileLispFragment(d, e, _quiet, first, locs, vars);
locs.clear();
compileLispFragment(d, e, _quiet, _init, locs);
return ret;
vars.clear();
if (compileLispFragment(d, e, _quiet, second, locs, vars) > -1)
{
_init = first;
return second;
}
return first;
}
string eth::disassemble(bytes const& _mem)

Loading…
Cancel
Save