/** \brief Calls a parser function with its corresponding arguments.
      \param a_stOpt The operator stack
      \param a_stVal The value stack
      \param a_iArgCount The number of function arguments
  */
void ParserXBase::ApplyFunc(Stack<ptr_tok_type> &a_stOpt,
                            int a_iArgCount) const
{
    if (a_stOpt.empty())
        return;

    ptr_tok_type tok = a_stOpt.pop();
    ICallback *pFun = tok->AsICallback();

    int iArgCount = (pFun->GetArgc()>=0) ? pFun->GetArgc() : a_iArgCount;
    pFun->SetNumArgsPresent(iArgCount);

    m_nPos -= (iArgCount - 1);
    m_rpn.Add(tok);
}
Beispiel #2
0
// UndoList.cpp : Implementation of CUndoList

#include "stdafx.h"
#include "UndoList.h"
#include "ShapeEditor.h"
#include "TableHelper.h"

int CUndoList::g_UniqueId = -1;
const int CUndoList::EMPTY_BATCH_ID = -1; 

//***********************************************************************/
//*			GetShapefile()
//***********************************************************************/
IShapefile* CUndoList::GetShapefile(long layerHandle)
{
	if (!CheckState()) return NULL;
	return _mapCallback->_GetShapefile(layerHandle);
}

//***********************************************************************/
//*			ErrorMessage()
//***********************************************************************/
void CUndoList::ErrorMessage(long ErrorCode)
{
	if (!CheckState()) return;

	_lastErrorCode = ErrorCode;
	USES_CONVERSION;
	ICallback* cb;
	if (_lastErrorCode != tkNO_ERROR) {
		cb = _mapCallback->_GetGlobalCallback();
		if (cb) {
			CallbackHelper::ErrorMsg("UndoList", cb, _key, ErrorMsg(_lastErrorCode));
			cb->Release();
		}
	}
}
Beispiel #3
0
  //---------------------------------------------------------------------------
  void RPN::Add(ptr_tok_type tok)
  {
    m_vRPN.push_back(tok);
    if (tok->AsIValue()!=NULL)
    {
      m_nStackPos++;
    }
    else if (tok->AsICallback())
    {
      ICallback *pFun = tok->AsICallback();
      MUP_ASSERT(pFun);
      m_nStackPos -= pFun->GetArgsPresent() - 1;
    }

    MUP_ASSERT(m_nStackPos>=0);
    m_nMaxStackPos = std::max(m_nStackPos, m_nMaxStackPos);
  }
Beispiel #4
0
 static void CreateFault(ICallback<const DataObject&>& rCallback, const std::string& sFaultCode,
                         const std::string& sFaultError)
 {
   // generate fault using Operation
   Operation tFault;
   tFault.SetFault(sFaultCode, sFaultError);
   rCallback.OnFault(tFault.GetResponse());
 }
        void SingleThreadedParallelizer::loop(ICallback& callback, int start, int end, int stride) {
            for(int i=start; i<end; i+=stride) {
                int jEnd = std::min(end, i + stride);

                for(int j=i; j<jEnd; ++j) {
                    callback.invoke(j);
                }
            }
        }
//++ ------------------------------------------------------------------------------------
// Details: Iterate all interested clients and tell them a command is being deleted.
// Type:    Method.
// Args:    vCmd    - (RW) The command to be deleted.
// Return:  MIstatus::success - Functional succeeded.
//          MIstatus::failure - Functional failed.
// Throws:  None.
//--
void
CSetClients::Delete(SMICmdData &vCmd)
{
    m_bClientUnregistered = false; // Reset
    iterator it = begin();
    while (it != end())
    {
        ICallback *pObj = *it;
        pObj->Delete(vCmd);

        if (m_bClientUnregistered)
        {
            m_bClientUnregistered = false; // Reset
            it = begin();
        }
        else
            // Next
            ++it;
    }
}
Beispiel #7
0
RESULT
Animation::CallbackOnFinished( ICallback& callback )
{
    RESULT rval = S_OK;
    
    if (callback.IsNull())
    {
        RETAILMSG(ZONE_ERROR, "ERROR: Animation::CallbackOnFinished( \"%s\", 0x%x ): Callback is NULL",
                  m_name.c_str(), (UINT32)&callback);
        
        SAFE_DELETE(m_pCallbackOnFinished);
        
        rval = E_INVALID_ARG;
        goto Exit;
    }
    
    SAFE_DELETE(m_pCallbackOnFinished);
    m_pCallbackOnFinished = callback.Clone();
    
Exit:
    return rval;
}
Beispiel #8
0
  virtual void Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
  {
    ParserXBase &parser = *GetParent();

    console() << _T("\nParser functions:\n");
    console() << _T(  "----------------\n");

    fun_maptype fmap = parser.GetFunDef();
    if (!fmap.size())
    {
      console() << _T("No functions defined\n");
    }
    else
    {
      val_maptype::iterator item = fmap.begin();
      for (; item!=fmap.end(); ++item)
      {
        ICallback *pFun = (ICallback*)item->second.Get();
        console() << pFun->GetDesc() << _T("\n");
      }
    }

    *ret = (int)fmap.size();
  }
