Salome HOME
Boost of expression evaluator DataArrayDouble::applyFunc* + DataArrayDouble::applyFun...
[modules/med.git] / src / INTERP_KERNEL / ExprEval / InterpKernelExprParser.cxx
index 69dabca7a6b747c4409751f5b1571303feb84358..c82cdfe3f40e859a5114f876e796ecf4b8d2c14b 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2014  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.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+// Author : Anthony Geay (CEA/DEN)
 
 #include "InterpKernelExprParser.hxx"
 #include "InterpKernelValue.hxx"
 #include "InterpKernelAsmX86.hxx"
+#include "InterpKernelAutoPtr.hxx"
 
 #include <cctype>
 #include <sstream>
@@ -37,7 +39,7 @@ 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)
+LeafExpr *LeafExpr::buildInstanceFrom(const std::string& expr)
 {
   std::istringstream stream;
   stream.str(expr);
@@ -69,12 +71,12 @@ LeafExprVal::~LeafExprVal()
 {
 }
 
-void LeafExprVal::fillValue(Value *val) const throw(INTERP_KERNEL::Exception)
+void LeafExprVal::fillValue(Value *val) const
 {
   val->setDouble(_value);
 }
 
-void LeafExprVal::replaceValues(const std::vector<double>& valuesInExpr) throw(INTERP_KERNEL::Exception)
+void LeafExprVal::replaceValues(const std::vector<double>& valuesInExpr)
 {
   int pos=(int)_value;
   int lgth=(int)valuesInExpr.size();
@@ -83,16 +85,25 @@ void LeafExprVal::replaceValues(const std::vector<double>& valuesInExpr) throw(I
   _value=valuesInExpr[pos];
 }
 
-LeafExprVar::LeafExprVar(const std::string& var):_fast_pos(-1),_var_name(var)
+LeafExprVal *LeafExprVal::deepCpy() const
 {
+  return new LeafExprVal(*this);
 }
 
-void LeafExprVar::fillValue(Value *val) const throw(INTERP_KERNEL::Exception)
+LeafExprVar::LeafExprVar(const std::string& var):_fast_pos(-1),_var_name(var),_val(0)
 {
-  val->setVarname(_fast_pos,_var_name);
 }
 
-void LeafExprVar::prepareExprEvaluation(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo) const throw(INTERP_KERNEL::Exception)
+void LeafExprVar::fillValue(Value *val) const
+{
+  if(_val)
+    val->setDouble(_val[_fast_pos]);
+  else
+    val->setVarname(_fast_pos,_var_name);
+
+}
+
+void LeafExprVar::prepareExprEvaluation(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo) const
 {
   std::vector<std::string>::const_iterator iter=std::find(vars.begin(),vars.end(),_var_name);
   if(iter==vars.end())
@@ -124,7 +135,23 @@ void LeafExprVar::prepareExprEvaluation(const std::vector<std::string>& vars, in
     }
 }
 
-void LeafExprVar::prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception)
+/*!
+ * \param [in] vars - the sorted list of vars
+ * \param [in] nbOfCompo - the size of the input tuples (it is used to scan if no problem occurs)
+ * \param [in] targetNbOfCompo - the size of the output tuple (it is used to check that no problem occurs)
+ * \param [in] refPos - is an integer in [0,targetNbOfCompo), that tell the id of \a this. It is for multi interpreters.
+ * \sa evaluateDouble
+ */
+void LeafExprVar::prepareExprEvaluationDouble(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo, int refPos, const double *ptOfInputStart, const double *ptOfInputEnd) const
+{
+  if((int)vars.size()!=std::distance(ptOfInputStart,ptOfInputEnd))
+    throw INTERP_KERNEL::Exception("LeafExprVar::prepareExprEvaluationDouble : size of input vector must be equal to the input vector !");
+  prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo);
+  _ref_pos=refPos;
+  _val=ptOfInputStart;
+}
+
+void LeafExprVar::prepareExprEvaluationVec() const
 {
   if(!isRecognizedKeyVar(_var_name,_fast_pos))
     _fast_pos=-2;
@@ -144,10 +171,15 @@ bool LeafExprVar::isRecognizedKeyVar(const std::string& var, int& pos)
   return true;
 }
 
+LeafExprVar *LeafExprVar::deepCpy() const
+{
+  return new LeafExprVar(*this);
+}
+
 /*!
  * Nothing to do it is not a bug.
  */
-void LeafExprVar::replaceValues(const std::vector<double>& valuesInExpr) throw(INTERP_KERNEL::Exception)
+void LeafExprVar::replaceValues(const std::vector<double>& valuesInExpr)
 {
 }
 
