code cleanup and fixes

This commit is contained in:
black
2025-07-08 21:04:04 +02:00
parent ab77f7118a
commit 09d2b178d6
8 changed files with 107 additions and 71 deletions

View File

@@ -5,32 +5,35 @@
#include "Manager.h" #include "Manager.h"
#include <iostream> #include <iostream>
#include <utility>
#include <filesystem> #include <filesystem>
#include "components/Alu.h" #include "components/Alu.h"
namespace fs = std::filesystem; namespace fs = std::filesystem;
Manager::~Manager() { Manager::~Manager() {
std::cout << "Schließe Quellcode Datei: '" << m_path << "'" << "\n" << std::flush;
m_programFile.close(); m_programFile.close();
} }
Manager *Manager::getInstance() { Manager &Manager::getInstance() {
static Manager instance; static Manager instance;
return &instance; return instance;
} }
int Manager::run() { int Manager::run() {
if (!m_programFile.is_open()) { if (!m_programFile.is_open()) {
std::cerr << "Bitte zuerst die init() Methode aufrufen!" << "\n" << std::flush; std::cerr << "Bitte zuerst die init() Methode aufrufen!" << "\n" << std::flush;
} }
ProgramLoader::getInstance()->indexFile(m_programFile); ProgramLoader::getInstance().indexFile(m_programFile);
/// Die Position des Streams (virtueller Lesekopf) muss nach dem Indexen wieder zurückgesetzt werden // Die Position des Streams (virtueller Lesekopf) muss nach dem Indexen wieder zurückgesetzt werden
m_programFile.clear(); m_programFile.clear();
m_programFile.seekg(0); m_programFile.seekg(0);
// Bearbeite jede Zeile des Quellcodes in der ALU
std::string line; std::string line;
while (std::getline(m_programFile, line)) { while (std::getline(m_programFile, line)) {
auto lineVector = ProgramLoader::parseLine(line); auto lineVector = ProgramLoader::parseLine(line);
// Sollte die aktuelle Zeile leer sein, überspringe die ALU
if (lineVector.empty()) continue; if (lineVector.empty()) continue;
Alu::calculate(lineVector); Alu::calculate(lineVector);
} }
@@ -48,11 +51,15 @@ std::streampos Manager::getStreamPosition() {
void Manager::init(const std::string &program_path) { void Manager::init(const std::string &program_path) {
m_path = 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;
//Überprüfe, ob die Datei existiert
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;
return; return;
} }
m_programFile.open(m_path); m_programFile.open(m_path);
// Sollte die Datei nicht geöffnet worden sein, gib den Fehler aus
if (!m_programFile.is_open()) { if (!m_programFile.is_open()) {
std::cerr << "Datei konnte nicht geöffnet werden: " << m_path << "\n" << std::flush; std::cerr << "Datei konnte nicht geöffnet werden: " << m_path << "\n" << std::flush;
std::cerr << "fail (z.B. Zugriffsrechte): " << m_programFile.fail() << "\n" << std::flush; std::cerr << "fail (z.B. Zugriffsrechte): " << m_programFile.fail() << "\n" << std::flush;
@@ -62,12 +69,14 @@ void Manager::init(const std::string &program_path) {
} }
std::streampos Manager::getNextStreamLineOffset() { std::streampos Manager::getNextStreamLineOffset() {
/// Speichert das aktuelle stream offset // Speichert das aktuelle stream offset
const auto positionBefore = m_programFile.tellg(); const auto positionBefore = m_programFile.tellg();
/// Geht eine Zeile nach vorne zum nächsten Befehl (PC+4) und speichert den offset
// Geht eine Zeile nach vorne zum nächsten Befehl (PC+4) und speichert den offset
gotoNextStreamLine(); gotoNextStreamLine();
const auto positionAfter = m_programFile.tellg(); const auto positionAfter = m_programFile.tellg();
/// Geht zum offset vom Anfang zurück und gibt die nächste Adresse (PC+4) zurück
// Geht zum offset vom Anfang zurück und gibt die nächste Adresse (PC+4) zurück
m_programFile.seekg(positionBefore); m_programFile.seekg(positionBefore);
return positionAfter; return positionAfter;
} }

View File

@@ -9,11 +9,11 @@
#include "ProgramLoader.h" #include "ProgramLoader.h"
/// Die Manager Instanz sorgt für die Koordination von user input, Datei einlesen, code execution und anderen Aktionen. // Die Manager Instanz sorgt für die Koordination von user input, Datei einlesen, code execution und anderen Aktionen.
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
Manager() = default; Manager() = default;
std::string m_path; std::string m_path;
@@ -21,7 +21,7 @@ private:
std::ifstream m_programFile; std::ifstream m_programFile;
public: public:
/// Singleton Logik // Singleton Logik
Manager(const Manager &) = delete; Manager(const Manager &) = delete;
Manager(const Manager &&) = delete; Manager(const Manager &&) = delete;
@@ -37,7 +37,7 @@ public:
* *
* @return Die Singleton Instance des Managers * @return Die Singleton Instance des Managers
*/ */
static Manager *getInstance(); static Manager &getInstance();
/** /**
* Die Hauptmethode des Emulators. * Die Hauptmethode des Emulators.

View File

@@ -5,44 +5,58 @@
#include "ProgramLoader.h" #include "ProgramLoader.h"
#include <sstream> #include <sstream>
ProgramLoader *ProgramLoader::getInstance() { ProgramLoader &ProgramLoader::getInstance() {
static ProgramLoader instance; static ProgramLoader instance;
return &instance; return instance;
} }
[[nodiscard]] std::vector<std::string> ProgramLoader::parseLine(const std::string &input) { [[nodiscard]] std::vector<std::string> ProgramLoader::parseLine(const std::string &input) {
// Sollte die aktuelle Zeile leer sein, gib einen leeren Vektor zurück
if (input.empty()) return std::vector<std::string>{}; if (input.empty()) return std::vector<std::string>{};
std::vector<std::string> output{}; std::vector<std::string> output{};
/// Konvertiere den Input String in einen IStringStream, damit dieser bei Leerzeichen gesplittet werden kann // Konvertiere den Input String in einen IStringStream, damit dieser bei Leerzeichen gesplittet werden kann
std::istringstream iss(input); std::istringstream iss(input);
std::string out; std::string out;
do { do {
out.clear(); out.clear();
/// Trenne den IStringStream bei jedem Leerzeichen und füge die Befehl(e)/-sargumente dem Output hinzu
// Trenne den IStringStream bei jedem Leerzeichen und füge die Befehl(e)/-sargumente dem Output hinzu
std::getline(iss, out, ' '); std::getline(iss, out, ' ');
if (out.empty()) break; if (out.empty()) break;
/// Stoppe, sobald ein Kommentar im Source Code vorkommt
// Entferne alle Leerzeichen hinter dem Befehl/Argument
while (out.at(out.length() - 1) == ' ') {
out.erase(out.length() - 1);
}
// Stoppe, sobald ein Kommentar im Source Code vorkommt
if (out.at(0) != '#') { if (out.at(0) != '#') {
if (out.at(out.length() - 1) == ',') { if (out.at(out.length() - 1) == ',') {
out.erase(out.length() - 1); out.erase(out.length() - 1);
} }
output.push_back(out); output.push_back(out);
} else { } else {
break; break;
} }
} while (!out.empty()); } while (!out.empty());
return output; return output;
} }
void ProgramLoader::indexFile(std::ifstream &m_programFile) { void ProgramLoader::indexFile(std::ifstream &m_programFile) {
// Setze den Lesekop zurück
m_programFile.clear(); m_programFile.clear();
m_programFile.seekg(0); m_programFile.seekg(0);
std::string line; std::string line;
/// Parse Zeile für Zeile // Parse Zeile für Zeile
while (std::getline(m_programFile, line)) { while (std::getline(m_programFile, line)) {
// Parst die aktuelle Zeile und springt zur nächsten, falls die aktuelle leer ist
auto lineVector = parseLine(line); auto lineVector = parseLine(line);
if (lineVector.empty()) continue; if (lineVector.empty()) continue;
/// Sobald ein Label gefunden wurde, speichere die Position des Streams
// 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();
} }

View File

@@ -9,7 +9,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
/// Der ProgramLoader, zuständig für das Lesen und Parsen des Quellcodes // Der ProgramLoader, zuständig für das Lesen und Parsen des Quellcodes
class ProgramLoader { class ProgramLoader {
private: private:
@@ -21,7 +21,7 @@ private:
std::map<std::string, std::streampos> m_labels; std::map<std::string, std::streampos> m_labels;
public: public:
/// Singleton Logik // Singleton Logik
ProgramLoader(const ProgramLoader &) = delete; ProgramLoader(const ProgramLoader &) = delete;
ProgramLoader(const ProgramLoader &&) = delete; ProgramLoader(const ProgramLoader &&) = delete;
@@ -35,7 +35,7 @@ public:
* *
* @return ProgramLoader Instanz * @return ProgramLoader Instanz
*/ */
static ProgramLoader *getInstance(); static ProgramLoader &getInstance();
/** /**
* Parst eine Zeile des Assembly Codes und gibt diese als sortierten Vektor zurück * Parst eine Zeile des Assembly Codes und gibt diese als sortierten Vektor zurück

View File

@@ -5,6 +5,7 @@
#include "Alu.h" #include "Alu.h"
#include <cstdint> #include <cstdint>
#include <iostream>
#include <vector> #include <vector>
#include "Memory.h" #include "Memory.h"
@@ -13,6 +14,11 @@
#include "../ProgramLoader.h" #include "../ProgramLoader.h"
void Alu::calculate(const std::vector<std::string> &commandVector) { void Alu::calculate(const std::vector<std::string> &commandVector) {
auto &reg = Register::getInstance();
auto &mem = Memory::getInstance();
const auto &pl = ProgramLoader::getInstance();
auto &man = Manager::getInstance();
// Falls die aktuelle Zeile ein Label ist, return // Falls die aktuelle Zeile ein Label ist, return
if (const auto length = commandVector.at(0).size(); commandVector.at(0).at(length - 1) == ':') { if (const auto length = commandVector.at(0).size(); commandVector.at(0).at(length - 1) == ':') {
return; return;
@@ -23,13 +29,16 @@ void Alu::calculate(const std::vector<std::string> &commandVector) {
// Extrahiere die Argumente des Befehls // Extrahiere die Argumente des Befehls
const auto arg1 = parseArgument(commandVector.at(1)); const auto arg1 = parseArgument(commandVector.at(1));
// Wandle Vektor[2] (das zweite Argument) nur um, falls es kein SW/LW Argument ist
// Wandle Vektor[2] (das zweite Argument) in eine Adresse um, falls es ein SW/LW Argument ist
int arg2 = 0; int arg2 = 0;
if (commandVector.at(2).find('(') != std::string::npos) { if (commandVector.at(2).find('(') != std::string::npos) {
arg2 = parseAddress(commandVector.at(2)); arg2 = parseAddress(commandVector.at(2));
} else { } else {
// Ansonsten wandle es in ein Registerargument um
arg2 = parseArgument(commandVector.at(2)); arg2 = parseArgument(commandVector.at(2));
} }
// Wandle Vektor[3] (das dritte Argument) nur um, falls dieser existiert und kein immediate Wert ist // Wandle Vektor[3] (das dritte Argument) nur um, falls dieser existiert und kein immediate Wert ist
int arg3 = 0; int arg3 = 0;
if (commandVector.size() > 3) { if (commandVector.size() > 3) {
@@ -41,124 +50,126 @@ void Alu::calculate(const std::vector<std::string> &commandVector) {
if (command == "add") { if (command == "add") {
// Addition Befehl // Addition Befehl
// Hole die Werte beider angegebener Register // Hole die Werte beider angegebener Register
const auto register1 = Register::getInstance().getRegister(arg2); const auto register1 = reg.getRegister(arg2);
const auto register2 = Register::getInstance().getRegister(arg3); const auto register2 = reg.getRegister(arg3);
// Addiere die beiden Werte und schreibe das Ergebnis ins angegebene Register zurück // Addiere die beiden Werte und schreibe das Ergebnis ins angegebene Register zurück
const auto result = register1 + register2; const auto result = register1 + register2;
Register::getInstance().setRegister(arg1, result); reg.setRegister(arg1, result);
} else if (command == "sub") { } else if (command == "sub") {
// Subtraktion Befehl // Subtraktion Befehl
// Hole die Werte beider angegebener Register // Hole die Werte beider angegebener Register
const auto register1 = Register::getInstance().getRegister(arg2); const auto register1 = reg.getRegister(arg2);
const auto register2 = Register::getInstance().getRegister(arg3); const auto register2 = reg.getRegister(arg3);
// Subtrahiere die beiden Werte und schreibe das Ergebnis ins angegebene Register zurück // Subtrahiere die beiden Werte und schreibe das Ergebnis ins angegebene Register zurück
const auto result = register1 - register2; const auto result = register1 - register2;
Register::getInstance().setRegister(arg1, result); reg.setRegister(arg1, result);
} else if (command == "and") { } else if (command == "and") {
// Binärer und Befehl // Binärer und Befehl
// Hole die Werte beider angegebener Register // Hole die Werte beider angegebener Register
const auto register1 = Register::getInstance().getRegister(arg2); const auto register1 = reg.getRegister(arg2);
const auto register2 = Register::getInstance().getRegister(arg3); const auto register2 = reg.getRegister(arg3);
// Verknüpfe die beiden Werte binär und schreibe das Ergebnis ins angegebene Register zurück // Verknüpfe die beiden Werte binär und schreibe das Ergebnis ins angegebene Register zurück
const auto result = register1 & register2; const auto result = register1 & register2;
Register::getInstance().setRegister(arg1, result); reg.setRegister(arg1, result);
} else if (command == "or") { } else if (command == "or") {
// Binärer oder Befehl // Binärer oder Befehl
// Hole die Werte beider angegebener Register // Hole die Werte beider angegebener Register
const auto register1 = Register::getInstance().getRegister(arg2); const auto register1 = reg.getRegister(arg2);
const auto register2 = Register::getInstance().getRegister(arg3); const auto register2 = reg.getRegister(arg3);
// Unterscheide die beiden Werte binär und schreibe das Ergebnis ins angegebene Register zurück // Unterscheide die beiden Werte binär und schreibe das Ergebnis ins angegebene Register zurück
const auto result = register1 | register2; const auto result = register1 | register2;
Register::getInstance().setRegister(arg1, result); reg.setRegister(arg1, result);
} else if (command == "xor") { } else if (command == "xor") {
// Binärer exklusiver oder Befehl // Binärer exklusiver oder Befehl
// Hole die Werte beider angegebener Register // Hole die Werte beider angegebener Register
const auto register1 = Register::getInstance().getRegister(arg2); const auto register1 = reg.getRegister(arg2);
const auto register2 = Register::getInstance().getRegister(arg3); const auto register2 = reg.getRegister(arg3);
// Unterscheide die beiden Werte binär exklusiv und schreibe das Ergebnis ins angegebene Register zurück // Unterscheide die beiden Werte binär exklusiv und schreibe das Ergebnis ins angegebene Register zurück
const auto result = register1 ^ register2; const auto result = register1 ^ register2;
Register::getInstance().setRegister(arg1, result); reg.setRegister(arg1, result);
} else if (command == "addi") { } else if (command == "addi") {
// Immediate und Befehl // Immediate und Befehl
// Hole Wert1 aus dem angegebenen Register und Wert2 aus dem Befehlsargument // Hole Wert1 aus dem angegebenen Register und Wert2 aus dem Befehlsargument
const auto register1 = Register::getInstance().getRegister(arg2); const auto register1 = reg.getRegister(arg2);
const auto immediate = arg3; const auto immediate = arg3;
// Addiere die beiden Werte und schreibe das Ergebnis ins angegebene Register zurück // Addiere die beiden Werte und schreibe das Ergebnis ins angegebene Register zurück
const auto result = register1 + immediate; const auto result = register1 + immediate;
Register::getInstance().setRegister(arg1, result); reg.setRegister(arg1, result);
} else if (command == "andi") { } else if (command == "andi") {
// Binärer immediate und Befehl // Binärer immediate und Befehl
// Hole Wert1 aus dem angegebnen Register und Wert2 aus dem Befehlsargument // Hole Wert1 aus dem angegebnen Register und Wert2 aus dem Befehlsargument
const auto register1 = Register::getInstance().getRegister(arg2); const auto register1 = reg.getRegister(arg2);
const auto immediate = arg3; const auto immediate = arg3;
// Addiere die beiden Werte und schreibe das Ergebnis ins angegebene Register zurück // Addiere die beiden Werte und schreibe das Ergebnis ins angegebene Register zurück
const auto result = register1 & immediate; const auto result = register1 & immediate;
Register::getInstance().setRegister(arg1, result); reg.setRegister(arg1, result);
} else if (command == "ori") { } else if (command == "ori") {
// Binärer immediate oder Befehl // Binärer immediate oder Befehl
// Hole Wert1 aus dem angegebenen Register und Wert2 aus dem Befehlsargument // Hole Wert1 aus dem angegebenen Register und Wert2 aus dem Befehlsargument
const auto register1 = Register::getInstance().getRegister(arg2); const auto register1 = reg.getRegister(arg2);
const auto immediate = arg3; const auto immediate = arg3;
// Unterscheide beide Werte binär und schreibe das Ergebnis ins angegebene Register zurück // Unterscheide beide Werte binär und schreibe das Ergebnis ins angegebene Register zurück
const auto result = register1 | immediate; const auto result = register1 | immediate;
Register::getInstance().setRegister(arg1, result); reg.setRegister(arg1, result);
} else if (command == "lw") { } else if (command == "lw") {
// Loadword Befehl // Loadword Befehl
// Hole die Adresse aus dem Befehlsargument und die dazugehörigen Daten aus dem RAM // Hole die Adresse aus dem Befehlsargument und die dazugehörigen Daten aus dem RAM
const auto address = arg2; const auto address = arg2;
const auto data = Memory::getInstance()->load(address); const auto data = mem.load(address);
// Speichere die Daten im angegeben Register // Speichere die Daten im angegeben Register
Register::getInstance().setRegister(arg1, data); reg.setRegister(arg1, data);
} else if (command == "sw") { } else if (command == "sw") {
// Storeword Befehl // Storeword Befehl
// Hole die Adresse aus dem Befehlsargument und die dazugehörigen Daten aus dem Register // Hole die Adresse aus dem Befehlsargument und die dazugehörigen Daten aus dem Register
const auto address = arg2; const auto address = arg2;
const auto data = Register::getInstance().getRegister(arg1); const auto data = reg.getRegister(arg1);
// Speichere die Daten im angegeben RAM slot // Speichere die Daten im angegeben RAM slot
Memory::getInstance()->store(address, data); mem.store(address, data);
} else if (command == "beq") { } else if (command == "beq") {
const auto register1 = Register::getInstance().getRegister(arg1); const auto register1 = reg.getRegister(arg1);
const auto register2 = Register::getInstance().getRegister(arg2); const auto register2 = reg.getRegister(arg2);
const auto &label = commandVector.at(3); const auto &label = commandVector.at(3);
const auto streamPos = ProgramLoader::getInstance()->getStreamPosition(label); const auto streamPos = pl.getStreamPosition(label);
if (register1 == register2) { if (register1 == register2) {
Manager::getInstance()->setStreamPosition(streamPos); man.setStreamPosition(streamPos);
} }
} else if (command == "bne") { } else if (command == "bne") {
const auto register1 = Register::getInstance().getRegister(arg1); const auto register1 = reg.getRegister(arg1);
const auto register2 = Register::getInstance().getRegister(arg2); const auto register2 = reg.getRegister(arg2);
const auto &label = commandVector.at(3); const auto &label = commandVector.at(3);
const auto streamPos = ProgramLoader::getInstance()->getStreamPosition(label); const auto streamPos = pl.getStreamPosition(label);
if (register1 != register2) { if (register1 != register2) {
Manager::getInstance()->setStreamPosition(streamPos); man.setStreamPosition(streamPos);
} }
} else if (command == "jal") { } else if (command == "jal") {
// Jump and link Befehl // Jump and link Befehl
// !!! Aufgrund des casts des stream offsets zu int funktioniert das nicht bei großen Quellcode Dateien // !!! Aufgrund des casts des stream offsets zu int funktioniert das nicht bei großen Quellcode Dateien
// und führt zu undefiniertem Verhalten !!! // und führt zu undefiniertem Verhalten !!!
// Speichert die Position des nächsten Befehls im angegebenen Register // Speichert die Position des nächsten Befehls im angegebenen Register
const auto pos = static_cast<int>(Manager::getInstance()->getNextStreamLineOffset().operator std::streamoff()); const auto pos = static_cast<int>(man.getNextStreamLineOffset().operator std::streamoff());
Register::getInstance().setRegister(arg1, pos); reg.setRegister(arg1, pos);
// Holt sich die Position des angegebenen labels und die stream Position auf diese // Holt sich die Position des angegebenen labels und die stream Position auf diese
const auto &label = commandVector.at(2); const auto &label = commandVector.at(2);
const auto streamPos = ProgramLoader::getInstance()->getStreamPosition(label); const auto streamPos = pl.getStreamPosition(label);
Manager::getInstance()->setStreamPosition(streamPos); man.setStreamPosition(streamPos);
} else if (command == "jalr") { } else if (command == "jalr") {
// Jump and link register Befehl // Jump and link register Befehl
// !!! Aufgrund des casts des stream offsets zu int funktioniert das nicht bei großen Quellcode Dateien // !!! Aufgrund des casts des stream offsets zu int funktioniert das nicht bei großen Quellcode Dateien
// und führt zu undefiniertem Verhalten !!! // und führt zu undefiniertem Verhalten !!!
// Speichert die Position des nächsten Befehls im angegebenen Register // Speichert die Position des nächsten Befehls im angegebenen Register
const auto pos = static_cast<int>(Manager::getInstance()->getNextStreamLineOffset().operator std::streamoff()); const auto pos = static_cast<int>(man.getNextStreamLineOffset().operator std::streamoff());
Register::getInstance().setRegister(arg1, pos); reg.setRegister(arg1, pos);
// Holt sich die Position des angegebenen labels und das Offset aus dem angegebenen Register // Holt sich die Position des angegebenen labels und das Offset aus dem angegebenen Register
const auto &label = commandVector.at(3); const auto &label = commandVector.at(3);
const auto streamPosLabel = ProgramLoader::getInstance()->getStreamPosition(label); const auto streamPosLabel = pl.getStreamPosition(label);
const auto posOffset = Register::getInstance().getRegister(arg2); const auto posOffset = reg.getRegister(arg2);
// Setzt die stream Position auf den gegebenen Wert & erhöht sie um den angegebenen Offset // Setzt die stream Position auf den gegebenen Wert & erhöht sie um den angegebenen Offset
Manager::getInstance()->setStreamPosition(streamPosLabel); man.setStreamPosition(streamPosLabel);
for (int i = 0; i < posOffset; ++i) { for (int i = 0; i < posOffset; ++i) {
Manager::getInstance()->gotoNextStreamLine(); man.gotoNextStreamLine();
} }
} else {
std::cerr << "Befehl " << command << " wurde nicht gefunden!";
} }
} }
@@ -188,6 +199,7 @@ bool Alu::isRegister(const std::string &argument) {
// Entfernt das voranstehende 'x' und checkt, ob darauf etwas folgt // Entfernt das voranstehende 'x' und checkt, ob darauf etwas folgt
const std::string numberPart = argument.substr(1); const std::string numberPart = argument.substr(1);
if (numberPart.empty()) return false; if (numberPart.empty()) return false;
// Überprüfe, ob alle Zeichen im restlichen Argument Nummern sind // Überprüfe, ob alle Zeichen im restlichen Argument Nummern sind
for (const char c: numberPart) { for (const char c: numberPart) {
if (!std::isdigit(c)) return false; if (!std::isdigit(c)) return false;
@@ -199,6 +211,7 @@ bool Alu::isRegister(const std::string &argument) {
bool Alu::isImmediate(const std::string &argument) { bool Alu::isImmediate(const std::string &argument) {
if (argument.empty()) return false; if (argument.empty()) return false;
constexpr size_t start = 0; constexpr size_t start = 0;
// Überprüfe, ob jedes Zeichen im Argument eine Nummer ista // Überprüfe, ob jedes Zeichen im Argument eine Nummer ista
for (size_t i = start; i < argument.size(); ++i) { for (size_t i = start; i < argument.size(); ++i) {

View File

@@ -8,9 +8,9 @@ Memory::Memory() {
m_memory = {0}; m_memory = {0};
} }
Memory *Memory::getInstance() { Memory &Memory::getInstance() {
static Memory instance; static Memory instance;
return &instance; return instance;
} }
void Memory::store(const int address, const int value) { void Memory::store(const int address, const int value) {

View File

@@ -35,7 +35,7 @@ public:
* *
* @return Memory Instanz * @return Memory Instanz
*/ */
static Memory *getInstance(); static Memory &getInstance();
/** /**
* Speichert den angegebenen Wert an der angegebenen Adresse im Hauptspeicher * Speichert den angegebenen Wert an der angegebenen Adresse im Hauptspeicher

View File

@@ -5,9 +5,9 @@
#include "Manager.h" #include "Manager.h"
int main() { int main() {
Manager::getInstance()->init( 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"
); );
Manager::getInstance()->run(); Manager::getInstance().run();
return 0; return 0;
} }