Beispiel #9
0
void SkypeLowIoImpl::thread_func()
{
    utils::set_this_thread_name( "skype_low_io" );

    dummy_log_trace( MODULENAME, "SkypeLowIoImpl::thread_func: started" );

    is_running_ = true;

    while( true )
    {
        if( must_stop_ )
            break;

        {
            MUTEX_SCOPE_LOCK( mutex_ );

            unsigned int seq = sequence_;

            dbus_.read_write_dispatch( 100 );

            if( seq != sequence_ )
            {
                if( sequence_ - seq > 1 )
                {
                    dummy_log_fatal( MODULENAME, "SkypeLowIoImpl::thread_func: missed messages" );
                    ::exit( 42 );
                }
                if( callback_ )
                    callback_->handle( response_ );
                seq = sequence_;
            }
        }

        THIS_THREAD_SLEEP_MS( 1 );
    }

    is_running_ = false;

    dummy_log_trace( MODULENAME, "SkypeLowIoImpl::thread_func: exit" );
}
Beispiel #10
0
  //---------------------------------------------------------------------------
  void ParserXBase::CreateRPN() const
  {
    if (!m_pTokenReader->GetExpr().length()) 
      Error(ecUNEXPECTED_EOF, 0);

    // The Stacks take the ownership over the tokens
    Stack<ptr_tok_type> stOpt;
    Stack<ptr_val_type> stVal;
    Stack<ICallback*>   stFunc;  
    Stack<int>  stArgCount;
    Stack<int>  stIdxCount;
    ptr_tok_type pTok, pTokPrev;
    Value val;    

    ReInit();

    // The outermost counter counts the number of seperated items
    // such as in "a=10,b=20,c=c+a"
    stArgCount.push(1);

    for(bool bLoop=true; bLoop;)
    {
      pTokPrev = pTok;
      pTok = m_pTokenReader->ReadNextToken();

#if defined(MUP_DUMP_TOKENS)
      cout << pTok->AsciiDump() << endl;
#endif
      ECmdCode eCmd = pTok->GetCode();
      switch (eCmd)
      {
      case  cmVAR:
      case  cmVAL:
            {
              IValue *pVal = pTok->AsIValue();
              if (stFunc.empty() && pVal->GetType()=='n')
              {
                ErrorContext err;
                err.Errc  = ecUNEXPECTED_PARENS;
                err.Ident = _T(")");
                err.Pos   = pTok->GetExprPos();
                throw ParserError(err);
              }

              stVal.push( ptr_val_type(pVal) );
              
              // Arrays can't be added directly to the reverse polish notation
              // since there may be an index operator following next...
              m_rpn.Add(pTok);

              // Apply infix operator if existant
              if (stOpt.size() && stOpt.top()->GetCode()==cmOPRT_INFIX) 
                ApplyFunc(stOpt, stVal, 1);
            }
            break;

      case  cmIC:
            {
              // The argument count for parameterless functions is zero
              // by default an opening bracket sets parameter count to 1
              // in preparation of arguments to come. If the last token
              // was an opening bracket we know better...
              if (pTokPrev.Get()!=NULL && pTokPrev->GetCode()==cmIO)
                --stArgCount.top();

              ApplyRemainingOprt(stOpt, stVal);

              // if opt is "]" and opta is "[" the bracket content has been evaluated.
              // Now its time to check if there is either a function or a sign pending.
              // - Neither the opening nor the closing bracket will be pushed back to
              //   the operator stack
              // - Check if a function is standing in front of the opening bracket, 
              //   if so evaluate it afterwards to apply an infix operator.
              if ( stOpt.size() && stOpt.top()->GetCode()==cmIO )
              {
                //
                // Find out how many dimensions were used in the index operator.
                //
                std::size_t iArgc = stArgCount.pop();

                stOpt.pop(); // Take opening bracket from stack
                
                IOprtIndex *pOprtIndex = pTok->AsIOprtIndex();
                MUP_ASSERT(pOprtIndex!=NULL);

                pOprtIndex->SetNumArgsPresent(iArgc);
                m_rpn.Add(pTok);
                
                // Pop the index values from the stack
                MUP_ASSERT(stVal.size()>=iArgc+1); 
                for (std::size_t i=0; i<iArgc; ++i)
                  stVal.pop();

                // Now i would need to pop the topmost value from the stack, apply the index
                // opertor and push the result back to the stack. But here we are just creating the
                // RPN and are working with dummy values anyway so i just mark the topmost value as 
                // volatile and leave it were it is. The real index logic is in the RPN evaluator...
                stVal.top()->AddFlags(IToken::flVOLATILE);
              } // if opening index bracket is on top of operator stack
            }
            break;

      case  cmBC:
            {
              // The argument count for parameterless functions is zero
              // by default an opening bracket sets parameter count to 1
              // in preparation of arguments to come. If the last token
              // was an opening bracket we know better...
              if (pTokPrev.Get()!=NULL && pTokPrev->GetCode()==cmBO)
                --stArgCount.top();

              ApplyRemainingOprt(stOpt, stVal);

              // if opt is ")" and opta is "(" the bracket content has been evaluated.
              // Now its time to check if there is either a function or a sign pending.
              // - Neither the opening nor the closing bracket will be pushed back to
              //   the operator stack
              // - Check if a function is standing in front of the opening bracket, 
              //   if so evaluate it afterwards to apply an infix operator.
              if ( stOpt.size() && stOpt.top()->GetCode()==cmBO )
              {
                //
                // Here is the stuff to evaluate a function token
                //
                int iArgc = stArgCount.pop();

                stOpt.pop(); // Take opening bracket from stack
                if ( stOpt.empty() )
                  break;
                  
                if ( (stOpt.top()->GetCode()!=cmFUNC) && (stOpt.top()->GetCode()!=cmOPRT_INFIX) )
                  break;

                ICallback *pFun = stOpt.top()->AsICallback();
                stFunc.pop(); 

                if (pFun->GetArgc()!=-1 && iArgc > pFun->GetArgc())
                  Error(ecTOO_MANY_PARAMS, pTok->GetExprPos(), pFun);

                if (iArgc < pFun->GetArgc())
                  Error(ecTOO_FEW_PARAMS, pTok->GetExprPos(), pFun);

                // Evaluate the function
                ApplyFunc(stOpt, stVal, iArgc);

                // Apply an infix operator, if present
                if (stOpt.size() && stOpt.top()->GetCode()==cmOPRT_INFIX) 
                  ApplyFunc(stOpt, stVal, 1);
              }
            }
            break;

      case  cmELSE:
            ApplyRemainingOprt(stOpt, stVal);
            m_rpn.Add(pTok);
            stOpt.push(pTok);
            break;

      case  cmSCRIPT_NEWLINE:
            {
              ApplyRemainingOprt(stOpt, stVal);

              // Value stack plätten
              // Stack der RPN um die Anzahl im stack enthaltener Werte zurück setzen
              int n = stVal.size();
              m_rpn.AddNewline(pTok, n);
              stVal.clear();
              stOpt.clear();
            }
            break;

      case  cmARG_SEP:
            if (stArgCount.empty())
              Error(ecUNEXPECTED_COMMA, m_pTokenReader->GetPos());

            ++stArgCount.top();

            //if (stVal.size()) // increase argument counter
            //  stArgCount.top()++;

            ApplyRemainingOprt(stOpt, stVal);
            break;

      case  cmEOE:
            ApplyRemainingOprt(stOpt, stVal);
            m_rpn.Finalize();
            break;

      case  cmIF:
      case  cmOPRT_BIN:
            {
              while ( stOpt.size() && 
                      stOpt.top()->GetCode() != cmBO && 
                      stOpt.top()->GetCode() != cmIO && 
                      stOpt.top()->GetCode() != cmELSE &&
                      stOpt.top()->GetCode() != cmIF)
              {
                IToken *pOprt1 = stOpt.top().Get();
                IToken *pOprt2 = pTok.Get();
                MUP_ASSERT(pOprt1 && pOprt2);  
                MUP_ASSERT(pOprt1->AsIPrecedence() && pOprt2->AsIPrecedence());  

                int nPrec1 = pOprt1->AsIPrecedence()->GetPri(),
                    nPrec2 = pOprt2->AsIPrecedence()->GetPri();

                if (pOprt1->GetCode()==pOprt2->GetCode())
                {
                  // Deal with operator associativity
                  EOprtAsct eOprtAsct = pOprt1->AsIPrecedence()->GetAssociativity();
                  if ( (eOprtAsct==oaRIGHT && (nPrec1 <= nPrec2)) || 
                       (eOprtAsct==oaLEFT  && (nPrec1 <  nPrec2)) )
                  {
                    break;
                  }
                }
                else if (nPrec1 < nPrec2)
                {
                  break;
                }
                
                // apply the operator now 
                // (binary operators are identic to functions with two arguments)
                ApplyFunc(stOpt, stVal, 2);
              } // while ( ... )

              if (pTok->GetCode()==cmIF)
                m_rpn.Add(pTok);

              stOpt.push(pTok);
            }
            break;

      //
      //  Postfix Operators
      //
      case  cmOPRT_POSTFIX:
            {
              MUP_ASSERT(stVal.size());

              ptr_val_type &pVal(stVal.top());
              try
              {
                // place a dummy return value into the value stack, do not
                // evaluate pOprt (this is important for lazy evaluation!)
                // The only place where evaluation takes place is the RPN 
                // engine!
                pVal = ptr_val_type(new Value());
                m_rpn.Add(pTok);
              }
              catch(ParserError &)
              {
                if (!m_bIsQueryingExprVar)
                  throw;
              }
            }
  		      break;

      case  cmIO:
      case  cmBO:    
            stOpt.push(pTok);
            stArgCount.push(1);
            break;

      //
      // Functions
      //
      case  cmOPRT_INFIX:
      case  cmFUNC:
            {
              ICallback *pFunc = pTok->AsICallback();
              MUP_ASSERT(pFunc);

              // Check if this function is a argument to another function
              // if so check if the the return type fits.
              if (!stFunc.empty() && stFunc.top()->GetCode()==cmFUNC)
              {
                MUP_ASSERT(stArgCount.size());
                int iArgc = (int)stArgCount.top() /*+ 1*/;

                ICallback *pOuterFunc = stFunc.top();
                if (pOuterFunc->GetArgc()!=-1 && iArgc>pOuterFunc->GetArgc())
		              Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos());

                MUP_ASSERT(pOuterFunc->GetArgc()==-1 || iArgc<=pOuterFunc->GetArgc());
              }

              stOpt.push(pTok);  
              stFunc.push(pFunc); // to collect runtime type information
            }
	          break;

      default: 
            Error(ecINTERNAL_ERROR);
      } // switch Code

      if (ParserXBase::s_bDumpStack)
      {
        StackDump( stVal, stOpt );
      }

      if ( pTok->GetCode() == cmEOE )
        bLoop = false;
    } // for (all tokens)

    if (ParserXBase::s_bDumpRPN)
    {
      m_rpn.AsciiDump();
    }

    m_nFinalResultIdx = stArgCount.top()-1;
    MUP_ASSERT(stVal.size());
  }
