diff options
author | 2020-07-02 21:29:25 +0200 | |
---|---|---|
committer | 2020-07-02 21:29:25 +0200 | |
commit | fb90cac2f2079972d75b3c4637de314a8498ed24 (patch) | |
tree | 4b89b545712e513bcebbfe3c995dc914a104637f /src/lib/netlist/plib/pfunction.cpp | |
parent | fd268c1202b3634c53ab1088026a925fb5134abb (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/lib/netlist/plib/pfunction.cpp')
-rw-r--r-- | src/lib/netlist/plib/pfunction.cpp | 32 |
1 files changed, 29 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)) |