#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);
}
}
}
-void ArithmeticEvaluator::setExpression(const QString& _expression) throw(int) {
+void ArithmeticEvaluator::setExpression(const QString& _expression) throw(int) {
+
+ setVariableNames(_expression);
+
try {
convert(_expression);
}
}
}
+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) << " ";
}
double ArithmeticEvaluator::evaluate() throw(int) {
+ errorMessage = "";
QStack<double> stack;
bool ok;
double value1,value2;
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)) {
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);
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 {
*offset += 1;
}
}
- else if (expr[*offset] == '/') {
+ else if ((expr[*offset] == '/')||(expr[*offset] == '|')||(expr[*offset] == '%')) {
if (!checkAfterOp(expr,*offset)) throw(*offset);
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 {
*size = 1;
}
- while ((_expression[i].isLetterOrNumber()) || (_expression[i] == '-') || (_expression[i] == '_')) {
+ while ((_expression[i].isLetterOrNumber()) || (_expression[i] == '_')) {
number.append(_expression[i]);
i += 1;
*size += 1;
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;
}