Beispiel #11
0
  /** \brief Calls a parser function with its corresponding arguments. 
      \param a_stOpt The operator stack
      \param a_stVal The value stack
      \param a_iArgCount The number of function arguments
  */
  void ParserXBase::ApplyFunc(Stack<ptr_tok_type> &a_stOpt,
                              Stack<ptr_val_type> &a_stVal, 
                              int a_iArgCount) const
  { 
    if (a_stOpt.empty())
      return;

    ptr_tok_type tok = a_stOpt.pop();
    ICallback *pFun = tok->AsICallback();

    int iArgCount = (pFun->GetArgc()>=0) ? pFun->GetArgc() : a_iArgCount;
    int iOffset = a_stVal.size() - iArgCount;
    MUP_ASSERT(iOffset>=0);

    // The paramater stack may be empty since functions may not
    // have a parameter. They do always have a return value though.
    // If the param stack is empty create an entry for the function 
    // return value.
    if (iArgCount==0)
      a_stVal.push(ptr_val_type(new Value()));

    MUP_ASSERT((std::size_t)iOffset<a_stVal.size());
    ptr_val_type *pArg = a_stVal.get_data() + iOffset;
    
    //if (pFun->GetArgc()==0)
    //  a_stVal.push(ptr_val_type(new Value()));

    //ptr_val_type *pArg = a_stVal.get_data() + iOffset;

    try
    {
      // Make sure to pass on a volatile flag to the function result
      bool bResultIsVolatile = false;
      for (int i=0; i<iArgCount && bResultIsVolatile==false; ++i)
      {
        if (pArg[i]->IsFlagSet(IToken::flVOLATILE))
          bResultIsVolatile = true;
      }

      // Instead of evaluating the function merely a dummy value of the same type as the function return value
      // is created 
      *pArg = ptr_val_type(new Value());
      pFun->SetNumArgsPresent(iArgCount);
      
      if (bResultIsVolatile)
        (*pArg)->AddFlags(IToken::flVOLATILE);

      m_rpn.Add(tok);
    }
    catch(ParserError &e)
    {
      // This are type related errors caused by undefined
      // variables. They must be ignored if the parser is
      // just checking the presence of expression variables
      if (!m_bIsQueryingExprVar)
      {
        ErrorContext &err = e.GetContext();
        err.Pos   = m_pTokenReader->GetPos();
        err.Expr  = m_pTokenReader->GetExpr();

        if (err.Ident.empty())
          err.Ident = pFun->GetIdent();

        throw;
      }
    }

    if (iArgCount>0)
      a_stVal.pop(iArgCount-1); // remove the arguments
  }
