Index: trunk/SophyaPI/PIext/piacmd.cc
===================================================================
--- trunk/SophyaPI/PIext/piacmd.cc	(revision 2236)
+++ trunk/SophyaPI/PIext/piacmd.cc	(revision 2241)
@@ -427,12 +427,13 @@
 usage += "  > setol varname patt     # Fills varname with object list \n";
 usage += "  > unset varname          # clear variable definition \n";
+usage += "  > rpneval varname RPNExpression # Reverse Polish Notation evaluation \n";
 usage += "  > echo string            # output string \n";
 usage += "  > alias name string      # define a command alias \n";
 usage += "  > readstdin varname      # reads a line from stdin into $varname \n";
-usage += "  > foreach varname string-list # Loop \n"; 
+usage += "  > foreach varname ( string-list ) # Loop \n"; 
 usage += "  > for varname i1:i2[:di]      # Integer loop  \n"; 
 usage += "  > for varname f1:f2[:df]      # Float loop  \n";
 usage += "  > end                         # end loops \n"; 
-usage += "  > if test then  # Conditional test : a == != < > <= >= b \n";
+usage += "  > if ( test ) then  # Conditional test : a == != < > <= >= b \n";
 usage += "  > else          # Conditional  \n";
 usage += "  > endif         # End of conditional if bloc \n"; 
@@ -914,8 +915,10 @@
   mImgApp->GetConsole()->SetPrompt(npr);
 }
-else if (kw == "@") {  // Evaluation d'expression
-  int rcev = EvalVarExpr(tokens, s);
+else if ((tokens.size() > 0) && (tokens[0] == "=")) {  
+  // x = RPNExpression (Evaluation d'expression RPN)
+  tokens[0] = kw;
+  int rcev = EvalRPNExpr(tokens, s);
   if (rcev) {
-    cerr << "PIACmd::Interpret() evaluation syntax Error ! " << endl;
+    cerr << "PIACmd::Interpret() evaluation (RPN) syntax Error ! " << endl;
     return(1);
   }
@@ -946,4 +949,5 @@
 //  cout << "arg[ " << ii << " ] : " << tokens[ii] << endl;
 
+return(0);
 }
 
@@ -1188,61 +1192,167 @@
 }
 
