Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
started top group gen, added project subdirs
[blast.git] / ArithmeticEvaluator.cpp
index 60db08e1265cfda852725112b896c5a6a7526a7b..54a9596a35b5fb569f6e65f683c439919d6baa30 100644 (file)
@@ -22,13 +22,19 @@ ArithmeticEvaluator::ArithmeticEvaluator() {
      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 = "+-*/";
   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)) {
@@ -165,15 +201,15 @@ double ArithmeticEvaluator::evaluate() throw(int) {
  */
 
 void ArithmeticEvaluator::convert(const QString& _expression) throw(int) {
-  QString expr = _expression;
+  
+  QString expr = _expression;    
   QString result="";
-  expr.remove(QChar(' '), Qt::CaseInsensitive);
-  foreach(QString func, fctMarkers) {
+  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 {
@@ -375,7 +411,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;