mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
[muparser] Continue adopting ValueOrError
This commit is contained in:
parent
bfd70880a5
commit
9649b132bd
8 changed files with 40 additions and 49 deletions
|
@ -97,8 +97,8 @@ class ParserBase {
|
|||
|
||||
virtual ~ParserBase();
|
||||
|
||||
value_type Eval() const;
|
||||
value_type *Eval(int &nStackSize) const;
|
||||
ValueOrError Eval() const;
|
||||
void Eval(std::vector<ValueOrError> *results) const;
|
||||
|
||||
int GetNumResults() const;
|
||||
|
||||
|
|
|
@ -112,7 +112,6 @@ 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);
|
||||
|
||||
// Defining callbacks / variables / constants
|
||||
API_EXPORT(void)
|
||||
|
|
|
@ -416,7 +416,7 @@ void Calc() {
|
|||
// 1.) If you know there is only a single return value or in case you only need the last
|
||||
// result of an expression consisting of comma separated subexpressions you can
|
||||
// simply use:
|
||||
mu::console() << _T("ans=") << parser.Eval() << _T("\n");
|
||||
mu::console() << _T("ans=") << *parser.Eval() << _T("\n");
|
||||
|
||||
// 2.) As an alternative you can also retrieve multiple return values using this API:
|
||||
int nNum = parser.GetNumResults();
|
||||
|
@ -425,10 +425,11 @@ void Calc() {
|
|||
|
||||
// this is the hard way if you need to retrieve multiple subexpression
|
||||
// results
|
||||
value_type *v = parser.Eval(nNum);
|
||||
std::vector<ValueOrError> vs;
|
||||
parser.Eval(&vs);
|
||||
mu::console() << std::setprecision(12);
|
||||
for (int i = 0; i < nNum; ++i) {
|
||||
mu::console() << v[i] << _T("\n");
|
||||
for (const ValueOrError &v : vs) {
|
||||
mu::console() << *v << _T("\n");
|
||||
}
|
||||
}
|
||||
} catch (mu::Parser::exception_type &e) {
|
||||
|
@ -446,8 +447,8 @@ void Calc() {
|
|||
//---------------------------------------------------------------------------
|
||||
int main(int, char **) {
|
||||
Splash();
|
||||
SelfTest();
|
||||
Help();
|
||||
(void)SelfTest();
|
||||
(void)Help();
|
||||
|
||||
// CheckLocale();
|
||||
// CheckDiff();
|
||||
|
|
|
@ -331,9 +331,10 @@ void Parser::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd
|
|||
http://sourceforge.net/forum/forum.php?thread_id=1994611&forum_id=462843
|
||||
*/
|
||||
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);
|
||||
value_type fRes(0), fBuf(*a_Var), fEpsilon(a_fEpsilon);
|
||||
ValueOrError f[4] = {0, 0, 0, 0};
|
||||
|
||||
// Backwards compatible calculation of epsilon inc case the user doesn't provide
|
||||
// Backwards compatible calculation of epsilon in 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;
|
||||
|
||||
|
@ -347,7 +348,10 @@ ValueOrError Parser::Diff(value_type *a_Var, value_type a_fPos, value_type a_fEp
|
|||
f[3] = Eval();
|
||||
*a_Var = fBuf; // restore variable
|
||||
|
||||
fRes = (-f[0] + 8 * f[1] - 8 * f[2] + f[3]) / (12 * fEpsilon);
|
||||
for (ValueOrError &v : f) {
|
||||
if (!v) return std::move(v);
|
||||
}
|
||||
fRes = (-*f[0] + 8 * *f[1] - 8 * *f[2] + *f[3]) / (12 * fEpsilon);
|
||||
return fRes;
|
||||
}
|
||||
} // namespace mu
|
||||
|
|
|
@ -1552,12 +1552,12 @@ void ParserBase::StackDump(const ParserStack<token_type> &a_stVal,
|
|||
This member function can be used to retrieve all results of an expression
|
||||
made up of multiple comma separated subexpressions (i.e. "x+y,sin(x),cos(y)")
|
||||
*/
|
||||
value_type *ParserBase::Eval(int &nStackSize) const {
|
||||
void ParserBase::Eval(std::vector<ValueOrError> *outResult) const {
|
||||
(this->*m_pParseFormula)();
|
||||
nStackSize = m_nFinalResultIdx;
|
||||
int stackSize = m_nFinalResultIdx;
|
||||
|
||||
// (for historic reasons the stack starts at position 1)
|
||||
return &m_vStackBuffer[1];
|
||||
outResult->assign(&m_vStackBuffer[1], &m_vStackBuffer[1 + stackSize]);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -1585,6 +1585,6 @@ int ParserBase::GetNumResults() const { return m_nFinalResultIdx; }
|
|||
\return The evaluation result
|
||||
\throw ParseException if no Formula is set or in case of any other error related to the formula.
|
||||
*/
|
||||
value_type ParserBase::Eval() const { return (this->*m_pParseFormula)().getOrThrow(); }
|
||||
ValueOrError ParserBase::Eval() const { return (this->*m_pParseFormula)(); }
|
||||
|
||||
} // namespace mu
|
||||
|
|
|
@ -195,19 +195,7 @@ API_EXPORT(const muChar_t*) mupGetVersion(muParserHandle_t a_hParser) {
|
|||
API_EXPORT(muFloat_t) mupEval(muParserHandle_t a_hParser) {
|
||||
MU_TRY
|
||||
muParser_t* const p(AsParser(a_hParser));
|
||||
return p->Eval();
|
||||
MU_CATCH
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
API_EXPORT(muFloat_t*) mupEvalMulti(muParserHandle_t a_hParser, int* nNum) {
|
||||
MU_TRY
|
||||
assert(nNum != NULL);
|
||||
|
||||
muParser_t* const p(AsParser(a_hParser));
|
||||
return p->Eval(*nNum);
|
||||
return *p->Eval();
|
||||
MU_CATCH
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -94,14 +94,14 @@ int ParserTester::TestInterface() {
|
|||
p.DefineVar(_T("b"), &afVal[1]);
|
||||
p.DefineVar(_T("c"), &afVal[2]);
|
||||
p.SetExpr(_T("a+b+c"));
|
||||
p.Eval();
|
||||
(void)p.Eval();
|
||||
} catch (...) {
|
||||
iStat += 1; // this is not supposed to happen
|
||||
}
|
||||
|
||||
try {
|
||||
p.RemoveVar(_T("c"));
|
||||
p.Eval();
|
||||
(void)p.Eval();
|
||||
iStat += 1; // not supposed to reach this, nonexisting variable "c" deleted...
|
||||
} catch (...) {
|
||||
// failure is expected...
|
||||
|
@ -1075,7 +1075,7 @@ int ParserTester::ThrowTest(const string_type &a_str, int a_iErrc, bool a_bFail)
|
|||
p.DefineFun(_T("strfun2"), StrFun2);
|
||||
p.DefineFun(_T("strfun3"), StrFun3);
|
||||
p.SetExpr(a_str);
|
||||
p.Eval();
|
||||
(void)p.Eval();
|
||||
} catch (ParserError &e) {
|
||||
// output the formula in case of an failed test
|
||||
if (a_bFail == false || (a_bFail == true && a_iErrc != e.GetCode())) {
|
||||
|
@ -1119,10 +1119,10 @@ int ParserTester::EqnTestWithVarChange(const string_type &a_str, double a_fVar1,
|
|||
p.SetExpr(a_str);
|
||||
|
||||
var = a_fVar1;
|
||||
fVal[0] = p.Eval();
|
||||
fVal[0] = *p.Eval();
|
||||
|
||||
var = a_fVar2;
|
||||
fVal[1] = p.Eval();
|
||||
fVal[1] = *p.Eval();
|
||||
|
||||
if (fabs(a_fRes1 - fVal[0]) > 0.0000000001)
|
||||
throw std::runtime_error("incorrect result (first pass)");
|
||||
|
@ -1234,8 +1234,8 @@ int ParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass)
|
|||
|
||||
// Test bytecode integrity
|
||||
// String parsing and bytecode parsing must yield the same result
|
||||
fVal[0] = p1->Eval(); // result from stringparsing
|
||||
fVal[1] = p1->Eval(); // result from bytecode
|
||||
fVal[0] = *p1->Eval(); // result from stringparsing
|
||||
fVal[1] = *p1->Eval(); // result from bytecode
|
||||
if (fVal[0] != fVal[1])
|
||||
throw Parser::exception_type(_T("Bytecode / string parsing mismatch."));
|
||||
|
||||
|
@ -1250,18 +1250,17 @@ int ParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass)
|
|||
vParser.clear(); // delete the vector
|
||||
p1.reset(0);
|
||||
|
||||
fVal[2] = p2.Eval();
|
||||
fVal[2] = *p2.Eval();
|
||||
|
||||
// Test assignment operator
|
||||
mu::Parser p3;
|
||||
p3 = p2;
|
||||
fVal[3] = p3.Eval();
|
||||
fVal[3] = *p3.Eval();
|
||||
|
||||
// Test Eval function for multiple return values
|
||||
// use p2 since it has the optimizer enabled!
|
||||
int nNum;
|
||||
value_type *v = p2.Eval(nNum);
|
||||
fVal[4] = v[nNum - 1];
|
||||
std::vector<ValueOrError> v;
|
||||
p2.Eval(&v);
|
||||
fVal[4] = *v.back();
|
||||
} catch (std::exception &e) {
|
||||
mu::console() << _T("\n ") << e.what() << _T("\n");
|
||||
}
|
||||
|
@ -1328,8 +1327,8 @@ int ParserTester::EqnTestInt(const string_type &a_str, double a_fRes, bool a_fPa
|
|||
p.DefineVar(_T("c"), &vVarVal[2]);
|
||||
|
||||
p.SetExpr(a_str);
|
||||
fVal[0] = p.Eval(); // result from stringparsing
|
||||
fVal[1] = p.Eval(); // result from bytecode
|
||||
fVal[0] = *p.Eval(); // result from stringparsing
|
||||
fVal[1] = *p.Eval(); // result from bytecode
|
||||
|
||||
if (fVal[0] != fVal[1]) throw Parser::exception_type(_T("Bytecode corrupt."));
|
||||
|
||||
|
|
|
@ -131,13 +131,13 @@ static int evaluate_expression(wchar_t *cmd, parser_t &parser, io_streams_t &str
|
|||
p.DefineOprt(L"%", moduloOperator, mu::prINFIX);
|
||||
|
||||
p.SetExpr(expression);
|
||||
int nNum;
|
||||
mu::value_type *v = p.Eval(nNum);
|
||||
for (int i = 0; i < nNum; ++i) {
|
||||
std::vector<mu::ValueOrError> vs;
|
||||
p.Eval(&vs);
|
||||
for (const mu::ValueOrError &v : vs) {
|
||||
if (opts.scale == 0) {
|
||||
streams.out.append_format(L"%ld\n", static_cast<long>(v[i]));
|
||||
streams.out.append_format(L"%ld\n", static_cast<long>(*v));
|
||||
} else {
|
||||
streams.out.append_format(L"%.*lf\n", opts.scale, v[i]);
|
||||
streams.out.append_format(L"%.*lf\n", opts.scale, *v);
|
||||
}
|
||||
}
|
||||
return STATUS_CMD_OK;
|
||||
|
|
Loading…
Reference in a new issue