X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fbooleanevaluator.cpp;h=ecb38fb0d07657e4ed9a1a3e574289e08bccee5b;hb=HEAD;hp=01037415d2bf36ee9d012f59840e5463151b1cf9;hpb=7c2db9e2b91da953701be233336c5bfa1f3c4af0;p=builder.git diff --git a/source/booleanevaluator.cpp b/source/booleanevaluator.cpp deleted file mode 100644 index 0103741..0000000 --- a/source/booleanevaluator.cpp +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include "booleanevaluator.h" - -using namespace std; - -/* I'd rather have overloads with different slots, but that creates an -ambiguity because slots have template constructors. */ -BooleanEvaluator::BooleanEvaluator(const Slot &s, bool allow_compare): - slot(s), - ops(allow_compare ? "&|!=^" : "&|!") -{ } - -bool BooleanEvaluator::evaluate(const string &str) -{ - string buf; - last_was_op = true; - for(auto i=str.begin();; ++i) - { - if(i!=str.end() && (isalnum(*i) || (!buf.empty() && (*i=='_' || *i=='-')))) - buf += *i; - else - { - if(!buf.empty()) - { - if(!last_was_op) - throw runtime_error("syntax error at "+buf); - - char op = (op_stack.empty() ? 0 : op_stack.back()); - if(op=='=' || op=='^') - { - op_stack.pop_back(); - string var = var_stack.back(); - var_stack.pop_back(); - bool value = (slot(var, &buf) == (op=='=')); - value_stack.push_back(value); - } - else - var_stack.push_back(buf); - - buf.clear(); - last_was_op = false; - } - - if(i==str.end()) - break; - else if(isspace(*i)) - ; - else if(ops.find(*i)!=string::npos) - push_op(*i); - else - throw runtime_error("syntax error at "+string(1, *i)); - } - } - - collapse(0); - - bool value = pop_value(); - if(!value_stack.empty()) - throw runtime_error("too many values"); - - return value; -} - -void BooleanEvaluator::push_op(char op) -{ - if(last_was_op!=is_unary(op)) - throw runtime_error("syntax error at "+string(1, op)); - // TODO Disallow mixing of ! and =/^ - if(is_logic(op) && !var_stack.empty()) - value_stack.push_back(pop_value()); - - if(!is_unary(op)) - collapse(precedence(op)); - op_stack.push_back(op); - last_was_op = true; -} - -bool BooleanEvaluator::pop_value() -{ - if(!var_stack.empty()) - { - string var = var_stack.back(); - var_stack.pop_back(); - return slot(var, 0); - } - else if(!value_stack.empty()) - { - bool value = value_stack.back(); - value_stack.pop_back(); - return value; - } - - throw runtime_error("value stack underflow"); -} - -void BooleanEvaluator::collapse(unsigned until) -{ - while(!op_stack.empty()) - { - char op = op_stack.back(); - if(precedence(op)