 +
 diff -ruN muparser-v2_2_3/CMakeLists.txt muparser-v2_2_3-new/CMakeLists.txt
 --- muparser-v2_2_3/CMakeLists.txt	1969-12-31 17:00:00.000000000 -0700
-+++ muparser-v2_2_3-new/CMakeLists.txt	2014-11-08 06:54:43.305092500 -0700
++++ muparser-v2_2_3-new/CMakeLists.txt	2015-01-20 19:18:46.184611500 -0700
 @@ -0,0 +1,77 @@
 +###################################################
 +#

diff -ruN muparser-v2_2_3/build/makefile.vc muparser-v2_2_3-new/build/makefile.vc
--- muparser-v2_2_3/build/makefile.vc	2011-11-19 23:49:50.000000000 -0700
+++ muparser-v2_2_3-new/build/makefile.vc	2014-11-08 06:56:11.428331100 -0700
@@ -1,322 +1,322 @@
-# =========================================================================
-#     This makefile was generated by

+
+# Install library
+install(TARGETS muparser DESTINATION lib)
diff -ruN muparser-v2_2_3/src/muParserBytecode.cpp muparser-v2_2_3-new/src/muParserBytecode.cpp
--- muparser-v2_2_3/src/muParserBytecode.cpp	2012-12-22 12:47:26.000000000 -0700
+++ muparser-v2_2_3-new/src/muParserBytecode.cpp	2015-01-20 19:19:31.705703300 -0700
@@ -37,6 +37,9 @@
 #include "muParserStack.h"
 #include "muParserTemplateMagic.h"
 
