25 #include <QMessageLogger> 
   32 #include "../vmisc/vmath.h" 
   41     :m_iStackPos(0), m_iMaxStackSize(0), m_vRPN(), m_bEnableOptimizer(true)
 
   53     :m_iStackPos(a_ByteCode.m_iStackPos), m_iMaxStackSize(a_ByteCode.m_iMaxStackSize), m_vRPN(a_ByteCode.m_vRPN),
 
   54       m_bEnableOptimizer(true)
 
   67     if (
this != &a_ByteCode)
 
   82     if (
this==&a_ByteCode)
 
  107     tok.
Val.ptr   = a_pVar;
 
  135     tok.
Val.ptr   = 
nullptr;
 
  137     tok.
Val.data2 = a_fVal;
 
  145     qreal &x = 
m_vRPN[sz-2].Val.data2,
 
  146           &y = 
m_vRPN[sz-1].Val.data2;
 
  150             x = 
static_cast<int>(x) && 
static_cast<int>(y);
 
  154             x = 
static_cast<int>(x) || 
static_cast<int>(y);
 
  194         #if defined(MUP_MATH_EXCEPTIONS) 
  213 QT_WARNING_DISABLE_INTEL(1195)
 
  214 QT_WARNING_DISABLE_MSVC(4826)
 
  230     bool bOptimized = 
false;
 
  232     if (m_bEnableOptimizer)
 
  234         int sz = m_vRPN.size();
 
  240         if (sz>=2 && m_vRPN.at(sz-2).Cmd == 
cmVAL && m_vRPN.at(sz-1).Cmd == 
cmVAL)
 
  242             ConstantFolding(a_Oprt);
 
  251                     if (m_vRPN.at(sz-2).Cmd == 
cmVAR && m_vRPN.at(sz-1).Cmd == 
cmVAL) 
 
  253                         if (qFuzzyCompare(m_vRPN.at(sz-1).Val.data2, 2)) 
 
  257                         else if (qFuzzyCompare(m_vRPN.at(sz-1).Val.data2, 3))
 
  261                         else if (qFuzzyCompare(m_vRPN.at(sz-1).Val.data2, 4))
 
  278                     if ( (m_vRPN.at(sz-1).Cmd == 
cmVAR    && m_vRPN.at(sz-2).Cmd == 
cmVAL)    ||
 
  279                          (m_vRPN.at(sz-1).Cmd == 
cmVAL    && m_vRPN.at(sz-2).Cmd == 
cmVAR)    ||
 
  280                          (m_vRPN.at(sz-1).Cmd == 
cmVAL    && m_vRPN.at(sz-2).Cmd == 
cmVARMUL) ||
 
  281                          (m_vRPN.at(sz-1).Cmd == 
cmVARMUL && m_vRPN.at(sz-2).Cmd == 
cmVAL)    ||
 
  282                          (m_vRPN.at(sz-1).Cmd == 
cmVAR    && m_vRPN.at(sz-2).Cmd == 
cmVAR &&
 
  283                           m_vRPN.at(sz-2).Val.ptr == m_vRPN.at(sz-1).Val.ptr) || 
 
  284                          (m_vRPN.at(sz-1).Cmd == 
cmVAR && m_vRPN.at(sz-2).Cmd == 
cmVARMUL 
  285                           && m_vRPN.at(sz-2).Val.ptr == m_vRPN.at(sz-1).Val.ptr) ||
 
  286                          (m_vRPN.at(sz-1).Cmd == 
cmVARMUL && m_vRPN.at(sz-2).Cmd == 
cmVAR &&
 
  287                           m_vRPN.at(sz-2).Val.ptr == m_vRPN.at(sz-1).Val.ptr) ||
 
  289                           m_vRPN.at(sz-2).Val.ptr == m_vRPN.at(sz-1).Val.ptr) )
 
  291                         assert( (m_vRPN.at(sz-2).Val.ptr==
nullptr && m_vRPN.at(sz-1).Val.ptr!=
nullptr) ||
 
  292                         (m_vRPN.at(sz-2).Val.ptr!=
nullptr && m_vRPN.at(sz-1).Val.ptr==
nullptr) ||
 
  293                         (m_vRPN.at(sz-2).Val.ptr == m_vRPN.at(sz-1).Val.ptr) );
 
  296                         m_vRPN[sz-2].Val.ptr = 
reinterpret_cast<qreal*
>( 
 
  297                                 reinterpret_cast<qlonglong
>(m_vRPN.at(sz-2).Val.ptr) |
 
  298                                 reinterpret_cast<qlonglong
>(m_vRPN.at(sz-1).Val.ptr));    
 
  299                         m_vRPN[sz-2].Val.data2 += ((a_Oprt==
cmSUB) ? -1 : 1) * m_vRPN.at(sz-1).Val.data2; 
 
  300                         m_vRPN[sz-2].Val.data  += ((a_Oprt==
cmSUB) ? -1 : 1) * m_vRPN.at(sz-1).Val.data;  
 
  306                     if ( (m_vRPN.at(sz-1).Cmd == 
cmVAR && m_vRPN.at(sz-2).Cmd == 
cmVAL) ||
 
  307                     (m_vRPN.at(sz-1).Cmd == 
cmVAL && m_vRPN.at(sz-2).Cmd == 
cmVAR) )
 
  310                         m_vRPN[sz-2].Val.ptr    = 
