]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Dealing with if <,> in expr
authorageay <ageay>
Tue, 25 Jan 2011 10:08:00 +0000 (10:08 +0000)
committerageay <ageay>
Tue, 25 Jan 2011 10:08:00 +0000 (10:08 +0000)
src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx
src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx
src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx
src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx
src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx
src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx
src/INTERP_KERNELTest/ExprEvalInterpTest.cxx
src/INTERP_KERNELTest/ExprEvalInterpTest.hxx

index 1f6b497b5fd10c7aee297bc290d57b9ba6ce5a6b..2d8055ffe310600c5958e2aeb1402c1fdeeab415 100644 (file)
@@ -380,8 +380,8 @@ void ExprParser::parseUnaryFunc() throw(INTERP_KERNEL::Exception)
   if(pos4!=pos1)
     return ;
   std::string funcName=_expr.substr(0,pos1);
-  std::size_t pos2=funcName.find_first_of("+-*/^",0,5);
-  std::size_t pos3=funcName.find_first_not_of("+-*/^",0,5);
+  std::size_t pos2=funcName.find_first_of("+-*/^><",0,7);
+  std::size_t pos3=funcName.find_first_not_of("+-*/^><",0,7);
   if(pos2!=std::string::npos && pos3!=std::string::npos)
     return ;//Bracket group is not alone, can't conclude not recursively.
   std::string newExp2=_expr.substr(pos1+1,_expr.length()-pos1-2);
@@ -401,7 +401,7 @@ void ExprParser::parseUnaryFunc() throw(INTERP_KERNEL::Exception)
   std::size_t pos6=0;
   for(int i=0;i<nbOfParamsInFunc;i++)
     {
-      std::size_t pos5=newExp2.find_first_of(',');
+      std::size_t pos5=newExp2.find_first_of(',',pos6);
       std::size_t len=std::string::npos;
       if(pos5!=std::string::npos)
         len=pos5-pos6;
@@ -436,6 +436,66 @@ bool ExprParser::tryToInterpALeaf() throw(INTERP_KERNEL::Exception)
   return true;
 }
 
