mirror of
https://github.com/hazemKrimi/jack-vm-translator.git
synced 2026-05-02 02:10:27 +00:00
Fixing functions logic wip
This commit is contained in:
@@ -4,7 +4,7 @@ This is a VM Translator made as the an assignment for the [Nand To Tetris Course
|
|||||||
|
|
||||||
To compile the program run the following command:
|
To compile the program run the following command:
|
||||||
```
|
```
|
||||||
g++ main.cpp -Isrc
|
g++ main.cpp -Isrc -std=c++17
|
||||||
```
|
```
|
||||||
To run the executable against jack vm files run the following command with the path of the file:
|
To run the executable against jack vm files run the following command with the path of the file:
|
||||||
```
|
```
|
||||||
|
|||||||
+10
-2
@@ -23,7 +23,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Code(string path, vector<vector<string>> tokens)
|
Code(string path, vector<vector<string>> tokens, bool isNew)
|
||||||
{
|
{
|
||||||
size_t slashIndex = path.find_last_of('/');
|
size_t slashIndex = path.find_last_of('/');
|
||||||
size_t dotIndex = path.find_last_of('.');
|
size_t dotIndex = path.find_last_of('.');
|
||||||
@@ -33,8 +33,16 @@ public:
|
|||||||
filename = path.substr(slashIndex + 1, dotIndex - slashIndex - 1);
|
filename = path.substr(slashIndex + 1, dotIndex - slashIndex - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
file = ofstream(path);
|
file = ofstream(path, isNew ? ios_base::out : ios_base::app);
|
||||||
commands = tokens;
|
commands = tokens;
|
||||||
|
|
||||||
|
if (isNew) {
|
||||||
|
file << "@256" << endl;
|
||||||
|
file << "D=A" << endl;
|
||||||
|
file << "@SP" << endl;
|
||||||
|
file << "M=D" << endl;
|
||||||
|
file << translateCall("Sys.init", 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~Code()
|
~Code()
|
||||||
|
|||||||
+45
-20
@@ -4,12 +4,14 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
string translateFunction(string name, int args) {
|
string translateFunction(string name, int args)
|
||||||
|
{
|
||||||
stringstream output;
|
stringstream output;
|
||||||
|
|
||||||
output << "(" << name << ")" << endl;
|
output << "(" << name << ")" << endl;
|
||||||
|
|
||||||
for (int i = 0; i < args; ++i) {
|
for (int i = 0; i < args; i++)
|
||||||
|
{
|
||||||
output << "@0" << endl;
|
output << "@0" << endl;
|
||||||
output << "D=A" << endl;
|
output << "D=A" << endl;
|
||||||
output << "@SP" << endl;
|
output << "@SP" << endl;
|
||||||
@@ -22,10 +24,10 @@ string translateFunction(string name, int args) {
|
|||||||
return output.str();
|
return output.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
string translateCall(string name, int args) {
|
string translateCall(string name, int args)
|
||||||
|
{
|
||||||
stringstream output;
|
stringstream output;
|
||||||
string label = name + "$ret" + generateRandomLabel(3);
|
string label = name + "$ret" + generateRandomLabel(3);
|
||||||
vector<string> frame = { "LCL", "ARG", "THIS", "THAT" };
|
|
||||||
|
|
||||||
output << "@" << label << endl;
|
output << "@" << label << endl;
|
||||||
output << "D=A" << endl;
|
output << "D=A" << endl;
|
||||||
@@ -35,20 +37,38 @@ string translateCall(string name, int args) {
|
|||||||
output << "@SP" << endl;
|
output << "@SP" << endl;
|
||||||
output << "M=M+1" << endl;
|
output << "M=M+1" << endl;
|
||||||
|
|
||||||
for (const string &segment : frame) {
|
|
||||||
output << "@" << segment << endl;
|
|
||||||
output << "D=M" << endl;
|
|
||||||
output << "@SP" << endl;
|
|
||||||
output << "A=M" << endl;
|
|
||||||
output << "M=D" << endl;
|
|
||||||
output << "@SP" << endl;
|
|
||||||
output << "M=M+1" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
output << "@SP" << endl;
|
|
||||||
output << "D=M" << endl;
|
|
||||||
output << "@LCL" << endl;
|
output << "@LCL" << endl;
|
||||||
|
output << "D=M" << endl;
|
||||||
|
output << "@SP" << endl;
|
||||||
|
output << "A=M" << endl;
|
||||||
output << "M=D" << endl;
|
output << "M=D" << endl;
|
||||||
|
output << "@SP" << endl;
|
||||||
|
output << "M=M+1" << endl;
|
||||||
|
|
||||||
|
output << "@ARG" << endl;
|
||||||
|
output << "D=M" << endl;
|
||||||
|
output << "@SP" << endl;
|
||||||
|
output << "A=M" << endl;
|
||||||
|
output << "M=D" << endl;
|
||||||
|
output << "@SP" << endl;
|
||||||
|
output << "M=M+1" << endl;
|
||||||
|
|
||||||
|
output << "@THIS" << endl;
|
||||||
|
output << "D=M" << endl;
|
||||||
|
output << "@SP" << endl;
|
||||||
|
output << "A=M" << endl;
|
||||||
|
output << "M=D" << endl;
|
||||||
|
output << "@SP" << endl;
|
||||||
|
output << "M=M+1" << endl;
|
||||||
|
|
||||||
|
output << "@THAT" << endl;
|
||||||
|
output << "D=M" << endl;
|
||||||
|
output << "@SP" << endl;
|
||||||
|
output << "A=M" << endl;
|
||||||
|
output << "M=D" << endl;
|
||||||
|
output << "@SP" << endl;
|
||||||
|
output << "M=M+1" << endl;
|
||||||
|
|
||||||
output << "@SP" << endl;
|
output << "@SP" << endl;
|
||||||
output << "D=M" << endl;
|
output << "D=M" << endl;
|
||||||
output << "@R" << endl;
|
output << "@R" << endl;
|
||||||
@@ -64,7 +84,11 @@ string translateCall(string name, int args) {
|
|||||||
output << "D=M" << endl;
|
output << "D=M" << endl;
|
||||||
output << "@ARG" << endl;
|
output << "@ARG" << endl;
|
||||||
output << "M=D" << endl;
|
output << "M=D" << endl;
|
||||||
output << "@R" << endl;
|
|
||||||
|
output << "@SP" << endl;
|
||||||
|
output << "D=M" << endl;
|
||||||
|
output << "@LCL" << endl;
|
||||||
|
output << "M=D" << endl;
|
||||||
|
|
||||||
output << "@" << name << endl;
|
output << "@" << name << endl;
|
||||||
output << "0;JMP" << endl;
|
output << "0;JMP" << endl;
|
||||||
@@ -73,7 +97,8 @@ string translateCall(string name, int args) {
|
|||||||
return output.str();
|
return output.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
string translateReturn() {
|
string translateReturn()
|
||||||
|
{
|
||||||
stringstream output;
|
stringstream output;
|
||||||
string cleanupLabel = "cleanup$ret" + generateRandomLabel(3);
|
string cleanupLabel = "cleanup$ret" + generateRandomLabel(3);
|
||||||
string endLabel = "end$ret" + generateRandomLabel(3);
|
string endLabel = "end$ret" + generateRandomLabel(3);
|
||||||
@@ -119,7 +144,7 @@ string translateReturn() {
|
|||||||
output << "D=M" << endl;
|
output << "D=M" << endl;
|
||||||
output << "@THAT" << endl;
|
output << "@THAT" << endl;
|
||||||
output << "M=D" << endl;
|
output << "M=D" << endl;
|
||||||
|
|
||||||
output << "@END_FRAME" << endl;
|
output << "@END_FRAME" << endl;
|
||||||
output << "D=M" << endl;
|
output << "D=M" << endl;
|
||||||
output << "@2" << endl;
|
output << "@2" << endl;
|
||||||
@@ -128,7 +153,7 @@ string translateReturn() {
|
|||||||
output << "D=M" << endl;
|
output << "D=M" << endl;
|
||||||
output << "@THIS" << endl;
|
output << "@THIS" << endl;
|
||||||
output << "M=D" << endl;
|
output << "M=D" << endl;
|
||||||
|
|
||||||
output << "@END_FRAME" << endl;
|
output << "@END_FRAME" << endl;
|
||||||
output << "D=M" << endl;
|
output << "D=M" << endl;
|
||||||
output << "@3" << endl;
|
output << "@3" << endl;
|
||||||
|
|||||||
@@ -1,39 +1,111 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <vector>
|
||||||
#include "include/parser.h"
|
#include "include/parser.h"
|
||||||
#include "include/code.h"
|
#include "include/code.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
string constructTranslatedPath(string path) {
|
string constructTranslatedFilePath(string path)
|
||||||
|
{
|
||||||
size_t position = path.rfind(".vm");
|
size_t position = path.rfind(".vm");
|
||||||
|
|
||||||
return path.replace(position, 3, ".asm");
|
return path.replace(position, 3, ".asm");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
string constructTranslatedDirectoryPath(string path)
|
||||||
{
|
{
|
||||||
if (!argv[1]) {
|
string newPath = path;
|
||||||
cout << "You must specify a vm file path!" << endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
string sourcePath = argv[1];
|
size_t position = path.rfind("/");
|
||||||
|
|
||||||
if (!regex_match(sourcePath, regex("^.+\\.vm"))) {
|
if (position != string::npos && position == path.size() - 1)
|
||||||
cout << "Wrong file extension!" << endl;
|
{
|
||||||
return 1;
|
newPath = path.replace(position, 1, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t slashIndex = path.find_last_of('/');
|
||||||
|
|
||||||
|
newPath += "/" + path.substr(slashIndex + 1);
|
||||||
|
|
||||||
|
return newPath + ".asm";
|
||||||
|
}
|
||||||
|
|
||||||
|
void processFile(string sourcePath)
|
||||||
|
{
|
||||||
Parser parser(sourcePath);
|
Parser parser(sourcePath);
|
||||||
|
|
||||||
vector<vector<string>> commands = parser.getCommands();
|
vector<vector<string>> commands = parser.getCommands();
|
||||||
|
|
||||||
string translatedPath = constructTranslatedPath(sourcePath);
|
|
||||||
|
|
||||||
Code code(translatedPath, commands);
|
string translatedPath = constructTranslatedFilePath(sourcePath);
|
||||||
|
|
||||||
|
Code code(translatedPath, commands, false);
|
||||||
|
|
||||||
code.translate();
|
code.translate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void processDirectory(string sourcePath, vector<string> files)
|
||||||
|
{
|
||||||
|
string translatedPath = constructTranslatedDirectoryPath(sourcePath);
|
||||||
|
bool isNew = true;
|
||||||
|
|
||||||
|
for (const auto &file : files)
|
||||||
|
{
|
||||||
|
Parser parser(file);
|
||||||
|
|
||||||
|
vector<vector<string>> commands = parser.getCommands();
|
||||||
|
|
||||||
|
Code code(translatedPath, commands, isNew);
|
||||||
|
|
||||||
|
code.translate();
|
||||||
|
|
||||||
|
isNew = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if (!argv[1])
|
||||||
|
{
|
||||||
|
cout << "You must specify a vm file path!" << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
string sourcePath = argv[1];
|
||||||
|
|
||||||
|
if (!regex_match(sourcePath, regex("^.+\\.vm")))
|
||||||
|
{
|
||||||
|
if (!fs::is_directory(sourcePath))
|
||||||
|
{
|
||||||
|
cerr << "Error: " << sourcePath << " is not a directory.\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<string> vmFiles;
|
||||||
|
|
||||||
|
for (const auto &entry : fs::directory_iterator(sourcePath))
|
||||||
|
{
|
||||||
|
if (entry.is_regular_file() && entry.path().extension() == ".vm")
|
||||||
|
{
|
||||||
|
vmFiles.push_back(entry.path().string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vmFiles.empty())
|
||||||
|
{
|
||||||
|
cout << "Directory does not contain vm files!" << sourcePath << "\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
processDirectory(sourcePath, vmFiles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
processFile(sourcePath);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user