[muparser] Restyle muparser sources to match fish

Add muparser soruces to style.fish, and run it to make muparser
match fish style guidelines.
This commit is contained in:
ridiculousfish 2017-11-18 13:49:52 -08:00
parent b39d0adc39
commit e2b798cda3
24 changed files with 6315 additions and 6962 deletions

View file

@ -29,7 +29,7 @@ if test $all = yes
echo
exit 1
end
set c_files src/*.h src/*.cpp
set c_files src/*.h src/*.cpp muparser-2.2.5/src/*.cpp muparser-2.2.5/include/*.h
# For now we don't restyle all fish scripts other than completion scripts. That's because people
# really like to vertically align the elements of the `complete` command and fish_indent
# currently does not honor that whitespace.

View file

@ -36,9 +36,8 @@
\brief Definition of the standard floating point parser.
*/
namespace mu
{
/** \brief Mathematical expressions parser.
namespace mu {
/** \brief Mathematical expressions parser.
Standard implementation of the mathematical expressions parser.
Can be used as a reference implementation for subclassing the parser.
@ -47,11 +46,9 @@ namespace mu
(C) 2011 Ingo Berg<br>
muparser(at)beltoforion.de
</small>
*/
/* final */ class Parser : public ParserBase
{
*/
/* final */ class Parser : public ParserBase {
public:
Parser();
virtual void InitCharSets();
@ -60,12 +57,9 @@ namespace mu
virtual void InitOprt();
virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd);
value_type Diff(value_type *a_Var,
value_type a_fPos,
value_type a_fEpsilon = 0) const;
value_type Diff(value_type *a_Var, value_type a_fPos, value_type a_fEpsilon = 0) const;
protected:
// Trigonometric functions
static value_type Sin(value_type);
static value_type Cos(value_type);
@ -102,14 +96,13 @@ namespace mu
static value_type UnaryPlus(value_type);
// Functions with variable number of arguments
static value_type Sum(const value_type*, int); // sum
static value_type Avg(const value_type*, int); // mean value
static value_type Min(const value_type*, int); // minimum
static value_type Max(const value_type*, int); // maximum
static value_type Sum(const value_type *, int); // sum
static value_type Avg(const value_type *, int); // mean value
static value_type Min(const value_type *, int); // minimum
static value_type Max(const value_type *, int); // maximum
static int IsVal(const char_type* a_szExpr, int *a_iPos, value_type *a_fVal);
};
static int IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal);
};
} // namespace mu
#endif

View file

