OmniaFramework/src/ostd/Logic.cpp

100 lines
2.3 KiB
C++
Executable file

#include "Logic.hpp"
#include "Utils.hpp"
#include "String.hpp"
#include <bits/stdc++.h>
namespace ostd
{
bool LogicEvaluator::eval(String exp)
{
String se(exp);
se = se.replaceAll("true", "1");
se = se.replaceAll("false", "0");
se = se.replaceAll("and", "&");
se = se.replaceAll("or", "+");
se = se.replaceAll("xor", "^");
se = se.replaceAll("nand", "%");
se = se.replaceAll("nor", "*");
se = se.replaceAll("xnor", ">");
se = se.replaceAll("not", "!");
se = se.replaceAll(" ", "");
se = se.replaceAll("!1", "0");
se = se.replaceAll("!0", "1");
se = se.trim();
exp = se;
std::stack<bool> values;
std::stack<eLogicOp> ops;
char c = 0;
for (unsigned int i = 0; i < exp.len(); i++)
{
c = exp[i];
if (c == ' ' || c == '#') continue;
else if (c == '1' || c == '0') values.push(c == '1');
else if (c == ')')
{
while(!ops.empty() && ops.top() != eLogicOp::O_PARENTH)
{
bool val2 = values.top();
values.pop();
bool val1 = values.top();
values.pop();
eLogicOp op = ops.top();
ops.pop();
values.push(applyOp(val1, val2, op));
}
if(!ops.empty()) ops.pop();
if (!ops.empty())
{
if (ops.top() == eLogicOp::NOT)
{
ops.pop();
bool tmp = values.top();
values.pop();
values.push(!tmp);
}
}
}
else ops.push(parseOp(c));
}
while(!ops.empty())
{
bool val2 = values.top();
values.pop();
bool val1 = values.top();
values.pop();
eLogicOp op = ops.top();
ops.pop();
values.push(applyOp(val1, val2, op));
}
return values.top();
}
bool LogicEvaluator::applyOp(bool a, bool b, eLogicOp op)
{
switch(op)
{
case eLogicOp::AND: return (a && b);
case eLogicOp::OR: return (a || b);
case eLogicOp::NAND: return !(a && b);
case eLogicOp::NOR: return !(a || b);
case eLogicOp::XOR: return (a != b);
case eLogicOp::XNOR: return !(a != b);
default: return false;
}
}
eLogicOp LogicEvaluator::parseOp(char op)
{
if (op == '&') return eLogicOp::AND;
if (op == '+') return eLogicOp::OR;
if (op == '^') return eLogicOp::XOR;
if (op == '%') return eLogicOp::NAND;
if (op == '*') return eLogicOp::NOR;
if (op == '>') return eLogicOp::XNOR;
if (op == '!') return eLogicOp::NOT;
if (op == '(') return eLogicOp::O_PARENTH;
if (op == ')') return eLogicOp::C_PARENTH;
return eLogicOp::NONE;
}
}