|
|
@ -146,12 +146,15 @@ static bool compileLispFragment(char const*& d, char const* e, bool _quiet, u256 |
|
|
|
while (d != e) |
|
|
|
{ |
|
|
|
// 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) |
|
|
|
break; |
|
|
|
|
|
|
|
switch (*d) |
|
|
|
{ |
|
|
|
case ';': |
|
|
|
for (; d != e && *d != '\n'; ++d) {} |
|
|
|
break; |
|
|
|
case '(': |
|
|
|
exec = true; |
|
|
|
++d; |
|
|
@ -343,6 +346,107 @@ static bool compileLispFragment(char const*& d, char const* e, bool _quiet, u256 |
|
|
|
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 |
|
|
|
{ |
|
|
|
auto it = c_instructions.find(t); |
|
|
|