Commit 4bce7b54 authored by Rohan Asokan's avatar Rohan Asokan
Browse files

Completed binary extension to Knumber

Added keyboard shortcuts to most operators
Binary operators completed
Completed Integeral Binary Calculator without Unary operators
parent 68cad369
......@@ -5,6 +5,7 @@ add_library(knumber STATIC
knumber_fraction.cpp
knumber_integer.cpp
knumber_operators.cpp
knumber_binary_wrapper.cpp
)
target_include_directories(knumber PUBLIC ${CMAKE_BINARY_DIR} ${GMP_INCLUDE_DIR})
......
/*
* SPDX-FileCopyrightText: 2021-2022 Rohan Asokan <rohan.asokan@students.iiit.ac.in>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "knumber_binary_wrapper.h"
#include "knumber.h"
#include <QString>
#include <QRegularExpression>
#include <QLatin1String>
#include <QDebug>
// Constructors and Destructors
BinaryNumber::BinaryNumber(const BinaryNumber& other) {
m_number = other.toKNum();
}
BinaryNumber::BinaryNumber(const KNumber &num) {
m_number = num;
}
BinaryNumber::BinaryNumber(const QString &s) : m_number(KNumber("UNDEFINED_ERROR")) {
const QRegularExpression binary_regex("^[01]+.[01]+|^[01]+");
if (binary_regex.match(s).hasMatch()) {
m_number = KNumber(0);
int seperator_loc = s.indexOf('.');
if (seperator_loc == -1) seperator_loc = s.length();
KNumber multiplier(1);
KNumber base(2);
// Integer Part Calculations
for (int idx = seperator_loc - 1; idx >= 0; idx--) {
m_number += (KNumber(s.at(idx)) * multiplier);
multiplier *= base;
}
// multiplier = base;
// // Fractional Part Calculations
// for (int idx = seperator_loc + 1; idx < s.length(); idx++) {
// m_number += (KNumber(s.at(idx)) / base);
// multiplier *= base;
// }
}
}
// Converters
QString BinaryNumber::toDec() const {
return m_number.toQString();
}
KNumber BinaryNumber::toKNum() const {
return m_number;
}
// Operators
BinaryNumber &BinaryNumber::operator=(const BinaryNumber &rhs) {
(*this).m_number = rhs.toKNum();
return *this;
}
BinaryNumber operator+(const BinaryNumber &lhs, const BinaryNumber &rhs) {
KNumber res(lhs.toKNum());
res += rhs.toKNum();
return BinaryNumber(res);
}
BinaryNumber operator-(const BinaryNumber &lhs, const BinaryNumber &rhs) {
KNumber res(lhs.toKNum());
res -= rhs.toKNum();
return BinaryNumber(res);
}
BinaryNumber operator*(const BinaryNumber &lhs, const BinaryNumber &rhs) {
KNumber res(lhs.toKNum());
res *= rhs.toKNum();
return BinaryNumber(res);
}
BinaryNumber operator/(const BinaryNumber &lhs, const BinaryNumber &rhs) {
KNumber res(lhs.toKNum());
res /= rhs.toKNum();
return BinaryNumber(res);
}
BinaryNumber operator&(const BinaryNumber &lhs, const BinaryNumber &rhs) {
KNumber res(lhs.toKNum());
res &= rhs.toKNum();
return BinaryNumber(res);
}
BinaryNumber operator|(const BinaryNumber &lhs, const BinaryNumber &rhs) {
KNumber res(lhs.toKNum());
res |= rhs.toKNum();
return BinaryNumber(res);
}
BinaryNumber operator^(const BinaryNumber &lhs, const BinaryNumber &rhs) {
KNumber res(lhs.toKNum());
res ^= rhs.toKNum();
return BinaryNumber(res);
}
BinaryNumber operator<<(const BinaryNumber &lhs, const BinaryNumber &rhs) {
KNumber res(lhs.toKNum());
res <<= rhs.toKNum();
return BinaryNumber(res);
}
BinaryNumber operator>>(const BinaryNumber &lhs, const BinaryNumber &rhs) {
KNumber res(lhs.toKNum());
res >>= rhs.toKNum();
return BinaryNumber(res);
}
/*
* SPDX-FileCopyrightText: 2021-2022 Rohan Asokan <rohan.asokan@students.iiit.ac.in>
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <QString>
#include "knumber.h"
class BinaryNumber {
public:
// construction/destruction
BinaryNumber();
explicit BinaryNumber(const QString &s);
explicit BinaryNumber(const KNumber &num);
BinaryNumber(const BinaryNumber &other);
// ~BinaryNumber();
public:
// assignment
BinaryNumber &operator=(const BinaryNumber &rhs);
public:
// Unary operators
// KNumber &operator~();
public:
// Converters
QString toHex() const;
QString toOct() const;
QString toBin() const;
QString toDec() const;
KNumber toKNum() const;
private:
KNumber m_number;
};
BinaryNumber operator+(const BinaryNumber &lhs, const BinaryNumber &rhs);
BinaryNumber operator-(const BinaryNumber &lhs, const BinaryNumber &rhs);
BinaryNumber operator*(const BinaryNumber &lhs, const BinaryNumber &rhs);
BinaryNumber operator/(const BinaryNumber &lhs, const BinaryNumber &rhs);
BinaryNumber operator&(const BinaryNumber &lhs, const BinaryNumber &rhs);
BinaryNumber operator|(const BinaryNumber &lhs, const BinaryNumber &rhs);
BinaryNumber operator^(const BinaryNumber &lhs, const BinaryNumber &rhs);
BinaryNumber operator<<(const BinaryNumber &lhs, const BinaryNumber &rhs);
BinaryNumber operator>>(const BinaryNumber &lhs, const BinaryNumber &rhs);
......@@ -69,7 +69,15 @@ void InputManager::backspace()
{
m_expression.chop(m_stack.back());
Q_EMIT expressionChanged();
MathEngine::inst()->parse(m_expression);
// Call the corresponding parser based on the type of expression.
MathEngine * engineInstance = MathEngine::inst();
if (m_isBinaryMode) {
engineInstance->parseBinaryExpression(m_expression);
} else {
engineInstance->parse(m_expression);
}
if(!MathEngine::inst()->error())
{
m_result = MathEngine::inst()->result();
......
......@@ -8,6 +8,7 @@
#include <QDebug>
#include <QRegularExpression>
#include <QStringList>
#include "knumber_binary_wrapper.h"
void MathEngine::parse(QString expr)
{
......@@ -23,7 +24,7 @@ QStringList getRegexMatches(QString expr, QString regex, int *counter) {
QStringList matches;
while (it.hasNext()) {
regexMatch = it.next();
QString match = regexMatch.captured(1);
QString match = regexMatch.captured(0);
matches << match;
(*counter)++;
}
......@@ -33,7 +34,7 @@ QStringList getRegexMatches(QString expr, QString regex, int *counter) {
void MathEngine::parseBinaryExpression(QString expr)
{
m_error = true;
qDebug() << expr;
qDebug() << "Current Epxression (mathengine.cpp): " << expr;
int numbersPresent = 0;
int operatorsPresent = 0;
......@@ -50,9 +51,47 @@ void MathEngine::parseBinaryExpression(QString expr)
return;
} else {
m_error = false;
if (operatorsPresent == 0 && numbersPresent == 1) {
m_result = BinaryNumber(numbers[0]).toDec();
emit resultChanged();
}
}
// Binary Operator Syntax
if (expressionSyntaxRegex1.match(expr).hasMatch()) {
qDebug() << "Expression valid to calculate";
BinaryNumber result(0);
switch (operatorsList.indexOf(operators[0])) {
case 0: // +
result = BinaryNumber(numbers[0]) + BinaryNumber(numbers[1]);
break;
case 1: // -
result = BinaryNumber(numbers[0]) - BinaryNumber(numbers[1]);
break;
case 2: // *
result = BinaryNumber(numbers[0]) * BinaryNumber(numbers[1]);
break;
case 3: // /
result = BinaryNumber(numbers[0]) / BinaryNumber(numbers[1]);
break;
case 4: // &
result = BinaryNumber(numbers[0]) & BinaryNumber(numbers[1]);
break;
case 5: // |
result = BinaryNumber(numbers[0]) | BinaryNumber(numbers[1]);
break;
case 6: // ^
result = BinaryNumber(numbers[0]) ^ BinaryNumber(numbers[1]);
break;
case 7: // <<
result = BinaryNumber(numbers[0]) << BinaryNumber(numbers[1]);
break;
case 8: // >>
result = BinaryNumber(numbers[0]) >> BinaryNumber(numbers[1]);
break;
default: // error
m_error = true;
};
m_result = result.toDec();
emit resultChanged();
}
}
......@@ -9,6 +9,7 @@
#include "mathengine/driver.hh"
#include <QObject>
#include <QRegularExpression>
#include <QStringList>
class MathEngine : public QObject
{
Q_OBJECT
......@@ -39,9 +40,13 @@ private:
QString m_result;
bool m_error;
const QString bitRegex = QString("[01]+");
const QString binaryOperatorRegex = QString("[\\+\\-\\*\\/&\\|~\\^]|<{2}|>{2}");
// Regex for binary expression syntaxes
const QString binaryOperatorRegex = QString("[\\+\\-\\*\\/&\\|\\^]|<{2}|>{2}");
QRegularExpression expressionSyntaxRegex1 = QRegularExpression("([01]+)([\\+\\-\\*\\/&\\|~\\^]|<{2}|>{2})([01]+)");
QStringList operatorsList = {
"+", "-", "*", "/",
"&", "|", "^",
"<<", ">>"
};
};
#endif
......@@ -27,6 +27,37 @@ Kirigami.Page {
return initialPage.height - Kirigami.Units.gridUnit * 7;
}
}
Keys.onPressed: {
switch(event.key) {
case Qt.Backspace || Qt.Delete:
inputManager.backspace(); break;
case Qt.Key_0:
inputManager.append("0"); break;
case Qt.Key_1:
inputManager.append("1"); break;
case Qt.Key_Plus:
inputManager.append("+"); break;
case Qt.Key_Minus:
inputManager.append("-"); break;
case Qt.Key_multiply:
inputManager.append("*"); break;
case Qt.Key_division:
inputManager.append("/"); break;
case Qt.Key_Ampersand:
inputManager.append("&"); break;
case Qt.Key_Bar:
inputManager.append("|"); break;
case Qt.Key_AsciiCircum:
inputManager.append("^"); break;
case Qt.Key_Period:
inputManager.append("."); break;
case Qt.Key_Equal:
case Qt.Key_Return:
case Qt.Key_Enter:
inputManager.equal(); break;
}
}
onIsCurrentPageChanged: {
inputManager.setBinaryMode(true)
......@@ -120,6 +151,9 @@ Kirigami.Page {
onPressed: {
if (text == "DEL") {
inputManager.backspace();
} else if (text == "=") {
inputManager.equal();
resultFadeOutAnimation.start();
} else {
inputManager.append(text, true);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment