diff --git a/muparser-2.2.5/include/muParser.h b/muparser-2.2.5/include/muParser.h index 42e0cbe1c..3b8ad7120 100644 --- a/muparser-2.2.5/include/muParser.h +++ b/muparser-2.2.5/include/muParser.h @@ -57,49 +57,49 @@ 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; + ValueOrError 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); - static value_type Tan(value_type); - static value_type Tan2(value_type, value_type); + static ValueOrError Sin(value_type); + static ValueOrError Cos(value_type); + static ValueOrError Tan(value_type); + static ValueOrError Tan2(value_type, value_type); // arcus functions - static value_type ASin(value_type); - static value_type ACos(value_type); - static value_type ATan(value_type); - static value_type ATan2(value_type, value_type); + static ValueOrError ASin(value_type); + static ValueOrError ACos(value_type); + static ValueOrError ATan(value_type); + static ValueOrError ATan2(value_type, value_type); // hyperbolic functions - static value_type Sinh(value_type); - static value_type Cosh(value_type); - static value_type Tanh(value_type); + static ValueOrError Sinh(value_type); + static ValueOrError Cosh(value_type); + static ValueOrError Tanh(value_type); // arcus hyperbolic functions - static value_type ASinh(value_type); - static value_type ACosh(value_type); - static value_type ATanh(value_type); + static ValueOrError ASinh(value_type); + static ValueOrError ACosh(value_type); + static ValueOrError ATanh(value_type); // Logarithm functions - static value_type Log2(value_type); // Logarithm Base 2 - static value_type Log10(value_type); // Logarithm Base 10 - static value_type Ln(value_type); // Logarithm Base e (natural logarithm) + static ValueOrError Log2(value_type); // Logarithm Base 2 + static ValueOrError Log10(value_type); // Logarithm Base 10 + static ValueOrError Ln(value_type); // Logarithm Base e (natural logarithm) // misc - static value_type Exp(value_type); - static value_type Abs(value_type); - static value_type Sqrt(value_type); - static value_type Rint(value_type); - static value_type Sign(value_type); + static ValueOrError Exp(value_type); + static ValueOrError Abs(value_type); + static ValueOrError Sqrt(value_type); + static ValueOrError Rint(value_type); + static ValueOrError Sign(value_type); // Prefix operators // !!! Unary Minus is a MUST if you want to use negative signs !!! - static value_type UnaryMinus(value_type); - static value_type UnaryPlus(value_type); + static ValueOrError UnaryMinus(value_type); + static ValueOrError 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 ValueOrError Sum(const value_type *, int); // sum + static ValueOrError Avg(const value_type *, int); // mean value + static ValueOrError Min(const value_type *, int); // minimum + static ValueOrError Max(const value_type *, int); // maximum static int IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal); }; diff --git a/muparser-2.2.5/include/muParserDLL.h b/muparser-2.2.5/include/muParserDLL.h index 7dae903f4..caaccd9d2 100644 --- a/muparser-2.2.5/include/muParserDLL.h +++ b/muparser-2.2.5/include/muParserDLL.h @@ -55,28 +55,29 @@ typedef wchar_t muChar_t; // character type typedef int muBool_t; // boolean type typedef int muInt_t; // integer type typedef double muFloat_t; // floating point type +using mu::ValueOrError; // 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 ValueOrError (*muFun0_t)(); +typedef ValueOrError (*muFun1_t)(muFloat_t); +typedef ValueOrError (*muFun2_t)(muFloat_t, muFloat_t); +typedef ValueOrError (*muFun3_t)(muFloat_t, muFloat_t, muFloat_t); +typedef ValueOrError (*muFun4_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t); +typedef ValueOrError (*muFun5_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); +typedef ValueOrError (*muFun6_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); +typedef ValueOrError (*muFun7_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, + muFloat_t); +typedef ValueOrError (*muFun8_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, + muFloat_t, muFloat_t); +typedef ValueOrError (*muFun9_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, + muFloat_t, muFloat_t, muFloat_t); +typedef ValueOrError (*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 (*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 ValueOrError (*muMultFun_t)(const muFloat_t *, muInt_t); +typedef ValueOrError (*muStrFun1_t)(const muChar_t *); +typedef ValueOrError (*muStrFun2_t)(const muChar_t *, muFloat_t); +typedef ValueOrError (*muStrFun3_t)(const muChar_t *, muFloat_t, muFloat_t); // Functions for parser management typedef void (*muErrorHandler_t)( diff --git a/muparser-2.2.5/include/muParserDef.h b/muparser-2.2.5/include/muParserDef.h index 6666df808..712dc67d8 100644 --- a/muparser-2.2.5/include/muParserDef.h +++ b/muparser-2.2.5/include/muParserDef.h @@ -25,8 +25,10 @@ #ifndef MUP_DEF_H #define MUP_DEF_H +#include #include #include +#include #include #include #include @@ -352,60 +354,137 @@ class ParserError { EErrorCodes m_iErrc; ///< Error code }; +// Compatibility with non-clang compilers. +#ifndef __has_attribute +#define __has_attribute(x) 0 +#endif + +// Define a type-level attribute declaring that this type, when used as the return value +// of a function, should produce warnings. +#if __has_attribute(warn_unused_result) +#define MUPARSER_ATTR_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +#define MUPARSER_ATTR_WARN_UNUSED_RESULT +#endif + +// OptionalError is used to optionally encapsulate an error. +class OptionalError { + std::unique_ptr error_{}; + + public: + /// Create an OptionalError that represents no error. + OptionalError() {} + + /// Create an OptionalError for the given error. + /* implicit */ OptionalError(ParserError err) : error_(new ParserError(std::move(err))) {} + + /// \return whether an error is present. + bool has_error() const { return bool(error_); } + + /// \return the error. asserts if this is not an error. + const ParserError &error() const { + assert(error_ && "Value did not error"); + return *error_; + } +} MUPARSER_ATTR_WARN_UNUSED_RESULT; + +// ValueOrError is used to propagate failures to callers. +class ValueOrError { + value_type value_{0}; + OptionalError error_{}; + + public: + /// \return true if this has a value, false if it is an error. + bool has_value() const { return !error_.has_error(); } + + /// \return false if this has a value,true if it is an error. + bool has_error() const { return error_.has_error(); } + + /// Construct from a value. + /* implicit */ ValueOrError(value_type value) : value_(value) {} + + /// Construct from an error. + /* implicit */ ValueOrError(ParserError err) : error_(std::move(err)) {} + + /// \return the error. asserts if this is not an error. + const ParserError &error() const { return error_.error(); } + + /// \return the value. asserts if this is an error. + value_type value() const { + assert(has_value() && "Value is an error"); + return value_; + } + + /// \return the value or throw the error + value_type getOrThrow() const { + if (has_error()) throw error(); + return value(); + } + + /// \return whether this has a value. + explicit operator bool() const { return has_value(); } + + value_type operator*() const { + assert(has_value() && "Cannot access value with error"); + return value_; + } + +} MUPARSER_ATTR_WARN_UNUSED_RESULT; + // Parser callbacks /** \brief Callback type used for functions without arguments. */ -typedef value_type (*generic_fun_type)(); +typedef ValueOrError (*generic_fun_type)(); /** \brief Callback type used for functions without arguments. */ -typedef value_type (*fun_type0)(); +typedef ValueOrError (*fun_type0)(); /** \brief Callback type used for functions with a single arguments. */ -typedef value_type (*fun_type1)(value_type); +typedef ValueOrError (*fun_type1)(value_type); /** \brief Callback type used for functions with two arguments. */ -typedef value_type (*fun_type2)(value_type, value_type); +typedef ValueOrError (*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); +typedef ValueOrError (*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); +typedef ValueOrError (*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); +typedef ValueOrError (*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); +typedef ValueOrError (*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); +typedef ValueOrError (*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); +typedef ValueOrError (*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); +typedef ValueOrError (*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); +typedef ValueOrError (*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 a variable argument list. */ -typedef value_type (*multfun_type)(const value_type *, int); +typedef ValueOrError (*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 *); +typedef ValueOrError (*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); +typedef ValueOrError (*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); +typedef ValueOrError (*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); diff --git a/muparser-2.2.5/include/muParserInt.h b/muparser-2.2.5/include/muParserInt.h index 6869fd67e..c1f687669 100644 --- a/muparser-2.2.5/include/muParserInt.h +++ b/muparser-2.2.5/include/muParserInt.h @@ -45,36 +45,36 @@ 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); - static value_type Ite(value_type, value_type, value_type); + static ValueOrError Abs(value_type); + static ValueOrError Sign(value_type); + static ValueOrError Ite(value_type, value_type, value_type); // !! The unary Minus is a MUST, otherwise you cant use negative signs !! - static value_type UnaryMinus(value_type); + static ValueOrError UnaryMinus(value_type); // Functions with variable number of arguments - static value_type Sum(const value_type* a_afArg, int a_iArgc); // sum - static value_type Min(const value_type* a_afArg, int a_iArgc); // minimum - static value_type Max(const value_type* a_afArg, int a_iArgc); // maximum + static ValueOrError Sum(const value_type* a_afArg, int a_iArgc); // sum + static ValueOrError Min(const value_type* a_afArg, int a_iArgc); // minimum + static ValueOrError Max(const value_type* a_afArg, int a_iArgc); // maximum // binary operator callbacks - static value_type Add(value_type v1, value_type v2); - static value_type Sub(value_type v1, value_type v2); - static value_type Mul(value_type v1, value_type v2); - static value_type Div(value_type v1, value_type v2); - static value_type Mod(value_type v1, value_type v2); - static value_type Pow(value_type v1, value_type v2); - static value_type Shr(value_type v1, value_type v2); - static value_type Shl(value_type v1, value_type v2); - static value_type LogAnd(value_type v1, value_type v2); - static value_type LogOr(value_type v1, value_type v2); - static value_type And(value_type v1, value_type v2); - static value_type Or(value_type v1, value_type v2); - static value_type Xor(value_type v1, value_type v2); - static value_type Less(value_type v1, value_type v2); - static value_type Greater(value_type v1, value_type v2); - static value_type LessEq(value_type v1, value_type v2); - static value_type GreaterEq(value_type v1, value_type v2); - static value_type Equal(value_type v1, value_type v2); - static value_type NotEqual(value_type v1, value_type v2); - static value_type Not(value_type v1); + static ValueOrError Add(value_type v1, value_type v2); + static ValueOrError Sub(value_type v1, value_type v2); + static ValueOrError Mul(value_type v1, value_type v2); + static ValueOrError Div(value_type v1, value_type v2); + static ValueOrError Mod(value_type v1, value_type v2); + static ValueOrError Pow(value_type v1, value_type v2); + static ValueOrError Shr(value_type v1, value_type v2); + static ValueOrError Shl(value_type v1, value_type v2); + static ValueOrError LogAnd(value_type v1, value_type v2); + static ValueOrError LogOr(value_type v1, value_type v2); + static ValueOrError And(value_type v1, value_type v2); + static ValueOrError Or(value_type v1, value_type v2); + static ValueOrError Xor(value_type v1, value_type v2); + static ValueOrError Less(value_type v1, value_type v2); + static ValueOrError Greater(value_type v1, value_type v2); + static ValueOrError LessEq(value_type v1, value_type v2); + static ValueOrError GreaterEq(value_type v1, value_type v2); + static ValueOrError Equal(value_type v1, value_type v2); + static ValueOrError NotEqual(value_type v1, value_type v2); + static ValueOrError 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); diff --git a/muparser-2.2.5/include/muParserTest.h b/muparser-2.2.5/include/muParserTest.h index 2ad907b80..ff6738784 100644 --- a/muparser-2.2.5/include/muParserTest.h +++ b/muparser-2.2.5/include/muParserTest.h @@ -50,65 +50,65 @@ class ParserTester // final static int c_iCount; // Multiarg callbacks - static value_type f1of1(value_type v) { return v; }; + static ValueOrError 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 ValueOrError f1of2(value_type v, value_type) { return v; }; + static ValueOrError 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 ValueOrError f1of3(value_type v, value_type, value_type) { return v; }; + static ValueOrError f2of3(value_type, value_type v, value_type) { return v; }; + static ValueOrError 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 ValueOrError f1of4(value_type v, value_type, value_type, value_type) { return v; } + static ValueOrError f2of4(value_type, value_type v, value_type, value_type) { return v; } + static ValueOrError f3of4(value_type, value_type, value_type v, value_type) { return v; } + static ValueOrError 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) { + static ValueOrError 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) { + static ValueOrError 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) { + static ValueOrError 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) { + static ValueOrError 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) { + static ValueOrError 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) { + static ValueOrError 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) { + static ValueOrError 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 sign(value_type v) { return -v; } - 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 ValueOrError plus2(value_type v1) { return v1 + 2; } + static ValueOrError times3(value_type v1) { return v1 * 3; } + static ValueOrError sqr(value_type v1) { return v1 * v1; } + static ValueOrError sign(value_type v) { return -v; } + static ValueOrError add(value_type v1, value_type v2) { return v1 + v2; } + static ValueOrError 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 ValueOrError FirstArg(const value_type* a_afArg, int a_iArgc) { if (!a_iArgc) 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 ValueOrError LastArg(const value_type* a_afArg, int a_iArgc) { if (!a_iArgc) throw mu::Parser::exception_type(_T("too few arguments for function LastArg.")); return a_afArg[a_iArgc - 1]; } - static value_type Sum(const value_type* a_afArg, int a_iArgc) { + static ValueOrError 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; @@ -116,46 +116,46 @@ class ParserTester // final return fRes; } - static value_type Rnd(value_type v) { + static ValueOrError Rnd(value_type v) { return (value_type)(1 + (v * std::rand() / (RAND_MAX + 1.0))); } - static value_type RndWithString(const char_type*) { + static ValueOrError RndWithString(const char_type*) { return (value_type)(1 + (1000.0f * std::rand() / (RAND_MAX + 1.0))); } - static value_type Ping() { return 10; } + static ValueOrError Ping() { return 10; } - static value_type ValueOf(const char_type*) { return 123; } + static ValueOrError ValueOf(const char_type*) { return 123; } - static value_type StrFun1(const char_type* v1) { + static ValueOrError 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 ValueOrError 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 ValueOrError 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 ValueOrError StrToFloat(const char_type* a_szMsg) { value_type val(0); stringstream_type(a_szMsg) >> val; return val; } // postfix operator callback - static value_type Mega(value_type a_fVal) { return a_fVal * (value_type)1e6; } - static value_type Micro(value_type a_fVal) { return a_fVal * (value_type)1e-6; } - static value_type Milli(value_type a_fVal) { return a_fVal / (value_type)1e3; } + static ValueOrError Mega(value_type a_fVal) { return a_fVal * (value_type)1e6; } + static ValueOrError Micro(value_type a_fVal) { return a_fVal * (value_type)1e-6; } + static ValueOrError 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); diff --git a/muparser-2.2.5/samples/example1/example1.cpp b/muparser-2.2.5/samples/example1/example1.cpp index aa77d0510..c54ad3e1e 100644 --- a/muparser-2.2.5/samples/example1/example1.cpp +++ b/muparser-2.2.5/samples/example1/example1.cpp @@ -56,39 +56,40 @@ struct DumpLeaks { #endif // Operator callback functions -value_type Mega(value_type a_fVal) { return a_fVal * 1e6; } -value_type Milli(value_type a_fVal) { return a_fVal / (value_type)1e3; } -value_type Rnd(value_type v) { return v * std::rand() / (value_type)(RAND_MAX + 1.0); } -value_type Not(value_type v) { return v == 0; } -value_type Add(value_type v1, value_type v2) { return v1 + v2; } -value_type Mul(value_type v1, value_type v2) { return v1 * v2; } +ValueOrError Mega(value_type a_fVal) { return a_fVal * 1e6; } +ValueOrError Milli(value_type a_fVal) { return a_fVal / (value_type)1e3; } +ValueOrError Rnd(value_type v) { return v * std::rand() / (value_type)(RAND_MAX + 1.0); } +ValueOrError Not(value_type v) { return v == 0; } +ValueOrError Add(value_type v1, value_type v2) { return v1 + v2; } +ValueOrError Mul(value_type v1, value_type v2) { return v1 * v2; } //--------------------------------------------------------------------------- -value_type ThrowAnException(value_type) { +ValueOrError ThrowAnException(value_type) { throw std::runtime_error("This function does throw an exception."); } //--------------------------------------------------------------------------- -value_type Ping() { +//--------------------------------------------------------------------------- +ValueOrError Ping() { mu::console() << "ping\n"; return 0; } //--------------------------------------------------------------------------- -value_type StrFun0(const char_type *szMsg) { +ValueOrError StrFun0(const char_type *szMsg) { if (szMsg) mu::console() << szMsg << std::endl; return 999; } //--------------------------------------------------------------------------- -value_type StrFun2(const char_type *v1, value_type v2, value_type v3) { +ValueOrError StrFun2(const char_type *v1, value_type v2, value_type v3) { mu::console() << v1 << std::endl; return v2 + v3; } //--------------------------------------------------------------------------- -value_type Debug(mu::value_type v1, mu::value_type v2) { +ValueOrError Debug(mu::value_type v1, mu::value_type v2) { ParserBase::EnableDebugDump(v1 != 0, v2 != 0); mu::console() << _T("Bytecode dumping ") << ((v1 != 0) ? _T("active") : _T("inactive")) << _T("\n"); @@ -153,7 +154,7 @@ void Splash() { } //--------------------------------------------------------------------------- -value_type SelfTest() { +ValueOrError SelfTest() { mu::console() << _T( "-----------------------------------------------------------\n"); mu::console() << _T( "Running test suite:\n\n"); @@ -170,7 +171,7 @@ value_type SelfTest() { } //--------------------------------------------------------------------------- -value_type Help() { +ValueOrError Help() { mu::console() << _T( "-----------------------------------------------------------\n"); mu::console() << _T( "Commands:\n\n"); mu::console() << _T( " list var - list parser variables\n"); diff --git a/muparser-2.2.5/src/muParser.cpp b/muparser-2.2.5/src/muParser.cpp index 74b355567..bbd0097f7 100644 --- a/muparser-2.2.5/src/muParser.cpp +++ b/muparser-2.2.5/src/muParser.cpp @@ -48,27 +48,27 @@ namespace mu { //--------------------------------------------------------------------------- // Trigonometric function -value_type Parser::Sin(value_type v) { return MathImpl::Sin(v); } -value_type Parser::Cos(value_type v) { return MathImpl::Cos(v); } -value_type Parser::Tan(value_type v) { return MathImpl::Tan(v); } -value_type Parser::ASin(value_type v) { return MathImpl::ASin(v); } -value_type Parser::ACos(value_type v) { return MathImpl::ACos(v); } -value_type Parser::ATan(value_type v) { return MathImpl::ATan(v); } -value_type Parser::ATan2(value_type v1, value_type v2) { +ValueOrError Parser::Sin(value_type v) { return MathImpl::Sin(v); } +ValueOrError Parser::Cos(value_type v) { return MathImpl::Cos(v); } +ValueOrError Parser::Tan(value_type v) { return MathImpl::Tan(v); } +ValueOrError Parser::ASin(value_type v) { return MathImpl::ASin(v); } +ValueOrError Parser::ACos(value_type v) { return MathImpl::ACos(v); } +ValueOrError Parser::ATan(value_type v) { return MathImpl::ATan(v); } +ValueOrError Parser::ATan2(value_type v1, value_type v2) { return MathImpl::ATan2(v1, v2); } -value_type Parser::Sinh(value_type v) { return MathImpl::Sinh(v); } -value_type Parser::Cosh(value_type v) { return MathImpl::Cosh(v); } -value_type Parser::Tanh(value_type v) { return MathImpl::Tanh(v); } -value_type Parser::ASinh(value_type v) { return MathImpl::ASinh(v); } -value_type Parser::ACosh(value_type v) { return MathImpl::ACosh(v); } -value_type Parser::ATanh(value_type v) { return MathImpl::ATanh(v); } +ValueOrError Parser::Sinh(value_type v) { return MathImpl::Sinh(v); } +ValueOrError Parser::Cosh(value_type v) { return MathImpl::Cosh(v); } +ValueOrError Parser::Tanh(value_type v) { return MathImpl::Tanh(v); } +ValueOrError Parser::ASinh(value_type v) { return MathImpl::ASinh(v); } +ValueOrError Parser::ACosh(value_type v) { return MathImpl::ACosh(v); } +ValueOrError Parser::ATanh(value_type v) { return MathImpl::ATanh(v); } //--------------------------------------------------------------------------- // Logarithm functions // Logarithm base 2 -value_type Parser::Log2(value_type v) { +ValueOrError Parser::Log2(value_type v) { #ifdef MUP_MATH_EXCEPTIONS if (v <= 0) throw ParserError(ecDOMAIN_ERROR, _T("Log2")); #endif @@ -77,7 +77,7 @@ value_type Parser::Log2(value_type v) { } // Logarithm base 10 -value_type Parser::Log10(value_type v) { +ValueOrError Parser::Log10(value_type v) { #ifdef MUP_MATH_EXCEPTIONS if (v <= 0) throw ParserError(ecDOMAIN_ERROR, _T("Log10")); #endif @@ -86,7 +86,7 @@ value_type Parser::Log10(value_type v) { } // Logarithm base e (natural logarithm) -value_type Parser::Ln(value_type v) { +ValueOrError Parser::Ln(value_type v) { #ifdef MUP_MATH_EXCEPTIONS if (v <= 0) throw ParserError(ecDOMAIN_ERROR, _T("Ln")); #endif @@ -96,38 +96,38 @@ value_type Parser::Ln(value_type v) { //--------------------------------------------------------------------------- // misc -value_type Parser::Exp(value_type v) { return MathImpl::Exp(v); } -value_type Parser::Abs(value_type v) { return MathImpl::Abs(v); } -value_type Parser::Sqrt(value_type v) { +ValueOrError Parser::Exp(value_type v) { return MathImpl::Exp(v); } +ValueOrError Parser::Abs(value_type v) { return MathImpl::Abs(v); } +ValueOrError Parser::Sqrt(value_type v) { #ifdef MUP_MATH_EXCEPTIONS if (v < 0) throw ParserError(ecDOMAIN_ERROR, _T("sqrt")); #endif return MathImpl::Sqrt(v); } -value_type Parser::Rint(value_type v) { return MathImpl::Rint(v); } -value_type Parser::Sign(value_type v) { return MathImpl::Sign(v); } +ValueOrError Parser::Rint(value_type v) { return MathImpl::Rint(v); } +ValueOrError Parser::Sign(value_type v) { return MathImpl::Sign(v); } //--------------------------------------------------------------------------- /** \brief Callback for the unary minus operator. \param v The value to negate \return -v */ -value_type Parser::UnaryMinus(value_type v) { return -v; } +ValueOrError Parser::UnaryMinus(value_type v) { return -v; } //--------------------------------------------------------------------------- /** \brief Callback for the unary minus operator. \param v The value to negate \return -v */ -value_type Parser::UnaryPlus(value_type v) { return v; } +ValueOrError Parser::UnaryPlus(value_type v) { return v; } //--------------------------------------------------------------------------- /** \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) { +ValueOrError 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; @@ -140,7 +140,7 @@ value_type Parser::Sum(const value_type *a_afArg, int a_iArgc) { \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) { +ValueOrError 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; @@ -153,7 +153,7 @@ value_type Parser::Avg(const value_type *a_afArg, int a_iArgc) { \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) { +ValueOrError 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]; @@ -167,7 +167,7 @@ value_type Parser::Min(const value_type *a_afArg, int a_iArgc) { \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) { +ValueOrError 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]; @@ -330,7 +330,7 @@ void Parser::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd 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 { +ValueOrError 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 diff --git a/muparser-2.2.5/src/muParserBase.cpp b/muparser-2.2.5/src/muParserBase.cpp index 71a27482a..d863ed88f 100644 --- a/muparser-2.2.5/src/muParserBase.cpp +++ b/muparser-2.2.5/src/muParserBase.cpp @@ -1025,62 +1025,74 @@ value_type ParserBase::ParseCmdCode() const { switch (iArgCount) { case 0: sidx += 1; - Stack[sidx] = (*(fun_type0)pTok->Fun.ptr)(); + Stack[sidx] = (*(fun_type0)pTok->Fun.ptr)().getOrThrow(); continue; case 1: - Stack[sidx] = (*(fun_type1)pTok->Fun.ptr)(Stack[sidx]); + Stack[sidx] = (*(fun_type1)pTok->Fun.ptr)(Stack[sidx]).getOrThrow(); continue; case 2: sidx -= 1; - Stack[sidx] = (*(fun_type2)pTok->Fun.ptr)(Stack[sidx], Stack[sidx + 1]); + Stack[sidx] = + (*(fun_type2)pTok->Fun.ptr)(Stack[sidx], Stack[sidx + 1]).getOrThrow(); continue; case 3: sidx -= 2; Stack[sidx] = (*(fun_type3)pTok->Fun.ptr)(Stack[sidx], Stack[sidx + 1], - Stack[sidx + 2]); + Stack[sidx + 2]) + .getOrThrow(); continue; case 4: sidx -= 3; Stack[sidx] = (*(fun_type4)pTok->Fun.ptr)(Stack[sidx], Stack[sidx + 1], - Stack[sidx + 2], Stack[sidx + 3]); + Stack[sidx + 2], Stack[sidx + 3]) + .getOrThrow(); continue; case 5: sidx -= 4; Stack[sidx] = (*(fun_type5)pTok->Fun.ptr)(Stack[sidx], Stack[sidx + 1], Stack[sidx + 2], Stack[sidx + 3], - Stack[sidx + 4]); + Stack[sidx + 4]) + .getOrThrow(); continue; case 6: sidx -= 5; Stack[sidx] = (*(fun_type6)pTok->Fun.ptr)(Stack[sidx], Stack[sidx + 1], Stack[sidx + 2], Stack[sidx + 3], - Stack[sidx + 4], Stack[sidx + 5]); + Stack[sidx + 4], Stack[sidx + 5]) + .getOrThrow(); continue; case 7: sidx -= 6; - Stack[sidx] = (*(fun_type7)pTok->Fun.ptr)( - Stack[sidx], Stack[sidx + 1], Stack[sidx + 2], Stack[sidx + 3], - Stack[sidx + 4], Stack[sidx + 5], Stack[sidx + 6]); + Stack[sidx] = (*(fun_type7)pTok->Fun.ptr)(Stack[sidx], Stack[sidx + 1], + Stack[sidx + 2], Stack[sidx + 3], + Stack[sidx + 4], Stack[sidx + 5], + Stack[sidx + 6]) + .getOrThrow(); continue; case 8: sidx -= 7; - Stack[sidx] = (*(fun_type8)pTok->Fun.ptr)( - Stack[sidx], Stack[sidx + 1], Stack[sidx + 2], Stack[sidx + 3], - Stack[sidx + 4], Stack[sidx + 5], Stack[sidx + 6], Stack[sidx + 7]); + Stack[sidx] = (*(fun_type8)pTok->Fun.ptr)(Stack[sidx], Stack[sidx + 1], + Stack[sidx + 2], Stack[sidx + 3], + Stack[sidx + 4], Stack[sidx + 5], + Stack[sidx + 6], Stack[sidx + 7]) + .getOrThrow(); continue; case 9: sidx -= 8; Stack[sidx] = (*(fun_type9)pTok->Fun.ptr)( - Stack[sidx], Stack[sidx + 1], Stack[sidx + 2], Stack[sidx + 3], - Stack[sidx + 4], Stack[sidx + 5], Stack[sidx + 6], Stack[sidx + 7], - Stack[sidx + 8]); + Stack[sidx], Stack[sidx + 1], Stack[sidx + 2], + Stack[sidx + 3], Stack[sidx + 4], Stack[sidx + 5], + Stack[sidx + 6], Stack[sidx + 7], Stack[sidx + 8]) + .getOrThrow(); continue; case 10: sidx -= 9; - Stack[sidx] = (*(fun_type10)pTok->Fun.ptr)( - Stack[sidx], Stack[sidx + 1], Stack[sidx + 2], Stack[sidx + 3], - Stack[sidx + 4], Stack[sidx + 5], Stack[sidx + 6], Stack[sidx + 7], - Stack[sidx + 8], Stack[sidx + 9]); + Stack[sidx] = (*(fun_type10)pTok->Fun.ptr)(Stack[sidx], Stack[sidx + 1], + Stack[sidx + 2], Stack[sidx + 3], + Stack[sidx + 4], Stack[sidx + 5], + Stack[sidx + 6], Stack[sidx + 7], + Stack[sidx + 8], Stack[sidx + 9]) + .getOrThrow(); continue; default: if (iArgCount > 0) // function with variable arguments store the number as @@ -1088,7 +1100,8 @@ value_type ParserBase::ParseCmdCode() const { assert(0 && "muParser internal error"); sidx -= -iArgCount - 1; - Stack[sidx] = (*(multfun_type)pTok->Fun.ptr)(&Stack[sidx], -iArgCount); + Stack[sidx] = + (*(multfun_type)pTok->Fun.ptr)(&Stack[sidx], -iArgCount).getOrThrow(); continue; } } @@ -1105,15 +1118,19 @@ value_type ParserBase::ParseCmdCode() const { { case 0: Stack[sidx] = - (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str()); + (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str()) + .getOrThrow(); continue; case 1: Stack[sidx] = (*(strfun_type2)pTok->Fun.ptr)( - m_vStringBuf[iIdxStack].c_str(), Stack[sidx]); + m_vStringBuf[iIdxStack].c_str(), Stack[sidx]) + .getOrThrow(); continue; case 2: - Stack[sidx] = (*(strfun_type3)pTok->Fun.ptr)( - m_vStringBuf[iIdxStack].c_str(), Stack[sidx], Stack[sidx + 1]); + Stack[sidx] = + (*(strfun_type3)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), + Stack[sidx], Stack[sidx + 1]) + .getOrThrow(); continue; } diff --git a/muparser-2.2.5/src/muParserInt.cpp b/muparser-2.2.5/src/muParserInt.cpp index 3d40f8179..10bbb1a18 100644 --- a/muparser-2.2.5/src/muParserInt.cpp +++ b/muparser-2.2.5/src/muParserInt.cpp @@ -37,40 +37,40 @@ using namespace std; /** \brief Namespace for mathematical applications. */ 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) { +ValueOrError ParserInt::Abs(value_type v) { return (value_type)Round(fabs((double)v)); } +ValueOrError ParserInt::Sign(value_type v) { return (Round(v) < 0) ? -1 : (Round(v) > 0) ? 1 : 0; } +ValueOrError 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); } -value_type ParserInt::Div(value_type v1, value_type v2) { return Round(v1) / Round(v2); } -value_type ParserInt::Mod(value_type v1, value_type v2) { return Round(v1) % Round(v2); } -value_type ParserInt::Shr(value_type v1, value_type v2) { return Round(v1) >> Round(v2); } -value_type ParserInt::Shl(value_type v1, value_type v2) { return Round(v1) << Round(v2); } -value_type ParserInt::LogAnd(value_type v1, value_type v2) { return Round(v1) & Round(v2); } -value_type ParserInt::LogOr(value_type v1, value_type v2) { return Round(v1) | Round(v2); } -value_type ParserInt::And(value_type v1, value_type v2) { return Round(v1) && Round(v2); } -value_type ParserInt::Or(value_type v1, value_type v2) { return Round(v1) || Round(v2); } -value_type ParserInt::Less(value_type v1, value_type v2) { return Round(v1) < Round(v2); } -value_type ParserInt::Greater(value_type v1, value_type v2) { return Round(v1) > Round(v2); } -value_type ParserInt::LessEq(value_type v1, value_type v2) { return Round(v1) <= Round(v2); } -value_type ParserInt::GreaterEq(value_type v1, value_type v2) { return Round(v1) >= Round(v2); } -value_type ParserInt::Equal(value_type v1, value_type v2) { return Round(v1) == Round(v2); } -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); } +ValueOrError ParserInt::Add(value_type v1, value_type v2) { return Round(v1) + Round(v2); } +ValueOrError ParserInt::Sub(value_type v1, value_type v2) { return Round(v1) - Round(v2); } +ValueOrError ParserInt::Mul(value_type v1, value_type v2) { return Round(v1) * Round(v2); } +ValueOrError ParserInt::Div(value_type v1, value_type v2) { return Round(v1) / Round(v2); } +ValueOrError ParserInt::Mod(value_type v1, value_type v2) { return Round(v1) % Round(v2); } +ValueOrError ParserInt::Shr(value_type v1, value_type v2) { return Round(v1) >> Round(v2); } +ValueOrError ParserInt::Shl(value_type v1, value_type v2) { return Round(v1) << Round(v2); } +ValueOrError ParserInt::LogAnd(value_type v1, value_type v2) { return Round(v1) & Round(v2); } +ValueOrError ParserInt::LogOr(value_type v1, value_type v2) { return Round(v1) | Round(v2); } +ValueOrError ParserInt::And(value_type v1, value_type v2) { return Round(v1) && Round(v2); } +ValueOrError ParserInt::Or(value_type v1, value_type v2) { return Round(v1) || Round(v2); } +ValueOrError ParserInt::Less(value_type v1, value_type v2) { return Round(v1) < Round(v2); } +ValueOrError ParserInt::Greater(value_type v1, value_type v2) { return Round(v1) > Round(v2); } +ValueOrError ParserInt::LessEq(value_type v1, value_type v2) { return Round(v1) <= Round(v2); } +ValueOrError ParserInt::GreaterEq(value_type v1, value_type v2) { return Round(v1) >= Round(v2); } +ValueOrError ParserInt::Equal(value_type v1, value_type v2) { return Round(v1) == Round(v2); } +ValueOrError ParserInt::NotEqual(value_type v1, value_type v2) { return Round(v1) != Round(v2); } +ValueOrError ParserInt::Not(value_type v) { return !Round(v); } -value_type ParserInt::Pow(value_type v1, value_type v2) { +ValueOrError 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); } +ValueOrError ParserInt::UnaryMinus(value_type v) { return -Round(v); } //--------------------------------------------------------------------------- -value_type ParserInt::Sum(const value_type *a_afArg, int a_iArgc) { +ValueOrError 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; @@ -80,7 +80,7 @@ value_type ParserInt::Sum(const value_type *a_afArg, int a_iArgc) { } //--------------------------------------------------------------------------- -value_type ParserInt::Min(const value_type *a_afArg, int a_iArgc) { +ValueOrError 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]; @@ -90,7 +90,7 @@ value_type ParserInt::Min(const value_type *a_afArg, int a_iArgc) { } //--------------------------------------------------------------------------- -value_type ParserInt::Max(const value_type *a_afArg, int a_iArgc) { +ValueOrError 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]; diff --git a/src/builtin_math.cpp b/src/builtin_math.cpp index 8e733b1cb..2a2325b5c 100644 --- a/src/builtin_math.cpp +++ b/src/builtin_math.cpp @@ -116,7 +116,7 @@ static const wchar_t *math_get_arg(int *argidx, wchar_t **argv, wcstring *storag } /// Implement integer modulo math operator. -static double moduloOperator(double v, double w) { return (int)v % std::max(1, (int)w); }; +static mu::ValueOrError moduloOperator(double v, double w) { return (int)v % std::max(1, (int)w); }; /// Evaluate math expressions. static int evaluate_expression(wchar_t *cmd, parser_t &parser, io_streams_t &streams,