netlist: Add comparison operators to pfunction.

Comparison operators evaluate either into 0.0 or 1.0. Thus they can be
used like "(a==1)*(b==2)" which will only result in 1.0 if a equal 1 and
b equal 1. From the yet to be released test code:

* PFUNCEXPECT("1==1", 1.0)
* PFUNCEXPECT("1 *0 == 2-1-1", 1.0)
* PFUNCEXPECT("0!=1", 1.0)
* PFUNCEXPECT("0<1",  1.0)
* PFUNCEXPECT("1>0",  1.0)
* PFUNCEXPECT("0<=1", 1.0)
* PFUNCEXPECT("1>=0", 1.0)
* PFUNCEXPECT("1<=1", 1.0)
* PFUNCEXPECT("1>=1", 1.0)
* PFUNCEXPECT("if(1>0, 2, 0)", 2.0)
* PFUNCEXPECT("if(0>1, 2, 3)", 3.0)
* PFUNCEXPECT("if(sin(1)>0, 2, 3)", 3.0) // fail
This commit is contained in:
couriersud 2020-07-02 21:29:25 +02:00
parent fd268c1202
commit fb90cac2f2
2 changed files with 36 additions and 3 deletions

View File

@ -84,6 +84,20 @@ namespace plib {
{ rc.m_cmd = MULT; stk -= 1; }
else if (cmd == "/")
{ rc.m_cmd = DIV; stk -= 1; }
else if (cmd == "==")
{ rc.m_cmd = EQ; stk -= 1; }
else if (cmd == "!=")
{ rc.m_cmd = NE; stk -= 1; }
else if (cmd == "<")
{ rc.m_cmd = LT; stk -= 1; }
else if (cmd == ">")
{ rc.m_cmd = GT; stk -= 1; }
else if (cmd == "<=")
{ rc.m_cmd = LE; stk -= 1; }
else if (cmd == ">=")
{ rc.m_cmd = GE; stk -= 1; }
else if (cmd == "if")
{ rc.m_cmd = IF; stk -= 2; }
else if (cmd == "pow")
{ rc.m_cmd = POW; stk -= 1; }
else if (cmd == "sin")
@ -142,12 +156,16 @@ namespace plib {
return 1;
if (plib::left(v, 1) >= "a" && plib::left(v, 1) <= "z")
return 0;
if (v == "^")
return 30;
if (v == "*" || v == "/")
return 20;
if (v == "+" || v == "-")
return 10;
if (v == "^")
return 30;
if (v == "<" || v == ">" || v == "<=" || v == ">=")
return 9;
if (v == "==" || v == "!=")
return 8;
return -1;
}
@ -165,7 +183,7 @@ namespace plib {
void pfunction<NT>::compile_infix(const pstring &expr, const inputs_container &inputs)
{
// Shunting-yard infix parsing
std::vector<pstring> sep = {"(", ")", ",", "*", "/", "+", "-", "^"};
std::vector<pstring> sep = {"(", ")", ",", "*", "/", "+", "-", "^", "<=", ">=", "==", "!=", "<", ">"};
std::vector<pstring> sexpr1(plib::psplit(plib::replace_all(expr, " ", ""), sep));
std::stack<pstring> opstk;
std::vector<pstring> postfix;
@ -302,6 +320,7 @@ namespace plib {
#define ST1 stack[ptr]
#define ST2 stack[ptr-1]
#define ST3 stack[ptr-2]
#define OP(OP, ADJ, EXPR) \
case OP: \
@ -323,6 +342,13 @@ namespace plib {
OP(MULT, 1, ST2 * ST1)
OP(SUB, 1, ST2 - ST1)
OP(DIV, 1, ST2 / ST1)
OP(EQ, 1, ST2 == ST1 ? 1.0 : 0.0)
OP(NE, 1, ST2 != ST1 ? 1.0 : 0.0)
OP(GT, 1, ST2 > ST1 ? 1.0 : 0.0)
OP(LT, 1, ST2 < ST1 ? 1.0 : 0.0)
OP(LE, 1, ST2 <= ST1 ? 1.0 : 0.0)
OP(GE, 1, ST2 >= ST1 ? 1.0 : 0.0)
OP(IF, 1, (ST3 != 0.0) ? ST2 : ST1)
OP(POW, 1, plib::pow(ST2, ST1))
OP(SIN, 0, plib::sin(ST2))
OP(COS, 0, plib::cos(ST2))

View File

@ -32,6 +32,13 @@ namespace plib {
MULT,
SUB,
DIV,
EQ,
NE,
LT,
GT,
LE,
GE,
IF,
POW,
SIN,
COS,