From 87f9d5bd3980105f5e335ffea104d78b9430bbc4 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 27 Feb 2014 12:37:50 +0000 Subject: [PATCH] Comments and boolean operators. --- libethereum/Instruction.cpp | 106 +++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/libethereum/Instruction.cpp b/libethereum/Instruction.cpp index 41cbf7fe2..bf8d02f4e 100644 --- a/libethereum/Instruction.cpp +++ b/libethereum/Instruction.cpp @@ -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 codes; + vector> 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 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 codes; + vector> 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 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);