1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "InterpKernelExprParser.hxx"
21 #include "InterpKernelValue.hxx"
22 #include "InterpKernelAsmX86.hxx"
32 using namespace INTERP_KERNEL;
34 const char LeafExprVar::END_OF_RECOGNIZED_VAR[]="Vec";
36 const char ExprParser::WHITE_SPACES[]=" \n";
38 const char ExprParser::EXPR_PARSE_ERR_MSG[]="Invalid expression detected : ";
40 LeafExpr *LeafExpr::buildInstanceFrom(const std::string& expr) throw(INTERP_KERNEL::Exception)
42 std::istringstream stream;
48 return new LeafExprVal(val);
51 std::ostringstream errMsg;
52 char MSGTYP6[]="Error following expression is not consedered as a double value : ";
53 errMsg << MSGTYP6 << expr;
54 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
57 return new LeafExprVar(expr);
64 LeafExprVal::LeafExprVal(double value):_value(value)
68 LeafExprVal::~LeafExprVal()
72 void LeafExprVal::fillValue(Value *val) const throw(INTERP_KERNEL::Exception)
74 val->setDouble(_value);
77 void LeafExprVal::replaceValues(const std::vector<double>& valuesInExpr) throw(INTERP_KERNEL::Exception)
80 int lgth=(int)valuesInExpr.size();
81 if(pos>=lgth || pos<0)
82 throw INTERP_KERNEL::Exception("LeafExprVal::replaceValues : Big Problem detected ! Send expression to Salome support with expression !");
83 _value=valuesInExpr[pos];
86 LeafExprVar::LeafExprVar(const std::string& var):_fast_pos(-1),_var_name(var)
90 void LeafExprVar::fillValue(Value *val) const throw(INTERP_KERNEL::Exception)
92 val->setVarname(_fast_pos,_var_name);
95 void LeafExprVar::prepareExprEvaluation(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo) const throw(INTERP_KERNEL::Exception)
97 std::vector<std::string>::const_iterator iter=std::find(vars.begin(),vars.end(),_var_name);
100 if(!isRecognizedKeyVar(_var_name,_fast_pos))
102 std::ostringstream oss; oss << "Var : " << _var_name << " not in : ";
103 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss,", "));
104 throw INTERP_KERNEL::Exception(oss.str().c_str());
108 int relPos=-7-_fast_pos;
109 if(relPos>=targetNbOfCompo)
111 std::ostringstream oss; oss << "LeafExprVar::prepareExprEvaluation : Found recognized unitary vector \"" << _var_name << "\" which implies that component #" << relPos;
112 oss << " exists, but it is not the case component id should be in [0," << targetNbOfCompo << ") !";
113 throw INTERP_KERNEL::Exception(oss.str().c_str());
119 _fast_pos=(int)std::distance(vars.begin(),iter);
120 if(_fast_pos>=nbOfCompo)
122 std::ostringstream oss; oss << "LeafExprVar::prepareExprEvaluation : Found var \"" << _var_name << "\" on place " << _fast_pos << " whereas only must be in [0," << nbOfCompo << ") !";
123 throw INTERP_KERNEL::Exception(oss.str().c_str());
127 void LeafExprVar::prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception)
129 if(!isRecognizedKeyVar(_var_name,_fast_pos))
133 bool LeafExprVar::isRecognizedKeyVar(const std::string& var, int& pos)
135 if(var.length()!=sizeof(END_OF_RECOGNIZED_VAR))
137 std::string end=var.substr(1);
138 if(end!=END_OF_RECOGNIZED_VAR)
141 if(first<'I' || first>'Z')
148 * Nothing to do it is not a bug.
150 void LeafExprVar::replaceValues(const std::vector<double>& valuesInExpr) throw(INTERP_KERNEL::Exception)
154 LeafExprVar::~LeafExprVar()
158 ExprParser::ExprParser(const char *expr, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr)
160 _expr=deleteWhiteSpaces(_expr);
163 //! For \b NOT null terminated strings coming from FORTRAN.
164 ExprParser::ExprParser(const char *expr, int lgth, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false)
166 _expr=buildStringFromFortran(expr,lgth);
167 _expr=deleteWhiteSpaces(_expr);
170 ExprParser::~ExprParser()
176 std::size_t ExprParser::FindCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket)
179 for(std::size_t iter=0;iter<posOfCloseBracket;iter++)
181 std::size_t iter2=posOfCloseBracket-1-iter;
184 else if(expr[iter2]=='(')
192 return std::string::npos;
195 std::string ExprParser::buildStringFromFortran(const char *expr, int lgth)
197 std::string ret(expr,lgth);
198 std::string whiteSpaces(WHITE_SPACES);
199 std::size_t found=ret.find_last_not_of(whiteSpaces);
200 if (found!=std::string::npos)
203 ret.clear();//ret is all whitespace
207 std::string ExprParser::deleteWhiteSpaces(const std::string& expr)
209 std::string ret(expr);
210 std::string whiteSpaces(WHITE_SPACES);
211 std::size_t where1=0,where2=0;
212 while(where2!=std::string::npos && where1!=std::string::npos)
214 where1=ret.find_first_of(whiteSpaces.c_str(),where1,whiteSpaces.length());
215 if(where1!=std::string::npos)
217 where2=ret.find_first_not_of(whiteSpaces,where1);
218 if(where2!=std::string::npos)
219 ret.erase(ret.begin()+where1,ret.begin()+where2);
221 ret.erase(ret.begin()+where1,ret.end());
227 void ExprParser::parse() throw(INTERP_KERNEL::Exception)
230 _is_parsing_ok=false;
235 std::string tmp(_expr);
236 std::vector<double> valuesInExpr;
237 fillValuesInExpr(valuesInExpr);
238 checkBracketsParity();
241 replaceValues(valuesInExpr);
247 double ExprParser::evaluate() const throw(INTERP_KERNEL::Exception)
249 Value *gen=new ValueDouble;
250 ValueDouble *res=(ValueDouble *)evaluateLowLev(gen);
252 double ret=res->getData();
257 DecompositionInUnitBase ExprParser::evaluateUnit() const throw(INTERP_KERNEL::Exception)
259 Value *gen=new ValueUnit;
263 res=(ValueUnit *)evaluateLowLev(gen);
265 catch(INTERP_KERNEL::Exception& e)
271 DecompositionInUnitBase ret=res->getData();
276 void ExprParser::evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const throw(INTERP_KERNEL::Exception)
278 Value *gen=new ValueDoubleExpr(szOfOutParam,inParam);
279 ValueDoubleExpr *res=0;
282 res=(ValueDoubleExpr *)evaluateLowLev(gen);
284 catch(INTERP_KERNEL::Exception& e)
290 std::copy(res->getData(),res->getData()+szOfOutParam,outParam);
294 void ExprParser::prepareExprEvaluation(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo) const throw(INTERP_KERNEL::Exception)
298 LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
300 leafC->prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo);
303 for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
304 (*iter).prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo);
307 void ExprParser::prepareExprEvaluationVec() const throw(INTERP_KERNEL::Exception)
309 std::set<std::string> trueVars;
310 getTrueSetOfVars(trueVars);
311 if(trueVars.size()>1)
313 std::ostringstream oss; oss << "For this type of evaluation only one not keyword variable authorized : ";
314 oss << "having " << trueVars.size() << " : ";
315 std::copy(trueVars.begin(),trueVars.end(),std::ostream_iterator<std::string>(oss," ")); oss << " !";
316 throw INTERP_KERNEL::Exception(oss.str().c_str());
318 prepareExprEvaluationVecLowLev();
321 void ExprParser::prepareExprEvaluationVecLowLev() const throw(INTERP_KERNEL::Exception)
325 LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
327 leafC->prepareExprEvaluationVec();
330 for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
331 (*iter).prepareExprEvaluationVecLowLev();
334 Value *ExprParser::evaluateLowLev(Value *valGen) const throw(INTERP_KERNEL::Exception)
337 throw INTERP_KERNEL::Exception("Parsing fails ! Invalid expression !");
338 if(_sub_expr.empty() && !_leaf)
339 throw INTERP_KERNEL::Exception("Empty expression !");
340 std::vector<Value *> stackOfVal;
345 Value *ret=valGen->newInstance();
348 _leaf->fillValue(ret);
350 catch(INTERP_KERNEL::Exception& e)
355 stackOfVal.resize(1);
360 stackOfVal.resize(_sub_expr.size());
361 std::vector<Value *>::reverse_iterator iter2=stackOfVal.rbegin();
362 for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++,iter2++)
363 *iter2=(*iter).evaluateLowLev(valGen);
365 std::list<Function *>::const_iterator iter3;
366 for(iter3=_func_btw_sub_expr.begin();iter3!=_func_btw_sub_expr.end();iter3++)
367 (*iter3)->operate(stackOfVal);
369 catch(INTERP_KERNEL::Exception& e)
371 for(std::vector<Value *>::iterator iter4=stackOfVal.begin();iter4!=stackOfVal.end();iter4++)
375 return stackOfVal.back();
378 void ExprParser::getSetOfVars(std::set<std::string>& vars) const
382 LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
384 vars.insert(leafC->getVar());
387 for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
388 (*iter).getSetOfVars(vars);
391 void ExprParser::getTrueSetOfVars(std::set<std::string>& trueVars) const
393 std::set<std::string> vars;
396 for(std::set<std::string>::const_iterator iter=vars.begin();iter!=vars.end();iter++)
399 if(!LeafExprVar::isRecognizedKeyVar(*iter,tmp))
400 trueVars.insert(*iter);
404 void ExprParser::parseDeeper() throw(INTERP_KERNEL::Exception)
406 for(std::list<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
407 if(!(*iter).simplify())
408 (*iter).parseDeeper();
412 * This method has the responsability to see if this->_expr can be seen as a unary function of something.
413 * Something defined as the contain of highest level barckets.
414 * Typically '(3*x+2)' and 'cos(4*l+p*n)' will be intercepted by this method whereas '3*x+2' not...etc..
416 void ExprParser::parseUnaryFunc() throw(INTERP_KERNEL::Exception)
418 if(_expr[_expr.length()-1]!=')')
420 //at this level of code _expr
421 std::size_t pos1=_expr.find_first_of('(');
422 std::size_t pos4=FindCorrespondingOpenBracket(_expr,_expr.length()-1);
425 std::string funcName=_expr.substr(0,pos1);
426 std::size_t pos2=funcName.find_first_of("+-*/^><",0,7);
427 std::size_t pos3=funcName.find_first_not_of("+-*/^><",0,7);
428 if(pos2!=std::string::npos && pos3!=std::string::npos)
429 return ;//Bracket group is not alone, can't conclude not recursively.
430 std::string newExp2=_expr.substr(pos1+1,_expr.length()-pos1-2);
431 std::size_t nbOfParamsInFunc=std::count(newExp2.begin(),newExp2.end(),',')+1;
432 if(pos3!=std::string::npos)
433 _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(funcName.c_str(),(int)nbOfParamsInFunc));
436 std::size_t lgth=funcName.length();
437 char tmp[2]; tmp[1]='\0';
438 for(std::size_t i=0;i<lgth;i++)
441 _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(tmp,(int)nbOfParamsInFunc));
445 for(std::size_t i=0;i<nbOfParamsInFunc;i++)
447 std::size_t pos5=newExp2.find_first_of(',',pos6);
448 std::size_t len=std::string::npos;
449 if(pos5!=std::string::npos)
451 std::string newExp3=newExp2.substr(pos6,len);
452 _sub_expr.push_back(ExprParser(newExp3.c_str(),this));
459 * This method has the responsability to see if this->_expr is interpretable without any recursion.
460 * \return true if no recursion needed, false if this->_expr is too complex to be interpreted at this level.
461 * \throw exception if this->_expr is simple enough to try to interprate this and this expression contains an error.
463 bool ExprParser::tryToInterpALeaf() throw(INTERP_KERNEL::Exception)
465 std::size_t pos=_expr.find_first_not_of("+-",0,2);
466 std::string minimizedExpr=_expr.substr(pos);
467 std::size_t pos2=minimizedExpr.find_first_of("+-*/^()<>",0,9);
468 if(pos2!=std::string::npos)
471 _leaf=LeafExpr::buildInstanceFrom(minimizedExpr);
473 for(std::size_t i=0;i<pos;i++)
477 _func_btw_sub_expr.push_back(FunctionsFactory::buildUnaryFuncFromString("-"));
482 void ExprParser::parseForCmp() throw(INTERP_KERNEL::Exception)
484 std::string::const_iterator iter;
487 bool isParsingSucceed=false;
488 for(iter=_expr.begin();iter!=_expr.end();iter++)
495 isParsingSucceed=true;
498 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
500 _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
504 std::ostringstream errMsg;
505 char MSGTYP1[]="Error non unary function for '";
506 errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'";
507 std::string tmp=_expr.substr(iter-_expr.begin());
508 LocateError(errMsg,tmp,0);
509 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
529 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
534 std::ostringstream errMsg;
535 char MSGTYP4[]="Error following expression finished by > / < without right part.";
536 errMsg << EXPR_PARSE_ERR_MSG << MSGTYP4 << _expr;
537 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
542 void ExprParser::parseForAddMin() throw(INTERP_KERNEL::Exception)
544 std::string::const_iterator iter;
547 bool isParsingSucceed=false;
548 for(iter=_expr.begin();iter!=_expr.end();iter++)
560 std::string::reverse_iterator accessor=curPart.rbegin();
561 if(*accessor!='*' && *accessor!='/' && *accessor!='^')
563 isParsingSucceed=true;
564 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
566 _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
591 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
596 std::ostringstream errMsg;
597 char MSGTYP4[]="Error following expression finished by +/- without right part.";
598 errMsg << EXPR_PARSE_ERR_MSG << MSGTYP4 << _expr;
599 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
604 void ExprParser::parseForMulDiv() throw(INTERP_KERNEL::Exception)
606 std::string::const_iterator iter;
609 bool isParsingSucceed=false;
610 for(iter=_expr.begin();iter!=_expr.end();iter++)
620 isParsingSucceed=true;
623 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
625 _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
629 std::ostringstream errMsg;
630 char MSGTYP1[]="Error non unary function for '";
631 errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'";
632 std::string tmp=_expr.substr(iter-_expr.begin());
633 LocateError(errMsg,tmp,0);
634 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
654 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
659 std::ostringstream errMsg;
660 char MSGTYP5[]="Error following expression finished by *// without right part.";
661 errMsg << EXPR_PARSE_ERR_MSG << MSGTYP5 << _expr;
662 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
667 void ExprParser::parseForPow() throw(INTERP_KERNEL::Exception)
669 std::string::const_iterator iter;
672 bool isParsingSucceed=false;
673 for(iter=_expr.begin();iter!=_expr.end();iter++)
683 isParsingSucceed=true;
684 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
686 _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
690 std::ostringstream errMsg;
691 char MSGTYP1[]="Error non unary function for '";
692 errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'";
693 std::string tmp=_expr.substr(iter-_expr.begin());
694 LocateError(errMsg,tmp,0);curPart+=*iter;
695 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
714 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
719 std::ostringstream errMsg;
720 char MSGTYP6[]="Error following expression finished by ^ without right part.";
721 errMsg << EXPR_PARSE_ERR_MSG << MSGTYP6 << _expr;
722 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
727 void ExprParser::releaseFunctions()
729 for(std::list<Function *>::iterator iter=_func_btw_sub_expr.begin();iter!=_func_btw_sub_expr.end();iter++)
731 _func_btw_sub_expr.clear();
735 * This method parse this->_expr at the current level.
736 * 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)
737 * 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 bool ExprParser::simplify() throw(INTERP_KERNEL::Exception)
741 if(tryToInterpALeaf())
760 std::ostringstream errMsg;
761 char MSGTYP3[]="Error in interpreting : ";
762 errMsg << EXPR_PARSE_ERR_MSG << MSGTYP3 << _expr;
763 LocateError(errMsg,_expr,0);
764 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
769 void ExprParser::checkBracketsParity() const throw(INTERP_KERNEL::Exception)
771 std::string::const_iterator iter;
773 for(iter=_expr.begin();iter!=_expr.end();iter++)
781 std::ostringstream errMsg;
782 char MSGTYP1[]="Error in brackets : closing brackets ')' before openning '('";
783 errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1;
784 LocateError(errMsg,_expr,(int)std::distance(_expr.begin(),iter));
785 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
792 std::ostringstream errMsg;
793 char MSGTYP2[]="Error in brackets : not finally closed expr.";
794 errMsg << EXPR_PARSE_ERR_MSG << MSGTYP2;
795 throw INTERP_KERNEL::Exception(errMsg.str().c_str());
800 * 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).
801 * If double representation is invalid an exception is thrown.
802 * This method returns a delta that is the delta to operate to pos in expr after substitution.
804 double ExprParser::ReplaceAndTraduce(std::string& expr, int id, std::size_t bg, std::size_t end, int& delta) throw(INTERP_KERNEL::Exception)
806 static const char MSG[]="Interal error : A string expected to be a float is not one ! Bug to signal !";
807 std::istringstream stream;
808 std::ostringstream oss;
809 std::size_t end2=end!=std::string::npos?end-bg:end;
810 std::string tmp=expr.substr(bg,end2);
812 double ret=std::numeric_limits<double>::max();
815 throw INTERP_KERNEL::Exception(MSG);
817 throw INTERP_KERNEL::Exception(MSG);
819 std::string tmp2(oss.str());
820 std::size_t l1=tmp.length();
821 delta=(int)tmp2.length()-(int)l1;
822 expr.replace(bg,l1,tmp2);
827 * This method makes the assumption that _expr has no white space.
828 * This method scans _expr finding in greedy mode the following pattern :
829 * {0..9}+{.}?{0..9}*{{eE}{-}?{0..9}+}?
831 void ExprParser::fillValuesInExpr(std::vector<double>& valuesInExpr) throw(INTERP_KERNEL::Exception)
833 const char FIGURES[]="0123456789";
834 const std::string other("+-*^/(<>,");
835 std::size_t lgth=_expr.length();
837 for(std::size_t pos=0;pos!=std::string::npos;id++)
839 std::size_t pos2=_expr.find_first_of(FIGURES,pos,10);
840 if(pos2==std::string::npos)
843 {//treat case of "x*log10(x)" -> "10" should NOT be intercepted by this
844 if(other.find_first_of(_expr[pos2-1])==std::string::npos)
846 pos=_expr.find_first_not_of(FIGURES,pos2,10);
850 if(_expr[pos2-1]==')')
852 pos=_expr.find_first_not_of(FIGURES,pos2,10);
853 std::ostringstream oss; oss << "Problem on parsing : Number \"" << _expr.substr(pos2,pos!=std::string::npos?pos2-pos:std::string::npos);
854 oss << "\" is right after close parenthesis... ')'";
855 throw INTERP_KERNEL::Exception(oss.str().c_str());
858 std::size_t pos3=_expr.find_first_not_of(FIGURES,pos2,10);
859 if(pos3==std::string::npos)
861 valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta));
868 std::size_t pos4=_expr.find_first_not_of(FIGURES,pos3,10);
869 if(pos4==std::string::npos)
871 valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta));
876 if(_expr[pos4]!='e' && _expr[pos4]!='E')
878 valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,pos4,delta));
886 if(_expr[pos4]=='+' || _expr[pos4]=='-')
889 {//"x+1223334.223e+" or "1223334.223E-"
890 std::ostringstream oss; oss << "Invalid expr : float number at the end of expr is invalid lacking number after exponential and sign ! -> \"" << _expr.substr(pos2) << "\"";
891 throw INTERP_KERNEL::Exception(oss.str().c_str());
893 std::size_t pos5=_expr.find_first_not_of(FIGURES,pos4,10);
895 {//"x+1223334.223e+x" or "1223334.223E-y"
896 std::ostringstream oss; oss << "Invalid expr : float number in expr is invalid lacking number after exponential ! -> \"" << _expr.substr(pos2,pos4-pos2) << "\"";
897 throw INTERP_KERNEL::Exception(oss.str().c_str());
900 valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,pos5,delta));
904 else//"x+1223334.223e"
906 std::ostringstream oss; oss << "Invalid expr : float number at the end of expr is invalid lacking number after exponential ! " << _expr.substr(pos2);
907 throw INTERP_KERNEL::Exception(oss.str().c_str());
914 valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta));
920 void ExprParser::replaceValues(const std::vector<double>& valuesInExpr) throw(INTERP_KERNEL::Exception)
923 _leaf->replaceValues(valuesInExpr);
926 for(std::list<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
927 (*iter).replaceValues(valuesInExpr);
931 void ExprParser::LocateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr)
933 stringToDisp << "Position is " << posOfErr << " of string : \"" << srcOfErr << "\"" << std::endl;
936 char *ExprParser::compileX86() const
938 std::vector<std::string> ass;
940 ass.push_back("push ebp");
941 ass.push_back("mov ebp,esp");
942 compileX86LowLev(ass);
943 ass.push_back("pop ebp");
944 ass.push_back("ret");
945 std::cout << std::endl;
946 for(std::vector<std::string>::const_iterator iter=ass.begin();iter!=ass.end();iter++)
947 std::cout << " " << *iter << std::endl;
949 std::vector<char> output=asmb.convertIntoMachineLangage(ass);
950 for(std::vector<char>::const_iterator iter=output.begin();iter!=output.end();iter++)
951 std::cout << std::hex << (int)((unsigned char)(*iter)) << " ";
952 std::cout << std::endl;
954 return asmb.copyToExecMemZone(output,offset);
957 char *ExprParser::compileX86_64() const
959 std::vector<std::string> ass;
961 ass.push_back("push rbp");
962 ass.push_back("mov rbp,rsp");
963 compileX86_64LowLev(ass);
964 ass.push_back("sub rsp,8");
965 ass.push_back("fst qword [rsp]");
966 ass.push_back("movsd xmm0,[rsp]");
967 ass.push_back("add rsp,8");
968 ass.push_back("leave");
969 ass.push_back("ret");
970 std::cout << std::endl;
971 for(std::vector<std::string>::const_iterator iter=ass.begin();iter!=ass.end();iter++)
972 std::cout << " " << *iter << std::endl;
974 std::vector<char> output=asmb.convertIntoMachineLangage(ass);
975 for(std::vector<char>::const_iterator iter=output.begin();iter!=output.end();iter++)
976 std::cout << std::hex << (int)((unsigned char)(*iter)) << " ";
977 std::cout << std::endl;
979 return asmb.copyToExecMemZone(output,offset);
982 void ExprParser::compileX86LowLev(std::vector<std::string>& ass) const
985 _leaf->compileX86(ass);
988 for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
989 (*iter).compileX86LowLev(ass);
991 for(std::list<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++)
992 (*iter2)->operateX86(ass);
995 void ExprParser::compileX86_64LowLev(std::vector<std::string>& ass) const
998 _leaf->compileX86_64(ass);
1001 for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
1002 (*iter).compileX86_64LowLev(ass);
1004 for(std::list<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++)
1005 (*iter2)->operateX86(ass);
1008 void LeafExprVal::compileX86(std::vector<std::string>& ass) const
1010 ass.push_back("sub esp,8");
1011 int *b=(int *)&_value,*c=(int *)&_value;
1013 std::ostringstream oss;
1015 oss << "mov dword [esp+4],0x" << *c;
1016 ass.push_back(oss.str());
1018 oss << "mov dword [esp],0x" << *b;
1019 ass.push_back(oss.str());
1020 ass.push_back("fld qword [esp]");
1021 ass.push_back("add esp,8");
1024 void LeafExprVal::compileX86_64(std::vector<std::string>& ass) const
1026 ass.push_back("sub rsp,8");
1027 int *b=(int *)&_value,*c=(int *)&_value;
1029 std::ostringstream oss;
1031 oss << "mov dword [rsp+4],0x" << *c;
1032 ass.push_back(oss.str());
1034 oss << "mov dword [rsp],0x" << *b;
1035 ass.push_back(oss.str());
1036 ass.push_back("fld qword [rsp]");
1037 ass.push_back("add rsp,8");
1040 void LeafExprVar::compileX86(std::vector<std::string>& ass) const
1042 ass.push_back("fld qword [ebp+8]");
1045 void LeafExprVar::compileX86_64(std::vector<std::string>& ass) const
1047 ass.push_back("sub rsp,8");
1048 ass.push_back("movsd [rsp],xmm0");
1049 ass.push_back("fld qword [rsp]");
1050 ass.push_back("add rsp,8");
1053 int ExprParser::getStackSizeToPlayX86(const ExprParser *asker) const
1057 int sz=_father->getStackSizeToPlayX86(this);
1059 for(std::list<ExprParser>::const_reverse_iterator iter=_sub_expr.rbegin();iter!=_sub_expr.rend();iter++,i++)
1061 const ExprParser& obj=(*iter);
1062 const ExprParser *pt=&obj;
1066 throw INTERP_KERNEL::Exception("error getStackSizeToPlayX86 an object ExprParser called as father, whereas it is not one !");
1071 return MAX_X86_FP_ST;
1072 return _father->getStackSizeToPlayX86(this);