+#if (_MSC_VER >= 1800)
+#include <algorithm>
+#endif
 
 namespace mu
 {
diff -ruN muparser-v2_2_3/src/muParserBytecode.cpp~ muparser-v2_2_3-new/src/muParserBytecode.cpp~
--- muparser-v2_2_3/src/muParserBytecode.cpp~	1969-12-31 17:00:00.000000000 -0700
+++ muparser-v2_2_3-new/src/muParserBytecode.cpp~	2015-01-20 19:16:34.971170300 -0700
@@ -0,0 +1,586 @@
+/*
+                 __________                                      
+    _____   __ __\______   \_____  _______  ______  ____ _______ 
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   
+        \/                       \/            \/      \/        
+  Copyright (C) 2011 Ingo Berg
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this 
+  software and associated documentation files (the "Software"), to deal in the Software
+  without restriction, including without limitation the rights to use, copy, modify, 
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in all copies or 
+  substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
+*/
+
+#include "muParserBytecode.h"
+
+#include <cassert>
+#include <string>
+#include <stack>
+#include <vector>
+#include <iostream>
+
+#include "muParserDef.h"
+#include "muParserError.h"
+#include "muParserToken.h"
+#include "muParserStack.h"
+#include "muParserTemplateMagic.h"
+
+
+namespace mu
+{
+  //---------------------------------------------------------------------------
+  /** \brief Bytecode default constructor. */
+  ParserByteCode::ParserByteCode()
+    :m_iStackPos(0)
+    ,m_iMaxStackSize(0)
+    ,m_vRPN()
+    ,m_bEnableOptimizer(true)
+  {
+    m_vRPN.reserve(50);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Copy constructor. 
+    
+      Implemented in Terms of Assign(const ParserByteCode &a_ByteCode)
+  */
+  ParserByteCode::ParserByteCode(const ParserByteCode &a_ByteCode)
+  {
+    Assign(a_ByteCode);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Assignment operator.
+    
+      Implemented in Terms of Assign(const ParserByteCode &a_ByteCode)
+  */
+  ParserByteCode& ParserByteCode::operator=(const ParserByteCode &a_ByteCode)
+  {
+    Assign(a_ByteCode);
+    return *this;
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserByteCode::EnableOptimizer(bool bStat)
+  {
+    m_bEnableOptimizer = bStat;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Copy state of another object to this. 
+    
+      \throw nowthrow
+  */
+  void ParserByteCode::Assign(const ParserByteCode &a_ByteCode)
+  {
+    if (this==&a_ByteCode)    
+      return;
+
+    m_iStackPos = a_ByteCode.m_iStackPos;
+    m_vRPN = a_ByteCode.m_vRPN;
+    m_iMaxStackSize = a_ByteCode.m_iMaxStackSize;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a Variable pointer to bytecode. 
+      \param a_pVar Pointer to be added.
+      \throw nothrow
+  */
+  void ParserByteCode::AddVar(value_type *a_pVar)
+  {
+    ++m_iStackPos;
+    m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
+
+    // optimization does not apply
+    SToken tok;
+    tok.Cmd       = cmVAR;
+    tok.Val.ptr   = a_pVar;
+    tok.Val.data  = 1;
+    tok.Val.data2 = 0;
+    m_vRPN.push_back(tok);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a Variable pointer to bytecode. 
+
+      Value entries in byte code consist of:
+      <ul>
+        <li>value array position of the value</li>
+        <li>the operator code according to ParserToken::cmVAL</li>
+        <li>the value stored in #mc_iSizeVal number of bytecode entries.</li>
+      </ul>
+
+      \param a_pVal Value to be added.
+      \throw nothrow
+  */
+  void ParserByteCode::AddVal(value_type a_fVal)
+  {
+    ++m_iStackPos;
+    m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
+
+    // If optimization does not apply
+    SToken tok;
+    tok.Cmd = cmVAL;
+    tok.Val.ptr   = NULL;
+    tok.Val.data  = 0;
+    tok.Val.data2 = a_fVal;
+    m_vRPN.push_back(tok);
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserByteCode::ConstantFolding(ECmdCode a_Oprt)
+  {
+    std::size_t sz = m_vRPN.size();
+    value_type &x = m_vRPN[sz-2].Val.data2,
+               &y = m_vRPN[sz-1].Val.data2;
+    switch (a_Oprt)
+    {
+    case cmLAND: x = (int)x && (int)y; m_vRPN.pop_back(); break;
+    case cmLOR:  x = (int)x || (int)y; m_vRPN.pop_back(); break;
+    case cmLT:   x = x < y;  m_vRPN.pop_back();  break;
+    case cmGT:   x = x > y;  m_vRPN.pop_back();  break;
+    case cmLE:   x = x <= y; m_vRPN.pop_back();  break;
+    case cmGE:   x = x >= y; m_vRPN.pop_back();  break;
+    case cmNEQ:  x = x != y; m_vRPN.pop_back();  break;
+    case cmEQ:   x = x == y; m_vRPN.pop_back();  break;
+    case cmADD:  x = x + y;  m_vRPN.pop_back();  break;
+    case cmSUB:  x = x - y;  m_vRPN.pop_back();  break;
+    case cmMUL:  x = x * y;  m_vRPN.pop_back();  break;
+    case cmDIV: 
+
+#if defined(MUP_MATH_EXCEPTIONS)
+        if (y==0)
+          throw ParserError(ecDIV_BY_ZERO, _T("0"));
+#endif
+
+        x = x / y;   
+        m_vRPN.pop_back();
+        break;
+
+    case cmPOW: x = MathImpl<value_type>::Pow(x, y); 
+                m_vRPN.pop_back();
+                break;
+
+    default:
+        break;
+    } // switch opcode
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add an operator identifier to bytecode. 
+    
+      Operator entries in byte code consist of:
+      <ul>
+        <li>value array position of the result</li>
+        <li>the operator code according to ParserToken::ECmdCode</li>
+      </ul>
+
+      \sa  ParserToken::ECmdCode
+  */
+  void ParserByteCode::AddOp(ECmdCode a_Oprt)
+  {
+    bool bOptimized = false;
+
+    if (m_bEnableOptimizer)
+    {
+      std::size_t sz = m_vRPN.size();
+
+      // Check for foldable constants like:
+      //   cmVAL cmVAL cmADD 
+      // where cmADD can stand fopr any binary operator applied to
+      // two constant values.
+      if (sz>=2 && m_vRPN[sz-2].Cmd == cmVAL && m_vRPN[sz-1].Cmd == cmVAL)
+      {
+        ConstantFolding(a_Oprt);
+        bOptimized = true;
+      }
+      else
+      {
+        switch(a_Oprt)
+        {
+        case  cmPOW:
+              // Optimization for ploynomials of low order
+              if (m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-1].Cmd == cmVAL)
+              {
+                if (m_vRPN[sz-1].Val.data2==2)
+                  m_vRPN[sz-2].Cmd = cmVARPOW2;
+                else if (m_vRPN[sz-1].Val.data2==3)
+                  m_vRPN[sz-2].Cmd = cmVARPOW3;
+                else if (m_vRPN[sz-1].Val.data2==4)
+                  m_vRPN[sz-2].Cmd = cmVARPOW4;
+                else
+                  break;
+
+                m_vRPN.pop_back();
+                bOptimized = true;
+              }
+              break;
+
+        case  cmSUB:
+        case  cmADD:
+              // Simple optimization based on pattern recognition for a shitload of different
+              // bytecode combinations of addition/subtraction
+              if ( (m_vRPN[sz-1].Cmd == cmVAR    && m_vRPN[sz-2].Cmd == cmVAL)    ||
+                   (m_vRPN[sz-1].Cmd == cmVAL    && m_vRPN[sz-2].Cmd == cmVAR)    || 
+                   (m_vRPN[sz-1].Cmd == cmVAL    && m_vRPN[sz-2].Cmd == cmVARMUL) ||
+                   (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL)    ||
+                   (m_vRPN[sz-1].Cmd == cmVAR    && m_vRPN[sz-2].Cmd == cmVAR    && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||
+                   (m_vRPN[sz-1].Cmd == cmVAR    && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||
+                   (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAR    && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||
+                   (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) )
+              {
+                assert( (m_vRPN[sz-2].Val.ptr==NULL && m_vRPN[sz-1].Val.ptr!=NULL) ||
+                        (m_vRPN[sz-2].Val.ptr!=NULL && m_vRPN[sz-1].Val.ptr==NULL) || 
+                        (m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) );
+
+                m_vRPN[sz-2].Cmd = cmVARMUL;
+                m_vRPN[sz-2].Val.ptr    = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr));    // variable
+                m_vRPN[sz-2].Val.data2 += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data2;  // offset
+                m_vRPN[sz-2].Val.data  += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data;   // multiplikatior
+                m_vRPN.pop_back();
+                bOptimized = true;
+              } 
+              break;
+
+        case  cmMUL:
+              if ( (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAL) ||
+                   (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) ) 
+              {
+                m_vRPN[sz-2].Cmd        = cmVARMUL;
+                m_vRPN[sz-2].Val.ptr    = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr));
+                m_vRPN[sz-2].Val.data   = m_vRPN[sz-2].Val.data2 + m_vRPN[sz-1].Val.data2;
+                m_vRPN[sz-2].Val.data2  = 0;
+                m_vRPN.pop_back();
+                bOptimized = true;
+              } 
+              else if ( (m_vRPN[sz-1].Cmd == cmVAL    && m_vRPN[sz-2].Cmd == cmVARMUL) ||
+                        (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL) )
+              {
+                // Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2
+                m_vRPN[sz-2].Cmd     = cmVARMUL;
+                m_vRPN[sz-2].Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr));
+                if (m_vRPN[sz-1].Cmd == cmVAL)
+                {
+                  m_vRPN[sz-2].Val.data  *= m_vRPN[sz-1].Val.data2;
+                  m_vRPN[sz-2].Val.data2 *= m_vRPN[sz-1].Val.data2;
+                }
+                else
+                {
+                  m_vRPN[sz-2].Val.data  = m_vRPN[sz-1].Val.data  * m_vRPN[sz-2].Val.data2;
+                  m_vRPN[sz-2].Val.data2 = m_vRPN[sz-1].Val.data2 * m_vRPN[sz-2].Val.data2;
+                }
+                m_vRPN.pop_back();
+                bOptimized = true;
+              }
+              else if (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR &&
+                       m_vRPN[sz-1].Val.ptr == m_vRPN[sz-2].Val.ptr)
+              {
+                // Optimization: a*a -> a^2
+                m_vRPN[sz-2].Cmd = cmVARPOW2;
+                m_vRPN.pop_back();
+                bOptimized = true;
+              }
+              break;
+
+        case cmDIV:
+              if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-1].Val.data2!=0)
+              {
+                // Optimization: 4*a/2 -> 2*a
+                m_vRPN[sz-2].Val.data  /= m_vRPN[sz-1].Val.data2;
+                m_vRPN[sz-2].Val.data2 /= m_vRPN[sz-1].Val.data2;
+                m_vRPN.pop_back();
+                bOptimized = true;
+              }
+              break;
+              
+        } // switch a_Oprt
+      }
+    }
+
+    // If optimization can't be applied just write the value
+    if (!bOptimized)
+    {
+      --m_iStackPos;
+      SToken tok;
+      tok.Cmd = a_Oprt;
+      m_vRPN.push_back(tok);
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  void ParserByteCode::AddIfElse(ECmdCode a_Oprt)
+  {
+    SToken tok;
+    tok.Cmd = a_Oprt;
+    m_vRPN.push_back(tok);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add an assignement operator
+    
+      Operator entries in byte code consist of:
+      <ul>
+        <li>cmASSIGN code</li>
+        <li>the pointer of the destination variable</li>
+      </ul>
+
+      \sa  ParserToken::ECmdCode
+  */
+  void ParserByteCode::AddAssignOp(value_type *a_pVar)
+  {
+    --m_iStackPos;
+
+    SToken tok;
+    tok.Cmd = cmASSIGN;
+    tok.Val.ptr = a_pVar;
+    m_vRPN.push_back(tok);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add function to bytecode. 
+
+      \param a_iArgc Number of arguments, negative numbers indicate multiarg functions.
+      \param a_pFun Pointer to function callback.
+  */
+  void ParserByteCode::AddFun(generic_fun_type a_pFun, int a_iArgc)
+  {
+    if (a_iArgc>=0)
+    {
+      m_iStackPos = m_iStackPos - a_iArgc + 1; 
+    }
+    else
+    {
+      // function with unlimited number of arguments
+      m_iStackPos = m_iStackPos + a_iArgc + 1; 
+    }
+    m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
+
+    SToken tok;
+    tok.Cmd = cmFUNC;
+    tok.Fun.argc = a_iArgc;
+    tok.Fun.ptr = a_pFun;
+    m_vRPN.push_back(tok);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add a bulk function to bytecode. 
+
+      \param a_iArgc Number of arguments, negative numbers indicate multiarg functions.
+      \param a_pFun Pointer to function callback.
+  */
+  void ParserByteCode::AddBulkFun(generic_fun_type a_pFun, int a_iArgc)
+  {
+    m_iStackPos = m_iStackPos - a_iArgc + 1; 
+    m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
+
+    SToken tok;
+    tok.Cmd = cmFUNC_BULK;
+    tok.Fun.argc = a_iArgc;
+    tok.Fun.ptr = a_pFun;
+    m_vRPN.push_back(tok);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add Strung function entry to the parser bytecode. 
+      \throw nothrow
+
+      A string function entry consists of the stack position of the return value,
+      followed by a cmSTRFUNC code, the function pointer and an index into the 
+      string buffer maintained by the parser.
+  */
+  void ParserByteCode::AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx)
+  {
+    m_iStackPos = m_iStackPos - a_iArgc + 1;
+
+    SToken tok;
+    tok.Cmd = cmFUNC_STR;
+    tok.Fun.argc = a_iArgc;
+    tok.Fun.idx = a_iIdx;
+    tok.Fun.ptr = a_pFun;
+    m_vRPN.push_back(tok);
+
+    m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Add end marker to bytecode.
+      
+      \throw nothrow 
+  */
+  void ParserByteCode::Finalize()
+  {
+    SToken tok;
+    tok.Cmd = cmEND;
+    m_vRPN.push_back(tok);
+    rpn_type(m_vRPN).swap(m_vRPN);     // shrink bytecode vector to fit
+
+    // Determine the if-then-else jump offsets
+    ParserStack<int> stIf, stElse;
+    int idx;
+    for (int i=0; i<(int)m_vRPN.size(); ++i)
+    {
+      switch(m_vRPN[i].Cmd)
+      {
+      case cmIF:
+            stIf.push(i);
+            break;
+
+      case  cmELSE:
+            stElse.push(i);
+            idx = stIf.pop();
+            m_vRPN[idx].Oprt.offset = i - idx;
+            break;
+      
+      case cmENDIF:
+            idx = stElse.pop();
+            m_vRPN[idx].Oprt.offset = i - idx;
+            break;
+
+      default:
+            break;
+      }
+    }
+  }
+
+  //---------------------------------------------------------------------------
+  const SToken* ParserByteCode::GetBase() const
+  {
+    if (m_vRPN.size()==0)
+      throw ParserError(ecINTERNAL_ERROR);
+    else
+      return &m_vRPN[0];
+  }
+
+  //---------------------------------------------------------------------------
+  std::size_t ParserByteCode::GetMaxStackSize() const
+  {
+    return m_iMaxStackSize+1;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Returns the number of entries in the bytecode. */
+  std::size_t ParserByteCode::GetSize() const
+  {
+    return m_vRPN.size();
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Delete the bytecode. 
+  
+      \throw nothrow
+
+      The name of this function is a violation of my own coding guidelines
+      but this way it's more in line with the STL functions thus more 
+      intuitive.
+  */
+  void ParserByteCode::clear()
+  {
+    m_vRPN.clear();
+    m_iStackPos = 0;
+    m_iMaxStackSize = 0;
+  }
+
+  //---------------------------------------------------------------------------
+  /** \brief Dump bytecode (for debugging only!). */
+  void ParserByteCode::AsciiDump()
+  {
+    if (!m_vRPN.size()) 
+    {
+      mu::console() << _T("No bytecode available\n");
+      return;
+    }
+
+    mu::console() << _T("Number of RPN tokens:") << (int)m_vRPN.size() << _T("\n");
+    for (std::size_t i=0; i<m_vRPN.size() && m_vRPN[i].Cmd!=cmEND; ++i)
+    {
+      mu::console() << std::dec << i << _T(" : \t");
+      switch (m_vRPN[i].Cmd)
+      {
+      case cmVAL:   mu::console() << _T("VAL \t");
+                    mu::console() << _T("[") << m_vRPN[i].Val.data2 << _T("]\n");
+                    break;
+
+      case cmVAR:   mu::console() << _T("VAR \t");
+	                  mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); 
+                    break;
+
+      case cmVARPOW2: mu::console() << _T("VARPOW2 \t");
+	                    mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); 
+                      break;
+
+      case cmVARPOW3: mu::console() << _T("VARPOW3 \t");
+	                    mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); 
+                      break;
+
+      case cmVARPOW4: mu::console() << _T("VARPOW4 \t");
+	                    mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); 
+                      break;
+
+      case cmVARMUL:  mu::console() << _T("VARMUL \t");
+	                    mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]"); 
+                      mu::console() << _T(" * [") << m_vRPN[i].Val.data << _T("]");
+                      mu::console() << _T(" + [") << m_vRPN[i].Val.data2 << _T("]\n");
+                      break;
+
+      case cmFUNC:  mu::console() << _T("CALL\t");
+                    mu::console() << _T("[ARG:") << std::dec << m_vRPN[i].Fun.argc << _T("]"); 
+                    mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Fun.ptr << _T("]"); 
+                    mu::console() << _T("\n");
+                    break;
+
+      case cmFUNC_STR:
+                    mu::console() << _T("CALL STRFUNC\t");
+                    mu::console() << _T("[ARG:") << std::dec << m_vRPN[i].Fun.argc << _T("]");
+                    mu::console() << _T("[IDX:") << std::dec << m_vRPN[i].Fun.idx << _T("]");
+                    mu::console() << _T("[ADDR: 0x") << m_vRPN[i].Fun.ptr << _T("]\n"); 
+                    break;
+
+      case cmLT:    mu::console() << _T("LT\n");  break;
+      case cmGT:    mu::console() << _T("GT\n");  break;
+      case cmLE:    mu::console() << _T("LE\n");  break;
+      case cmGE:    mu::console() << _T("GE\n");  break;
+      case cmEQ:    mu::console() << _T("EQ\n");  break;
+      case cmNEQ:   mu::console() << _T("NEQ\n"); break;
+      case cmADD:   mu::console() << _T("ADD\n"); break;
+      case cmLAND:  mu::console() << _T("&&\n"); break;
+      case cmLOR:   mu::console() << _T("||\n"); break;
+      case cmSUB:   mu::console() << _T("SUB\n"); break;
+      case cmMUL:   mu::console() << _T("MUL\n"); break;
+      case cmDIV:   mu::console() << _T("DIV\n"); break;
+      case cmPOW:   mu::console() << _T("POW\n"); break;
+
+      case cmIF:    mu::console() << _T("IF\t");
+                    mu::console() << _T("[OFFSET:") << std::dec << m_vRPN[i].Oprt.offset << _T("]\n");
+                    break;
+
+      case cmELSE:  mu::console() << _T("ELSE\t");
+                    mu::console() << _T("[OFFSET:") << std::dec << m_vRPN[i].Oprt.offset << _T("]\n");
+                    break;
+
+      case cmENDIF: mu::console() << _T("ENDIF\n"); break;
+
+      case cmASSIGN: 
+                    mu::console() << _T("ASSIGN\t");
+                    mu::console() << _T("[ADDR: 0x") << m_vRPN[i].Oprt.ptr << _T("]\n"); 
+                    break; 
+
+      default:      mu::console() << _T("(unknown code: ") << m_vRPN[i].Cmd << _T(")\n"); 
+                    break;
+      } // switch cmdCode
+    } // while bytecode
+
+    mu::console() << _T("END") << std::endl;
+  }
+} // namespace mu
