feat: handle branching commands

This commit is contained in:
2026-04-07 16:05:28 +01:00
parent 48b68c0247
commit fba936ea53
3 changed files with 75 additions and 11 deletions
+32
View File
@@ -235,6 +235,29 @@ static int translateBistwiseUnaryOperation(std::ostringstream &stream) {
return 0; return 0;
} }
static int translateLabel(std::ostringstream &stream, Command cmd) {
stream << "(" << cmd.label << ")" << std::endl;
return 0;
}
static int translateGoTo(std::ostringstream &stream, Command cmd) {
stream << "@" << cmd.label << std::endl;
stream << "0;JMP" << std::endl;
return 0;
}
static int translateIfGoTo(std::ostringstream &stream, Command cmd) {
if (popFromStackToDRegister(stream) != 0)
return 1;
stream << "@" << cmd.label << std::endl;
stream << "D;JNE" << std::endl;
return 0;
}
int translateCommand(std::string &output, const std::string fileName, int translateCommand(std::string &output, const std::string fileName,
Command cmd) { Command cmd) {
std::ostringstream stream; std::ostringstream stream;
@@ -266,6 +289,15 @@ int translateCommand(std::string &output, const std::string fileName,
case CommandType::NOT: case CommandType::NOT:
translateBistwiseUnaryOperation(stream); translateBistwiseUnaryOperation(stream);
break; break;
case CommandType::LABEL:
translateLabel(stream, cmd);
break;
case CommandType::GOTO:
translateGoTo(stream, cmd);
break;
case CommandType::IFGOTO:
translateIfGoTo(stream, cmd);
break;
default: default:
break; break;
} }
+20 -5
View File
@@ -8,7 +8,7 @@
int parseCommand(std::vector<Command> &commands, std::string line) { int parseCommand(std::vector<Command> &commands, std::string line) {
std::smatch matched; std::smatch matched;
if (regex_search(line, matched, std::regex("^(.*) (.*) (.*)"))) { if (regex_search(line, matched, std::regex("^(\\S+)\\s+(\\S+)\\s+(\\S+)$"))) {
Command cmd; Command cmd;
if (matched.ready()) { if (matched.ready()) {
@@ -24,16 +24,31 @@ int parseCommand(std::vector<Command> &commands, std::string line) {
return 0; return 0;
} }
if (regex_search(line, matched, std::regex("^(.*)"))) { if (std::regex_search(line, matched, std::regex("^(\\S+)\\s+(\\S+)$"))) {
Command cmd; Command cmd;
cmd.line = line; if (matched.ready()) {
cmd.commandType = commandTypes.at(matched[1]); cmd.line = line;
cmd.commandType = commandTypes.at(matched[1]);
cmd.label = matched[2];
}
commands.push_back(cmd); commands.push_back(cmd);
return 0; return 0;
} }
std::cerr << "Incorrect vm command!" << std::endl; if (regex_search(line, matched, std::regex("^(\\S+)$"))) {
Command cmd;
if (matched.ready()) {
cmd.line = line;
cmd.commandType = commandTypes.at(matched[1]);
}
commands.push_back(cmd);
return 0;
}
std::cerr << "Incorrect vm command: " << line << std::endl;
return 1; return 1;
} }
+23 -6
View File
@@ -15,6 +15,12 @@ enum class CommandType {
NOT, NOT,
PUSH, PUSH,
POP, POP,
LABEL,
GOTO,
IFGOTO,
FUNCTION,
CALL,
RETURN
}; };
enum class SegmentType { enum class SegmentType {
@@ -29,13 +35,23 @@ enum class SegmentType {
}; };
std::unordered_map<std::string, CommandType> const commandTypes = { std::unordered_map<std::string, CommandType> const commandTypes = {
{"add", CommandType::ADD}, {"sub", CommandType::SUB}, {"add", CommandType::ADD},
{"neg", CommandType::NEG}, {"eq", CommandType::EQ}, {"sub", CommandType::SUB},
{"gt", CommandType::GT}, {"lt", CommandType::LT}, {"neg", CommandType::NEG},
{"and", CommandType::AND}, {"or", CommandType::OR}, {"eq", CommandType::EQ},
{"not", CommandType::NOT}, {"push", CommandType::PUSH}, {"gt", CommandType::GT},
{"lt", CommandType::LT},
{"and", CommandType::AND},
{"or", CommandType::OR},
{"not", CommandType::NOT},
{"push", CommandType::PUSH},
{"pop", CommandType::POP}, {"pop", CommandType::POP},
}; {"label", CommandType::LABEL},
{"goto", CommandType::GOTO},
{"if-goto", CommandType::IFGOTO},
{"function", CommandType::FUNCTION},
{"call", CommandType::CALL},
{"return", CommandType::RETURN}};
std::unordered_map<std::string, SegmentType> const segmentTypes = { std::unordered_map<std::string, SegmentType> const segmentTypes = {
{"local", SegmentType::LCL}, {"argument", SegmentType::ARG}, {"local", SegmentType::LCL}, {"argument", SegmentType::ARG},
@@ -55,6 +71,7 @@ typedef struct {
CommandType commandType; CommandType commandType;
SegmentType segmentType; SegmentType segmentType;
std::string segmentName; std::string segmentName;
std::string label;
int index; int index;
} Command; } Command;