diff --git a/latan/CompiledFunction.cpp b/latan/CompiledFunction.cpp index cc8a6b4..3fc77ab 100644 --- a/latan/CompiledFunction.cpp +++ b/latan/CompiledFunction.cpp @@ -27,30 +27,39 @@ using namespace Latan; /****************************************************************************** * Compiled double function implementation * ******************************************************************************/ -// constructor/destructor ////////////////////////////////////////////////////// +// constructor ///////////////////////////////////////////////////////////////// CompiledDoubleFunction::CompiledDoubleFunction(const unsigned nArg) : DoubleFunction(nArg) -{} +{ + interpreter_ = new MathInterpreter; + context_ = new RunContext; +} CompiledDoubleFunction::CompiledDoubleFunction(const unsigned nArg, const string &code) : DoubleFunction(nArg) { + interpreter_ = new MathInterpreter; + context_ = new RunContext; setCode(code); } +// destructor ////////////////////////////////////////////////////////////////// CompiledDoubleFunction::~CompiledDoubleFunction(void) -{} +{ + delete interpreter_; + delete context_; +} // access ////////////////////////////////////////////////////////////////////// void CompiledDoubleFunction::setCode(const string &code) { - interpreter_.setCode(code); - StdMath::addStdMathFunc(context_.fTable); + interpreter_->setCode(code); + StdMath::addStdMathFunc(context_->fTable); } // function call /////////////////////////////////////////////////////////////// -double CompiledDoubleFunction::operator()(vector &arg) +double CompiledDoubleFunction::evaluate(const vector &arg) const { double result; @@ -62,13 +71,13 @@ double CompiledDoubleFunction::operator()(vector &arg) } for (unsigned int i = 0; i < getNArg(); ++i) { - context_.vTable["x_" + strFrom(i)] = arg[i]; + context_->vTable["x_" + strFrom(i)] = arg[i]; } - interpreter_(context_); - if (!context_.dStack.empty()) + (*interpreter_)(*context_); + if (!context_->dStack.empty()) { - result = context_.dStack.top(); - context_.dStack.pop(); + result = context_->dStack.top(); + context_->dStack.pop(); } else { @@ -82,7 +91,8 @@ double CompiledDoubleFunction::operator()(vector &arg) // IO ////////////////////////////////////////////////////////////////////////// ostream &Latan::operator<<(ostream &out, CompiledDoubleFunction &f) { - out << f.interpreter_; + f.interpreter_->compile(); + out << *(f.interpreter_); return out; } diff --git a/latan/CompiledFunction.hpp b/latan/CompiledFunction.hpp index 35a6366..b9a2c33 100644 --- a/latan/CompiledFunction.hpp +++ b/latan/CompiledFunction.hpp @@ -35,22 +35,22 @@ BEGIN_NAMESPACE class CompiledDoubleFunction: public DoubleFunction { public: - // constructor/destructor + // constructors explicit CompiledDoubleFunction(const unsigned nArg); explicit CompiledDoubleFunction(const unsigned nArg, const std::string &code); + // destructor virtual ~CompiledDoubleFunction(void); // access void setCode(const std::string &code); // function call - using DoubleFunction::operator(); - virtual double operator()(std::vector &arg); + virtual double evaluate(const std::vector &arg) const; // IO friend std::ostream &operator<<(std::ostream &out, CompiledDoubleFunction &f); private: - MathInterpreter interpreter_; - RunContext context_; + MathInterpreter* interpreter_; + RunContext* context_; }; END_NAMESPACE diff --git a/latan/Function.cpp b/latan/Function.cpp index cc94442..714004d 100644 --- a/latan/Function.cpp +++ b/latan/Function.cpp @@ -61,27 +61,38 @@ unsigned int Function::getNArg(void) const /****************************************************************************** * DoubleFunction implementation * ******************************************************************************/ -DoubleFunction::DoubleFunction(const unsigned nArg) -: Function(nArg), buffer_(nArg) -{} +DoubleFunction::DoubleFunction(const unsigned nArg, vecFunc *f) +: Function(nArg) +, f_(f) +{ + buffer_ = new vector(nArg); +} DoubleFunction::~DoubleFunction(void) -{} +{ + delete buffer_; +} -double DoubleFunction::operator()(std::stack &arg) +double DoubleFunction::evaluate(const std::vector &arg) const +{ + std::cout << "double()" << endl; + return f_(arg); +} + +double DoubleFunction::operator()(std::stack &arg) const { for (unsigned int i = 0; i < getNArg(); ++i) { - buffer_[getNArg() - i - 1] = arg.top(); + (*buffer_)[getNArg() - i - 1] = arg.top(); arg.pop(); } - return (*this)(buffer_); + return this->evaluate(*buffer_); } -double DoubleFunction::operator()(const double x0, ...) +double DoubleFunction::operator()(const double x0, ...) const { - buffer_[0] = x0; + (*buffer_)[0] = x0; if (getNArg() > 1) { va_list va; @@ -89,10 +100,10 @@ double DoubleFunction::operator()(const double x0, ...) va_start(va, x0); for (unsigned int i = 1; i < getNArg(); ++i) { - buffer_[i] = va_arg(va, double); + (*buffer_)[i] = va_arg(va, double); } va_end(va); } - return (*this)(buffer_); + return this->evaluate(*buffer_); } diff --git a/latan/Function.hpp b/latan/Function.hpp index b44b4dd..b39ed62 100644 --- a/latan/Function.hpp +++ b/latan/Function.hpp @@ -47,16 +47,19 @@ private: ******************************************************************************/ class DoubleFunction: public Function { +private: + typedef double vecFunc(const std::vector &); public: // constructor/destructor - explicit DoubleFunction(const unsigned nArg); + explicit DoubleFunction(const unsigned nArg, vecFunc *f = NULL); virtual ~DoubleFunction(void); // function call - virtual double operator()(std::vector &arg) = 0; - double operator()(std::stack &arg); - double operator()(const double x0, ...); + virtual double evaluate(const std::vector &arg) const; + double operator()(std::stack &arg) const; + double operator()(const double x0, ...) const; private: - std::vector buffer_; + std::vector *buffer_; + vecFunc *f_; }; END_NAMESPACE diff --git a/latan/Math.cpp b/latan/Math.cpp index 883016c..2d499db 100644 --- a/latan/Math.cpp +++ b/latan/Math.cpp @@ -27,58 +27,54 @@ using namespace Latan; * Standard C functions * ******************************************************************************/ -#define DEF_STD_FUNC_1ARG(name, funcName) \ -name##Function::name##Function(void): DoubleFunction(1) {}\ -name##Function::~name##Function(void) {}\ -double name##Function::operator()(std::vector &arg)\ +#define DEF_STD_FUNC_1ARG(name) \ +static double name##VecFunc(const vector &arg)\ {\ - return funcName(arg[0]);\ + return (name)(arg[0]);\ }\ -name##Function STDMATH_NAMESPACE::funcName; +DoubleFunction STDMATH_NAMESPACE::name(1, &name##VecFunc); -#define DEF_STD_FUNC_2ARG(name, funcName) \ -name##Function::name##Function(void): DoubleFunction(2) {}\ -name##Function::~name##Function(void) {}\ -double name##Function::operator()(std::vector &arg)\ +#define DEF_STD_FUNC_2ARG(name) \ +static double name##VecFunc(const vector &arg)\ {\ - return funcName(arg[0], arg[1]);\ +return (name)(arg[0], arg[1]);\ }\ -name##Function STDMATH_NAMESPACE::funcName; +DoubleFunction STDMATH_NAMESPACE::name(2, &name##VecFunc); // Trigonometric functions -DEF_STD_FUNC_1ARG(Cos, cos) -DEF_STD_FUNC_1ARG(Sin, sin) -DEF_STD_FUNC_1ARG(Tan, tan) -DEF_STD_FUNC_1ARG(ACos, acos) -DEF_STD_FUNC_1ARG(ASin, asin) -DEF_STD_FUNC_1ARG(ATan, atan) -DEF_STD_FUNC_2ARG(ATan2, atan2) +DEF_STD_FUNC_1ARG(cos) +DEF_STD_FUNC_1ARG(sin) +DEF_STD_FUNC_1ARG(tan) +DEF_STD_FUNC_1ARG(acos) +DEF_STD_FUNC_1ARG(asin) +DEF_STD_FUNC_1ARG(atan) +DEF_STD_FUNC_2ARG(atan2) // Hyperbolic functions -DEF_STD_FUNC_1ARG(Cosh, cosh) -DEF_STD_FUNC_1ARG(Sinh, sinh) -DEF_STD_FUNC_1ARG(Tanh, tanh) +DEF_STD_FUNC_1ARG(cosh) +DEF_STD_FUNC_1ARG(sinh) +DEF_STD_FUNC_1ARG(tanh) // Exponential and logarithmic functions -DEF_STD_FUNC_1ARG(Exp, exp) -DEF_STD_FUNC_1ARG(Log, log) +DEF_STD_FUNC_1ARG(exp) +DEF_STD_FUNC_1ARG(log) // Power functions -DEF_STD_FUNC_2ARG(Pow, pow) -DEF_STD_FUNC_1ARG(Sqrt, sqrt) +DEF_STD_FUNC_2ARG(pow) +DEF_STD_FUNC_1ARG(sqrt) // Rounding and remainder functions -DEF_STD_FUNC_1ARG(Ceil, ceil) -DEF_STD_FUNC_1ARG(Floor, floor) -DEF_STD_FUNC_2ARG(FMod, fmod) +DEF_STD_FUNC_1ARG(ceil) +DEF_STD_FUNC_1ARG(floor) +DEF_STD_FUNC_2ARG(fmod) // Minimum, maximum, difference functions -DEF_STD_FUNC_2ARG(FDim, fdim) -DEF_STD_FUNC_2ARG(FMax, fmax) -DEF_STD_FUNC_2ARG(FMin, fmin) +DEF_STD_FUNC_2ARG(fdim) +DEF_STD_FUNC_2ARG(fmax) +DEF_STD_FUNC_2ARG(fmin) // Absolute value -DEF_STD_FUNC_1ARG(Abs, abs) +DEF_STD_FUNC_1ARG(fabs) #define ADD_FUNC(func) fTable[#func] = &STDMATH_NAMESPACE::func void STDMATH_NAMESPACE::addStdMathFunc(FunctionTable &fTable) @@ -110,5 +106,5 @@ void STDMATH_NAMESPACE::addStdMathFunc(FunctionTable &fTable) ADD_FUNC(fmax); ADD_FUNC(fmin); // Absolute value - ADD_FUNC(abs); + ADD_FUNC(fabs); } diff --git a/latan/Math.hpp b/latan/Math.hpp index 21fe9ec..1904ea5 100644 --- a/latan/Math.hpp +++ b/latan/Math.hpp @@ -32,54 +32,46 @@ BEGIN_NAMESPACE ******************************************************************************/ #define STDMATH_NAMESPACE StdMath -#define DECL_STD_FUNC(name, funcName) \ -class name##Function: public DoubleFunction\ -{\ -public:\ - name##Function(void);\ - virtual ~name##Function(void);\ - using DoubleFunction::operator();\ - virtual double operator()(std::vector &arg);\ -};\ +#define DECL_STD_FUNC(name) \ namespace STDMATH_NAMESPACE\ {\ - extern name##Function funcName;\ + extern DoubleFunction name;\ } // Trigonometric functions -DECL_STD_FUNC(Cos, cos) -DECL_STD_FUNC(Sin, sin) -DECL_STD_FUNC(Tan, tan) -DECL_STD_FUNC(ACos, acos) -DECL_STD_FUNC(ASin, asin) -DECL_STD_FUNC(ATan, atan) -DECL_STD_FUNC(ATan2, atan2) +DECL_STD_FUNC(cos) +DECL_STD_FUNC(sin) +DECL_STD_FUNC(tan) +DECL_STD_FUNC(acos) +DECL_STD_FUNC(asin) +DECL_STD_FUNC(atan) +DECL_STD_FUNC(atan2) // Hyperbolic functions -DECL_STD_FUNC(Cosh, cosh) -DECL_STD_FUNC(Sinh, sinh) -DECL_STD_FUNC(Tanh, tanh) +DECL_STD_FUNC(cosh) +DECL_STD_FUNC(sinh) +DECL_STD_FUNC(tanh) // Exponential and logarithmic functions -DECL_STD_FUNC(Exp, exp) -DECL_STD_FUNC(Log, log) +DECL_STD_FUNC(exp) +DECL_STD_FUNC(log) // Power functions -DECL_STD_FUNC(Pow, pow) -DECL_STD_FUNC(Sqrt, sqrt) +DECL_STD_FUNC(pow) +DECL_STD_FUNC(sqrt) // Rounding and remainder functions -DECL_STD_FUNC(Ceil, ceil) -DECL_STD_FUNC(Floor, floor) -DECL_STD_FUNC(FMod, fmod) +DECL_STD_FUNC(ceil) +DECL_STD_FUNC(floor) +DECL_STD_FUNC(fmod) // Minimum, maximum, difference functions -DECL_STD_FUNC(FDim, fdim) -DECL_STD_FUNC(FMax, fmax) -DECL_STD_FUNC(FMin, fmin) +DECL_STD_FUNC(fdim) +DECL_STD_FUNC(fmax) +DECL_STD_FUNC(fmin) // Absolute value -DECL_STD_FUNC(Abs, abs) +DECL_STD_FUNC(fabs) // Add standard math functions to a table for the math compiler namespace STDMATH_NAMESPACE