1 // Copyright (C) 2007-2013 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
19 // Author : Anthony Geay (CEA/DEN)
21 #include "InterpKernelExprParser.hxx"
22 #include "InterpKernelValue.hxx"
23 #include "InterpKernelAsmX86.hxx"
33 using namespace INTERP_KERNEL;
35 const char LeafExprVar::END_OF_RECOGNIZED_VAR[]="Vec";
37 const char ExprParser::WHITE_SPACES[]=" \n";
39 const char ExprParser::EXPR_PARSE_ERR_MSG[]="Invalid expression detected : ";
41 LeafExpr *LeafExpr::buildInstanceFrom(const std::string& expr)
43 std::istringstream stream;
49 return new LeafExprVal(val);
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());
58 return new LeafExprVar(expr);
65 LeafExprVal::LeafExprVal(double value):_value(value)
69 LeafExprVal::~LeafExprVal()
73 void LeafExprVal::fillValue(Value *val) const
75 val->setDouble(_value);
78 void LeafExprVal::replaceValues(const std::vector<double>& valuesInExpr)
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];
87 LeafExprVar::LeafExprVar(const std::string& var):_fast_pos(-1),_var_name(var)
91 void LeafExprVar::fillValue(Value *val) const
93 val->setVarname(_fast_pos,_var_name);
96 void LeafExprVar::prepareExprEvaluation(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo) const
98 std::vector<std::string>::const_iterator iter=std::find(vars.begin(),vars.end(),_var_name);
101 if(!isRecognizedKeyVar(_var_name,_fast_pos))
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());
109 int relPos=-7-_fast_pos;
110 if(relPos>=targetNbOfCompo)
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());
120 _fast_pos=(int)std::distance(vars.begin(),iter);
121 if(_fast_pos>=nbOfCompo)
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());
128 void LeafExprVar::prepareExprEvaluationVec() const
130 if(!isRecognizedKeyVar(_var_name,_fast_pos))
134 bool LeafExprVar::isRecognizedKeyVar(const std::string& var, int& pos)
136 if(var.length()!=sizeof(END_OF_RECOGNIZED_VAR))
138 std::string end=var.substr(1);
139 if(end!=END_OF_RECOGNIZED_VAR)
142 if(first<'I' || first>'Z')
149 * Nothing to do it is not a bug.
151 void LeafExprVar::replaceValues(const std::vector<double>& valuesInExpr)
155 LeafExprVar::~LeafExprVar()
159 ExprParser::ExprParser(const char *expr, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr)
161 _expr=deleteWhiteSpaces(_expr);
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)
167 _expr=buildStringFromFortran(expr,lgth);
168 _expr=deleteWhiteSpaces(_expr);
171 ExprParser::~ExprParser()
177 std::size_t ExprParser::FindCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket)
180 for(std::size_t iter=0;iter<posOfCloseBracket;iter++)
182 std::size_t iter2=posOfCloseBracket-1-iter;
185 else if(expr[iter2]=='(')
193 return std::string::npos;
196 std::string ExprParser::buildStringFromFortran(const char *expr, int lgth)
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)
204 ret.clear();//ret is all whitespace
208 std::string ExprParser::deleteWhiteSpaces(const std::string& expr)
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)
215 where1=ret.find_first_of(whiteSpaces.c_str(),where1,whiteSpaces.length());
216 if(where1!=std::string::npos)
218 where2=ret.find_first_not_of(whiteSpaces,where1);
219 if(where2!=std::string::npos)
220 ret.erase(ret.begin()+where1,ret.begin()+where2);
222 ret.erase(ret.begin()+where1,ret.end());
228 void ExprParser::parse()
231 _is_parsing_ok=false;
236 std::string tmp(_expr);
237 std::vector<double> valuesInExpr;
238 fillValuesInExpr(valuesInExpr);
239 checkBracketsParity();
242 replaceValues(valuesInExpr);
248 double ExprParser::evaluate() const
250 Value *gen=new ValueDouble;
251 ValueDouble *res=(ValueDouble *)evaluateLowLev(gen);
253 double ret=res->getData();
258 DecompositionInUnitBase ExprParser::evaluateUnit() const
260 Value *gen=new ValueUnit;
264 res=(ValueUnit *)evaluateLowLev(gen);
266 catch(INTERP_KERNEL::Exception& e)
272 DecompositionInUnitBase ret=res->getData();
277 void ExprParser::evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const
279 Value *gen=new ValueDoubleExpr(szOfOutParam,inParam);
280 ValueDoubleExpr *res=0;
283 res=(ValueDoubleExpr *)evaluateLowLev(gen);
285 catch(INTERP_KERNEL::Exception& e)
291 std::copy(res->getData(),res->getData()+szOfOutParam,outParam);
295 void ExprParser::prepareExprEvaluation(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo) const
299 LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
301 leafC->prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo);
304 for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
305 (*iter).prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo);
308 void ExprParser::prepareExprEvaluationVec() const
310 std::set<std::string> trueVars;
311 getTrueSetOfVars(trueVars);
312 if(trueVars.size()>1)
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());
319 prepareExprEvaluationVecLowLev();
322 void ExprParser::prepareExprEvaluationVecLowLev() const
326 LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
328 leafC->prepareExprEvaluationVec();
331 for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
332 (*iter).prepareExprEvaluationVecLowLev();
335 Value *ExprParser::evaluateLowLev(Value *valGen) const
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;
346 Value *ret=valGen->newInstance();
349 _leaf->fillValue(ret);
351 catch(INTERP_KERNEL::Exception& e)
356 stackOfVal.resize(1);
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);
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);
370 catch(INTERP_KERNEL::Exception& e)
372 for(std::vector<Value *>::iterator iter4=stackOfVal.begin();iter4!=stackOfVal.end();iter4++)
376 return stackOfVal.back();
379 void ExprParser::getSetOfVars(std::set<std::string>& vars) const
383 LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf);
385 vars.insert(leafC->getVar());
388 for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
389 (*iter).getSetOfVars(vars);
392 void ExprParser::getTrueSetOfVars(std::set<std::string>& trueVars) const
394 std::set<std::string> vars;
397 for(std::set<std::string>::const_iterator iter=vars.begin();iter!=vars.end();iter++)
400 if(!LeafExprVar::isRecognizedKeyVar(*iter,tmp))
401 trueVars.insert(*iter);
405 void ExprParser::parseDeeper()
407 for(std::list<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
408 if(!(*iter).simplify())
409 (*iter).parseDeeper();
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..
417 void ExprParser::parseUnaryFunc()
419 if(_expr[_expr.length()-1]!=')')
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);
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));
437 std::size_t lgth=funcName.length();
438 char tmp[2]; tmp[1]='\0';
439 for(std::size_t i=0;i<lgth;i++)
442 _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(tmp,(int)nbOfParamsInFunc));
446 for(std::size_t i=0;i<nbOfParamsInFunc;i++)
448 std::size_t pos5=newExp2.find_first_of(',',pos6);
449 std::size_t len=std::string::npos;
450 if(pos5!=std::string::npos)
452 std::string newExp3=newExp2.substr(pos6,len);
453 _sub_expr.push_back(ExprParser(newExp3.c_str(),this));
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.
464 bool ExprParser::tryToInterpALeaf()
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)
472 _leaf=LeafExpr::buildInstanceFrom(minimizedExpr);
474 for(std::size_t i=0;i<pos;i++)
478 _func_btw_sub_expr.push_back(FunctionsFactory::buildUnaryFuncFromString("-"));
483 void ExprParser::parseForCmp()
485 std::string::const_iterator iter;
488 bool isParsingSucceed=false;
489 for(iter=_expr.begin();iter!=_expr.end();iter++)
496 isParsingSucceed=true;
499 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
501 _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
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());
530 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
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());
543 void ExprParser::parseForAddMin()
545 std::string::const_iterator iter;
548 bool isParsingSucceed=false;
549 for(iter=_expr.begin();iter!=_expr.end();iter++)
561 std::string::reverse_iterator accessor=curPart.rbegin();
562 if(*accessor!='*' && *accessor!='/' && *accessor!='^')
564 isParsingSucceed=true;
565 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
567 _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
592 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
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());
605 void ExprParser::parseForMulDiv()
607 std::string::const_iterator iter;
610 bool isParsingSucceed=false;
611 for(iter=_expr.begin();iter!=_expr.end();iter++)
621 isParsingSucceed=true;
624 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
626 _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
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());
655 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
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());
668 void ExprParser::parseForPow()
670 std::string::const_iterator iter;
673 bool isParsingSucceed=false;
674 for(iter=_expr.begin();iter!=_expr.end();iter++)
684 isParsingSucceed=true;
685 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
687 _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter));
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());
715 _sub_expr.push_back(ExprParser(curPart.c_str(),this));
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());
728 void ExprParser::releaseFunctions()
730 for(std::list<Function *>::iterator iter=_func_btw_sub_expr.begin();iter!=_func_btw_sub_expr.end();iter++)
732 _func_btw_sub_expr.clear();
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.
740 bool ExprParser::simplify()
742 if(tryToInterpALeaf())
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());
770 void ExprParser::checkBracketsParity() const
772 std::string::const_iterator iter;
774 for(iter=_expr.begin();iter!=_expr.end();iter++)
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());
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());
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.
805 double ExprParser::ReplaceAndTraduce(std::string& expr, int id, std::size_t bg, std::size_t end, int& delta)
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);
813 double ret=std::numeric_limits<double>::max();
816 throw INTERP_KERNEL::Exception(MSG);
818 throw INTERP_KERNEL::Exception(MSG);
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);
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}+}?
832 void ExprParser::fillValuesInExpr(std::vector<double>& valuesInExpr)
834 const char FIGURES[]="0123456789";
835 const std::string other("+-*^/(<>,");
836 std::size_t lgth=_expr.length();
838 for(std::size_t pos=0;pos!=std::string::npos;id++)
840 std::size_t pos2=_expr.find_first_of(FIGURES,pos,10);
841 if(pos2==std::string::npos)
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)
847 pos=_expr.find_first_not_of(FIGURES,pos2,10);
851 if(_expr[pos2-1]==')')
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());
859 std::size_t pos3=_expr.find_first_not_of(FIGURES,pos2,10);
860 if(pos3==std::string::npos)
862 valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta));
869 std::size_t pos4=_expr.find_first_not_of(FIGURES,pos3,10);
870 if(pos4==std::string::npos)
872 valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta));
877 if(_expr[pos4]!='e' && _expr[pos4]!='E')
879 valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,pos4,delta));
887 if(_expr[pos4]=='+' || _expr[pos4]=='-')
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());
894 std::size_t pos5=_expr.find_first_not_of(FIGURES,pos4,10);
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());
901 valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,pos5,delta));
905 else//"x+1223334.223e"
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());
915 valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta));
921 void ExprParser::replaceValues(const std::vector<double>& valuesInExpr)
924 _leaf->replaceValues(valuesInExpr);
927 for(std::list<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
928 (*iter).replaceValues(valuesInExpr);
932 void ExprParser::LocateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr)
934 stringToDisp << "Position is " << posOfErr << " of string : \"" << srcOfErr << "\"" << std::endl;
937 char *ExprParser::compileX86() const
939 std::vector<std::string> ass;
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;
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;
955 return asmb.copyToExecMemZone(output,offset);
958 char *ExprParser::compileX86_64() const
960 std::vector<std::string> ass;
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;
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;
980 return asmb.copyToExecMemZone(output,offset);
983 void ExprParser::compileX86LowLev(std::vector<std::string>& ass) const
986 _leaf->compileX86(ass);
989 for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
990 (*iter).compileX86LowLev(ass);
992 for(std::list<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++)
993 (*iter2)->operateX86(ass);
996 void ExprParser::compileX86_64LowLev(std::vector<std::string>& ass) const
999 _leaf->compileX86_64(ass);
1002 for(std::list<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++)
1003 (*iter).compileX86_64LowLev(ass);
1005 for(std::list<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++)
1006 (*iter2)->operateX86(ass);
1009 void LeafExprVal::compileX86(std::vector<std::string>& ass) const
1011 ass.push_back("sub esp,8");
1012 const int *b=reinterpret_cast<const int *>(&_value),*c=reinterpret_cast<const int *>(&_value);
1014 std::ostringstream oss;
1016 oss << "mov dword [esp+4],0x" << *c;
1017 ass.push_back(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");
1025 void LeafExprVal::compileX86_64(std::vector<std::string>& ass) const
1027 ass.push_back("sub rsp,8");
1028 const int *b=reinterpret_cast<const int *>(&_value),*c=reinterpret_cast<const int *>(&_value);
1030 std::ostringstream oss;
1032 oss << "mov dword [rsp+4],0x" << *c;
1033 ass.push_back(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");
1041 void LeafExprVar::compileX86(std::vector<std::string>& ass) const
1043 ass.push_back("fld qword [ebp+8]");
1046 void LeafExprVar::compileX86_64(std::vector<std::string>& ass) const
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");
1054 int ExprParser::getStackSizeToPlayX86(const ExprParser *asker) const
1058 int sz=_father->getStackSizeToPlayX86(this);
1060 for(std::list<ExprParser>::const_reverse_iterator iter=_sub_expr.rbegin();iter!=_sub_expr.rend();iter++,i++)
1062 const ExprParser& obj=(*iter);
1063 const ExprParser *pt=&obj;
1067 throw INTERP_KERNEL::Exception("error getStackSizeToPlayX86 an object ExprParser called as father, whereas it is not one !");
1072 return MAX_X86_FP_ST;
1073 return _father->getStackSizeToPlayX86(this);