Changeset 2215 in Sophya for trunk/SophyaPI/PIext


Ignore:
Timestamp:
Oct 20, 2002, 4:12:08 PM (23 years ago)
Author:
ansari
Message:

Amelioration de l'interpreteur de base de piapp (PIAcmd), en particulier :

  • Gestion de stack pour les arguments des .pic
  • Gestion de stack pour les if then else endif
  • Gestion de stack pour les blocs for / foreach
  • Amelioration decodage des variables $varname et introduction de la possibilite d'acces aux mots d'une variable sous forme de tableau $varname[i] : le mot numero i de la chaine $varname

Reza - 20/10/2002

Location:
trunk/SophyaPI/PIext
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaPI/PIext/piacmd.cc

    r2214 r2215  
    1010#include "ctimer.h"
    1111#include "strutil.h"
     12#include "strutilxx.h"
    1213// #include "dlftypes.h"
    1314
     
    141142  inline void   AddLine(string& line) 
    142143    { lines.push_back(line); bloclineid.push_back(lines.size()); }
     144  void          AddLine(string& line, string& kw); 
    143145  inline void   AddBloc(PIACmdBloc* blk) 
    144146    { blocs.push_back(blk); bloclineid.push_back(-blocs.size()); }
    145147  PIACmdBloc*   Execute();
     148  inline int&   TestLevel()  { return testlevel; }
    146149protected:
    147150  PIACmd* piacmd;
     
    156159  int i1,i2,di;
    157160  float f1,f2,df;
     161  int testlevel;   // niveau d'imbrication des if
    158162};
    159163
     
    167171i1 = 0;  i2 = -1;  di = 1;
    168172f1 = 0.; f2 = -1.; df = 1.;
     173testlevel = 0;
    169174if ((args.size() < 2) ||  !isalpha((int)args[0][0]) )  return;
    170175if ((kw != "foreach") && (kw != "for"))  return;
     
    172177//if (isalpha((int)args[1][0]) ) {  This is a foreach bloc with string list
    173178if (kw == "foreach" ) { // This is a foreach bloc with string list
    174   for(int kk=1; kk<args.size(); kk++) strlist.push_back(args[kk]);
     179  if ((args[1] != "(") || (args[args.size()-1] != ")") ) return;
     180  for(int kk=2; kk<args.size()-1; kk++) strlist.push_back(args[kk]);
    175181  typ = BT_ForeachList;
    176182  blkok = true;
     
    219225
    220226/* --Methode-- */
     227void PIACmdBloc::AddLine(string& line, string& kw)
     228{
     229  AddLine(line);
     230  if (kw == "if")  testlevel++;
     231  else if (kw == "endif")  testlevel--;
     232}
     233
     234/* --Methode-- */
    221235PIACmdBloc* PIACmdBloc::Execute()
    222236{
     
    228242int kk=0;
    229243char buff[32];
     244int rcc = 0;
     245
    230246if (typ == BT_ForeachList)   // foreach string loop
    231247  for(k=0; k<strlist.size(); k++) {
     
    234250    for(kj=0; kj<bloclineid.size(); kj++) {
    235251      kk = bloclineid[kj];
    236       if (kk > 0)  piacmd->Interpret(lines[kk-1]);
     252      if (kk > 0)  {
     253        rcc = piacmd->Interpret(lines[kk-1]);
     254        if (rcc == 77766)  break;
     255      }
    237256      else blocs[-kk-1]->Execute();
    238       }
     257    }
     258    if (rcc == 77766)  break;
    239259  }
    240260else if (typ == BT_ForeachInt)  // Integer loop
     
    250270    for(kj=0; kj<bloclineid.size(); kj++) {
    251271      kk = bloclineid[kj];
    252       if (kk > 0)  piacmd->Interpret(lines[kk-1]);
     272      if (kk > 0)  {
     273        rcc = piacmd->Interpret(lines[kk-1]);
     274        if (rcc == 77766)  break;
     275      }
    253276      else blocs[-kk-1]->Execute();
    254       }
     277    }
     278    if (rcc == 77766)  break;
    255279  }
    256280else if (typ == BT_ForeachFloat)  // float loop
     
    266290    for(kj=0; kj<bloclineid.size(); kj++) {
    267291      kk = bloclineid[kj];
    268       if (kk > 0)  piacmd->Interpret(lines[kk-1]);
     292      if (kk > 0)  {
     293        rcc = piacmd->Interpret(lines[kk-1]);
     294        if (rcc == 77766)  break;
     295      }
    269296      else blocs[-kk-1]->Execute();
    270       }
     297    }
     298    if (rcc == 77766)  break;
    271299  }
    272300
     
    298326trace = false;   timing = false;
    299327gltimer = NULL;
    300 curblk = NULL;
    301328felevel = 0;
     329
    302330mulinecmd = "";
    303331mulinefg = false;
     332
     333CmdBlks.push(NULL);
     334list<char> xtx;
     335TestsStack.push(xtx);
     336curtestresult = true;
    304337
    305338cmdhgrp["All"] = 0;
     
    517550NamedObjMgr omg;
    518551
     552
    519553// On saute de commandes vides
    520554size_t l;
     
    541575  mulinecmd = "";
    542576  mulinefg = false;
    543   const char * rprompt = (curblk == NULL) ? "Cmd> " : "for...? ";
     577  const char * rprompt = (CmdBlks.empty()) ? "Cmd> " : "for...? ";
    544578  mImgApp->GetConsole()->SetPrompt(rprompt);
    545579}
     
    583617}
    584618
    585 if (kw == "break") {
    586   PIACmdBloc* curb = curblk;
    587   while (curb) {
    588     PIACmdBloc* dblk = curb;
    589     curb = curb->Parent();
    590     delete dblk;
    591   }
    592   testresult.clear();
    593   return(0);
    594 }
    595 else if (kw == "return")  return(77777);
    596 
    597619// On verifie si nous sommes dans un bloc (for , foreach)
    598 if (curblk != NULL)  { // On est dans un bloc
     620if (CmdBlks.top() != NULL)  { // On est dans un bloc
    599621  if ( (kw == "for") || (kw == "foreach")) felevel++;
    600622  else if (kw == "end") felevel--;
    601623  if (felevel == 0) { // Il faut executer le bloc
    602     PIACmdBloc* curb = curblk;
    603     curblk = curb->Parent();
     624    PIACmdBloc* curb = CmdBlks.top();
     625    CmdBlks.top() = curb->Parent();
    604626    mImgApp->GetConsole()->SetPrompt("Cmd> ");
     627    if (curb->TestLevel() != 0) {
     628      cerr << "PIACmd::Interpret()/syntax error - unbalenced if ... endif"
     629           << " within for/foreach bloc ! " << endl;
     630      delete curb;
     631      return(2); 
     632    }
    605633       //       cout << " *DBG* Executing bloc " << endl;
    606634    bool ohv = histon;
    607635    histon = false;
    608     curb->Execute();
     636    if (curtestresult) {
     637      // We push also PIACmdBloc and testresult on the stack
     638      CmdBlks.push(NULL);
     639      list<char> xtx;
     640      TestsStack.push(xtx);
     641      curb->Execute();
     642      // And PIACmdBloc and TestResult from the corresponding stacks
     643      PopStack(false);
     644    }
     645    delete curb;
    609646    histon = ohv;
    610647  }
    611   else curblk->AddLine(s);
     648  else CmdBlks.top()->AddLine(s, kw);
    612649  return(0);
    613650}
     
    619656
    620657// Sommes-nous dans un bloc de test if then else
    621 if (testresult.size() > 0) {  // Nous sommes ds un bloc if
     658if (TestsStack.top().size() > 0) {  // Nous sommes ds un bloc if
    622659  if (kw == "else") {
    623660    if ((*tresit) & 2) {
     
    628665    else {
    629666      const char * npr = ((*tresit)&1) ? "else-F> " : "else-T> ";
     667      if ((*tresit)&1)  curtestresult = false;
    630668      mImgApp->GetConsole()->SetPrompt(npr);
    631669      (*tresit) |= 2;
     
    636674    list<char>::iterator dbit = tresit;
    637675    tresit--;
    638     testresult.erase(dbit);
     676    TestsStack.top().erase(dbit);
    639677    const char * npr = "Cmd> ";
    640     if (testresult.size() > 1) {
     678    if (TestsStack.top().size() > 1) {
     679      curtestresult = true;
     680      list<char>::iterator it;
     681      for(it=TestsStack.top().begin(); it!=TestsStack.top().end(); it++) {
     682        // Si on n'est pas ds le else et le if est faux
     683        if ( !((*it)&2) && !((*it)&1) ) curtestresult = false;
     684        // Si on est ds else et le if etait vrai !
     685        if ( ((*it)&2) && ((*it)&1) )  curtestresult = false;
     686        if (!curtestresult)  break;
     687      }
     688     
    641689      if (!((*tresit)&2))
    642690        npr = ((*tresit)&1) ? "if-T> " : "if-F> ";
     
    644692        npr = ((*tresit)&1) ? "else-F> " : "else-T> ";
    645693    }
     694    else curtestresult = true;
    646695    mImgApp->GetConsole()->SetPrompt(npr);
    647696    return(0);
     
    655704
    656705bool fgcont = true;
    657 if (testresult.size() > 0) { // Resultat de if ou else
     706if (TestsStack.top().size() > 0) { // Resultat de if ou else
    658707  list<char>::iterator it;
    659   for(it=testresult.begin(); it!=testresult.end(); it++) {
     708  for(it=TestsStack.top().begin(); it!=TestsStack.top().end(); it++) {
    660709    // Si on n'est pas ds le else et le if est faux
    661710    if ( !((*it)&2) && !((*it)&1) )  fgcont = false;
     
    668717if ((!fgcont) && (kw != "if"))  return(0);
    669718
     719
     720// Les mots cles break et return peuvent de sortir de boucles/scripts/execfile
     721if (kw == "break") return(77766);
     722else if (kw == "return")  return(77777);
    670723
    671724// Nous ne sommes donc pas dans un bloc ....  Substitution de variables
     
    725778if ((kw == "foreach") || (kw == "for")) {
    726779  //     cout << " *DBG* We got a foreach... " << endl;
    727   PIACmdBloc* bloc = new PIACmdBloc(this, curblk, kw, tokens);
     780  PIACmdBloc* bloc = new PIACmdBloc(this, CmdBlks.top(), kw, tokens);
    728781  if (!bloc->CheckOK()) {
    729782    cerr << "PIACmd::Interpret() for/foreach syntax Error ! " << endl;
     
    732785    }
    733786  felevel++;
    734   if (curblk)  curblk->AddBloc(bloc);
     787  if (CmdBlks.top())  CmdBlks.top()->AddBloc(bloc);
    735788  else  mImgApp->GetConsole()->SetPrompt("for...> ");
    736   curblk = bloc;
     789  CmdBlks.top() = bloc;
    737790  //  cout << " *DBG* New Bloc created ... " << endl;
    738791  return(0);
     
    746799  }
    747800  char res_tst = (restst) ? 1 : 0;
    748   testresult.push_back(res_tst);
    749   if (testresult.size() == 1) tresit = testresult.begin();
     801  TestsStack.top().push_back(res_tst);
     802  if (TestsStack.top().size() == 1) tresit = TestsStack.top().begin();
    750803  else tresit++;
    751804  const char * npr = (restst) ? "if-T> " : "if-F> ";
     
    768821NamedObjMgr& omg = *mObjMgr;
    769822
    770 size_t p,q,q2,l;
     823int iarr = -1;  // index d'element de tableau
     824size_t p,q,q2,q3,l;
    771825
    772826s2="";
     
    805859    vn = s.substr(q+2,q2-q-2);
    806860    q2++;
    807     }
     861  }
     862  else if ( s[q+1] == '(' ) {  // Variable in the form $(name)
     863    q2 = s.find(')',q+1);
     864    if (q2 >= l) {
     865      cerr << " Syntax error -  Unbalenced  parenthesis () !!! " << endl;
     866      return(3);
     867      }
     868    vn = s.substr(q+2,q2-q-2);
     869    q2++;
     870  }
    808871  else if ( s[q+1] == '[' ) {  // Variable in the form $[varname]  -> This is $$varname
    809872    q2 = s.find(']',q+1);
     
    820883    q2 = s.find_first_of(" .:+-*/,[](){}&|!$\"'",q+1);
    821884    if (q2 > l) q2 = l;
     885    q3 = q2;
    822886    vn = s.substr(q+1, q2-q-1);
    823     }
     887    // Si variable de type $varname[index] : element de tableau
     888    if ((q2 < l) && (s[q2] == '[') ) {
     889      q3 = s.find_first_of("]",q2+1);
     890      string sia = s.substr(q2+1, q3-q2-1);
     891      int rcdia = ctoi(sia.c_str(), &iarr);
     892      if (rcdia < 0) {
     893        cerr << " Syntax error - in $varname[iarr] : $"
     894             << vn << "[" << sia <<"]" << endl;
     895        return(4);
     896      }
     897    }
     898  }
    824899  if (!GetVar(vn, vv)) return(5);
    825   s2 += (s.substr(p, q-p) + vv);
    826   p = q2;
    827   }
     900  if (iarr < 0) {
     901    s2 += (s.substr(p, q-p) + vv);
     902    p = q2;
     903  }
     904  else {
     905    vector<string> vs;
     906    FillVStringFrString(vv, vs);
     907    if (iarr >= vs.size()) {
     908      cerr << " Substitution error - word index out of range in "
     909           << "$varname[iarr] : $" << vn << "[" << iarr <<"]" << endl;
     910      return(4);
     911    }
     912    else s2 += (s.substr(p, q-p) + vs[iarr]);
     913    p = q3+1;
     914  }
     915}
    828916if (p < l) s2 += s.substr(p);
    829917
     
    884972{
    885973  res = true;
    886   if ((args.size() < 4) || (args[3] != "then")) return(1);
    887   if (args[1] == "==") res = (args[0] == args[2]);
    888   else if (args[1] == "!=") res = (args[0] != args[2]);
    889   else if (args[1] == "<")
    890     res = (atof(args[0].c_str()) < atof(args[2].c_str()));
    891   else if (args[1] == ">")
    892     res = (atof(args[0].c_str()) > atof(args[2].c_str()));
    893   else if (args[1] == "<=")
    894     res = (atof(args[0].c_str()) <= atof(args[2].c_str()));
    895   else if (args[1] == ">=")
    896     res = (atof(args[0].c_str()) >= atof(args[2].c_str()));
     974  if ((args.size() != 6) || (args[5] != "then") ||
     975      (args[0] != "(") || (args[4] != ")") ) return(1);
     976  if (args[2] == "==") res = (args[1] == args[3]);
     977  else if (args[2] == "!=") res = (args[1] != args[3]);
     978  else if (args[2] == "<")
     979    res = (atof(args[1].c_str()) < atof(args[3].c_str()));
     980  else if (args[2] == ">")
     981    res = (atof(args[1].c_str()) > atof(args[3].c_str()));
     982  else if (args[2] == "<=")
     983    res = (atof(args[1].c_str()) <= atof(args[3].c_str()));
     984  else if (args[2] == ">=")
     985    res = (atof(args[1].c_str()) >= atof(args[3].c_str()));
    897986  else return(2);
    898987  return(0);
     988}
     989
     990/* --Methode-- */
     991void PIACmd::PushStack(vector<string>& args)
     992{
     993  // We push the argument list (args) on the stack
     994  ArgsStack.push(args);
     995  // We push also PIACmdBloc and testresult on the stack
     996  CmdBlks.push(NULL);
     997  list<char> xtx;
     998  TestsStack.push(xtx);
     999
     1000}
     1001
     1002/* --Methode-- */
     1003void PIACmd::PopStack(bool psta)
     1004{
     1005  // We remove the argument list (args) from the stack
     1006  if (psta) ArgsStack.pop();
     1007  // And PIACmdBloc and TestResult from the corresponding stacks
     1008  PIACmdBloc* curb = CmdBlks.top();
     1009  while (curb != NULL) {
     1010    PIACmdBloc* parb = curb->Parent();
     1011    delete curb;  curb = parb;
     1012  }
     1013  CmdBlks.pop();
     1014  TestsStack.pop();
    8991015}
    9001016
     
    11221238// hist << "### Executing commands from " << file << endl;
    11231239
    1124 // We push the argument list (args) on the stack
    1125 ArgsStack.push(args);
    1126 
     1240PushStack(args);
    11271241if (trace) {
    11281242  mImgApp->GetConsole()->AddStr("### Executing commands from ", PIVA_Magenta);
     
    11491263  }
    11501264
    1151 // We remove the argument list (args) from the stack
    1152 ArgsStack.pop();
     1265PopStack(true);
    11531266
    11541267return(0);
  • trunk/SophyaPI/PIext/piacmd.h

    r2214 r2215  
    102102
    103103protected:
    104   virtual int           CheckHelpGrp(string& grp);
     104  virtual int   CheckHelpGrp(string& grp);
    105105  int           ExecuteCommandLine(string & keyw, vector<string> & args,
    106106                                   string & toks);
     
    110110                             string & line, bool & res);
    111111  bool          GetVar(string & vn, string & vv);
     112  void          PushStack(vector<string> & args);
     113  void          PopStack(bool psta=true);
    112114
    113115  NamedObjMgr* mObjMgr;
     
    151153  stack< vector<string> > ArgsStack;
    152154
    153   PIACmdBloc * curblk;  // Bloc de commande courant (foreach, ...)
    154   int felevel;          // foreah level
    155   list<char> testresult;    // Resultat des test if
     155  stack< PIACmdBloc * > CmdBlks;  // Bloc de commande courant (foreach, ...)
     156  int felevel;                    // foreach-for level
     157  stack< list<char> > TestsStack; // Stack des resultats de test
    156158  list<char>::iterator tresit;       // Test courant
     159  bool curtestresult;             // Resultat courant des tests
     160
    157161  bool mulinefg;            // Bloc multi-lignes (ligne suite)
    158162  string mulinecmd;         // Commande multi-lignes
Note: See TracChangeset for help on using the changeset viewer.