added "jalr" command
This commit is contained in:
@@ -27,11 +27,15 @@ void Alu::calculate(const std::vector<std::string> &commandVector) {
|
||||
int arg2 = 0;
|
||||
if (commandVector.at(2).find('(') != std::string::npos) {
|
||||
arg2 = parseAddress(commandVector.at(2));
|
||||
} else {
|
||||
arg2 = parseArgument(commandVector.at(2));
|
||||
}
|
||||
/// Wandle Vektor[3] (das dritte Argument) nur um, falls dieser existiert
|
||||
/// Wandle Vektor[3] (das dritte Argument) nur um, falls dieser existiert und kein immediate Wert ist
|
||||
int arg3 = 0;
|
||||
if (commandVector.size() > 3 && isdigit(commandVector.at(3).at(1))) {
|
||||
arg3 = parseArgument(commandVector.at(3));
|
||||
if (commandVector.size() > 3) {
|
||||
if (const std::string &arg = commandVector.at(3); isRegister(arg) || isImmediate(arg)) {
|
||||
arg3 = parseArgument(arg);
|
||||
}
|
||||
}
|
||||
|
||||
if (command == "add") {
|
||||
@@ -138,14 +142,24 @@ void Alu::calculate(const std::vector<std::string> &commandVector) {
|
||||
Register::getInstance().setRegister(arg1, pos);
|
||||
Manager::getInstance()->setStreamPosition(streamPos);
|
||||
} else if (command == "jalr") {
|
||||
/// Jump and link register Befehl
|
||||
/// !!! Aufgrund des casts des stream offsets zu int funktioniert das nicht bei großen Quellcode Dateien
|
||||
/// und führt zu undefiniertem Verhalten !!!
|
||||
const auto pos = static_cast<int>(Manager::getInstance()->getNextStreamLineOffset().operator std::streamoff());
|
||||
const auto &label = commandVector.at(3);
|
||||
const auto streamPosLabel = ProgramLoader::getInstance()->getStreamPosition(label);
|
||||
const auto posOffset = Register::getInstance().getRegister(arg2);
|
||||
Register::getInstance().setRegister(arg1, pos);
|
||||
Manager::getInstance()->setStreamPosition(streamPosLabel);
|
||||
for (int i = 0; i < posOffset; ++i) {
|
||||
Manager::getInstance()->gotoNextStreamLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Alu::parseArgument(std::string argument) {
|
||||
/// Falls das erste Argument ein Register ist, entferne das führende "x"
|
||||
if (argument.at(0) == 'x') {
|
||||
argument = argument.substr(1, argument.length() - 1);
|
||||
}
|
||||
if (argument.at(0) == 'x') argument = argument.substr(1);
|
||||
/// Da das Argument noch als String vorliegt, muss es in ein int umgewandelt werden
|
||||
return std::stoi(argument);
|
||||
}
|
||||
@@ -162,3 +176,28 @@ int Alu::parseAddress(const std::string &argument) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Alu::isRegister(const std::string &argument) {
|
||||
/// Überprüfe, ob das nichtleere Argument mit 'x' startet
|
||||
if (argument.empty() || argument.at(0) != 'x') return false;
|
||||
/// Entfernt das voranstehende 'x' und checkt, ob darauf etwas folgt
|
||||
const std::string numberPart = argument.substr(1);
|
||||
if (numberPart.empty()) return false;
|
||||
/// Überprüfe, ob alle Zeichen im restlichen Argument Nummern sind
|
||||
for (const char c: numberPart) {
|
||||
if (!std::isdigit(c)) return false;
|
||||
}
|
||||
/// Konvertiere zu int und überprüfe, ob es ein Register zwischen inklusive x0 und x32 ist
|
||||
const int regNum = std::stoi(numberPart);
|
||||
return regNum >= 0 && regNum <= 32;
|
||||
}
|
||||
|
||||
bool Alu::isImmediate(const std::string &argument) {
|
||||
if (argument.empty()) return false;
|
||||
constexpr size_t start = 0;
|
||||
/// Überprüfe, ob jedes Zeichen im Argument eine Nummer ista
|
||||
for (size_t i = start; i < argument.size(); ++i) {
|
||||
if (!std::isdigit(argument.at(i))) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user