Beispiel #12
0
  //---------------------------------------------------------------------------
  const IValue& ParserXBase::ParseFromRPN() const
  {
    ptr_val_type *pStack = &m_vStackBuffer[0];
    const ptr_tok_type *pRPN = &(m_rpn.GetData()[0]);

    int sidx = -1;
    std::size_t lenRPN = m_rpn.GetSize();
    for (std::size_t i=0; i<lenRPN; ++i)
    {
      IToken *pTok = pRPN[i].Get();
      ECmdCode eCode = pTok->GetCode();

      switch (eCode)
      {
      case cmSCRIPT_NEWLINE:
           sidx = -1; //-= static_cast<TokenNewline*>(pTok)->GetStackOffset();
           m_nFinalResultIdx = 0;
           continue;

      case cmVAR:
           {
             sidx++;
             assert(sidx<(int)m_vStackBuffer.size());
             pStack[sidx].Reset(static_cast<IValue*>(pTok));
           }
           continue;

      case cmVAL:
           {
             sidx++;
             assert(sidx<(int)m_vStackBuffer.size());
             ptr_val_type &val = pStack[sidx];
             if (val->GetCode()==cmVAR)
               val.Reset(m_cache.CreateFromCache());

             *val = *(static_cast<IValue*>(pTok));
           }
           continue;

      case  cmIC:
            {
              IOprtIndex *pIdxOprt = static_cast<IOprtIndex*>(pTok);
              int nArgs = pIdxOprt->GetArgsPresent();
              sidx -= nArgs - 1;
              assert(sidx>=0);

              ptr_val_type &idx = pStack[sidx];     // Pointer to the first index
              ptr_val_type &val = pStack[--sidx];   // Pointer to the variable or value beeing indexed
              pIdxOprt->At(val, &idx, nArgs);




/*

              // apply the index operator
              ptr_val_type &idx = pStack[sidx--];
              ptr_val_type &val = pStack[sidx];
              MUP_ASSERT(val->GetCode()==cmVAR);
             
              int i;
              try
              {
                i = idx->GetInteger();
                if (i<0)
                  Error(ecINDEX_OUT_OF_BOUNDS, pTok->GetExprPos(), val.Get());
              }
              catch(ParserError &exc)
              {
                if (exc.GetCode()==ecTYPE_CONFLICT)
                  Error(ecTYPE_CONFLICT_IDX, pTok->GetExprPos(), val.Get());
                else 
                  throw;
              }
              val.Reset(new Variable( &(val->At(i)) ) );
*/
            }
            continue;

      case cmOPRT_POSTFIX:
      case cmFUNC:
      case cmOPRT_BIN:
      case cmOPRT_INFIX:
           {
             ICallback *pFun = static_cast<ICallback*>(pTok);
             int nArgs = pFun->GetArgsPresent();
             sidx -= nArgs - 1;
             assert(sidx>=0);

             ptr_val_type &val = pStack[sidx];
             try
             {
               if (val->GetCode()==cmVAR)
               {
                 ptr_val_type buf(m_cache.CreateFromCache());
                 pFun->Eval(buf, &val, nArgs);
                 val = buf;
               }
               else
                 pFun->Eval(val, &val, nArgs);
             }
             catch(ParserError &exc)
             {
               ErrorContext err;
               err.Expr = m_pTokenReader->GetExpr();
               err.Ident = pFun->GetIdent();
               err.Errc = ecEVAL;
               err.Pos = pFun->GetExprPos();
               err.Hint = exc.GetMsg();
               throw ParserError(err);
             }
             catch(MatrixError & /*exc*/)
             {
               ErrorContext err;
               err.Expr = m_pTokenReader->GetExpr();
               err.Ident = pFun->GetIdent();
               err.Errc = ecEVAL;
               err.Pos = pFun->GetExprPos();
               err.Hint = _T("Matrix dimension mismatch");
               throw ParserError(err);
             }
           }
           continue;

      case cmIF:
           MUP_ASSERT(sidx>=0);
           if (pStack[sidx--]->GetBool()==false)
             i+=static_cast<TokenIfThenElse*>(pTok)->GetOffset();
           continue;

      case cmELSE:
      case cmJMP:
           i += static_cast<TokenIfThenElse*>(pTok)->GetOffset();
           continue;

      case cmENDIF:
           continue;

			default:
					Error(ecINTERNAL_ERROR);
      } // switch token
    } // for all RPN tokens

    return *pStack[m_nFinalResultIdx];
  }
