added "beq" command
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<std::string, int> 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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<std::string, std::streampos> 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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -7,8 +7,15 @@
|
||||
|
||||
#include "Memory.h"
|
||||
#include "Register.h"
|
||||
#include "../Manager.h"
|
||||
#include "../ProgramLoader.h"
|
||||
|
||||
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
|
||||
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
|
||||
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<std::string> &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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user