@ -26,24 +26,22 @@
#define MU_PARSER_BASE_H
//--- Standard includes ------------------------------------------------------------------------
#include <limits.h>
#include <cmath>
#include <string>
#include <iostream>
#include <locale>
#include <map>
#include <memory>
#include <locale>
#include <limits.h>
#include <string>
//--- Parser includes --------------------------------------------------------------------------
#include "muParserBytecode.h"
#include "muParserDef.h"
#include "muParserError.h"
#include "muParserStack.h"
#include "muParserTokenReader.h"
#include "muParserBytecode.h"
#include "muParserError.h"
namespace mu
{
namespace mu {
/** \file
\brief This file contains the class definition of the muparser engine.
*/
@ -59,12 +57,10 @@ namespace mu
Complementary to a set of internally implemented functions the parser is able to handle
user defined functions and variables.
*/
class ParserBase
{
friend class ParserTokenReader;
private:
class ParserBase {
friend class ParserTokenReader;
private:
/** \brief Typedef for the parse functions.
The parse function do the actual work. The parser exchanges
@ -89,7 +85,6 @@ private:
static const int s_MaxNumOpenMPThreads = 16;
public:
/** \brief Type of the error class.
Included for backwards compatibility.
@ -100,12 +95,12 @@ private:
ParserBase();
ParserBase(const ParserBase &a_Parser);
ParserBase& operator=(const ParserBase &a_Parser);
ParserBase &operator=(const ParserBase &a_Parser);
virtual ~ParserBase();
value_type Eval() const;
value_type* Eval(int &nStackSize) const;
value_type *Eval(int &nStackSize) const;
void Eval(value_type *results, int nBulkSize);
int GetNumResults() const;
@ -117,34 +112,32 @@ private:
void SetThousandsSep(char_type cThousandsSep = 0);
void ResetLocale();
void EnableOptimizer(bool a_bIsOn=true);
void EnableBuiltInOprt(bool a_bIsOn=true);
void EnableOptimizer(bool a_bIsOn = true);
void EnableBuiltInOprt(bool a_bIsOn = true);
bool HasBuiltInOprt() const;
void AddValIdent(identfun_type a_pCallback);
/** \fn void mu::ParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, bool a_bAllowOpt = true)
/** \fn void mu::ParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, bool
a_bAllowOpt = true)
\brief Define a parser function without arguments.
\param a_strName Name of the function
\param a_pFun Pointer to the callback function
\param a_bAllowOpt A flag indicating this function may be optimized
*/
template<typename T>
void DefineFun(const string_type &a_strName, T a_pFun, bool a_bAllowOpt = true)
{
AddCallback( a_strName, ParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() );
template <typename T>
void DefineFun(const string_type &a_strName, T a_pFun, bool a_bAllowOpt = true) {
AddCallback(a_strName, ParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars());
}
void DefineOprt(const string_type &a_strName,
fun_type2 a_pFun,
unsigned a_iPri=0,
EOprtAssociativity a_eAssociativity = oaLEFT,
bool a_bAllowOpt = false);
void DefineOprt(const string_type &a_strName, fun_type2 a_pFun, unsigned a_iPri = 0,
EOprtAssociativity a_eAssociativity = oaLEFT, bool a_bAllowOpt = false);
void DefineConst(const string_type &a_sName, value_type a_fVal);
void DefineStrConst(const string_type &a_sName, const string_type &a_strVal);
void DefineVar(const string_type &a_sName, value_type *a_fVar);
void DefinePostfixOprt(const string_type &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true);
void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true);
void DefinePostfixOprt(const string_type &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt = true);
void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec = prINFIX,
bool a_bAllowOpt = true);
// Clear user defined variables, constants or functions
void ClearVar();
@ -155,31 +148,29 @@ private:
void ClearOprt();
void RemoveVar(const string_type &a_strVarName);
const varmap_type& GetUsedVar() const;
const varmap_type& GetVar() const;
const valmap_type& GetConst() const;
const string_type& GetExpr() const;
const funmap_type& GetFunDef() const;
const varmap_type &GetUsedVar() const;
const varmap_type &GetVar() const;
const valmap_type &GetConst() const;
const string_type &GetExpr() const;
const funmap_type &GetFunDef() const;
string_type GetVersion(EParserVersionInfo eInfo = pviFULL) const;
const char_type ** GetOprtDef() const;
const char_type **GetOprtDef() const;
void DefineNameChars(const char_type *a_szCharset);
void DefineOprtChars(const char_type *a_szCharset);
void DefineInfixOprtChars(const char_type *a_szCharset);
const char_type* ValidNameChars() const;
const char_type* ValidOprtChars() const;
const char_type* ValidInfixOprtChars() const;
const char_type *ValidNameChars() const;
const char_type *ValidOprtChars() const;
const char_type *ValidInfixOprtChars() const;
void SetArgSep(char_type cArgSep);
char_type GetArgSep() const;
void Error(EErrorCodes a_iErrc,
int a_iPos = (int)mu::string_type::npos,
const string_type &a_strTok = string_type() ) const;
void Error(EErrorCodes a_iErrc, int a_iPos = (int)mu::string_type::npos,
const string_type &a_strTok = string_type()) const;
protected:
void Init();
virtual void InitCharSets() = 0;
@ -195,32 +186,21 @@ private:
static bool g_DbgDumpStack;
/** \brief A facet class used to change decimal and thousands separator. */
template<class TChar>
class change_dec_sep : public std::numpunct<TChar>
{
template <class TChar>
class change_dec_sep : public std::numpunct<TChar> {
public:
explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3)
:std::numpunct<TChar>()
,m_nGroup(nGroup)
,m_cDecPoint(cDecSep)
,m_cThousandsSep(cThousandsSep)
{}
: std::numpunct<TChar>(),
m_nGroup(nGroup),
m_cDecPoint(cDecSep),
m_cThousandsSep(cThousandsSep) {}
protected:
virtual char_type do_decimal_point() const { return m_cDecPoint; }
virtual char_type do_decimal_point() const
{
return m_cDecPoint;
}
virtual char_type do_thousands_sep() const { return m_cThousandsSep; }
virtual char_type do_thousands_sep() const
{
return m_cThousandsSep;
}
virtual std::string do_grouping() const
{
virtual std::string do_grouping() const {
// fix for issue 4: https://code.google.com/p/muparser/issues/detail?id=4
// courtesy of Jens Bartsch
// original code:
@ -230,33 +210,26 @@ private:
}
private:
int m_nGroup;
char_type m_cDecPoint;
char_type m_cThousandsSep;
};
private:
void Assign(const ParserBase &a_Parser);
void InitTokenReader();
void ReInit() const;
void AddCallback( const string_type &a_strName,
const ParserCallback &a_Callback,
funmap_type &a_Storage,
const char_type *a_szCharSet );
void AddCallback(const string_type &a_strName, const ParserCallback &a_Callback,
funmap_type &a_Storage, const char_type *a_szCharSet);
void ApplyRemainingOprt(ParserStack<token_type> &a_stOpt,
ParserStack<token_type> &a_stVal) const;
void ApplyBinOprt(ParserStack<token_type> &a_stOpt,
ParserStack<token_type> &a_stVal) const;
void ApplyBinOprt(ParserStack<token_type> &a_stOpt, ParserStack<token_type> &a_stVal) const;
void ApplyIfElse(ParserStack<token_type> &a_stOpt,
ParserStack<token_type> &a_stVal) const;
void ApplyIfElse(ParserStack<token_type> &a_stOpt, ParserStack<token_type> &a_stVal) const;
void ApplyFunc(ParserStack<token_type> &a_stOpt,
ParserStack<token_type> &a_stVal,
void ApplyFunc(ParserStack<token_type> &a_stOpt, ParserStack<token_type> &a_stVal,
int iArgCount) const;
token_type ApplyStrFunc(const token_type &a_FunTok,
@ -272,12 +245,11 @@ private:
value_type ParseCmdCodeBulk(int nOffset, int nThreadID) const;
void CheckName(const string_type &a_strName, const string_type &a_CharSet) const;
void CheckOprt(const string_type &a_sName,
const ParserCallback &a_Callback,
void CheckOprt(const string_type &a_sName, const ParserCallback &a_Callback,
const string_type &a_szCharSet) const;
void StackDump(const ParserStack<token_type > &a_stVal,
const ParserStack<token_type > &a_stOprt) const;
void StackDump(const ParserStack<token_type> &a_stVal,
const ParserStack<token_type> &a_stOprt) const;
/** \brief Pointer to the parser function.
@ -285,10 +257,12 @@ private:
*/
mutable ParseFunction m_pParseFormula;
mutable ParserByteCode m_vRPN; ///< The Bytecode class.
mutable stringbuf_type m_vStringBuf; ///< String buffer, used for storing string function arguments
mutable stringbuf_type
m_vStringBuf; ///< String buffer, used for storing string function arguments
stringbuf_type m_vStringVarBuf;
std::auto_ptr<token_reader_type> m_pTokenReader; ///< Managed pointer to the token reader object.
std::auto_ptr<token_reader_type>
m_pTokenReader; ///< Managed pointer to the token reader object.
funmap_type m_FunDef; ///< Map of function names and pointers.
funmap_type m_PostOprtDef; ///< Postfix operator callbacks
@ -304,14 +278,14 @@ private:
string_type m_sOprtChars; ///< Charset for postfix/ binary operator tokens
string_type m_sInfixOprtChars; ///< Charset for infix operator tokens
mutable int m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses
mutable int
m_nIfElseCounter; ///< Internal counter for keeping track of nested if-then-else clauses
// items merely used for caching state information
mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine
mutable valbuf_type
m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine
mutable int m_nFinalResultIdx;
};
} // namespace mu
#endif

View file

@ -26,8 +26,8 @@
#define MU_PARSER_BYTECODE_H
#include <cassert>
#include <string>
#include <stack>
#include <string>
#include <vector>
#include "muParserDef.h"
@ -38,24 +38,20 @@
\brief Definition of the parser bytecode class.
*/
namespace mu
{
struct SToken
{
namespace mu {
struct SToken {
ECmdCode Cmd;
int StackPos;
union
{
struct //SValData
union {
struct // SValData
{
value_type *ptr;
value_type data;
value_type data2;
} Val;
struct //SFunData
struct // SFunData
{
// Note: generic_fun_type is merely a placeholder. The real type could be
// anything between gun_type1 and fun_type9. I can't use a void
@ -66,28 +62,25 @@ namespace mu
int idx;
} Fun;
struct //SOprtData
struct // SOprtData
{
value_type *ptr;
int offset;
} Oprt;
};
};
};
/** \brief Bytecode implementation of the Math Parser.
/** \brief Bytecode implementation of the Math Parser.
The bytecode contains the formula converted to revers polish notation stored in a continious
memory area. Associated with this data are operator codes, variable pointers, constant
values and function pointers. Those are necessary in order to calculate the result.
All those data items will be casted to the underlying datatype of the bytecode.
The bytecode contains the formula converted to revers polish notation stored in a continious
memory area. Associated with this data are operator codes, variable pointers, constant
values and function pointers. Those are necessary in order to calculate the result.
All those data items will be casted to the underlying datatype of the bytecode.
\author (C) 2004-2013 Ingo Berg
\author (C) 2004-2013 Ingo Berg
*/
class ParserByteCode
{
private:
class ParserByteCode {
private:
/** \brief Token type for internal use only. */
typedef ParserToken<value_type, string_type> token_type;
@ -107,11 +100,10 @@ private:
void ConstantFolding(ECmdCode a_Oprt);
public:
public:
ParserByteCode();
ParserByteCode(const ParserByteCode &a_ByteCode);
ParserByteCode& operator=(const ParserByteCode &a_ByteCode);
ParserByteCode &operator=(const ParserByteCode &a_ByteCode);
void Assign(const ParserByteCode &a_ByteCode);
void AddVar(value_type *a_pVar);
@ -130,12 +122,10 @@ public:
std::size_t GetMaxStackSize() const;
std::size_t GetSize() const;
const SToken* GetBase() const;
const SToken *GetBase() const;
void AsciiDump();
};
} // namespace mu
#endif

View file

@ -32,8 +32,7 @@
\brief Definition of the parser callback class.
*/
namespace mu
{
namespace mu {
/** \brief Encapsulation of prototypes for a numerical parser function.
@ -47,12 +46,13 @@ namespace mu
\author (C) 2004-2011 Ingo Berg
*/
class ParserCallback
{
public:
class ParserCallback {
public:
ParserCallback(fun_type0 a_pFun, bool a_bAllowOpti);
ParserCallback(fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec = -1, ECmdCode a_iCode=cmFUNC);
ParserCallback(fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec, EOprtAssociativity a_eAssociativity);
ParserCallback(fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec = -1,
ECmdCode a_iCode = cmFUNC);
ParserCallback(fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec,
EOprtAssociativity a_eAssociativity);
ParserCallback(fun_type2 a_pFun, bool a_bAllowOpti);
ParserCallback(fun_type3 a_pFun, bool a_bAllowOpti);
ParserCallback(fun_type4 a_pFun, bool a_bAllowOpti);
@ -80,7 +80,7 @@ public:
ParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti);
ParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti);
ParserCallback();
ParserCallback(const ParserCallback &a_Fun);
ParserCallback(const ParserCallback& a_Fun);
ParserCallback* Clone() const;
@ -92,8 +92,8 @@ public:
EOprtAssociativity GetAssociativity() const;
int GetArgc() const;
private:
void *m_pFun; ///< Pointer to the callback function, casted to void
private:
void* m_pFun; ///< Pointer to the callback function, casted to void
/** \brief Number of numeric function arguments
@ -115,4 +115,3 @@ typedef std::map<string_type, ParserCallback> funmap_type;
} // namespace mu
#endif

View file

@ -26,19 +26,17 @@
#define MU_PARSER_DLL_H
#if defined(WIN32) || defined(_WIN32)
#ifdef MUPARSERLIB_EXPORTS
#define API_EXPORT(TYPE) __declspec(dllexport) TYPE __cdecl
#else
#define API_EXPORT(TYPE) __declspec(dllimport) TYPE __cdecl
#endif
#ifdef MUPARSERLIB_EXPORTS
#define API_EXPORT(TYPE) __declspec(dllexport) TYPE __cdecl
#else
#define API_EXPORT(TYPE) TYPE
#define API_EXPORT(TYPE) __declspec(dllimport) TYPE __cdecl
#endif
#else
#define API_EXPORT(TYPE) TYPE
#endif
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
/** \file
@ -46,12 +44,12 @@ extern "C"
*/
// Basic types
typedef void* muParserHandle_t; // parser handle
typedef void *muParserHandle_t; // parser handle
#ifndef _UNICODE
typedef char muChar_t; // character type
typedef char muChar_t; // character type
#else
typedef wchar_t muChar_t; // character type
typedef wchar_t muChar_t; // character type
#endif
typedef int muBool_t; // boolean type
@ -59,40 +57,52 @@ typedef int muInt_t; // integer type
typedef double muFloat_t; // floating point type
// function types for calculation
typedef muFloat_t (*muFun0_t )();
typedef muFloat_t (*muFun1_t )(muFloat_t);
typedef muFloat_t (*muFun2_t )(muFloat_t, muFloat_t);
typedef muFloat_t (*muFun3_t )(muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muFun4_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muFun5_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muFun6_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muFun7_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muFun8_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muFun9_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muFun10_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muFun0_t)();
typedef muFloat_t (*muFun1_t)(muFloat_t);
typedef muFloat_t (*muFun2_t)(muFloat_t, muFloat_t);
typedef muFloat_t (*muFun3_t)(muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muFun4_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muFun5_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muFun6_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muFun7_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t,
muFloat_t);
typedef muFloat_t (*muFun8_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t,
muFloat_t, muFloat_t);
typedef muFloat_t (*muFun9_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t,
muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muFun10_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t,
muFloat_t, muFloat_t, muFloat_t, muFloat_t);
// Function prototypes for bulkmode functions
typedef muFloat_t (*muBulkFun0_t )(int, int);
typedef muFloat_t (*muBulkFun1_t )(int, int, muFloat_t);
typedef muFloat_t (*muBulkFun2_t )(int, int, muFloat_t, muFloat_t);
typedef muFloat_t (*muBulkFun3_t )(int, int, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muBulkFun4_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muBulkFun5_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muBulkFun6_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muBulkFun7_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muBulkFun8_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muBulkFun9_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muBulkFun10_t)(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muBulkFun0_t)(int, int);
typedef muFloat_t (*muBulkFun1_t)(int, int, muFloat_t);
typedef muFloat_t (*muBulkFun2_t)(int, int, muFloat_t, muFloat_t);
typedef muFloat_t (*muBulkFun3_t)(int, int, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muBulkFun4_t)(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muBulkFun5_t)(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muBulkFun6_t)(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t,
muFloat_t);
typedef muFloat_t (*muBulkFun7_t)(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t,
muFloat_t, muFloat_t);
typedef muFloat_t (*muBulkFun8_t)(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t,
muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muBulkFun9_t)(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t,
muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muBulkFun10_t)(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t,
muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t);
typedef muFloat_t (*muMultFun_t)(const muFloat_t*, muInt_t);
typedef muFloat_t (*muStrFun1_t)(const muChar_t*);
typedef muFloat_t (*muStrFun2_t)(const muChar_t*, muFloat_t);
typedef muFloat_t (*muStrFun3_t)(const muChar_t*, muFloat_t, muFloat_t);
typedef muFloat_t (*muMultFun_t)(const muFloat_t *, muInt_t);
typedef muFloat_t (*muStrFun1_t)(const muChar_t *);
typedef muFloat_t (*muStrFun2_t)(const muChar_t *, muFloat_t);
typedef muFloat_t (*muStrFun3_t)(const muChar_t *, muFloat_t, muFloat_t);
// Functions for parser management
typedef void (*muErrorHandler_t)(muParserHandle_t a_hParser); // [optional] callback to an error handler
typedef muFloat_t* (*muFacFun_t)(const muChar_t*, void*); // [optional] callback for creating new variables
typedef muInt_t (*muIdentFun_t)(const muChar_t*, muInt_t*, muFloat_t*); // [optional] value identification callbacks
typedef void (*muErrorHandler_t)(
muParserHandle_t a_hParser); // [optional] callback to an error handler
typedef muFloat_t *(*muFacFun_t)(const muChar_t *,
void *); // [optional] callback for creating new variables
typedef muInt_t (*muIdentFun_t)(const muChar_t *, muInt_t *,
muFloat_t *); // [optional] value identification callbacks
//-----------------------------------------------------------------------------------------------------
// Constants
@ -110,95 +120,120 @@ static const int muBASETYPE_INT = 1;
//
//-----------------------------------------------------------------------------------------------------
// Basic operations / initialization
API_EXPORT(muParserHandle_t) mupCreate(int nBaseType);
API_EXPORT(void) mupRelease(muParserHandle_t a_hParser);
API_EXPORT(const muChar_t*) mupGetExpr(muParserHandle_t a_hParser);
API_EXPORT(const muChar_t *) mupGetExpr(muParserHandle_t a_hParser);
API_EXPORT(void) mupSetExpr(muParserHandle_t a_hParser, const muChar_t *a_szExpr);
API_EXPORT(void) mupSetVarFactory(muParserHandle_t a_hParser, muFacFun_t a_pFactory, void* pUserData);
API_EXPORT(const muChar_t*) mupGetVersion(muParserHandle_t a_hParser);
API_EXPORT(void)
mupSetVarFactory(muParserHandle_t a_hParser, muFacFun_t a_pFactory, void *pUserData);
API_EXPORT(const muChar_t *) mupGetVersion(muParserHandle_t a_hParser);
API_EXPORT(muFloat_t) mupEval(muParserHandle_t a_hParser);
API_EXPORT(muFloat_t*) mupEvalMulti(muParserHandle_t a_hParser, int *nNum);
API_EXPORT(muFloat_t *) mupEvalMulti(muParserHandle_t a_hParser, int *nNum);
API_EXPORT(void) mupEvalBulk(muParserHandle_t a_hParser, muFloat_t *a_fResult, int nSize);
// Defining callbacks / variables / constants
API_EXPORT(void) mupDefineFun0(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun0_t a_pFun, muBool_t a_bOptimize);
API_EXPORT(void) mupDefineFun1(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun1_t a_pFun, muBool_t a_bOptimize);
API_EXPORT(void) mupDefineFun2(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun2_t a_pFun, muBool_t a_bOptimize);
API_EXPORT(void) mupDefineFun3(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun3_t a_pFun, muBool_t a_bOptimize);
API_EXPORT(void) mupDefineFun4(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun4_t a_pFun, muBool_t a_bOptimize);
API_EXPORT(void) mupDefineFun5(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun5_t a_pFun, muBool_t a_bOptimize);
API_EXPORT(void) mupDefineFun6(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun6_t a_pFun, muBool_t a_bOptimize);
API_EXPORT(void) mupDefineFun7(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun7_t a_pFun, muBool_t a_bOptimize);
API_EXPORT(void) mupDefineFun8(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun8_t a_pFun, muBool_t a_bOptimize);
API_EXPORT(void) mupDefineFun9(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun9_t a_pFun, muBool_t a_bOptimize);
API_EXPORT(void) mupDefineFun10(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun10_t a_pFun, muBool_t a_bOptimize);
API_EXPORT(void)
mupDefineFun0(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun0_t a_pFun,
muBool_t a_bOptimize);
API_EXPORT(void)
mupDefineFun1(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun1_t a_pFun,
muBool_t a_bOptimize);
API_EXPORT(void)
mupDefineFun2(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun2_t a_pFun,
muBool_t a_bOptimize);
API_EXPORT(void)
mupDefineFun3(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun3_t a_pFun,
muBool_t a_bOptimize);
API_EXPORT(void)
mupDefineFun4(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun4_t a_pFun,
muBool_t a_bOptimize);
API_EXPORT(void)
mupDefineFun5(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun5_t a_pFun,
muBool_t a_bOptimize);
API_EXPORT(void)
mupDefineFun6(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun6_t a_pFun,
muBool_t a_bOptimize);
API_EXPORT(void)
mupDefineFun7(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun7_t a_pFun,
muBool_t a_bOptimize);
API_EXPORT(void)
mupDefineFun8(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun8_t a_pFun,
muBool_t a_bOptimize);
API_EXPORT(void)
mupDefineFun9(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun9_t a_pFun,
muBool_t a_bOptimize);
API_EXPORT(void)
mupDefineFun10(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun10_t a_pFun,
muBool_t a_bOptimize);
// Defining bulkmode functions
API_EXPORT(void) mupDefineBulkFun0(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun0_t a_pFun);
API_EXPORT(void) mupDefineBulkFun1(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun1_t a_pFun);
API_EXPORT(void) mupDefineBulkFun2(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun2_t a_pFun);
API_EXPORT(void) mupDefineBulkFun3(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun3_t a_pFun);
API_EXPORT(void) mupDefineBulkFun4(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun4_t a_pFun);
API_EXPORT(void) mupDefineBulkFun5(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun5_t a_pFun);
API_EXPORT(void) mupDefineBulkFun6(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun6_t a_pFun);
API_EXPORT(void) mupDefineBulkFun7(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun7_t a_pFun);
API_EXPORT(void) mupDefineBulkFun8(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun8_t a_pFun);
API_EXPORT(void) mupDefineBulkFun9(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun9_t a_pFun);
API_EXPORT(void) mupDefineBulkFun10(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun10_t a_pFun);
API_EXPORT(void)
mupDefineBulkFun0(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun0_t a_pFun);
API_EXPORT(void)
mupDefineBulkFun1(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun1_t a_pFun);
API_EXPORT(void)
mupDefineBulkFun2(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun2_t a_pFun);
API_EXPORT(void)
mupDefineBulkFun3(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun3_t a_pFun);
API_EXPORT(void)
mupDefineBulkFun4(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun4_t a_pFun);
API_EXPORT(void)
mupDefineBulkFun5(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun5_t a_pFun);
API_EXPORT(void)
mupDefineBulkFun6(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun6_t a_pFun);
API_EXPORT(void)
mupDefineBulkFun7(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun7_t a_pFun);
API_EXPORT(void)
mupDefineBulkFun8(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun8_t a_pFun);
API_EXPORT(void)
mupDefineBulkFun9(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun9_t a_pFun);
API_EXPORT(void)
mupDefineBulkFun10(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun10_t a_pFun);
// string functions
API_EXPORT(void) mupDefineStrFun1(muParserHandle_t a_hParser, const muChar_t *a_szName, muStrFun1_t a_pFun);
API_EXPORT(void) mupDefineStrFun2(muParserHandle_t a_hParser, const muChar_t *a_szName, muStrFun2_t a_pFun);
API_EXPORT(void) mupDefineStrFun3(muParserHandle_t a_hParser, const muChar_t *a_szName, muStrFun3_t a_pFun);
API_EXPORT(void)
mupDefineStrFun1(muParserHandle_t a_hParser, const muChar_t *a_szName, muStrFun1_t a_pFun);
API_EXPORT(void)
mupDefineStrFun2(muParserHandle_t a_hParser, const muChar_t *a_szName, muStrFun2_t a_pFun);
API_EXPORT(void)
mupDefineStrFun3(muParserHandle_t a_hParser, const muChar_t *a_szName, muStrFun3_t a_pFun);
API_EXPORT(void) mupDefineMultFun( muParserHandle_t a_hParser,
const muChar_t* a_szName,
muMultFun_t a_pFun,
API_EXPORT(void)
mupDefineMultFun(muParserHandle_t a_hParser, const muChar_t *a_szName, muMultFun_t a_pFun,
muBool_t a_bOptimize);
API_EXPORT(void) mupDefineOprt( muParserHandle_t a_hParser,
const muChar_t* a_szName,
muFun2_t a_pFun,
muInt_t a_nPrec,
muInt_t a_nOprtAsct,
API_EXPORT(void)
mupDefineOprt(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun2_t a_pFun,
muInt_t a_nPrec, muInt_t a_nOprtAsct, muBool_t a_bOptimize);
API_EXPORT(void)
mupDefineConst(muParserHandle_t a_hParser, const muChar_t *a_szName, muFloat_t a_fVal);
API_EXPORT(void)
mupDefineStrConst(muParserHandle_t a_hParser, const muChar_t *a_szName, const muChar_t *a_sVal);
API_EXPORT(void)
mupDefineVar(muParserHandle_t a_hParser, const muChar_t *a_szName, muFloat_t *a_fVar);
API_EXPORT(void)
mupDefineBulkVar(muParserHandle_t a_hParser, const muChar_t *a_szName, muFloat_t *a_fVar);
API_EXPORT(void)
mupDefinePostfixOprt(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun1_t a_pOprt,
muBool_t a_bOptimize);
API_EXPORT(void) mupDefineConst( muParserHandle_t a_hParser,
const muChar_t* a_szName,
muFloat_t a_fVal );
API_EXPORT(void) mupDefineStrConst( muParserHandle_t a_hParser,
const muChar_t* a_szName,
const muChar_t *a_sVal );
API_EXPORT(void) mupDefineVar( muParserHandle_t a_hParser,
const muChar_t* a_szName,
muFloat_t *a_fVar);
API_EXPORT(void) mupDefineBulkVar( muParserHandle_t a_hParser,
const muChar_t* a_szName,
muFloat_t *a_fVar);
API_EXPORT(void) mupDefinePostfixOprt( muParserHandle_t a_hParser,
const muChar_t* a_szName,
muFun1_t a_pOprt,
muBool_t a_bOptimize);
API_EXPORT(void) mupDefineInfixOprt( muParserHandle_t a_hParser,
const muChar_t* a_szName,
muFun1_t a_pOprt,
API_EXPORT(void)
mupDefineInfixOprt(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun1_t a_pOprt,
muBool_t a_bOptimize);
// Define character sets for identifiers
API_EXPORT(void) mupDefineNameChars(muParserHandle_t a_hParser, const muChar_t* a_szCharset);
API_EXPORT(void) mupDefineOprtChars(muParserHandle_t a_hParser, const muChar_t* a_szCharset);
API_EXPORT(void) mupDefineInfixOprtChars(muParserHandle_t a_hParser, const muChar_t* a_szCharset);
API_EXPORT(void) mupDefineNameChars(muParserHandle_t a_hParser, const muChar_t *a_szCharset);
API_EXPORT(void) mupDefineOprtChars(muParserHandle_t a_hParser, const muChar_t *a_szCharset);
API_EXPORT(void) mupDefineInfixOprtChars(muParserHandle_t a_hParser, const muChar_t *a_szCharset);
// Remove all / single variables
API_EXPORT(void) mupRemoveVar(muParserHandle_t a_hParser, const muChar_t* a_szName);
API_EXPORT(void) mupRemoveVar(muParserHandle_t a_hParser, const muChar_t *a_szName);
API_EXPORT(void) mupClearVar(muParserHandle_t a_hParser);
API_EXPORT(void) mupClearConst(muParserHandle_t a_hParser);
API_EXPORT(void) mupClearOprt(muParserHandle_t a_hParser);
@ -208,9 +243,15 @@ API_EXPORT(void) mupClearFun(muParserHandle_t a_hParser);
API_EXPORT(int) mupGetExprVarNum(muParserHandle_t a_hParser);
API_EXPORT(int) mupGetVarNum(muParserHandle_t a_hParser);
API_EXPORT(int) mupGetConstNum(muParserHandle_t a_hParser);
API_EXPORT(void) mupGetExprVar(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t** a_pszName, muFloat_t** a_pVar);
API_EXPORT(void) mupGetVar(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t** a_pszName, muFloat_t** a_pVar);
API_EXPORT(void) mupGetConst(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t** a_pszName, muFloat_t* a_pVar);
API_EXPORT(void)
mupGetExprVar(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t **a_pszName,
muFloat_t **a_pVar);
API_EXPORT(void)
mupGetVar(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t **a_pszName,
muFloat_t **a_pVar);
API_EXPORT(void)
mupGetConst(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t **a_pszName,
muFloat_t *a_pVar);
API_EXPORT(void) mupSetArgSep(muParserHandle_t a_hParser, const muChar_t cArgSep);
API_EXPORT(void) mupSetDecSep(muParserHandle_t a_hParser, const muChar_t cArgSep);
API_EXPORT(void) mupSetThousandsSep(muParserHandle_t a_hParser, const muChar_t cArgSep);
@ -223,16 +264,16 @@ API_EXPORT(void) mupAddValIdent(muParserHandle_t a_hParser, muIdentFun_t);
API_EXPORT(muBool_t) mupError(muParserHandle_t a_hParser);
API_EXPORT(void) mupErrorReset(muParserHandle_t a_hParser);
API_EXPORT(void) mupSetErrorHandler(muParserHandle_t a_hParser, muErrorHandler_t a_pErrHandler);
API_EXPORT(const muChar_t*) mupGetErrorMsg(muParserHandle_t a_hParser);
API_EXPORT(const muChar_t *) mupGetErrorMsg(muParserHandle_t a_hParser);
API_EXPORT(muInt_t) mupGetErrorCode(muParserHandle_t a_hParser);
API_EXPORT(muInt_t) mupGetErrorPos(muParserHandle_t a_hParser);
API_EXPORT(const muChar_t*) mupGetErrorToken(muParserHandle_t a_hParser);
//API_EXPORT(const muChar_t*) mupGetErrorExpr(muParserHandle_t a_hParser);
API_EXPORT(const muChar_t *) mupGetErrorToken(muParserHandle_t a_hParser);
// API_EXPORT(const muChar_t*) mupGetErrorExpr(muParserHandle_t a_hParser);
// This is used for .NET only. It creates a new variable allowing the dll to
// manage the variable rather than the .NET garbage collector.
API_EXPORT(muFloat_t*) mupCreateVar();
API_EXPORT(void) mupReleaseVar(muFloat_t*);
API_EXPORT(muFloat_t *) mupCreateVar();
API_EXPORT(void) mupReleaseVar(muFloat_t *);
#ifdef __cplusplus
}

View file

@ -26,9 +26,9 @@
#define MUP_DEF_H
#include <iostream>
#include <string>
#include <sstream>
#include <map>
#include <sstream>
#include <string>
#include "muParserFixes.h"
@ -41,7 +41,8 @@
#define MUP_CHARS _T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
/** \brief If this macro is defined mathematical exceptions (div by zero) will be thrown as exceptions. */
/** \brief If this macro is defined mathematical exceptions (div by zero) will be thrown as
* exceptions. */
//#define MUP_MATH_EXCEPTIONS
/** \brief Define the base datatype for values.
@ -52,96 +53,79 @@
#define MUP_BASETYPE double
#if defined(_UNICODE)
/** \brief Definition of the basic parser string type. */
#define MUP_STRING_TYPE std::wstring
/** \brief Definition of the basic parser string type. */
#define MUP_STRING_TYPE std::wstring
#if !defined(_T)
#define _T(x) L##x
#endif // not defined _T
#if !defined(_T)
#define _T(x) L##x
#endif // not defined _T
#else
#ifndef _T
#define _T(x) x
#endif
#ifndef _T
#define _T(x) x
#endif
/** \brief Definition of the basic parser string type. */
#define MUP_STRING_TYPE std::string
/** \brief Definition of the basic parser string type. */
#define MUP_STRING_TYPE std::string
#endif
#if defined(_DEBUG)
/** \brief Debug macro to force an abortion of the programm with a certain message.
*/
#define MUP_FAIL(MSG) \
/** \brief Debug macro to force an abortion of the programm with a certain message.
*/
#define MUP_FAIL(MSG) \
{ \
bool MSG=false; \
bool MSG = false; \
assert(MSG); \
}
/** \brief An assertion that does not kill the program.
/** \brief An assertion that does not kill the program.
This macro is neutralised in UNICODE builds. It's
too difficult to translate.
*/
#define MUP_ASSERT(COND) \
if (!(COND)) \
{ \
*/
#define MUP_ASSERT(COND) \
if (!(COND)) { \
stringstream_type ss; \
ss << _T("Assertion \"") _T(#COND) _T("\" failed: ") \
<< __FILE__ << _T(" line ") \
ss << _T("Assertion \"") _T(#COND) _T("\" failed: ") << __FILE__ << _T(" line ") \
<< __LINE__ << _T("."); \
throw ParserError( ss.str() ); \
throw ParserError(ss.str()); \
}
#else
#define MUP_FAIL(MSG)
#define MUP_ASSERT(COND)
#define MUP_FAIL(MSG)
#define MUP_ASSERT(COND)
#endif
namespace mu
{
namespace mu {
#if defined(_UNICODE)
//------------------------------------------------------------------------------
/** \brief Encapsulate wcout. */
inline std::wostream& console()
{
return std::wcout;
}
//------------------------------------------------------------------------------
/** \brief Encapsulate wcout. */
inline std::wostream& console() { return std::wcout; }
/** \brief Encapsulate cin. */
inline std::wistream& console_in()
{
return std::wcin;
}
/** \brief Encapsulate cin. */
inline std::wistream& console_in() { return std::wcin; }
#else
/** \brief Encapsulate cout.
/** \brief Encapsulate cout.
Used for supporting UNICODE more easily.
*/
inline std::ostream& console()
{
return std::cout;
}
*/
inline std::ostream& console() { return std::cout; }
/** \brief Encapsulate cin.
/** \brief Encapsulate cin.
Used for supporting UNICODE more easily.
*/
inline std::istream& console_in()
{
return std::cin;
}
*/
inline std::istream& console_in() { return std::cin; }
#endif
//------------------------------------------------------------------------------
/** \brief Bytecode values.
//------------------------------------------------------------------------------
/** \brief Bytecode values.
\attention The order of the operator entries must match the order in ParserBase::c_DefaultOprt!
*/
enum ECmdCode
{
*/
enum ECmdCode {
// The following are codes for built in binary operators
// apart from built in operators the user has the opportunity to
// add user defined operators.
@ -178,45 +162,35 @@ namespace mu
// operators and functions
cmFUNC, ///< Code for a generic function item
cmFUNC_STR, ///< Code for a function with a string parameter
cmFUNC_BULK, ///< Special callbacks for Bulk mode with an additional parameter for the bulk index
cmFUNC_BULK, ///< Special callbacks for Bulk mode with an additional parameter for the bulk
///index
cmSTRING, ///< Code for a string token
cmOPRT_BIN, ///< user defined binary operator
cmOPRT_POSTFIX, ///< code for postfix operators
cmOPRT_INFIX, ///< code for infix operators
cmEND, ///< end of formula
cmUNKNOWN ///< uninitialized item
};
};
//------------------------------------------------------------------------------
/** \brief Types internally used by the parser.
*/
enum ETypeCode
{
//------------------------------------------------------------------------------
/** \brief Types internally used by the parser.
*/
enum ETypeCode {
tpSTR = 0, ///< String type (Function arguments and constants only, no string variables)
tpDBL = 1, ///< Floating point variables
tpVOID = 2 ///< Undefined type.
};
};
//------------------------------------------------------------------------------
enum EParserVersionInfo
{
pviBRIEF,
pviFULL
};
//------------------------------------------------------------------------------
enum EParserVersionInfo { pviBRIEF, pviFULL };
//------------------------------------------------------------------------------
/** \brief Parser operator precedence values. */
enum EOprtAssociativity
{
oaLEFT = 0,
oaRIGHT = 1,
oaNONE = 2
};
//------------------------------------------------------------------------------
/** \brief Parser operator precedence values. */
enum EOprtAssociativity { oaLEFT = 0, oaRIGHT = 1, oaNONE = 2 };
//------------------------------------------------------------------------------
/** \brief Parser operator precedence values. */
enum EOprtPrecedence
{
//------------------------------------------------------------------------------
/** \brief Parser operator precedence values. */
enum EOprtPrecedence {
// binary operators
prLOR = 1,
prLAND = 2,
@ -229,134 +203,144 @@ namespace mu
// infix operators
prINFIX = 6, ///< Signs have a higher priority than ADD_SUB, but lower than power operator
prPOSTFIX = 6 ///< Postfix operator priority (currently unused)
};
};
//------------------------------------------------------------------------------
// basic types
//------------------------------------------------------------------------------
// basic types
/** \brief The numeric datatype used by the parser.
/** \brief The numeric datatype used by the parser.
Normally this is a floating point type either single or double precision.
*/
typedef MUP_BASETYPE value_type;
*/
typedef MUP_BASETYPE value_type;
/** \brief The stringtype used by the parser.
/** \brief The stringtype used by the parser.
Depends on wether UNICODE is used or not.
*/
typedef MUP_STRING_TYPE string_type;
*/
typedef MUP_STRING_TYPE string_type;
/** \brief The character type used by the parser.
/** \brief The character type used by the parser.
Depends on wether UNICODE is used or not.
*/
typedef string_type::value_type char_type;
*/
typedef string_type::value_type char_type;
/** \brief Typedef for easily using stringstream that respect the parser stringtype. */
typedef std::basic_stringstream<char_type,
std::char_traits<char_type>,
std::allocator<char_type> > stringstream_type;
/** \brief Typedef for easily using stringstream that respect the parser stringtype. */
typedef std::basic_stringstream<char_type, std::char_traits<char_type>, std::allocator<char_type> >
stringstream_type;
// Data container types
// Data container types
/** \brief Type used for storing variables. */
typedef std::map<string_type, value_type*> varmap_type;
/** \brief Type used for storing variables. */
typedef std::map<string_type, value_type*> varmap_type;
/** \brief Type used for storing constants. */
typedef std::map<string_type, value_type> valmap_type;
/** \brief Type used for storing constants. */
typedef std::map<string_type, value_type> valmap_type;
/** \brief Type for assigning a string name to an index in the internal string table. */
typedef std::map<string_type, std::size_t> strmap_type;
/** \brief Type for assigning a string name to an index in the internal string table. */
typedef std::map<string_type, std::size_t> strmap_type;
// Parser callbacks
// Parser callbacks
/** \brief Callback type used for functions without arguments. */
typedef value_type (*generic_fun_type)();
/** \brief Callback type used for functions without arguments. */
typedef value_type (*generic_fun_type)();
/** \brief Callback type used for functions without arguments. */
typedef value_type (*fun_type0)();
/** \brief Callback type used for functions without arguments. */
typedef value_type (*fun_type0)();
/** \brief Callback type used for functions with a single arguments. */
typedef value_type (*fun_type1)(value_type);
/** \brief Callback type used for functions with a single arguments. */
typedef value_type (*fun_type1)(value_type);
/** \brief Callback type used for functions with two arguments. */
typedef value_type (*fun_type2)(value_type, value_type);
/** \brief Callback type used for functions with two arguments. */
typedef value_type (*fun_type2)(value_type, value_type);
/** \brief Callback type used for functions with three arguments. */
typedef value_type (*fun_type3)(value_type, value_type, value_type);
/** \brief Callback type used for functions with three arguments. */
typedef value_type (*fun_type3)(value_type, value_type, value_type);
/** \brief Callback type used for functions with four arguments. */
typedef value_type (*fun_type4)(value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with four arguments. */
typedef value_type (*fun_type4)(value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type5)(value_type, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type5)(value_type, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type6)(value_type, value_type, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type6)(value_type, value_type, value_type, value_type, value_type,
value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type7)(value_type, value_type, value_type, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type7)(value_type, value_type, value_type, value_type, value_type,
value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type8)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type8)(value_type, value_type, value_type, value_type, value_type,
value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type9)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type9)(value_type, value_type, value_type, value_type, value_type,
value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type10)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*fun_type10)(value_type, value_type, value_type, value_type, value_type,
value_type, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions without arguments. */
typedef value_type (*bulkfun_type0)(int, int);
/** \brief Callback type used for functions without arguments. */
typedef value_type (*bulkfun_type0)(int, int);
/** \brief Callback type used for functions with a single arguments. */
typedef value_type (*bulkfun_type1)(int, int, value_type);
/** \brief Callback type used for functions with a single arguments. */
typedef value_type (*bulkfun_type1)(int, int, value_type);
/** \brief Callback type used for functions with two arguments. */
typedef value_type (*bulkfun_type2)(int, int, value_type, value_type);
/** \brief Callback type used for functions with two arguments. */
typedef value_type (*bulkfun_type2)(int, int, value_type, value_type);
/** \brief Callback type used for functions with three arguments. */
typedef value_type (*bulkfun_type3)(int, int, value_type, value_type, value_type);
/** \brief Callback type used for functions with three arguments. */
typedef value_type (*bulkfun_type3)(int, int, value_type, value_type, value_type);
/** \brief Callback type used for functions with four arguments. */
typedef value_type (*bulkfun_type4)(int, int, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with four arguments. */
typedef value_type (*bulkfun_type4)(int, int, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type5)(int, int, value_type, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type5)(int, int, value_type, value_type, value_type, value_type,
value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type6)(int, int, value_type, value_type, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type6)(int, int, value_type, value_type, value_type, value_type,
value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type7)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type7)(int, int, value_type, value_type, value_type, value_type,
value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type8)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type8)(int, int, value_type, value_type, value_type, value_type,
value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type9)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type9)(int, int, value_type, value_type, value_type, value_type,
value_type, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type10)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);
/** \brief Callback type used for functions with five arguments. */
typedef value_type (*bulkfun_type10)(int, int, value_type, value_type, value_type, value_type,
value_type, value_type, value_type, value_type, value_type,
value_type);
/** \brief Callback type used for functions with a variable argument list. */
typedef value_type (*multfun_type)(const value_type*, int);
/** \brief Callback type used for functions with a variable argument list. */
typedef value_type (*multfun_type)(const value_type*, int);
/** \brief Callback type used for functions taking a string as an argument. */
typedef value_type (*strfun_type1)(const char_type*);
/** \brief Callback type used for functions taking a string as an argument. */
typedef value_type (*strfun_type1)(const char_type*);
/** \brief Callback type used for functions taking a string and a value as arguments. */
typedef value_type (*strfun_type2)(const char_type*, value_type);
/** \brief Callback type used for functions taking a string and a value as arguments. */
typedef value_type (*strfun_type2)(const char_type*, value_type);
/** \brief Callback type used for functions taking a string and two values as arguments. */
typedef value_type (*strfun_type3)(const char_type*, value_type, value_type);
/** \brief Callback type used for functions taking a string and two values as arguments. */
typedef value_type (*strfun_type3)(const char_type*, value_type, value_type);
/** \brief Callback used for functions that identify values in a string. */
typedef int (*identfun_type)(const char_type *sExpr, int *nPos, value_type *fVal);
/** \brief Callback used for functions that identify values in a string. */
typedef int (*identfun_type)(const char_type* sExpr, int* nPos, value_type* fVal);
/** \brief Callback used for variable creation factory functions. */
typedef value_type* (*facfun_type)(const char_type*, void*);
/** \brief Callback used for variable creation factory functions. */
typedef value_type* (*facfun_type)(const char_type*, void*);
} // end of namespace
#endif

View file

@ -27,11 +27,11 @@
#define MU_PARSER_ERROR_H
#include <cassert>
#include <memory>
#include <sstream>
#include <stdexcept>
#include <string>
#include <sstream>
#include <vector>
#include <memory>
#include "muParserDef.h"
@ -39,12 +39,10 @@
\brief This file defines the error class used by the parser.
*/
namespace mu
{
namespace mu {
/** \brief Error codes. */
enum EErrorCodes
{
enum EErrorCodes {
// Formula syntax errors
ecUNEXPECTED_OPERATOR = 0, ///< Unexpected binary operator found
ecUNASSIGNABLE_TOKEN = 1, ///< Token cant be identified.
@ -56,13 +54,15 @@ enum EErrorCodes
ecUNEXPECTED_PARENS = 7, ///< Unexpected Parenthesis, opening or closing
ecUNEXPECTED_STR = 8, ///< A string has been found at an inapropriate position
ecSTRING_EXPECTED = 9, ///< A string function has been called with a different type of argument
ecVAL_EXPECTED = 10, ///< A numerical function has been called with a non value type of argument
ecVAL_EXPECTED =
10, ///< A numerical function has been called with a non value type of argument
ecMISSING_PARENS = 11, ///< Missing parens. (Example: "3*sin(3")
ecUNEXPECTED_FUN = 12, ///< Unexpected function found. (Example: "sin(8)cos(9)")
ecUNTERMINATED_STRING = 13, ///< unterminated string constant. (Example: "3*valueof("hello)")
ecTOO_MANY_PARAMS = 14, ///< Too many function parameters
ecTOO_FEW_PARAMS = 15, ///< Too few function parameters. (Example: "ite(1<2,2)")
ecOPRT_TYPE_CONFLICT = 16, ///< binary operators may only be applied to value items of the same type
ecOPRT_TYPE_CONFLICT =
16, ///< binary operators may only be applied to value items of the same type
ecSTR_RESULT = 17, ///< result is a string
// Invalid Parser input Parameters
@ -97,21 +97,20 @@ enum EErrorCodes
//---------------------------------------------------------------------------
/** \brief A class that handles the error messages.
*/
class ParserErrorMsg
{
public:
class ParserErrorMsg {
public:
typedef ParserErrorMsg self_type;
ParserErrorMsg& operator=(const ParserErrorMsg &);
ParserErrorMsg(const ParserErrorMsg&);
ParserErrorMsg &operator=(const ParserErrorMsg &);
ParserErrorMsg(const ParserErrorMsg &);
ParserErrorMsg();
~ParserErrorMsg();
static const ParserErrorMsg& Instance();
static const ParserErrorMsg &Instance();
string_type operator[](unsigned a_iIdx) const;
private:
private:
std::vector<string_type> m_vErrMsg; ///< A vector with the predefined error messages
static const self_type m_Instance; ///< The instance pointer
};
@ -122,43 +121,33 @@ private:
Part of the math parser package.
*/
class ParserError
{
private:
class ParserError {
private:
/** \brief Replace all ocuurences of a substring with another string. */
void ReplaceSubString( string_type &strSource,
const string_type &strFind,
void ReplaceSubString(string_type &strSource, const string_type &strFind,
const string_type &strReplaceWith);
void Reset();
public:
public:
ParserError();
explicit ParserError(EErrorCodes a_iErrc);
explicit ParserError(const string_type &sMsg);
ParserError( EErrorCodes a_iErrc,
const string_type &sTok,
const string_type &sFormula = string_type(),
int a_iPos = -1);
ParserError( EErrorCodes a_iErrc,
int a_iPos,
const string_type &sTok);
ParserError( const char_type *a_szMsg,
int a_iPos = -1,
const string_type &sTok = string_type());
ParserError(EErrorCodes a_iErrc, const string_type &sTok,
const string_type &sFormula = string_type(), int a_iPos = -1);
ParserError(EErrorCodes a_iErrc, int a_iPos, const string_type &sTok);
ParserError(const char_type *a_szMsg, int a_iPos = -1, const string_type &sTok = string_type());
ParserError(const ParserError &a_Obj);
ParserError& operator=(const ParserError &a_Obj);
ParserError &operator=(const ParserError &a_Obj);
~ParserError();
void SetFormula(const string_type &a_strFormula);
const string_type& GetExpr() const;
const string_type& GetMsg() const;
const string_type &GetExpr() const;
const string_type &GetMsg() const;
int GetPos() const;
const string_type& GetToken() const;
const string_type &GetToken() const;
EErrorCodes GetCode() const;
private:
private:
string_type m_strMsg; ///< The message string
string_type m_strFormula; ///< Formula string
string_type m_strTok; ///< Token related with the error
@ -170,4 +159,3 @@ private:
} // namespace mu
#endif

View file

@ -45,18 +45,16 @@
// remark #981: operands are evaluated in unspecified order
// disabled -> completely pointless if the functions do not have side effects
//
#pragma warning(disable:981)
#pragma warning(disable : 981)
// remark #383: value copied to temporary, reference to temporary used
#pragma warning(disable:383)
#pragma warning(disable : 383)
// remark #1572: floating-point equality and inequality comparisons are unreliable
// disabled -> everyone knows it, the parser passes this problem
// deliberately to the user
#pragma warning(disable:1572)
#pragma warning(disable : 1572)
#endif
#endif // include guard

View file

@ -26,27 +26,24 @@
#ifndef MU_PARSER_INT_H
#define MU_PARSER_INT_H
#include "muParserBase.h"
#include <vector>
#include "muParserBase.h"
/** \file
\brief Definition of a parser using integer value.
*/
namespace mu
{
namespace mu {
/** \brief Mathematical expressions parser.
This version of the parser handles only integer numbers. It disables the built in operators thus it is
This version of the parser handles only integer numbers. It disables the built in operators thus
it is
slower than muParser. Integer values are stored in the double value_type and converted if needed.
*/
class ParserInt : public ParserBase
{
private:
static int Round(value_type v) { return (int)(v + ((v>=0) ? 0.5 : -0.5) ); };
class ParserInt : public ParserBase {
private:
static int Round(value_type v) { return (int)(v + ((v >= 0) ? 0.5 : -0.5)); };
static value_type Abs(value_type);
static value_type Sign(value_type);
@ -79,37 +76,26 @@ private:
static value_type NotEqual(value_type v1, value_type v2);
static value_type Not(value_type v1);
static int IsHexVal(const char_type* a_szExpr, int *a_iPos, value_type *a_iVal);
static int IsBinVal(const char_type* a_szExpr, int *a_iPos, value_type *a_iVal);
static int IsVal (const char_type* a_szExpr, int *a_iPos, value_type *a_iVal);
static int IsHexVal(const char_type* a_szExpr, int* a_iPos, value_type* a_iVal);
static int IsBinVal(const char_type* a_szExpr, int* a_iPos, value_type* a_iVal);
static int IsVal(const char_type* a_szExpr, int* a_iPos, value_type* a_iVal);
/** \brief A facet class used to change decimal and thousands separator. */
template<class TChar>
class change_dec_sep : public std::numpunct<TChar>
{
template <class TChar>
class change_dec_sep : public std::numpunct<TChar> {
public:
explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3)
:std::numpunct<TChar>()
,m_cDecPoint(cDecSep)
,m_cThousandsSep(cThousandsSep)
,m_nGroup(nGroup)
{}
: std::numpunct<TChar>(),
m_cDecPoint(cDecSep),
m_cThousandsSep(cThousandsSep),
m_nGroup(nGroup) {}
protected:
virtual char_type do_decimal_point() const { return m_cDecPoint; }
virtual char_type do_decimal_point() const
{
return m_cDecPoint;
}
virtual char_type do_thousands_sep() const { return m_cThousandsSep; }
virtual char_type do_thousands_sep() const
{
return m_cThousandsSep;
}
virtual std::string do_grouping() const
{
virtual std::string do_grouping() const {
// fix for issue 4: https://code.google.com/p/muparser/issues/detail?id=4
// courtesy of Jens Bartsch
// original code:
@ -119,13 +105,12 @@ private:
}
private:
int m_nGroup;
char_type m_cDecPoint;
char_type m_cThousandsSep;
};
public:
public:
ParserInt();
virtual void InitFun();
@ -137,4 +122,3 @@ public:
} // namespace mu
#endif

View file

@ -27,8 +27,8 @@
#define MU_PARSER_STACK_H
#include <cassert>
#include <string>
#include <stack>
#include <string>
#include <vector>
#include "muParserError.h"
@ -38,37 +38,30 @@
\brief This file defines the stack used by muparser.
*/
namespace mu
{
namespace mu {
/** \brief Parser stack implementation.
/** \brief Parser stack implementation.
Stack implementation based on a std::stack. The behaviour of pop() had been
slightly changed in order to get an error code if the stack is empty.
The stack is used within the Parser both as a value stack and as an operator stack.
\author (C) 2004-2011 Ingo Berg
*/
template <typename TValueType>
class ParserStack
{
*/
template <typename TValueType>
class ParserStack {
private:
/** \brief Type of the underlying stack implementation. */
typedef std::stack<TValueType, std::vector<TValueType> > impl_type;
impl_type m_Stack; ///< This is the actual stack.
public:
//---------------------------------------------------------------------------
ParserStack() : m_Stack() {}
//---------------------------------------------------------------------------
ParserStack()
:m_Stack()
{}
//---------------------------------------------------------------------------
virtual ~ParserStack()
{}
virtual ~ParserStack() {}
//---------------------------------------------------------------------------
/** \brief Pop a value from the stack.
@ -79,10 +72,8 @@ namespace mu
\throw ParserException in case the stack is empty.
\sa pop(int &a_iErrc)
*/
TValueType pop()
{
if (empty())
throw ParserError( _T("stack is empty.") );
TValueType pop() {
if (empty()) throw ParserError(_T("stack is empty."));
TValueType el = top();
m_Stack.pop();
@ -94,32 +85,20 @@ namespace mu
\param a_Val object to push into the stack.
\throw nothrow
*/
void push(const TValueType& a_Val)
{
m_Stack.push(a_Val);
}
void push(const TValueType& a_Val) { m_Stack.push(a_Val); }
/** \brief Return the number of stored elements. */
unsigned size() const
{
return (unsigned)m_Stack.size();
}
unsigned size() const { return (unsigned)m_Stack.size(); }
/** \brief Returns true if stack is empty false otherwise. */
bool empty() const
{
return m_Stack.empty();
}
bool empty() const { return m_Stack.empty(); }
/** \brief Return reference to the top object in the stack.
The top object is the one pushed most recently.
*/
TValueType& top()
{
return m_Stack.top();
}
};
TValueType& top() { return m_Stack.top(); }
};
} // namespace MathUtils
#endif

View file

@ -4,87 +4,74 @@
#include <cmath>
#include "muParserError.h"
namespace mu {
//-----------------------------------------------------------------------------------------------
//
// Compile time type detection
//
//-----------------------------------------------------------------------------------------------
namespace mu
{
//-----------------------------------------------------------------------------------------------
//
// Compile time type detection
//
//-----------------------------------------------------------------------------------------------
/** \brief A class singling out integer types at compile time using
/** \brief A class singling out integer types at compile time using
template meta programming.
*/
template<typename T>
struct TypeInfo
{
*/
template <typename T>
struct TypeInfo {
static bool IsInteger() { return false; }
};
};
template<>
struct TypeInfo<char>
{
template <>
struct TypeInfo<char> {
static bool IsInteger() { return true; }
};
};
template<>
struct TypeInfo<short>
{
template <>
struct TypeInfo<short> {
static bool IsInteger() { return true; }
};
};
template<>
struct TypeInfo<int>
{
template <>
struct TypeInfo<int> {
static bool IsInteger() { return true; }
};
};
template<>
struct TypeInfo<long>
{
template <>
struct TypeInfo<long> {
static bool IsInteger() { return true; }
};
};
template<>
struct TypeInfo<unsigned char>
{
template <>
struct TypeInfo<unsigned char> {
static bool IsInteger() { return true; }
};
};
template<>
struct TypeInfo<unsigned short>
{
template <>
struct TypeInfo<unsigned short> {
static bool IsInteger() { return true; }
};
};
template<>
struct TypeInfo<unsigned int>
{
template <>
struct TypeInfo<unsigned int> {
static bool IsInteger() { return true; }
};
};
template<>
struct TypeInfo<unsigned long>
{
template <>
struct TypeInfo<unsigned long> {
static bool IsInteger() { return true; }
};
};
//-----------------------------------------------------------------------------------------------
//
// Standard math functions with dummy overload for integer types
//
//-----------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------
//
// Standard math functions with dummy overload for integer types
//
//-----------------------------------------------------------------------------------------------
/** \brief A template class for providing wrappers for essential math functions.
/** \brief A template class for providing wrappers for essential math functions.
This template is spezialized for several types in order to provide a unified interface
for parser internal math function calls regardless of the data type.
*/
template<typename T>
struct MathImpl
{
*/
template <typename T>
struct MathImpl {
static T Sin(T v) { return sin(v); }
static T Cos(T v) { return cos(v); }
static T Tan(T v) { return tan(v); }
@ -99,15 +86,15 @@ namespace mu
static T ACosh(T v) { return log(v + sqrt(v * v - 1)); }
static T ATanh(T v) { return ((T)0.5 * log((1 + v) / (1 - v))); }
static T Log(T v) { return log(v); }
static T Log2(T v) { return log(v)/log((T)2); } // Logarithm base 2
static T Log2(T v) { return log(v) / log((T)2); } // Logarithm base 2
static T Log10(T v) { return log10(v); } // Logarithm base 10
static T Exp(T v) { return exp(v); }
static T Abs(T v) { return (v>=0) ? v : -v; }
static T Abs(T v) { return (v >= 0) ? v : -v; }
static T Sqrt(T v) { return sqrt(v); }
static T Rint(T v) { return floor(v + (T)0.5); }
static T Sign(T v) { return (T)((v<0) ? -1 : (v>0) ? 1 : 0); }
static T Sign(T v) { return (T)((v < 0) ? -1 : (v > 0) ? 1 : 0); }
static T Pow(T v1, T v2) { return std::pow(v1, v2); }
};
};
}
#endif

View file

@ -26,9 +26,9 @@
#ifndef MU_PARSER_TEST_H
#define MU_PARSER_TEST_H
#include <string>
#include <cstdlib>
#include <numeric> // for accumulate
#include <string>
#include "muParser.h"
#include "muParserInt.h"
@ -36,122 +36,117 @@
\brief This file contains the parser test class.
*/
namespace mu
{
/** \brief Namespace for test cases. */
namespace Test
{
//------------------------------------------------------------------------------
/** \brief Test cases for unit testing.
namespace mu {
/** \brief Namespace for test cases. */
namespace Test {
//------------------------------------------------------------------------------
/** \brief Test cases for unit testing.
(C) 2004-2011 Ingo Berg
*/
class ParserTester // final
{
*/
class ParserTester // final
{
private:
static int c_iCount;
// Multiarg callbacks
static value_type f1of1(value_type v) { return v;};
static value_type f1of1(value_type v) { return v; };
static value_type f1of2(value_type v, value_type ) {return v;};
static value_type f2of2(value_type , value_type v) {return v;};
static value_type f1of2(value_type v, value_type) { return v; };
static value_type f2of2(value_type, value_type v) { return v; };
static value_type f1of3(value_type v, value_type , value_type ) {return v;};
static value_type f2of3(value_type , value_type v, value_type ) {return v;};
static value_type f3of3(value_type , value_type , value_type v) {return v;};
static value_type f1of3(value_type v, value_type, value_type) { return v; };
static value_type f2of3(value_type, value_type v, value_type) { return v; };
static value_type f3of3(value_type, value_type, value_type v) { return v; };
static value_type f1of4(value_type v, value_type, value_type , value_type ) {return v;}
static value_type f2of4(value_type , value_type v, value_type , value_type ) {return v;}
static value_type f3of4(value_type , value_type, value_type v, value_type ) {return v;}
static value_type f4of4(value_type , value_type, value_type , value_type v) {return v;}
static value_type f1of4(value_type v, value_type, value_type, value_type) { return v; }
static value_type f2of4(value_type, value_type v, value_type, value_type) { return v; }
static value_type f3of4(value_type, value_type, value_type v, value_type) { return v; }
static value_type f4of4(value_type, value_type, value_type, value_type v) { return v; }
static value_type f1of5(value_type v, value_type, value_type , value_type , value_type ) { return v; }
static value_type f2of5(value_type , value_type v, value_type , value_type , value_type ) { return v; }
static value_type f3of5(value_type , value_type, value_type v, value_type , value_type ) { return v; }
static value_type f4of5(value_type , value_type, value_type , value_type v, value_type ) { return v; }
static value_type f5of5(value_type , value_type, value_type , value_type , value_type v) { return v; }
static value_type f1of5(value_type v, value_type, value_type, value_type, value_type) {
return v;
}
static value_type f2of5(value_type, value_type v, value_type, value_type, value_type) {
return v;
}
static value_type f3of5(value_type, value_type, value_type v, value_type, value_type) {
return v;
}
static value_type f4of5(value_type, value_type, value_type, value_type v, value_type) {
return v;
}
static value_type f5of5(value_type, value_type, value_type, value_type, value_type v) {
return v;
}
static value_type Min(value_type a_fVal1, value_type a_fVal2) { return (a_fVal1<a_fVal2) ? a_fVal1 : a_fVal2; }
static value_type Max(value_type a_fVal1, value_type a_fVal2) { return (a_fVal1>a_fVal2) ? a_fVal1 : a_fVal2; }
static value_type Min(value_type a_fVal1, value_type a_fVal2) {
return (a_fVal1 < a_fVal2) ? a_fVal1 : a_fVal2;
}
static value_type Max(value_type a_fVal1, value_type a_fVal2) {
return (a_fVal1 > a_fVal2) ? a_fVal1 : a_fVal2;
}
static value_type plus2(value_type v1) { return v1+2; }
static value_type times3(value_type v1) { return v1*3; }
static value_type sqr(value_type v1) { return v1*v1; }
static value_type plus2(value_type v1) { return v1 + 2; }
static value_type times3(value_type v1) { return v1 * 3; }
static value_type sqr(value_type v1) { return v1 * v1; }
static value_type sign(value_type v) { return -v; }
static value_type add(value_type v1, value_type v2) { return v1+v2; }
static value_type add(value_type v1, value_type v2) { return v1 + v2; }
static value_type land(value_type v1, value_type v2) { return (int)v1 & (int)v2; }
static value_type FirstArg(const value_type* a_afArg, int a_iArgc)
{
static value_type FirstArg(const value_type* a_afArg, int a_iArgc) {
if (!a_iArgc)
throw mu::Parser::exception_type( _T("too few arguments for function FirstArg.") );
throw mu::Parser::exception_type(_T("too few arguments for function FirstArg."));
return a_afArg[0];
}
static value_type LastArg(const value_type* a_afArg, int a_iArgc)
{
static value_type LastArg(const value_type* a_afArg, int a_iArgc) {
if (!a_iArgc)
throw mu::Parser::exception_type( _T("too few arguments for function LastArg.") );
throw mu::Parser::exception_type(_T("too few arguments for function LastArg."));
return a_afArg[a_iArgc-1];
return a_afArg[a_iArgc - 1];
}
static value_type Sum(const value_type* a_afArg, int a_iArgc)
{
if (!a_iArgc)
throw mu::Parser::exception_type( _T("too few arguments for function sum.") );
static value_type Sum(const value_type* a_afArg, int a_iArgc) {
if (!a_iArgc) throw mu::Parser::exception_type(_T("too few arguments for function sum."));
value_type fRes=0;
for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
value_type fRes = 0;
for (int i = 0; i < a_iArgc; ++i) fRes += a_afArg[i];
return fRes;
}
static value_type Rnd(value_type v)
{
return (value_type)(1+(v*std::rand()/(RAND_MAX+1.0)));
static value_type Rnd(value_type v) {
return (value_type)(1 + (v * std::rand() / (RAND_MAX + 1.0)));
}
static value_type RndWithString(const char_type*)
{
return (value_type)( 1 + (1000.0f * std::rand() / (RAND_MAX + 1.0) ) );
static value_type RndWithString(const char_type*) {
return (value_type)(1 + (1000.0f * std::rand() / (RAND_MAX + 1.0)));
}
static value_type Ping()
{
return 10;
}
static value_type Ping() { return 10; }
static value_type ValueOf(const char_type*)
{
return 123;
}
static value_type ValueOf(const char_type*) { return 123; }
static value_type StrFun1(const char_type* v1)
{
static value_type StrFun1(const char_type* v1) {
int val(0);
stringstream_type(v1) >> val;
return (value_type)val;
}
static value_type StrFun2(const char_type* v1, value_type v2)
{
static value_type StrFun2(const char_type* v1, value_type v2) {
int val(0);
stringstream_type(v1) >> val;
return (value_type)(val + v2);
}
static value_type StrFun3(const char_type* v1, value_type v2, value_type v3)
{
static value_type StrFun3(const char_type* v1, value_type v2, value_type v3) {
int val(0);
stringstream_type(v1) >> val;
return val + v2 + v3;
}
static value_type StrToFloat(const char_type* a_szMsg)
{
static value_type StrToFloat(const char_type* a_szMsg) {
value_type val(0);
stringstream_type(a_szMsg) >> val;
return val;
@ -163,7 +158,7 @@ namespace mu
static value_type Milli(value_type a_fVal) { return a_fVal / (value_type)1e3; }
// Custom value recognition
static int IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal);
static int IsHexVal(const char_type* a_szExpr, int* a_iPos, value_type* a_fVal);
int TestNames();
int TestSyntax();
@ -193,11 +188,8 @@ namespace mu
// Test Double Parser
int EqnTest(const string_type& a_str, double a_fRes, bool a_fPass);
int EqnTestWithVarChange(const string_type& a_str,
double a_fRes1,
double a_fVar1,
double a_fRes2,
double a_fVar2);
int EqnTestWithVarChange(const string_type& a_str, double a_fRes1, double a_fVar1,
double a_fRes2, double a_fVar2);
int ThrowTest(const string_type& a_str, int a_iErrc, bool a_bFail = true);
// Test Int Parser
@ -205,10 +197,8 @@ namespace mu
// Test Bulkmode
int EqnTestBulk(const string_type& a_str, double a_fRes[4], bool a_fPass);
};
} // namespace Test
};
} // namespace Test
} // namespace mu
#endif

View file

@ -27,21 +27,20 @@
#define MU_PARSER_TOKEN_H
#include <cassert>
#include <string>
#include <stack>
#include <vector>
#include <memory>
#include <stack>
#include <string>
#include <vector>
#include "muParserError.h"
#include "muParserCallback.h"
#include "muParserError.h"
/** \file
\brief This file contains the parser token definition.
*/
namespace mu
{
/** \brief Encapsulation of the data for a single formula token.
namespace mu {
/** \brief Encapsulation of the data for a single formula token.
Formula token implementation. Part of the Math Parser Package.
Formula tokens can be either one of the following:
@ -56,12 +55,10 @@ namespace mu
</ul>
\author (C) 2004-2013 Ingo Berg
*/
template<typename TBase, typename TString>
class ParserToken
{
*/
template <typename TBase, typename TString>
class ParserToken {
private:
ECmdCode m_iCode; ///< Type of the token; The token type is a constant of type #ECmdCode.
ETypeCode m_iType;
void *m_pTok; ///< Stores Token pointer; not applicable for all tokens
@ -72,7 +69,6 @@ namespace mu
std::auto_ptr<ParserCallback> m_pCallback;
public:
//---------------------------------------------------------------------------
/** \brief Constructor (default).
@ -81,15 +77,14 @@ namespace mu
\sa ECmdCode
*/
ParserToken()
:m_iCode(cmUNKNOWN)
,m_iType(tpVOID)
,m_pTok(0)
,m_iIdx(-1)
,m_strTok()
,m_strVal()
,m_fVal(0)
,m_pCallback()
{}
: m_iCode(cmUNKNOWN),
m_iType(tpVOID),
m_pTok(0),
m_iIdx(-1),
m_strTok(),
m_strVal(),
m_fVal(0),
m_pCallback() {}
//------------------------------------------------------------------------------
/** \brief Create token from another one.
@ -99,10 +94,7 @@ namespace mu
\post m_iType==cmUNKNOWN
\sa #Assign
*/
ParserToken(const ParserToken &a_Tok)
{
Assign(a_Tok);
}
ParserToken(const ParserToken &a_Tok) { Assign(a_Tok); }
//------------------------------------------------------------------------------
/** \brief Assignement operator.
@ -111,8 +103,7 @@ namespace mu
Implemented by calling Assign(...).
\throw nothrow
*/
ParserToken& operator=(const ParserToken &a_Tok)
{
ParserToken &operator=(const ParserToken &a_Tok) {
Assign(a_Tok);
return *this;
}
@ -122,8 +113,7 @@ namespace mu
\throw nothrow
*/
void Assign(const ParserToken &a_Tok)
{
void Assign(const ParserToken &a_Tok) {
m_iCode = a_Tok.m_iCode;
m_pTok = a_Tok.m_pTok;
m_strTok = a_Tok.m_strTok;
@ -146,12 +136,11 @@ namespace mu
\post m_fVal = 0
\post m_pTok = 0
*/
ParserToken& Set(ECmdCode a_iType, const TString &a_strTok=TString())
{
ParserToken &Set(ECmdCode a_iType, const TString &a_strTok = TString()) {
// The following types cant be set this way, they have special Set functions
assert(a_iType!=cmVAR);
assert(a_iType!=cmVAL);
assert(a_iType!=cmFUNC);
assert(a_iType != cmVAR);
assert(a_iType != cmVAL);
assert(a_iType != cmFUNC);
m_iCode = a_iType;
m_iType = tpVOID;
@ -164,8 +153,7 @@ namespace mu
//------------------------------------------------------------------------------
/** \brief Set Callback type. */
ParserToken& Set(const ParserCallback &a_pCallback, const TString &a_sTok)
{
ParserToken &Set(const ParserCallback &a_pCallback, const TString &a_sTok) {
assert(a_pCallback.GetAddr());
m_iCode = a_pCallback.GetCode();
@ -185,8 +173,7 @@ namespace mu
Member variables not necessary for value tokens will be invalidated.
\throw nothrow
*/
ParserToken& SetVal(TBase a_fVal, const TString &a_strTok=TString())
{
ParserToken &SetVal(TBase a_fVal, const TString &a_strTok = TString()) {
m_iCode = cmVAL;
m_iType = tpDBL;
m_fVal = a_fVal;
@ -205,13 +192,12 @@ namespace mu
Member variables not necessary for variable tokens will be invalidated.
\throw nothrow
*/
ParserToken& SetVar(TBase *a_pVar, const TString &a_strTok)
{
ParserToken &SetVar(TBase *a_pVar, const TString &a_strTok) {
m_iCode = cmVAR;
m_iType = tpDBL;
m_strTok = a_strTok;
m_iIdx = -1;
m_pTok = (void*)a_pVar;
m_pTok = (void *)a_pVar;
m_pCallback.reset(0);
return *this;
}
@ -222,8 +208,7 @@ namespace mu
Member variables not necessary for variable tokens will be invalidated.
\throw nothrow
*/
ParserToken& SetString(const TString &a_strTok, std::size_t a_iSize)
{
ParserToken &SetString(const TString &a_strTok, std::size_t a_iSize) {
m_iCode = cmSTRING;
m_iType = tpSTR;
m_strTok = a_strTok;
@ -241,10 +226,8 @@ namespace mu
\param a_iIdx The index the string function result will take in the bytecode parser.
\throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING
*/
void SetIdx(int a_iIdx)
{
if (m_iCode!=cmSTRING || a_iIdx<0)
assert(0 && "muParser internal error");
void SetIdx(int a_iIdx) {
if (m_iCode != cmSTRING || a_iIdx < 0) assert(0 && "muParser internal error");
m_iIdx = a_iIdx;
}
@ -257,10 +240,8 @@ namespace mu
\throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING
\return The index the result will take in the Bytecode calculatin array (#m_iIdx).
*/
int GetIdx() const
{
if (m_iIdx<0 || m_iCode!=cmSTRING )
assert(0 && "muParser internal error");
int GetIdx() const {
if (m_iIdx < 0 || m_iCode != cmSTRING) assert(0 && "muParser internal error");
return m_iIdx;
}
@ -271,47 +252,36 @@ namespace mu
\return #m_iType
\throw nothrow
*/
ECmdCode GetCode() const
{
if (m_pCallback.get())
{
ECmdCode GetCode() const {
if (m_pCallback.get()) {
return m_pCallback->GetCode();
}
else
{
} else {
return m_iCode;
}
}
//------------------------------------------------------------------------------
ETypeCode GetType() const
{
if (m_pCallback.get())
{
ETypeCode GetType() const {
if (m_pCallback.get()) {
return m_pCallback->GetType();
}
else
{
} else {
return m_iType;
}
}
//------------------------------------------------------------------------------
int GetPri() const
{
if ( !m_pCallback.get())
assert(0 && "muParser internal error");
int GetPri() const {
if (!m_pCallback.get()) assert(0 && "muParser internal error");
if ( m_pCallback->GetCode()!=cmOPRT_BIN && m_pCallback->GetCode()!=cmOPRT_INFIX)
if (m_pCallback->GetCode() != cmOPRT_BIN && m_pCallback->GetCode() != cmOPRT_INFIX)
assert(0 && "muParser internal error");
return m_pCallback->GetPri();
}
//------------------------------------------------------------------------------
EOprtAssociativity GetAssociativity() const
{
if (m_pCallback.get()==NULL || m_pCallback->GetCode()!=cmOPRT_BIN)
EOprtAssociativity GetAssociativity() const {
if (m_pCallback.get() == NULL || m_pCallback->GetCode() != cmOPRT_BIN)
assert(0 && "muParser internal error");
return m_pCallback->GetAssociativity();
@ -332,8 +302,7 @@ namespace mu
</ul>
\sa ECmdCode
*/
generic_fun_type GetFuncAddr() const
{
generic_fun_type GetFuncAddr() const {
return (m_pCallback.get()) ? (generic_fun_type)m_pCallback->GetAddr() : 0;
}
@ -343,13 +312,14 @@ namespace mu
Only applicable to variable and value tokens.
\throw exception_type if token is no value/variable token.
*/
TBase GetVal() const
{
switch (m_iCode)
{
case cmVAL: return m_fVal;
case cmVAR: return *((TBase*)m_pTok);
default: throw ParserError(ecVAL_EXPECTED);
TBase GetVal() const {
switch (m_iCode) {
case cmVAL:
return m_fVal;
case cmVAR:
return *((TBase *)m_pTok);
default:
throw ParserError(ecVAL_EXPECTED);
}
}
@ -359,12 +329,10 @@ namespace mu
Valid only if m_iType==CmdVar.
\throw exception_type if token is no variable token.
*/
TBase* GetVar() const
{
if (m_iCode!=cmVAR)
assert(0 && "muParser internal error");
TBase *GetVar() const {
if (m_iCode != cmVAR) assert(0 && "muParser internal error");
return (TBase*)m_pTok;
return (TBase *)m_pTok;
}
//------------------------------------------------------------------------------
@ -372,12 +340,10 @@ namespace mu
Valid only if m_iType==CmdFUNC.
*/
int GetArgCount() const
{
int GetArgCount() const {
assert(m_pCallback.get());
if (!m_pCallback->GetAddr())
assert(0 && "muParser internal error");
if (!m_pCallback->GetAddr()) assert(0 && "muParser internal error");
return m_pCallback->GetArgc();
}
@ -391,11 +357,8 @@ namespace mu
\throw nothrow
\sa m_strTok
*/
const TString& GetAsString() const
{
return m_strTok;
}
};
const TString &GetAsString() const { return m_strTok; }
};
} // namespace mu
#endif

View file

@ -42,25 +42,20 @@
\brief This file contains the parser token reader definition.
*/
namespace mu {
// Forward declaration
class ParserBase;
namespace mu
{
// Forward declaration
class ParserBase;
/** \brief Token reader for the ParserBase class.
/** \brief Token reader for the ParserBase class.
*/
class ParserTokenReader
{
*/
class ParserTokenReader {
private:
typedef ParserToken<value_type, string_type> token_type;
public:
ParserTokenReader(ParserBase *a_pParent);
ParserTokenReader* Clone(ParserBase *a_pParent) const;
ParserTokenReader *Clone(ParserBase *a_pParent) const;
void AddValIdent(identfun_type a_pCallback);
void SetVarCreator(facfun_type a_pFactory, void *pUserData);
@ -68,8 +63,8 @@ namespace mu
void SetArgSep(char_type cArgSep);
int GetPos() const;
const string_type& GetExpr() const;
varmap_type& GetUsedVar();
const string_type &GetExpr() const;
varmap_type &GetUsedVar();
char_type GetArgSep() const;
void IgnoreUndefVar(bool bIgnore);
@ -77,15 +72,13 @@ namespace mu
token_type ReadNextToken();
private:
/** \brief Syntax codes.
The syntax codes control the syntax check done during the first time parsing of
the expression string. They are flags that indicate which tokens are allowed next
if certain tokens are identified.
*/
enum ESynCodes
{
enum ESynCodes {
noBO = 1 << 0, ///< to avoid i.e. "cos(7)("
noBC = 1 << 1, ///< to avoid i.e. "sin)" or "()"
noVAL = 1 << 2, ///< to avoid i.e. "tan 2" or "sin(8)3.14"
@ -105,13 +98,11 @@ namespace mu
};
ParserTokenReader(const ParserTokenReader &a_Reader);
ParserTokenReader& operator=(const ParserTokenReader &a_Reader);
ParserTokenReader &operator=(const ParserTokenReader &a_Reader);
void Assign(const ParserTokenReader &a_Reader);
void SetParent(ParserBase *a_pParent);
int ExtractToken(const char_type *a_szCharSet,
string_type &a_strTok,
int a_iPos) const;
int ExtractToken(const char_type *a_szCharSet, string_type &a_strTok, int a_iPos) const;
int ExtractOperatorToken(string_type &a_sTok, int a_iPos) const;
bool IsBuiltIn(token_type &a_Tok);
@ -126,11 +117,10 @@ namespace mu
bool IsStrVarTok(token_type &a_Tok);
bool IsUndefVarTok(token_type &a_Tok);
bool IsString(token_type &a_Tok);
void Error(EErrorCodes a_iErrc,
int a_iPos = -1,
const string_type &a_sTok = string_type() ) const;
void Error(EErrorCodes a_iErrc, int a_iPos = -1,
const string_type &a_sTok = string_type()) const;
token_type& SaveBeforeReturn(const token_type &tok);
token_type &SaveBeforeReturn(const token_type &tok);
ParserBase *m_pParser;
string_type m_strFormula;
@ -153,9 +143,7 @@ namespace mu
int m_iBrackets;
token_type m_lastTok;
char_type m_cArgSep; ///< The character used for separating function arguments
};
};
} // namespace mu
#endif

View file

@ -27,8 +27,8 @@
#include "muParserTemplateMagic.h"
//--- Standard includes ------------------------------------------------------------------------
#include <cmath>
#include <algorithm>
#include <cmath>
#include <numeric>
/** \brief Pi (what else?). */
@ -43,176 +43,147 @@ using namespace std;
\brief Implementation of the standard floating point parser.
*/
/** \brief Namespace for mathematical applications. */
namespace mu
{
namespace mu {
//---------------------------------------------------------------------------
// Trigonometric function
value_type Parser::Sin(value_type v) { return MathImpl<value_type>::Sin(v); }
value_type Parser::Cos(value_type v) { return MathImpl<value_type>::Cos(v); }
value_type Parser::Tan(value_type v) { return MathImpl<value_type>::Tan(v); }
value_type Parser::ASin(value_type v) { return MathImpl<value_type>::ASin(v); }
value_type Parser::ACos(value_type v) { return MathImpl<value_type>::ACos(v); }
value_type Parser::ATan(value_type v) { return MathImpl<value_type>::ATan(v); }
value_type Parser::ATan2(value_type v1, value_type v2) {
return MathImpl<value_type>::ATan2(v1, v2);
}
value_type Parser::Sinh(value_type v) { return MathImpl<value_type>::Sinh(v); }
value_type Parser::Cosh(value_type v) { return MathImpl<value_type>::Cosh(v); }
value_type Parser::Tanh(value_type v) { return MathImpl<value_type>::Tanh(v); }
value_type Parser::ASinh(value_type v) { return MathImpl<value_type>::ASinh(v); }
value_type Parser::ACosh(value_type v) { return MathImpl<value_type>::ACosh(v); }
value_type Parser::ATanh(value_type v) { return MathImpl<value_type>::ATanh(v); }
//---------------------------------------------------------------------------
// Trigonometric function
value_type Parser::Sin(value_type v) { return MathImpl<value_type>::Sin(v); }
value_type Parser::Cos(value_type v) { return MathImpl<value_type>::Cos(v); }
value_type Parser::Tan(value_type v) { return MathImpl<value_type>::Tan(v); }
value_type Parser::ASin(value_type v) { return MathImpl<value_type>::ASin(v); }
value_type Parser::ACos(value_type v) { return MathImpl<value_type>::ACos(v); }
value_type Parser::ATan(value_type v) { return MathImpl<value_type>::ATan(v); }
value_type Parser::ATan2(value_type v1, value_type v2) { return MathImpl<value_type>::ATan2(v1, v2); }
value_type Parser::Sinh(value_type v) { return MathImpl<value_type>::Sinh(v); }
value_type Parser::Cosh(value_type v) { return MathImpl<value_type>::Cosh(v); }
value_type Parser::Tanh(value_type v) { return MathImpl<value_type>::Tanh(v); }
value_type Parser::ASinh(value_type v) { return MathImpl<value_type>::ASinh(v); }
value_type Parser::ACosh(value_type v) { return MathImpl<value_type>::ACosh(v); }
value_type Parser::ATanh(value_type v) { return MathImpl<value_type>::ATanh(v); }
//---------------------------------------------------------------------------
// Logarithm functions
//---------------------------------------------------------------------------
// Logarithm functions
// Logarithm base 2
value_type Parser::Log2(value_type v)
{
#ifdef MUP_MATH_EXCEPTIONS
if (v<=0)
throw ParserError(ecDOMAIN_ERROR, _T("Log2"));
#endif
// Logarithm base 2
value_type Parser::Log2(value_type v) {
#ifdef MUP_MATH_EXCEPTIONS
if (v <= 0) throw ParserError(ecDOMAIN_ERROR, _T("Log2"));
#endif
return MathImpl<value_type>::Log2(v);
}
}
// Logarithm base 10
value_type Parser::Log10(value_type v)
{
#ifdef MUP_MATH_EXCEPTIONS
if (v<=0)
throw ParserError(ecDOMAIN_ERROR, _T("Log10"));
#endif
// Logarithm base 10
value_type Parser::Log10(value_type v) {
#ifdef MUP_MATH_EXCEPTIONS
if (v <= 0) throw ParserError(ecDOMAIN_ERROR, _T("Log10"));
#endif
return MathImpl<value_type>::Log10(v);
}
}
// Logarithm base e (natural logarithm)
value_type Parser::Ln(value_type v)
{
#ifdef MUP_MATH_EXCEPTIONS
if (v<=0)
throw ParserError(ecDOMAIN_ERROR, _T("Ln"));
#endif
value_type Parser::Ln(value_type v) {
#ifdef MUP_MATH_EXCEPTIONS
if (v <= 0) throw ParserError(ecDOMAIN_ERROR, _T("Ln"));
#endif
return MathImpl<value_type>::Log(v);
}
}
//---------------------------------------------------------------------------
// misc
value_type Parser::Exp(value_type v) { return MathImpl<value_type>::Exp(v); }
value_type Parser::Abs(value_type v) { return MathImpl<value_type>::Abs(v); }
value_type Parser::Sqrt(value_type v)
{
#ifdef MUP_MATH_EXCEPTIONS
if (v<0)
throw ParserError(ecDOMAIN_ERROR, _T("sqrt"));
#endif
//---------------------------------------------------------------------------
// misc
value_type Parser::Exp(value_type v) { return MathImpl<value_type>::Exp(v); }
value_type Parser::Abs(value_type v) { return MathImpl<value_type>::Abs(v); }
value_type Parser::Sqrt(value_type v) {
#ifdef MUP_MATH_EXCEPTIONS
if (v < 0) throw ParserError(ecDOMAIN_ERROR, _T("sqrt"));
#endif
return MathImpl<value_type>::Sqrt(v);
}
value_type Parser::Rint(value_type v) { return MathImpl<value_type>::Rint(v); }
value_type Parser::Sign(value_type v) { return MathImpl<value_type>::Sign(v); }
}
value_type Parser::Rint(value_type v) { return MathImpl<value_type>::Rint(v); }
value_type Parser::Sign(value_type v) { return MathImpl<value_type>::Sign(v); }
//---------------------------------------------------------------------------
/** \brief Callback for the unary minus operator.
//---------------------------------------------------------------------------
/** \brief Callback for the unary minus operator.
\param v The value to negate
\return -v
*/
value_type Parser::UnaryMinus(value_type v)
{
return -v;
}
*/
value_type Parser::UnaryMinus(value_type v) { return -v; }
//---------------------------------------------------------------------------
/** \brief Callback for the unary minus operator.
//---------------------------------------------------------------------------
/** \brief Callback for the unary minus operator.
\param v The value to negate
\return -v
*/
value_type Parser::UnaryPlus(value_type v)
{
return v;
}
*/
value_type Parser::UnaryPlus(value_type v) { return v; }
//---------------------------------------------------------------------------
/** \brief Callback for adding multiple values.
//---------------------------------------------------------------------------
/** \brief Callback for adding multiple values.
\param [in] a_afArg Vector with the function arguments
\param [in] a_iArgc The size of a_afArg
*/
value_type Parser::Sum(const value_type *a_afArg, int a_iArgc)
{
if (!a_iArgc)
throw exception_type(_T("too few arguments for function sum."));
*/
value_type Parser::Sum(const value_type *a_afArg, int a_iArgc) {
if (!a_iArgc) throw exception_type(_T("too few arguments for function sum."));
value_type fRes=0;
for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
value_type fRes = 0;
for (int i = 0; i < a_iArgc; ++i) fRes += a_afArg[i];
return fRes;
}
}
//---------------------------------------------------------------------------
/** \brief Callback for averaging multiple values.
//---------------------------------------------------------------------------
/** \brief Callback for averaging multiple values.
\param [in] a_afArg Vector with the function arguments
\param [in] a_iArgc The size of a_afArg
*/
value_type Parser::Avg(const value_type *a_afArg, int a_iArgc)
{
if (!a_iArgc)
throw exception_type(_T("too few arguments for function sum."));
*/
value_type Parser::Avg(const value_type *a_afArg, int a_iArgc) {
if (!a_iArgc) throw exception_type(_T("too few arguments for function sum."));
value_type fRes=0;
for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
return fRes/(value_type)a_iArgc;
}
value_type fRes = 0;
for (int i = 0; i < a_iArgc; ++i) fRes += a_afArg[i];
return fRes / (value_type)a_iArgc;
}
//---------------------------------------------------------------------------
/** \brief Callback for determining the minimum value out of a vector.
//---------------------------------------------------------------------------
/** \brief Callback for determining the minimum value out of a vector.
\param [in] a_afArg Vector with the function arguments
\param [in] a_iArgc The size of a_afArg
*/
value_type Parser::Min(const value_type *a_afArg, int a_iArgc)
{
if (!a_iArgc)
throw exception_type(_T("too few arguments for function min."));
*/
value_type Parser::Min(const value_type *a_afArg, int a_iArgc) {
if (!a_iArgc) throw exception_type(_T("too few arguments for function min."));
value_type fRes=a_afArg[0];
for (int i=0; i<a_iArgc; ++i)
fRes = std::min(fRes, a_afArg[i]);
value_type fRes = a_afArg[0];
for (int i = 0; i < a_iArgc; ++i) fRes = std::min(fRes, a_afArg[i]);
return fRes;
}
}
//---------------------------------------------------------------------------
/** \brief Callback for determining the maximum value out of a vector.
//---------------------------------------------------------------------------
/** \brief Callback for determining the maximum value out of a vector.
\param [in] a_afArg Vector with the function arguments
\param [in] a_iArgc The size of a_afArg
*/
value_type Parser::Max(const value_type *a_afArg, int a_iArgc)
{
if (!a_iArgc)
throw exception_type(_T("too few arguments for function min."));
*/
value_type Parser::Max(const value_type *a_afArg, int a_iArgc) {
if (!a_iArgc) throw exception_type(_T("too few arguments for function min."));
value_type fRes=a_afArg[0];
for (int i=0; i<a_iArgc; ++i) fRes = std::max(fRes, a_afArg[i]);
value_type fRes = a_afArg[0];
for (int i = 0; i < a_iArgc; ++i) fRes = std::max(fRes, a_afArg[i]);
return fRes;
}
}
//---------------------------------------------------------------------------
/** \brief Default value recognition callback.
//---------------------------------------------------------------------------
/** \brief Default value recognition callback.
\param [in] a_szExpr Pointer to the expression
\param [in, out] a_iPos Pointer to an index storing the current position within the expression
\param [out] a_fVal Pointer where the value should be stored in case one is found.
\return 1 if a value was found 0 otherwise.
*/
int Parser::IsVal(const char_type* a_szExpr, int *a_iPos, value_type *a_fVal)
{
*/
int Parser::IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal) {
value_type fVal(0);
stringstream_type stream(a_szExpr);
@ -221,59 +192,50 @@ namespace mu
stream >> fVal;
stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading
if (iEnd==(stringstream_type::pos_type)-1)
return 0;
if (iEnd == (stringstream_type::pos_type)-1) return 0;
*a_iPos += (int)iEnd;
*a_fVal = fVal;
return 1;
}
}
//---------------------------------------------------------------------------
/** \brief Constructor.
//---------------------------------------------------------------------------
/** \brief Constructor.
Call ParserBase class constructor and trigger Function, Operator and Constant initialization.
*/
Parser::Parser()
:ParserBase()
{
*/
Parser::Parser() : ParserBase() {
AddValIdent(IsVal);
InitCharSets();
InitFun();
InitConst();
InitOprt();
}
}
//---------------------------------------------------------------------------
/** \brief Define the character sets.
//---------------------------------------------------------------------------
/** \brief Define the character sets.
\sa DefineNameChars, DefineOprtChars, DefineInfixOprtChars
This function is used for initializing the default character sets that define
the characters to be useable in function and variable names and operators.
*/
void Parser::InitCharSets()
{
DefineNameChars( _T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") );
DefineOprtChars( _T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}") );
DefineInfixOprtChars( _T("/+-*^?<>=#!$%&|~'_") );
}
*/
void Parser::InitCharSets() {
DefineNameChars(_T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"));
DefineOprtChars(_T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}"));
DefineInfixOprtChars(_T("/+-*^?<>=#!$%&|~'_"));
}
//---------------------------------------------------------------------------
/** \brief Initialize the default functions. */
void Parser::InitFun()
{
if (mu::TypeInfo<mu::value_type>::IsInteger())
{
//---------------------------------------------------------------------------
/** \brief Initialize the default functions. */
void Parser::InitFun() {
if (mu::TypeInfo<mu::value_type>::IsInteger()) {
// When setting MUP_BASETYPE to an integer type
// Place functions for dealing with integer values here
// ...
// ...
// ...
}
else
{
} else {
// trigonometric functions
DefineFun(_T("sin"), Sin);
DefineFun(_T("cos"), Cos);
@ -308,34 +270,31 @@ namespace mu
DefineFun(_T("min"), Min);
DefineFun(_T("max"), Max);
}
}
}
//---------------------------------------------------------------------------
/** \brief Initialize constants.
//---------------------------------------------------------------------------
/** \brief Initialize constants.
By default the parser recognizes two constants. Pi ("pi") and the Eulerian
number ("_e").
*/
void Parser::InitConst()
{
*/
void Parser::InitConst() {
DefineConst(_T("_pi"), (value_type)PARSER_CONST_PI);
DefineConst(_T("_e"), (value_type)PARSER_CONST_E);
}
}
//---------------------------------------------------------------------------
/** \brief Initialize operators.
//---------------------------------------------------------------------------
/** \brief Initialize operators.
By default only the unary minus operator is added.
*/
void Parser::InitOprt()
{
*/
void Parser::InitOprt() {
DefineInfixOprt(_T("-"), UnaryMinus);
DefineInfixOprt(_T("+"), UnaryPlus);
}
}
//---------------------------------------------------------------------------
void Parser::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/)
{
//---------------------------------------------------------------------------
void Parser::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/) {
// this is just sample code to illustrate modifying variable names on the fly.
// I'm not sure anyone really needs such a feature...
/*
@ -356,10 +315,10 @@ namespace mu
pExpr->replace(pExpr->begin()+nStart, pExpr->begin()+nOrigVarEnd, sRepl);
cout << " New expr: " << *pExpr << "\n";
*/
}
}
//---------------------------------------------------------------------------
/** \brief Numerically differentiate with regard to a variable.
//---------------------------------------------------------------------------
/** \brief Numerically differentiate with regard to a variable.
\param [in] a_Var Pointer to the differentiation variable.
\param [in] a_fPos Position at which the differentiation should take place.
\param [in] a_fEpsilon Epsilon used for the numerical differentiation.
@ -370,28 +329,25 @@ namespace mu
forum:
http://sourceforge.net/forum/forum.php?thread_id=1994611&forum_id=462843
*/
value_type Parser::Diff(value_type *a_Var,
value_type a_fPos,
value_type a_fEpsilon) const
{
value_type fRes(0),
fBuf(*a_Var),
f[4] = {0,0,0,0},
fEpsilon(a_fEpsilon);
*/
value_type Parser::Diff(value_type *a_Var, value_type a_fPos, value_type a_fEpsilon) const {
value_type fRes(0), fBuf(*a_Var), f[4] = {0, 0, 0, 0}, fEpsilon(a_fEpsilon);
// Backwards compatible calculation of epsilon inc case the user doesn't provide
// his own epsilon
if (fEpsilon==0)
fEpsilon = (a_fPos==0) ? (value_type)1e-10 : (value_type)1e-7 * a_fPos;
if (fEpsilon == 0) fEpsilon = (a_fPos == 0) ? (value_type)1e-10 : (value_type)1e-7 * a_fPos;
*a_Var = a_fPos+2 * fEpsilon; f[0] = Eval();
*a_Var = a_fPos+1 * fEpsilon; f[1] = Eval();
*a_Var = a_fPos-1 * fEpsilon; f[2] = Eval();
*a_Var = a_fPos-2 * fEpsilon; f[3] = Eval();
*a_Var = a_fPos + 2 * fEpsilon;
f[0] = Eval();
*a_Var = a_fPos + 1 * fEpsilon;
f[1] = Eval();
*a_Var = a_fPos - 1 * fEpsilon;
f[2] = Eval();
*a_Var = a_fPos - 2 * fEpsilon;
f[3] = Eval();
*a_Var = fBuf; // restore variable
fRes = (-f[0] + 8*f[1] - 8*f[2] + f[3]) / (12*fEpsilon);
fRes = (-f[0] + 8 * f[1] - 8 * f[2] + f[3]) / (12 * fEpsilon);
return fRes;
}
}
} // namespace mu

File diff suppressed because it is too large Load diff

View file

@ -27,81 +27,65 @@
#include <algorithm>
#include <cassert>
#include <string>
#include <stack>
#include <vector>
#include <iostream>
#include <stack>
#include <string>
#include <vector>
#include "muParserDef.h"
#include "muParserError.h"
#include "muParserToken.h"
#include "muParserStack.h"
#include "muParserTemplateMagic.h"
#include "muParserToken.h"
namespace mu
{
//---------------------------------------------------------------------------
/** \brief Bytecode default constructor. */
ParserByteCode::ParserByteCode()
:m_iStackPos(0)
,m_iMaxStackSize(0)
,m_vRPN()
,m_bEnableOptimizer(true)
{
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.
//---------------------------------------------------------------------------
/** \brief Copy constructor.
Implemented in Terms of Assign(const ParserByteCode &a_ByteCode)
*/
ParserByteCode::ParserByteCode(const ParserByteCode &a_ByteCode)
{
Assign(a_ByteCode);
}
*/
ParserByteCode::ParserByteCode(const ParserByteCode &a_ByteCode) { Assign(a_ByteCode); }
//---------------------------------------------------------------------------
/** \brief Assignment operator.
//---------------------------------------------------------------------------
/** \brief Assignment operator.
Implemented in Terms of Assign(const ParserByteCode &a_ByteCode)
*/
ParserByteCode& ParserByteCode::operator=(const ParserByteCode &a_ByteCode)
{
*/
ParserByteCode &ParserByteCode::operator=(const ParserByteCode &a_ByteCode) {
Assign(a_ByteCode);
return *this;
}
}
//---------------------------------------------------------------------------
void ParserByteCode::EnableOptimizer(bool bStat)
{
m_bEnableOptimizer = bStat;
}
//---------------------------------------------------------------------------
void ParserByteCode::EnableOptimizer(bool bStat) { m_bEnableOptimizer = bStat; }
//---------------------------------------------------------------------------
/** \brief Copy state of another object to this.
//---------------------------------------------------------------------------
/** \brief Copy state of another object to this.
\throw nowthrow
*/
void ParserByteCode::Assign(const ParserByteCode &a_ByteCode)
{
if (this==&a_ByteCode)
return;
*/
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;
m_bEnableOptimizer = a_ByteCode.m_bEnableOptimizer;
}
}
//---------------------------------------------------------------------------
/** \brief Add a Variable pointer to bytecode.
//---------------------------------------------------------------------------
/** \brief Add a Variable pointer to bytecode.
\param a_pVar Pointer to be added.
\throw nothrow
*/
void ParserByteCode::AddVar(value_type *a_pVar)
{
*/
void ParserByteCode::AddVar(value_type *a_pVar) {
++m_iStackPos;
m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
@ -112,10 +96,10 @@ namespace mu
tok.Val.data = 1;
tok.Val.data2 = 0;
m_vRPN.push_back(tok);
}
}
//---------------------------------------------------------------------------
/** \brief Add a Variable pointer to bytecode.
//---------------------------------------------------------------------------
/** \brief Add a Variable pointer to bytecode.
Value entries in byte code consist of:
<ul>
@ -126,9 +110,8 @@ namespace mu
\param a_pVal Value to be added.
\throw nothrow
*/
void ParserByteCode::AddVal(value_type a_fVal)
{
*/
void ParserByteCode::AddVal(value_type a_fVal) {
++m_iStackPos;
m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
@ -139,49 +122,79 @@ namespace mu
tok.Val.data = 0;
tok.Val.data2 = a_fVal;
m_vRPN.push_back(tok);
}
}
//---------------------------------------------------------------------------
void ParserByteCode::ConstantFolding(ECmdCode a_Oprt)
{
//---------------------------------------------------------------------------
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;
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"));
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);
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.
//---------------------------------------------------------------------------
/** \brief Add an operator identifier to bytecode.
Operator entries in byte code consist of:
<ul>
@ -190,38 +203,31 @@ namespace mu
</ul>
\sa ParserToken::ECmdCode
*/
void ParserByteCode::AddOp(ECmdCode a_Oprt)
{
*/
void ParserByteCode::AddOp(ECmdCode a_Oprt) {
bool bOptimized = false;
if (m_bEnableOptimizer)
{
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)
{
if (sz >= 2 && m_vRPN[sz - 2].Cmd == cmVAL && m_vRPN[sz - 1].Cmd == cmVAL) {
ConstantFolding(a_Oprt);
bOptimized = true;
}
else
{
switch(a_Oprt)
{
} else {
switch (a_Oprt) {
case cmPOW:
// Optimization for polynomials 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;
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;
@ -234,74 +240,80 @@ namespace mu
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) );
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; // multiplicand
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; // multiplicand
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;
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) )
{
} 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[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)
{
} 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[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)
{
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[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;
}
@ -312,25 +324,23 @@ namespace mu
}
// If optimization can't be applied just write the value
if (!bOptimized)
{
if (!bOptimized) {
--m_iStackPos;
SToken tok;
tok.Cmd = a_Oprt;
m_vRPN.push_back(tok);
}
}
}
//---------------------------------------------------------------------------
void ParserByteCode::AddIfElse(ECmdCode a_Oprt)
{
//---------------------------------------------------------------------------
void ParserByteCode::AddIfElse(ECmdCode a_Oprt) {
SToken tok;
tok.Cmd = a_Oprt;
m_vRPN.push_back(tok);
}
}
//---------------------------------------------------------------------------
/** \brief Add an assignment operator
//---------------------------------------------------------------------------
/** \brief Add an assignment operator
Operator entries in byte code consist of:
<ul>
@ -339,31 +349,26 @@ namespace mu
</ul>
\sa ParserToken::ECmdCode
*/
void ParserByteCode::AddAssignOp(value_type *a_pVar)
{
*/
void ParserByteCode::AddAssignOp(value_type *a_pVar) {
--m_iStackPos;
SToken tok;
tok.Cmd = cmASSIGN;
tok.Oprt.ptr = a_pVar;
m_vRPN.push_back(tok);
}
}
//---------------------------------------------------------------------------
/** \brief Add function to bytecode.
//---------------------------------------------------------------------------
/** \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)
{
*/
void ParserByteCode::AddFun(generic_fun_type a_pFun, int a_iArgc) {
if (a_iArgc >= 0) {
m_iStackPos = m_iStackPos - a_iArgc + 1;
}
else
{
} else {
// function with unlimited number of arguments
m_iStackPos = m_iStackPos + a_iArgc + 1;
}
@ -374,16 +379,15 @@ namespace mu
tok.Fun.argc = a_iArgc;
tok.Fun.ptr = a_pFun;
m_vRPN.push_back(tok);
}
}
//---------------------------------------------------------------------------
/** \brief Add a bulk function to bytecode.
//---------------------------------------------------------------------------
/** \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)
{
*/
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);
@ -392,18 +396,17 @@ namespace mu
tok.Fun.argc = a_iArgc;
tok.Fun.ptr = a_pFun;
m_vRPN.push_back(tok);
}
}
//---------------------------------------------------------------------------
/** \brief Add Strung function entry to the parser bytecode.
//---------------------------------------------------------------------------
/** \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)
{
*/
void ParserByteCode::AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx) {
m_iStackPos = m_iStackPos - a_iArgc + 1;
SToken tok;
@ -414,15 +417,14 @@ namespace mu
m_vRPN.push_back(tok);
m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);
}
}
//---------------------------------------------------------------------------
/** \brief Add end marker to bytecode.
//---------------------------------------------------------------------------
/** \brief Add end marker to bytecode.
\throw nothrow
*/
void ParserByteCode::Finalize()
{
*/
void ParserByteCode::Finalize() {
SToken tok;
tok.Cmd = cmEND;
m_vRPN.push_back(tok);
@ -431,10 +433,8 @@ namespace mu
// 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)
{
for (int i = 0; i < (int)m_vRPN.size(); ++i) {
switch (m_vRPN[i].Cmd) {
case cmIF:
stIf.push(i);
break;
@ -454,88 +454,82 @@ namespace mu
break;
}
}
}
}
//---------------------------------------------------------------------------
const SToken* ParserByteCode::GetBase() const
{
if (m_vRPN.size()==0)
assert(0 && "muParser internal error");
//---------------------------------------------------------------------------
const SToken *ParserByteCode::GetBase() const {
if (m_vRPN.size() == 0) assert(0 && "muParser internal error");
return &m_vRPN[0];
}
}
//---------------------------------------------------------------------------
std::size_t ParserByteCode::GetMaxStackSize() const
{
return m_iMaxStackSize+1;
}
//---------------------------------------------------------------------------
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 Returns the number of entries in the bytecode. */
std::size_t ParserByteCode::GetSize() const { return m_vRPN.size(); }
//---------------------------------------------------------------------------
/** \brief Delete the bytecode.
//---------------------------------------------------------------------------
/** \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()
{
*/
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())
{
//---------------------------------------------------------------------------
/** \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)
{
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");
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");
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");
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");
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");
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");
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");
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");
@ -548,40 +542,71 @@ namespace mu
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 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");
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");
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 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");
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

View file

@ -29,354 +29,309 @@
\brief Implementation of the parser callback class.
*/
namespace mu {
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type0 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(0),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
namespace mu
{
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type0 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(0)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec, ECmdCode a_iCode)
: m_pFun((void*)a_pFun),
m_iArgc(1),
m_iPri(a_iPrec),
m_eOprtAsct(oaNONE),
m_iCode(a_iCode),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec, ECmdCode a_iCode)
:m_pFun((void*)a_pFun)
,m_iArgc(1)
,m_iPri(a_iPrec)
,m_eOprtAsct(oaNONE)
,m_iCode(a_iCode)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
/** \brief Constructor for constructing function callbacks taking two arguments.
//---------------------------------------------------------------------------
/** \brief Constructor for constructing function callbacks taking two arguments.
\throw nothrow
*/
ParserCallback::ParserCallback(fun_type2 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(2)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
*/
ParserCallback::ParserCallback(fun_type2 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(2),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
/** \brief Constructor for constructing binary operator callbacks.
//---------------------------------------------------------------------------
/** \brief Constructor for constructing binary operator callbacks.
\param a_pFun Pointer to a static function taking two arguments
\param a_bAllowOpti A flag indicating this function can be optimized
\param a_iPrec The operator precedence
\param a_eOprtAsct The operators associativity
\throw nothrow
*/
ParserCallback::ParserCallback(fun_type2 a_pFun,
bool a_bAllowOpti,
int a_iPrec,
*/
ParserCallback::ParserCallback(fun_type2 a_pFun, bool a_bAllowOpti, int a_iPrec,
EOprtAssociativity a_eOprtAsct)
:m_pFun((void*)a_pFun)
,m_iArgc(2)
,m_iPri(a_iPrec)
,m_eOprtAsct(a_eOprtAsct)
,m_iCode(cmOPRT_BIN)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
: m_pFun((void*)a_pFun),
m_iArgc(2),
m_iPri(a_iPrec),
m_eOprtAsct(a_eOprtAsct),
m_iCode(cmOPRT_BIN),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type3 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(3)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type3 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(3),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type4 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(4),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type4 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(4)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type5 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(5),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type6 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(6),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type5 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(5)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type7 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(7),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type6 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(6)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type8 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(8),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type7 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(7)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type9 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(9),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type8 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(8)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type10 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(10),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type9 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(9)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type0 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(0),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC_BULK),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(fun_type10 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(10)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type1 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(1),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC_BULK),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type0 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(0)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC_BULK)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type1 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(1)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC_BULK)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
/** \brief Constructor for constructing function callbacks taking two arguments.
//---------------------------------------------------------------------------
/** \brief Constructor for constructing function callbacks taking two arguments.
\throw nothrow
*/
ParserCallback::ParserCallback(bulkfun_type2 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(2)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC_BULK)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
*/
ParserCallback::ParserCallback(bulkfun_type2 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(2),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC_BULK),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type3 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(3)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC_BULK)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type3 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(3),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC_BULK),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type4 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(4),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC_BULK),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type4 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(4)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC_BULK)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type5 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(5),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC_BULK),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type6 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(6),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC_BULK),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type5 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(5)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC_BULK)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type7 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(7),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC_BULK),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type6 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(6)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC_BULK)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type8 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(8),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC_BULK),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type7 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(7)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC_BULK)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type9 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(9),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC_BULK),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type8 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(8)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC_BULK)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type10 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(10),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC_BULK),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type9 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(9)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC_BULK)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(multfun_type a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(-1),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC),
m_iType(tpDBL),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(bulkfun_type10 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(10)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC_BULK)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(0),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC_STR),
m_iType(tpSTR),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(1),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC_STR),
m_iType(tpSTR),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(multfun_type a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(-1)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC)
,m_iType(tpDBL)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti)
: m_pFun((void*)a_pFun),
m_iArgc(2),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmFUNC_STR),
m_iType(tpSTR),
m_bAllowOpti(a_bAllowOpti) {}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(0)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC_STR)
,m_iType(tpSTR)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(1)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC_STR)
,m_iType(tpSTR)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
ParserCallback::ParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti)
:m_pFun((void*)a_pFun)
,m_iArgc(2)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmFUNC_STR)
,m_iType(tpSTR)
,m_bAllowOpti(a_bAllowOpti)
{}
//---------------------------------------------------------------------------
/** \brief Default constructor.
//---------------------------------------------------------------------------
/** \brief Default constructor.
\throw nothrow
*/
ParserCallback::ParserCallback()
:m_pFun(0)
,m_iArgc(0)
,m_iPri(-1)
,m_eOprtAsct(oaNONE)
,m_iCode(cmUNKNOWN)
,m_iType(tpVOID)
,m_bAllowOpti(0)
{}
*/
ParserCallback::ParserCallback()
: m_pFun(0),
m_iArgc(0),
m_iPri(-1),
m_eOprtAsct(oaNONE),
m_iCode(cmUNKNOWN),
m_iType(tpVOID),
m_bAllowOpti(0) {}
//---------------------------------------------------------------------------
/** \brief Copy constructor.
//---------------------------------------------------------------------------
/** \brief Copy constructor.
\throw nothrow
*/
ParserCallback::ParserCallback(const ParserCallback &ref)
{
*/
ParserCallback::ParserCallback(const ParserCallback& ref) {
m_pFun = ref.m_pFun;
m_iArgc = ref.m_iArgc;
m_bAllowOpti = ref.m_bAllowOpti;
@ -384,80 +339,55 @@ namespace mu
m_iType = ref.m_iType;
m_iPri = ref.m_iPri;
m_eOprtAsct = ref.m_eOprtAsct;
}
}
//---------------------------------------------------------------------------
/** \brief Clone this instance and return a pointer to the new instance. */
ParserCallback* ParserCallback::Clone() const
{
return new ParserCallback(*this);
}
//---------------------------------------------------------------------------
/** \brief Clone this instance and return a pointer to the new instance. */
ParserCallback* ParserCallback::Clone() const { return new ParserCallback(*this); }
//---------------------------------------------------------------------------
/** \brief Return tru if the function is conservative.
//---------------------------------------------------------------------------
/** \brief Return tru if the function is conservative.
Conservative functions return always the same result for the same argument.
\throw nothrow
*/
bool ParserCallback::IsOptimizable() const
{
return m_bAllowOpti;
}
*/
bool ParserCallback::IsOptimizable() const { return m_bAllowOpti; }
//---------------------------------------------------------------------------
/** \brief Get the callback address for the parser function.
//---------------------------------------------------------------------------
/** \brief Get the callback address for the parser function.
The type of the address is void. It needs to be recasted according to the
argument number to the right type.
\throw nothrow
\return #pFun
*/
void* ParserCallback::GetAddr() const
{
return m_pFun;
}
*/
void* ParserCallback::GetAddr() const { return m_pFun; }
//---------------------------------------------------------------------------
/** \brief Return the callback code. */
ECmdCode ParserCallback::GetCode() const
{
return m_iCode;
}
//---------------------------------------------------------------------------
/** \brief Return the callback code. */
ECmdCode ParserCallback::GetCode() const { return m_iCode; }
//---------------------------------------------------------------------------
ETypeCode ParserCallback::GetType() const
{
return m_iType;
}
//---------------------------------------------------------------------------
ETypeCode ParserCallback::GetType() const { return m_iType; }
//---------------------------------------------------------------------------
/** \brief Return the operator precedence.
//---------------------------------------------------------------------------
/** \brief Return the operator precedence.
\throw nothrown
Only valid if the callback token is an operator token (binary or infix).
*/
int ParserCallback::GetPri() const
{
return m_iPri;
}
*/
int ParserCallback::GetPri() const { return m_iPri; }
//---------------------------------------------------------------------------
/** \brief Return the operators associativity.
//---------------------------------------------------------------------------
/** \brief Return the operators associativity.
\throw nothrown
Only valid if the callback token is a binary operator token.
*/
EOprtAssociativity ParserCallback::GetAssociativity() const
{
return m_eOprtAsct;
}
*/
EOprtAssociativity ParserCallback::GetAssociativity() const { return m_eOprtAsct; }
//---------------------------------------------------------------------------
/** \brief Returns the number of function Arguments. */
int ParserCallback::GetArgc() const
{
return m_iArgc;
}
//---------------------------------------------------------------------------
/** \brief Returns the number of function Arguments. */
int ParserCallback::GetArgc() const { return m_iArgc; }
} // namespace mu

File diff suppressed because it is too large Load diff

View file

@ -24,44 +24,33 @@
*/
#include "muParserError.h"
namespace mu {
const ParserErrorMsg ParserErrorMsg::m_Instance;
namespace mu
{
const ParserErrorMsg ParserErrorMsg::m_Instance;
//------------------------------------------------------------------------------
const ParserErrorMsg &ParserErrorMsg::Instance() { return m_Instance; }
//------------------------------------------------------------------------------
const ParserErrorMsg& ParserErrorMsg::Instance()
{
return m_Instance;
}
//------------------------------------------------------------------------------
string_type ParserErrorMsg::operator[](unsigned a_iIdx) const {
return (a_iIdx < m_vErrMsg.size()) ? m_vErrMsg[a_iIdx] : string_type();
}
//------------------------------------------------------------------------------
string_type ParserErrorMsg::operator[](unsigned a_iIdx) const
{
return (a_iIdx<m_vErrMsg.size()) ? m_vErrMsg[a_iIdx] : string_type();
}
//---------------------------------------------------------------------------
ParserErrorMsg::~ParserErrorMsg() {}
//---------------------------------------------------------------------------
ParserErrorMsg::~ParserErrorMsg()
{}
//---------------------------------------------------------------------------
/** \brief Assignement operator is deactivated.
*/
ParserErrorMsg& ParserErrorMsg::operator=(const ParserErrorMsg& )
{
//---------------------------------------------------------------------------
/** \brief Assignement operator is deactivated.
*/
ParserErrorMsg &ParserErrorMsg::operator=(const ParserErrorMsg &) {
assert(false);
return *this;
}
}
//---------------------------------------------------------------------------
ParserErrorMsg::ParserErrorMsg(const ParserErrorMsg&)
{}
//---------------------------------------------------------------------------
ParserErrorMsg::ParserErrorMsg(const ParserErrorMsg &) {}
//---------------------------------------------------------------------------
ParserErrorMsg::ParserErrorMsg()
:m_vErrMsg(0)
{
//---------------------------------------------------------------------------
ParserErrorMsg::ParserErrorMsg() : m_vErrMsg(0) {
m_vErrMsg.resize(ecCOUNT);
m_vErrMsg[ecUNASSIGNABLE_TOKEN] = _T("Unexpected token \"$TOK$\" found at position $POS$.");
@ -79,165 +68,158 @@ namespace mu
m_vErrMsg[ecUNEXPECTED_FUN] = _T("Unexpected function \"$TOK$\" at position $POS$");
m_vErrMsg[ecUNEXPECTED_VAL] = _T("Unexpected value \"$TOK$\" found at position $POS$");
m_vErrMsg[ecUNEXPECTED_VAR] = _T("Unexpected variable \"$TOK$\" found at position $POS$");
m_vErrMsg[ecUNEXPECTED_ARG] = _T("Function arguments used without a function (position: $POS$)");
m_vErrMsg[ecUNEXPECTED_ARG] =
_T("Function arguments used without a function (position: $POS$)");
m_vErrMsg[ecMISSING_PARENS] = _T("Missing parenthesis");
m_vErrMsg[ecTOO_MANY_PARAMS] = _T("Too many parameters for function \"$TOK$\" at expression position $POS$");
m_vErrMsg[ecTOO_FEW_PARAMS] = _T("Too few parameters for function \"$TOK$\" at expression position $POS$");
m_vErrMsg[ecTOO_MANY_PARAMS] =
_T("Too many parameters for function \"$TOK$\" at expression position $POS$");
m_vErrMsg[ecTOO_FEW_PARAMS] =
_T("Too few parameters for function \"$TOK$\" at expression position $POS$");
m_vErrMsg[ecDIV_BY_ZERO] = _T("Divide by zero");
m_vErrMsg[ecDOMAIN_ERROR] = _T("Domain error");
m_vErrMsg[ecNAME_CONFLICT] = _T("Name conflict");
m_vErrMsg[ecOPT_PRI] = _T("Invalid value for operator priority (must be greater or equal to zero).");
m_vErrMsg[ecBUILTIN_OVERLOAD] = _T("user defined binary operator \"$TOK$\" conflicts with a built in operator.");
m_vErrMsg[ecOPT_PRI] =
_T("Invalid value for operator priority (must be greater or equal to zero).");
m_vErrMsg[ecBUILTIN_OVERLOAD] =
_T("user defined binary operator \"$TOK$\" conflicts with a built in operator.");
m_vErrMsg[ecUNEXPECTED_STR] = _T("Unexpected string token found at position $POS$.");
m_vErrMsg[ecUNTERMINATED_STRING] = _T("Unterminated string starting at position $POS$.");
m_vErrMsg[ecSTRING_EXPECTED] = _T("String function called with a non string type of argument.");
m_vErrMsg[ecVAL_EXPECTED] = _T("String value used where a numerical argument is expected.");
m_vErrMsg[ecOPRT_TYPE_CONFLICT] = _T("No suitable overload for operator \"$TOK$\" at position $POS$.");
m_vErrMsg[ecOPRT_TYPE_CONFLICT] =
_T("No suitable overload for operator \"$TOK$\" at position $POS$.");
m_vErrMsg[ecSTR_RESULT] = _T("Function result is a string.");
m_vErrMsg[ecGENERIC] = _T("Parser error.");
m_vErrMsg[ecLOCALE] = _T("Decimal separator is identic to function argument separator.");
m_vErrMsg[ecUNEXPECTED_CONDITIONAL] = _T("The \"$TOK$\" operator must be preceeded by a closing bracket.");
m_vErrMsg[ecUNEXPECTED_CONDITIONAL] =
_T("The \"$TOK$\" operator must be preceeded by a closing bracket.");
m_vErrMsg[ecMISSING_ELSE_CLAUSE] = _T("If-then-else operator is missing an else clause");
m_vErrMsg[ecMISPLACED_COLON] = _T("Misplaced colon at position $POS$");
m_vErrMsg[ecUNREASONABLE_NUMBER_OF_COMPUTATIONS] = _T("Number of computations to small for bulk mode. (Vectorisation overhead too costly)");
m_vErrMsg[ecUNREASONABLE_NUMBER_OF_COMPUTATIONS] =
_T("Number of computations to small for bulk mode. (Vectorisation overhead too costly)");
#if defined(_DEBUG)
for (int i=0; i<ecCOUNT; ++i)
if (!m_vErrMsg[i].length())
assert(false);
#endif
}
#if defined(_DEBUG)
for (int i = 0; i < ecCOUNT; ++i)
if (!m_vErrMsg[i].length()) assert(false);
#endif
}
//---------------------------------------------------------------------------
//
// ParserError class
//
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
// ParserError class
//
//---------------------------------------------------------------------------
/** \brief Default constructor. */
ParserError::ParserError()
:m_strMsg()
,m_strFormula()
,m_strTok()
,m_iPos(-1)
,m_iErrc(ecUNDEFINED)
,m_ErrMsg(ParserErrorMsg::Instance())
{
}
/** \brief Default constructor. */
ParserError::ParserError()
: m_strMsg(),
m_strFormula(),
m_strTok(),
m_iPos(-1),
m_iErrc(ecUNDEFINED),
m_ErrMsg(ParserErrorMsg::Instance()) {}
//------------------------------------------------------------------------------
/** \brief This Constructor is used for internal exceptions only.
//------------------------------------------------------------------------------
/** \brief This Constructor is used for internal exceptions only.
It does not contain any information but the error code.
*/
ParserError::ParserError(EErrorCodes a_iErrc)
:m_strMsg()
,m_strFormula()
,m_strTok()
,m_iPos(-1)
,m_iErrc(a_iErrc)
,m_ErrMsg(ParserErrorMsg::Instance())
{
*/
ParserError::ParserError(EErrorCodes a_iErrc)
: m_strMsg(),
m_strFormula(),
m_strTok(),
m_iPos(-1),
m_iErrc(a_iErrc),
m_ErrMsg(ParserErrorMsg::Instance()) {
m_strMsg = m_ErrMsg[m_iErrc];
stringstream_type stream;
stream << (int)m_iPos;
ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());
ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);
}
}
//------------------------------------------------------------------------------
/** \brief Construct an error from a message text. */
ParserError::ParserError(const string_type &sMsg)
:m_ErrMsg(ParserErrorMsg::Instance())
{
//------------------------------------------------------------------------------
/** \brief Construct an error from a message text. */
ParserError::ParserError(const string_type &sMsg) : m_ErrMsg(ParserErrorMsg::Instance()) {
Reset();
m_strMsg = sMsg;
}
}
//------------------------------------------------------------------------------
/** \brief Construct an error object.
//------------------------------------------------------------------------------
/** \brief Construct an error object.
\param [in] a_iErrc the error code.
\param [in] sTok The token string related to this error.
\param [in] sExpr The expression related to the error.
\param [in] a_iPos the position in the expression where the error occurred.
*/
ParserError::ParserError( EErrorCodes iErrc,
const string_type &sTok,
const string_type &sExpr,
int iPos )
:m_strMsg()
,m_strFormula(sExpr)
,m_strTok(sTok)
,m_iPos(iPos)
,m_iErrc(iErrc)
,m_ErrMsg(ParserErrorMsg::Instance())
{
*/
ParserError::ParserError(EErrorCodes iErrc, const string_type &sTok, const string_type &sExpr,
int iPos)
: m_strMsg(),
m_strFormula(sExpr),
m_strTok(sTok),
m_iPos(iPos),
m_iErrc(iErrc),
m_ErrMsg(ParserErrorMsg::Instance()) {
m_strMsg = m_ErrMsg[m_iErrc];
stringstream_type stream;
stream << (int)m_iPos;
ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());
ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);
}
}
//------------------------------------------------------------------------------
/** \brief Construct an error object.
//------------------------------------------------------------------------------
/** \brief Construct an error object.
\param [in] iErrc the error code.
\param [in] iPos the position in the expression where the error occurred.
\param [in] sTok The token string related to this error.
*/
ParserError::ParserError(EErrorCodes iErrc, int iPos, const string_type &sTok)
:m_strMsg()
,m_strFormula()
,m_strTok(sTok)
,m_iPos(iPos)
,m_iErrc(iErrc)
,m_ErrMsg(ParserErrorMsg::Instance())
{
*/
ParserError::ParserError(EErrorCodes iErrc, int iPos, const string_type &sTok)
: m_strMsg(),
m_strFormula(),
m_strTok(sTok),
m_iPos(iPos),
m_iErrc(iErrc),
m_ErrMsg(ParserErrorMsg::Instance()) {
m_strMsg = m_ErrMsg[m_iErrc];
stringstream_type stream;
stream << (int)m_iPos;
ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());
ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);
}
}
//------------------------------------------------------------------------------
/** \brief Construct an error object.
//------------------------------------------------------------------------------
/** \brief Construct an error object.
\param [in] szMsg The error message text.
\param [in] iPos the position related to the error.
\param [in] sTok The token string related to this error.
*/
ParserError::ParserError(const char_type *szMsg, int iPos, const string_type &sTok)
:m_strMsg(szMsg)
,m_strFormula()
,m_strTok(sTok)
,m_iPos(iPos)
,m_iErrc(ecGENERIC)
,m_ErrMsg(ParserErrorMsg::Instance())
{
*/
ParserError::ParserError(const char_type *szMsg, int iPos, const string_type &sTok)
: m_strMsg(szMsg),
m_strFormula(),
m_strTok(sTok),
m_iPos(iPos),
m_iErrc(ecGENERIC),
m_ErrMsg(ParserErrorMsg::Instance()) {
stringstream_type stream;
stream << (int)m_iPos;
ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());
ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);
}
}
//------------------------------------------------------------------------------
/** \brief Copy constructor. */
ParserError::ParserError(const ParserError &a_Obj)
:m_strMsg(a_Obj.m_strMsg)
,m_strFormula(a_Obj.m_strFormula)
,m_strTok(a_Obj.m_strTok)
,m_iPos(a_Obj.m_iPos)
,m_iErrc(a_Obj.m_iErrc)
,m_ErrMsg(ParserErrorMsg::Instance())
{
}
//------------------------------------------------------------------------------
/** \brief Copy constructor. */
ParserError::ParserError(const ParserError &a_Obj)
: m_strMsg(a_Obj.m_strMsg),
m_strFormula(a_Obj.m_strFormula),
m_strTok(a_Obj.m_strTok),
m_iPos(a_Obj.m_iPos),
m_iErrc(a_Obj.m_iErrc),
m_ErrMsg(ParserErrorMsg::Instance()) {}
//------------------------------------------------------------------------------
/** \brief Assignment operator. */
ParserError& ParserError::operator=(const ParserError &a_Obj)
{
if (this==&a_Obj)
return *this;
//------------------------------------------------------------------------------
/** \brief Assignment operator. */
ParserError &ParserError::operator=(const ParserError &a_Obj) {
if (this == &a_Obj) return *this;
m_strMsg = a_Obj.m_strMsg;
m_strFormula = a_Obj.m_strFormula;
@ -245,92 +227,68 @@ namespace mu
m_iPos = a_Obj.m_iPos;
m_iErrc = a_Obj.m_iErrc;
return *this;
}
}
//------------------------------------------------------------------------------
ParserError::~ParserError()
{}
//------------------------------------------------------------------------------
ParserError::~ParserError() {}
//------------------------------------------------------------------------------
/** \brief Replace all occurrences of a substring with another string.
//------------------------------------------------------------------------------
/** \brief Replace all occurrences of a substring with another string.
\param strFind The string that shall be replaced.
\param strReplaceWith The string that should be inserted instead of strFind
*/
void ParserError::ReplaceSubString( string_type &strSource,
const string_type &strFind,
const string_type &strReplaceWith)
{
*/
void ParserError::ReplaceSubString(string_type &strSource, const string_type &strFind,
const string_type &strReplaceWith) {
string_type strResult;
string_type::size_type iPos(0), iNext(0);
for(;;)
{
for (;;) {
iNext = strSource.find(strFind, iPos);
strResult.append(strSource, iPos, iNext-iPos);
strResult.append(strSource, iPos, iNext - iPos);
if( iNext==string_type::npos )
break;
if (iNext == string_type::npos) break;
strResult.append(strReplaceWith);
iPos = iNext + strFind.length();
}
strSource.swap(strResult);
}
}
//------------------------------------------------------------------------------
/** \brief Reset the erro object. */
void ParserError::Reset()
{
//------------------------------------------------------------------------------
/** \brief Reset the erro object. */
void ParserError::Reset() {
m_strMsg = _T("");
m_strFormula = _T("");
m_strTok = _T("");
m_iPos = -1;
m_iErrc = ecUNDEFINED;
}
}
//------------------------------------------------------------------------------
/** \brief Set the expression related to this error. */
void ParserError::SetFormula(const string_type &a_strFormula)
{
m_strFormula = a_strFormula;
}
//------------------------------------------------------------------------------
/** \brief Set the expression related to this error. */
void ParserError::SetFormula(const string_type &a_strFormula) { m_strFormula = a_strFormula; }
//------------------------------------------------------------------------------
/** \brief gets the expression related tp this error.*/
const string_type& ParserError::GetExpr() const
{
return m_strFormula;
}
//------------------------------------------------------------------------------
/** \brief gets the expression related tp this error.*/
const string_type &ParserError::GetExpr() const { return m_strFormula; }
//------------------------------------------------------------------------------
/** \brief Returns the message string for this error. */
const string_type& ParserError::GetMsg() const
{
return m_strMsg;
}
//------------------------------------------------------------------------------
/** \brief Returns the message string for this error. */
const string_type &ParserError::GetMsg() const { return m_strMsg; }
//------------------------------------------------------------------------------
/** \brief Return the formula position related to the error.
//------------------------------------------------------------------------------
/** \brief Return the formula position related to the error.
If the error is not related to a distinct position this will return -1
*/
int ParserError::GetPos() const
{
return m_iPos;
}
*/
int ParserError::GetPos() const { return m_iPos; }
//------------------------------------------------------------------------------
/** \brief Return string related with this token (if available). */
const string_type& ParserError::GetToken() const
{
return m_strTok;
}
//------------------------------------------------------------------------------
/** \brief Return string related with this token (if available). */
const string_type &ParserError::GetToken() const { return m_strTok; }
//------------------------------------------------------------------------------
/** \brief Return the error code. */
EErrorCodes ParserError::GetCode() const
{
return m_iErrc;
}
//------------------------------------------------------------------------------
/** \brief Return the error code. */
EErrorCodes ParserError::GetCode() const { return m_iErrc; }
} // namespace mu

View file

@ -25,8 +25,8 @@
#include "muParserInt.h"
#include <cmath>
#include <algorithm>
#include <cmath>
#include <numeric>
using namespace std;
@ -36,13 +36,12 @@ using namespace std;
*/
/** \brief Namespace for mathematical applications. */
namespace mu
{
namespace mu {
value_type ParserInt::Abs(value_type v) { return (value_type)Round(fabs((double)v)); }
value_type ParserInt::Sign(value_type v) { return (Round(v)<0) ? -1 : (Round(v)>0) ? 1 : 0; }
value_type ParserInt::Ite(value_type v1,
value_type v2,
value_type v3) { return (Round(v1)==1) ? Round(v2) : Round(v3); }
value_type ParserInt::Sign(value_type v) { return (Round(v) < 0) ? -1 : (Round(v) > 0) ? 1 : 0; }
value_type ParserInt::Ite(value_type v1, value_type v2, value_type v3) {
return (Round(v1) == 1) ? Round(v2) : Round(v3);
}
value_type ParserInt::Add(value_type v1, value_type v2) { return Round(v1) + Round(v2); }
value_type ParserInt::Sub(value_type v1, value_type v2) { return Round(v1) - Round(v2); }
value_type ParserInt::Mul(value_type v1, value_type v2) { return Round(v1) * Round(v2); }
@ -62,80 +61,62 @@ value_type ParserInt::Equal(value_type v1, value_type v2) { return Round(v1)
value_type ParserInt::NotEqual(value_type v1, value_type v2) { return Round(v1) != Round(v2); }
value_type ParserInt::Not(value_type v) { return !Round(v); }
value_type ParserInt::Pow(value_type v1, value_type v2)
{
value_type ParserInt::Pow(value_type v1, value_type v2) {
return std::pow((double)Round(v1), (double)Round(v2));
}
//---------------------------------------------------------------------------
// Unary operator Callbacks: Infix operators
value_type ParserInt::UnaryMinus(value_type v)
{
return -Round(v);
}
value_type ParserInt::UnaryMinus(value_type v) { return -Round(v); }
//---------------------------------------------------------------------------
value_type ParserInt::Sum(const value_type* a_afArg, int a_iArgc)
{
if (!a_iArgc)
throw ParserError(_T("too few arguments for function sum."));
value_type ParserInt::Sum(const value_type *a_afArg, int a_iArgc) {
if (!a_iArgc) throw ParserError(_T("too few arguments for function sum."));
value_type fRes=0;
for (int i=0; i<a_iArgc; ++i)
fRes += a_afArg[i];
value_type fRes = 0;
for (int i = 0; i < a_iArgc; ++i) fRes += a_afArg[i];
return fRes;
}
//---------------------------------------------------------------------------
value_type ParserInt::Min(const value_type* a_afArg, int a_iArgc)
{
if (!a_iArgc)
throw ParserError( _T("too few arguments for function min.") );
value_type ParserInt::Min(const value_type *a_afArg, int a_iArgc) {
if (!a_iArgc) throw ParserError(_T("too few arguments for function min."));
value_type fRes=a_afArg[0];
for (int i=0; i<a_iArgc; ++i)
fRes = std::min(fRes, a_afArg[i]);
value_type fRes = a_afArg[0];
for (int i = 0; i < a_iArgc; ++i) fRes = std::min(fRes, a_afArg[i]);
return fRes;
}
//---------------------------------------------------------------------------
value_type ParserInt::Max(const value_type* a_afArg, int a_iArgc)
{
if (!a_iArgc)
throw ParserError(_T("too few arguments for function min."));
value_type ParserInt::Max(const value_type *a_afArg, int a_iArgc) {
if (!a_iArgc) throw ParserError(_T("too few arguments for function min."));
value_type fRes=a_afArg[0];
for (int i=0; i<a_iArgc; ++i)
fRes = std::max(fRes, a_afArg[i]);
value_type fRes = a_afArg[0];
for (int i = 0; i < a_iArgc; ++i) fRes = std::max(fRes, a_afArg[i]);
return fRes;
}
//---------------------------------------------------------------------------
// Default value recognition callback
int ParserInt::IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
{
int ParserInt::IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal) {
string_type buf(a_szExpr);
std::size_t pos = buf.find_first_not_of(_T("0123456789"));
if (pos==std::string::npos)
return 0;
if (pos == std::string::npos) return 0;
stringstream_type stream( buf.substr(0, pos ) );
stringstream_type stream(buf.substr(0, pos));
int iVal(0);
stream >> iVal;
if (stream.fail())
return 0;
if (stream.fail()) return 0;
stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading
if (stream.fail())
iEnd = stream.str().length();
if (stream.fail()) iEnd = stream.str().length();
if (iEnd==(stringstream_type::pos_type)-1)
return 0;
if (iEnd == (stringstream_type::pos_type)-1) return 0;
*a_iPos += (int)iEnd;
*a_fVal = (value_type)iVal;
@ -152,10 +133,8 @@ int ParserInt::IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
Hey values must be prefixed with "0x" in order to be detected properly.
*/
int ParserInt::IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
{
if (a_szExpr[1]==0 || (a_szExpr[0]!='0' || a_szExpr[1]!='x') )
return 0;
int ParserInt::IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal) {
if (a_szExpr[1] == 0 || (a_szExpr[0] != '0' || a_szExpr[1] != 'x')) return 0;
unsigned iVal(0);
@ -165,8 +144,7 @@ int ParserInt::IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fV
ss >> std::hex >> iVal;
nPos = ss.tellg();
if (nPos==(stringstream_type::pos_type)0)
return 1;
if (nPos == (stringstream_type::pos_type)0) return 1;
*a_iPos += (int)(2 + nPos);
*a_fVal = (value_type)iVal;
@ -174,26 +152,20 @@ int ParserInt::IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fV
}
//---------------------------------------------------------------------------
int ParserInt::IsBinVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)
{
if (a_szExpr[0]!='#')
return 0;
int ParserInt::IsBinVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal) {
if (a_szExpr[0] != '#') return 0;
unsigned iVal(0),
iBits(sizeof(iVal)*8),
i(0);
unsigned iVal(0), iBits(sizeof(iVal) * 8), i(0);
for (i=0; (a_szExpr[i+1]=='0' || a_szExpr[i+1]=='1') && i<iBits; ++i)
iVal |= (int)(a_szExpr[i+1]=='1') << ((iBits-1)-i);
for (i = 0; (a_szExpr[i + 1] == '0' || a_szExpr[i + 1] == '1') && i < iBits; ++i)
iVal |= (int)(a_szExpr[i + 1] == '1') << ((iBits - 1) - i);
if (i==0)
return 0;
if (i == 0) return 0;
if (i==iBits)
throw exception_type(_T("Binary to integer conversion error (overflow)."));
if (i == iBits) throw exception_type(_T("Binary to integer conversion error (overflow)."));
*a_fVal = (unsigned)(iVal >> (iBits-i) );
*a_iPos += i+1;
*a_fVal = (unsigned)(iVal >> (iBits - i));
*a_iPos += i + 1;
return 1;
}
@ -203,9 +175,7 @@ int ParserInt::IsBinVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fV
Call ParserBase class constructor and trigger Function, Operator and Constant initialization.
*/
ParserInt::ParserInt()
:ParserBase()
{
ParserInt::ParserInt() : ParserBase() {
AddValIdent(IsVal); // lowest priority
AddValIdent(IsBinVal);
AddValIdent(IsHexVal); // highest priority
@ -216,65 +186,60 @@ ParserInt::ParserInt()
}
//---------------------------------------------------------------------------
void ParserInt::InitConst()
{
}
void ParserInt::InitConst() {}
//---------------------------------------------------------------------------
void ParserInt::InitCharSets()
{
DefineNameChars( _T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") );
DefineOprtChars( _T("+-*^/?<>=!%&|~'_") );
DefineInfixOprtChars( _T("/+-*^?<>=!%&|~'_") );
void ParserInt::InitCharSets() {
DefineNameChars(_T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"));
DefineOprtChars(_T("+-*^/?<>=!%&|~'_"));
DefineInfixOprtChars(_T("/+-*^?<>=!%&|~'_"));
}
//---------------------------------------------------------------------------
/** \brief Initialize the default functions. */
void ParserInt::InitFun()
{
DefineFun( _T("sign"), Sign);
DefineFun( _T("abs"), Abs);
DefineFun( _T("if"), Ite);
DefineFun( _T("sum"), Sum);
DefineFun( _T("min"), Min);
DefineFun( _T("max"), Max);
void ParserInt::InitFun() {
DefineFun(_T("sign"), Sign);
DefineFun(_T("abs"), Abs);
DefineFun(_T("if"), Ite);
DefineFun(_T("sum"), Sum);
DefineFun(_T("min"), Min);
DefineFun(_T("max"), Max);
}
//---------------------------------------------------------------------------
/** \brief Initialize operators. */
void ParserInt::InitOprt()
{
void ParserInt::InitOprt() {
// disable all built in operators, not all of them useful for integer numbers
// (they don't do rounding of values)
EnableBuiltInOprt(false);
// Disable all built in operators, they wont work with integer numbers
// since they are designed for floating point numbers
DefineInfixOprt( _T("-"), UnaryMinus);
DefineInfixOprt( _T("!"), Not);
DefineInfixOprt(_T("-"), UnaryMinus);
DefineInfixOprt(_T("!"), Not);
DefineOprt( _T("&"), LogAnd, prLOGIC);
DefineOprt( _T("|"), LogOr, prLOGIC);
DefineOprt( _T("&&"), And, prLOGIC);
DefineOprt( _T("||"), Or, prLOGIC);
DefineOprt(_T("&"), LogAnd, prLOGIC);
DefineOprt(_T("|"), LogOr, prLOGIC);
DefineOprt(_T("&&"), And, prLOGIC);
DefineOprt(_T("||"), Or, prLOGIC);
DefineOprt( _T("<"), Less, prCMP);
DefineOprt( _T(">"), Greater, prCMP);
DefineOprt( _T("<="), LessEq, prCMP);
DefineOprt( _T(">="), GreaterEq, prCMP);
DefineOprt( _T("=="), Equal, prCMP);
DefineOprt( _T("!="), NotEqual, prCMP);
DefineOprt(_T("<"), Less, prCMP);
DefineOprt(_T(">"), Greater, prCMP);
DefineOprt(_T("<="), LessEq, prCMP);
DefineOprt(_T(">="), GreaterEq, prCMP);
DefineOprt(_T("=="), Equal, prCMP);
DefineOprt(_T("!="), NotEqual, prCMP);
DefineOprt( _T("+"), Add, prADD_SUB);
DefineOprt( _T("-"), Sub, prADD_SUB);
DefineOprt(_T("+"), Add, prADD_SUB);
DefineOprt(_T("-"), Sub, prADD_SUB);
DefineOprt( _T("*"), Mul, prMUL_DIV);
DefineOprt( _T("/"), Div, prMUL_DIV);
DefineOprt( _T("%"), Mod, prMUL_DIV);
DefineOprt(_T("*"), Mul, prMUL_DIV);
DefineOprt(_T("/"), Div, prMUL_DIV);
DefineOprt(_T("%"), Mod, prMUL_DIV);
DefineOprt( _T("^"), Pow, prPOW, oaRIGHT);
DefineOprt( _T(">>"), Shr, prMUL_DIV+1);
DefineOprt( _T("<<"), Shl, prMUL_DIV+1);
DefineOprt(_T("^"), Pow, prPOW, oaRIGHT);
DefineOprt(_T(">>"), Shr, prMUL_DIV + 1);
DefineOprt(_T("<<"), Shl, prMUL_DIV + 1);
}
} // namespace mu

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff