From 54ac86405049364df763e8ce002cf7aed4b69bed Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Mon, 15 Jul 2019 14:46:09 +0200 Subject: Move fixmatheval to initial directory for assembler library. Signed-off-by: Pavel Pisa --- qtmips.pro | 3 +- qtmips_asm/fixmatheval.cpp | 331 +++++++++++++++++++++++++++++++++++++++++++++ qtmips_asm/fixmatheval.h | 126 +++++++++++++++++ qtmips_asm/qtmips_asm.pro | 20 +++ qtmips_cli/qtmips_cli.pro | 6 +- qtmips_gui/fixmatheval.cpp | 331 --------------------------------------------- qtmips_gui/fixmatheval.h | 126 ----------------- qtmips_gui/qtmips_gui.pro | 8 +- 8 files changed, 487 insertions(+), 464 deletions(-) create mode 100644 qtmips_asm/fixmatheval.cpp create mode 100644 qtmips_asm/fixmatheval.h create mode 100644 qtmips_asm/qtmips_asm.pro delete mode 100644 qtmips_gui/fixmatheval.cpp delete mode 100644 qtmips_gui/fixmatheval.h diff --git a/qtmips.pro b/qtmips.pro index 3826627..f13d321 100644 --- a/qtmips.pro +++ b/qtmips.pro @@ -2,7 +2,8 @@ TEMPLATE = subdirs SUBDIRS += \ qtmips_machine \ - qtmips_osemu + qtmips_osemu \ + qtmips_asm !wasm: SUBDIRS += \ qtmips_machine/tests \ diff --git a/qtmips_asm/fixmatheval.cpp b/qtmips_asm/fixmatheval.cpp new file mode 100644 index 0000000..8852938 --- /dev/null +++ b/qtmips_asm/fixmatheval.cpp @@ -0,0 +1,331 @@ +// SPDX-License-Identifier: GPL-2.0+ +/******************************************************************************* + * QtMips - MIPS 32-bit Architecture Subset Simulator + * + * Implemented to support following courses: + * + * B35APO - Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b35apo + * + * B4M35PAP - Advanced Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b4m35pap/start + * + * Copyright (c) 2017-2019 Karel Koci + * Copyright (c) 2019 Pavel Pisa + * + * Faculty of Electrical Engineering (http://www.fel.cvut.cz) + * Czech Technical University (http://www.cvut.cz/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + ******************************************************************************/ + +#include "fixmatheval.h" + +#include "limits.h" + +using namespace fixmatheval; + +FmeSymbolDb::~FmeSymbolDb() { +} + +bool FmeSymbolDb::getValue(FmeValue &value, QString name) { + (void)value; + (void)name; + return false; +} + +FmeNode::FmeNode(int priority) { + prio = priority; +} + +FmeNode::~FmeNode() { +} + +int FmeNode::priority() { + return prio; +} + +bool FmeNode::insert(FmeNode *node) { + (void)node; + return false; +} + +FmeNode *FmeNode::child() { + return nullptr; +} + + +FmeNodeConstant::FmeNodeConstant(FmeValue value) : FmeNode(INT_MAX) { + this->value = value; +} + +FmeNodeConstant::~FmeNodeConstant() { + +} + +bool FmeNodeConstant::eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) { + (void)symdb; + (void)error; + value = this->value; + return true; +} + +QString FmeNodeConstant::dump() { + return QString::number(value); +} + +FmeNodeSymbol::FmeNodeSymbol(QString &name) : FmeNode(INT_MAX) { + this->name = name; +} + +FmeNodeSymbol::~FmeNodeSymbol() { +} + +bool FmeNodeSymbol::eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) { + if (!symdb) { + error = QString("no symbol table to find value for %1").arg(name); + return false; + } + bool ok = symdb->getValue(value, name); + if (!ok) + error = QString("value for symbol \"%1\" not found").arg(name); + return ok; +} + +QString FmeNodeSymbol::dump() { + return name; +} + +FmeNodeUnaryOp::FmeNodeUnaryOp(int priority, FmeValue (*op)(FmeValue &a)) : + FmeNode(priority) { + this->operand_a = nullptr; + this->op = op; +} + +FmeNodeUnaryOp::~FmeNodeUnaryOp() { + delete operand_a; +} + +bool FmeNodeUnaryOp::FmeNodeUnaryOp::eval(FmeValue &value, FmeSymbolDb *symdb, + QString &error) { + FmeValue value_a; + if (!operand_a) + return false; + if (!operand_a->eval(value_a, symdb, error)) + return false; + value = op(value_a); + return true; +} + +FmeNode *FmeNodeUnaryOp::child() { + return operand_a; +} + +bool FmeNodeUnaryOp::insert(FmeNode *node) { + operand_a = node; + return true; +} + +QString FmeNodeUnaryOp::dump() { + return "(OP " + (operand_a? operand_a->dump(): "nullptr") + ")"; +} + +FmeNodeBinaryOp::FmeNodeBinaryOp(int priority, FmeValue (*op)(FmeValue &a, FmeValue &b), + FmeNode *left) : FmeNode(priority) { + this->operand_a = left; + this->operand_b = nullptr; + this->op = op; +} + +FmeNodeBinaryOp::~FmeNodeBinaryOp() { + delete operand_a; + delete operand_b; +} + +bool FmeNodeBinaryOp::eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) { + FmeValue value_a; + FmeValue value_b; + if (!operand_a || !operand_b) + return false; + if (!operand_a->eval(value_a, symdb, error) || + !operand_b->eval(value_b, symdb, error)) + return false; + value = op(value_a, value_b); + return true; +} + +FmeNode *FmeNodeBinaryOp::child() { + return operand_b; +} + +bool FmeNodeBinaryOp::insert(FmeNode *node) { + operand_b = node; + return true; +} + +QString FmeNodeBinaryOp::dump() { + return "(" + (operand_a? operand_a->dump(): "nullptr") + + " OP " + (operand_b? operand_b->dump(): "nullptr") + ")"; +} + +FmeExpression::FmeExpression() : FmeNode(0) { + root = nullptr; +} + +bool FmeExpression::parse(const QString &expression, QString &error) { + delete root; + int base_prio = 100; + root = nullptr; + bool ok = true; + int i; + int word_start = 0; + bool in_word = false; + bool is_unary = true; + for (i = 0; true; i++) { + QChar ch = 0; + if (i < expression.size()) + ch = expression.at(i); + if(!(ch.isLetterOrNumber() || (ch == '_')) || (i >= expression.size())) { + if (in_word) { + FmeNode *new_node = nullptr; + QString word = expression.mid(word_start, i - word_start); + if (word.at(0).isDigit()) { + new_node = new FmeNodeConstant(word.toLongLong(&ok, 0)); + if (!ok) { + error = QString("cannot convert \"%1\" to number").arg(word); + break; + } + } else { + new_node = new FmeNodeSymbol(word); + } + FmeNode *node; + FmeNode *child; + for (node = this; (child = node->child()) != nullptr; node = child); + ok = node->insert(new_node); + if (!ok) { + error = QString("parse stuck at \"%1\"").arg(word); + break; + } + + in_word = false; + is_unary = false; + if (i >= expression.size()) + break; + } + if (ch.isSpace()) + continue; + FmeValue (*binary_op)(FmeValue &a, FmeValue &b) = nullptr; + FmeValue (*unary_op)(FmeValue &a) = nullptr; + int prio = base_prio; + + if (ch == '~') { + prio += 90; + unary_op = [](FmeValue &a) -> FmeValue { return ~a; }; + } else if (ch == '-') { + if (is_unary) { + prio += 90; + unary_op = [](FmeValue &a) -> FmeValue { return -a; }; + } else { + binary_op = [](FmeValue &a, FmeValue &b) -> FmeValue { return a - b; }; + prio += 20; + } + } else if (ch == '+') { + if (is_unary) + continue; + binary_op = [](FmeValue &a, FmeValue &b) -> FmeValue { return a + b; }; + prio += 20; + } else if (ch == '*') { + binary_op = [](FmeValue &a, FmeValue &b) -> FmeValue { return a * b; }; + prio += 30; + } else if (ch == '/') { + binary_op = [](FmeValue &a, FmeValue &b) -> FmeValue { return a / b; }; + prio += 30; + } else if (ch == '|') { + binary_op = [](FmeValue &a, FmeValue &b) -> FmeValue { return a | b; }; + prio += 10; + } else if (ch == '&') { + binary_op = [](FmeValue &a, FmeValue &b) -> FmeValue { return a & b; }; + prio += 15; + } else if (ch == '^') { + binary_op = [](FmeValue &a, FmeValue &b) -> FmeValue { return a ^ b; }; + prio += 15; + } else if (ch == '(') { + base_prio += 100; + } else if (ch == ')') { + base_prio -= 100; + if (base_prio <= 0) { + ok = false; + error = QString("Unbalanced brackets."); + break; + } + } else { + error = QString("Unknow character \"%1\" in expression.").arg(ch); + ok = false; + break; + } + if ((binary_op != nullptr) || (unary_op != nullptr)) { + FmeNode *node; + FmeNode *child; + for (node = this; (child = node->child()) != nullptr; node = child) { + if (child->priority() >= prio) + break; + } + if (binary_op != nullptr) { + ok = node->insert(new FmeNodeBinaryOp(prio, binary_op, child)); + is_unary = true; + } else { + ok = node->insert(new FmeNodeUnaryOp(prio, unary_op)); + } + if (!ok) { + error = QString("parse stuck at \"%1\"").arg(QString(ch)); + break; + } + } + } else { + if (!in_word) + word_start = i; + in_word = true; + } + } + + return ok; +} + +FmeExpression::~FmeExpression() { + delete root; + root = nullptr; +} + +bool FmeExpression::eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) { + if (!root) + return false; + return root->eval(value, symdb, error); +} + +bool FmeExpression::insert(FmeNode *node) { + root = node; + return true; +} + +FmeNode *FmeExpression::child() { + return root; +} + +QString FmeExpression::dump() { + return "(" + (root? root->dump(): "nullptr") + ")"; +} + diff --git a/qtmips_asm/fixmatheval.h b/qtmips_asm/fixmatheval.h new file mode 100644 index 0000000..3312bfa --- /dev/null +++ b/qtmips_asm/fixmatheval.h @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0+ +/******************************************************************************* + * QtMips - MIPS 32-bit Architecture Subset Simulator + * + * Implemented to support following courses: + * + * B35APO - Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b35apo + * + * B4M35PAP - Advanced Computer Architectures + * https://cw.fel.cvut.cz/wiki/courses/b4m35pap/start + * + * Copyright (c) 2017-2019 Karel Koci + * Copyright (c) 2019 Pavel Pisa + * + * Faculty of Electrical Engineering (http://www.fel.cvut.cz) + * Czech Technical University (http://www.cvut.cz/) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + ******************************************************************************/ + +#ifndef FIXMATHEVAL_H +#define FIXMATHEVAL_H + +#include + +namespace fixmatheval { + +typedef std::int64_t FmeValue; + +class FmeSymbolDb { +public: + virtual ~FmeSymbolDb(); + virtual bool getValue(FmeValue &value, QString name) = 0; +}; + +class FmeNode { +public: + FmeNode(int priority); + virtual ~FmeNode(); + virtual bool eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) = 0; + virtual bool insert(FmeNode *node); + virtual FmeNode *child(); + virtual QString dump() = 0; + int priority(); +private: + int prio; +}; + +class FmeNodeConstant : public FmeNode { +public: + FmeNodeConstant(FmeValue value); + virtual ~FmeNodeConstant(); + virtual bool eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) override; + virtual QString dump() override; +private: + FmeValue value; +}; + +class FmeNodeSymbol : public FmeNode { +public: + FmeNodeSymbol(QString &name); + virtual ~FmeNodeSymbol(); + virtual bool eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) override; + virtual QString dump() override; +private: + QString name; +}; + +class FmeNodeUnaryOp : public FmeNode { +public: + FmeNodeUnaryOp(int priority, FmeValue (*op)(FmeValue &a)); + virtual ~FmeNodeUnaryOp(); + virtual bool eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) override; + virtual bool insert(FmeNode *node) override; + virtual FmeNode *child() override; + virtual QString dump() override; +private: + FmeValue (*op)(FmeValue &a); + FmeNode *operand_a; +}; + +class FmeNodeBinaryOp : public FmeNode { +public: + FmeNodeBinaryOp(int priority, FmeValue (*op)(FmeValue &a, FmeValue &b), FmeNode *left); + virtual ~FmeNodeBinaryOp(); + virtual bool eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) override; + virtual bool insert(FmeNode *node) override; + virtual FmeNode *child() override; + virtual QString dump() override; +private: + FmeValue (*op)(FmeValue &a, FmeValue &b); + FmeNode *operand_a; + FmeNode *operand_b; +}; + +class FmeExpression : public FmeNode { +public: + FmeExpression(); + virtual ~FmeExpression(); + virtual bool parse(const QString &expression, QString &error); + virtual bool eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) override; + virtual bool insert(FmeNode *node) override; + virtual FmeNode *child() override; + virtual QString dump() override; +private: + FmeNode *root; +}; + +} + +#endif /*FIXMATHEVAL*/ diff --git a/qtmips_asm/qtmips_asm.pro b/qtmips_asm/qtmips_asm.pro new file mode 100644 index 0000000..20b988f --- /dev/null +++ b/qtmips_asm/qtmips_asm.pro @@ -0,0 +1,20 @@ +QT -= gui + +TARGET = qtmips_asm +CONFIG += c++11 + +TEMPLATE = lib +CONFIG += staticlib + +LIBS += -lelf +QMAKE_CXXFLAGS += -std=c++0x +QMAKE_CXXFLAGS_DEBUG += -ggdb + +DEFINES += QTMIPS_MACHINE_LIBRARY +DEFINES += QT_DEPRECATED_WARNINGS + +SOURCES += \ + fixmatheval.cpp + +HEADERS += \ + fixmatheval.h diff --git a/qtmips_cli/qtmips_cli.pro b/qtmips_cli/qtmips_cli.pro index 8cacde6..6cc1909 100644 --- a/qtmips_cli/qtmips_cli.pro +++ b/qtmips_cli/qtmips_cli.pro @@ -12,8 +12,10 @@ else:win32:CONFIG(debug, debug|release): LIBS_SUBDIR = debug else:unix: LIBS_SUBDIR = . LIBS += -L$$OUT_PWD/../qtmips_machine/$${LIBS_SUBDIR} -lqtmips_machine -lelf +LIBS += -L$$OUT_PWD/../qtmips_asm/$${LIBS_SUBDIR} -lqtmips_asm -lelf PRE_TARGETDEPS += $$OUT_PWD/../qtmips_machine/$${LIBS_SUBDIR}/libqtmips_machine.a +PRE_TARGETDEPS += $$OUT_PWD/../qtmips_asm/$${LIBS_SUBDIR}/libqtmips_asm.a DOLAR=$ @@ -21,8 +23,8 @@ unix: LIBS += \ -Wl,-rpath,\'$${DOLAR}$${DOLAR}ORIGIN/../lib\' \ # --enable-new-dtags \ -INCLUDEPATH += $$PWD/../qtmips_machine -DEPENDPATH += $$PWD/../qtmips_machine +INCLUDEPATH += $$PWD/../qtmips_machine $$PWD/../qtmips_asm +DEPENDPATH += $$PWD/../qtmips_machine $$PWD/../qtmips_asm QMAKE_CXXFLAGS += -std=c++0x QMAKE_CXXFLAGS_DEBUG += -ggdb diff --git a/qtmips_gui/fixmatheval.cpp b/qtmips_gui/fixmatheval.cpp deleted file mode 100644 index 8852938..0000000 --- a/qtmips_gui/fixmatheval.cpp +++ /dev/null @@ -1,331 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/******************************************************************************* - * QtMips - MIPS 32-bit Architecture Subset Simulator - * - * Implemented to support following courses: - * - * B35APO - Computer Architectures - * https://cw.fel.cvut.cz/wiki/courses/b35apo - * - * B4M35PAP - Advanced Computer Architectures - * https://cw.fel.cvut.cz/wiki/courses/b4m35pap/start - * - * Copyright (c) 2017-2019 Karel Koci - * Copyright (c) 2019 Pavel Pisa - * - * Faculty of Electrical Engineering (http://www.fel.cvut.cz) - * Czech Technical University (http://www.cvut.cz/) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - ******************************************************************************/ - -#include "fixmatheval.h" - -#include "limits.h" - -using namespace fixmatheval; - -FmeSymbolDb::~FmeSymbolDb() { -} - -bool FmeSymbolDb::getValue(FmeValue &value, QString name) { - (void)value; - (void)name; - return false; -} - -FmeNode::FmeNode(int priority) { - prio = priority; -} - -FmeNode::~FmeNode() { -} - -int FmeNode::priority() { - return prio; -} - -bool FmeNode::insert(FmeNode *node) { - (void)node; - return false; -} - -FmeNode *FmeNode::child() { - return nullptr; -} - - -FmeNodeConstant::FmeNodeConstant(FmeValue value) : FmeNode(INT_MAX) { - this->value = value; -} - -FmeNodeConstant::~FmeNodeConstant() { - -} - -bool FmeNodeConstant::eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) { - (void)symdb; - (void)error; - value = this->value; - return true; -} - -QString FmeNodeConstant::dump() { - return QString::number(value); -} - -FmeNodeSymbol::FmeNodeSymbol(QString &name) : FmeNode(INT_MAX) { - this->name = name; -} - -FmeNodeSymbol::~FmeNodeSymbol() { -} - -bool FmeNodeSymbol::eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) { - if (!symdb) { - error = QString("no symbol table to find value for %1").arg(name); - return false; - } - bool ok = symdb->getValue(value, name); - if (!ok) - error = QString("value for symbol \"%1\" not found").arg(name); - return ok; -} - -QString FmeNodeSymbol::dump() { - return name; -} - -FmeNodeUnaryOp::FmeNodeUnaryOp(int priority, FmeValue (*op)(FmeValue &a)) : - FmeNode(priority) { - this->operand_a = nullptr; - this->op = op; -} - -FmeNodeUnaryOp::~FmeNodeUnaryOp() { - delete operand_a; -} - -bool FmeNodeUnaryOp::FmeNodeUnaryOp::eval(FmeValue &value, FmeSymbolDb *symdb, - QString &error) { - FmeValue value_a; - if (!operand_a) - return false; - if (!operand_a->eval(value_a, symdb, error)) - return false; - value = op(value_a); - return true; -} - -FmeNode *FmeNodeUnaryOp::child() { - return operand_a; -} - -bool FmeNodeUnaryOp::insert(FmeNode *node) { - operand_a = node; - return true; -} - -QString FmeNodeUnaryOp::dump() { - return "(OP " + (operand_a? operand_a->dump(): "nullptr") + ")"; -} - -FmeNodeBinaryOp::FmeNodeBinaryOp(int priority, FmeValue (*op)(FmeValue &a, FmeValue &b), - FmeNode *left) : FmeNode(priority) { - this->operand_a = left; - this->operand_b = nullptr; - this->op = op; -} - -FmeNodeBinaryOp::~FmeNodeBinaryOp() { - delete operand_a; - delete operand_b; -} - -bool FmeNodeBinaryOp::eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) { - FmeValue value_a; - FmeValue value_b; - if (!operand_a || !operand_b) - return false; - if (!operand_a->eval(value_a, symdb, error) || - !operand_b->eval(value_b, symdb, error)) - return false; - value = op(value_a, value_b); - return true; -} - -FmeNode *FmeNodeBinaryOp::child() { - return operand_b; -} - -bool FmeNodeBinaryOp::insert(FmeNode *node) { - operand_b = node; - return true; -} - -QString FmeNodeBinaryOp::dump() { - return "(" + (operand_a? operand_a->dump(): "nullptr") + - " OP " + (operand_b? operand_b->dump(): "nullptr") + ")"; -} - -FmeExpression::FmeExpression() : FmeNode(0) { - root = nullptr; -} - -bool FmeExpression::parse(const QString &expression, QString &error) { - delete root; - int base_prio = 100; - root = nullptr; - bool ok = true; - int i; - int word_start = 0; - bool in_word = false; - bool is_unary = true; - for (i = 0; true; i++) { - QChar ch = 0; - if (i < expression.size()) - ch = expression.at(i); - if(!(ch.isLetterOrNumber() || (ch == '_')) || (i >= expression.size())) { - if (in_word) { - FmeNode *new_node = nullptr; - QString word = expression.mid(word_start, i - word_start); - if (word.at(0).isDigit()) { - new_node = new FmeNodeConstant(word.toLongLong(&ok, 0)); - if (!ok) { - error = QString("cannot convert \"%1\" to number").arg(word); - break; - } - } else { - new_node = new FmeNodeSymbol(word); - } - FmeNode *node; - FmeNode *child; - for (node = this; (child = node->child()) != nullptr; node = child); - ok = node->insert(new_node); - if (!ok) { - error = QString("parse stuck at \"%1\"").arg(word); - break; - } - - in_word = false; - is_unary = false; - if (i >= expression.size()) - break; - } - if (ch.isSpace()) - continue; - FmeValue (*binary_op)(FmeValue &a, FmeValue &b) = nullptr; - FmeValue (*unary_op)(FmeValue &a) = nullptr; - int prio = base_prio; - - if (ch == '~') { - prio += 90; - unary_op = [](FmeValue &a) -> FmeValue { return ~a; }; - } else if (ch == '-') { - if (is_unary) { - prio += 90; - unary_op = [](FmeValue &a) -> FmeValue { return -a; }; - } else { - binary_op = [](FmeValue &a, FmeValue &b) -> FmeValue { return a - b; }; - prio += 20; - } - } else if (ch == '+') { - if (is_unary) - continue; - binary_op = [](FmeValue &a, FmeValue &b) -> FmeValue { return a + b; }; - prio += 20; - } else if (ch == '*') { - binary_op = [](FmeValue &a, FmeValue &b) -> FmeValue { return a * b; }; - prio += 30; - } else if (ch == '/') { - binary_op = [](FmeValue &a, FmeValue &b) -> FmeValue { return a / b; }; - prio += 30; - } else if (ch == '|') { - binary_op = [](FmeValue &a, FmeValue &b) -> FmeValue { return a | b; }; - prio += 10; - } else if (ch == '&') { - binary_op = [](FmeValue &a, FmeValue &b) -> FmeValue { return a & b; }; - prio += 15; - } else if (ch == '^') { - binary_op = [](FmeValue &a, FmeValue &b) -> FmeValue { return a ^ b; }; - prio += 15; - } else if (ch == '(') { - base_prio += 100; - } else if (ch == ')') { - base_prio -= 100; - if (base_prio <= 0) { - ok = false; - error = QString("Unbalanced brackets."); - break; - } - } else { - error = QString("Unknow character \"%1\" in expression.").arg(ch); - ok = false; - break; - } - if ((binary_op != nullptr) || (unary_op != nullptr)) { - FmeNode *node; - FmeNode *child; - for (node = this; (child = node->child()) != nullptr; node = child) { - if (child->priority() >= prio) - break; - } - if (binary_op != nullptr) { - ok = node->insert(new FmeNodeBinaryOp(prio, binary_op, child)); - is_unary = true; - } else { - ok = node->insert(new FmeNodeUnaryOp(prio, unary_op)); - } - if (!ok) { - error = QString("parse stuck at \"%1\"").arg(QString(ch)); - break; - } - } - } else { - if (!in_word) - word_start = i; - in_word = true; - } - } - - return ok; -} - -FmeExpression::~FmeExpression() { - delete root; - root = nullptr; -} - -bool FmeExpression::eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) { - if (!root) - return false; - return root->eval(value, symdb, error); -} - -bool FmeExpression::insert(FmeNode *node) { - root = node; - return true; -} - -FmeNode *FmeExpression::child() { - return root; -} - -QString FmeExpression::dump() { - return "(" + (root? root->dump(): "nullptr") + ")"; -} - diff --git a/qtmips_gui/fixmatheval.h b/qtmips_gui/fixmatheval.h deleted file mode 100644 index 3312bfa..0000000 --- a/qtmips_gui/fixmatheval.h +++ /dev/null @@ -1,126 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/******************************************************************************* - * QtMips - MIPS 32-bit Architecture Subset Simulator - * - * Implemented to support following courses: - * - * B35APO - Computer Architectures - * https://cw.fel.cvut.cz/wiki/courses/b35apo - * - * B4M35PAP - Advanced Computer Architectures - * https://cw.fel.cvut.cz/wiki/courses/b4m35pap/start - * - * Copyright (c) 2017-2019 Karel Koci - * Copyright (c) 2019 Pavel Pisa - * - * Faculty of Electrical Engineering (http://www.fel.cvut.cz) - * Czech Technical University (http://www.cvut.cz/) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - ******************************************************************************/ - -#ifndef FIXMATHEVAL_H -#define FIXMATHEVAL_H - -#include - -namespace fixmatheval { - -typedef std::int64_t FmeValue; - -class FmeSymbolDb { -public: - virtual ~FmeSymbolDb(); - virtual bool getValue(FmeValue &value, QString name) = 0; -}; - -class FmeNode { -public: - FmeNode(int priority); - virtual ~FmeNode(); - virtual bool eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) = 0; - virtual bool insert(FmeNode *node); - virtual FmeNode *child(); - virtual QString dump() = 0; - int priority(); -private: - int prio; -}; - -class FmeNodeConstant : public FmeNode { -public: - FmeNodeConstant(FmeValue value); - virtual ~FmeNodeConstant(); - virtual bool eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) override; - virtual QString dump() override; -private: - FmeValue value; -}; - -class FmeNodeSymbol : public FmeNode { -public: - FmeNodeSymbol(QString &name); - virtual ~FmeNodeSymbol(); - virtual bool eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) override; - virtual QString dump() override; -private: - QString name; -}; - -class FmeNodeUnaryOp : public FmeNode { -public: - FmeNodeUnaryOp(int priority, FmeValue (*op)(FmeValue &a)); - virtual ~FmeNodeUnaryOp(); - virtual bool eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) override; - virtual bool insert(FmeNode *node) override; - virtual FmeNode *child() override; - virtual QString dump() override; -private: - FmeValue (*op)(FmeValue &a); - FmeNode *operand_a; -}; - -class FmeNodeBinaryOp : public FmeNode { -public: - FmeNodeBinaryOp(int priority, FmeValue (*op)(FmeValue &a, FmeValue &b), FmeNode *left); - virtual ~FmeNodeBinaryOp(); - virtual bool eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) override; - virtual bool insert(FmeNode *node) override; - virtual FmeNode *child() override; - virtual QString dump() override; -private: - FmeValue (*op)(FmeValue &a, FmeValue &b); - FmeNode *operand_a; - FmeNode *operand_b; -}; - -class FmeExpression : public FmeNode { -public: - FmeExpression(); - virtual ~FmeExpression(); - virtual bool parse(const QString &expression, QString &error); - virtual bool eval(FmeValue &value, FmeSymbolDb *symdb, QString &error) override; - virtual bool insert(FmeNode *node) override; - virtual FmeNode *child() override; - virtual QString dump() override; -private: - FmeNode *root; -}; - -} - -#endif /*FIXMATHEVAL*/ diff --git a/qtmips_gui/qtmips_gui.pro b/qtmips_gui/qtmips_gui.pro index ae4f525..8e27fe2 100644 --- a/qtmips_gui/qtmips_gui.pro +++ b/qtmips_gui/qtmips_gui.pro @@ -13,9 +13,11 @@ else:unix: LIBS_SUBDIR = . LIBS += -L$$OUT_PWD/../qtmips_osemu/$${LIBS_SUBDIR} -lqtmips_osemu LIBS += -L$$OUT_PWD/../qtmips_machine/$${LIBS_SUBDIR} -lqtmips_machine -lelf +LIBS += -L$$OUT_PWD/../qtmips_asm/$${LIBS_SUBDIR} -lqtmips_asm -lelf PRE_TARGETDEPS += $$OUT_PWD/../qtmips_osemu/$${LIBS_SUBDIR}/libqtmips_osemu.a PRE_TARGETDEPS += $$OUT_PWD/../qtmips_machine/$${LIBS_SUBDIR}/libqtmips_machine.a +PRE_TARGETDEPS += $$OUT_PWD/../qtmips_asm/$${LIBS_SUBDIR}/libqtmips_asm.a DOLAR=$ @@ -23,8 +25,8 @@ unix: LIBS += \ -Wl,-rpath,\'$${DOLAR}$${DOLAR}ORIGIN/../lib\' \ # --enable-new-dtags \ -INCLUDEPATH += $$PWD/../qtmips_machine $$PWD/../qtmips_osemu -DEPENDPATH += $$PWD/../qtmips_machine $$PWD/../qtmips_osemu +INCLUDEPATH += $$PWD/../qtmips_machine $$PWD/../qtmips_osemu $$PWD/../qtmips_asm +DEPENDPATH += $$PWD/../qtmips_machine $$PWD/../qtmips_osemu $$PWD/../qtmips_asm QMAKE_CXXFLAGS += -std=c++0x QMAKE_CXXFLAGS_DEBUG += -ggdb @@ -74,7 +76,6 @@ SOURCES += \ hinttabledelegate.cpp \ coreview/minimux.cpp \ srceditor.cpp \ - fixmatheval.cpp \ highlighter.cpp HEADERS += \ @@ -120,7 +121,6 @@ HEADERS += \ hinttabledelegate.h \ coreview/minimux.h \ srceditor.h \ - fixmatheval.h \ highlighter.h wasm: SOURCES += \ -- cgit v1.2.3