added "beq" command

This commit is contained in:
black
2025-07-08 15:18:00 +02:00
parent f896f82db8
commit 6e65fe88fc
6 changed files with 76 additions and 32 deletions

View File

@@ -11,7 +11,37 @@
#include "components/Alu.h" #include "components/Alu.h"
namespace fs = std::filesystem; 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; std::cout << "Öffne Quellcode Datei: '" << m_path << "'" << "\n" << std::flush;
if (!fs::exists(m_path)) { if (!fs::exists(m_path)) {
std::cerr << "Datei existiert nicht: " << m_path << "\n" << std::flush; 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; 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;
}

View File

@@ -14,7 +14,7 @@
class Manager { class Manager {
private: private:
/// Die Instanz des Managers soll mit einem immutable path zum Programm erstellt werden /// 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::string m_path;
std::map<std::string, int> m_labels; std::map<std::string, int> m_labels;
@@ -38,7 +38,7 @@ public:
* @param program_path Der Pfad des Quellcodes * @param program_path Der Pfad des Quellcodes
* @return Die Singleton Instance des Managers * @return Die Singleton Instance des Managers
*/ */
static Manager *getInstance(const std::string &program_path); static Manager *getInstance();
/** /**
* Die Hauptmethode des Emulators. * Die Hauptmethode des Emulators.
@@ -47,6 +47,15 @@ public:
* @return Der Exitcode des Emulators * @return Der Exitcode des Emulators
*/ */
int run(); 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);
}; };

View File

@@ -40,9 +40,13 @@ void ProgramLoader::indexFile(std::ifstream &m_programFile) {
/// Parse Zeile für Zeile /// Parse Zeile für Zeile
while (std::getline(m_programFile, line)) { while (std::getline(m_programFile, line)) {
auto lineVector = parseLine(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) == ':') { if (const auto first = lineVector.begin(); first->at(first->length() - 1) == ':') {
m_labels[first->substr(0, first->length() - 1)] = m_programFile.tellg(); 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;
}

View File

@@ -15,9 +15,7 @@ class ProgramLoader {
private: private:
/** /**
* Der private Konstruktor für ProgramLoader * Der private Konstruktor für ProgramLoader
* * */
* @param path Der Pfad zur .txt Quelldatei des Programmes
*/
explicit ProgramLoader() = default; explicit ProgramLoader() = default;
std::map<std::string, std::streampos> m_labels; std::map<std::string, std::streampos> m_labels;
@@ -35,7 +33,6 @@ public:
/** /**
* Gibt die Singleton Instanz des ProgramLoaders zurück * Gibt die Singleton Instanz des ProgramLoaders zurück
* *
* @param program_path Der Pfad zur .txt Quelldatei des Programmes
* @return ProgramLoader Instanz * @return ProgramLoader Instanz
*/ */
static ProgramLoader *getInstance(); static ProgramLoader *getInstance();
@@ -52,6 +49,14 @@ public:
* Durchscucht das aktuelle Programm nach Labeln und speichert diese zusammen mit den Zeilennummern in einer Map * Durchscucht das aktuelle Programm nach Labeln und speichert diese zusammen mit den Zeilennummern in einer Map
*/ */
void indexFile(std::ifstream &m_programFile); 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;
}; };

View File

@@ -7,8 +7,15 @@
#include "Memory.h" #include "Memory.h"
#include "Register.h" #include "Register.h"
#include "../Manager.h"
#include "../ProgramLoader.h"
void Alu::calculate(const std::vector<std::string> &commandVector) { void Alu::calculate(const std::vector<std::string> &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 /// Extrahiere den eigentlichen RISC-V Befehl für die ALU
const std::string &command = commandVector.at(0); const std::string &command = commandVector.at(0);
@@ -21,7 +28,7 @@ void Alu::calculate(const std::vector<std::string> &commandVector) {
} }
/// Wandle Vektor[3] (das dritte Argument) nur um, falls dieser existiert /// Wandle Vektor[3] (das dritte Argument) nur um, falls dieser existiert
int arg3 = 0; int arg3 = 0;
if (commandVector.size() > 3) { if (commandVector.size() > 3 && isdigit(commandVector.at(3).at(1))) {
arg3 = parseArgument(commandVector.at(3)); arg3 = parseArgument(commandVector.at(3));
} }
@@ -103,6 +110,14 @@ void Alu::calculate(const std::vector<std::string> &commandVector) {
const auto data = Register::getInstance().getRegister(arg1); const auto data = Register::getInstance().getRegister(arg1);
/// Speichere die Daten im angegeben RAM slot /// Speichere die Daten im angegeben RAM slot
Memory::getInstance()->store(address, data); 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);
}
} }
} }

View File

@@ -5,7 +5,9 @@
#include "Manager.h" #include "Manager.h"
int main() { int main() {
return Manager::getInstance( Manager::getInstance()->init(
"/home/black/Nextcloud/Dokumente/Dokumente/Hochschule/2. Semester/Rechnerarchitektur/Projekt/test.txt" "/home/black/Nextcloud/Dokumente/Dokumente/Hochschule/2. Semester/Rechnerarchitektur/Projekt/test.txt"
)->run(); );
Manager::getInstance()->run();
return 0;
} }