예제 #1
0
  //-----------------------------------------------------------
  void OprtShr::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
  {
	  assert(num==2);

	  if (!a_pArg[0]->IsScalar())
		  throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, GetExprPos(), GetIdent(), a_pArg[0]->GetType(), 'i', 1));

	  if (!a_pArg[1]->IsScalar())
		  throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, GetExprPos(), GetIdent(), a_pArg[1]->GetType(), 'i', 2));

	  float_type a = a_pArg[0]->GetFloat(),
		  b = a_pArg[1]->GetFloat();

	  if (a!=(int_type)a)
		  throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, GetExprPos(), a_pArg[0]->GetIdent(), a_pArg[0]->GetType(), 'i', 1) ); 

	  if (b!=(int_type)b)
		  throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, GetExprPos(), a_pArg[1]->GetIdent(), a_pArg[1]->GetType(), 'i', 2) ); 

	  float_type result = a*std::pow(2, -b);
	  int numDigits = std::numeric_limits<float_type>::digits10;

	  if (std::fabs(result) >= std::fabs(std::pow(10.0, numDigits)))
		  throw ParserError(ErrorContext(ecOVERFLOW, GetExprPos(), GetIdent()));

	  if (result>0)
		  *ret = std::floor(result);
	  else
		  *ret = std::ceil(result);
  }
예제 #2
0
  /** \brief Index operator implementation
      \param ret A reference to the return value
      \param a_pArg Pointer to an array with the indices as ptr_val_type
      \param a_iArgc Number of indices (=dimension) actully used in the expression found. This must 
             be 1 or 2 since three dimensional data structures are not supported by muParserX.
  */
  void OprtIndex::At(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
  {
    try
    {
      // The index is -1, thats the actual variable reference
      if (a_iArgc!=a_pArg[-1]->GetDim())
      {
        throw ParserError(ErrorContext(ecINDEX_DIMENSION, -1, GetIdent()));
      }

      switch(a_iArgc)
      {
      case 1:
          ret.Reset(new Variable( &(ret->At(*a_pArg[0], Value(0))) ) );
          break;

      case 2:
          ret.Reset(new Variable( &(ret->At(*a_pArg[0], *a_pArg[1])) ) );
          break;

      default:
          throw ParserError(ErrorContext(ecINDEX_DIMENSION, -1, GetIdent()));
      }
    }
    catch(ParserError &exc)
    {
      exc.GetContext().Pos = GetExprPos();
      throw exc;
    }
  }
예제 #3
0
  //-----------------------------------------------------------------------------------------------
  void OprtSubCmplx::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
  { 
    assert(num==2);
    
    const IValue *arg1 = a_pArg[0].Get();
    const IValue *arg2 = a_pArg[1].Get();
    if ( a_pArg[0]->IsNonComplexScalar() && a_pArg[1]->IsNonComplexScalar())
    {
      *ret = arg1->GetFloat() - arg2->GetFloat(); 
    }
    else if (a_pArg[0]->GetType()=='m' && a_pArg[1]->GetType()=='m')
    {
      // Matrix + Matrix
      *ret = arg1->GetArray() - arg2->GetArray();
    }
    else
    {
      if (!a_pArg[0]->IsScalar())
        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, GetExprPos(), GetIdent(), a_pArg[0]->GetType(), 'c', 1)); 

      if (!a_pArg[1]->IsScalar())
        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, GetExprPos(), GetIdent(), a_pArg[1]->GetType(), 'c', 2)); 
      
      *ret = cmplx_type(a_pArg[0]->GetFloat() - a_pArg[1]->GetFloat(),
                        a_pArg[0]->GetImag() - a_pArg[1]->GetImag()); 
    }
  }
