File indexing completed on 2024-05-12 17:21:07

0001 /*
0002  * SPDX-FileCopyrightText: 2020-2021 Han Young <hanyoung@protonmail.com>
0003  * SPDX-FileCopyrightText: 2021-2022 Rohan Asokan
0004  * <rohan.asokan@students.iiit.ac.in>
0005  *
0006  * SPDX-License-Identifier: GPL-3.0-or-later
0007  */
0008 #include "mathengine.h"
0009 #include <QDebug>
0010 #include <QRegularExpression>
0011 #include <QStringList>
0012 #include <knumber.h>
0013 
0014 void MathEngine::parse(QString expr) {
0015   m_driver.parse(expr.toStdString());
0016   m_result = m_driver.result;
0017   m_error = m_driver.syntaxError;
0018   if (m_error && (expr == QStringLiteral("-") || expr == QStringLiteral("+"))) {
0019       m_result = KNumber::Zero;
0020       m_error = false;
0021   }
0022   Q_EMIT resultChanged();
0023 }
0024 
0025 QStringList MathEngine::getRegexMatches(const QString &expr,
0026                                         const QString &regex,
0027                                         int *counter) const {
0028     QRegularExpression re(regex);
0029     QRegularExpressionMatch regexMatch;
0030     QRegularExpressionMatchIterator it = re.globalMatch(expr);
0031     QStringList matches;
0032     while (it.hasNext()) {
0033         regexMatch = it.next();
0034         QString match = regexMatch.captured(0);
0035         matches << match;
0036         (*counter)++;
0037     }
0038     return matches;
0039 }
0040 
0041 void MathEngine::parseBinaryExpression(QString expr) {
0042     m_error = true;
0043     // qDebug() << "Current Epxression (mathengine.cpp): " << expr;
0044 
0045     int numbersPresent = 0;
0046     int operatorsPresent = 0;
0047     // Match for the numbers and binary operators
0048     QStringList numbers = getRegexMatches(expr, bitRegex, &numbersPresent);
0049     QStringList operators =
0050         getRegexMatches(expr, binaryOperatorRegex, &operatorsPresent);
0051 
0052     // Erroraneous Parses return here itself
0053     if ((operatorsPresent != 0 && numbersPresent == 0) ||
0054         (operatorsPresent > 1) || (numbersPresent > 2)) {
0055         return;
0056     } else {
0057         m_error = false;
0058         if (operatorsPresent == 0 && numbersPresent == 1) {
0059             m_result = KNumber::binaryFromString(numbers[0]);
0060             Q_EMIT resultChanged();
0061         }
0062     }
0063 
0064     // Binary Operator Syntax
0065     if (expressionSyntaxRegex1.match(expr).hasMatch()) {
0066         KNumber result(0);
0067         switch (operatorsList.indexOf(operators[0])) {
0068             case 0: // +
0069                 result = KNumber::binaryFromString(numbers[0]) +
0070                         KNumber::binaryFromString(numbers[1]);
0071                 break;
0072             case 1: // -
0073                 result = KNumber::binaryFromString(numbers[0]) -
0074                         KNumber::binaryFromString(numbers[1]);
0075                 break;
0076             case 2: // *
0077                 result = KNumber::binaryFromString(numbers[0]) *
0078                         KNumber::binaryFromString(numbers[1]);
0079                 break;
0080             case 3: // /
0081                 result = KNumber::binaryFromString(numbers[0]) /
0082                         KNumber::binaryFromString(numbers[1]);
0083                 break;
0084             case 4: // &
0085                 result = KNumber::binaryFromString(numbers[0]) &
0086                         KNumber::binaryFromString(numbers[1]);
0087                 break;
0088             case 5: // |
0089                 result = KNumber::binaryFromString(numbers[0]) |
0090                         KNumber::binaryFromString(numbers[1]);
0091                 break;
0092             case 6: // ^
0093                 result = KNumber::binaryFromString(numbers[0]) ^
0094                         KNumber::binaryFromString(numbers[1]);
0095                 break;
0096             case 7: // <<
0097                 result = KNumber::binaryFromString(numbers[0])
0098                         << KNumber::binaryFromString(numbers[1]);
0099                 break;
0100             case 8: // >>
0101                 result = KNumber::binaryFromString(numbers[0]) >>
0102                         KNumber::binaryFromString(numbers[1]);
0103                 break;
0104             default: // error
0105                 m_error = true;
0106         };
0107         m_result = result;
0108         Q_EMIT resultChanged();
0109     }
0110 }