]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
*** empty log message ***
authorageay <ageay>
Mon, 22 Feb 2010 07:29:52 +0000 (07:29 +0000)
committerageay <ageay>
Mon, 22 Feb 2010 07:29:52 +0000 (07:29 +0000)
15 files changed:
src/INTERP_KERNEL/ExprEval/INTERPKERNELEXPREVALDefines.hxx [new file with mode: 0644]
src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx [new file with mode: 0644]
src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx [new file with mode: 0644]
src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx [new file with mode: 0644]
src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx [new file with mode: 0644]
src/INTERP_KERNEL/ExprEval/InterpKernelUnit.cxx [new file with mode: 0644]
src/INTERP_KERNEL/ExprEval/InterpKernelUnit.hxx [new file with mode: 0644]
src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx [new file with mode: 0644]
src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx [new file with mode: 0644]
src/INTERP_KERNEL/ExprEval/Makefile.am [new file with mode: 0644]
src/INTERP_KERNEL/Makefile.am
src/INTERP_KERNELTest/ExprEvalInterpTest.cxx [new file with mode: 0644]
src/INTERP_KERNELTest/ExprEvalInterpTest.hxx [new file with mode: 0644]
src/INTERP_KERNELTest/Makefile.am
src/INTERP_KERNELTest/TestInterpKernel.cxx