@@ -155,7 +187,27 @@ LeafExprVar::~LeafExprVar()
 {
 }
 
-ExprParser::ExprParser(const char *expr, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr)
+void ExprParserOfEval::clearSortedMemory()
+{
+  delete _leaf;
+  for(std::vector<ExprParserOfEval>::iterator it=_sub_parts.begin();it!=_sub_parts.end();it++)
+    (*it).clearSortedMemory();
+  for(std::vector<Function *>::iterator it=_funcs.begin();it!=_funcs.end();it++)
+    delete *it;
+}
+
+void ExprParserOfEval::sortMemory()
+{
+  for(std::vector<ExprParserOfEval>::iterator it=_sub_parts.begin();it!=_sub_parts.end();it++)
+    (*it).sortMemory();
+  if(_leaf)
+    _leaf=_leaf->deepCpy();
+  for(std::vector<Function *>::iterator it=_funcs.begin();it!=_funcs.end();it++)
+    if(*it)
+      *it=(*it)->deepCpy();
+}
+
+ExprParser::ExprParser(const std::string& expr, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr)
 {
   _expr=deleteWhiteSpaces(_expr);
 }
@@ -170,6 +222,7 @@ ExprParser::ExprParser(const char *expr, int lgth, ExprParser *father):_father(f
 ExprParser::~ExprParser()
 {
   delete _leaf;
+  _for_eval.clearSortedMemory();
   releaseFunctions();
 }
 
@@ -224,7 +277,7 @@ std::string ExprParser::deleteWhiteSpaces(const std::string& expr)
   return ret;
 }
 
-void ExprParser::parse() throw(INTERP_KERNEL::Exception)
+void ExprParser::parse()
 {
   _is_parsed=true;
   _is_parsing_ok=false;
@@ -241,20 +294,18 @@ void ExprParser::parse() throw(INTERP_KERNEL::Exception)
       replaceValues(valuesInExpr);
       _expr=tmp;
     }
+  reverseThis();
   _is_parsing_ok=true;
 }
 
-double ExprParser::evaluate() const throw(INTERP_KERNEL::Exception)
+double ExprParser::evaluate() const
 {
-  Value *gen=new ValueDouble;
-  ValueDouble *res=(ValueDouble *)evaluateLowLev(gen);
-  delete gen;
-  double ret=res->getData();
-  delete res;
-  return ret;
+  AutoCppPtr<Value> gen(new ValueDouble);
+  AutoCppPtr<ValueDouble> res(static_cast<ValueDouble *>(evaluateLowLev(gen)));
+  return res->getData();
 }
 