+void ExprParser::parseForCmp() throw(INTERP_KERNEL::Exception)
+{
+  std::string::const_iterator iter;
+  int curLevel=0;
+  std::string curPart;
+  bool isParsingSucceed=false;
+  for(iter=_expr.begin();iter!=_expr.end();iter++)
+    {
+      switch(*iter)
+        {
+        case '>':
+        case '<':
+          {
+            isParsingSucceed=true;
+            if(!curPart.empty())
+              {
+                _sub_expr.push_back(ExprParser(curPart.c_str(),this));
+                curPart.clear();
+                _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
+              }
+            else
+              {
+                std::ostringstream errMsg;
+                char MSGTYP1[]="Error non unary function for '";
+                errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'";
+                std::string tmp=_expr.substr(iter-_expr.begin());
+                locateError(errMsg,tmp,0);
+                throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+              }
+            break;
+          }
+        case '(':
+          curLevel++;
+          curPart+=*iter;
+          break;
+        case ')':
+          curLevel--;
+          curPart+=*iter;
+          break;
+        default:
+          curPart+=*iter;
+        }
+    }
+  if(isParsingSucceed)
+    {
+      if(!curPart.empty())
+        {
+          _sub_expr.push_back(ExprParser(curPart.c_str(),this));
+          _is_parsing_ok=true;
+        }
+      else
+        {
+          std::ostringstream errMsg;
+          char MSGTYP4[]="Error following expression finished by > / < without right part.";
+          errMsg << EXPR_PARSE_ERR_MSG << MSGTYP4 << _expr;
+          throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+        }
+    }
+}
+
 void ExprParser::parseForAddMin() throw(INTERP_KERNEL::Exception)
 {
   std::string::const_iterator iter;
@@ -640,12 +700,16 @@ bool ExprParser::simplify() throw(INTERP_KERNEL::Exception)
   parseUnaryFunc();
   if(!_is_parsing_ok)
     {
-      parseForAddMin();
+      parseForCmp();
       if(!_is_parsing_ok)
         {
-          parseForMulDiv();
+          parseForAddMin();
           if(!_is_parsing_ok)
-            parseForPow();
+            {
+              parseForMulDiv();
+              if(!_is_parsing_ok)
+                parseForPow();
+            }
         }
     }
   if(!_is_parsing_ok)
index 7ff8babb57eb193d2983fb4540041f375a78f3c7..07334076e6fec7d400497f57198fe4b98ca78405 100644 (file)
@@ -105,6 +105,7 @@ namespace INTERP_KERNEL
     void prepareExprEvaluationVecLowLev() const throw(INTERP_KERNEL::Exception);
     bool tryToInterpALeaf() throw(INTERP_KERNEL::Exception);
     void parseUnaryFunc() throw(INTERP_KERNEL::Exception);
+    void parseForCmp() throw(INTERP_KERNEL::Exception);
     void parseForAddMin() throw(INTERP_KERNEL::Exception);
     void parseForMulDiv() throw(INTERP_KERNEL::Exception);
     void parseForPow() throw(INTERP_KERNEL::Exception);
index dd16329f6d43afacacdb496ecb4b973be26458b2..ad23a0891ebdf68fce3c717c5779c9b851fec6fc 100644 (file)
@@ -58,6 +58,12 @@ const char MaxFunction::REPR[]="max";
 
 const char MinFunction::REPR[]="min";
 
+const char GreaterThanFunction::REPR[]=">";
+
+const char LowerThanFunction::REPR[]="<";
+
+const char IfFunction::REPR[]="if";
+
 Function *FunctionsFactory::buildFuncFromString(const char *type, int nbOfParams) throw(INTERP_KERNEL::Exception)
 {
   switch(nbOfParams)
@@ -66,6 +72,8 @@ Function *FunctionsFactory::buildFuncFromString(const char *type, int nbOfParams
       return buildUnaryFuncFromString(type);
     case 2:
       return buildBinaryFuncFromString(type);
+    case 3:
+      return buildTernaryFuncFromString(type);
     default:
       throw INTERP_KERNEL::Exception("Invalid number of params detected : limited to 2 !");
     }
@@ -117,11 +125,25 @@ Function *FunctionsFactory::buildBinaryFuncFromString(const char *type) throw(IN
     return new MaxFunction;
   if(tmp==MinFunction::REPR)
     return new MinFunction;
+  if(tmp==GreaterThanFunction::REPR)
+    return new GreaterThanFunction;
+  if(tmp==LowerThanFunction::REPR)
+    return new LowerThanFunction;
   std::string msg("Invalid binary function detected : \"");
   msg+=type; msg+="\"";
   throw INTERP_KERNEL::Exception(msg.c_str());
 }
 
+Function *FunctionsFactory::buildTernaryFuncFromString(const char *type) throw(INTERP_KERNEL::Exception)
+{
+  std::string tmp(type);
+  if(tmp==IfFunction::REPR)
+    return new IfFunction();
+  std::string msg("Invalid ternary function detected : \"");
+  msg+=type; msg+="\"";
+  throw INTERP_KERNEL::Exception(msg.c_str());
+}
+
 Function *FunctionsFactory::buildBinaryFuncFromString(char type) throw(INTERP_KERNEL::Exception)
 {
   char tmp[2]; tmp[0]=type; tmp[1]='\0';
@@ -649,3 +671,130 @@ bool MinFunction::isACall() const
 {
   return false;
 }
+
+GreaterThanFunction::~GreaterThanFunction()
+{
+}
+
+void GreaterThanFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val1=stack.back();
+  stack.pop_back();
+  Value *& val2=stack.back();
+  Value *val3;
+  try
+    {
+      val3=val1->greaterThan(val2);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      delete val1;
+      throw e;
+    }
+  delete val1;
+  delete val2;
+  val2=val3;
+}
+
+void GreaterThanFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
+}
+
+const char *GreaterThanFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool GreaterThanFunction::isACall() const
+{
+  return false;
+}
+
+LowerThanFunction::~LowerThanFunction()
+{
+}
+
+void LowerThanFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val1=stack.back();
+  stack.pop_back();
+  Value *& val2=stack.back();
+  Value *val3;
+  try
+    {
+      val3=val1->lowerThan(val2);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      delete val1;
+      throw e;
+    }
+  delete val1;
+  delete val2;
+  val2=val3;
+}
+
+void LowerThanFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
+}
+
+const char *LowerThanFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool LowerThanFunction::isACall() const
+{
+  return false;
+}
+
+int TernaryFunction::getNbInputParams() const
+{
+  return 3;
+}
+
+IfFunction::~IfFunction()
+{
+}
+
+void IfFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val1=stack.back();
+  stack.pop_back();
+  Value *val2=stack.back();
+  stack.pop_back();
+  Value *&val3=stack.back();
+  Value *val4;
+  try
+    {
+      val4=val1->ifFunc(val2,val3);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      delete val1;
+      delete val2;
+      throw e;
+    }
+  delete val1;
+  delete val2;
+  delete val3;
+  val3=val4;
+}
+
+void IfFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
+}
+
+const char *IfFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool IfFunction::isACall() const
+{
+  return false;
+}
+
index 160e15ba92031c0d880a4d62d5cb074277114485..5ef74540f33a45a07201b24f14cd4c08c72ea446 100644 (file)
@@ -38,6 +38,7 @@ namespace INTERP_KERNEL
     //static Function *buildUnaryFuncFromString(char type) throw(INTERP_KERNEL::Exception);
     static Function *buildBinaryFuncFromString(const char *type) throw(INTERP_KERNEL::Exception);
     static Function *buildBinaryFuncFromString(char type) throw(INTERP_KERNEL::Exception);
