diff --git a/src/code.cpp b/src/code.cpp index de68809..a0a14a9 100644 --- a/src/code.cpp +++ b/src/code.cpp @@ -235,6 +235,29 @@ static int translateBistwiseUnaryOperation(std::ostringstream &stream) { 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, Command cmd) { std::ostringstream stream; @@ -266,6 +289,15 @@ int translateCommand(std::string &output, const std::string fileName, case CommandType::NOT: translateBistwiseUnaryOperation(stream); break; + case CommandType::LABEL: + translateLabel(stream, cmd); + break; + case CommandType::GOTO: + translateGoTo(stream, cmd); + break; + case CommandType::IFGOTO: + translateIfGoTo(stream, cmd); + break; default: break; } diff --git a/src/parser.cpp b/src/parser.cpp index 6c910e6..c9666ab 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -8,7 +8,7 @@ int parseCommand(std::vector &commands, std::string line) { std::smatch matched; - if (regex_search(line, matched, std::regex("^(.*) (.*) (.*)"))) { + if (regex_search(line, matched, std::regex("^(\\S+)\\s+(\\S+)\\s+(\\S+)$"))) { Command cmd; if (matched.ready()) { @@ -24,16 +24,31 @@ int parseCommand(std::vector &commands, std::string line) { return 0; } - if (regex_search(line, matched, std::regex("^(.*)"))) { + if (std::regex_search(line, matched, std::regex("^(\\S+)\\s+(\\S+)$"))) { Command cmd; - cmd.line = line; - cmd.commandType = commandTypes.at(matched[1]); + if (matched.ready()) { + cmd.line = line; + cmd.commandType = commandTypes.at(matched[1]); + cmd.label = matched[2]; + } commands.push_back(cmd); 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; } diff --git a/src/types.hpp b/src/types.hpp index faa8f63..92c879a 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -15,6 +15,12 @@ enum class CommandType { NOT, PUSH, POP, + LABEL, + GOTO, + IFGOTO, + FUNCTION, + CALL, + RETURN }; enum class SegmentType { @@ -29,13 +35,23 @@ enum class SegmentType { }; std::unordered_map const commandTypes = { - {"add", CommandType::ADD}, {"sub", CommandType::SUB}, - {"neg", CommandType::NEG}, {"eq", CommandType::EQ}, - {"gt", CommandType::GT}, {"lt", CommandType::LT}, - {"and", CommandType::AND}, {"or", CommandType::OR}, - {"not", CommandType::NOT}, {"push", CommandType::PUSH}, + {"add", CommandType::ADD}, + {"sub", CommandType::SUB}, + {"neg", CommandType::NEG}, + {"eq", CommandType::EQ}, + {"gt", CommandType::GT}, + {"lt", CommandType::LT}, + {"and", CommandType::AND}, + {"or", CommandType::OR}, + {"not", CommandType::NOT}, + {"push", CommandType::PUSH}, {"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 const segmentTypes = { {"local", SegmentType::LCL}, {"argument", SegmentType::ARG}, @@ -55,6 +71,7 @@ typedef struct { CommandType commandType; SegmentType segmentType; std::string segmentName; + std::string label; int index; } Command;