diff --git a/CMakeLists.txt b/CMakeLists.txt index e466a1c..e193693 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,6 @@ add_executable(riscv_emulator src/components/Memory.h src/Manager.cpp src/Manager.h - src/loader/CommandParser.cpp - src/loader/CommandParser.h + src/ProgramLoader.cpp + src/ProgramLoader.h ) diff --git a/src/Manager.h b/src/Manager.h index 2e60c77..fdd6c8c 100644 --- a/src/Manager.h +++ b/src/Manager.h @@ -4,7 +4,9 @@ #ifndef MANAGER_H #define MANAGER_H +#include #include +#include /// Die Manager Instanz sorgt für die Koordination von user input, Datei einlesen, code execution und anderen Aktionen. @@ -13,6 +15,8 @@ private: /// Die Instanz des Managers soll mit einem immutable path zum Programm erstellt werden explicit Manager(std::string path); std::string m_path; + std::map m_labels; + public: /// Singleton Logik Manager(const Manager &) = delete; @@ -27,8 +31,6 @@ public: * @return Manager Instanz */ static Manager *getInstance(const std::string &program_path); - - }; diff --git a/src/ProgramLoader.cpp b/src/ProgramLoader.cpp new file mode 100644 index 0000000..3e06040 --- /dev/null +++ b/src/ProgramLoader.cpp @@ -0,0 +1,56 @@ +// +// Created by black on 06.07.25. +// + +#include "ProgramLoader.h" +#include + +ProgramLoader::ProgramLoader(const std::string &path){ + m_programFile.open(path); +} + +ProgramLoader * ProgramLoader::getInstance(const std::string &program_path) { + static ProgramLoader instance{program_path}; + return &instance; +} + +[[nodiscard]] std::vector ProgramLoader::parseLine(const std::string &input) { + std::vector output{}; + /// Konvertiere den Input String in einen IStringStream, damit dieser bei Leerzeichen gesplittet werden kann + std::istringstream iss(input); + std::string out; + do { + /// Trenne den IStringStream bei jedem Leerzeichen und füge die Befehl(e)/-sargumente dem Output hinzu + std::getline(iss, out, ' '); + /// Stoppe, sobald ein Kommentar im Source Code vorkommt + if (out.at(0) != '#') { + if (out.at(out.length() -1) == ',') { + out.erase(out.length() - 1); + } + if (out.at(out.length() -1) == ':') { + break; + } + output.push_back(out); + } else { + break; + } + } while (!out.empty()); + return output; +} + +void ProgramLoader::indexFile() { + if (m_programFile.is_open()) { + std::string line; + int lineNumber = 1; + /// Parse Zeile für Zeile + while (std::getline(m_programFile, line)) { + auto lineVector = parseLine(line); + const auto first = lineVector.begin(); + /// Sobald ein Label gefunden wurde, speichere die Zeile + if (first->at(first->length() - 1) == ':') { + m_labels[first->substr(0, first->length() - 1)] = lineNumber; + } + lineNumber++; + } + } +} diff --git a/src/ProgramLoader.h b/src/ProgramLoader.h new file mode 100644 index 0000000..6f753e0 --- /dev/null +++ b/src/ProgramLoader.h @@ -0,0 +1,57 @@ +// +// Created by black on 06.07.25. +// + +#ifndef PROGRAMLOADER_H +#define PROGRAMLOADER_H +#include +#include +#include +#include + +/// Der ProgramLoader, zuständig für das Lesen und Parsen des Quellcodes + +class ProgramLoader { +private: + /** + * Der private Konstruktor für ProgramLoader + * + * @param path Der Pfad zur .txt Quelldatei des Programmes + */ + explicit ProgramLoader(const std::string &path); + + std::ifstream m_programFile; + std::map m_labels; + +public: + /// Singleton Logik + ProgramLoader(const ProgramLoader&) = delete; + ProgramLoader(const ProgramLoader&&) = delete; + ProgramLoader& operator=(const ProgramLoader&) = delete; + ProgramLoader& operator=(const ProgramLoader&&) = delete; + + /** + * Gibt die Singleton Instanz des ProgramLoaders zurück + * + * @param program_path Der Pfad zur .txt Quelldatei des Programmes + * @return ProgramLoader Instanz + */ + static ProgramLoader *getInstance(const std::string &program_path); + + /** + * Parst eine Zeile des Assembly Codes und gibt diese als sortierten Vektor zurück + * + * @param input Eine Zeile aus dem Assembly Code + * @return Ein Vektor mit Befehl und dessen Argumenten + */ + static std::vector parseLine(const std::string &input); + + /** + * Durchscucht das aktuelle Programm nach Labeln und speichert diese zusammen mit den Zeilennummern in einer Map + */ + void indexFile(); +}; + + + +#endif //PROGRAMLOADER_H diff --git a/src/loader/CommandParser.cpp b/src/loader/CommandParser.cpp deleted file mode 100644 index 585984f..0000000 --- a/src/loader/CommandParser.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// -// Created by black on 12.06.25. -// - -#include "emulator/CommandParser.h" - -#include - -CommandParser & CommandParser::getInstance() { - static CommandParser instance; - return instance; -} - -std::vector CommandParser::parseLine(const std::string &input) { - std::vector output{}; - /// Konvertiere den Input String in einen IStringStream, damit dieser bei Leerzeichen gesplittet werden kann - std::istringstream iss(input); - std::string out; - do { - /// Trenne den IStringStream bei jedem Leerzeichen und füge die Befehl(e)/-sargumente dem Output hinzu - std::getline(iss, out, ' '); - /// Stoppe, sobald ein Kommentar im Source Code vorkommt - if (out.at(0) != '#') { - output.push_back(out); - } else { - break; - } - } while (!out.empty()); - return output; -} diff --git a/src/loader/CommandParser.h b/src/loader/CommandParser.h deleted file mode 100644 index 7d1dbae..0000000 --- a/src/loader/CommandParser.h +++ /dev/null @@ -1,42 +0,0 @@ -// -// Created by black on 12.06.25. -// - -#ifndef COMMANDPARSER_H -#define COMMANDPARSER_H -#include -#include - - -class CommandParser { - -private: - CommandParser() = default; - -public: - /// Singleton Logik - CommandParser(const CommandParser&) = delete; - CommandParser(const CommandParser&&) = delete; - CommandParser& operator=(const CommandParser&) = delete; - CommandParser& operator=(const CommandParser&&) = delete; - ~CommandParser() = default; - - /** - * - * @return CommandParser Instanz - */ - static CommandParser& getInstance(); - - /** - * Parst eine Zeile des Assembly Codes und gibt diese als sortierten Vektor zurück - * - * @param input Eine Zeile aus dem Assembly Code - * @return Ein Vektor mit Befehl und dessen Argumenten - */ - static std::vector parseLine(const std::string& input); - -}; - - - -#endif //COMMANDPARSER_H