+    static Function *buildTernaryFuncFromString(const char *type) throw(INTERP_KERNEL::Exception);
   };
 
   class INTERPKERNELEXPREVAL_EXPORT Function
@@ -266,6 +267,48 @@ namespace INTERP_KERNEL
   public:
     static const char REPR[];
   };
+
+  class INTERPKERNELEXPREVAL_EXPORT GreaterThanFunction : public BinaryFunction
+  {
+  public:
+    ~GreaterThanFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT LowerThanFunction : public BinaryFunction
+  {
+  public:
+    ~LowerThanFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT TernaryFunction : public Function
+  {
+  public:
+    int getNbInputParams() const;
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT IfFunction : public TernaryFunction
+  {
+  public:
+    ~IfFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
 }
 
 #endif
index 5e3bcfe19c215d3d5c45325dd6934d835073fd29..338541960c2f2bb0aaf02549cebffa72963fa6ec 100644 (file)
@@ -137,6 +137,29 @@ Value *ValueDouble::min(const Value *other) const throw(INTERP_KERNEL::Exception
   return new ValueDouble(std::min(_data,valC->_data));
 }
 
+Value *ValueDouble::greaterThan(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueDouble *valC=checkSameType(other);
+  return new ValueDouble(_data>valC->_data?std::numeric_limits<double>::max():-std::numeric_limits<double>::max());
+}
+
+Value *ValueDouble::lowerThan(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueDouble *valC=checkSameType(other);
+  return new ValueDouble(_data<valC->_data?std::numeric_limits<double>::max():-std::numeric_limits<double>::max());
+}
+
+Value *ValueDouble::ifFunc(const Value *the, const Value *els) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueDouble *theC=checkSameType(the);
+  const ValueDouble *elsC=checkSameType(els);
+  if(_data==std::numeric_limits<double>::max())
+    return new ValueDouble(theC->_data);
+  if(_data==-std::numeric_limits<double>::max())
+    return new ValueDouble(elsC->_data);
+  throw INTERP_KERNEL::Exception("ValueDouble::ifFunc : The fist element of ternary function if is not a binary op !");
+}
+
 const ValueDouble *ValueDouble::checkSameType(const Value *val) throw(INTERP_KERNEL::Exception)
 {
   const ValueDouble *valC=dynamic_cast<const ValueDouble *>(val);
@@ -227,6 +250,24 @@ Value *ValueUnit::minus(const Value *other) const throw(INTERP_KERNEL::Exception
   return 0;
 }
 
+Value *ValueUnit::greaterThan(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(GreaterThanFunction::REPR);
+  return 0;
+}
+
+Value *ValueUnit::lowerThan(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(LowerThanFunction::REPR);
+  return 0;
+}
+
+Value *ValueUnit::ifFunc(const Value *the, const Value *els) const throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(IfFunction::REPR);
+  return 0;
+}
+
 Value *ValueUnit::mult(const Value *other) const throw(INTERP_KERNEL::Exception)
 {
   const ValueUnit *valC=checkSameType(other);
@@ -423,3 +464,57 @@ Value *ValueDoubleExpr::min(const Value *other) const throw(INTERP_KERNEL::Excep
   std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun<const double&, const double&, const double& >(std::min));
   return ret;
 }
+
+Value *ValueDoubleExpr::greaterThan(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
+  ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
+  for(int i=0;i<_sz_dest_data;i++)
+    if(_dest_data[i]<=otherC->getData()[i])
+      {
+        std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits<double>::max());
+        return ret;
+      }
+  std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits<double>::max());
+  return ret;
+}
+
+Value *ValueDoubleExpr::lowerThan(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
+  ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
+  for(int i=0;i<_sz_dest_data;i++)
+    if(_dest_data[i]>=otherC->getData()[i])
+      {
+        std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits<double>::max());
+        return ret;
+      }
+  std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits<double>::max());
+  return ret;
+}
+
+Value *ValueDoubleExpr::ifFunc(const Value *the, const Value *els) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueDoubleExpr *theC=static_cast<const ValueDoubleExpr *>(the);
+  const ValueDoubleExpr *elsC=static_cast<const ValueDoubleExpr *>(els);
+  ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
+  bool okmax=true;
+  bool okmin=true;
+  for(int i=0;i<_sz_dest_data && (okmax || okmin);i++)
+    {
+      okmax=_dest_data[i]==std::numeric_limits<double>::max();
+      okmin=_dest_data[i]==-std::numeric_limits<double>::max();
+    }
+  if(okmax || okmin)
+    {
+      if(okmax)
+        std::copy(theC->getData(),theC->getData()+_sz_dest_data,ret->getData());
+      else
+        std::copy(elsC->getData(),elsC->getData()+_sz_dest_data,ret->getData());
+      return ret;
+    }
+  else
+    {
+      throw INTERP_KERNEL::Exception("ValueDoubleExpr::ifFunc : first parameter of ternary func is NOT a consequence of a boolean op !");
+    }
+}
index 95ac2e66baeb4d2ab93f45a523de07be1338aaa1..71f1b79fe37780daf4dff5d5cb155f5b9a59982a 100644 (file)
@@ -51,6 +51,10 @@ namespace INTERP_KERNEL
     virtual Value *pow(const Value *other) const throw(INTERP_KERNEL::Exception) = 0;
     virtual Value *max(const Value *other) const throw(INTERP_KERNEL::Exception) = 0;
     virtual Value *min(const Value *other) const throw(INTERP_KERNEL::Exception) = 0;