reinterpret_cast<qreal*
>(
 
  311                                 reinterpret_cast<qlonglong
>(m_vRPN.at(sz-2).Val.ptr) |
 
  312                                 reinterpret_cast<qlonglong
>(m_vRPN.at(sz-1).Val.ptr));
 
  313                         m_vRPN[sz-2].Val.data   = m_vRPN.at(sz-2).Val.data2 + m_vRPN.at(sz-1).Val.data2;
 
  314                         m_vRPN[sz-2].Val.data2  = 0;
 
  318                     else if ( (m_vRPN.at(sz-1).Cmd == 
cmVAL    && m_vRPN.at(sz-2).Cmd == 
cmVARMUL) ||
 
  319                     (m_vRPN.at(sz-1).Cmd == 
cmVARMUL && m_vRPN.at(sz-2).Cmd == 
cmVAL) )
 
  323                         m_vRPN[sz-2].Val.ptr = 
reinterpret_cast<qreal*
>(
 
  324                                 reinterpret_cast<qlonglong
>(m_vRPN.at(sz-2).Val.ptr) |
 
  325                                 reinterpret_cast<qlonglong
>(m_vRPN.at(sz-1).Val.ptr));
 
  326                         if (m_vRPN.at(sz-1).Cmd == 
cmVAL)
 
  328                             m_vRPN[sz-2].Val.data  *= m_vRPN.at(sz-1).Val.data2;
 
  329                             m_vRPN[sz-2].Val.data2 *= m_vRPN.at(sz-1).Val.data2;
 
  333                             m_vRPN[sz-2].Val.data  = m_vRPN.at(sz-1).Val.data  * m_vRPN.at(sz-2).Val.data2;
 
  334                             m_vRPN[sz-2].Val.data2 = m_vRPN.at(sz-1).Val.data2 * m_vRPN.at(sz-2).Val.data2;
 
  339                     else if (m_vRPN.at(sz-1).Cmd == 
cmVAR && m_vRPN.at(sz-2).Cmd == 
cmVAR &&
 
  340                     m_vRPN.at(sz-1).Val.ptr == m_vRPN.at(sz-2).Val.ptr)
 
  349                     if (m_vRPN.at(sz-1).Cmd == 
cmVAL && m_vRPN.at(sz-2).Cmd == 
cmVARMUL &&
 
  350                             not qFuzzyIsNull(m_vRPN.at(sz-1).Val.data2))
 
  353                         m_vRPN[sz-2].Val.data  /= m_vRPN.at(sz-1).Val.data2;
 
  354                         m_vRPN[sz-2].Val.data2 /= m_vRPN.at(sz-1).Val.data2;
 
  367     if (bOptimized == 
false)
 
  372         m_vRPN.push_back(tok);
 
  404     tok.
Oprt.ptr = a_pVar;
 
  430     tok.
Fun.argc = a_iArgc;
 
  431     tok.
Fun.ptr = a_pFun;
 
  449     tok.
Fun.argc = a_iArgc;
 
  450     tok.
Fun.ptr = a_pFun;
 
  468     tok.
Fun.argc = a_iArgc;
 
  469     tok.
Fun.idx = a_iIdx;
 
  470     tok.
Fun.ptr = a_pFun;
 
  492     for (
int i=0; i<
m_vRPN.size(); ++i)
 
  502                 m_vRPN[idx].Oprt.offset = i - idx;
 
  506                 m_vRPN[idx].Oprt.offset = i - idx;
 
  549     if (
m_vRPN.size() == 
false)
 
  551         qDebug() << 
"No bytecode available\n";
 
  555     qDebug() << 
"Number of RPN tokens:" << 
m_vRPN.size() << 
"\n";
 
  558         qDebug() << i << 
" : \t";
 
  562                 qDebug() << 
"VAL \t" << 
"[" << 
m_vRPN.at(i).Val.data2 << 
"]\n";
 
  565                 qDebug() << 
"VAR \t" << 
"[ADDR: 0x" << QString::number(*
m_vRPN.at(i).Val.ptr, 
'f', 16) << 
"]\n";
 
  568                 qDebug() << 
"VARPOW2 \t" << 
"[ADDR: 0x" << QString::number(*
m_vRPN.at(i).Val.ptr, 
'f', 16) << 
"]\n";
 
  571                 qDebug() << 
"VARPOW3 \t" << 
"[ADDR: 0x" << QString::number(*
m_vRPN.at(i).Val.ptr, 
'f', 16) << 
"]\n";
 
  574                 qDebug() << 
"VARPOW4 \t" << 
"[ADDR: 0x" << QString::number(*
m_vRPN.at(i).Val.ptr, 
'f', 16) << 
"]\n";
 
  577                 qDebug() << 
"VARMUL \t" << 
"[ADDR: 0x" << QString::number(*
m_vRPN.at(i).Val.ptr, 
'f', 16) << 
"]" << 
" * ["  
  578                          << 
