summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2020-07-02 21:29:25 +0200
committer couriersud <couriersud@gmx.org>2020-07-02 21:29:25 +0200
commitfb90cac2f2079972d75b3c4637de314a8498ed24 (patch)
tree4b89b545712e513bcebbfe3c995dc914a104637f /src
parentfd268c1202b3634c53ab1088026a925fb5134abb (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/lib/netlist/plib/pfunction.cpp32
-rw-r--r--src/lib/netlist/plib/pfunction.h7
2 files changed, 36 insertions, 3 deletions
diff --git a/src/lib/netlist/plib/pfunction.cpp b/src/lib/netlist/plib/pfunction.cpp
index 3a360c7a33f..bc8f50434e2 100644
--- a/src/lib/netlist/plib/pfunction.cpp
+++ b/src/lib/netlist/plib/pfunction.cpp
@@ -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))
diff --git a/src/lib/netlist/plib/pfunction.h b/src/lib/netlist/plib/pfunction.h
index e0b81a25e00..fe5a5dd1dc6 100644
--- a/src/lib/netlist/plib/pfunction.h
+++ b/src/lib/netlist/plib/pfunction.h
@@ -32,6 +32,13 @@ namespace plib {
MULT,
SUB,
DIV,
+ EQ,
+ NE,
+ LT,
+ GT,
+ LE,
+ GE,
+ IF,
POW,
SIN,
COS,