mirror of
https://github.com/hazemKrimi/jack-vm-translator.git
synced 2026-05-02 02:10:27 +00:00
feat: handle branching commands
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-3
@@ -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;
|
||||||
|
|
||||||
|
if (matched.ready()) {
|
||||||
cmd.line = line;
|
cmd.line = line;
|
||||||
cmd.commandType = commandTypes.at(matched[1]);
|
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
@@ -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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user