Browse Source

Comments and boolean operators.

cl-refactor
Gav Wood 11 years ago
parent
commit
87f9d5bd39
  1. 106
      libethereum/Instruction.cpp

106
libethereum/Instruction.cpp

@ -146,12 +146,15 @@ static bool compileLispFragment(char const*& d, char const* e, bool _quiet, u256
while (d != e) while (d != e)
{ {
// skip to next token // skip to next token
for (; d != e && !isalnum(*d) && *d != '(' && *d != ')' && *d != '_' && *d != '"' && !c_allowed.count(*d); ++d) {} for (; d != e && !isalnum(*d) && *d != '(' && *d != ')' && *d != '_' && *d != '"' && !c_allowed.count(*d) && *d != ';'; ++d) {}
if (d == e) if (d == e)
break; break;
switch (*d) switch (*d)
{ {
case ';':
for (; d != e && *d != '\n'; ++d) {}
break;
case '(': case '(':
exec = true; exec = true;
++d; ++d;
@ -343,6 +346,107 @@ static bool compileLispFragment(char const*& d, char const* e, bool _quiet, u256
break; break;
} }
} }
else if (t == "AND")
{
vector<u256s> codes;
vector<vector<unsigned>> locs;
while (d != e)
{
codes.resize(codes.size() + 1);
locs.resize(locs.size() + 1);
if (!compileLispFragment(d, e, _quiet, codes.back(), locs.back()))
break;
}
// last one is empty.
if (codes.size() < 2)
return false;
codes.pop_back();
locs.pop_back();
vector<unsigned> ends;
if (codes.size() > 1)
{
o_code.push_back(Instruction::PUSH);
o_code.push_back(0);
for (unsigned i = 1; i < codes.size(); ++i)
{
// Push the false location.
o_code.push_back(Instruction::PUSH);
ends.push_back((unsigned)o_code.size());
o_locs.push_back(ends.back());
o_code.push_back(0);
// Check if true - predicate
appendCode(o_code, o_locs, codes[i - 1], locs[i - 1]);
// Jump to end...
o_code.push_back(Instruction::NOT);
o_code.push_back(Instruction::JMPI);
}
o_code.push_back(Instruction::POP);
}
// Check if true - predicate
appendCode(o_code, o_locs, codes.back(), locs.back());
// At end now.
for (auto i: ends)
o_code[i] = o_code.size();
}
else if (t == "OR")
{
vector<u256s> codes;
vector<vector<unsigned>> locs;
while (d != e)
{
codes.resize(codes.size() + 1);
locs.resize(locs.size() + 1);
if (!compileLispFragment(d, e, _quiet, codes.back(), locs.back()))
break;
}
// last one is empty.
if (codes.size() < 2)
return false;
codes.pop_back();
locs.pop_back();
vector<unsigned> ends;
if (codes.size() > 1)
{
o_code.push_back(Instruction::PUSH);
o_code.push_back(1);
for (unsigned i = 1; i < codes.size(); ++i)
{
// Push the false location.
o_code.push_back(Instruction::PUSH);
ends.push_back((unsigned)o_code.size());
o_locs.push_back(ends.back());
o_code.push_back(0);
// Check if true - predicate
appendCode(o_code, o_locs, codes[i - 1], locs[i - 1]);
// Jump to end...
o_code.push_back(Instruction::JMPI);
}
o_code.push_back(Instruction::POP);
}
// Check if true - predicate
appendCode(o_code, o_locs, codes.back(), locs.back());
// At end now.
for (auto i: ends)
o_code[i] = o_code.size();
}
else else
{ {
auto it = c_instructions.find(t); auto it = c_instructions.find(t);

Loading…
Cancel
Save