Salome HOME
Update copyrights 2014.
[modules/med.git] / src / INTERP_KERNEL / ExprEval / InterpKernelExprParser.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "InterpKernelExprParser.hxx"
22 #include "InterpKernelValue.hxx"
23 #include "InterpKernelAsmX86.hxx"
24
25 #include <cctype>
26 #include <sstream>
27 #include <limits>
28 #include <vector>
29 #include <iterator>
30 #include <iostream>
31 #include <algorithm>
32
33 using namespace INTERP_KERNEL;
34
35 const char LeafExprVar::END_OF_RECOGNIZED_VAR[]="Vec";
36
37 const char ExprParser::WHITE_SPACES[]=" \n";
38
39 const char ExprParser::EXPR_PARSE_ERR_MSG[]="Invalid expression detected : ";
40
41 LeafExpr *LeafExpr::buildInstanceFrom(const std::string& expr)
42 {
43   std::istringstream stream;
44   stream.str(expr);
45   double val;
46   stream >> val;
47   if(!stream.fail())
48     if(stream.eof())
49       return new LeafExprVal(val);
50     else
51       {
52         std::ostringstream errMsg;
53         char MSGTYP6[]="Error following expression is not consedered as a double value : ";
54         errMsg << MSGTYP6 << expr;
55         throw INTERP_KERNEL::Exception(errMsg.str().c_str());
56       }
57   else
58     return new LeafExprVar(expr);
59 }
60
61 LeafExpr::~LeafExpr()
62 {
63 }
64
65 LeafExprVal::LeafExprVal(double value):_value(value)
66 {
67 }
68
69 LeafExprVal::~LeafExprVal()
70 {
71 }
72
73 void LeafExprVal::fillValue(Value *val) const
74 {
75   val->setDouble(_value);
76 }
77
78 void LeafExprVal::replaceValues(const std::vector<double>& valuesInExpr)
79 {
80   int pos=(int)_value;
81   int lgth=(int)valuesInExpr.size();
82   if(pos>=lgth || pos<0)
83     throw INTERP_KERNEL::Exception("LeafExprVal::replaceValues : Big Problem detected ! Send expression to Salome support with expression !");
84   _value=valuesInExpr[pos];
85 }
86
87 LeafExprVar::LeafExprVar(const std::string& var):_fast_pos(-1),_var_name(var)
88 {
89 }
90
91 void LeafExprVar::fillValue(Value *val) const
92 {
93   val->setVarname(_fast_pos,_var_name);
94 }
95
96 void LeafExprVar::prepareExprEvaluation(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo) const
97 {
98   std::vector<std::string>::const_iterator iter=std::find(vars.begin(),vars.end(),_var_name);
99   if(iter==vars.end())
100     {
101       if(!isRecognizedKeyVar(_var_name,_fast_pos))
102         {
103           std::ostringstream oss; oss << "Var : " << _var_name << " not in : ";
104           std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss,", "));
105           throw INTERP_KERNEL::Exception(oss.str().c_str());
106         }
107       else
108         {
109           int relPos=-7-_fast_pos;
110           if(relPos>=targetNbOfCompo)
111             {
112               std::ostringstream oss; oss << "LeafExprVar::prepareExprEvaluation : Found recognized unitary vector \"" << _var_name << "\" which implies that component #" << relPos;
113               oss << " exists, but it is not the case component id should be in [0," << targetNbOfCompo << ") !";
114               throw INTERP_KERNEL::Exception(oss.str().c_str());
115             }
116           else
117             return;
118         }
119     }
120   _fast_pos=(int)std::distance(vars.begin(),iter);
121   if(_fast_pos>=nbOfCompo)
122     {
123       std::ostringstream oss; oss << "LeafExprVar::prepareExprEvaluation : Found var \"" << _var_name << "\" on place " << _fast_pos << " whereas only must be in [0," << nbOfCompo << ") !";
124       throw INTERP_KERNEL::Exception(oss.str().c_str());
125     }
126 }
127
128 void LeafExprVar::prepareExprEvaluationVec() const
129 {
130   if(!isRecognizedKeyVar(_var_name,_fast_pos))
131     _fast_pos=-2;
132 }
133
134 bool LeafExprVar::isRecognizedKeyVar(const std::string& var, int& pos)
135 {
136   if(var.length()!=sizeof(END_OF_RECOGNIZED_VAR))
137     return false;
138   std::string end=var.substr(1);
139   if(end!=END_OF_RECOGNIZED_VAR)
140     return false;
141   char first=var[0];
142   if(first<'I' || first>'Z')
143     return false;
144   pos=-7-(first-'I');
145   return true;
146 }
147
148 /*!
149  * Nothing to do it is not a bug.
150  */
151 void LeafExprVar::replaceValues(const std::vector<double>& valuesInExpr)
152 {
153 }
154
155 LeafExprVar::~LeafExprVar()
156 {
157 }
158
159 ExprParser::ExprParser(const std::string& expr, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr)
160 {
161   _expr=deleteWhiteSpaces(_expr);
162 }
163
164 //! For \b NOT null terminated strings coming from FORTRAN.
165 ExprParser::ExprParser(const char *expr, int lgth, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false)
166 {
167   _expr=buildStringFromFortran(expr,lgth);
168   _expr=deleteWhiteSpaces(_expr);
169 }
170
171 ExprParser::~ExprParser()
172 {
173   delete _leaf;
174   releaseFunctions();
175 }
176
177 std::size_t ExprParser::FindCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket)
178 {
179   int level=0;
180   for(std::size_t iter=0;iter<posOfCloseBracket;iter++)
181     {
182       std::size_t iter2=posOfCloseBracket-1-iter;
183       if(expr[iter2]==')')
184         level++;
185       else if(expr[iter2]=='(')
186         {
187           if(level==0)
188             return iter2;
189           else
190             level--;
191         }
192     }
193   return std::string::npos;
194 }
195
196 std::string ExprParser::buildStringFromFortran(const char *expr, int lgth)
197 {
198   std::string ret(expr,lgth);
199   std::string whiteSpaces(WHITE_SPACES);
200   std::size_t found=ret.find_last_not_of(whiteSpaces);
201   if (found!=std::string::npos)
202     ret.erase(found+1);
203   else
204     ret.clear();//ret is all whitespace
205   return ret;
206 }
207
208 std::string ExprParser::deleteWhiteSpaces(const std::string& expr)
209 {
210   std::string ret(expr);
211   std::string whiteSpaces(WHITE_SPACES);
212   std::size_t where1=0,where2=0;
213   while(where2!=std::string::npos && where1!=std::string::npos)
214     {
215       where1=ret.find_first_of(whiteSpaces.c_str(),where1,whiteSpaces.length());
216       if(where1!=std::string::npos)
217         {
218           where2=ret.find_first_not_of(whiteSpaces,where1);
219           if(where2!=std::string::npos)
220             ret.erase(ret.begin()+where1,ret.begin()+where2);
221           else
222             ret.erase(ret.begin()+where1,ret.end());
223         }
224     }
225   return ret;
226 }
227
228 void ExprParser::parse()
229 {
230   _is_parsed=true;
231   _is_parsing_ok=false;
232   _sub_expr.clear();
233   releaseFunctions();
234   if(!_expr.empty())
235     {
236       std::string tmp(_expr);
237       std::vector<double> valuesInExpr;
238       fillValuesInExpr(valuesInExpr);
239       checkBracketsParity();
240       if(!simplify())
241         parseDeeper();
242       replaceValues(valuesInExpr);
243       _expr=tmp;
244     }
245   _is_parsing_ok=true;
246 }
247
248 double ExprParser::evaluate() const
249 {
250   Value *gen=new ValueDouble;
251   ValueDouble *res=(ValueDouble *)evaluateLowLev(gen);
252   delete gen;
253   double ret=res->getData();
254   delete res;
255   return ret;
256 }
257
258 DecompositionInUnitBase ExprParser::evaluateUnit() const
259 {
260   Value *gen=new ValueUnit;
261   ValueUnit *res=0;
262   try
263     {
264       res=(ValueUnit *)evaluateLowLev(gen);
265     }
266   catch(INTERP_KERNEL::Exception& e)
267     {
268       delete gen;
269       throw e;
270     }
271   delete gen;
272   DecompositionInUnitBase ret=res->getData();
273   delete res;
274   return ret;
275 }
276
277 void ExprParser::evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const
278 {
279   Value *gen=new ValueDoubleExpr(szOfOutParam,inParam);
280   ValueDoubleExpr *res=0;
281   try
282     {
283       res=(ValueDoubleExpr *)evaluateLowLev(gen);
284     }
285   catch(INTERP_KERNEL::Exception& e)
286     {
287       delete gen;
288       throw e;
289     }
290   delete gen;
291   std::copy(res->getData(),res->getData()+szOfOutParam,outParam);
292   delete res;
293 }
294
295 void ExprParser::prepareExprEvaluation(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo) const
296 {
297   if(_leaf)
298     {
299       LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
300       if(leafC)
301         leafC->prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo);
302     }
303   else
304     for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
305       (*iter).prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo);
306 }
307
308 void ExprParser::prepareExprEvaluationVec() const
309 {
310   std::set<std::string> trueVars;
311   getTrueSetOfVars(trueVars);
312   if(trueVars.size()>1)
313     {
314       std::ostringstream oss; oss << "For this type of evaluation only one not keyword variable authorized : ";
315       oss << "having " << trueVars.size() << " : ";
316       std::copy(trueVars.begin(),trueVars.end(),std::ostream_iterator<std::string>(oss," ")); oss << " !";
317       throw INTERP_KERNEL::Exception(oss.str().c_str());
318     }
319   prepareExprEvaluationVecLowLev();
320 }
321
322 void ExprParser::prepareExprEvaluationVecLowLev() const
323 {
324   if(_leaf)
325     {
326       LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
327       if(leafC)
328         leafC->prepareExprEvaluationVec();
329     }
330   else
331     for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
332       (*iter).prepareExprEvaluationVecLowLev();
333 }
334
335 Value *ExprParser::evaluateLowLev(Value *valGen) const
336 {
337   if(!_is_parsing_ok)
338     throw INTERP_KERNEL::Exception("Parsing fails ! Invalid expression !");
339   if(_sub_expr.empty() && !_leaf)
340     throw INTERP_KERNEL::Exception("Empty expression !");
341   std::vector<Value *> stackOfVal;
342   try
343     {
344       if(_leaf)
345         {
346           Value *ret=valGen->newInstance();
347           try
348             {
349               _leaf->fillValue(ret);
350             }
351           catch(INTERP_KERNEL::Exception& e)
352             {
353               delete ret;
354               throw e;
355             }
356           stackOfVal.resize(1);
357           stackOfVal[0]=ret;
358         }
359       else
360         {
361           stackOfVal.resize(_sub_expr.size());
362           std::vector<Value *>::reverse_iterator iter2=stackOfVal.rbegin();
363           for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++,iter2++)
364             *iter2=(*iter).evaluateLowLev(valGen);
365         }
366       std::list<Function *>::const_iterator iter3;
367       for(iter3=_func_btw_sub_expr.begin();iter3!=_func_btw_sub_expr.end();iter3++)
368         (*iter3)->operate(stackOfVal);
369     }
370   catch(INTERP_KERNEL::Exception& e)
371     {
372       for(std::vector<Value *>::iterator iter4=stackOfVal.begin();iter4!=stackOfVal.end();iter4++)
373         delete *iter4;
374       throw e;
375     }
376   return stackOfVal.back();
377 }
378
379 void ExprParser::getSetOfVars(std::set<std::string>& vars) const
380 {
381   if(_leaf)
382     {
383       LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
384       if(leafC)
385         vars.insert(leafC->getVar());
386     }
387   else
388     for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
389       (*iter).getSetOfVars(vars);
390 }
391
392 void ExprParser::getTrueSetOfVars(std::set<std::string>& trueVars) const
393 {
394   std::set<std::string> vars;
395   getSetOfVars(vars);
396   trueVars.clear();
397   for(std::set<std::string>::const_iterator iter=vars.begin();iter!=vars.end();iter++)
398     {
399       int tmp;
400       if(!LeafExprVar::isRecognizedKeyVar(*iter,tmp))
401         trueVars.insert(*iter);
402     }
403 }
404
405 void ExprParser::parseDeeper()
406 {
407   for(std::list<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
408     if(!(*iter).simplify())
409       (*iter).parseDeeper();
410 }
411
412 /*!
413  * This method has the responsability to see if this->_expr can be seen as a unary function of something.
414  * Something defined as the contain of highest level barckets.
415  * Typically '(3*x+2)' and 'cos(4*l+p*n)' will be intercepted by this method whereas '3*x+2' not...etc..
416  */
417 void ExprParser::parseUnaryFunc()
418 {
419   if(_expr[_expr.length()-1]!=')')
420     return ;
421   //at this level of code _expr 
422   std::size_t pos1=_expr.find_first_of('(');
423   std::size_t pos4=FindCorrespondingOpenBracket(_expr,_expr.length()-1);
424   if(pos4!=pos1)
425     return ;
426   std::string funcName=_expr.substr(0,pos1);
427   std::size_t pos2=funcName.find_first_of("+-*/^><",0,7);
428   std::size_t pos3=funcName.find_first_not_of("+-*/^><",0,7);
429   if(pos2!=std::string::npos && pos3!=std::string::npos)
430     return ;//Bracket group is not alone, can't conclude not recursively.
431   std::string newExp2=_expr.substr(pos1+1,_expr.length()-pos1-2);
432   std::size_t nbOfParamsInFunc=std::count(newExp2.begin(),newExp2.end(),',')+1;
433   if(pos3!=std::string::npos)
434     _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(funcName.c_str(),(int)nbOfParamsInFunc));
435   else
436     {
437       std::size_t lgth=funcName.length();
438       char tmp[2]; tmp[1]='\0';
439       for(std::size_t i=0;i<lgth;i++)
440         {
441           tmp[0]=funcName[i];
442           _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(tmp,(int)nbOfParamsInFunc));
443         }
444     }
445   std::size_t pos6=0;
446   for(std::size_t i=0;i<nbOfParamsInFunc;i++)
447     {
448       std::size_t pos5=newExp2.find_first_of(',',pos6);
449       std::size_t len=std::string::npos;
450       if(pos5!=std::string::npos)
451         len=pos5-pos6;
452       std::string newExp3=newExp2.substr(pos6,len);
453       _sub_expr.push_back(ExprParser(newExp3.c_str(),this));
454       pos6=pos5+1;
455     }
456   _is_parsing_ok=true;
457 }
458
459 /*!
460  *  This method has the responsability to see if this->_expr is interpretable without any recursion.
461  * \return true if no recursion needed, false if this->_expr is too complex to be interpreted at this level.
462  * \throw exception if this->_expr is simple enough to try to interprate this and this expression contains an error.  
463  */
464 bool ExprParser::tryToInterpALeaf()
465 {
466   std::size_t pos=_expr.find_first_not_of("+-",0,2);
467   std::string minimizedExpr=_expr.substr(pos);
468   std::size_t pos2=minimizedExpr.find_first_of("+-*/^()<>",0,9);
469   if(pos2!=std::string::npos)
470     return false;
471   delete _leaf;
472   _leaf=LeafExpr::buildInstanceFrom(minimizedExpr);
473   int nbOfNegs=0;
474   for(std::size_t i=0;i<pos;i++)
475     if(_expr[i]=='-')
476       nbOfNegs++;
477   if(nbOfNegs%2)
478     _func_btw_sub_expr.push_back(FunctionsFactory::buildUnaryFuncFromString("-"));
479   _is_parsing_ok=true;
480   return true;
481 }
482
483 void ExprParser::parseForCmp()
484 {
485   std::string::const_iterator iter;
486   int curLevel=0;
487   std::string curPart;
488   bool isParsingSucceed=false;
489   for(iter=_expr.begin();iter!=_expr.end();iter++)
490     {
491       switch(*iter)
492         {
493         case '>':
494         case '<':
495           {
496             isParsingSucceed=true;
497             if(!curPart.empty())
498               {
499                 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
500                 curPart.clear();
501                 _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
502               }
503             else
504               {
505                 std::ostringstream errMsg;
506                 char MSGTYP1[]="Error non unary function for '";
507                 errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'";
508                 std::string tmp=_expr.substr(iter-_expr.begin());
509                 LocateError(errMsg,tmp,0);
510                 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
511               }
512             break;
513           }
514         case '(':
515           curLevel++;
516           curPart+=*iter;
517           break;
518         case ')':
519           curLevel--;
520           curPart+=*iter;
521           break;
522         default:
523           curPart+=*iter;
524         }
525     }
526   if(isParsingSucceed)
527     {
528       if(!curPart.empty())
529         {
530           _sub_expr.push_back(ExprParser(curPart.c_str(),this));
531           _is_parsing_ok=true;
532         }
533       else
534         {
535           std::ostringstream errMsg;
536           char MSGTYP4[]="Error following expression finished by > / < without right part.";
537           errMsg << EXPR_PARSE_ERR_MSG << MSGTYP4 << _expr;
538           throw INTERP_KERNEL::Exception(errMsg.str().c_str());
539         }
540     }
541 }
542
543 void ExprParser::parseForAddMin()
544 {
545   std::string::const_iterator iter;
546   int curLevel=0;
547   std::string curPart;
548   bool isParsingSucceed=false;
549   for(iter=_expr.begin();iter!=_expr.end();iter++)
550     {
551       switch(*iter)
552         {
553         case '+':
554         case '-':
555           if(curLevel!=0)
556             curPart+=*iter;
557           else
558             {
559               if(!curPart.empty())
560                 {
561                   std::string::reverse_iterator accessor=curPart.rbegin();
562                   if(*accessor!='*' && *accessor!='/' && *accessor!='^')
563                     {
564                       isParsingSucceed=true;
565                       _sub_expr.push_back(ExprParser(curPart.c_str(),this));
566                       curPart.clear();
567                       _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
568                     }
569                   else
570                     curPart+=*iter;
571                 }
572               else
573                 curPart+=*iter;
574             }
575         break;
576         case '(':
577           curLevel++;
578           curPart+=*iter;
579           break;
580         case ')':
581           curLevel--;
582           curPart+=*iter;
583           break;
584         default:
585           curPart+=*iter;
586         }
587     }
588   if(isParsingSucceed)
589     {
590       if(!curPart.empty())
591         {
592           _sub_expr.push_back(ExprParser(curPart.c_str(),this));
593           _is_parsing_ok=true;
594         }
595       else
596         {
597           std::ostringstream errMsg;
598           char MSGTYP4[]="Error following expression finished by +/- without right part.";
599           errMsg << EXPR_PARSE_ERR_MSG << MSGTYP4 << _expr;
600           throw INTERP_KERNEL::Exception(errMsg.str().c_str());
601         }
602     }
603 }
604
605 void ExprParser::parseForMulDiv()
606 {
607   std::string::const_iterator iter;
608   int curLevel=0;
609   std::string curPart;
610   bool isParsingSucceed=false;
611   for(iter=_expr.begin();iter!=_expr.end();iter++)
612     {
613       switch(*iter)
614         {
615         case '/':
616         case '*':
617           if(curLevel!=0)
618             curPart+=*iter;
619           else
620             {
621               isParsingSucceed=true;
622               if(!curPart.empty())
623                 {
624                   _sub_expr.push_back(ExprParser(curPart.c_str(),this));
625                   curPart.clear();
626                   _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
627                 }
628               else
629                 {
630                   std::ostringstream errMsg;
631                   char MSGTYP1[]="Error non unary function for '";
632                   errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'";
633                   std::string tmp=_expr.substr(iter-_expr.begin());
634                   LocateError(errMsg,tmp,0);
635                   throw INTERP_KERNEL::Exception(errMsg.str().c_str());
636                 }
637             }
638         break;
639         case '(':
640           curLevel++;
641           curPart+=*iter;
642           break;
643         case ')':
644           curLevel--;
645           curPart+=*iter;
646           break;
647         default:
648           curPart+=*iter;
649         }
650     }
651   if(isParsingSucceed)
652     {
653       if(!curPart.empty())
654         {
655           _sub_expr.push_back(ExprParser(curPart.c_str(),this));
656           _is_parsing_ok=true;
657         }
658       else
659         {
660           std::ostringstream errMsg;
661           char MSGTYP5[]="Error following expression finished by *// without right part.";
662           errMsg << EXPR_PARSE_ERR_MSG << MSGTYP5 << _expr;
663           throw INTERP_KERNEL::Exception(errMsg.str().c_str());
664         }
665     }
666 }
667
668 void ExprParser::parseForPow()
669 {
670   std::string::const_iterator iter;
671   int curLevel=0;
672   std::string curPart;
673   bool isParsingSucceed=false;
674   for(iter=_expr.begin();iter!=_expr.end();iter++)
675     {
676       switch(*iter)
677         {
678         case '^':
679           if(curLevel!=0)
680             curPart+=*iter;
681           else
682             if(!curPart.empty())
683               {
684                 isParsingSucceed=true;
685                 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
686                 curPart.clear();
687                 _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
688               }
689             else
690               {
691                 std::ostringstream errMsg;
692                 char MSGTYP1[]="Error non unary function for '";
693                 errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'";
694                 std::string tmp=_expr.substr(iter-_expr.begin());
695                 LocateError(errMsg,tmp,0);curPart+=*iter;
696                 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
697               }
698           break;
699         case '(':
700           curLevel++;
701           curPart+=*iter;
702           break;
703         case ')':
704           curLevel--;
705           curPart+=*iter;
706           break;
707         default:
708           curPart+=*iter;
709         }
710     }
711   if(isParsingSucceed)
712     {
713       if(!curPart.empty())
714         {
715           _sub_expr.push_back(ExprParser(curPart.c_str(),this));
716           _is_parsing_ok=true;
717         }
718       else
719         {
720           std::ostringstream errMsg;
721           char MSGTYP6[]="Error following expression finished by ^ without right part.";
722           errMsg << EXPR_PARSE_ERR_MSG << MSGTYP6 << _expr;
723           throw INTERP_KERNEL::Exception(errMsg.str().c_str());
724         }
725     }
726 }
727
728 void ExprParser::releaseFunctions()
729 {
730   for(std::list<Function *>::iterator iter=_func_btw_sub_expr.begin();iter!=_func_btw_sub_expr.end();iter++)
731     delete *iter;
732   _func_btw_sub_expr.clear();
733 }
734
735 /*!
736  * This method parse this->_expr at the current level.
737  * 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)
738  * 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.
739  */
740 bool ExprParser::simplify()
741 {
742   if(tryToInterpALeaf())
743     return true;
744   parseUnaryFunc();
745   if(!_is_parsing_ok)
746     {
747       parseForCmp();
748       if(!_is_parsing_ok)
749         {
750           parseForAddMin();
751           if(!_is_parsing_ok)
752             {
753               parseForMulDiv();
754               if(!_is_parsing_ok)
755                 parseForPow();
756             }
757         }
758     }
759   if(!_is_parsing_ok)
760     {
761       std::ostringstream errMsg;
762       char MSGTYP3[]="Error in interpreting : ";
763       errMsg << EXPR_PARSE_ERR_MSG << MSGTYP3 << _expr;
764       LocateError(errMsg,_expr,0);
765       throw INTERP_KERNEL::Exception(errMsg.str().c_str());
766     }
767   return false;
768 }
769
770 void ExprParser::checkBracketsParity() const
771 {
772   std::string::const_iterator iter;
773   int curLevel=0;
774   for(iter=_expr.begin();iter!=_expr.end();iter++)
775     {
776       if(*iter=='(')
777         curLevel++;
778       else if(*iter==')')
779         {
780           if(curLevel==0)
781             {
782               std::ostringstream errMsg;
783               char MSGTYP1[]="Error in brackets : closing brackets ')' before openning '('";
784               errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1;
785               LocateError(errMsg,_expr,(int)std::distance(_expr.begin(),iter));
786               throw INTERP_KERNEL::Exception(errMsg.str().c_str());
787             }
788           curLevel--;
789         }
790     }
791   if(curLevel!=0)
792     {
793       std::ostringstream errMsg;
794       char MSGTYP2[]="Error in brackets : not finally closed expr.";
795       errMsg << EXPR_PARSE_ERR_MSG << MSGTYP2;
796       throw INTERP_KERNEL::Exception(errMsg.str().c_str());
797     }
798 }
799
800 /*!
801  * This method substitutes part in [bg,end) in expr by the content of (str(id)) and returns the double value representation in expr[bg,end).
802  * If double representation is invalid an exception is thrown.
803  * This method returns a delta that is the delta to operate to pos in expr after substitution.
804  */
805 double ExprParser::ReplaceAndTraduce(std::string& expr, int id, std::size_t bg, std::size_t end, int& delta)
806 {
807   static const char MSG[]="Interal error : A string expected to be a float is not one ! Bug to signal !";
808   std::istringstream stream;
809   std::ostringstream oss;
810   std::size_t end2=end!=std::string::npos?end-bg:end;
811   std::string tmp=expr.substr(bg,end2);
812   stream.str(tmp);
813   double ret=std::numeric_limits<double>::max();
814   stream >> ret;
815   if(stream.fail())
816     throw INTERP_KERNEL::Exception(MSG);
817   if(!stream.eof())
818     throw INTERP_KERNEL::Exception(MSG);
819   oss << id;
820   std::string tmp2(oss.str());
821   std::size_t l1=tmp.length();
822   delta=(int)tmp2.length()-(int)l1;
823   expr.replace(bg,l1,tmp2);
824   return ret;
825 }
826
827 /*!
828  * This method makes the assumption that _expr has no white space.
829  * This method scans _expr finding in greedy mode the following pattern :
830  * {0..9}+{.}?{0..9}*{{eE}{-}?{0..9}+}?
831  */
832 void ExprParser::fillValuesInExpr(std::vector<double>& valuesInExpr)
833 {
834   const char FIGURES[]="0123456789";
835   const std::string other("+-*^/(<>,");
836   std::size_t lgth=_expr.length();
837   int id=0,delta;
838   for(std::size_t pos=0;pos!=std::string::npos;id++)
839     {
840       std::size_t pos2=_expr.find_first_of(FIGURES,pos,10);
841       if(pos2==std::string::npos)
842         break;
843       if(pos2>0)
844         {//treat case of "x*log10(x)" -> "10" should NOT be intercepted by this
845           if(other.find_first_of(_expr[pos2-1])==std::string::npos)
846             {
847               pos=_expr.find_first_not_of(FIGURES,pos2,10);
848               id--;
849               continue;
850             }
851           if(_expr[pos2-1]==')')
852             {
853               pos=_expr.find_first_not_of(FIGURES,pos2,10);
854               std::ostringstream oss; oss << "Problem on parsing : Number \"" << _expr.substr(pos2,pos!=std::string::npos?pos2-pos:std::string::npos);
855               oss << "\" is right after close parenthesis... ')'";
856               throw INTERP_KERNEL::Exception(oss.str().c_str());
857             }
858         }
859       std::size_t pos3=_expr.find_first_not_of(FIGURES,pos2,10);
860       if(pos3==std::string::npos)
861         {//"x+1223442320"
862           valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta));
863           break;
864         }
865       if(_expr[pos3]=='.')
866         pos3++;
867       if(pos3<lgth)
868         {
869           std::size_t pos4=_expr.find_first_not_of(FIGURES,pos3,10);
870           if(pos4==std::string::npos)
871             {//"x+1223334.223"
872               valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta));
873               break;
874             }
875           else
876             {
877               if(_expr[pos4]!='e' && _expr[pos4]!='E')
878                 {//"x+1223334.223+x"
879                   valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,pos4,delta));
880                   pos=pos4+delta;
881                   continue;
882                 }
883               else
884                 {
885                   if(++pos4<lgth)
886                     {
887                       if(_expr[pos4]=='+' || _expr[pos4]=='-')
888                         pos4++;
889                       if(pos4>=lgth)
890                         {//"x+1223334.223e+" or "1223334.223E-"
891                           std::ostringstream oss; oss << "Invalid expr : float number at the end of expr is invalid lacking number after exponential and sign ! -> \"" << _expr.substr(pos2) << "\"";
892                           throw INTERP_KERNEL::Exception(oss.str().c_str());
893                         }
894                       std::size_t pos5=_expr.find_first_not_of(FIGURES,pos4,10);
895                       if(pos4==pos5)
896                         {//"x+1223334.223e+x" or "1223334.223E-y"
897                           std::ostringstream oss; oss << "Invalid expr : float number in expr is invalid lacking number after exponential ! -> \"" << _expr.substr(pos2,pos4-pos2) << "\"";
898                           throw INTERP_KERNEL::Exception(oss.str().c_str());
899                         }
900                       //OK, normal case
901                       valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,pos5,delta));
902                       pos=pos5+delta;
903                       continue;
904                     }
905                   else//"x+1223334.223e"
906                     {
907                       std::ostringstream oss; oss << "Invalid expr : float number at the end of expr is invalid lacking number after exponential ! " << _expr.substr(pos2);
908                       throw INTERP_KERNEL::Exception(oss.str().c_str());
909                     }
910                 }
911             }
912         }
913       else
914         {//"x+1223334."
915           valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta));
916           break;
917         }
918     }
919 }
920
921 void ExprParser::replaceValues(const std::vector<double>& valuesInExpr)
922 {
923   if(_leaf)
924     _leaf->replaceValues(valuesInExpr);
925   else
926     {
927       for(std::list<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
928         (*iter).replaceValues(valuesInExpr);
929     }
930 }
931
932 void ExprParser::LocateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr)
933 {
934   stringToDisp << "Position is " << posOfErr << " of string : \"" <<  srcOfErr << "\"" << std::endl;
935 }
936
937 char *ExprParser::compileX86() const
938 {
939   std::vector<std::string> ass;
940   //need in stack
941   ass.push_back("push ebp");
942   ass.push_back("mov ebp,esp");
943   compileX86LowLev(ass);
944   ass.push_back("pop ebp");
945   ass.push_back("ret");
946   std::cout << std::endl;
947   for(std::vector<std::string>::const_iterator iter=ass.begin();iter!=ass.end();iter++)
948     std::cout << "        " << *iter << std::endl;
949   AsmX86 asmb;
950   std::vector<char> output=asmb.convertIntoMachineLangage(ass);
951   for(std::vector<char>::const_iterator iter=output.begin();iter!=output.end();iter++)
952     std::cout << std::hex << (int)((unsigned char)(*iter)) << " ";
953   std::cout << std::endl;
954   unsigned offset;
955   return asmb.copyToExecMemZone(output,offset);
956 }
957
958 char *ExprParser::compileX86_64() const
959 {
960   std::vector<std::string> ass;
961   //need in stack
962   ass.push_back("push rbp");
963   ass.push_back("mov rbp,rsp");
964   compileX86_64LowLev(ass);
965   ass.push_back("sub rsp,8");
966   ass.push_back("fst qword [rsp]");
967   ass.push_back("movsd xmm0,[rsp]");
968   ass.push_back("add rsp,8");
969   ass.push_back("leave");
970   ass.push_back("ret");
971   std::cout << std::endl;
972   for(std::vector<std::string>::const_iterator iter=ass.begin();iter!=ass.end();iter++)
973     std::cout << "        " << *iter << std::endl;
974   AsmX86 asmb;
975   std::vector<char> output=asmb.convertIntoMachineLangage(ass);
976   for(std::vector<char>::const_iterator iter=output.begin();iter!=output.end();iter++)
977     std::cout << std::hex << (int)((unsigned char)(*iter)) << " ";
978   std::cout << std::endl;
979   unsigned offset;
980   return asmb.copyToExecMemZone(output,offset);
981 }
982
983 void ExprParser::compileX86LowLev(std::vector<std::string>& ass) const
984 {
985   if(_leaf)
986     _leaf->compileX86(ass);
987   else
988     {
989       for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
990         (*iter).compileX86LowLev(ass);
991     }
992   for(std::list<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++)
993     (*iter2)->operateX86(ass);
994 }
995
996 void ExprParser::compileX86_64LowLev(std::vector<std::string>& ass) const
997 {
998   if(_leaf)
999     _leaf->compileX86_64(ass);
1000   else
1001     {
1002       for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
1003         (*iter).compileX86_64LowLev(ass);
1004     }
1005   for(std::list<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++)
1006     (*iter2)->operateX86(ass);
1007 }
1008
1009 void LeafExprVal::compileX86(std::vector<std::string>& ass) const
1010 {
1011   ass.push_back("sub esp,8");
1012   const int *b=reinterpret_cast<const int *>(&_value),*c=reinterpret_cast<const int *>(&_value);
1013   c++;
1014   std::ostringstream oss;
1015   oss << std::hex;
1016   oss << "mov dword [esp+4],0x" << *c;
1017   ass.push_back(oss.str());
1018   oss.str("");
1019   oss << "mov dword [esp],0x" << *b;
1020   ass.push_back(oss.str());
1021   ass.push_back("fld qword [esp]");
1022   ass.push_back("add esp,8");
1023 }
1024
1025 void LeafExprVal::compileX86_64(std::vector<std::string>& ass) const
1026 {
1027   ass.push_back("sub rsp,8");
1028   const int *b=reinterpret_cast<const int *>(&_value),*c=reinterpret_cast<const int *>(&_value);
1029   c++;
1030   std::ostringstream oss;
1031   oss << std::hex;
1032   oss << "mov dword [rsp+4],0x" << *c;
1033   ass.push_back(oss.str());
1034   oss.str("");
1035   oss << "mov dword [rsp],0x" << *b;
1036   ass.push_back(oss.str());
1037   ass.push_back("fld qword [rsp]");
1038   ass.push_back("add rsp,8");
1039 }
1040
1041 void LeafExprVar::compileX86(std::vector<std::string>& ass) const
1042 {
1043   ass.push_back("fld qword [ebp+8]");
1044 }
1045
1046 void LeafExprVar::compileX86_64(std::vector<std::string>& ass) const
1047 {
1048   ass.push_back("sub rsp,8");
1049   ass.push_back("movsd [rsp],xmm0");
1050   ass.push_back("fld qword [rsp]");
1051   ass.push_back("add rsp,8");
1052 }
1053
1054 int ExprParser::getStackSizeToPlayX86(const ExprParser *asker) const
1055 {
1056   if(asker)
1057     {
1058       int sz=_father->getStackSizeToPlayX86(this);
1059       int i=0;
1060       for(std::list<ExprParser>::const_reverse_iterator iter=_sub_expr.rbegin();iter!=_sub_expr.rend();iter++,i++)
1061         {
1062           const ExprParser& obj=(*iter);
1063           const ExprParser *pt=&obj;
1064           if(pt==asker)
1065             return sz-i;
1066         }
1067       throw INTERP_KERNEL::Exception("error getStackSizeToPlayX86 an object ExprParser called as father, whereas it is not one !");
1068     }
1069   else
1070     {
1071       if(!_father)
1072         return MAX_X86_FP_ST;
1073       return _father->getStackSizeToPlayX86(this);
1074     }
1075 }