예제 #4
0
  /** \brief Implements the Division operator. 
      \throw ParserError in case one of the arguments if 
             nonnumeric or an array.
  
  */
  void OprtDiv::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
  { 
    assert(num==2);

    if (!a_pArg[0]->IsNonComplexScalar())
      throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[0]->GetType(), 'f', 1)); 

    if (!a_pArg[1]->IsNonComplexScalar())
      throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[1]->GetType(), 'f', 2)); 
    
    *ret = a_pArg[0]->GetFloat() / a_pArg[1]->GetFloat();
  }
예제 #5
0
  //-----------------------------------------------------------
  void OprtMul::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
  { 
    assert(num==2);
    IValue *arg1 = a_pArg[0].Get();
    IValue *arg2 = a_pArg[1].Get();
    if (arg1->GetType()=='m' && arg2->GetType()=='m')
    {
      // Scalar multiplication
      matrix_type a1 = arg1->GetArray();
      matrix_type a2 = arg2->GetArray();

      if (a1.GetRows()!=a2.GetRows())
        throw ParserError(ErrorContext(ecARRAY_SIZE_MISMATCH, -1, GetIdent(), 'm', 'm', 2));

      float_type val(0);
      for (int i=0; i<a1.GetRows(); ++i)
        val += a1.At(i).GetFloat()*a2.At(i).GetFloat();

      *ret = val;
    }
    else if (arg1->GetType()=='m' && arg2->IsNonComplexScalar())
    {
      // Skalar * Vector
      matrix_type out(a_pArg[0]->GetArray());
      for (int i=0; i<out.GetRows(); ++i)
        out.At(i) = out.At(i).GetFloat() * arg2->GetFloat();

      *ret = out; 
    }
    else if (arg2->GetType()=='m' && arg1->IsNonComplexScalar())
    {
      // Vector * Skalar
      matrix_type out(arg2->GetArray());
      for (int i=0; i<out.GetRows(); ++i)
        out.At(i) = out.At(i).GetFloat() * arg1->GetFloat();

      *ret = out; 
    }
    else
    {
      if (!arg1->IsNonComplexScalar())
        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), arg1->GetType(), 'f', 1)); 

      if (!arg2->IsNonComplexScalar())
        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), arg2->GetType(), 'f', 2)); 

      *ret = arg1->GetFloat() * arg2->GetFloat(); 
    }
  }
예제 #6
0
  //---------------------------------------------------------------------------
  IValue& Value::operator+=(const IValue &val)
  {
    if (IsScalar() && val.IsScalar())
    {
      // Scalar/Scalar addition
      m_val += val.GetComplex();
      m_cType = (m_val.imag()==0) ? ( (m_val.real()==(int)m_val.real()) ? 'i' : 'f' ) : 'c';
    }
    else if (IsMatrix() && val.IsMatrix())
    {
      // Matrix/Matrix addition
      assert(m_pvVal);
      *m_pvVal += val.GetArray();
    }
    else if (IsString() && val.IsString())
    {
      // string/string addition
      assert(m_psVal);
      *m_psVal += val.GetString();
    }
    else
    {
      // Type conflict
      throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, -1, _T("+"), GetType(), val.GetType(), 2));
    }

    return *this;
  }
