mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 21:44:16 +00:00
[muparser] Add a muParser ValueOrError type
First steps towards removing exceptions from muParser.
This commit is contained in:
parent
c0af4ba70a
commit
5655f255ef
10 changed files with 324 additions and 226 deletions
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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)(
|
||||
|
|
|
@ -25,8 +25,10 @@
|
|||
#ifndef MUP_DEF_H
|
||||
#define MUP_DEF_H
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -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<ParserError> 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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -48,27 +48,27 @@ 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) {
|
||||
ValueOrError Parser::Sin(value_type v) { return MathImpl<value_type>::Sin(v); }
|
||||
ValueOrError Parser::Cos(value_type v) { return MathImpl<value_type>::Cos(v); }
|
||||
ValueOrError Parser::Tan(value_type v) { return MathImpl<value_type>::Tan(v); }
|
||||
ValueOrError Parser::ASin(value_type v) { return MathImpl<value_type>::ASin(v); }
|
||||
ValueOrError Parser::ACos(value_type v) { return MathImpl<value_type>::ACos(v); }
|
||||
ValueOrError Parser::ATan(value_type v) { return MathImpl<value_type>::ATan(v); }
|
||||
ValueOrError 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); }
|
||||
ValueOrError Parser::Sinh(value_type v) { return MathImpl<value_type>::Sinh(v); }
|
||||
ValueOrError Parser::Cosh(value_type v) { return MathImpl<value_type>::Cosh(v); }
|
||||
ValueOrError Parser::Tanh(value_type v) { return MathImpl<value_type>::Tanh(v); }
|
||||
ValueOrError Parser::ASinh(value_type v) { return MathImpl<value_type>::ASinh(v); }
|
||||
ValueOrError Parser::ACosh(value_type v) { return MathImpl<value_type>::ACosh(v); }
|
||||
ValueOrError Parser::ATanh(value_type v) { return MathImpl<value_type>::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<value_type>::Exp(v); }
|
||||
value_type Parser::Abs(value_type v) { return MathImpl<value_type>::Abs(v); }
|
||||
value_type Parser::Sqrt(value_type v) {
|
||||
ValueOrError Parser::Exp(value_type v) { return MathImpl<value_type>::Exp(v); }
|
||||
ValueOrError Parser::Abs(value_type v) { return MathImpl<value_type>::Abs(v); }
|
||||
ValueOrError 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); }
|
||||
ValueOrError Parser::Rint(value_type v) { return MathImpl<value_type>::Rint(v); }
|
||||
ValueOrError Parser::Sign(value_type v) { return MathImpl<value_type>::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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue