From 6e65fe88fcc795241dc96a06985e847d86d9f38b Mon Sep 17 00:00:00 2001 From: black Date: Tue, 8 Jul 2025 15:18:00 +0200 Subject: [PATCH] added "beq" command --- src/Manager.cpp | 53 ++++++++++++++++++++++++------------------ src/Manager.h | 13 +++++++++-- src/ProgramLoader.cpp | 6 ++++- src/ProgramLoader.h | 13 +++++++---- src/components/Alu.cpp | 17 +++++++++++++- src/main.cpp | 6 +++-- 6 files changed, 76 insertions(+), 32 deletions(-) diff --git a/src/Manager.cpp b/src/Manager.cpp index 167e0c3..d957c86 100644 --- a/src/Manager.cpp +++ b/src/Manager.cpp @@ -11,7 +11,37 @@ #include "components/Alu.h" namespace fs = std::filesystem; -Manager::Manager(std::string path): m_path(std::move(path)) { +Manager::~Manager() { + m_programFile.close(); +} + +Manager *Manager::getInstance() { + static Manager instance; + return &instance; +} + +int Manager::run() { + if (!m_programFile.is_open()) { + std::cerr << "Bitte zuerst die init() Methode aufrufen!" << "\n" << std::flush; + } + std::string line; + ProgramLoader::getInstance()->indexFile(m_programFile); + /// Die Position des Streams (virtueller Lesekopf) muss nach dem Indexen wieder zurückgesetzt werden + m_programFile.clear(); + m_programFile.seekg(0); + while (std::getline(m_programFile, line)) { + auto lineVector = ProgramLoader::parseLine(line); + Alu::calculate(lineVector); + } + return 0; +} + +void Manager::setStreamPosition(const std::streampos pos) { + m_programFile.seekg(pos); +} + +void Manager::init(const std::string &program_path) { + m_path = program_path; std::cout << "Öffne Quellcode Datei: '" << m_path << "'" << "\n" << std::flush; if (!fs::exists(m_path)) { std::cerr << "Datei existiert nicht: " << m_path << "\n" << std::flush; @@ -25,24 +55,3 @@ Manager::Manager(std::string path): m_path(std::move(path)) { return; } } - -Manager::~Manager() { - m_programFile.close(); -} - -Manager *Manager::getInstance(const std::string &program_path) { - static Manager instance{program_path}; - return &instance; -} - -int Manager::run() { - std::string line; - ProgramLoader::getInstance()->indexFile(m_programFile); - m_programFile.clear(); - m_programFile.seekg(0); - while (std::getline(m_programFile, line)) { - auto lineVector = ProgramLoader::parseLine(line); - Alu::calculate(lineVector); - } - return 0; -} diff --git a/src/Manager.h b/src/Manager.h index cca103f..6d6bfec 100644 --- a/src/Manager.h +++ b/src/Manager.h @@ -14,7 +14,7 @@ class Manager { private: /// Die Instanz des Managers soll mit einem immutable path zum Programm erstellt werden - explicit Manager(std::string path); + Manager() = default; std::string m_path; std::map m_labels; @@ -38,7 +38,7 @@ public: * @param program_path Der Pfad des Quellcodes * @return Die Singleton Instance des Managers */ - static Manager *getInstance(const std::string &program_path); + static Manager *getInstance(); /** * Die Hauptmethode des Emulators. @@ -47,6 +47,15 @@ public: * @return Der Exitcode des Emulators */ int run(); + + /** + * Setzt die Position des Streams (virtuellen Lesekopfes) auf die angegebene Position + * + * @param pos Die Position des Lesekopfes + */ + void setStreamPosition(std::streampos pos); + + void init(const std::string &program_path); }; diff --git a/src/ProgramLoader.cpp b/src/ProgramLoader.cpp index ef047fb..4951746 100644 --- a/src/ProgramLoader.cpp +++ b/src/ProgramLoader.cpp @@ -40,9 +40,13 @@ void ProgramLoader::indexFile(std::ifstream &m_programFile) { /// Parse Zeile für Zeile while (std::getline(m_programFile, line)) { auto lineVector = parseLine(line); - /// Sobald ein Label gefunden wurde, speichere die Zeile + /// Sobald ein Label gefunden wurde, speichere die Position des Streams if (const auto first = lineVector.begin(); first->at(first->length() - 1) == ':') { m_labels[first->substr(0, first->length() - 1)] = m_programFile.tellg(); } } } + +std::streampos ProgramLoader::getStreamPosition(const std::string &label) const { + return m_labels.find(label)->second; +} diff --git a/src/ProgramLoader.h b/src/ProgramLoader.h index 9a17ccc..7ad0d90 100644 --- a/src/ProgramLoader.h +++ b/src/ProgramLoader.h @@ -15,9 +15,7 @@ class ProgramLoader { private: /** * Der private Konstruktor für ProgramLoader - * - * @param path Der Pfad zur .txt Quelldatei des Programmes - */ + * */ explicit ProgramLoader() = default; std::map m_labels; @@ -35,7 +33,6 @@ public: /** * Gibt die Singleton Instanz des ProgramLoaders zurück * - * @param program_path Der Pfad zur .txt Quelldatei des Programmes * @return ProgramLoader Instanz */ static ProgramLoader *getInstance(); @@ -52,6 +49,14 @@ public: * Durchscucht das aktuelle Programm nach Labeln und speichert diese zusammen mit den Zeilennummern in einer Map */ void indexFile(std::ifstream &m_programFile); + + /** + * Gibt die Position des Streams (virtuellen Lesekopfes) im aktuellen Quellcode zurück + * + * @param label Das Label, dessen Streamposition zurückgegeben werden soll + * @return Die Streamposition des angegebenen Labels + */ + [[nodiscard]] std::streampos getStreamPosition(const std::string &label) const; }; diff --git a/src/components/Alu.cpp b/src/components/Alu.cpp index 88c2262..70f2c04 100644 --- a/src/components/Alu.cpp +++ b/src/components/Alu.cpp @@ -7,8 +7,15 @@ #include "Memory.h" #include "Register.h" +#include "../Manager.h" +#include "../ProgramLoader.h" void Alu::calculate(const std::vector &commandVector) { + /// Falls die aktuelle Zeile ein Label ist, return + if (const auto length = commandVector.at(0).size(); commandVector.at(0).at(length - 1) == ':') { + return; + } + /// Extrahiere den eigentlichen RISC-V Befehl für die ALU const std::string &command = commandVector.at(0); @@ -21,7 +28,7 @@ void Alu::calculate(const std::vector &commandVector) { } /// Wandle Vektor[3] (das dritte Argument) nur um, falls dieser existiert int arg3 = 0; - if (commandVector.size() > 3) { + if (commandVector.size() > 3 && isdigit(commandVector.at(3).at(1))) { arg3 = parseArgument(commandVector.at(3)); } @@ -103,6 +110,14 @@ void Alu::calculate(const std::vector &commandVector) { const auto data = Register::getInstance().getRegister(arg1); /// Speichere die Daten im angegeben RAM slot Memory::getInstance()->store(address, data); + } else if (command == "beq") { + const auto register1 = Register::getInstance().getRegister(arg1); + const auto register2 = Register::getInstance().getRegister(arg2); + const auto &label = commandVector.at(3); + const auto streamPos = ProgramLoader::getInstance()->getStreamPosition(label); + if (register1 == register2) { + Manager::getInstance()->setStreamPosition(streamPos); + } } } diff --git a/src/main.cpp b/src/main.cpp index 8e377e4..1689dc8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,7 +5,9 @@ #include "Manager.h" int main() { - return Manager::getInstance( + Manager::getInstance()->init( "/home/black/Nextcloud/Dokumente/Dokumente/Hochschule/2. Semester/Rechnerarchitektur/Projekt/test.txt" - )->run(); + ); + Manager::getInstance()->run(); + return 0; }