diff --git a/src/INTERP_KERNEL/ExprEval/INTERPKERNELEXPREVALDefines.hxx b/src/INTERP_KERNEL/ExprEval/INTERPKERNELEXPREVALDefines.hxx
new file mode 100644 (file)
index 0000000..665de2e
--- /dev/null
@@ -0,0 +1,33 @@
+//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef __INTERPKERNELEXPREVALDEFINES_HXX__
+#define __INTERPKERNELEXPREVALDEFINES_HXX__
+
+//export symbols
+#ifdef WIN32
+# if defined INTERPKERNELEXPREVAL_EXPORTS || defined interpkernelexpreval_EXPORTS
+#  define INTERPKERNELEXPREVAL_EXPORT __declspec(dllexport)
+# else
+#  define INTERPKERNELEXPREVAL_EXPORT __declspec(dllimport)
+# endif
+#else
+# define INTERPKERNELEXPREVAL_EXPORT
+#endif 
+
+#endif
diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx
new file mode 100644 (file)
index 0000000..e5e3589
--- /dev/null
@@ -0,0 +1,674 @@
+#include "InterpKernelExprParser.hxx"
+#include "InterpKernelValue.hxx"
+
+#include <cctype>
+#include <sstream>
+#include <vector>
+#include <iterator>
+#include <algorithm>
+
+using namespace INTERP_KERNEL;
+
+const char LeafExprVar::END_OF_RECOGNIZED_VAR[]="Vec";
+
+const char ExprParser::WHITE_SPACES[]=" \n";
+
+const char ExprParser::EXPR_PARSE_ERR_MSG[]="Invalid expression detected : ";
+
+LeafExpr *LeafExpr::buildInstanceFrom(const std::string& expr) throw(INTERP_KERNEL::Exception)
+{
+  std::istringstream stream;
+  stream.str(expr);
+  double val;
+  stream >> val;
+  if(!stream.fail())
+    if(stream.eof())
+      return new LeafExprVal(val);
+    else
+      {
+        std::ostringstream errMsg;
+        char MSGTYP6[]="Error following expression is not consedered as a double value : ";
+        errMsg << MSGTYP6 << expr;
+        throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+      }
+  else
+    return new LeafExprVar(expr);
+}
+
+LeafExpr::~LeafExpr()
+{
+}
+
+LeafExprVal::LeafExprVal(double value):_value(value)
+{
+}
+
+LeafExprVal::~LeafExprVal()
+{
+}
+
+void LeafExprVal::fillValue(Value *val) const throw(INTERP_KERNEL::Exception)
+{
+  val->setDouble(_value);
+}
+
+LeafExprVar::LeafExprVar(const std::string& var):_fast_pos(-1),_var_name(var)
+{
+}
+
+void LeafExprVar::fillValue(Value *val) const throw(INTERP_KERNEL::Exception)
+{
+  val->setVarname(_fast_pos,_var_name);
+}
+
+void LeafExprVar::prepareExprEvaluation(const std::vector<std::string>& vars) const throw(INTERP_KERNEL::Exception)
+{
+  std::vector<std::string>::const_iterator iter=std::find(vars.begin(),vars.end(),_var_name);
+  if(iter==vars.end())
+    {
+      if(!isRecognizedKeyVar(_var_name,_fast_pos))
+        {
+          std::ostringstream oss; oss << "Var : " << _var_name << " not in : ";
+          std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss,", "));
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+      return;
+    }
+  _fast_pos=iter-vars.begin();
+}
+
+void LeafExprVar::prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception)
+{
+  if(!isRecognizedKeyVar(_var_name,_fast_pos))
+    _fast_pos=-2;
+}
+
+bool LeafExprVar::isRecognizedKeyVar(const std::string& var, int& pos)
+{
+  if(var.length()!=sizeof(END_OF_RECOGNIZED_VAR))
+    return false;
+  std::string end=var.substr(1);
+  if(end!=END_OF_RECOGNIZED_VAR)
+    return false;
+  char first=var[0];
+  if(first<'I' || first>'Z')
+    return false;
+  pos=-7-(first-'I');
+  return true;
+}
+
+LeafExprVar::~LeafExprVar()
+{
+}
+
+ExprParser::ExprParser(const char *expr):_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr)
+{
+}
+
+//! For \b NOT null terminated strings coming from FORTRAN.
+ExprParser::ExprParser(const char *expr, int lgth):_is_parsed(false),_leaf(0),_is_parsing_ok(false)
+{
+  _expr=buildStringFromFortran(expr,lgth);
+}
+
+ExprParser::~ExprParser()
+{
+  delete _leaf;
+  releaseFunctions();
+}
+
+std::size_t ExprParser::findCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket)
+{
+  int level=0;
+  for(std::size_t iter=posOfCloseBracket-1;iter>=0;iter--)
+    if(expr[iter]==')')
+      level++;
+    else if(expr[iter]=='(')
+      {
+        if(level==0)
+          return iter;
+        else
+          level--;
+      }
+  return std::string::npos;
+}
+
+std::string ExprParser::buildStringFromFortran(const char *expr, int lgth)
+{
+  std::string ret(expr,lgth);
+  std::string whiteSpaces(WHITE_SPACES);
+  std::size_t found=ret.find_last_not_of(whiteSpaces);
+  if (found!=std::string::npos)
+    ret.erase(found+1);
+  else
+    ret.clear();//ret is all whitespace
+  return ret;
+}
+
+std::string ExprParser::deleteWhiteSpaces(const std::string& expr)
+{
+  std::string ret(expr);
+  std::string whiteSpaces(WHITE_SPACES);
+  std::size_t where1=0,where2=0;
+  while(where2!=std::string::npos && where1!=std::string::npos)
+    {
+      where1=ret.find_first_of(whiteSpaces.c_str(),where1,whiteSpaces.length());
+      if(where1!=std::string::npos)
+        {
+          where2=ret.find_first_not_of(whiteSpaces,where1);
+          if(where2!=std::string::npos)
+            ret.erase(ret.begin()+where1,ret.begin()+where2);
+          else
+            ret.erase(ret.begin()+where1,ret.end());
+        }
+    }
+  return ret;
+}
+
+void ExprParser::parse() throw(INTERP_KERNEL::Exception)
+{
+  _is_parsed=true;
+  _is_parsing_ok=false;
+  _sub_expr.clear();
+  releaseFunctions();
+  if(!_expr.empty())
+    {
+      checkBracketsParity();
+      if(!simplify())
+        parseDeeper();
+    }
+  _is_parsing_ok=true;
+}
+
+double ExprParser::evaluate() const throw(INTERP_KERNEL::Exception)
+{
+  Value *gen=new ValueDouble;
+  ValueDouble *res=(ValueDouble *)evaluateLowLev(gen);
+  delete gen;
+  double ret=res->getData();
+  delete res;
+  return ret;
+}
+
+DecompositionInUnitBase ExprParser::evaluateUnit() const throw(INTERP_KERNEL::Exception)
+{
+  Value *gen=new ValueUnit;
+  ValueUnit *res=0;
+  try
+    {
+      res=(ValueUnit *)evaluateLowLev(gen);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      delete gen;
+      throw e;
+    }
+  delete gen;
+  DecompositionInUnitBase ret=res->getData();
+  delete res;
+  return ret;
+}
+
+void ExprParser::evaluateExpr(int szOfOutParam, double *outParam, const double *inParam) const throw(INTERP_KERNEL::Exception)
+{
+  Value *gen=new ValueDoubleExpr(szOfOutParam,inParam);
+  ValueDoubleExpr *res=0;
+  try
+    {
+      res=(ValueDoubleExpr *)evaluateLowLev(gen);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      delete gen;
+      throw e;
+    }
+  delete gen;
+  std::copy(res->getData(),res->getData()+szOfOutParam,outParam);
+  delete res;
+}
+
+void ExprParser::prepareExprEvaluation(const std::vector<std::string>& vars) const throw(INTERP_KERNEL::Exception)
+{
+  if(_leaf)
+    {
+      LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
+      if(leafC)
+        leafC->prepareExprEvaluation(vars);
+    }
+  else
+    for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+      (*iter).prepareExprEvaluation(vars);
+}
+
+void ExprParser::prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception)
+{
+  std::set<std::string> trueVars;
+  getTrueSetOfVars(trueVars);
+  if(trueVars.size()>1)
+    {
+      std::ostringstream oss; oss << "For this type of evaluation only one not keyword variable authorized : ";
+      oss << "having " << trueVars.size() << " : ";
+      std::copy(trueVars.begin(),trueVars.end(),std::ostream_iterator<std::string>(oss," ")); oss << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  prepareExprEvaluationVecLowLev();
+}
+
+void ExprParser::prepareExprEvaluationVecLowLev() const throw(INTERP_KERNEL::Exception)
+{
+  if(_leaf)
+    {
+      LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
+      if(leafC)
+        leafC->prepareExprEvaluationVec();
+    }
+  else
+    for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+      (*iter).prepareExprEvaluationVecLowLev();
+}
+
+Value *ExprParser::evaluateLowLev(Value *valGen) const throw(INTERP_KERNEL::Exception)
+{
+  if(!_is_parsing_ok)
+    throw INTERP_KERNEL::Exception("Parsing fails ! Invalid expression !");
+  if(_sub_expr.empty() && !_leaf)
+    throw INTERP_KERNEL::Exception("Empty expression !");
+  std::vector<Value *> stackOfVal;
+  try
+    {
+      if(_leaf)
+        {
+          Value *ret=valGen->newInstance();
+          try
+            {
+              _leaf->fillValue(ret);
+            }
+          catch(INTERP_KERNEL::Exception& e)
+            {
+              delete ret;
+              throw e;
+            }
+          stackOfVal.resize(1);
+          stackOfVal[0]=ret;
+        }
+      else
+        {
+          stackOfVal.resize(_sub_expr.size());
+          std::vector<Value *>::reverse_iterator iter2=stackOfVal.rbegin();
+          for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++,iter2++)
+            *iter2=(*iter).evaluateLowLev(valGen);
+        }
+      std::list<Function *>::const_iterator iter3;
+      for(iter3=_func_btw_sub_expr.begin();iter3!=_func_btw_sub_expr.end();iter3++)
+        (*iter3)->operate(stackOfVal);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      for(std::vector<Value *>::iterator iter4=stackOfVal.begin();iter4!=stackOfVal.end();iter4++)
+        delete *iter4;
+      throw e;
+    }
+  return stackOfVal.back();
+}
+
+void ExprParser::getSetOfVars(std::set<std::string>& vars) const
+{
+  if(_leaf)
+    {
+      LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
+      if(leafC)
+        vars.insert(leafC->getVar());
+    }
+  else
+    for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+      (*iter).getSetOfVars(vars);
+}
+
+void ExprParser::getTrueSetOfVars(std::set<std::string>& trueVars) const
+{
+  std::set<std::string> vars;
+  getSetOfVars(vars);
+  trueVars.clear();
+  for(std::set<std::string>::const_iterator iter=vars.begin();iter!=vars.end();iter++)
+    {
+      int tmp;
+      if(!LeafExprVar::isRecognizedKeyVar(*iter,tmp))
+        trueVars.insert(*iter);
+    }
+}
+
+void ExprParser::parseDeeper() throw(INTERP_KERNEL::Exception)
+{
+  for(std::list<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+    if(!(*iter).simplify())
+      (*iter).parseDeeper();
+}
+
+/*!
+ * This method has the responsability to see if this->_expr can be seen as a unary function of something.
+ * Something defined as the contain of highest level barckets.
+ * Typically '(3*x+2)' and 'cos(4*l+p*n)' will be intercepted by this method whereas '3*x+2' not...etc..
+ */
+void ExprParser::parseUnaryFunc() throw(INTERP_KERNEL::Exception)
+{
+  if(_expr[_expr.length()-1]!=')')
+    return ;
+  //at this level of code _expr 
+  std::size_t pos1=_expr.find_first_of('(');
+  std::size_t pos4=findCorrespondingOpenBracket(_expr,_expr.length()-1);
+  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);
+  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);
+  int nbOfParamsInFunc=std::count(newExp2.begin(),newExp2.end(),',')+1;
+  if(pos3!=std::string::npos)
+    _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(funcName.c_str(),nbOfParamsInFunc));
+  else
+    {
+      int lgth=funcName.length();
+      char tmp[2]; tmp[1]='\0';
+      for(int i=0;i<lgth;i++)
+        {
+          tmp[0]=funcName[i];
+          _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(tmp,nbOfParamsInFunc));
+        }
+    }
+  std::size_t pos6=0;
+  for(int i=0;i<nbOfParamsInFunc;i++)
+    {
+      std::size_t pos5=newExp2.find_first_of(',');
+      std::size_t len=std::string::npos;
+      if(pos5!=std::string::npos)
+        len=pos5-pos6;
+      std::string newExp3=newExp2.substr(pos6,len);
+      _sub_expr.push_back(ExprParser(newExp3.c_str()));
+      pos6=pos5+1;
+    }
+  _is_parsing_ok=true;
+}
+
+/*!
+ *  This method has the responsability to see if this->_expr is interpretable without any recursion.
+ * \return true if no recursion needed, false if this->_expr is too complex to be interpreted at this level.
+ * \throw exception if this->_expr is simple enough to try to interprate this and this expression contains an error.  
+ */
+bool ExprParser::tryToInterpALeaf() throw(INTERP_KERNEL::Exception)
+{
+  std::size_t pos=_expr.find_first_not_of("+-",0,2);
+  std::string minimizedExpr=_expr.substr(pos);
+  std::size_t pos2=minimizedExpr.find_first_of("+-*/^()",0,7);
+  if(pos2!=std::string::npos)
+    return false;
+  delete _leaf;
+  _leaf=LeafExpr::buildInstanceFrom(minimizedExpr);
+  int nbOfNegs=0;
+  for(std::size_t i=0;i<pos;i++)
+    if(_expr[i]=='-')
+      nbOfNegs++;
+  if(nbOfNegs%2)
+    _func_btw_sub_expr.push_back(FunctionsFactory::buildUnaryFuncFromString("-"));
+  _is_parsing_ok=true;
+  return true;
+}
+
+void ExprParser::parseForAddMin() 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 '-':
+          if(curLevel!=0)
+            curPart+=*iter;
+          else
+            {
+              if(!curPart.empty())
+                {
+                  std::string::reverse_iterator accessor=curPart.rbegin();
+                  if(*accessor!='*' && *accessor!='/' && *accessor!='^')
+                    {
+                      isParsingSucceed=true;
+                      _sub_expr.push_back(ExprParser(curPart.c_str()));
+                      curPart.clear();
+                      _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
+                    }
+                  else
+                    curPart+=*iter;
+                }
+              else
+                curPart+=*iter;
+            }
+        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()));
+          _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::parseForMulDiv() 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 '*':
+          if(curLevel!=0)
+            curPart+=*iter;
+          else
+            {
+              isParsingSucceed=true;
+              if(!curPart.empty())
+                {
+                  _sub_expr.push_back(ExprParser(curPart.c_str()));
+                  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()));
+          _is_parsing_ok=true;
+        }
+      else
+        {
+          std::ostringstream errMsg;
+          char MSGTYP5[]="Error following expression finished by *// without right part.";
+          errMsg << EXPR_PARSE_ERR_MSG << MSGTYP5 << _expr;
+          throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+        }
+    }
+}
+
+void ExprParser::parseForPow() 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 '^':
+          if(curLevel!=0)
+            curPart+=*iter;
+          else
+            if(!curPart.empty())
+              {
+                isParsingSucceed=true;
+                _sub_expr.push_back(ExprParser(curPart.c_str()));
+                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);curPart+=*iter;
+                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()));
+          _is_parsing_ok=true;
+        }
+      else
+        {
+          std::ostringstream errMsg;
+          char MSGTYP6[]="Error following expression finished by ^ without right part.";
+          errMsg << EXPR_PARSE_ERR_MSG << MSGTYP6 << _expr;
+          throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+        }
+    }
+}
+
+void ExprParser::releaseFunctions()
+{
+  for(std::list<Function *>::iterator iter=_func_btw_sub_expr.begin();iter!=_func_btw_sub_expr.end();iter++)
+    delete *iter;
+  _func_btw_sub_expr.clear();
+}
+
+/*!
+ * This method parse this->_expr at the current level.
+ * This method first try to see if this->_expr is a leaf, if not it try a unary function of something (see INTERP_KERNEL::ExprParser::parseUnaryFunc method)
+ * If true is returned, no deeper parsing needed, if false is returned for a full parsing of this->_expr INTERP_KERNEL::ExprParser::parseDeeper call needed.
+ */
+bool ExprParser::simplify() throw(INTERP_KERNEL::Exception)
+{
+  if(tryToInterpALeaf())
+    return true;
+  parseUnaryFunc();
+  if(!_is_parsing_ok)
+    {
+      parseForAddMin();
+      if(!_is_parsing_ok)
+        {
+          parseForMulDiv();
+          if(!_is_parsing_ok)
+            parseForPow();
+        }
+    }
+  if(!_is_parsing_ok)
+    {
+      std::ostringstream errMsg;
+      char MSGTYP3[]="Error in interpreting : ";
+      errMsg << EXPR_PARSE_ERR_MSG << MSGTYP3 << _expr;
+      locateError(errMsg,_expr,0);
+      throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+    }
+  return false;
+}
+
+void ExprParser::checkBracketsParity() const throw(INTERP_KERNEL::Exception)
+{
+  std::string::const_iterator iter;
+  int curLevel=0;
+  for(iter=_expr.begin();iter!=_expr.end();iter++)
+    {
+      if(*iter=='(')
+        curLevel++;
+      else if(*iter==')')
+        {
+          if(curLevel==0)
+            {
+              std::ostringstream errMsg;
+              char MSGTYP1[]="Error in brackets : closing brackets ')' before openning '('";
+              errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1;
+              locateError(errMsg,_expr,iter-_expr.begin());
+              throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+            }
+          curLevel--;
+        }
+    }
+  if(curLevel!=0)
+    {
+      std::ostringstream errMsg;
+      char MSGTYP2[]="Error in brackets : not finally closed expr.";
+      errMsg << EXPR_PARSE_ERR_MSG << MSGTYP2;
+      throw INTERP_KERNEL::Exception(errMsg.str().c_str());
+    }
+}
+
+void ExprParser::locateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr)
+{
+  stringToDisp << "Position is " << posOfErr << " of string : \"" <<  srcOfErr << "\"" << std::endl;
+}
diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx
new file mode 100644 (file)
index 0000000..3b5c046
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef __INTERPKERNELEXPRPARSER_HXX__
+#define __INTERPKERNELEXPRPARSER_HXX__
+
+#include "INTERPKERNELEXPREVALDefines.hxx"
+#include "InterpKernelUnit.hxx"
+#include "InterpKernelException.hxx"
+#include "InterpKernelFunction.hxx"
+
+#include <string>
+#include <list>
+#include <map>
+#include <set>
+
+namespace INTERP_KERNEL
+{
+  class ValueDouble;
+
+  class INTERPKERNELEXPREVAL_EXPORT LeafExpr
+  {
+  public:
+    virtual ~LeafExpr();
+    virtual void fillValue(Value *val) const throw(INTERP_KERNEL::Exception) = 0;
+    static LeafExpr *buildInstanceFrom(const std::string& expr) throw(INTERP_KERNEL::Exception);
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT LeafExprVal : public LeafExpr
+  {
+  public:
+    LeafExprVal(double value);
+    ~LeafExprVal();
+    void fillValue(Value *val) const throw(INTERP_KERNEL::Exception);
+  private:
+    double _value;
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT LeafExprVar : public LeafExpr
+  {
+  public:
+    LeafExprVar(const std::string& var);
+    ~LeafExprVar();
+    void fillValue(Value *val) const throw(INTERP_KERNEL::Exception);
+    std::string getVar() const { return _var_name; }
+    void prepareExprEvaluation(const std::vector<std::string>& vars) const throw(INTERP_KERNEL::Exception);
+    void prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception);
+    static bool isRecognizedKeyVar(const std::string& var, int& pos);
+  public:
+    static const char END_OF_RECOGNIZED_VAR[];
+  private:
+    mutable int _fast_pos;
+    std::string _var_name;
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT ExprParser
+  {
+  public:
+    ExprParser(const char *expr);
+    ExprParser(const char *expr, int lgth);
+    ~ExprParser();
+    void parse() throw(INTERP_KERNEL::Exception);
+    bool isParsingSuccessfull() const { return _is_parsing_ok; }
+    double evaluate() const throw(INTERP_KERNEL::Exception);
+    DecompositionInUnitBase evaluateUnit() const throw(INTERP_KERNEL::Exception);
+    void prepareExprEvaluation(const std::vector<std::string>& vars) const throw(INTERP_KERNEL::Exception);
+    void evaluateExpr(int szOfOutParam, double *outParam, const double *inParam) const throw(INTERP_KERNEL::Exception);
+    void prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception);
+    void getSetOfVars(std::set<std::string>& vars) const;
+    void getTrueSetOfVars(std::set<std::string>& vars) const;
+    static std::string buildStringFromFortran(const char *expr, int lgth);
+    static std::string deleteWhiteSpaces(const std::string& expr);
+  private:
+    Value *evaluateLowLev(Value *valGen) const throw(INTERP_KERNEL::Exception);
+  private:
+    void prepareExprEvaluationVecLowLev() const throw(INTERP_KERNEL::Exception);
+    bool tryToInterpALeaf() throw(INTERP_KERNEL::Exception);
+    void parseUnaryFunc() throw(INTERP_KERNEL::Exception);
+    void parseForAddMin() throw(INTERP_KERNEL::Exception);
+    void parseForMulDiv() throw(INTERP_KERNEL::Exception);
+    void parseForPow() throw(INTERP_KERNEL::Exception);
+    void parseDeeper() throw(INTERP_KERNEL::Exception);
+    bool simplify() throw(INTERP_KERNEL::Exception);
+    void releaseFunctions();
+    void checkBracketsParity() const throw(INTERP_KERNEL::Exception);
+    static std::size_t findCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket);
+    static void locateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr);
+  private:
+    bool _is_parsed;
+    LeafExpr *_leaf;
+    bool _is_parsing_ok;
+    std::string _expr;
+    std::list<ExprParser> _sub_expr;
+    std::list<Function *> _func_btw_sub_expr;
+  private:
+    static const char WHITE_SPACES[];
+    static const char EXPR_PARSE_ERR_MSG[];
+  };
+}
+
+#endif
diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx
new file mode 100644 (file)
index 0000000..3f22d6b
--- /dev/null
@@ -0,0 +1,549 @@
+#include "InterpKernelFunction.hxx"
+#include "InterpKernelValue.hxx"
+
+#include <cmath>
+
+using namespace INTERP_KERNEL;
+
+const char IdentityFunction::REPR[]="Id";
+
+const char PositiveFunction::REPR[]="+";
+
+const char NegateFunction::REPR[]="-";
+
+const char CosFunction::REPR[]="cos";
+
+const char SinFunction::REPR[]="sin";
+
+const char TanFunction::REPR[]="tan";
+
+const char SqrtFunction::REPR[]="sqrt";
+
+const char AbsFunction::REPR[]="abs";
+
+const char PlusFunction::REPR[]="+";
+
+const char MinusFunction::REPR[]="-";
+
+const char MultFunction::REPR[]="*";
+
+const char DivFunction::REPR[]="/";
+
+const char PowFunction::REPR[]="^";
+
+const char ExpFunction::REPR[]="exp";
+
+const char LnFunction::REPR[]="ln";
+
+const char MaxFunction::REPR[]="max";
+
+const char MinFunction::REPR[]="min";
+
+Function *FunctionsFactory::buildFuncFromString(const char *type, int nbOfParams) throw(INTERP_KERNEL::Exception)
+{
+  switch(nbOfParams)
+    {
+    case 1:
+      return buildUnaryFuncFromString(type);
+    case 2:
+      return buildBinaryFuncFromString(type);
+    default:
+      throw INTERP_KERNEL::Exception("Invalid number of params detected : limited to 2 !");
+    }
+}
+
+Function *FunctionsFactory::buildUnaryFuncFromString(const char *type) throw(INTERP_KERNEL::Exception)
+{
+  std::string tmp(type);
+  if(tmp.empty())
+    return new IdentityFunction;
+  if(tmp==CosFunction::REPR)
+    return new CosFunction;
+  if(tmp==SinFunction::REPR)
+    return new SinFunction;
+  if(tmp==TanFunction::REPR)
+    return new TanFunction;
+  if(tmp==SqrtFunction::REPR)
+    return new SqrtFunction;
+  if(tmp==AbsFunction::REPR)
+    return new AbsFunction;
+  if(tmp==PositiveFunction::REPR)
+    return new PositiveFunction;
+  if(tmp==NegateFunction::REPR)
+    return new NegateFunction;
+  if(tmp==ExpFunction::REPR)
+    return new ExpFunction;
+  if(tmp==LnFunction::REPR)
+    return new LnFunction;
+  //
+  std::string msg("Invalid unary function detected : \"");
+  msg+=type; msg+="\"";
+  throw INTERP_KERNEL::Exception(msg.c_str());
+}
+
+Function *FunctionsFactory::buildBinaryFuncFromString(const char *type) throw(INTERP_KERNEL::Exception)
+{
+  std::string tmp(type);
+  if(tmp==PositiveFunction::REPR)
+    return new PlusFunction;
+  if(tmp==NegateFunction::REPR)
+    return new MinusFunction;
+  if(tmp==MultFunction::REPR)
+    return new MultFunction;
+  if(tmp==DivFunction::REPR)
+    return new DivFunction;
+  if(tmp==PowFunction::REPR)
+    return new PowFunction;
+  if(tmp==MaxFunction::REPR)
+    return new MaxFunction;
+  if(tmp==MinFunction::REPR)
+    return new MinFunction;
+  std::string msg("Invalid binary 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';
+  return buildBinaryFuncFromString(tmp);
+}
+
+Function::~Function()
+{
+}
+
+IdentityFunction::~IdentityFunction()
+{
+}
+
+void IdentityFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+}
+
+const char *IdentityFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool IdentityFunction::isACall() const
+{
+  return false;
+}
+
+PositiveFunction::~PositiveFunction()
+{
+}
+
+int UnaryFunction::getNbInputParams() const
+{
+  return 1;
+}
+
+void PositiveFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+}
+
+const char *PositiveFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool PositiveFunction::isACall() const
+{
+  return false;
+}
+
+NegateFunction::~NegateFunction()
+{
+}
+
+void NegateFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val=stack.back();
+  val->negate();
+}
+
+const char *NegateFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool NegateFunction::isACall() const
+{
+  return false;
+}
+
+CosFunction::~CosFunction()
+{
+}
+
+void CosFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val=stack.back();
+  val->cos();
+}
+
+const char *CosFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool CosFunction::isACall() const
+{
+  return true;
+}
+
+SinFunction::~SinFunction()
+{
+}
+
+void SinFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val=stack.back();
+  val->sin();
+}
+
+const char *SinFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool SinFunction::isACall() const
+{
+  return true;
+}
+
+TanFunction::~TanFunction()
+{
+}
+
+void TanFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val=stack.back();
+  val->tan();
+}
+
+const char *TanFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool TanFunction::isACall() const
+{
+  return true;
+}
+
+SqrtFunction::~SqrtFunction()
+{
+}
+
+void SqrtFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val=stack.back();
+  val->sqrt();
+}
+
+const char *SqrtFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool SqrtFunction::isACall() const
+{
+  return true;
+}
+
+AbsFunction::~AbsFunction()
+{
+}
+
+void AbsFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val=stack.back();
+  val->abs();
+}
+
+const char *AbsFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool AbsFunction::isACall() const
+{
+  return false;
+}
+
+void ExpFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val=stack.back();
+  val->exp();
+}
+const char *ExpFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool ExpFunction::isACall() const
+{
+  return true;
+}
+
+LnFunction::~LnFunction()
+{
+}
+
+void LnFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val=stack.back();
+  val->ln();
+}
+
+const char *LnFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool LnFunction::isACall() const
+{
+  return true;
+}
+
+int BinaryFunction::getNbInputParams() const
+{
+  return 2;
+}
+
+PlusFunction::~PlusFunction()
+{
+}
+
+void PlusFunction::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->plus(val2);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      delete val1;
+      throw e;
+    }
+  delete val1;
+  delete val2;
+  val2=val3;
+}
+
+const char *PlusFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool PlusFunction::isACall() const
+{
+  return false;
+}
+
+MinusFunction::~MinusFunction()
+{
+}
+
+void MinusFunction::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->minus(val2);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      delete val1;
+      throw e;
+    }
+  delete val1;
+  delete val2;
+  val2=val3;
+}
+
+const char *MinusFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool MinusFunction::isACall() const
+{
+  return false;
+}
+
+MultFunction::~MultFunction()
+{
+}
+
+void MultFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val1=stack.back();
+  stack.pop_back();
+  Value *& val2=stack.back();
+  Value *val3=val1->mult(val2);
+  delete val1;
+  delete val2;
+  val2=val3;
+}
+
+const char *MultFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool MultFunction::isACall() const
+{
+  return false;
+}
+
+DivFunction::~DivFunction()
+{
+}
+
+void DivFunction::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->div(val2);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      delete val1;
+      throw e;
+    }
+  delete val1;
+  delete val2;
+  val2=val3;
+}
+
+const char *DivFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool DivFunction::isACall() const
+{
+  return false;
+}
+
+PowFunction::~PowFunction()
+{
+}
+
+void PowFunction::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->pow(val2);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      delete val1;
+      throw e;
+    }
+  delete val1;
+  delete val2;
+  val2=val3;
+}
+
+const char *PowFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool PowFunction::isACall() const
+{
+  return true;
+}
+
+ExpFunction::~ExpFunction()
+{
+}
+
+MaxFunction::~MaxFunction()
+{
+}
+
+void MaxFunction::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->max(val2);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      delete val1;
+      throw e;
+    }
+  delete val1;
+  delete val2;
+  val2=val3;
+}
+
+const char *MaxFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool MaxFunction::isACall() const
+{
+  return false;
+}
+
+MinFunction::~MinFunction()
+{
+}
+
+void MinFunction::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->min(val2);
+    }
+  catch(INTERP_KERNEL::Exception& e)
+    {
+      delete val1;
+      throw e;
+    }
+  delete val1;
+  delete val2;
+  val2=val3;
+}
+
+const char *MinFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool MinFunction::isACall() const
+{
+  return false;
+}
diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx
new file mode 100644 (file)
index 0000000..cd158e5
--- /dev/null
@@ -0,0 +1,234 @@
+#ifndef __INTERPKERNELFUNCTION_HXX__
+#define __INTERPKERNELFUNCTION_HXX__
+
+#include "INTERPKERNELEXPREVALDefines.hxx"
+#include "InterpKernelException.hxx"
+
+#include <vector>
+
+namespace INTERP_KERNEL
+{
+  class Value;
+  class Function;
+
+  class INTERPKERNELEXPREVAL_EXPORT FunctionsFactory
+  {
+  public:
+    static Function *buildFuncFromString(const char *type, int nbOfParams) throw(INTERP_KERNEL::Exception);
+    static Function *buildUnaryFuncFromString(const char *type) throw(INTERP_KERNEL::Exception);
+    //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);
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT Function
+  {
+  public:
+    virtual ~Function();
+    virtual int getNbInputParams() const = 0;
+    virtual void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception) = 0;
+    virtual const char *getRepr() const = 0;
+    virtual bool isACall() const = 0;
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT UnaryFunction : public Function
+  { 
+  public:
+    int getNbInputParams() const;
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT IdentityFunction : public UnaryFunction
+  {
+  public:
+    ~IdentityFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT PositiveFunction : public UnaryFunction
+  {
+  public:
+    ~PositiveFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT NegateFunction : public UnaryFunction
+  {
+  public:
+    ~NegateFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT CosFunction : public UnaryFunction
+  {
+  public:
+    ~CosFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT SinFunction : public UnaryFunction
+  {
+  public:
+    ~SinFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT TanFunction : public UnaryFunction
+  {
+  public:
+    ~TanFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT SqrtFunction : public UnaryFunction
+  {
+  public:
+    ~SqrtFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT AbsFunction : public UnaryFunction
+  {
+  public:
+    ~AbsFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT ExpFunction : public UnaryFunction
+  {
+  public:
+    ~ExpFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT LnFunction : public UnaryFunction
+  {
+  public:
+    ~LnFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT BinaryFunction : public Function
+  {
+  public:
+    int getNbInputParams() const;
+  };
+
+  class PlusFunction : public BinaryFunction
+  {
+  public:
+    ~PlusFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT MinusFunction : public BinaryFunction
+  {
+  public:
+    ~MinusFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT MultFunction : public BinaryFunction
+  {
+  public:
+    ~MultFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+  
+  class INTERPKERNELEXPREVAL_EXPORT DivFunction : public BinaryFunction
+  {
+  public:
+    ~DivFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT PowFunction : public BinaryFunction
+  {
+  public:
+    ~PowFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT MaxFunction : public BinaryFunction
+  {
+  public:
+    ~MaxFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT MinFunction : public BinaryFunction
+  {
+  public:
+    ~MinFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+}
+
+#endif
diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.cxx
new file mode 100644 (file)
index 0000000..86d5dec
--- /dev/null
@@ -0,0 +1,353 @@
+#include "InterpKernelUnit.hxx"
+#include "InterpKernelExprParser.hxx"
+
+#include <cmath>
+#include <sstream>
+#include <iomanip>
+#include <limits>
+
+using namespace INTERP_KERNEL;
+
+UnitDataBase UnitDataBase::_uniqueMapForExpr;
+
+static const char InterpKernelMuAscii[2]={-0x4B,0x0};
+
+static const char InterpKernelMuUnicode[3]={-0x3E,-0x4B,0x0};
+
+const char *UnitDataBase::PREF_POW10[NB_OF_PREF_POW10]={"y","z","a","f","p","n",InterpKernelMuAscii,InterpKernelMuUnicode,"u","m","c","d",
+                                                        "da","h","k","M","G","T","P","E","Z","Y"};
+
+const double UnitDataBase::POW10[NB_OF_PREF_POW10]={1e-24,1e-21,1e-18,1e-15,1e-12,1e-9,1e-6,1e-6,1e-6,1e-3,1e-2,1e-1,
+                                                  1e1,1e2,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24};
+
+static const char InterpKernelDegreeCAscii[3]={-0x50,0x43,0x0};
+
+static const char InterpKernelDegreeCUnicode[4]={-0x3E,-0x50,0x43,0x0};
+
+static const char InterpKernelDegreeCUnicodeWin[3]={-0x08,0x43,0x0};
+
+const char *UnitDataBase::UNITS_RECOGN[NB_OF_UNITS_RECOGN]={"g","m","s","A","K",
+                                                            "W","J","Hz","V","h","min","t","N","dyn",
+                                                            "eV","Pa","atm","bar",InterpKernelDegreeCAscii,"C","ohm","F","S",
+                                                            "T","H","P","St",InterpKernelDegreeCUnicode,InterpKernelDegreeCUnicodeWin};
+
+const short UnitDataBase::PROJ_IN_BASE[NB_OF_UNITS_RECOGN][SIZE_OF_UNIT_BASE]=
+  {
+    {1,0,0,0,0},//g
+    {0,1,0,0,0},//m
+    {0,0,1,0,0},//s
+    {0,0,0,1,0},//A
+    {0,0,0,0,1},//K
+    {1,2,-3,0,0},//W
+    {1,2,-2,0,0},//J
+    {0,0,-1,0,0},//Hz
+    {1,2,-3,-1,0},//V
+    {0,0,1,0,0},//h
+    {0,0,1,0,0},//min
+    {1,0,0,0,0},//t
+    {1,1,-2,0,0},//N
+    {1,1,-2,0,0},//dyn
+    {1,2,-2,0,0},//eV
+    {1,-1,-2,0,0},//Pa
+    {1,-1,-2,0,0},//atm
+    {1,-1,-2,0,0},//bar
+    {0,0,0,0,1},//degree C
+    {0,0,1,1,0},//C
+    {1,2,-3,-2,0},//ohm
+    {-1,-2,4,2,0},//F
+    {-1,-2,3,2,0},//S
+    {1,0,-2,-1,0},//T
+    {1,2,-2,-2,0},//H
+    {1,-1,-1,0,0},//P
+    {0,2,-1,0,0},//St
+    {0,0,0,0,1},//degree C
+    {0,0,0,0,1}//degree C
+  };
+
+const double UnitDataBase::MUL_COEFF[NB_OF_UNITS_RECOGN]=
+  { 1.,1.,1.,1.,1.,
+    1000.,1000.,1.,1000.,3600.,3600.,1e6,1000.,1e-2,
+    1.60217733e-16,1000.,1.01325e8,1e8,1.,1.,1000.,1e-3,
+    1000.,1000.,100.,1.,1.,1.,1.};
+
+const double UnitDataBase::ADD_COEFF[NB_OF_UNITS_RECOGN]=
+  { 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 273.15, 0., 0., 0., 0., 0., 0., 0., 0., 273.15 ,273.15};
+
+UnitDataBase::UnitDataBase()
+{
+  for(int i=0;i<NB_OF_PREF_POW10;i++)
+    _prefix_pow_10[PREF_POW10[i]]=POW10[i];
+  for(int i=0;i<NB_OF_UNITS_RECOGN;i++)
+    {
+      _units_semantic[UNITS_RECOGN[i]]=PROJ_IN_BASE[i];
+      _units_mul[UNITS_RECOGN[i]]=MUL_COEFF[i];
+      _units_add[UNITS_RECOGN[i]]=ADD_COEFF[i];
+    }
+}
+
+const short *UnitDataBase::getInfoForUnit(const std::string& unit,
+                                          double& addFact, double& mFact) const throw(INTERP_KERNEL::Exception)
+{
+  std::size_t lgth=unit.length();
+  std::string work,work2;
+  const short *ret=0;
+  for(std::size_t i=0;i<lgth && !ret;i++)
+    {
+      work=unit.substr(i);
+      std::map<std::string,const short *>::const_iterator iter=_units_semantic.find(work);
+      if(iter!=_units_semantic.end())
+        {
+          ret=(*iter).second;
+          std::map<std::string,double>::const_iterator iter2=_units_add.find(work);
+          addFact=(*iter2).second;
+          std::map<std::string,double>::const_iterator iter3=_units_mul.find(work);
+          mFact=(*iter3).second;
+          work2=unit.substr(0,i);
+        }
+    }
+  if(!ret)
+    {
+      std::ostringstream os;
+      os << "Unit : " << unit << " not recognized !";
+      throw INTERP_KERNEL::Exception(os.str().c_str());
+    }
+  if(!work2.empty())
+    {
+      std::map<std::string,double>::const_iterator iter4=_prefix_pow_10.find(work2);
+      if(iter4==_prefix_pow_10.end())
+        {
+          std::ostringstream os;
+          os << "Unit : " << unit << " not fully recognized : \"" << work << "\" detected as core unit and \"";
+          os << work2 << "\" not recognized prefix !";
+          throw INTERP_KERNEL::Exception(os.str().c_str());
+        }
+      addFact=0.;
+      mFact*=(*iter4).second;
+    }
+  return ret;
+}
+
+DecompositionInUnitBase::DecompositionInUnitBase():_add_to_base(0.),_mult_fact_to_base(1.)
+{
+  _value[0]=0;
+  _value[1]=0;
+  _value[2]=0;
+  _value[3]=0;
+  _value[4]=0;
+}
+
+void DecompositionInUnitBase::setInfo(const short *vals, double addFact, double mFact)
+{
+  _add_to_base=addFact;
+  _mult_fact_to_base=mFact;
+  _value[0]=vals[0];
+  _value[1]=vals[1];
+  _value[2]=vals[2];
+  _value[3]=vals[3];
+  _value[4]=vals[4];
+}
+
+bool DecompositionInUnitBase::operator==(const DecompositionInUnitBase& other) const
+{
+  return _value[0]==other._value[0] && _value[1]==other._value[1] && _value[2]==other._value[2] && _value[3]==other._value[3] && _value[4]==other._value[4];
+}
+
+void DecompositionInUnitBase::getTranslationParams(const DecompositionInUnitBase& other, double& mul, double& add) const
+{
+  if((*this)==other)
+    {
+      mul=_mult_fact_to_base/other._mult_fact_to_base;
+      add=_add_to_base/other._mult_fact_to_base-other._add_to_base;
+    }
+  else
+    {
+      mul=std::numeric_limits<double>::max();
+      add=std::numeric_limits<double>::max();
+    }
+}
+
+bool DecompositionInUnitBase::isEqual(short mass, short lgth, short time, short intensity, short temp, double add, double mult)
+{
+  bool ret1=mass==_value[0];
+  bool ret2=lgth==_value[1];
+  bool ret3=time==_value[2];
+  bool ret4=intensity==_value[3];
+  bool ret5=temp==_value[4];
+  bool ret6=areDoubleEquals(add,_add_to_base);
+  bool ret7=areDoubleEquals(mult,_mult_fact_to_base);
+  return ret1 && ret2 && ret3 && ret4 && ret5 && ret6 && ret7;
+}
+
+void DecompositionInUnitBase::negate()
+{
+  _mult_fact_to_base=-_mult_fact_to_base;
+}
+
+bool DecompositionInUnitBase::isAdimensional() const
+{
+  return _value[0]==0 && _value[1]==0 && _value[2]==0 && _value[3]==0 && _value[4]==0;
+}
+
+bool DecompositionInUnitBase::isUnitary() const
+{
+  return areDoubleEquals(_add_to_base,0.) && areDoubleEquals(_mult_fact_to_base,1.);
+}
+
+void DecompositionInUnitBase::tryToConvertInUnit(double val) throw(INTERP_KERNEL::Exception)
+{
+  int valI=(int)val;
+  if((val-(double)valI)!=0.)
+    {
+      std::ostringstream os;
+      os << "Double value " << val << " can't be considered as integer. Not admitable for units !";
+      throw INTERP_KERNEL::Exception(os.str().c_str());
+    }
+  _value[0]=0;
+  _value[1]=0;
+  _value[2]=0;
+  _value[3]=0;
+  _value[4]=0;
+  _add_to_base=0;
+  _mult_fact_to_base=valI;
+}
+
+DecompositionInUnitBase &DecompositionInUnitBase::operator*(const DecompositionInUnitBase& other)
+{
+  _value[0]+=other._value[0]; _value[1]+=other._value[1]; _value[2]+=other._value[2]; _value[3]+=other._value[3]; _value[4]+=other._value[4];
+  _mult_fact_to_base*=other._mult_fact_to_base;
+  _add_to_base=0.;
+  return *this;
+}
+
+DecompositionInUnitBase &DecompositionInUnitBase::operator/(const DecompositionInUnitBase& other)
+{
+  _value[0]-=other._value[0]; _value[1]-=other._value[1]; _value[2]-=other._value[2]; _value[3]-=other._value[3]; _value[4]-=other._value[4];
+  _mult_fact_to_base/=other._mult_fact_to_base;
+ _add_to_base=0.;
+ return *this;
+}
+
+DecompositionInUnitBase &DecompositionInUnitBase::operator^(const DecompositionInUnitBase& other) throw(INTERP_KERNEL::Exception)
+{
+  if(!other.isAdimensional())
+    throw INTERP_KERNEL::Exception("Trying to execute operator ^ with a second member not adimensionnal");
+  int exp=couldItBeConsideredAsInt(other._mult_fact_to_base);
+  _value[0]*=exp; _value[1]*=exp; _value[2]*=exp; _value[3]*=exp; _value[4]*=exp;
+  _mult_fact_to_base=powInt(_mult_fact_to_base,exp);
+  _add_to_base=0.;
+  return *this;
+}
+
+void DecompositionInUnitBase::dealWithAddFactor(const DecompositionInUnitBase& other)
+{
+  if(!areDoubleEquals(_add_to_base,0.))
+    if(other.isAdimensional())
+      if(areDoubleEquals(other._mult_fact_to_base,1.))
+        return ;
+  if(!other.areDoubleEquals(_add_to_base,0.))
+    if(isAdimensional())
+      if(areDoubleEquals(_mult_fact_to_base,1.))
+        return ;
+  _add_to_base=0.;
+}
+
+double DecompositionInUnitBase::powInt(double val, int exp)
+{
+  double work=1.;
+  if(exp==0)
+    return 1.;
+  if(exp>0)
+    for(int i=0;i<exp;i++)
+      work*=val;
+  else
+    {
+      int tmp=-exp;
+      for(int i=0;i<tmp;i++)
+        work*=1/val;
+    }
+  return work;
+}
+
+bool DecompositionInUnitBase::areDoubleEquals(double a, double b)
+{
+  if(a==0. || b==0.)
+    return a==b;
+  double ref=fmax(a,b);
+  return fabs((a-b)/ref)<1e-7;
+}
+
+int DecompositionInUnitBase::couldItBeConsideredAsInt(double val) throw(INTERP_KERNEL::Exception)
+{
+  int ret=(int)val;
+  double valT=(double) ret;
+  if(valT==val)
+    return ret;
+  else
+    {
+      std::ostringstream stream; stream << "Invalid double number " << std::setprecision(16) << val << " can's be considered for ^ operation on unit.";
+      throw INTERP_KERNEL::Exception(stream.str().c_str());
+    }
+}
+
+Unit::Unit(const char *reprC, bool tryToInterp):_coarse_repr(reprC),
+                                                _is_interpreted(false),
+                                                _is_interpretation_ok(false)
+{
+  if(tryToInterp)
+    tryToInterprate();
+}
+
+Unit::Unit(const char *reprFortran, int sizeOfRepr, bool tryToInterp):_coarse_repr(ExprParser::buildStringFromFortran(reprFortran,sizeOfRepr)),
+                                                                      _is_interpreted(false),
+                                                                      _is_interpretation_ok(false)
+{
+}
+
+void Unit::tryToInterprate() const
+{
+  if(!_is_interpreted)
+    {
+      _is_interpreted=true;
+      _is_interpretation_ok=false;
+      try
+        {
+          ExprParser expr(_coarse_repr.c_str());
+          expr.parse();
+          _decomp_in_base=expr.evaluateUnit();
+          _is_interpretation_ok=true;
+        }
+      catch(INTERP_KERNEL::Exception& e) { }
+    }
+}
+
+bool Unit::isInterpretationOK() const
+{
+  return _is_interpretation_ok;
+}
+
+bool Unit::isCompatibleWith(const Unit& other) const
+{
+  tryToInterprate();
+  other.tryToInterprate();
+  if(_is_interpretation_ok && other._is_interpretation_ok)
+    return _decomp_in_base==other._decomp_in_base;
+  else
+    return false;
+}
+
+double Unit::convert(const Unit& target, double sourceVal) const
+{
+  if(isCompatibleWith(target))
+    {
+      double mult,add;
+      _decomp_in_base.getTranslationParams(target._decomp_in_base,mult,add);
+      return mult*sourceVal+add;
+    }
+  else
+    return std::numeric_limits<double>::max();
+}
+
+std::string Unit::getCoarseRepr() const
+{
+  return _coarse_repr;
+}
diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.hxx
new file mode 100644 (file)
index 0000000..62c62d7
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef __INTERPKERNELUNIT_HXX__
+#define __INTERPKERNELUNIT_HXX__
+
+#include "INTERPKERNELEXPREVALDefines.hxx"
+#include "InterpKernelException.hxx"
+
+#include <map>
+#include <sstream>
+
+namespace INTERP_KERNEL
+{
+  class INTERPKERNELEXPREVAL_EXPORT UnitDataBase
+  {
+  public:
+    UnitDataBase();
+    const short *getInfoForUnit(const std::string& unit,
+                                double& addFact, double& mFact) const throw(INTERP_KERNEL::Exception);
+    static UnitDataBase _uniqueMapForExpr;
+    static const int SIZE_OF_UNIT_BASE=5;
+  private:
+    std::map<std::string,double> _prefix_pow_10;
+    std::map<std::string,const short *> _units_semantic;
+    std::map<std::string,double> _units_mul;
+    std::map<std::string,double> _units_add;
+  private:
+    static const int NB_OF_PREF_POW10=22;
+    static const char *PREF_POW10[NB_OF_PREF_POW10];
+    static const double POW10[NB_OF_PREF_POW10];
+    static const int NB_OF_UNITS_RECOGN=29;
+    static const char *UNITS_RECOGN[NB_OF_UNITS_RECOGN];
+    static const short PROJ_IN_BASE[NB_OF_UNITS_RECOGN][SIZE_OF_UNIT_BASE];
+    static const double MUL_COEFF[NB_OF_UNITS_RECOGN];
+    static const double ADD_COEFF[NB_OF_UNITS_RECOGN];
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT DecompositionInUnitBase
+  {
+  public:
+    DecompositionInUnitBase();
+    void setInfo(const short *vals, double addFact, double mFact);
+    short operator[](int i) const { return _value[i]; }
+    bool operator==(const DecompositionInUnitBase& other) const;
+    void getTranslationParams(const DecompositionInUnitBase& other, double& mul, double& add) const;
+    bool isEqual(short mass, short lgth, short time, short intensity, short temp,
+                 double add, double mult);
+    bool isUnitary() const;
+    //! \b WARNING no test is done on the fact that unit is adimensionnal.
+    void negate();
+    bool isAdimensional() const;
+    void tryToConvertInUnit(double val) throw(INTERP_KERNEL::Exception);
+    DecompositionInUnitBase &operator*(const DecompositionInUnitBase& other);
+    DecompositionInUnitBase &operator/(const DecompositionInUnitBase& other);
+    DecompositionInUnitBase &operator^(const DecompositionInUnitBase& other) throw(INTERP_KERNEL::Exception);
+  private:
+    void dealWithAddFactor(const DecompositionInUnitBase& other);
+    static int couldItBeConsideredAsInt(double val) throw(INTERP_KERNEL::Exception);
+    static bool areDoubleEquals(double a, double b);
+    static double powInt(double val, int exp);
+  private:
+    short _value[UnitDataBase::SIZE_OF_UNIT_BASE];
+    double _add_to_base;
+    double _mult_fact_to_base;
+  };
+
+  /*!
+   * This class deals with units.
+   * This class has two main responsabilities :
+   *      - interprete units by giving simply their representation in string type.
+   *      - performing operations on these units.
+   *
+   * All the possible units are represented with a unique tuple with 5 elements
+   * representing the unique decomposition of a unit in the following base.
+   *
+   * dimension 0 stands for mass in g (\b NOT kg to simplify parsing).
+   * dimension 1 stands for length in m.
+   * dimension 2 stands for time in s.
+   * dimension 3 stands for elec intensity A.
+   * dimension 4 stands for temperature in K.
+   */
+  class INTERPKERNELEXPREVAL_EXPORT Unit
+  {
+  public:
+    Unit(const char *reprC, bool tryToInterp=true);
+    Unit(const char *reprFortran, int sizeOfRepr, bool tryToInterp=true);
+    void tryToInterprate() const;
+    bool isInterpretationOK() const;
+    bool isCompatibleWith(const Unit& other) const;
+    double convert(const Unit& target, double sourceVal) const;
+    std::string getCoarseRepr() const;
+  private:
+    std::string _coarse_repr;
+    mutable bool _is_interpreted;
+    mutable bool _is_interpretation_ok;
+    mutable DecompositionInUnitBase _decomp_in_base;
+  };
+}
+
+#endif
diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx
new file mode 100644 (file)
index 0000000..b644057
--- /dev/null
@@ -0,0 +1,409 @@
+#include "InterpKernelValue.hxx"
+#include "InterpKernelFunction.hxx"
+
+#include <cmath>
+#include <limits>
+#include <algorithm>
+
+using namespace INTERP_KERNEL;
+
+ValueDouble::ValueDouble():_data(std::numeric_limits<double>::max())
+{
+}
+
+Value *ValueDouble::newInstance() const
+{
+  return new ValueDouble;
+}
+
+ValueDouble::ValueDouble(double val):_data(val)
+{
+}
+
+void ValueDouble::setDouble(double val) throw(INTERP_KERNEL::Exception)
+{
+  _data=val;
+}
+
+void ValueDouble::setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception)
+{
+  std::string msg("Error var : "); msg+=var; msg+=" not numeric : use another expression evaluator !";
+  throw INTERP_KERNEL::Exception(msg.c_str());
+}
+
+void ValueDouble::positive() throw(INTERP_KERNEL::Exception)
+{
+}
+
+void ValueDouble::negate() throw(INTERP_KERNEL::Exception)
+{
+  _data=-_data;
+}
+
+void ValueDouble::sqrt() throw(INTERP_KERNEL::Exception)
+{
+  _data=std::sqrt(_data);
+}
+
+void ValueDouble::cos() throw(INTERP_KERNEL::Exception)
+{
+  _data=std::cos(_data);
+}
+
+void ValueDouble::sin() throw(INTERP_KERNEL::Exception)
+{
+  _data=std::sin(_data);
+}
+
+void ValueDouble::tan() throw(INTERP_KERNEL::Exception)
+{
+  _data=std::tan(_data);
+}
+
+void ValueDouble::abs() throw(INTERP_KERNEL::Exception)
+{
+  if(_data<0.)
+    _data=-_data;
+}
+
+void ValueDouble::exp() throw(INTERP_KERNEL::Exception)
+{
+  _data=std::exp(_data);
+}
+
+void ValueDouble:: ln() throw(INTERP_KERNEL::Exception)
+{
+  _data=std::log(_data);
+}
+
+Value *ValueDouble::plus(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueDouble *valC=checkSameType(other);
+  return new ValueDouble(_data+valC->_data);
+}
+
+Value *ValueDouble::minus(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueDouble *valC=checkSameType(other);
+  return new ValueDouble(_data-valC->_data);
+}
+
+Value *ValueDouble::mult(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueDouble *valC=checkSameType(other);
+  return new ValueDouble(_data*valC->_data);
+}
+
+Value *ValueDouble::div(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueDouble *valC=checkSameType(other);
+  return new ValueDouble(_data/valC->_data);
+}
+
+Value *ValueDouble::pow(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueDouble *valC=checkSameType(other);
+  return new ValueDouble(std::pow(_data,valC->_data));
+}
+
+Value *ValueDouble::max(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueDouble *valC=checkSameType(other);
+  return new ValueDouble(std::max(_data,valC->_data));
+}
+
+Value *ValueDouble::min(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueDouble *valC=checkSameType(other);
+  return new ValueDouble(std::min(_data,valC->_data));
+}
+
+const ValueDouble *ValueDouble::checkSameType(const Value *val) throw(INTERP_KERNEL::Exception)
+{
+  const ValueDouble *valC=dynamic_cast<const ValueDouble *>(val);
+  if(!valC)
+    throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (double with other type) !");
+  return valC;
+}
+
+ValueUnit::ValueUnit()
+{
+}
+
+Value *ValueUnit::newInstance() const
+{
+  return new ValueUnit;
+}
+
+ValueUnit::ValueUnit(const DecompositionInUnitBase& unit):_data(unit)
+{
+}
+
+void ValueUnit::setDouble(double val) throw(INTERP_KERNEL::Exception)
+{
+  _data.tryToConvertInUnit(val);
+}
+
+void ValueUnit::setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception)
+{
+  double add,mult;
+  const short *projInBase=UnitDataBase::_uniqueMapForExpr.getInfoForUnit(var,add,mult);
+  _data.setInfo(projInBase,add,mult);
+}
+
+void ValueUnit::positive() throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(PositiveFunction::REPR);
+}
+
+void ValueUnit::negate() throw(INTERP_KERNEL::Exception)
+{
+  _data.negate();
+}
+
+void ValueUnit::sqrt() throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(SqrtFunction::REPR);
+}
+
+void ValueUnit::cos() throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(CosFunction::REPR);
+}
+
+void ValueUnit::sin() throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(SinFunction::REPR);
+}
+
+void ValueUnit::tan() throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(TanFunction::REPR);
+}
+
+void ValueUnit::abs() throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(AbsFunction::REPR);
+}
+
+void ValueUnit::exp() throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(ExpFunction::REPR);
+}
+
+void ValueUnit::ln() throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(LnFunction::REPR);
+}
+
+Value *ValueUnit::plus(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(PlusFunction::REPR);
+  return 0;
+}
+
+Value *ValueUnit::minus(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(MinusFunction::REPR);
+  return 0;
+}
+
+Value *ValueUnit::mult(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueUnit *valC=checkSameType(other);
+  DecompositionInUnitBase tmp=_data;
+  tmp*valC->getData();
+  return new ValueUnit(tmp);
+}
+
+Value *ValueUnit::div(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueUnit *valC=checkSameType(other);
+  DecompositionInUnitBase tmp=_data;
+  tmp/valC->getData();
+  return new ValueUnit(tmp);
+}
+
+Value *ValueUnit::pow(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueUnit *valC=checkSameType(other);
+  DecompositionInUnitBase tmp=_data;
+  tmp^valC->getData();
+  return new ValueUnit(tmp);
+}
+
+Value *ValueUnit::max(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(MaxFunction::REPR);
+  return 0;
+}
+
+Value *ValueUnit::min(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(MinFunction::REPR);
+  return 0;
+}
+
+const ValueUnit *ValueUnit::checkSameType(const Value *val) throw(INTERP_KERNEL::Exception)
+{
+  const ValueUnit *valC=dynamic_cast<const ValueUnit *>(val);
+  if(!valC)
+    throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (Units with other type) !");
+  return valC;
+}
+
+void ValueUnit::unsupportedOp(const char *type) throw(INTERP_KERNEL::Exception)
+{
+  const char msg[]="Unsupported operation for units :";
+  std::string msgStr(msg);
+  msgStr+=type;
+  throw INTERP_KERNEL::Exception(msgStr.c_str());
+}
+
+ValueDoubleExpr::ValueDoubleExpr(int szDestData, const double *srcData):_sz_dest_data(szDestData),_dest_data(new double[_sz_dest_data]),_src_data(srcData)
+{
+}
+
+ValueDoubleExpr::~ValueDoubleExpr()
+{
+  delete [] _dest_data;
+}
+
+Value *ValueDoubleExpr::newInstance() const
+{
+  return new ValueDoubleExpr(_sz_dest_data,_src_data);
+}
+
+void ValueDoubleExpr::setDouble(double val) throw(INTERP_KERNEL::Exception)
+{
+  std::fill(_dest_data,_dest_data+_sz_dest_data,val);
+}
+
+void ValueDoubleExpr::setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception)
+{
+  if(fastPos==-2)
+    std::copy(_src_data,_src_data+_sz_dest_data,_dest_data);
+  else if(fastPos>-2)
+    std::fill(_dest_data,_dest_data+_sz_dest_data,_src_data[fastPos]);
+  else
+    {
+      std::fill(_dest_data,_dest_data+_sz_dest_data,0.);
+      _dest_data[-7-fastPos]=1.;
+    }
+}
+
+void ValueDoubleExpr::positive() throw(INTERP_KERNEL::Exception)
+{
+}
+
+void ValueDoubleExpr::negate() throw(INTERP_KERNEL::Exception)
+{
+  std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::negate<double>());
+}
+
+void ValueDoubleExpr::sqrt() throw(INTERP_KERNEL::Exception)
+{
+  double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),0.));
+  if(it!=_dest_data+_sz_dest_data)
+    throw INTERP_KERNEL::Exception("Trying to apply sqrt on < 0. value !");
+  std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sqrt));
+}
+
+void ValueDoubleExpr::cos() throw(INTERP_KERNEL::Exception)
+{
+  std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::cos));
+}
+
+void ValueDoubleExpr::sin() throw(INTERP_KERNEL::Exception)
+{
+  std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sin));
+}
+
+void ValueDoubleExpr::tan() throw(INTERP_KERNEL::Exception)
+{
+  std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::tan));
+}
+
+void ValueDoubleExpr::abs() throw(INTERP_KERNEL::Exception)
+{
+  std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(fabs));
+}
+
+void ValueDoubleExpr::exp() throw(INTERP_KERNEL::Exception)
+{
+  std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::exp));
+}
+
+void ValueDoubleExpr::ln() throw(INTERP_KERNEL::Exception)
+{
+  double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal<double>(),0.));
+  if(it!=_dest_data+_sz_dest_data)
+    throw INTERP_KERNEL::Exception("Trying to apply sqrt on < 0. value !");
+  std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::log));
+}
+
+Value *ValueDoubleExpr::plus(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);
+  std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::plus<double>());
+  return ret;
+}
+
+Value *ValueDoubleExpr::minus(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);
+  std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::minus<double>());
+  return ret;
+}
+
+Value *ValueDoubleExpr::mult(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);
+  std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::multiplies<double>());
+  return ret;
+}
+
+Value *ValueDoubleExpr::div(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
+  double *it=std::find(otherC->getData(),otherC->getData()+_sz_dest_data,0.);
+  if(it!=otherC->getData()+_sz_dest_data)
+    throw INTERP_KERNEL::Exception("Trying to operate division by 0. !");
+  ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
+  std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::divides<double>());
+  return ret;
+}
+
+Value *ValueDoubleExpr::pow(const Value *other) const throw(INTERP_KERNEL::Exception)
+{
+  const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other);
+  double p=otherC->getData()[0];
+  if(p<0.)
+    {
+      double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),0.));
+      if(it!=_dest_data+_sz_dest_data)
+        throw INTERP_KERNEL::Exception("Trying to operate pow(a,b) with a<0. and b<0. !");
+    }
+  ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data);
+  std::transform(_dest_data,_dest_data+_sz_dest_data,ret->getData(),std::bind2nd(std::ptr_fun(powl),p));
+  return ret;
+}
+
+Value *ValueDoubleExpr::max(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);
+  std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun(fmax));
+  return ret;
+}
+
+Value *ValueDoubleExpr::min(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);
+  std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun(fmin));
+  return ret;
+}
diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx
new file mode 100644 (file)
index 0000000..ae0357c
--- /dev/null
@@ -0,0 +1,138 @@
+#ifndef __INTERPKERNELVALUE_HXX__
+#define __INTERPKERNELVALUE_HXX__
+
+#include "INTERPKERNELEXPREVALDefines.hxx"
+#include "InterpKernelException.hxx"
+#include "InterpKernelUnit.hxx"
+
+namespace INTERP_KERNEL
+{
+  class INTERPKERNELEXPREVAL_EXPORT Value
+  {
+  public:
+    virtual Value *newInstance() const = 0;
+    virtual ~Value() { }
+    virtual void setDouble(double val) throw(INTERP_KERNEL::Exception) = 0;
+    virtual void setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception) = 0;
+    //unary
+    virtual void positive() throw(INTERP_KERNEL::Exception) = 0;
+    virtual void negate() throw(INTERP_KERNEL::Exception) = 0;
+    virtual void sqrt() throw(INTERP_KERNEL::Exception) = 0;
+    virtual void cos() throw(INTERP_KERNEL::Exception) = 0;
+    virtual void sin() throw(INTERP_KERNEL::Exception) = 0;
+    virtual void tan() throw(INTERP_KERNEL::Exception) = 0;
+    virtual void abs() throw(INTERP_KERNEL::Exception) = 0;
+    virtual void exp() throw(INTERP_KERNEL::Exception) = 0;
+    virtual void ln() throw(INTERP_KERNEL::Exception) = 0;
+    //binary
+    virtual Value *plus(const Value *other) const throw(INTERP_KERNEL::Exception) = 0;
+    virtual Value *minus(const Value *other) const throw(INTERP_KERNEL::Exception) = 0;
+    virtual Value *mult(const Value *other) const throw(INTERP_KERNEL::Exception) = 0;
+    virtual Value *div(const Value *other) const throw(INTERP_KERNEL::Exception) = 0;
+    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;
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT ValueDouble : public Value
+  {
+  public:
+    ValueDouble();
+    Value *newInstance() const;
+    void setDouble(double val) throw(INTERP_KERNEL::Exception);
+    void setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception);
+    //
+    double getData() const { return _data; }
+    void positive() throw(INTERP_KERNEL::Exception);
+    void negate() throw(INTERP_KERNEL::Exception);
+    void sqrt() throw(INTERP_KERNEL::Exception);
+    void cos() throw(INTERP_KERNEL::Exception);
+    void sin() throw(INTERP_KERNEL::Exception);
+    void tan() throw(INTERP_KERNEL::Exception);
+    void abs() throw(INTERP_KERNEL::Exception);
+    void exp() throw(INTERP_KERNEL::Exception);
+    void ln() throw(INTERP_KERNEL::Exception);
+    //
+    Value *plus(const Value *other) const throw(INTERP_KERNEL::Exception);
+    Value *minus(const Value *other) const throw(INTERP_KERNEL::Exception);
+    Value *mult(const Value *other) const throw(INTERP_KERNEL::Exception);
+    Value *div(const Value *other) const throw(INTERP_KERNEL::Exception);
+    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);
+  private:
+    ValueDouble(double val);
+    static const ValueDouble *checkSameType(const Value *val) throw(INTERP_KERNEL::Exception);
+  private:
+    double _data;
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT ValueUnit : public Value
+  {
+  public:
+    ValueUnit();
+    Value *newInstance() const;
+    void setDouble(double val) throw(INTERP_KERNEL::Exception);
+    void setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception);
+    //
+    DecompositionInUnitBase getData() const { return _data; }
+    void positive() throw(INTERP_KERNEL::Exception);
+    void negate() throw(INTERP_KERNEL::Exception);
+    void sqrt() throw(INTERP_KERNEL::Exception);
+    void cos() throw(INTERP_KERNEL::Exception);
+    void sin() throw(INTERP_KERNEL::Exception);
+    void tan() throw(INTERP_KERNEL::Exception);
+    void abs() throw(INTERP_KERNEL::Exception);
+    void exp() throw(INTERP_KERNEL::Exception);
+    void ln() throw(INTERP_KERNEL::Exception);
+    //
+    Value *plus(const Value *other) const throw(INTERP_KERNEL::Exception);
+    Value *minus(const Value *other) const throw(INTERP_KERNEL::Exception);
+    Value *mult(const Value *other) const throw(INTERP_KERNEL::Exception);
+    Value *div(const Value *other) const throw(INTERP_KERNEL::Exception);
+    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);
+  private:
+    ValueUnit(const DecompositionInUnitBase& unit);
+    static void unsupportedOp(const char *type) throw(INTERP_KERNEL::Exception);
+    static const ValueUnit *checkSameType(const Value *val) throw(INTERP_KERNEL::Exception);
+  private:
+    DecompositionInUnitBase _data;
+  };
+
+  class INTERPKERNELEXPREVAL_EXPORT ValueDoubleExpr : public Value
+  {
+  public:
+    ValueDoubleExpr(int szDestData, const double *srcData);
+    ~ValueDoubleExpr();
+    double *getData() const { return _dest_data; }
+    Value *newInstance() const;
+    void setDouble(double val) throw(INTERP_KERNEL::Exception);
+    void setVarname(int fastPos, const std::string& var) throw(INTERP_KERNEL::Exception);
+    //
+    void positive() throw(INTERP_KERNEL::Exception);
+    void negate() throw(INTERP_KERNEL::Exception);
+    void sqrt() throw(INTERP_KERNEL::Exception);
+    void cos() throw(INTERP_KERNEL::Exception);
+    void sin() throw(INTERP_KERNEL::Exception);
+    void tan() throw(INTERP_KERNEL::Exception);
+    void abs() throw(INTERP_KERNEL::Exception);
+    void exp() throw(INTERP_KERNEL::Exception);
+    void ln() throw(INTERP_KERNEL::Exception);
+    //
+    Value *plus(const Value *other) const throw(INTERP_KERNEL::Exception);
+    Value *minus(const Value *other) const throw(INTERP_KERNEL::Exception);
+    Value *mult(const Value *other) const throw(INTERP_KERNEL::Exception);
+    Value *div(const Value *other) const throw(INTERP_KERNEL::Exception);
+    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);
+  private:
+    int _sz_dest_data;
+    double *_dest_data;
+    const double *_src_data;
+  };
+}
+
+#endif
diff --git a/src/INTERP_KERNEL/ExprEval/Makefile.am b/src/INTERP_KERNEL/ExprEval/Makefile.am
new file mode 100644 (file)
index 0000000..0df59ea
--- /dev/null
@@ -0,0 +1,56 @@
+#  Copyright (C) 2007-2008  CEA/DEN, EDF R&D
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+#  File   : Makefile.am
+#  Author : Anthony GEAY (CEA/DEN/DANS/DM2S/SFME/LGLS)
+#  Module : MED
+#
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+lib_LTLIBRARIES = libinterpkernelexpreval.la
+
+salomeinclude_HEADERS =                \
+INTERPKERNELEXPREVALDefines.hxx         \
+InterpKernelExprParser.hxx              \
+InterpKernelFunction.hxx                \
+InterpKernelUnit.hxx                    \
+InterpKernelValue.hxx
+
+
+EXTRA_DIST +=                          \
+INTERPKERNELEXPREVALDefines.hxx         \
+InterpKernelExprParser.hxx              \
+InterpKernelFunction.hxx                \
+InterpKernelUnit.hxx                    \
+InterpKernelValue.hxx
+
+dist_libinterpkernelexpreval_la_SOURCES = \
+       InterpKernelExprParser.cxx        \
+       InterpKernelFunction.cxx          \
+       InterpKernelUnit.cxx              \
+       InterpKernelValue.cxx
+
+libinterpkernelexpreval_la_CPPFLAGS=-I$(srcdir)/../Bases
+
+libinterpkernelexpreval_la_LDFLAGS=
+
+libinterpkernelexpreval_la_LIBADD= ../Bases/libinterpkernelbases.la
+
+AM_CPPFLAGS += $(libinterpkernelexpreval_la_CPPFLAGS)
+
+LDADD= $(libinterpkernelexpreval_la_LDFLAGS)
index 3afcd5360a9bca7f363b06665d8c86402e8cd191..fd748819a4fcd9d80b9534203cc04a624da0eee7 100644 (file)
@@ -23,9 +23,9 @@
 #
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
-SUBDIRS = Bases Geometric2D .
+SUBDIRS = Bases Geometric2D ExprEval .
 
