reordering and ProgramLoader basic functionality

This commit is contained in:
black
2025-07-06 18:54:20 +02:00
parent 5e45b71b8e
commit 3326227bb1
6 changed files with 119 additions and 76 deletions

View File

@@ -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
)

View File

@@ -4,7 +4,9 @@
#ifndef MANAGER_H
#define MANAGER_H
#include <map>
#include <string>
#include <vector>
/// 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<std::string, int> 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);
};

56
src/ProgramLoader.cpp Normal file
View File

@@ -0,0 +1,56 @@
//
// Created by black on 06.07.25.
//
#include "ProgramLoader.h"
#include <sstream>
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<std::string> ProgramLoader::parseLine(const std::string &input) {
std::vector<std::string> 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++;
}
}
}

57
src/ProgramLoader.h Normal file
View File

@@ -0,0 +1,57 @@
//
// Created by black on 06.07.25.
//
#ifndef PROGRAMLOADER_H
#define PROGRAMLOADER_H
#include <fstream>
#include <map>
#include <string>
#include <vector>
/// 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<std::string, int> 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<std::string> 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

View File

@@ -1,30 +0,0 @@
//
// Created by black on 12.06.25.
//
#include "emulator/CommandParser.h"
#include <sstream>
CommandParser & CommandParser::getInstance() {
static CommandParser instance;
return instance;
}
std::vector<std::string> CommandParser::parseLine(const std::string &input) {
std::vector<std::string> 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;
}

View File

@@ -1,42 +0,0 @@
//
// Created by black on 12.06.25.
//
#ifndef COMMANDPARSER_H
#define COMMANDPARSER_H
#include <string>
#include <vector>
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<std::string> parseLine(const std::string& input);
};
#endif //COMMANDPARSER_H