-DecompositionInUnitBase ExprParser::evaluateUnit() const throw(INTERP_KERNEL::Exception)
+DecompositionInUnitBase ExprParser::evaluateUnit() const
 {
   Value *gen=new ValueUnit;
   ValueUnit *res=0;
@@ -273,25 +324,14 @@ DecompositionInUnitBase ExprParser::evaluateUnit() const throw(INTERP_KERNEL::Ex
   return ret;
 }
 
-void ExprParser::evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const throw(INTERP_KERNEL::Exception)
+void ExprParser::evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const
 {
-  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;
+  AutoCppPtr<Value> gen(new ValueDoubleExpr(szOfOutParam,inParam));
+  AutoCppPtr<ValueDoubleExpr> res(static_cast<ValueDoubleExpr *>(evaluateLowLev(gen)));
   std::copy(res->getData(),res->getData()+szOfOutParam,outParam);
-  delete res;
 }
 
-void ExprParser::prepareExprEvaluation(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo) const throw(INTERP_KERNEL::Exception)
+void ExprParser::prepareExprEvaluation(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo) const
 {
   if(_leaf)
     {
@@ -300,11 +340,59 @@ void ExprParser::prepareExprEvaluation(const std::vector<std::string>& vars, int
         leafC->prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo);
     }
   else
-    for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+    for(std::vector<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
       (*iter).prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo);
 }
 
-void ExprParser::prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception)
+/*!
+ * \param [in] vars - the sorted list of vars
+ * \param [in] nbOfCompo - the size of the input tuples (it is used to scan if no problem occurs)
+ * \param [in] targetNbOfCompo - the size of the output tuple (it is used to check that no problem occurs)
+ * \param [in] refPos - is an integer in [0,targetNbOfCompo), that tell the id of \a this. It is for multi interpreters.
+ * \sa evaluateDouble
+ */
+void ExprParser::prepareExprEvaluationDouble(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo, int refPos, const double *ptOfInputStart, const double *ptOfInputEnd) const
+{
+  if((int)vars.size()!=std::distance(ptOfInputStart,ptOfInputEnd))
+    throw INTERP_KERNEL::Exception("ExprParser::prepareExprEvaluationDouble : size of input vector must be equal to the input vector !");
+  if(_leaf)
+    {
+      LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
+      if(leafC)
+        leafC->prepareExprEvaluationDouble(vars,nbOfCompo,targetNbOfCompo,refPos,ptOfInputStart,ptOfInputEnd);
+    }
+  else
+    for(std::vector<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+      (*iter).prepareExprEvaluationDouble(vars,nbOfCompo,targetNbOfCompo,refPos,ptOfInputStart,ptOfInputEnd);
+}
+
+void ExprParser::prepareFastEvaluator() const
+{
+  _for_eval.clearSortedMemory();
+  _for_eval=convertMeTo();
+  _for_eval.sortMemory();
+}
+
+/*!
+ * \sa prepareExprEvaluationDouble
+ */
+double ExprParser::evaluateDouble() const
+{
+  checkForEvaluation();
+  std::vector<double> stackOfVal;
+  evaluateDoubleInternal(stackOfVal);
+  return stackOfVal.back();
+}
+
+void ExprParser::checkForEvaluation() const
+{
+  if(!_is_parsing_ok)
+    throw INTERP_KERNEL::Exception("checkForEvaluation : Parsing fails ! Invalid expression !");
+  if(_sub_expr.empty() && !_leaf)
+    throw INTERP_KERNEL::Exception("checkForEvaluation : Empty expression !");
+}
+
+void ExprParser::prepareExprEvaluationVec() const
 {
   std::set<std::string> trueVars;
   getTrueSetOfVars(trueVars);
@@ -318,7 +406,7 @@ void ExprParser::prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception
   prepareExprEvaluationVecLowLev();
 }
 
-void ExprParser::prepareExprEvaluationVecLowLev() const throw(INTERP_KERNEL::Exception)
+void ExprParser::prepareExprEvaluationVecLowLev() const
 {
   if(_leaf)
     {
@@ -327,16 +415,13 @@ void ExprParser::prepareExprEvaluationVecLowLev() const throw(INTERP_KERNEL::Exc
         leafC->prepareExprEvaluationVec();
     }
   else
-    for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+    for(std::vector<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
       (*iter).prepareExprEvaluationVecLowLev();
 }
 
-Value *ExprParser::evaluateLowLev(Value *valGen) const throw(INTERP_KERNEL::Exception)
+Value *ExprParser::evaluateLowLev(Value *valGen) const
 {
-  if(!_is_parsing_ok)
-    throw INTERP_KERNEL::Exception("Parsing fails ! Invalid expression !");
-  if(_sub_expr.empty() && !_leaf)
-    throw INTERP_KERNEL::Exception("Empty expression !");
+  checkForEvaluation();
   std::vector<Value *> stackOfVal;
   try
     {
@@ -358,12 +443,11 @@ Value *ExprParser::evaluateLowLev(Value *valGen) const throw(INTERP_KERNEL::Exce
       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++)
+          std::vector<Value *>::iterator iter2=stackOfVal.begin();
+          for(std::vector<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++)
+      for(std::vector<Function *>::const_iterator iter3=_func_btw_sub_expr.begin();iter3!=_func_btw_sub_expr.end();iter3++)
         (*iter3)->operate(stackOfVal);
     }
   catch(INTERP_KERNEL::Exception& e)
@@ -375,6 +459,33 @@ Value *ExprParser::evaluateLowLev(Value *valGen) const throw(INTERP_KERNEL::Exce
   return stackOfVal.back();
 }
 
+void ExprParser::reverseThis()
+{
+  if(_leaf)
+    return ;
+  for(std::vector<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+    (*iter).reverseThis();
+  AutoPtr<char> buf(new char[sizeof(ExprParser)]);
+  char *loc(reinterpret_cast<char *>(&_sub_expr[0])),*bufPtr(buf);
+  std::size_t sz(_sub_expr.size());
+  std::size_t nbOfTurn(sz/2);
+  for(std::size_t i=0;i<nbOfTurn;i++)
+    {
+      std::copy(loc+i*sizeof(ExprParser),loc+(i+1)*sizeof(ExprParser),bufPtr);
+      std::copy(loc+(sz-i-1)*sizeof(ExprParser),loc+(sz-i)*sizeof(ExprParser),loc+i*sizeof(ExprParser));
+      std::copy(bufPtr,bufPtr+sizeof(ExprParser),loc+(sz-i-1)*sizeof(ExprParser));
+    }
+}
+
+ExprParserOfEval ExprParser::convertMeTo() const
+{
+  std::size_t sz(_sub_expr.size());
+  std::vector<ExprParserOfEval> subExpr(sz);
+  for(std::size_t i=0;i<sz;i++)
+    subExpr[i]=_sub_expr[i].convertMeTo();
+  return ExprParserOfEval(_leaf,subExpr,_func_btw_sub_expr);
+}
+
 void ExprParser::getSetOfVars(std::set<std::string>& vars) const
 {
   if(_leaf)
@@ -384,7 +495,7 @@ void ExprParser::getSetOfVars(std::set<std::string>& vars) const
         vars.insert(leafC->getVar());
     }
   else
-    for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+    for(std::vector<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
       (*iter).getSetOfVars(vars);
 }
 
@@ -401,9 +512,9 @@ void ExprParser::getTrueSetOfVars(std::set<std::string>& trueVars) const
     }
 }
 
-void ExprParser::parseDeeper() throw(INTERP_KERNEL::Exception)
+void ExprParser::parseDeeper()
 {
-  for(std::list<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+  for(std::vector<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
     if(!(*iter).simplify())
       (*iter).parseDeeper();
 }
@@ -413,7 +524,7 @@ void ExprParser::parseDeeper() throw(INTERP_KERNEL::Exception)
  * 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)
+void ExprParser::parseUnaryFunc()
 {
   if(_expr[_expr.length()-1]!=')')
     return ;
@@ -460,7 +571,7 @@ void ExprParser::parseUnaryFunc() throw(INTERP_KERNEL::Exception)
  * \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)
+bool ExprParser::tryToInterpALeaf()
 {
   std::size_t pos=_expr.find_first_not_of("+-",0,2);
   std::string minimizedExpr=_expr.substr(pos);
@@ -479,7 +590,7 @@ bool ExprParser::tryToInterpALeaf() throw(INTERP_KERNEL::Exception)
   return true;
 }
 
-void ExprParser::parseForCmp() throw(INTERP_KERNEL::Exception)
+void ExprParser::parseForCmp()
 {
   std::string::const_iterator iter;
   int curLevel=0;
@@ -539,7 +650,7 @@ void ExprParser::parseForCmp() throw(INTERP_KERNEL::Exception)
     }
 }
 
-void ExprParser::parseForAddMin() throw(INTERP_KERNEL::Exception)
+void ExprParser::parseForAddMin()
 {
   std::string::const_iterator iter;
   int curLevel=0;
@@ -601,7 +712,7 @@ void ExprParser::parseForAddMin() throw(INTERP_KERNEL::Exception)
     }
 }
 
-void ExprParser::parseForMulDiv() throw(INTERP_KERNEL::Exception)
+void ExprParser::parseForMulDiv()
 {
   std::string::const_iterator iter;
   int curLevel=0;
@@ -664,7 +775,7 @@ void ExprParser::parseForMulDiv() throw(INTERP_KERNEL::Exception)
     }
 }
 
-void ExprParser::parseForPow() throw(INTERP_KERNEL::Exception)
+void ExprParser::parseForPow()
 {
   std::string::const_iterator iter;
   int curLevel=0;
@@ -726,7 +837,7 @@ void ExprParser::parseForPow() throw(INTERP_KERNEL::Exception)
 
 void ExprParser::releaseFunctions()
 {
-  for(std::list<Function *>::iterator iter=_func_btw_sub_expr.begin();iter!=_func_btw_sub_expr.end();iter++)
+  for(std::vector<Function *>::iterator iter=_func_btw_sub_expr.begin();iter!=_func_btw_sub_expr.end();iter++)
     delete *iter;
   _func_btw_sub_expr.clear();
 }
@@ -736,7 +847,7 @@ void ExprParser::releaseFunctions()
  * 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)
+bool ExprParser::simplify()
 {
   if(tryToInterpALeaf())
     return true;
@@ -766,7 +877,7 @@ bool ExprParser::simplify() throw(INTERP_KERNEL::Exception)
   return false;
 }
 
-void ExprParser::checkBracketsParity() const throw(INTERP_KERNEL::Exception)
+void ExprParser::checkBracketsParity() const
 {
   std::string::const_iterator iter;
   int curLevel=0;
@@ -801,7 +912,7 @@ void ExprParser::checkBracketsParity() const throw(INTERP_KERNEL::Exception)
  * If double representation is invalid an exception is thrown.
  * This method returns a delta that is the delta to operate to pos in expr after substitution.
  */
-double ExprParser::ReplaceAndTraduce(std::string& expr, int id, std::size_t bg, std::size_t end, int& delta) throw(INTERP_KERNEL::Exception)
+double ExprParser::ReplaceAndTraduce(std::string& expr, int id, std::size_t bg, std::size_t end, int& delta)
 {
   static const char MSG[]="Interal error : A string expected to be a float is not one ! Bug to signal !";
   std::istringstream stream;
@@ -828,7 +939,7 @@ double ExprParser::ReplaceAndTraduce(std::string& expr, int id, std::size_t bg,
  * This method scans _expr finding in greedy mode the following pattern :
  * {0..9}+{.}?{0..9}*{{eE}{-}?{0..9}+}?
  */
-void ExprParser::fillValuesInExpr(std::vector<double>& valuesInExpr) throw(INTERP_KERNEL::Exception)
+void ExprParser::fillValuesInExpr(std::vector<double>& valuesInExpr)
 {
   const char FIGURES[]="0123456789";
   const std::string other("+-*^/(<>,");
@@ -917,13 +1028,13 @@ void ExprParser::fillValuesInExpr(std::vector<double>& valuesInExpr) throw(INTER
     }
 }
 
-void ExprParser::replaceValues(const std::vector<double>& valuesInExpr) throw(INTERP_KERNEL::Exception)
+void ExprParser::replaceValues(const std::vector<double>& valuesInExpr)
 {
   if(_leaf)
     _leaf->replaceValues(valuesInExpr);
   else
     {
-      for(std::list<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+      for(std::vector<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
         (*iter).replaceValues(valuesInExpr);
     }
 }
@@ -985,10 +1096,10 @@ void ExprParser::compileX86LowLev(std::vector<std::string>& ass) const
     _leaf->compileX86(ass);
   else
     {
-      for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+      for(std::vector<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
         (*iter).compileX86LowLev(ass);
     }
-  for(std::list<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++)
+  for(std::vector<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++)
     (*iter2)->operateX86(ass);
 }
 
@@ -998,17 +1109,22 @@ void ExprParser::compileX86_64LowLev(std::vector<std::string>& ass) const
     _leaf->compileX86_64(ass);
   else
     {
-      for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
+      for(std::vector<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
         (*iter).compileX86_64LowLev(ass);
     }
-  for(std::list<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++)
+  for(std::vector<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++)
     (*iter2)->operateX86(ass);
 }
 
+double LeafExprVal::getDoubleValue() const
+{
+  return _value;
+}
+
 void LeafExprVal::compileX86(std::vector<std::string>& ass) const
 {
   ass.push_back("sub esp,8");
-  int *b=(int *)&_value,*c=(int *)&_value;
+  const int *b=reinterpret_cast<const int *>(&_value),*c=reinterpret_cast<const int *>(&_value);
   c++;
   std::ostringstream oss;
   oss << std::hex;
@@ -1024,7 +1140,7 @@ void LeafExprVal::compileX86(std::vector<std::string>& ass) const
 void LeafExprVal::compileX86_64(std::vector<std::string>& ass) const
 {
   ass.push_back("sub rsp,8");
-  int *b=(int *)&_value,*c=(int *)&_value;
+  const int *b=reinterpret_cast<const int *>(&_value),*c=reinterpret_cast<const int *>(&_value);
   c++;
   std::ostringstream oss;
   oss << std::hex;
@@ -1037,6 +1153,17 @@ void LeafExprVal::compileX86_64(std::vector<std::string>& ass) const
   ass.push_back("add rsp,8");
 }
 
+double LeafExprVar::getDoubleValue() const
+{
+  if(_fast_pos>=0)
+    return _val[_fast_pos];
+  else
+    {
+      int pos(-7-_fast_pos);
+      return pos==_ref_pos?1.:0.;
+    }
+}
+
 void LeafExprVar::compileX86(std::vector<std::string>& ass) const
 {
   ass.push_back("fld qword [ebp+8]");
@@ -1056,7 +1183,7 @@ int ExprParser::getStackSizeToPlayX86(const ExprParser *asker) const
     {
       int sz=_father->getStackSizeToPlayX86(this);
       int i=0;
-      for(std::list<ExprParser>::const_reverse_iterator iter=_sub_expr.rbegin();iter!=_sub_expr.rend();iter++,i++)
+      for(std::vector<ExprParser>::const_reverse_iterator iter=_sub_expr.rbegin();iter!=_sub_expr.rend();iter++,i++)
         {
           const ExprParser& obj=(*iter);
           const ExprParser *pt=&obj;