m_vRPN.at(i).Val.data << 
"]" << 
" + [" << 
m_vRPN.at(i).Val.data2 << 
"]\n";
 
  581                 qDebug() << 
"CALL\t" << 
"[ARG:" << 
m_vRPN.at(i).Fun.argc << 
"]" << 
"[ADDR: 0x" << 
m_vRPN.at(i).Fun.ptr << 
"]" 
  585                 qDebug() << 
"CALL STRFUNC\t" << 
"[ARG:" << 
m_vRPN.at(i).Fun.argc << 
"]" << 
"[IDX:" << 
m_vRPN.at(i).Fun.idx 
 
  586                          << 
"]" << 
"[ADDR: 0x" << 
m_vRPN.at(i).Fun.ptr << 
"]\n";
 
  628                 qDebug() << 
"IF\t" << 
"[OFFSET:" << 
m_vRPN.at(i).Oprt.offset << 
"]\n";
 
  631                 qDebug() << 
"ELSE\t" << 
"[OFFSET:" << 
m_vRPN.at(i).Oprt.offset << 
"]\n";
 
  634                 qDebug() << 
"ENDIF\n"; 
break;
 
  636                 qDebug() << 
"ASSIGN\t" << 
"[ADDR: 0x" << QString::number(*
m_vRPN.at(i).Oprt.ptr, 
'f', 16) << 
"]\n";
 
  650                 qDebug() << 
"(unknown code: " << 
m_vRPN.at(i).Cmd << 
")\n";
 
Bytecode implementation of the Math Parser.
 
void AddIfElse(ECmdCode a_Oprt)
 
void ConstantFolding(ECmdCode a_Oprt)
 
void Finalize()
Add end marker to bytecode.
 
void AddFun(generic_fun_type a_pFun, int a_iArgc)
Add function to bytecode.
 
const SToken * GetBase() const
 
void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx)
Add Strung function entry to the parser bytecode.
 
void AddVal(qreal a_fVal)
Add a Variable pointer to bytecode.
 
unsigned m_iMaxStackSize
Maximum size needed for the stack.
 
QmuParserByteCode()
Bytecode default constructor.
 
unsigned m_iStackPos
Position in the Calculation array.
 
rpn_type m_vRPN
The actual rpn storage.
 
void AddVar(qreal *a_pVar)
Add a Variable pointer to bytecode.
 
void clear()
Delete the bytecode.
 
void Assign(const QmuParserByteCode &a_ByteCode)
Copy state of another object to this.
 
void AddBulkFun(generic_fun_type a_pFun, int a_iArgc)
Add a bulk function to bytecode.
 
void AsciiDump()
Dump bytecode (for debugging only!).
 
QVector< SToken > rpn_type
Token vector for storing the RPN.
 
QmuParserByteCode & operator=(const QmuParserByteCode &a_ByteCode)
Assignment operator.
 
void AddAssignOp(qreal *a_pVar)
Add an assignement operator.
 
Error class of the parser.
 
Namespace for mathematical applications.
 
@ ecINTERNAL_ERROR
Internal error of any kind.
 
@ ecDIV_BY_ZERO
Division by zero (currently unused)
 
@ cmOPRT_INFIX
code for infix operators
 
@ cmBC
Operator item: closing bracket.
 
@ cmLE
Operator item: less or equal.
 
@ cmUNKNOWN
uninitialized item
 
@ cmSUB
Operator item: subtract.
 
@ cmGT
Operator item: greater than.
 
@ cmSTRING
Code for a string token.
 
@ cmFUNC
Code for a generic function item.
 
@ cmFUNC_STR
Code for a function with a string parameter.
 
@ cmLT
Operator item: less than.
 
@ cmMUL
Operator item: multiply.
 
@ cmGE
Operator item: greater or equal.
 
@ cmADD
Operator item: add.
 
@ cmASSIGN
Operator item: Assignment operator.
 
@ cmENDIF
For use in the ternary if-then-else operator.
 
@ cmELSE
For use in the ternary if-then-else operator.
 
@ cmEQ
Operator item: equals.
 
@ cmFUNC_BULK
Special callbacks for Bulk mode with an additional parameter for the bulk index.
 
@ cmARG_SEP
function argument separator
 
@ cmPOW
Operator item: y to the power of ...
 
@ cmNEQ
Operator item: not equal.
 
@ cmOPRT_BIN
user defined binary operator
 
@ cmIF
For use in the ternary if-then-else operator.
 
@ cmOPRT_POSTFIX
code for postfix operators
 
@ cmDIV
Operator item: division.
 
@ cmBO
Operator item: opening bracket.
 
qreal(* generic_fun_type)()
Callback type used for functions without arguments.
 
QT_WARNING_POP static Q_REQUIRED_RESULT bool QmuFuzzyComparePossibleNulls(double p1, double p2)
 
Definition of the parser bytecode class.
 
This file defines the error class used by the parser.
 
struct qmu::SToken::@3::@6 Fun
 
struct qmu::SToken::@3::@5 Val
 
struct qmu::SToken::@3::@7 Oprt