+    virtual Value *greaterThan(const Value *other) const throw(INTERP_KERNEL::Exception) = 0;
+    virtual Value *lowerThan(const Value *other) const throw(INTERP_KERNEL::Exception) = 0;
+    //ternary
+    virtual Value *ifFunc(const Value *the, const Value *els) const throw(INTERP_KERNEL::Exception) = 0;
   };
 
   class INTERPKERNELEXPREVAL_EXPORT ValueDouble : public Value
@@ -79,6 +83,10 @@ namespace INTERP_KERNEL
     Value *pow(const Value *other) const throw(INTERP_KERNEL::Exception);
     Value *max(const Value *other) const throw(INTERP_KERNEL::Exception);
     Value *min(const Value *other) const throw(INTERP_KERNEL::Exception);
+    Value *greaterThan(const Value *other) const throw(INTERP_KERNEL::Exception);
+    Value *lowerThan(const Value *other) const throw(INTERP_KERNEL::Exception);
+    //
+    Value *ifFunc(const Value *the, const Value *els) const throw(INTERP_KERNEL::Exception);
   private:
     ValueDouble(double val);
     static const ValueDouble *checkSameType(const Value *val) throw(INTERP_KERNEL::Exception);
@@ -112,6 +120,10 @@ namespace INTERP_KERNEL
     Value *pow(const Value *other) const throw(INTERP_KERNEL::Exception);
     Value *max(const Value *other) const throw(INTERP_KERNEL::Exception);
     Value *min(const Value *other) const throw(INTERP_KERNEL::Exception);
+    Value *greaterThan(const Value *other) const throw(INTERP_KERNEL::Exception);
+    Value *lowerThan(const Value *other) const throw(INTERP_KERNEL::Exception);
+    //
+    Value *ifFunc(const Value *the, const Value *els) const throw(INTERP_KERNEL::Exception);
   private:
     ValueUnit(const DecompositionInUnitBase& unit);
     static void unsupportedOp(const char *type) throw(INTERP_KERNEL::Exception);
@@ -147,6 +159,10 @@ namespace INTERP_KERNEL
     Value *pow(const Value *other) const throw(INTERP_KERNEL::Exception);
     Value *max(const Value *other) const throw(INTERP_KERNEL::Exception);
     Value *min(const Value *other) const throw(INTERP_KERNEL::Exception);