예제 #7
0
  //---------------------------------------------------------------------------
  IValue& Value::At(int nRow, int nCol)
  {
    if (IsMatrix())
    {
      if (nRow>=m_pvVal->GetRows() || nCol>=m_pvVal->GetCols() || nRow<0 || nCol<0)
        throw ParserError( ErrorContext(ecINDEX_OUT_OF_BOUNDS, -1, GetIdent()) ); 

      return m_pvVal->At(nRow, nCol);
    }
    else if (nRow==0 && nCol==0)
    {
      return *this;
    }
    else
      throw ParserError( ErrorContext(ecINDEX_OUT_OF_BOUNDS) ); 
  }
  //------------------------------------------------------------------------------
  void FunMax::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
  {
	  if (a_iArgc < 1)
		throw ParserError(ErrorContext(ecTOO_FEW_PARAMS, GetExprPos(), GetIdent()));

	float_type smax(-1e30), sval(0);
	for (int i=0; i<a_iArgc; ++i)
	{
	  switch(a_pArg[i]->GetType())
	  {
	  case 'f': sval = a_pArg[i]->GetFloat();   break;
	  case 'i': sval = a_pArg[i]->GetFloat(); break;
	  case 'n': break; // ignore not in list entries (missing parameter)
	  case 'c':
	  default:
		{
		  ErrorContext err;
		  err.Errc = ecTYPE_CONFLICT_FUN;
		  err.Arg = i+1;
		  err.Type1 = a_pArg[i]->GetType();
		  err.Type2 = 'f';
		  throw ParserError(err);
		}
	  }
	  smax = max(smax, sval);
	}

	*ret = smax;
  }
  /** \brief Returns the minimum value of all values.
	  \param a_pArg Pointer to an array of Values
	  \param a_iArgc Number of values stored in a_pArg
  */
  void FunSum::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int a_iArgc)
  {
	  if (a_iArgc < 1)
		  throw ParserError(ErrorContext(ecTOO_FEW_PARAMS, GetExprPos(), GetIdent()));

	float_type sum(0);

	for (int i=0; i<a_iArgc; ++i)
	{
	  switch(a_pArg[i]->GetType())
	  {
	  case 'f':
	  case 'i': sum += a_pArg[i]->GetFloat();   break;
	  default:
		{
		  ErrorContext err;
		  err.Errc = ecTYPE_CONFLICT_FUN;
		  err.Arg = i+1;
		  err.Type1 = a_pArg[i]->GetType();
		  err.Type2 = 'f';
		  throw ParserError(err);
		}
	  }
	}

	*ret = sum;
  }
예제 #10
0
파일: mpIOprt.cpp 프로젝트: QAndot/muparser
/** \brief Verify the operator prototype.

  Binary operators have the additional constraint that return type and the types
  of both arguments must be the same. So adding to floats can not produce a string
  and adding a number to a string is impossible.
*/
void IOprtBin::CheckPrototype(const string_type &a_sProt)
{
    if (a_sProt.length()!=4)
        throw ParserError( ErrorContext(ecAPI_INVALID_PROTOTYPE, -1, GetIdent() ) );

    //if (a_sProt[0]!=a_sProt[2] || a_sProt[0]!=a_sProt[3])
    //  throw ParserError( ErrorContext(ecAPI_INVALID_PROTOTYPE, -1, GetIdent() ) );
}
예제 #11
0
  //-----------------------------------------------------------
  void OprtOr::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
  {
	assert(num==2);

	if (!a_pArg[0]->IsScalar())
	  throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[0]->GetType(), 'i', 1));

	if (!a_pArg[1]->IsScalar())
	  throw ParserError(ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[1]->GetType(), 'i', 2));

	float_type a = a_pArg[0]->GetFloat(),
			   b = a_pArg[1]->GetFloat();

	if (a!=(int_type)a)
	  throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, a_pArg[0]->GetIdent(), a_pArg[0]->GetType(), 'i', 1) );

	if (b!=(int_type)b)
	  throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, a_pArg[1]->GetIdent(), a_pArg[1]->GetType(), 'i', 2) );

	*ret = (int_type)a | (int_type)(b);
  }
