]> AND Private Git Repository - blast.git/blobdiff - ArithmeticEvaluator.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
changed ref/impls xsd and xml
[blast.git] / ArithmeticEvaluator.cpp
index dd8081ea03eccca986313810960688c032ea9af9..2898f139dd356293d174308c4c005292e1cb0c63 100644 (file)
@@ -15,20 +15,26 @@ supp. infos : saved in UTF-8 [éè]
 #include <math.h>
 
 ArithmeticEvaluator::ArithmeticEvaluator() {
-  opMarkers = "+-*/";
+  opMarkers = "+-*/|%"; // | is for euclidan division
   varMarkers = "$";
   expression = QStringList();
   /* CAUTION : function are mandatory using ( ) to encapsulate the operand
      since spaces are removed. Thus, an expression like sin 10 will lead to
      sin10 after spaces removal, and thus becomes invalid.
    */
-  fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round";
+  fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round";  
 }
 
 ArithmeticEvaluator::ArithmeticEvaluator(const QString& _expression) throw(int) {
-  opMarkers = "+-*/";
+  opMarkers = "+-*/|%"; // | is for euclidan division
   varMarkers = "$";
-  fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round";
+  expression = QStringList();
+  /* CAUTION : function are mandatory using ( ) to encapsulate the operand
+     since spaces are removed. Thus, an expression like sin 10 will lead to
+     sin10 after spaces removal, and thus becomes invalid.
+   */
+  fctMarkers << "sin" << "cos" << "log10" << "log2" << "log" << "ceil" << "floor" << "round";   
+  
   try {
     setExpression(_expression);
   }
@@ -37,7 +43,10 @@ ArithmeticEvaluator::ArithmeticEvaluator(const QString& _expression) throw(int)
   }
 }
 
-void ArithmeticEvaluator::setExpression(const QString& _expression) throw(int) {
+void ArithmeticEvaluator::setExpression(const QString& _expression) throw(int) {  
+  
+  setVariableNames(_expression);
+  
   try {
     convert(_expression);
   }
@@ -46,6 +55,28 @@ void ArithmeticEvaluator::setExpression(const QString& _expression) throw(int) {
   }
 }
 
+void ArithmeticEvaluator::setVariablesValue(const QHash<QString,double>& _varValues) { 
+  varValues =  _varValues;
+  /*
+  QHashIterator<QString,double> iterV(varValues);
+  while (iterV.hasNext()) {
+    iterV.next();
+    cout << "var " << qPrintable(iterV.key()) << " = " << iterV.value() << endl;
+  }
+  */
+}
+
+void ArithmeticEvaluator::setVariableNames(const QString& _expression) {
+  varNames.clear();
+  QRegularExpression re("[$][a-zA-Z0-9_]+");
+  QRegularExpressionMatchIterator matcher = re.globalMatch(_expression);
+  while(matcher.hasNext()) {
+    QRegularExpressionMatch m = matcher.next();
+    QString var = m.captured(0);    
+    varNames.append(var);
+  }
+}
+
 void ArithmeticEvaluator::print() {
   foreach(QString elt, expression) {
     cout << qPrintable(elt) << " ";
@@ -84,6 +115,7 @@ double ArithmeticEvaluator::evalFunction(int indexFunc, double value) {
 }
 
 double ArithmeticEvaluator::evaluate() throw(int) {
+  errorMessage = "";
   QStack<double> stack;
   bool ok;
   double value1,value2;
@@ -102,7 +134,11 @@ double ArithmeticEvaluator::evaluate() throw(int) {
       stack.push(evalFunction(idFunc,value1));
     }
     else if (varMarkers.contains(c)) {
-      if (!varValues.contains(elt)) throw(-index);
+      if (!varValues.contains(elt)) {
+        errorMessage = "cannot find value of ";
+        errorMessage += qPrintable(elt);
+        throw(-index);
+      }
       stack.push(varValues.value(elt));
     }
     else if (opMarkers.contains(c)) {
@@ -120,6 +156,16 @@ double ArithmeticEvaluator::evaluate() throw(int) {
       else if (c == '/') {
         stack.push(value1/value2);
       }
+      else if (c == '|') {
+        int val1 = (int)value1;
+        int val2 = (int)value2;
+        stack.push(val1/val2);
+      }
+      else if (c == '%') {
+        int val1 = (int)value1;
+        int val2 = (int)value2;
+        stack.push(val1%val2);
+      }
     }
     else {
       value1 = elt.toDouble(&ok);
@@ -166,18 +212,14 @@ double ArithmeticEvaluator::evaluate() throw(int) {
 
 void ArithmeticEvaluator::convert(const QString& _expression) throw(int) {
   
-  QString expr = _expression;  
-  cout << "converting " << qPrintable(expr) << endl;
+  QString expr = _expression;    
   QString result="";
-  expr.remove(QChar(' '), Qt::CaseInsensitive);
-  cout << "converting " << qPrintable(expr) << endl;
-  foreach(QString func, fctMarkers) {
-    cout << "for " << qPrintable(func) << endl;
+  expr.remove(QChar(' '), Qt::CaseInsensitive);  
+  foreach(QString func, fctMarkers) {    
     QString rep = QString("\x1b%1").arg(fctMarkers.indexOf(QRegExp(func)));
 
     expr.replace(QRegExp(func),rep);
-  }
-  cout << "packed expr: " << qPrintable(expr) << endl;
+  }  
 
   int offset = 0;
   try {
@@ -271,7 +313,7 @@ QString ArithmeticEvaluator::convertRecur(const QString& _expression, int *offse
         *offset += 1;
       }      
     }
-    else if (expr[*offset] == '/') {
+    else if ((expr[*offset] == '/')||(expr[*offset] == '|')||(expr[*offset] == '%')) {
 
       if (!checkAfterOp(expr,*offset)) throw(*offset);
 
@@ -279,7 +321,7 @@ QString ArithmeticEvaluator::convertRecur(const QString& _expression, int *offse
       c = '1';
       while ( (pile.isEmpty() == false) && (c != '(') && (c != '+') && (c != '-')) {
         c = pile.pop();
-        if ( (c=='*') || (c == '/')) {
+        if ( (c=='*') || (c == '/') || (c == '|') || (c=='%')) {
           result.append(c).append(",");
         }
         else {
@@ -379,7 +421,7 @@ QString ArithmeticEvaluator::getVariable(const QString& _expression, int offset,
     *size = 1;
   }
 
-  while ((_expression[i].isLetterOrNumber()) || (_expression[i] == '-') || (_expression[i] == '_')) {
+  while ((_expression[i].isLetterOrNumber()) || (_expression[i] == '_')) {
     number.append(_expression[i]);
     i += 1;
     *size += 1;
@@ -437,6 +479,8 @@ bool ArithmeticEvaluator::checkAfterPar(const QString& _expression, int offset)
   else if (_expression[offset+1] == '-') return true;
   else if (_expression[offset+1] == '*') return true;
   else if (_expression[offset+1] == '/') return true;
+  else if (_expression[offset+1] == '|') return true;
+  else if (_expression[offset+1] == '%') return true;
 
   return false;
 }