-DIST_SUBDIRS = Bases Geometric2D
+DIST_SUBDIRS = Bases Geometric2D ExprEval
 
 lib_LTLIBRARIES = libinterpkernel.la
 
@@ -173,7 +173,7 @@ libinterpkernel_la_CPPFLAGS=-I$(srcdir)/Geometric2D -I$(srcdir)/Bases
 libinterpkernel_la_LDFLAGS=
 
 # the geom2D library is included in the interpkernel one
-libinterpkernel_la_LIBADD= ./Geometric2D/libInterpGeometric2DAlg.la Bases/libinterpkernelbases.la
+libinterpkernel_la_LIBADD= ./Geometric2D/libInterpGeometric2DAlg.la Bases/libinterpkernelbases.la ExprEval/libinterpkernelexpreval.la
 
 AM_CPPFLAGS += $(libinterpkernel_la_CPPFLAGS)
 LDADD= $(libinterpkernel_la_LDFLAGS)
diff --git a/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx b/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx
new file mode 100644 (file)
index 0000000..9bf31ed
--- /dev/null
@@ -0,0 +1,380 @@
+//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "ExprEvalInterpTest.hxx"
+#include "InterpKernelExprParser.hxx"
+
+using namespace std;
+using namespace INTERP_TEST;
+
+void ExprEvalInterpTest::testBuildStringFromFortran()
+{
+  char toto1[]="123456  ";
+  char result[]="123456";
+  string titi;
+  titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto1,8);
+  CPPUNIT_ASSERT_EQUAL(6,(int)titi.length());
+  CPPUNIT_ASSERT(titi==result);
+  //
+  char toto2[]=" 23456  ";
+  char result2[]=" 23456";
+  titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto2,8);
+  CPPUNIT_ASSERT(titi==result2);
+  CPPUNIT_ASSERT_EQUAL(6,(int)titi.length());
+  //
+  char toto3[]="  3456  ";
+  char result3[]="  3456";
+  titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto3,8);
+  CPPUNIT_ASSERT(titi==result3);
+  CPPUNIT_ASSERT_EQUAL(6,(int)titi.length());
+  //
+  char toto4[]="        ";
+  titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto4,8);
+  CPPUNIT_ASSERT_EQUAL(0,(int)titi.length());
+  //
+  char toto5[]="  345677";
+  titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto5,8);
+  CPPUNIT_ASSERT(titi==toto5);
+  CPPUNIT_ASSERT_EQUAL(8,(int)titi.length());
+}
+
+void ExprEvalInterpTest::testDeleteWhiteSpaces()
+{
+  char toto[]=" jkhjkh ooooppp l ";
+  char result[]="jkhjkhoooopppl";
+  string totoS(toto);
+  string totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+  CPPUNIT_ASSERT(totoR==result);
+  CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+  //
+  char toto2[]=" jkhjkh     ooooppp    l ";
+  totoS=toto2;
+  totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+  CPPUNIT_ASSERT(totoR==result);
+  CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+  //
+  char toto3[]=" jkhjkh     oooo pppl ";
+  totoS=toto3;
+  totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+  CPPUNIT_ASSERT(totoR==result);
+  CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+  //
+  char toto4[]=" jkhjkh     oooo pppl";
+  totoS=toto4;
+  totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+  CPPUNIT_ASSERT(totoR==result);
+  CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+  //
+  char toto5[]="jkhjkh     oooo pppl";
+  totoS=toto5;
+  totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+  CPPUNIT_ASSERT(totoR==result);
+  CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+  //
+  totoS=result;
+  totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+  CPPUNIT_ASSERT(totoR==result);
+  CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+  //
+  char toto6[]="j k h j k h o o o o p p p l";
+  totoS=toto6;
+  totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+  CPPUNIT_ASSERT(totoR==result);
+  CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+  //
+  char toto7[]="j  k  h j    k h   o  o  o  o  p  pp    l";
+  totoS=toto7;
+  totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+  CPPUNIT_ASSERT(totoR==result);
+  CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+  //
+  char toto8[]="           ";
+  totoS=toto8;
+  totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+  CPPUNIT_ASSERT(totoR.empty());
+  //
+  char toto9[]="";
+  totoS=toto9;
+  totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+  CPPUNIT_ASSERT(totoR.empty());
+  //
+  char toto10[]="j\n k \nh\nj \n\n  k\nh \n o \no\n o\n o \np\n\npp \n\n l";
+  totoS=toto10;
+  totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS);
+  CPPUNIT_ASSERT(totoR==result);
+  CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length());
+}
+
+void ExprEvalInterpTest::testInterpreter0()
+{
+  INTERP_KERNEL::ExprParser expr1("3*-2");
+  expr1.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.,expr1.evaluate(),1e-15);
+  INTERP_KERNEL::ExprParser expr2("-2.3");
+  expr2.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.3,expr2.evaluate(),1e-15);
+  INTERP_KERNEL::ExprParser expr3("--2.3");
+  expr3.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,expr3.evaluate(),1e-15);
+  INTERP_KERNEL::ExprParser expr4("-++2.3");
+  expr4.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.3,expr4.evaluate(),1e-15);
+  INTERP_KERNEL::ExprParser expr5("+2.3");
+  expr5.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,expr5.evaluate(),1e-15);
+  INTERP_KERNEL::ExprParser expr6("3^-1");
+  expr6.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333333,expr6.evaluate(),1e-15);
+}
+
+void ExprEvalInterpTest::testInterpreter1()
+{
+  INTERP_KERNEL::ExprParser expr1("3+2*5");
+  expr1.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(13.,expr1.evaluate(),1e-14);
+  INTERP_KERNEL::ExprParser expr2("3+2^3*5");
+  expr2.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(43.,expr2.evaluate(),1e-14);
+  INTERP_KERNEL::ExprParser expr3("3+2^(2*5)");
+  expr3.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(1027.,expr3.evaluate(),1e-14);
+  INTERP_KERNEL::ExprParser expr4("(3.2+4.3)*(1.3+2.3*7.8)");
+  expr4.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(144.3,expr4.evaluate(),1e-10);
+  INTERP_KERNEL::ExprParser expr5("(3.2+4.3)*cos(1.3+2.3*7.8)");
+  expr5.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(6.9355510138337619,expr5.evaluate(),1e-14);
+  INTERP_KERNEL::ExprParser expr6("3+2-4-7+4.3");
+  expr6.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.7,expr6.evaluate(),1e-14);
+  INTERP_KERNEL::ExprParser expr7("3.2*4.5/3.3/2.2");
+  expr7.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(1.9834710743801653,expr7.evaluate(),1e-14);
+  INTERP_KERNEL::ExprParser expr8("3.2*4.5/3.3/2.2");
+  expr8.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(1.9834710743801653,expr8.evaluate(),1e-14);
+  INTERP_KERNEL::ExprParser expr9("(((1.23456789)))");
+  expr9.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(1.23456789,expr9.evaluate(),1e-14);
+  INTERP_KERNEL::ExprParser expr10("3.2*((2*5.2+6.)+(1.2*1.2+3.))");
+  expr10.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(66.688,expr10.evaluate(),1e-13);
+  INTERP_KERNEL::ExprParser expr11("((3.2*(((2*5.2+6.)+(1.2*1.2+3.)))))");
+  expr11.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(66.688,expr11.evaluate(),1e-13);
+  INTERP_KERNEL::ExprParser expr12("((3.2*(cos((2*5.2+6.)+(1.2*1.2+3.)))))");
+  expr12.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.3038041398761016,expr12.evaluate(),1e-14);
+  INTERP_KERNEL::ExprParser expr13("((3.2*(sin((2*5.2+6.)+(1.2*1.2+3.)))))");
+  expr13.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(2.9223440531261784,expr13.evaluate(),1e-14);
+  INTERP_KERNEL::ExprParser expr14("((3.2*(tan((2*5.2+6.)+(1.2*1.2+3.)))))");
+  expr14.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-7.1724737512280257,expr14.evaluate(),1e-14);
+  INTERP_KERNEL::ExprParser expr15("((3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))");
+  expr15.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(14.608271629457059,expr15.evaluate(),1e-13);
+  INTERP_KERNEL::ExprParser expr16("-((3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))");
+  expr16.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.608271629457059,expr16.evaluate(),1e-13);
+  INTERP_KERNEL::ExprParser expr17("(-(3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))");
+  expr17.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.608271629457059,expr17.evaluate(),1e-13);
+  INTERP_KERNEL::ExprParser expr18("((-3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))");
+  expr18.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.608271629457059,expr18.evaluate(),1e-13);
+  INTERP_KERNEL::ExprParser expr19("((3.2*(exp((6.+2*5.2)+(1.2*1.2+3.)))))");
+  expr19.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(3596226038.1784945,expr19.evaluate(),1e-6);
+  INTERP_KERNEL::ExprParser expr20("((3.2*(ln((2*5.2+6.)+(1.2*1.2+3.)))))");
+  expr20.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(9.7179974940325309,expr20.evaluate(),1e-14);
+  INTERP_KERNEL::ExprParser expr21("max(3.2,4.5)");
+  expr21.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5,expr21.evaluate(),1e-14);
+  INTERP_KERNEL::ExprParser expr22("3.*max(((3.2*(ln((2*5.2+6.)+(1.2*1.2+3.))))),((3.2*(exp((6.+2*5.2)+(1.2*1.2+3.))))))");
+  expr22.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(10788678114.535484,expr22.evaluate(),1e-5);
+  INTERP_KERNEL::ExprParser expr23("min(3.2,4.5)");
+  expr23.parse();
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2,expr23.evaluate(),1e-14);
+}
+
+void ExprEvalInterpTest::testInterpreter2()
+{
+  INTERP_KERNEL::ExprParser expr1("3.5*x+x*x*x/(2+x)+2*5*y");
+  expr1.parse();
+  std::set<std::string> res,expected;
+  expr1.getSetOfVars(res);
+  CPPUNIT_ASSERT_EQUAL(2,(int)res.size());
+  expected.insert("x"); expected.insert("y");
+  CPPUNIT_ASSERT(std::equal(res.begin(),res.end(),expected.begin()));
+  double xyValue[2]={1.,3.};
+  double res1;
+  std::vector<std::string> vars; vars.push_back("x"); vars.push_back("y");
+  expr1.prepareExprEvaluation(vars);
+  expr1.evaluateExpr(1,&res1,xyValue);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res1,1e-13);
+  xyValue[0]=-2.;
+  CPPUNIT_ASSERT_THROW(expr1.evaluateExpr(1,&res1,xyValue),INTERP_KERNEL::Exception);
+  double res2[2];
+  xyValue[0]=1.;
+  expr1.evaluateExpr(2,res2,xyValue);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res2[0],1e-13);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res2[1],1e-13);
+  INTERP_KERNEL::ExprParser expr2("3.5*tan(2.3*x)*IVec+(cos(1.2+y/x)*JVec)");
+  expr2.parse();
+  res.clear(); expected.clear();
+  expr2.getSetOfVars(res);
+  CPPUNIT_ASSERT_EQUAL(4,(int)res.size());
+  expected.insert("x"); expected.insert("y"); expected.insert("IVec"); expected.insert("JVec");
+  CPPUNIT_ASSERT(std::equal(res.begin(),res.end(),expected.begin()));
+  expr2.prepareExprEvaluation(vars);
+  expr2.evaluateExpr(2,res2,xyValue);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.9172477460694637,res2[0],1e-14);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.49026082134069943,res2[1],1e-14);
+  INTERP_KERNEL::ExprParser expr3("3.5*u+u^2.4+2.");
+  expr3.parse();
+  expr3.prepareExprEvaluationVec();
+  expr3.evaluateExpr(2,res2,xyValue);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(6.5,res2[0],1e-14);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(26.466610165238237,res2[1],1e-14);
+  INTERP_KERNEL::ExprParser expr4("3.5*v+u^2.4+2.");
+  expr4.parse();
+  CPPUNIT_ASSERT_THROW(expr4.prepareExprEvaluationVec(),INTERP_KERNEL::Exception);
+}
+
+void ExprEvalInterpTest::testInterpreterUnit0()
+{
+  INTERP_KERNEL::ExprParser expr1("kg");
+  expr1.parse();
+  INTERP_KERNEL::DecompositionInUnitBase unit=expr1.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(1,0,0,0,0,0.,1000.));
+  INTERP_KERNEL::ExprParser expr2("kgT");
+  expr2.parse();
+  CPPUNIT_ASSERT_THROW(expr2.evaluateUnit(),INTERP_KERNEL::Exception);
+  INTERP_KERNEL::ExprParser expr3("g");
+  expr3.parse();
+  unit=expr3.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(1,0,0,0,0,0.,1.));
+  INTERP_KERNEL::ExprParser expr4("g*m");
+  expr4.parse();
+  unit=expr4.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,0,0.,1.));
+  INTERP_KERNEL::ExprParser expr5("g*m/K");
+  expr5.parse();
+  unit=expr5.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,-1,0.,1.));
+  INTERP_KERNEL::ExprParser expr6("g*m/K^2");
+  expr6.parse();
+  unit=expr6.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,-2,0.,1.));
+  INTERP_KERNEL::ExprParser expr7("g/K^2*m");
+  expr7.parse();
+  unit=expr7.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,-2,0.,1.));
+  INTERP_KERNEL::ExprParser expr8("g/(K^2*m)");
+  expr8.parse();
+  unit=expr8.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(1,-1,0,0,-2,0.,1.));
+  INTERP_KERNEL::ExprParser expr9("km/h");
+  expr9.parse();
+  unit=expr9.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(0,1,-1,0,0,0.,0.27777777777777779));
+  INTERP_KERNEL::ExprParser expr10("m/s");
+  expr10.parse();
+  unit=expr10.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(0,1,-1,0,0,0.,1.));
+  INTERP_KERNEL::ExprParser expr11("m+s");
+  expr11.parse();
+  CPPUNIT_ASSERT_THROW(expr11.evaluateUnit(),INTERP_KERNEL::Exception);
+  INTERP_KERNEL::ExprParser expr12("m-m");
+  expr12.parse();
+  CPPUNIT_ASSERT_THROW(expr12.evaluateUnit(),INTERP_KERNEL::Exception);
+  const char expr13C[3]={-0x50,0x43,0x0};
+  INTERP_KERNEL::ExprParser expr13(expr13C);
+  expr13.parse();
+  unit=expr13.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,273.15,1.));
+  const char expr14C[4]={-0x3E,-0x50,0x43,0x0};
+  INTERP_KERNEL::ExprParser expr14(expr14C);
+  expr14.parse();
+  unit=expr14.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,273.15,1.));
+  INTERP_KERNEL::ExprParser expr15("kN/kg");
+  expr15.parse();
+  unit=expr15.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(0,1,-2,0,0,0.,1000.));
+  INTERP_KERNEL::ExprParser expr16("cm");
+  expr16.parse();
+  unit=expr16.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(0,1,0,0,0,0.,0.01));
+  INTERP_KERNEL::ExprParser expr17("m");
+  expr17.parse();
+  unit=expr17.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(0,1,0,0,0,0.,1));
+  const char expr18C[3]={-0x08,0x43,0x0};
+  INTERP_KERNEL::ExprParser expr18(expr18C);
+  expr18.parse();
+  unit=expr18.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,273.15,1.));
+  const char expr19C[6]={-0x50,0x43,0x2F,-0x50,0x43,0x0};
+  INTERP_KERNEL::ExprParser expr19(expr19C);
+  expr19.parse();
+  unit=expr19.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,0,0.,1.));
+  const char expr20C[9]={-0x50,0x43,0x2A,-0x50,0x43,0x2F,-0x50,0x43,0x0};
+  INTERP_KERNEL::ExprParser expr20(expr20C);
+  expr20.parse();
+  unit=expr20.evaluateUnit();
+  CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,0.,1.));
+}
+
+void ExprEvalInterpTest::testInterpreterUnit1()
+{
+  INTERP_KERNEL::Unit unit1("m/s");
+  INTERP_KERNEL::Unit unit2("km/h");
+  CPPUNIT_ASSERT(unit1.isCompatibleWith(unit2) && unit2.isCompatibleWith(unit1));
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(360,unit1.convert(unit2,100.),1e-10);
+  INTERP_KERNEL::Unit unit3("J/s");
+  INTERP_KERNEL::Unit unit4("kW");
+  CPPUNIT_ASSERT(unit3.isCompatibleWith(unit4) && unit4.isCompatibleWith(unit3));
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,unit3.convert(unit4,1000.),1e-10);
+  CPPUNIT_ASSERT(unit4.getCoarseRepr()=="kW");
+  INTERP_KERNEL::Unit unit5("kpT");
+  CPPUNIT_ASSERT(!unit5.isInterpretationOK());
+  CPPUNIT_ASSERT(unit5.getCoarseRepr()=="kpT");
+  INTERP_KERNEL::Unit unit6("m*kpT");
+  CPPUNIT_ASSERT(!unit6.isInterpretationOK());
+  INTERP_KERNEL::Unit unit7("m*s^-1");
+  CPPUNIT_ASSERT(unit7.isCompatibleWith(unit2) && unit2.isCompatibleWith(unit7));
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(360,unit7.convert(unit2,100.),1e-10);
+  const char unit8C[3]={-0x50,0x43,0x0};
+  INTERP_KERNEL::Unit unit8(unit8C);
+  INTERP_KERNEL::Unit unit9("K");
+  CPPUNIT_ASSERT(unit9.isCompatibleWith(unit8) && unit8.isCompatibleWith(unit9));
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(335.15,unit8.convert(unit9,62.),1e-10);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(-16.37,unit9.convert(unit8,256.78),1e-10);
+  INTERP_KERNEL::Unit unit10("m");
+  INTERP_KERNEL::Unit unit11("cm");
+  CPPUNIT_ASSERT(unit10.isCompatibleWith(unit11) && unit11.isCompatibleWith(unit10));
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(6200.,unit10.convert(unit11,62.),1e-8);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL(0.62,unit11.convert(unit10,62.),1e-15);
+  INTERP_KERNEL::Unit unit12("m-m");
+  CPPUNIT_ASSERT(!unit12.isInterpretationOK());
+}
diff --git a/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx b/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx
new file mode 100644 (file)
index 0000000..0a38512
--- /dev/null
@@ -0,0 +1,53 @@
+//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef _EXPREVALINTERPTEST_HXX_
+#define _EXPREVALINTERPTEST_HXX_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "InterpKernelTestExport.hxx"
+
+namespace INTERP_TEST
+{
+  class INTERPKERNELTEST_EXPORT ExprEvalInterpTest : public CppUnit::TestFixture
+  {
+    CPPUNIT_TEST_SUITE( ExprEvalInterpTest );
+    CPPUNIT_TEST( testBuildStringFromFortran );
+    CPPUNIT_TEST( testDeleteWhiteSpaces );
+    CPPUNIT_TEST( testInterpreter0 );
+    CPPUNIT_TEST( testInterpreter1 );
+    CPPUNIT_TEST( testInterpreter2 );
+    CPPUNIT_TEST( testInterpreterUnit0 );
+    CPPUNIT_TEST( testInterpreterUnit1 );
+    CPPUNIT_TEST_SUITE_END();
+  public:
+    void setUp() { }
+    void tearDown() { }
+    void cleanUp() { }
+    void testBuildStringFromFortran();
+    void testDeleteWhiteSpaces();
+    void testInterpreter0();
+    void testInterpreter1();
+    void testInterpreter2();
+    void testInterpreterUnit0();
+    void testInterpreterUnit1();
+  };
+}
+
+#endif
index 7651c053388192765600e6256daa83227f634138..a7c0b6e3190bc41284030bc0bcf8e8b46d69ff51 100644 (file)
@@ -42,6 +42,8 @@ libInterpKernelTest_la_SOURCES=              \
        CppUnitTest.hxx                      \
        CppUnitTest.cxx                      \
        InterpolationPlanarTestSuite.hxx     \
