[muparser] DefineFun() to return an error instead of throwing

This commit is contained in:
ridiculousfish 2017-12-17 14:26:55 -08:00
parent 6f14d55612
commit 11d729d09c
4 changed files with 80 additions and 81 deletions

View File

@ -122,10 +122,9 @@ class ParserBase {
\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) {
auto oerr =
AddCallback(a_strName, ParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars());
if (oerr.has_error()) throw oerr.error();
OptionalError DefineFun(const string_type &a_strName, T a_pFun, bool a_bAllowOpt = true) {
return AddCallback(a_strName, ParserCallback(a_pFun, a_bAllowOpt), m_FunDef,
ValidNameChars());
}
OptionalError DefineOprt(const string_type &a_strName, fun_type2 a_pFun, unsigned a_iPri = 0,

View File

@ -226,6 +226,14 @@ void Parser::InitCharSets() {
DefineInfixOprtChars(_T("/+-*^?<>=#!$%&|~'_"));
}
/// assert that the given optional error \p oerr is not an error.
/// This is used only during initialization, when it ought to be impossible
/// to generate an error.
static void assertNoError(OptionalError oerr) {
assert(!oerr.has_error() && "Unexpected error during initialization");
(void)oerr;
}
//---------------------------------------------------------------------------
/** \brief Initialize the default functions. */
void Parser::InitFun() {
@ -237,49 +245,41 @@ void Parser::InitFun() {
// ...
} else {
// trigonometric functions
DefineFun(_T("sin"), Sin);
DefineFun(_T("cos"), Cos);
DefineFun(_T("tan"), Tan);
assertNoError(DefineFun(_T("sin"), Sin));
assertNoError(DefineFun(_T("cos"), Cos));
assertNoError(DefineFun(_T("tan"), Tan));
// arcus functions
DefineFun(_T("asin"), ASin);
DefineFun(_T("acos"), ACos);
DefineFun(_T("atan"), ATan);
DefineFun(_T("atan2"), ATan2);
assertNoError(DefineFun(_T("asin"), ASin));
assertNoError(DefineFun(_T("acos"), ACos));
assertNoError(DefineFun(_T("atan"), ATan));
assertNoError(DefineFun(_T("atan2"), ATan2));
// hyperbolic functions
DefineFun(_T("sinh"), Sinh);
DefineFun(_T("cosh"), Cosh);
DefineFun(_T("tanh"), Tanh);
assertNoError(DefineFun(_T("sinh"), Sinh));
assertNoError(DefineFun(_T("cosh"), Cosh));
assertNoError(DefineFun(_T("tanh"), Tanh));
// arcus hyperbolic functions
DefineFun(_T("asinh"), ASinh);
DefineFun(_T("acosh"), ACosh);
DefineFun(_T("atanh"), ATanh);
assertNoError(DefineFun(_T("asinh"), ASinh));
assertNoError(DefineFun(_T("acosh"), ACosh));
assertNoError(DefineFun(_T("atanh"), ATanh));
// Logarithm functions
DefineFun(_T("log2"), Log2);
DefineFun(_T("log10"), Log10);
DefineFun(_T("log"), Ln);
DefineFun(_T("ln"), Ln);
assertNoError(DefineFun(_T("log2"), Log2));
assertNoError(DefineFun(_T("log10"), Log10));
assertNoError(DefineFun(_T("log"), Ln));
assertNoError(DefineFun(_T("ln"), Ln));
// misc
DefineFun(_T("exp"), Exp);
DefineFun(_T("sqrt"), Sqrt);
DefineFun(_T("sign"), Sign);
DefineFun(_T("rint"), Rint);
DefineFun(_T("abs"), Abs);
assertNoError(DefineFun(_T("exp"), Exp));
assertNoError(DefineFun(_T("sqrt"), Sqrt));
assertNoError(DefineFun(_T("sign"), Sign));
assertNoError(DefineFun(_T("rint"), Rint));
assertNoError(DefineFun(_T("abs"), Abs));
// Functions with variable number of arguments
DefineFun(_T("sum"), Sum);
DefineFun(_T("avg"), Avg);
DefineFun(_T("min"), Min);
DefineFun(_T("max"), Max);
assertNoError(DefineFun(_T("sum"), Sum));
assertNoError(DefineFun(_T("avg"), Avg));
assertNoError(DefineFun(_T("min"), Min));
assertNoError(DefineFun(_T("max"), Max));
}
}
/// assert that the given optional error \p oerr is not an error.
/// This is used only during initialization, when it ought to be impossible
/// to generate an error.
static void assertNoError(OptionalError oerr) {
assert(!oerr.has_error() && "Unexpected error during initialization");
(void)oerr;
}
//---------------------------------------------------------------------------
/** \brief Initialize constants.

View File

@ -196,17 +196,6 @@ void ParserInt::InitCharSets() {
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);
}
/// assert that the given optional error \p oerr is not an error.
/// This is used only during initialization, when it ought to be impossible
/// to generate an error.
@ -215,6 +204,17 @@ static void assertNoError(OptionalError oerr) {
(void)oerr;
}
//---------------------------------------------------------------------------
/** \brief Initialize the default functions. */
void ParserInt::InitFun() {
assertNoError(DefineFun(_T("sign"), Sign));
assertNoError(DefineFun(_T("abs"), Abs));
assertNoError(DefineFun(_T("if"), Ite));
assertNoError(DefineFun(_T("sum"), Sum));
assertNoError(DefineFun(_T("min"), Min));
assertNoError(DefineFun(_T("max"), Max));
}
//---------------------------------------------------------------------------
/** \brief Initialize operators. */
void ParserInt::InitOprt() {

View File

@ -977,11 +977,11 @@ int ParserTester::ThrowTest(const string_type &a_str, int a_iErrc, bool a_bFail)
throwIfError(p.DefineVar(_T("c"), &fVal[2]));
throwIfError(p.DefinePostfixOprt(_T("{m}"), Milli));
throwIfError(p.DefinePostfixOprt(_T("m"), Milli));
p.DefineFun(_T("ping"), Ping);
p.DefineFun(_T("valueof"), ValueOf);
p.DefineFun(_T("strfun1"), StrFun1);
p.DefineFun(_T("strfun2"), StrFun2);
p.DefineFun(_T("strfun3"), StrFun3);
throwIfError(p.DefineFun(_T("ping"), Ping));
throwIfError(p.DefineFun(_T("valueof"), ValueOf));
throwIfError(p.DefineFun(_T("strfun1"), StrFun1));
throwIfError(p.DefineFun(_T("strfun2"), StrFun2));
throwIfError(p.DefineFun(_T("strfun3"), StrFun3));
throwIfError(p.SetExpr(a_str));
getOrThrow(p.Eval());
} catch (ParserError &e) {
@ -1091,22 +1091,22 @@ int ParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass)
p1->AddValIdent(&ParserTester::IsHexVal);
// functions
p1->DefineFun(_T("ping"), Ping);
p1->DefineFun(_T("f1of1"), f1of1); // one parameter
p1->DefineFun(_T("f1of2"), f1of2); // two parameter
p1->DefineFun(_T("f2of2"), f2of2);
p1->DefineFun(_T("f1of3"), f1of3); // three parameter
p1->DefineFun(_T("f2of3"), f2of3);
p1->DefineFun(_T("f3of3"), f3of3);
p1->DefineFun(_T("f1of4"), f1of4); // four parameter
p1->DefineFun(_T("f2of4"), f2of4);
p1->DefineFun(_T("f3of4"), f3of4);
p1->DefineFun(_T("f4of4"), f4of4);
p1->DefineFun(_T("f1of5"), f1of5); // five parameter
p1->DefineFun(_T("f2of5"), f2of5);
p1->DefineFun(_T("f3of5"), f3of5);
p1->DefineFun(_T("f4of5"), f4of5);
p1->DefineFun(_T("f5of5"), f5of5);
throwIfError(p1->DefineFun(_T("ping"), Ping));
throwIfError(p1->DefineFun(_T("f1of1"), f1of1)); // one parameter
throwIfError(p1->DefineFun(_T("f1of2"), f1of2)); // two parameter
throwIfError(p1->DefineFun(_T("f2of2"), f2of2));
throwIfError(p1->DefineFun(_T("f1of3"), f1of3)); // three parameter
throwIfError(p1->DefineFun(_T("f2of3"), f2of3));
throwIfError(p1->DefineFun(_T("f3of3"), f3of3));
throwIfError(p1->DefineFun(_T("f1of4"), f1of4)); // four parameter
throwIfError(p1->DefineFun(_T("f2of4"), f2of4));
throwIfError(p1->DefineFun(_T("f3of4"), f3of4));
throwIfError(p1->DefineFun(_T("f4of4"), f4of4));
throwIfError(p1->DefineFun(_T("f1of5"), f1of5)); // five parameter
throwIfError(p1->DefineFun(_T("f2of5"), f2of5));
throwIfError(p1->DefineFun(_T("f3of5"), f3of5));
throwIfError(p1->DefineFun(_T("f4of5"), f4of5));
throwIfError(p1->DefineFun(_T("f5of5"), f5of5));
// binary operators
throwIfError(p1->DefineOprt(_T("add"), add, 0));
@ -1114,17 +1114,17 @@ int ParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass)
throwIfError(p1->DefineOprt(_T("&"), land, prLAND));
// sample functions
p1->DefineFun(_T("min"), Min);
p1->DefineFun(_T("max"), Max);
p1->DefineFun(_T("sum"), Sum);
p1->DefineFun(_T("valueof"), ValueOf);
p1->DefineFun(_T("atof"), StrToFloat);
p1->DefineFun(_T("strfun1"), StrFun1);
p1->DefineFun(_T("strfun2"), StrFun2);
p1->DefineFun(_T("strfun3"), StrFun3);
p1->DefineFun(_T("lastArg"), LastArg);
p1->DefineFun(_T("firstArg"), FirstArg);
p1->DefineFun(_T("order"), FirstArg);
throwIfError(p1->DefineFun(_T("min"), Min));
throwIfError(p1->DefineFun(_T("max"), Max));
throwIfError(p1->DefineFun(_T("sum"), Sum));
throwIfError(p1->DefineFun(_T("valueof"), ValueOf));
throwIfError(p1->DefineFun(_T("atof"), StrToFloat));
throwIfError(p1->DefineFun(_T("strfun1"), StrFun1));
throwIfError(p1->DefineFun(_T("strfun2"), StrFun2));
throwIfError(p1->DefineFun(_T("strfun3"), StrFun3));
throwIfError(p1->DefineFun(_T("lastArg"), LastArg));
throwIfError(p1->DefineFun(_T("firstArg"), FirstArg));
throwIfError(p1->DefineFun(_T("order"), FirstArg));
// infix / postfix operator
// Note: Identifiers used here do not have any meaning