//---------------------------------------------------------------------------
const IValue& ParserXBase::ParseFromRPN() const
{
    ptr_val_type *pStack = &m_vStackBuffer[0];
    if (m_rpn.GetSize()==0)
    {
        // Passiert bei leeren strings oder solchen, die nur Leerzeichen enthalten
        ErrorContext err;
        err.Expr = m_pTokenReader->GetExpr();
        err.Errc = ecUNEXPECTED_EOF;
        err.Pos  = 0;
        throw ParserError(err);
    }

    const ptr_tok_type *pRPN = &(m_rpn.GetData()[0]);

    int sidx = -1;
    std::size_t lenRPN = m_rpn.GetSize();
    for (std::size_t i=0; i<lenRPN; ++i)
    {
        IToken *pTok = pRPN[i].Get();
        ECmdCode eCode = pTok->GetCode();

        switch (eCode)
        {
        case cmSCRIPT_NEWLINE:
            sidx = -1;
            continue;

        case cmVAL:
        {
            IValue *pVal = static_cast<IValue*>(pTok);

            sidx++;
            assert(sidx<(int)m_vStackBuffer.size());
            if (pVal->IsVariable())
            {
                pStack[sidx].Reset(pVal);
            }
            else
            {
                ptr_val_type &val = pStack[sidx];
                if (val->IsVariable())
                    val.Reset(m_cache.CreateFromCache());

                *val = *(static_cast<IValue*>(pTok));
            }
        }
        continue;

        case  cmIC:
        {
            IOprtIndex *pIdxOprt = static_cast<IOprtIndex*>(pTok);
            int nArgs = pIdxOprt->GetArgsPresent();
            sidx -= nArgs - 1;
            assert(sidx>=0);

            ptr_val_type &idx = pStack[sidx];     // Pointer to the first index
            ptr_val_type &val = pStack[--sidx];   // Pointer to the variable or value beeing indexed
            pIdxOprt->At(val, &idx, nArgs);
        }
        continue;

        case cmOPRT_POSTFIX:
        case cmFUNC:
        case cmOPRT_BIN:
        case cmOPRT_INFIX:
        {
            ICallback *pFun = static_cast<ICallback*>(pTok);
            int nArgs = pFun->GetArgsPresent();
            sidx -= nArgs - 1;
            assert(sidx>=0);

            ptr_val_type &val = pStack[sidx];
            try
            {
                if (val->IsVariable())
                {
                    ptr_val_type buf(m_cache.CreateFromCache());
                    pFun->Eval(buf, &val, nArgs);
                    val = buf;
                }
                else
                    pFun->Eval(val, &val, nArgs);
            }
            catch(ParserError &exc)
            {
                // <ibg 20130131> Not too happy about that:
                // Multiarg functions may throw specific error codes when evaluating.
                // These codes would be converted to ecEVAL here. I omit the conversion
                // for certain handpicked errors. (The reason this catch block exists is
                // that not all exceptions contain proper metadata when thrown out of
                // a function.)
                if (exc.GetCode()==ecTOO_FEW_PARAMS || exc.GetCode()==ecDOMAIN_ERROR || exc.GetCode()==ecOVERFLOW)
                    throw;
                // </ibg>

                ErrorContext err;
                err.Expr = m_pTokenReader->GetExpr();
                err.Ident = pFun->GetIdent();
                err.Errc = ecEVAL;
                err.Pos = pFun->GetExprPos();
                err.Hint = exc.GetMsg();
                throw ParserError(err);
            }
            catch(MatrixError & /*exc*/)
            {
                ErrorContext err;
                err.Expr = m_pTokenReader->GetExpr();
                err.Ident = pFun->GetIdent();
                err.Errc = ecMATRIX_DIMENSION_MISMATCH;
                err.Pos = pFun->GetExprPos();
                throw ParserError(err);
            }
        }
        continue;

        case cmIF:
            MUP_ASSERT(sidx>=0);
            if (pStack[sidx--]->GetBool()==false)
                i+=static_cast<TokenIfThenElse*>(pTok)->GetOffset();
            continue;

        case cmELSE:
        case cmJMP:
            i += static_cast<TokenIfThenElse*>(pTok)->GetOffset();
            continue;

        case cmENDIF:
            continue;

        default:
            Error(ecINTERNAL_ERROR);
        } // switch token
    } // for all RPN tokens

    return *pStack[0];
}
//---------------------------------------------------------------------------
void ParserXBase::CreateRPN() const
{
    if (!m_pTokenReader->GetExpr().length())
        Error(ecUNEXPECTED_EOF, 0);

    // The Stacks take the ownership over the tokens
    Stack<ptr_tok_type> stOpt;
    Stack<ICallback*>   stFunc;
    Stack<int>  stArgCount;
    Stack<int>  stIdxCount;
    ptr_tok_type pTok, pTokPrev;
    Value val;

    ReInit();

    for(;;)
    {
        pTokPrev = pTok;
        pTok = m_pTokenReader->ReadNextToken();

#if defined(MUP_DUMP_TOKENS)
        console() << pTok->AsciiDump() << endl;
#endif

        ECmdCode eCmd = pTok->GetCode();
        switch (eCmd)
        {
        case  cmVAL:
            m_nPos++;
            m_rpn.Add(pTok);
            break;

        case  cmIC:
        {
            // The argument count for parameterless functions is zero
            // by default an opening bracket sets parameter count to 1
            // in preparation of arguments to come. If the last token
            // was an opening bracket we know better...
            if (pTokPrev.Get()!=nullptr && pTokPrev->GetCode()==cmIO)
                --stArgCount.top();

            ApplyRemainingOprt(stOpt);

            // if opt is "]" and opta is "[" the bracket content has been evaluated.
            // Now its time to check if there is either a function or a sign pending.
            // - Neither the opening nor the closing bracket will be pushed back to
            //   the operator stack
            // - Check if a function is standing in front of the opening bracket,
            //   if so evaluate it afterwards to apply an infix operator.
            if ( stOpt.size() && stOpt.top()->GetCode()==cmIO )
            {
                //
                // Find out how many dimensions were used in the index operator.
                //
                std::size_t iArgc = stArgCount.pop();
                stOpt.pop(); // Take opening bracket from stack

                IOprtIndex *pOprtIndex = pTok->AsIOprtIndex();
                MUP_ASSERT(pOprtIndex!=nullptr);

                pOprtIndex->SetNumArgsPresent(iArgc);
                m_rpn.Add(pTok);

                // Pop the index values from the stack
                MUP_ASSERT(m_nPos>=(int)iArgc+1);
                m_nPos -= iArgc;
            } // if opening index bracket is on top of operator stack
        }
        break;

        case  cmBC:
        {
            // The argument count for parameterless functions is zero
            // by default an opening bracket sets parameter count to 1
            // in preparation of arguments to come. If the last token
            // was an opening bracket we know better...
            if (pTokPrev.Get()!=nullptr && pTokPrev->GetCode()==cmBO)
                --stArgCount.top();

            ApplyRemainingOprt(stOpt);

            // if opt is ")" and opta is "(" the bracket content has been evaluated.
            // Now its time to check if there is either a function or a sign pending.
            // - Neither the opening nor the closing bracket will be pushed back to
            //   the operator stack
            // - Check if a function is standing in front of the opening bracket,
            //   if so evaluate it afterwards to apply an infix operator.
            if ( stOpt.size() && stOpt.top()->GetCode()==cmBO )
            {
                //
                // Here is the stuff to evaluate a function token
                //
                int iArgc = stArgCount.pop();

                stOpt.pop(); // Take opening bracket from stack
                if (stOpt.empty())
                    break;

                if ((stOpt.top()->GetCode()!=cmFUNC) && (stOpt.top()->GetCode()!=cmOPRT_INFIX))
                    break;

                ICallback *pFun = stOpt.top()->AsICallback();
                stFunc.pop();

                if (pFun->GetArgc()!=-1 && iArgc > pFun->GetArgc())
                    Error(ecTOO_MANY_PARAMS, pTok->GetExprPos(), pFun);

                if (iArgc < pFun->GetArgc())
                    Error(ecTOO_FEW_PARAMS, pTok->GetExprPos(), pFun);

                // Apply function, if present
                if (stOpt.size() &&
                        stOpt.top()->GetCode()!=cmOPRT_INFIX &&
                        stOpt.top()->GetCode()!=cmOPRT_BIN)
                {
                    ApplyFunc(stOpt, iArgc);
                }
            }
        }
        break;

        case  cmELSE:
            ApplyRemainingOprt(stOpt);
            m_rpn.Add(pTok);
            stOpt.push(pTok);
            break;

        case  cmSCRIPT_NEWLINE:
            ApplyRemainingOprt(stOpt);
            m_rpn.AddNewline(pTok, m_nPos);
            stOpt.clear();
            m_nPos = 0;
            break;

        case  cmARG_SEP:
            if (stArgCount.empty())
                Error(ecUNEXPECTED_COMMA, m_pTokenReader->GetPos()-1);

            ++stArgCount.top();

            ApplyRemainingOprt(stOpt);
            break;

        case  cmEOE:
            ApplyRemainingOprt(stOpt);
            m_rpn.Finalize();
            break;

        case  cmIF:
        case  cmOPRT_BIN:
        {
            while ( stOpt.size() &&
                    stOpt.top()->GetCode() != cmBO &&
                    stOpt.top()->GetCode() != cmIO &&
                    stOpt.top()->GetCode() != cmELSE &&
                    stOpt.top()->GetCode() != cmIF)
            {
                IToken *pOprt1 = stOpt.top().Get();
                IToken *pOprt2 = pTok.Get();
                MUP_ASSERT(pOprt1 && pOprt2);
                MUP_ASSERT(pOprt1->AsIPrecedence() && pOprt2->AsIPrecedence());

                int nPrec1 = pOprt1->AsIPrecedence()->GetPri(),
                    nPrec2 = pOprt2->AsIPrecedence()->GetPri();

                if (pOprt1->GetCode()==pOprt2->GetCode())
                {
                    // Deal with operator associativity
                    EOprtAsct eOprtAsct = pOprt1->AsIPrecedence()->GetAssociativity();
                    if ( (eOprtAsct==oaRIGHT && (nPrec1 <= nPrec2)) ||
                            (eOprtAsct==oaLEFT  && (nPrec1 <  nPrec2)) )
                    {
                        break;
                    }
                }
                else if (nPrec1 < nPrec2)
                {
                    break;
                }

                // apply the operator now
                // (binary operators are identic to functions with two arguments)
                ApplyFunc(stOpt, 2);
            } // while ( ... )

            if (pTok->GetCode()==cmIF)
                m_rpn.Add(pTok);

            stOpt.push(pTok);
        }
        break;

        //
        //  Postfix Operators
        //
        case  cmOPRT_POSTFIX:
            MUP_ASSERT(m_nPos);
            m_rpn.Add(pTok);
            break;

        case  cmIO:
        case  cmBO:
            stOpt.push(pTok);
            stArgCount.push(1);
            break;

        //
        // Functions
        //
        case  cmOPRT_INFIX:
        case  cmFUNC:
        {
            ICallback *pFunc = pTok->AsICallback();
            MUP_ASSERT(pFunc);

            // Check if this function is a argument to another function
            // if so check if the the return type fits.
            if (!stFunc.empty() && stFunc.top()->GetCode()==cmFUNC)
            {
                MUP_ASSERT(stArgCount.size());
                int iArgc = (int)stArgCount.top() /*+ 1*/;

                ICallback *pOuterFunc = stFunc.top();
                if (pOuterFunc->GetArgc()!=-1 && iArgc>pOuterFunc->GetArgc())
                    Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos());

                MUP_ASSERT(pOuterFunc->GetArgc()==-1 || iArgc<=pOuterFunc->GetArgc());
            }

            stOpt.push(pTok);
            stFunc.push(pFunc); // to collect runtime type information
        }
        break;

        default:
            Error(ecINTERNAL_ERROR);
        } // switch Code

        if (ParserXBase::s_bDumpStack)
        {
            StackDump(stOpt);
        }

        if ( pTok->GetCode() == cmEOE )
            break;
    } // for (all tokens)

    if (ParserXBase::s_bDumpRPN)
    {
        m_rpn.AsciiDump();
    }

    if (m_nPos>1)
    {
        Error(ecUNEXPECTED_COMMA, -1);
    }
}
 void SingleThreadedParallelizer::loop(ICallback& callback, int start, int end) {
     for(int i=start; i<end; ++i) {
         callback.invoke(i);
     }
 }