예제 #12
0
  //-----------------------------------------------------------
  void OprtAdd::Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int num)
  { 
    assert(num==2);

    const IValue *arg1 = a_pArg[0].Get();
    const IValue *arg2 = a_pArg[1].Get();
    if (arg1->GetType()=='m' && arg2->GetType()=='m')
    {
      // Vector + Vector
      const matrix_type &a1 = arg1->GetArray(),
                       &a2 = arg2->GetArray();
      if (a1.GetRows()!=a2.GetRows())
        throw ParserError(ErrorContext(ecARRAY_SIZE_MISMATCH, -1, GetIdent(), 'm', 'm', 2));
      
      matrix_type rv(a1.GetRows());
      for (int i=0; i<a1.GetRows(); ++i)
      {
        if (!a1.At(i).IsNonComplexScalar())
          throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a1.At(i).GetType(), 'f', 1)); 

        if (!a2.At(i).IsNonComplexScalar())
          throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a2.At(i).GetType(), 'f', 1)); 

        rv.At(i) = a1.At(i).GetFloat() + a2.At(i).GetFloat();
      }

      *ret = rv; 
    }
    else
    {
      if (!arg1->IsNonComplexScalar())
        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), arg1->GetType(), 'f', 1)); 

      if (!arg2->IsNonComplexScalar())
        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), arg2->GetType(), 'f', 2)); 
      
      *ret = arg1->GetFloat() + arg2->GetFloat(); 
    }
  }
예제 #13
0
  //-----------------------------------------------------------
  void OprtColon::Eval(ptr_val_type& ret, const ptr_val_type *a_pArg, int num)
  { 
    assert(num==2);

    const IValue *argMin = a_pArg[0].Get();
    const IValue *argMax = a_pArg[1].Get();
  
    if (!argMin->IsNonComplexScalar())
      throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), argMin->GetType(), 'i', 1)); 

    if (!argMax->IsNonComplexScalar())
      throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), argMax->GetType(), 'i', 1)); 

    if (*argMax < *argMin)
      throw ParserError(_T("Colon operator: Maximum value smaller than Minimum!")); 

    int n = (argMax->GetFloat() - argMin->GetFloat()) + 1;
    matrix_type arr(n);
    for (int i=0; i<n; ++i)
      arr.At(i) = argMin->GetFloat() + i;

    *ret = arr; 
  }
예제 #14
0
  //-----------------------------------------------------------
  void OprtSub::Eval(ptr_val_type &ret, const ptr_val_type *a_pArg, int num)
  { 
    assert(num==2);

    if (a_pArg[0]->GetType()=='m' && a_pArg[1]->GetType()=='m')
    {
      const matrix_type &a1 = a_pArg[0]->GetArray(),
                       &a2 = a_pArg[1]->GetArray();
      if (a1.GetRows()!=a2.GetRows())
        throw ParserError(ErrorContext(ecARRAY_SIZE_MISMATCH, -1, GetIdent(), 'm', 'm', 2));
      
      matrix_type rv(a1.GetRows());
      for (int i=0; i<a1.GetRows(); ++i)
      {
        if (!a1.At(i).IsNonComplexScalar())
          throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a1.At(i).GetType(), 'f', 1)); 

        if (!a2.At(i).IsNonComplexScalar())
          throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a2.At(i).GetType(), 'f', 1)); 

        rv.At(i) = cmplx_type(a1.At(i).GetFloat() - a2.At(i).GetFloat(),
                              a1.At(i).GetImag()  - a2.At(i).GetImag());
      }

      *ret = rv;
    }
    else
    {
      if (!a_pArg[0]->IsNonComplexScalar())
        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[0]->GetType(), 'f', 1)); 

      if (!a_pArg[1]->IsNonComplexScalar())
        throw ParserError( ErrorContext(ecTYPE_CONFLICT_FUN, -1, GetIdent(), a_pArg[1]->GetType(), 'f', 2)); 
      
      *ret = a_pArg[0]->GetFloat() - a_pArg[1]->GetFloat(); 
    }
  }
예제 #15
0
파일: mpError.cpp 프로젝트: QAndot/muparser
 //------------------------------------------------------------------------------
 void ParserError::Reset()
 {
   m_sMsg = _T("");
   m_Err = ErrorContext();
 }
예제 #16
0
bool normalizeAlgorithm(const AlgorithmIdentifier& raw, WebCryptoOperation op, WebCryptoAlgorithm& algorithm, AlgorithmError* error)
{
    return parseAlgorithmIdentifier(raw, op, algorithm, ErrorContext(), error);
}