+    Value *greaterThan(const Value *other) const throw(INTERP_KERNEL::Exception);
+    Value *lowerThan(const Value *other) const throw(INTERP_KERNEL::Exception);
+    //
+    Value *ifFunc(const Value *the, const Value *els) const throw(INTERP_KERNEL::Exception);
   private:
     int _sz_dest_data;
     double *_dest_data;
index b62b39e351e6267cfad1f30ed5049b79c12ca03e..96032f6a3433942ad1361a49ccedf3f6b9364a11 100644 (file)
@@ -20,6 +20,9 @@
 #include "ExprEvalInterpTest.hxx"
 #include "InterpKernelExprParser.hxx"
 
+#include <limits>
+#include <iterator>
+
 using namespace INTERP_TEST;
 
 void ExprEvalInterpTest::testBuildStringFromFortran()
@@ -378,3 +381,59 @@ void ExprEvalInterpTest::testInterpreterUnit1()
   INTERP_KERNEL::Unit unit12("m-m");
   CPPUNIT_ASSERT(!unit12.isInterpretationOK());
 }
+
+void ExprEvalInterpTest::testInterpreter3()
+{
+  INTERP_KERNEL::ExprParser expr1("2.3+x>5.");
+  expr1.parse();
+  std::set<std::string> res;
+  expr1.getSetOfVars(res);
+  CPPUNIT_ASSERT_EQUAL(1,(int)res.size());
+  CPPUNIT_ASSERT(*(res.begin())=="x");
+  expr1.prepareExprEvaluationVec();
+  double input[3];
+  input[0]=0.;
+  double res2[3];
+  expr1.evaluateExpr(1,input,res2);
+  CPPUNIT_ASSERT(-std::numeric_limits<double>::max()==res2[0]);
+  input[0]=2.8;
+  expr1.evaluateExpr(1,input,res2);
+  CPPUNIT_ASSERT(std::numeric_limits<double>::max()==res2[0]);
+  input[0]=2.6;
+  expr1.evaluateExpr(1,input,res2);
+  CPPUNIT_ASSERT(-std::numeric_limits<double>::max()==res2[0]);
+  //
+  INTERP_KERNEL::ExprParser expr2("2.3+x<5.");
+  expr2.parse();
+  res.clear();
+  expr2.getSetOfVars(res);
+  CPPUNIT_ASSERT_EQUAL(1,(int)res.size());
+  CPPUNIT_ASSERT(*(res.begin())=="x");
+  expr2.prepareExprEvaluationVec();
+  input[0]=0.;
+  expr2.evaluateExpr(1,input,res2);
+  CPPUNIT_ASSERT(std::numeric_limits<double>::max()==res2[0]);
+  input[0]=2.8;
+  expr2.evaluateExpr(1,input,res2);
+  CPPUNIT_ASSERT(-std::numeric_limits<double>::max()==res2[0]);
+  input[0]=2.6;
+  expr2.evaluateExpr(1,input,res2);
+  CPPUNIT_ASSERT(std::numeric_limits<double>::max()==res2[0]);
+  //
+  INTERP_KERNEL::ExprParser expr3("if(2.3+x<5.,2+3*x,3+x/2)");
+  expr3.parse();
+  res.clear();
+  expr3.getSetOfVars(res);
+  CPPUNIT_ASSERT_EQUAL(1,(int)res.size());
+  CPPUNIT_ASSERT(*(res.begin())=="x");
+  expr3.prepareExprEvaluationVec();
+  input[0]=0.;
+  expr3.evaluateExpr(1,input,res2);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res2[0],1e-12);
+  input[0]=2.8;
+  expr3.evaluateExpr(1,input,res2);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(4.4,res2[0],1e-12);
+  input[0]=2.6;
+  expr3.evaluateExpr(1,input,res2);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(9.8,res2[0],1e-12);
+}
index a135201dadeb152d791b05215e84bd5ff7c616d2..2730af59a0a3ab544581926344e32cd8e72e7f09 100644 (file)
@@ -36,6 +36,7 @@ namespace INTERP_TEST
     CPPUNIT_TEST( testInterpreter2 );
     CPPUNIT_TEST( testInterpreterUnit0 );
     CPPUNIT_TEST( testInterpreterUnit1 );
+    CPPUNIT_TEST( testInterpreter3 );
     CPPUNIT_TEST_SUITE_END();
   public:
     void setUp() { }
@@ -46,6 +47,7 @@ namespace INTERP_TEST
     void testInterpreter0();
     void testInterpreter1();
     void testInterpreter2();
+    void testInterpreter3();
     void testInterpreterUnit0();
     void testInterpreterUnit1();
   };