+       ExprEvalInterpTest.hxx               \
+       ExprEvalInterpTest.cxx               \
        QuadraticPlanarInterpTest.hxx        \
        QuadraticPlanarInterpTest.cxx        \
        QuadraticPlanarInterpTest2.cxx       \
@@ -64,6 +66,7 @@ libInterpKernelTest_la_CPPFLAGS =                \
        -I$(srcdir)/../INTERP_KERNEL             \
        -I$(srcdir)/../INTERP_KERNEL/Geometric2D \
        -I$(srcdir)/../INTERP_KERNEL/Bases       \
+       -I$(srcdir)/../INTERP_KERNEL/ExprEval    \
        -DOPTIMIZE -DLOG_LEVEL=0
 
 libInterpKernelTest_la_LDFLAGS  =                \
index c8f8ea0737f1390b15bd094278b3359ab7e90f7e..05611fbe6fe30bae66e9978dceafaa0381a427f5 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "CppUnitTest.hxx"
 #include "BBTreeTest.hxx"
+#include "ExprEvalInterpTest.hxx"
 #include "QuadraticPlanarInterpTest.hxx"
 #include "SingleElementPlanarTests.hxx"
 #include "TransformedTriangleIntersectTest.hxx"
@@ -39,6 +40,7 @@ using namespace INTERP_TEST;
 //--- Registers the fixture into the 'registry'
 
 CPPUNIT_TEST_SUITE_REGISTRATION( BBTreeTest);
+CPPUNIT_TEST_SUITE_REGISTRATION( ExprEvalInterpTest );
 CPPUNIT_TEST_SUITE_REGISTRATION( QuadraticPlanarInterpTest );
 CPPUNIT_TEST_SUITE_REGISTRATION( SingleElementPlanarTests );
 CPPUNIT_TEST_SUITE_REGISTRATION( TransformedTriangleIntersectTest );