-/* Verification la presence d'argument d'operation */
-#define _Check_EvalVarArg(j_) if (j_ >= args.size()) { \
-  cerr << "PIACmd::EvalVarExpr: syntax error " << line << endl; \
-  return(1); }
+/* Operations sur le stack RPN */
+inline bool Check_myRPNStack_(stack<double>& s, double& x, string& line) 
+{
+  if (s.empty()) { 
+    cerr << "PIACmd::EvalRPNExpr: syntax error / empty RPN stack " << line << endl; 
+    return true; 
+  } 
+  else x = s.top();
+  return false;
+}
+inline bool Check_myRPNStack_(stack<double>& s, double& x, double& y, string& line) 
+{
+  if (s.size() < 2) { 
+    cerr << "PIACmd::EvalRPNExpr: syntax error / RPN stack size < 2  " << line << endl; 
+    return true; 
+  }  
+ else { 
+   x = s.top(); s.pop(); y = s.top(); 
+ }
+  return false;
+}
+
+inline void Print_myRPNStack_(stack<double> s)
+{
+  if (s.empty()) 
+    cout << "PIACmd::EvalRPNExpr/PrintStack: Empty stack " << endl;
+  else {
+    int k = 0;
+    cout << "PIACmd::EvalRPNExpr/PrintStack: Size()= " << s.size() << endl;
+    while( !s.empty() ) {
+      cout << "    " << k << ":  " << s.top() << "  ";
+      if (k == 0)  cout << " (x) " << endl;
+      else if (k == 1) cout << " (y) " << endl;
+      else if (k == 2) cout << " (z) " << endl;
+      else cout << endl;
+      s.pop(); k++;
+    }
+  }
   
-/* --Methode-- */
-int PIACmd::EvalVarExpr(vector<string> & args, string & line)
-{
-  if ((args.size() < 3) || (args[1] != "=") || !isalpha(args[0][0]) )  { 
-    cerr << " PIACmd::EvalVarExpr: syntax error " << line << endl;
+} 
+
+  
+/* --Methode-- */
+int PIACmd::EvalRPNExpr(vector<string> & args, string & line)
+{
+  NamedObjMgr& omg = *mObjMgr;
+  
+  if (args.size() < 2) { 
+    cerr << "PIACmd::EvalRPNExpr: syntax error / missing arguments " << line << endl; 
     return(1);
   }
-
-  double x = atof(args[2].c_str());
-  double y = 0.;
-  int k = 3;
-  while (k < args.size()) {
+  else if (args.size() == 2) { 
+    omg.SetVar(args[0], args[1]);
+    return(0); 
+  }
+
+  double x,y;
+  x = y = 0.;
+  stack<double> rpnstack;  // Stack des operations en RPN 
+  for(int k=1; k<args.size(); k++) {
+    // Les 4 operations de base + - * / 
     if (args[k] == "+") { 
-      _Check_EvalVarArg(k+1);
-      y = atof(args[k+1].c_str());
-      x += y;  k += 2;
+      if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
+      rpnstack.top() = y+x;
     }
     else if (args[k] == "-") { 
-      _Check_EvalVarArg(k+1);
-      y = atof(args[k+1].c_str());
-      x -= y;  k += 2;
+      if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
+      rpnstack.top() = y-x;
     }
     else if (args[k] == "*") { 
-      _Check_EvalVarArg(k+1);
-      y = atof(args[k+1].c_str());
-      x *= y;  k += 2;
+      if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
+      rpnstack.top() = y*x;
     }
     else if (args[k] == "/") { 
-      _Check_EvalVarArg(k+1);
-      y = atof(args[k+1].c_str());
-      x /= y;  k += 2;
-    }
-    else if (args[k] == "//") { 
-      _Check_EvalVarArg(k+1);
-      if (args[k+1] == "sin")  x = sin(x);
-      else if (args[k+1] == "cos")  x = cos(x);
-      else if (args[k+1] == "tan")  x = tan(x);
-      else if (args[k+1] == "asin")  x = asin(x);
-      else if (args[k+1] == "acos")  x = acos(x);
-      else if (args[k+1] == "atan")  x = atan(x);
-      else if (args[k+1] == "log")   x = log(x);
-      else if (args[k+1] == "log10") x = log10(x);
-      else if (args[k+1] == "exp")   x = exp(x);
-      k += 2;
-   }
-  }
-
-  NamedObjMgr& omg = *mObjMgr;
+      if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
+      rpnstack.top() = y/x;
+    }
+    // Les constantes : e , pi
+    else if (args[k] == "e") {
+      rpnstack.push(M_E);
+    }
+    else if (args[k] == "pi") {
+      rpnstack.push(M_PI);
+    }
+    // Les fonctions usuelles a 1 argument f(x)
+    else if (args[k] == "cos") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = cos(x);
+    }
+    else if (args[k] == "sin") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = sin(x);
+    }
+    else if (args[k] == "tan") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = tan(x);
+    }
+    else if (args[k] == "acos") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = acos(x);
+    }
+    else if (args[k] == "asin") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = asin(x);
+    }
+    else if (args[k] == "atan") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = atan(x);
+    }
+    else if (args[k] == "log") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = log(x);
+    }
+    else if (args[k] == "log10") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = log10(x);
+    }
+    else if (args[k] == "exp") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = exp(x);
+    }
+    else if (args[k] == "deg2rad") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = x*M_PI/180.;
+    }
+    else if (args[k] == "rad2deg") {
+      if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
+      rpnstack.top() = x*180./M_PI;
+    }
+    // Les fonctions usuelles a 2 argument f(x,y)
+    else if (args[k] == "pow") { 
+      if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
+      rpnstack.top() = pow(y,x);
+    }
+    else if (args[k] == "atan2") { 
+      if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
+      rpnstack.top() = atan2(x,y);
+    }
+    // Fonctions de manipulation de stack
+    else if (args[k] == "print") { 
+      Print_myRPNStack_(rpnstack);
+    }
+    else if (args[k] == "x<>y") {
+      if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
+      rpnstack.top() = x;  rpnstack.push(y);
+    }
+    // On met un nombre sur le stack 
+    else {
+      if (ctof(args[k].c_str(),&x) < 0) {
+	cerr << "PIACmd::EvalRPNExpr: syntax error near " << args[k] 
+	     << " in expression: \n" << line << endl; 
+	return(2);
+      }
+      rpnstack.push(x);
+    }
+
+  }
+
+  if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
   char buff[64];
   sprintf(buff, "%g", x);
-  string vv = buff;
-  omg.SetVar(args[0], vv); 
+  string res = buff;
+  omg.SetVar(args[0], res);
   return(0);
 }
@@ -1347,4 +1457,7 @@
   else cerr << "PIACmd::Interpret() No variable with name " << tokens[0] << endl;
   }
+ else if (kw == "rpneval") {  // Evaluation d'expression en notation polonaise inverse
+  return(EvalRPNExpr(tokens, toks));
+}
 else if (kw == "echo") {
   for (int ii=0; ii<tokens.size(); ii++)
