//----------------------------------------------------------- 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); }
//----------------------------------------------------------------------------------------------- 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()); } }
//--------------------------------------------------------------------------- string_type Value::AsciiDump() const { stringstream_type ss; ss << g_sCmdCode[ GetCode() ]; ss << _T(" [addr=0x") << std::hex << this << std::dec; ss << _T("; pos=") << GetExprPos(); ss << _T("; type=\"") << GetType() << _T("\""); ss << _T("; val="); switch(m_cType) { case 'i': ss << (int_type)m_val.real(); break; case 'f': ss << m_val.real(); break; case 'm': ss << _T("(matrix)"); break; case 's': assert(m_psVal!=nullptr); ss << _T("\"") << m_psVal << _T("\""); break; } ss << ((IsFlagSet(IToken::flVOLATILE)) ? _T("; ") : _T("; not ")) << _T("vol"); ss << _T("]"); return ss.str(); }
/** \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; } }
//------------------------------------------------------------------------------ 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; }
//--------------------------------------------------------------------------- string_type TokenNewline::AsciiDump() const { stringstream_type ss; ss << g_sCmdCode[ GetCode() ]; ss << _T(" [addr=0x") << std::hex << this << std::dec; ss << _T("; pos=") << GetExprPos(); ss << _T("; offset=") << m_nOffset; ss << _T("]"); return ss.str(); }
//------------------------------------------------------------------------------ string_type ICallback::AsciiDump() const { stringstream_type ss; ss << g_sCmdCode[ GetCode() ]; ss << _T(" [addr=0x") << std::hex << this << std::dec; ss << _T("; pos=") << GetExprPos(); ss << _T("; id=\"") << GetIdent() << "\""; ss << _T("; argc=") << GetArgc() << " (found: " << m_nArgsPresent << ")"; ss << _T("]"); return ss.str(); }
/** \brief Return the matrix element at row col. Row and col are the indices of the matrix. If this element does not represent a matrix row and col must be 0 otherwise an index out of bound error is thrown. */ IValue& Value::At(const IValue &row, const IValue &col) { if (!row.IsInteger() || !col.IsInteger()) { ErrorContext errc(ecTYPE_CONFLICT_IDX, GetExprPos()); errc.Type1 = (!row.IsInteger()) ? row.GetType() : col.GetType(); errc.Type2 = 'i'; throw ParserError(errc); } int nRow = row.GetInteger(), nCol = col.GetInteger(); return At(nRow, nCol); }
//----------------------------------------------------------------------------------------------- string_type Variable::AsciiDump() const { stringstream_type ss; ss << g_sCmdCode[ GetCode() ]; ss << _T(" [addr=0x") << std::hex << this << std::dec; ss << _T("; pos=") << GetExprPos(); ss << _T("; id=\"") << GetIdent() << _T("\""); ss << _T("; type=\"") << GetType() << _T("\""); ss << _T("; val="); switch(GetType()) { case 'i': ss << (int_type)GetFloat(); break; case 'f': ss << GetFloat(); break; case 'm': ss << _T("(array)"); break; case 's': ss << _T("\"") << GetString() << _T("\""); break; } ss << ((IsFlagSet(IToken::flVOLATILE)) ? _T("; ") : _T("; not ")) << _T("vol"); ss << _T("]"); return ss.str(); }