]> git.tdb.fi Git - builder.git/blobdiff - source/booleanevaluator.cpp
Refactor transitive dependencies to work on all targets
[builder.git] / source / booleanevaluator.cpp
diff --git a/source/booleanevaluator.cpp b/source/booleanevaluator.cpp
deleted file mode 100644 (file)
index 074956a..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-#include <stdexcept>
-#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 Function &f, bool allow_compare):
-       func(f),
-       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 = (func(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 func(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)<until)
-                       return;
-
-               op_stack.pop_back();
-               bool value1 = pop_value();
-               if(is_unary(op))
-               {
-                       if(op=='!')
-                               value1 = !value1;
-               }
-               else
-               {
-                       bool value2 = pop_value();
-                       if(op=='&')
-                               value1 = (value1 && value2);
-                       else if(op=='|')
-                               value1 = (value1 || value2);
-               }
-               value_stack.push_back(value1);
-       }
-}
-
-unsigned BooleanEvaluator::precedence(char op)
-{
-       if(op=='&')
-               return 1;
-       else if(op=='=' || op=='^')
-               return 2;
-       else if(op=='!')
-               return 3;
-       else
-               return 0;
-}
-
-bool BooleanEvaluator::is_unary(char op)
-{
-       return op=='!';
-}
-
-bool BooleanEvaluator::is_logic(char op)
-{
-       return (op=='&' || op=='|' || op=='!');
-}